Skip to content

Making it look like your brand

The look comes from a small set of tokens. Change a token and every page, component and state follows — you rarely need to touch a component.

Run npm run dev and open http://localhost:3000/style-guide. It shows the colours, text styles, buttons, form fields, cards and every other component with its name. When you want to know what a change will affect, look there.

src/design-system/theme.css:

@theme {
--color-ink: #101010; /* text, buttons, dark surfaces */
--color-canvas: #f6f6f6; /* page background */
--color-line: #d9d9d9; /* dividers, menu hover */
--color-muted: #818181; /* secondary text, icons */
--color-accent: #fc5000; /* accent */
--color-star: #fdca49; /* rating stars */
--color-danger: #ff2244; /* form errors */
}

Each name becomes a Tailwind class: bg-ink, text-muted, border-line. Swap the hex values for your own palette and the whole site changes. Keep enough contrast between --color-ink and --color-canvas — dark text on a light background, at least 4.5:1, or the site becomes hard to read.

The template loads Inter through next/font in src/app/layout.tsx:

const inter = Inter({ variable: "--font-inter", subsets: ["latin"] });

To use another Google font, import it by name from next/font/google and keep the variable name:

import { Manrope } from "next/font/google";
const inter = Manrope({ variable: "--font-inter", subsets: ["latin"] });

For a font you have licensed yourself, use next/font/local and point it at the files in src/app/fonts/. Next.js serves the font from your own domain either way, so there is no request to Google at runtime.

src/design-system/tokens/text.ts holds the sizes, weights and line heights, named after the design:

h01, h02, h2, h3, h4, h5, h6
hugeParagraph, largeParagraph, paragraph, smallParagraph
button, menu

Each is a set of Tailwind classes with the phone size first and the tablet (md:) and desktop (lg:) sizes after: h2: "text-[32px] md:text-[36px] lg:text-[42px] leading-[1.2] font-medium". Change the numbers here rather than in the components, and headings stay consistent across the site.

Use them as className={text.h2} or combine: className={cn(text.h6, "text-muted")}.

Three sizes, set in theme.css:

Width Tailwind prefix
Phone below 810 px (none)
Tablet 810–1199 px md:
Desktop 1200 px and up lg:

src/design-system/tokens/motion.ts holds the springs and the reveal used by menus, accordions, sliders and hover states. Lower the stiffness for a softer feel, raise the damping to settle faster. Every animation respects the visitor’s “reduce motion” setting.

These are Tailwind classes on the components (rounded-2xl, px-5, gap-10). Tailwind’s scale is 4 px per step, so p-5 is 20 px. Change them where you see them; the style guide shows the result immediately.

src/design-system/components/ — buttons, form fields, cards, sliders, the cursor, the icons. Its README explains the folders and how the pieces fit together. The sections that make up a page are one level up, in src/components/sections/, and are listed in Pages and sections.

The SVG files are in public/icons/ (Phosphor Icons plus a few drawn for Nitip) and src/design-system/components/icons/Icon.tsx lists them by name. To add one, drop my-icon.svg next to the others, add "my-icon": { dark: "my-icon.svg" } to the icons map, and use <Icon name="my-icon" />. A light file is the white version; when only one file exists, the other tone is produced with a CSS filter.

The custom cursor follows the pointer on desktop and turns into a label on cards (“View”, “Read”). It is in src/design-system/components/cursor/. To remove it, delete <Cursor /> from src/app/layout.tsx; nothing else depends on it.