# Fern Design The design system behind buildwithfern.com. This document is the canonical, machine-readable description of our brand and UI tokens. It mirrors the design tokens that drive the site and is meant to be read by both designers and agents. ## Brand - **Name:** Fern (a Postman company). - **Wordmark:** "Fern" set in GT Planar. Never restyle, recolor, or add effects to the wordmark. - **Brand color:** Fern green. The vivid mark is `#70E155`; the accessible text/accent step is `#008700` in light mode and `#9CDD8D` in dark mode (exposed as the `brand` token). - **Voice:** Clear, confident, developer-oriented. Lead with the problem solved or the outcome unlocked. No em-dashes, no future hedging, no unqualified "10x". AI features are always named (Ask Fern, MCP server, llms.txt), never abstracted as "AI-powered". - **Brand assets:** Logos, colors, and the wordmark are on Brandfetch: . ## Colors Components reference the semantic token name (`bg-background`, `text-muted-foreground`, `border-border`), never the literal value. Each token resolves to a different value per theme. Values are stored as `oklch()` (a few as hex) and are P3-aware: wide-gamut displays get `color(display-p3 …)` automatically. Each line below is commented with the color it renders as and its sRGB hex, since `oklch()` is hard to read at a glance. ```css /* Light theme */ --background: oklch(0.977 0 0); /* #F7F7F7 off-white, page surface */ --foreground: #202020; /* near-black, body text (Radix gray-12) */ --card: oklch(1 0 0); /* #FFFFFF white, raised surfaces */ --card-foreground: oklch(0.145 0 0); /* #0A0A0A near-black, text on cards */ --popover: oklch(1 0 0); /* #FFFFFF white */ --popover-foreground: oklch(0.145 0 0); /* #0A0A0A near-black */ --primary: oklch(0.205 0 0); /* #171717 charcoal, primary buttons, emphasis */ --primary-foreground: oklch(0.985 0 0); /* #FAFAFA near-white */ --secondary: oklch(0.97 0 0); /* #F5F5F5 off-white grey, quiet fills */ --secondary-foreground: oklch(0.205 0 0); /* #171717 charcoal */ --muted: var(--radix-gray-2); /* #F9F9FB palest cool grey */ --muted-foreground: oklch(0.556 0 0); /* #737373 mid grey, secondary / caption text */ --accent: oklch(0.97 0 0); /* #F5F5F5 off-white grey, hover states */ --accent-foreground: oklch(0.205 0 0); /* #171717 charcoal */ --brand: #008700; /* deep green, Fern accent (Radix green-11) */ --destructive: oklch(0.577 0.245 27.325); /* #E7000B red, errors and delete actions */ --border: oklch(0.92 0 0); /* #E4E4E4 light grey, hairlines (~9% black over bg) */ --input: oklch(0.922 0 0); /* #E5E5E5 light grey, field outlines */ --ring: oklch(0.708 0 0); /* #A1A1A1 light-mid grey, focus ring */ --pattern: oklch(0.83 0 0); /* #C7C7C7 mid-light grey, dot/grid/soil fields */ --pattern-highlight: #000000; /* black */ --radius: 0.625rem; /* 10px base radius (not a color) */ /* Dark theme */ --background: oklch(0.145 0 0); /* #0A0A0A near-black, page surface */ --foreground: #eeeeee; /* near-white, body text (Radix gray-12 dark) */ --card: oklch(0.205 0 0); /* #171717 charcoal, raised surfaces */ --card-foreground: oklch(0.985 0 0); /* #FAFAFA near-white, text on cards */ --popover: oklch(0.205 0 0); /* #171717 charcoal */ --popover-foreground: oklch(0.985 0 0); /* #FAFAFA near-white */ --primary: oklch(0.922 0 0); /* #E5E5E5 light grey, primary buttons, emphasis */ --primary-foreground: oklch(0.205 0 0); /* #171717 charcoal */ --secondary: oklch(0.269 0 0); /* #262626 near-black grey, quiet fills */ --secondary-foreground: oklch(0.985 0 0); /* #FAFAFA near-white */ --muted: var(--radix-gray-2); /* #18191B near-black cool grey, darker than the light-theme step */ --muted-foreground: oklch(0.708 0 0); /* #A1A1A1 light-mid grey, secondary / caption text */ --accent: oklch(0.269 0 0); /* #262626 near-black grey, hover states */ --accent-foreground: oklch(0.985 0 0); /* #FAFAFA near-white */ --brand: #9CDD8D; /* pale green, Fern accent dark-mode step */ --destructive: oklch(0.704 0.191 22.216); /* #FF6467 light red, errors and delete actions */ --border: oklch(0.265 0 0); /* #252525 dark grey, hairlines (~9% white over dark bg) */ --input: oklch(1 0 0 / 15%); /* #FFFFFF at 15%, field outlines */ --ring: oklch(0.556 0 0); /* #737373 mid grey, focus ring */ --pattern: oklch(0.325 0 0); /* #343434 mid-dark grey, dot/grid/soil fields */ --pattern-highlight: #ffffff; /* white */ ``` ### Fern green scale The brand green is the Radix green scale. `green-9` is the vivid mark; `green-11` is the legible text/accent step the `brand` token points at. ```css /* Light */ /* Dark */ --radix-green-1: #FAFEF9; /* #0E120E */ --radix-green-2: #F3FCF1; /* #141A13 */ --radix-green-3: #DBFDD3; /* #1E291C */ --radix-green-9: #70E155; /* #ABF39B — vivid Fern mark */ --radix-green-11: #008700; /* #9CDD8D — accent text (= --brand) */ --radix-green-12: #17450A; /* #D2F5CA */ ``` The neutral scale is Radix **slate**, a 12-step P3-aware grayscale (`--slate-1` … `--slate-12`) used for surfaces, borders, and text tints across both themes. ## Typography Two families, both loaded locally: - **Sans (default + headings):** GT Planar, six weights (100, 300, 400, 500, 700, 900) with matching italics. Intermediate weights are not loaded and fall back to the nearest cut. Licensed from Grilli Type: . - **Mono:** Berkeley Mono. Used for code, terminals, and anything that signals "machine". Licensed from U.S. Graphics Company: . Both faces are commercial and require a license to use. Don't redownload them from the site; obtain them from the foundries above. Each type token bundles size, line-height, letter-spacing, and weight, so a single class applies all four. | Token | Size | Weight | Use | |---|---|---|---| | `text-h1` | 48px | 400 | Page titles and heroes (auto on `

`) | | `text-h2` | 36px | 400 | Section titles (auto on `

`) | | `text-h3` | 24px | 400 | Subsections (auto on `

`) | | `text-p-large` | 24px | 300 | Hero subtitle | | `text-p` | 20px | 300 | Default body copy | | `text-p-small` | 16px | 300 | Secondary / dense copy | | `text-p-x-small` | 14px | 300 | Captions, footnotes, micro-copy | Headings run 24 → 36 → 48. `h1` is the top of the scale and doubles as the hero size; there is no separate display step. h1 and h2 use `-0.04em` tracking; h3 uses `-0.02em`. The raw tokens (1280px+ desktop scale): ```css --text-h1: 3rem; /* 48px */ line-height: 1.15; letter-spacing: -0.04em; weight: 400; --text-h2: 2.25rem; /* 36px */ line-height: normal; letter-spacing: -0.04em; weight: 400; --text-h3: 1.5rem; /* 24px */ line-height: normal; letter-spacing: -0.02em; weight: 400; --text-p-large: 1.5rem; /* 24px */ line-height: 1.3; letter-spacing: -0.01em; weight: 300; --text-p: 1.25rem; /* 20px */ line-height: 1.5; letter-spacing: -0.01em; weight: 300; --text-p-small: 1rem; /* 16px */ line-height: 1.6; weight: 300; --text-p-x-small: 0.875rem; /* 14px */ line-height: 1.4; weight: 300; ``` Don't override headings with ad-hoc `text-3xl font-semibold` utilities; use the semantic level or a `text-*` token. List markers render as squares site-wide. ## Layout - **Grid max width:** `86rem` (1376px), exposed as `--grid-max-w`. Content is centered within this rail; full-bleed sections expand past it deliberately. - **`xl` breakpoint:** `86rem`. - **Spacing:** Tailwind's 4px-based scale. Sections breathe; dense UI is the exception, not the default. ## Shape & elevation - **Radius scale:** `--radius` is `0.625rem` (10px); the scale multiplies it. ```css --radius-sm: calc(var(--radius) * 0.6); /* 6px */ --radius-md: calc(var(--radius) * 0.8); /* 8px */ --radius-lg: var(--radius); /* 10px */ --radius-xl: calc(var(--radius) * 1.4); /* 14px */ --radius-2xl: calc(var(--radius) * 1.8); /* 18px */ --radius-3xl: calc(var(--radius) * 2.2); /* 22px */ --radius-4xl: calc(var(--radius) * 2.6); /* 26px */ ``` - **Elevation:** Depth is communicated with hairline borders and a subtle inset-frame shadow rather than heavy drop shadows. Light mode uses a soft drop shadow plus a 1px outline; dark mode adds a 1px top highlight, which is omitted in light mode because white tints are invisible there. Raised panels read as "lifted off" the gray background. ## Motion - Easing favors `cubic-bezier(0.16, 1, 0.3, 1)` for entrances (fast in, soft settle). - Motion is purposeful: reveals, gentle pulses, and continuous tickers for logos. Durations run ~0.5s for UI transitions and longer for ambient loops. - Respect reduced-motion preferences. ## Components Built on shadcn/ui + Radix primitives with Tailwind v4. Buttons, dialogs, dropdowns, and inputs are composed from headless primitives and styled with the tokens above. New interactive UI uses these primitives rather than bespoke markup. ## Do's and don'ts - **Do** use semantic tokens (`bg-background`, `text-h2`, `rounded-lg`). - **Do** add a new token in globals.css when a genuinely new value is needed. - **Don't** write raw values like `bg-[#f9f9f9]` or `text-3xl font-semibold` when a token exists. - **Don't** restyle the wordmark or apply the brand green to large fills; keep it to accents. - **Don't** introduce a new dependency or pre-styled component kit without a clear reason the existing stack can't cover. ## Get in touch - Site: - Brand assets: - Careers: - Support: