ElevenLabs
MIT
Modern SaaS design system with pill-shaped components, custom Waldenburg typography, and a light eggshell aesthetic suited for developer tools and voice-tech platforms
Layout StudioImport this kit into a Studio project and start editing.
CLI installRun it in any project. No account needed.
npx @layoutdesign/context install elevenlabs# ElevenLabs Design System — layout.md
---
## 0. Quick Reference
**Stack:** Next.js · Tailwind CSS · shadcn/ui · Token source: extracted-css-vars (388 properties, high confidence)
**How to apply:** Use as `var(--token-name)` in CSS, `style={{ prop: 'var(--token-name)' }}` in JSX, or `bg-[var(--token-name)]` in Tailwind.
```css
/* ── Core Colour Tokens ── */
--black: #000; /* Primary text, primary button bg */
--white-50: #FFF; /* Inverse text, light surface */
--page-background-color: #FDFCFC; /* App-level background (eggshell white) */
--neutral-200: #DCDCDC; /* Subtle dividers */
--neutral-400: #949494; /* Placeholder / muted text */
--neutral-600: #6E6E6E; /* Secondary text */
--shadcn-border: 0 0% 89.8%; /* Default border (HSL — wrap in hsl()) */
--shadcn-destructive: 0 84.2% 60.2%; /* Error / destructive (HSL) */
--orange-500: #F36F1C; /* Accent hover / highlight colour */
/* ── Typography ── */
--font-waldenburg: "Waldenburg", "Waldenburg Fallback", sans-serif; /* Display, headings, UI labels */
--font-waldenburg-fh: "WaldenburgFH", "WaldenburgFH Fallback", sans-serif; /* Bold condensed UI */
--font-inter: "Inter", "Inter Fallback", sans-serif; /* Body, paragraphs, descriptions */
/* ── Spacing ── */
--space-xs: 6px; --space-sm: 8px; --space-md: 12px;
--space-lg: 16px; --space-xl: 24px; --space-2xl: 32px; --space-3xl: 48px;
/* ── Radius (pill-first brand) ── */
--radius-sm: 18px; /* Tag / chip */
--radius-md: 50px; /* Standard button — pill */
--radius-full: 100px; /* Toggle / badge */
/* ── Motion ── */
--duration-fast: 0.15s; --duration-base: 0.3s; --ease-default: ease;
/* ── Layout ── */
--container-width: min(100%, 81.5rem);
--contextual-nav-height: 4rem;
```
```tsx
// Primary button — correct token usage
<button
className="rounded-full bg-black text-white px-6 py-3 font-bold
transition-colors duration-[0.15s] ease-[ease]
hover:bg-[var(--neutral-800)] focus-visible:outline
focus-visible:outline-[var(--black)] disabled:opacity-40
disabled:cursor-default"
style={{ fontFamily: 'var(--font-waldenburg-fh)', letterSpacing: '0.03em' }}
>
Get Started
</button>
```
**NEVER rules:**
1. NEVER use `font-family: Inter` or `font-family: Arial` for headings — Waldenburg is the brand display face
2. NEVER apply `border-radius: 8px` to buttons — ElevenLabs uses pill-shaped buttons (`--radius-md: 50px`)
3. NEVER hardcode `#000000` or `#ffffff` — use `var(--black)` and `var(--white-50)`
4. NEVER use spacing values off the token scale (6 / 8 / 12 / 16 / 24 / 32 / 48px)
5. NEVER use `hsl()` values from shadcn tokens as raw hex — always wrap: `hsl(var(--shadcn-border))`
6. NEVER construct Tailwind classes dynamically (e.g. `` `bg-${color}` ``) — use `bg-[var(--token)]` instead
7. NEVER omit hover, focus-visible, and disabled states on interactive elements
**Full design system → see layout.md**
---
## 1. Design Direction & Philosophy
### Character & Mood
ElevenLabs presents as a **precision-engineered, technology-forward AI platform** with a restrained editorial aesthetic. The visual language is confident and minimal — black on near-white, large typographic hierarchies, generous whitespace, and controlled use of accent colour. The tone is professional but approachable: a research-grade product that does not feel cold.
### Typographic Identity
The brand's most distinctive choice is **Waldenburg** — a custom-licensed German grotesque. Three variants are in use:
- **Waldenburg** (300, 400, 700) — editorial headings, body-adjacent subheads
- **WaldenburgFH** (700 condensed) — bold UI labels, CTA copy, navigation, uppercase UI elements
- **Inter** (variable 100–900) — body copy, paragraph text, descriptions, form fields
This dual-typeface system creates a clear hierarchy: Waldenburg for *brand voice*, Inter for *reading comfort*.
### What This Design Explicitly Rejects
- **Rounded cards with drop shadows** — surfaces are flat or very subtly elevated; cards use thin borders, not shadows
- **Bright brand colour as background** — the primary palette is achromatic; colour appears as small accents, status indicators, or data visualisation only
- **Heavy button fills in the hero** — CTAs use pill outlines or dark fills, never colourful fills as primary brand expression
- **Warm, friendly rounded corners** — even though pill buttons are used, they signal *precision* not playfulness; no 8px card radius
- **Decorative gradients** — any gradient use is subtle and purposeful (e.g. audio waveform visualisations)
- **Dense information hierarchy** — sections breathe; large type, large whitespace, few elements per visual zone
### What This Design Does
- Uses **uppercase small-caps UI labels** (WaldenburgFH, `letter-spacing: 0.03em–0.05em`) to organise UI chrome
- Uses **scale transforms on hover** (1.02×–1.075×) instead of colour shifts as primary interactive feedback
- Applies **negative letter-spacing** on large headings (`-0.02em` to `-0.03em`) for tight, editorial display type
- Reserves **orange** (`--orange-500: #F36F1C`) as the single warm accent — used sparingly for hover states and highlights
---
## 2. Colour System
### Tier 1 — Primitive Palette
```css
/* ── Neutrals ── */
--black: #000;
--white-50: #FFF;
--white-200: #F5F3F1;
--eggshell: #FDFCFC; /* = --page-background-color */
--neutral-50: #F2F2F2;
--neutral-100: #E5E5E5;
--neutral-200: #DCDCDC;
--neutral-300: #BDBDBD;
--neutral-400: #949494;
--neutral-500: #767676;
--neutral-600: #6E6E6E;
--neutral-700: #525252;
--neutral-800: #464646;
--neutral-900: #3D3D3D;
--neutral-950: #1C1C1C;
/* ── Orange (primary accent) ── */
--orange-50: #FFF7ED;
--orange-100: #FEECD6;
--orange-200: #FCD5AC;
--orange-300: #F9B778;
--orange-400: #F58633;
--orange-500: #F36F1C; /* KEY: accent hover / highlight */
--orange-600: #E45512;
--orange-700: #BD3F11;
--orange-800: #963316;
--orange-900: #792C15;
--orange-950: #492104;
/* ── Blue ── */
--blue-50: #F2F5FC; --blue-100: #E1E8F9; --blue-200: #C8D5F4;
--blue-300: #A1BAEC; --blue-400: #7294E3; --blue-500: #5D79DF;
--blue-600: #4056CE; --blue-700: #3C48B9; --blue-800: #384094;
--blue-900: #353B73; --blue-950: #252846;
/* ── Green ── */
--green-50: #ECFDF4; --green-100: #D1FAE3; --green-200: #A7F3CC;
--green-300: #6EE7B1; --green-400: #2DD28D; --green-500: #10B978;
--green-600: #059661; --green-700: #047851; --green-800: #065F41;
--green-900: #064E37; --green-950: #022C20;
/* ── Red ── */
--red-50: #FEF3F2; --red-100: #FDE4E3; --red-200: #FDCDCB;
--red-300: #FAABA7; --red-400: #F57A74; --red-500: #EB524B;
--red-600: #D7332B; --red-700: #B52720; --red-800: #96231E;
--red-900: #7D231F; --red-950: #440D0B;
/* ── Yellow ── */
--yellow-50: #FCFCEA; --yellow-100: #FAF9C7; --yellow-200: #F6F092;
--yellow-300: #EFDE44; --yellow-400: #EACE25; --yellow-500: #DAB718;
--yellow-600: #BC8F12; --yellow-700: #966812; --yellow-800: #7D5316;
--yellow-900: #6A4419; --yellow-950: #3E240A;
/* ── Cyan ── */
--cyan-50: #EEFBFD; --cyan-100: #D3F4FA; --cyan-200: #ADEAF4;
--cyan-300: #74D9EC; --cyan-400: #4EC7E0; --cyan-500: #19A2C1;
--cyan-600: #1783A3; --cyan-700: #1A6984; --cyan-800: #1E566C;
--cyan-900: #1D495C; --cyan-950: #0D2F3F;
/* ── Teal ── */
--teal-50: #EAFDF9; --teal-100: #CEF8EF; --teal-200: #9EF0DE;
--teal-300: #66E1CC; --teal-400: #37C8B5; --teal-500: #1FAD9D;
--teal-600: #168D81; --teal-700: #166F67; --teal-800: #165A55;
--teal-900: #174A46; --teal-950: #072C2B;
/* ── Magenta ── */
--magenta-50: #FCF2FB; --magenta-100: #FBE4FB; --magenta-200: #F8D3F5;
--magenta-300: #F0B2EA; --magenta-400: #E273D5; --magenta-500: #D65CC8;
--magenta-600: #B83DA5; --magenta-700: #973086; --magenta-800: #7A296B;
--magenta-900: #642656; --magenta-950: #3F0D35;
/* ── Purple ── */
--purple-50: #FBF6FE; --purple-100: #F6EBFC; --purple-200: #EEDBF9;
--purple-300: #E1BEF4; --purple-400: #CF94EC; --purple-500: #C47DE5;
--purple-600: #A94BD2; --purple-700: #9139B7; --purple-800: #7A3396;
--purple-900: #632A79; --purple-950: #32123E;
/* ── Overlays ── */
--overlay-darker-plus: rgba(0, 0, 0, 0.4);
--transparent: transparent;
--current: currentColor;
--inherit: inherit;
```
### Tier 2 — Semantic Aliases
```css
/* ── Surface & Background ── */
--page-background-color: #FDFCFC; /* App root background — near-white eggshell */
---shadcn-background: 0 0% 100%; /* shadcn component canvas — pure white (use: hsl(var(---shadcn-background))) */
--shadcn-card: 0 0% 100%; /* Card surface (HSL) */
--shadcn-popover: 0 0% 100%; /* Popover / tooltip background (HSL) */
--shadcn-muted: 0 0% 96.1%; /* Muted/secondary surface (HSL) */
/* ── Text ── */
--shadcn-foreground: 0 0% 3.9%; /* Primary text — near-black (HSL) */
--shadcn-card-foreground: 0 0% 3.9%; /* Text on card surfaces (HSL) */
--shadcn-popover-foreground: 0 0% 3.9%; /* Text in popovers (HSL) */
--shadcn-muted-foreground: 0 0% 45.1%; /* Subdued / helper text (HSL) */
--shadcn-primary-foreground: 0 0% 98%; /* Text on primary (dark) buttons (HSL) */
--shadcn-secondary-foreground: 0 0% 9%; /* Text on secondary surfaces (HSL) */
--shadcn-accent-foreground: 0 0% 9%; /* Text on accent surfaces (HSL) */
--shadcn-destructive-foreground: 0 0% 98%; /* Text on destructive elements (HSL) */
/* ── Interactive ── */
--shadcn-primary: 0 0% 9%; /* Primary button / action background — near-black (HSL) */
--shadcn-secondary: 0 0% 96.1%; /* Secondary button background (HSL) */
--shadcn-accent: 0 0% 96.1%; /* Accent surface (hover highlight bg) (HSL) */
--shadcn-ring: 0 0% 3.9%; /* Focus ring colour (HSL) */
--shadcn-input: 0 0% 89.8%; /* Input border colour (HSL) */
--shadcn-border: 0 0% 89.8%; /* Default border (HSL) */
/* ── Status ── */
--shadcn-destructive: 0 84.2% 60.2%; /* Error / destructive state (HSL) */
/* success surface → var(--green-50) #ECFDF4 */
/* warning surface → var(--orange-50) #FFF7ED */
/* error surface → var(--red-50) #FEF3F2 */
/* info surface → var(--blue-50) #F2F5FC */
```
### Tier 3 — Component Tokens
```css
/* ── Buttons ── */
/* primary bg */ hsl(var(--shadcn-primary)) /* #171717 near-black */
/* primary text */ hsl(var(--shadcn-primary-foreground)) /* #FAFAFA near-white */
/* primary hover */ var(--neutral-800) /* #464646 */
/* secondary bg */ hsl(var(--shadcn-secondary)) /* #F5F5F5 */
/* secondary text */ hsl(var(--shadcn-secondary-foreground)) /* #171717 */
/* focus ring */ hsl(var(--shadcn-ring)) /* #0A0A0A */
/* ── Form Inputs ── */
/* input border */ hsl(var(--shadcn-input)) /* #E5E5E5 */
/* input bg */ hsl(var(---shadcn-background)) /* #FFFFFF */
/* input text */ hsl(var(--shadcn-foreground)) /* #0A0A0A */
/* ── Nav ── */
/* nav height */ var(--contextual-nav-height) /* 4rem = 64px */
/* nav bg (default)*/ transparent /* scrolls to white */
```
### Colour Roles — Quick Reference Table
| Role | Token | Value |
|---|---|---|
| Page background | `--page-background-color` | `#FDFCFC` |
| Primary action bg | `hsl(var(--shadcn-primary))` | `≈ #171717` |
| Primary action text | `hsl(var(--shadcn-primary-foreground))` | `≈ #FAFAFA` |
| Body text | `var(--black)` | `#000` |
| Muted text | `hsl(var(--shadcn-muted-foreground))` | `≈ #737373` |
| Border default | `hsl(var(--shadcn-border))` | `≈ #E5E5E5` |
| Accent hover | `var(--orange-500)` | `#F36F1C` |
| Destructive | `hsl(var(--shadcn-destructive))` | `≈ #EF4444` |
| Success surface | `var(--green-50)` | `#ECFDF4` |
| Warning surface | `var(--orange-50)` | `#FFF7ED` |
---
## 3. Typography System
### Font Stacks
```css
/* ── Font Family Aliases ── */
--waldenburg: var(--font-waldenburg); /* Waldenburg, "Waldenburg Fallback", sans-serif */
--waldenburgFH: var(--font-waldenburg-fh); /* WaldenburgFH 700 condensed — bold UI chrome */
--jetbrainsMono: var(--font-jetbrains-mono); /* Monospace — code blocks */
--inter: var(--font-inter); /* Inter variable — body copy */
```
### Composite Typography Tokens
Each group bundles font-family + font-size + font-weight + line-height + letter-spacing. NEVER split these apart.
```css
/* ══ DISPLAY ══ */
/* --f-display-01 — Hero display, largest headline */
--f-display-01-font-family: var(--font-waldenburg-fh);
--f-display-01-font-size: 6.25rem; /* 100px */
--f-display-01-font-weight: 700;
--f-display-01-line-height: 95%;
/* letter-spacing: not set — tightly tracked by line-height */
/* --f-display-02 — Secondary display */
--f-display-02-font-family: var(--font-waldenburg-fh);
--f-display-02-font-size: 4rem; /* 64px */
--f-display-02-font-weight: 700;
--f-display-02-line-height: 100%;
/* ══ HEADINGS ══ */
/* --f-heading-01 — Page-level H1 */
--f-heading-01-font-family: var(--font-waldenburg);
--f-heading-01-font-size: 3.75rem; /* 60px */
--f-heading-01-font-weight: 300;
--f-heading-01-line-height: 105%;
--f-heading-01-letter-spacing: -0.03em;
/* --f-heading-02 — Section H2 */
--f-heading-02-font-family: var(--font-waldenburg);
--f-heading-02-font-size: 3rem; /* 48px */
--f-heading-02-font-weight: 300;
--f-heading-02-line-height: 110%;
--f-heading-02-letter-spacing: -0.03em;
/* --f-heading-03 — Sub-section H3 */
--f-heading-03-font-family: var(--font-waldenburg);
--f-heading-03-font-size: 2.25rem; /* 36px */
--f-heading-03-font-weight: 300;
--f-heading-03-line-height: 120%;
--f-heading-03-letter-spacing: -0.02em;
/* --f-heading-04 — Card / feature heading */
--f-heading-04-font-family: var(--font-waldenburg);
--f-heading-04-font-size: 1.5rem; /* 24px */
--f-heading-04-font-weight: 400;
--f-heading-04-line-height: 130%;
--f-heading-04-letter-spacing: -0.01em;
/* --f-heading-05 — Small heading */
--f-heading-05-font-family: var(--font-waldenburg);
--f-heading-05-font-size: 1.25rem; /* 20px */
--f-heading-05-font-weight: 400;
--f-heading-05-line-height: 135%;
--f-heading-05-letter-spacing: 0em;
/* ══ SUBHEADS ══ */
/* --f-subhead-01 — Bold section label, large */
--f-subhead-01-font-family: var(--font-waldenburg);
--f-subhead-01-font-size: 1.375rem; /* 22px */
--f-subhead-01-font-weight: 700;
--f-subhead-01-line-height: 140%;
--f-subhead-01-letter-spacing: 0.01em;
/* --f-subhead-02 — Bold section label, medium */
--f-subhead-02-font-family: var(--font-waldenburg);
--f-subhead-02-font-size: 1.125rem; /* 18px */
--f-subhead-02-font-weight: 700;
--f-subhead-02-line-height: 140%;
--f-subhead-02-letter-spacing: 0.01em;
/* --f-subhead-03 — Bold label, base */
--f-subhead-03-font-family: var(--font-waldenburg);
--f-subhead-03-font-size: 1rem; /* 16px */
--f-subhead-03-font-weight: 700;
--f-subhead-03-line-height: 140%;
--f-subhead-03-letter-spacing: 0.01em;
/* --f-subhead-04 — Regular label, base */
--f-subhead-04-font-family: var(--font-waldenburg);
--f-subhead-04-font-size: 1rem;
--f-subhead-04-font-weight: 400;
--f-subhead-04-line-height: 140%;
/* --f-subhead-05 — Small label */
--f-subhead-05-font-family: var(--font-waldenburg);
--f-subhead-05-font-size: 0.875rem; /* 14px */
--f-subhead-05-font-weight: 400;
--f-subhead-05-line-height: 120%;
/* ══ DESCRIPTIONS ══ */
/* --f-description-01 — Lead / intro text, Waldenburg */
--f-description-01-font-family: var(--font-waldenburg);
--f-description-01-font-size: 1.375rem; /* 22px */
--f-description-01-font-weight: 400;
--f-description-01-line-height: 130%;
--f-description-01-letter-spacing: -0.02em;
/* --f-description-02 — Supporting text, Inter */
--f-description-02-font-family: var(--font-inter);
--f-description-02-font-size: 1.125rem; /* 18px */
--f-description-02-font-weight: 400;
--f-description-02-line-height: 140%;
--f-description-02-letter-spacing: 0.01em;
/* --f-description-03 — Base description, Inter */
--f-description-03-font-family: var(--font-inter);
--f-description-03-font-size: 1rem;
--f-description-03-font-weight: 400;
--f-description-03-line-height: 140%;
--f-description-03-letter-spacing: 0.01em;
/* --f-description-04 — Small description, Inter */
--f-description-04-font-family: var(--font-inter);
--f-description-04-font-size: 0.875rem; /* 14px */
--f-description-04-font-weight: 400;
--f-description-04-line-height: 140%;
--f-description-04-letter-spacing: 0.01em;
/* --f-description-05 — Alternate base, Inter */
--f-description-05-font-family: var(--font-inter);
--f-description-05-font-size: 1rem;
--f-description-05-font-weight: 400;
--f-description-05-line-height: 140%;
--f-description-05-letter-spacing: 0.01em;
/* ══ PARAGRAPHS ══ */
/* --f-paragraph-01 — Body copy, large */
--f-paragraph-01-font-family: var(--font-inter);
--f-paragraph-01-font-size: 1.125rem; /* 18px */
--f-paragraph-01-font-weight: 400;
--f-paragraph-01-line-height: 140%;
--f-paragraph-01-letter-spacing: 0em;
/* --f-paragraph-02 — Body copy, base */
--f-paragraph-02-font-family: var(--font-inter);
--f-paragraph-02-font-size: 1rem;
--f-paragraph-02-font-weight: 400;
--f-paragraph-02-line-height: 140%;
--f-paragraph-02-letter-spacing: 0em;
/* --f-paragraph-03 — Body copy, small */
--f-paragraph-03-font-family: var(--font-inter);
--f-paragraph-03-font-size: 0.875rem;
--f-paragraph-03-font-weight: 400;
--f-paragraph-03-line-height: 140%;
--f-paragraph-03-letter-spacing: 0em;
/* --f-paragraph-04 — Body copy, xs */
--f-paragraph-04-font-family: var(--font-inter);
--f-paragraph-04-font-size: 0.75rem; /* 12px */
--f-paragraph-04-font-weight: 400;
--f-paragraph-04-line-height: 140%;
--f-paragraph-04-letter-spacing: 0em;
/* --f-body-01 — Long-form body copy */
--f-body-01-font-family: var(--font-inter);
--f-body-01-font-size: 1.125rem;
--f-body-01-font-weight: 400;
--f-body-01-line-height: 160%; /* Generous for readability */
/* ══ UI LABELS ══ */
/* --f-ui-01 — Primary UI label, uppercase */
--f-ui-01-font-family: var(--font-waldenburg-fh);
--f-ui-01-font-size: 1.125rem;
--f-ui-01-font-weight: 700;
--f-ui-01-line-height: 110%;
--f-ui-01-letter-spacing: 0.03em;
--f-ui-01-text-transform: uppercase;
/* --f-ui-02 — Secondary UI label, Inter */
--f-ui-02-font-family: var(--font-inter);
--f-ui-02-font-size: 0.875rem;
--f-ui-02-font-weight: 400;
--f-ui-02-line-height: 140%;
--f-ui-02-letter-spacing: 0.02em;
/* --f-ui-03 — Condensed uppercase label */
--f-ui-03-font-family: var(--font-waldenburg-fh);
--f-ui-03-font-size: 0.875rem;
--f-ui-03-font-weight: 700;
--f-ui-03-line-height: 110%;
--f-ui-03-letter-spacing: 0.05em;
--f-ui-03-text-transform: uppercase;
/* --f-ui-04 — Smallest uppercase label */
--f-ui-04-font-family: var(--font-waldenburg-fh);
--f-ui-04-font-size: 0.75rem;
--f-ui-04-font-weight: 700;
--f-ui-04-line-height: 110%;
--f-ui-04-letter-spacing: 0.05em;
--f-ui-04-text-transform: uppercase;
/* --f-ui-05 — Small Inter label */
--f-ui-05-font-family: var(--font-inter);
--f-ui-05-font-size: 0.75rem;
--f-ui-05-font-weight: 400;
--f-ui-05-line-height: 140%;
--f-ui-05-letter-spacing: 0.02em;
/* --f-ui-06 — WaldenburgFH, small */
--f-ui-06-font-family: var(--font-waldenburg-fh);
--f-ui-06-font-size: 0.875rem;
--f-ui-06-font-weight: 700;
--f-ui-06-line-height: 110%;
--f-ui-06-letter-spacing: 0.05em;
/* --f-ui-07 — Micro label */
--f-ui-07-font-family: var(--font-inter);
--f-ui-07-font-size: 0.625rem; /* 10px */
--f-ui-07-font-weight: 400;
--f-ui-07-line-height: 140%;
--f-ui-07-letter-spacing: 0.02em;
/* --f-ui-08 — Micro Inter */
--f-ui-08-font-family: var(--font-inter);
--f-ui-08-font-size: 0.75rem;
--f-ui-08-font-weight: 400;
--f-ui-08-line-height: 140%;
/* ══ BLOG ══ */
/* --f-description-blog — Blog description */
--f-description-blog-font-family: var(--font-inter);
--f-description-blog-font-size: 1.0625rem; /* 17px */
--f-description-blog-font-weight: 400;
--f-description-blog-line-height: 30px;
--f-description-blog-letter-spacing: 0.01em;
/* --f-body-blog — Blog body */
--f-body-blog-font-family: var(--font-inter);
--f-body-blog-font-size: 1.0625rem;
--f-body-blog-font-weight: 400;
--f-body-blog-line-height: 30px;
```
### Typography Pairing Rules
| Context | Token to use | Why |
|---|---|---|
| Hero / display headline | `--f-display-01` or `--f-heading-01` | WaldenburgFH 700 or Waldenburg 300 |
| Section headings (H2) | `--f-heading-02` / `--f-heading-03` | Waldenburg light-weight, negative tracking |
| Feature card titles | `--f-heading-04` / `--f-heading-05` | Waldenburg regular |
| Body / paragraphs | `--f-paragraph-01` – `--f-paragraph-03` | Inter for reading comfort |
| CTA button text | `--f-ui-01` | WaldenburgFH 700, uppercase, 0.03em tracking |
| Navigation links | `--f-ui-03` / `--f-ui-04` | WaldenburgFH 700 uppercase |
| Helper / caption | `--f-ui-05` / `--f-ui-07` | Inter, small, positive tracking |
| Code blocks | `var(--jetbrainsMono)` | Never use Inter for code |
**NEVER use Inter for display headings.** The Waldenburg–Inter split is the fundamental brand typeface rule.
---
## 4. Spacing & Layout
```css
/* ── Spacing Scale ── */
--space-xs: 6px; /* Tight internal padding (icon gaps, badge padding) */
--space-sm: 8px; /* Input internal padding, small gaps */
--space-md: 12px; /* Component internal padding standard */
--space-lg: 16px; /* Section element gap, card internal padding */
--space-xl: 24px; /* Between related components */
--space-2xl: 32px; /* Between sections internally */
--space-3xl: 48px; /* Between major sections */
/* ── Layout Container ── */
--container-width: min(100%, 81.5rem); /* Max 1304px, full below */
--container-width-absolute: min(100vw, 81.5rem); /* VW-based variant */
/* ── Gutters ── */
--spacing-outer-gutter: 4rem; /* 64px — outer page margin */
--spacing-inner-gutter: 1.25rem; /* 20px — internal column gap */
--spacing-container-gutter: 0.625rem; /* 10px — tight container padding */
--spacing-outer-content: 6.25rem; /* 100px — vertical section padding */
--spacing-content-wide: 10rem; /* 160px — wide content inset */
--spacing-content-xwide: 12.5rem; /* 200px — extra-wide content inset */
/* ── Raw Gutter Aliases (from computed) ── */
--inner-gutter: 20px; /* = --spacing-inner-gutter */
--outer-gutter: 64px; /* = --spacing-outer-gutter */
/* ── Grid ── */
--grid-columns: 12; /* 12-column grid */
/* ── Nav ── */
--contextual-nav-height: 4rem; /* 64px — sticky nav height */
/* ── Radius ── */
--radius-sm: 18px; /* Chip / tag pill */
--radius-md: 50px; /* Standard button pill — BRAND DEFAULT */
--radius-lg: 50%; /* Circular (avatar, orb button) */
--radius-full: 100px; /* Toggle / badge full-pill */
--shadcn-radius: 0.5rem; /* 8px — shadcn component default (override as needed) */
```
### Breakpoints
| Name | Value | Notes |
|---|---|---|
| `sm` | `480px` | Mobile → narrow viewport |
| `lg` | `1024px` | Tablet / desktop threshold |
### Layout Decision Rules
- **Flex row** for nav items, button groups, icon+label pairs, card rows
- **CSS Grid 12-col** for page-level section layouts (use `--grid-columns: 12`)
- **Full-width** hero and media sections; **contained** (`--container-width`) for text content
- **Outer gutter** (`--outer-gutter: 64px`) applied to left/right of the container at desktop
- Below `480px`: collapse multi-column to single column; reduce outer gutter to `--space-lg` (16px)
- Between `480px` and `1024px`: 2-column grid for feature cards
---
## 5. Page Structure & Layout Patterns
> **Note:** No page screenshots were supplied. All section ordering and layout details below are inferred from the layout digest, component inventory, computed styles, and CSS variable analysis. Rows marked **(inferred)** are probable but not visually confirmed.
### 5.1 Section Map
| # | Section | Layout Type | Approx. Height | Key Elements |
|---|---|---|---|---|
| 1 | Nav / Header | Flex row, sticky | 64px (`--contextual-nav-height`) | Logo, nav links (WaldenburgFH uppercase), CTA button (pill) |
| 2 | Hero | Full-width, centred column | ~80–100vh (inferred) | Display headline (f-display-01/f-heading-01), sub-description (f-description-01), CTA button pair (inferred) |
| 3 | Social Proof / Logos | Contained, flex row | ~120px (inferred) | "Trusted by" label + logo strip; auto-scrolling (inferred from `animated-social-proof-text`) |
| 4 | Feature Grid — ElevenCreative / ElevenAgents | 2-col or 3-col grid, contained | ~600px (inferred) | Feature cards with chip labels (radius-sm 18px), icon, heading (f-heading-04), description (f-description-03) |
| 5 | Product Showcase — Text to Speech / API | Alternating 2-col (text + visual), contained | ~500px per row (inferred) | Section heading (f-heading-02), paragraph (f-paragraph-01), CTA link, product visual/demo |
| 6 | Tabbed Product Demo | Contained, tab navigation + panel | ~600px (inferred) | Tabs (WaldenburgHF, 16px/700, 18px padding), demo canvas |
| 7 | Blog / News Cards | 3-col grid, contained | ~500px (inferred) | Card image, heading (f-heading-04/f-heading-05), blog description (f-description-blog), date meta (f-ui-05) |
| 8 | CTA Banner | Full-width, centred | ~300px (inferred) | Large display heading, primary CTA button (black fill, pill, white text) |
| 9 | Footer | 4–5 col grid, contained | ~300px (inferred) | Logo, nav link columns (f-ui-03 uppercase), legal copy (f-ui-05) |
### 5.2 Layout Patterns
**Navigation:**
- `display: block` (role_navigation computed), full-width bar
- Items: flex row, centred vertically, gap: `--space-lg` (16px)
- Height fixed at `var(--contextual-nav-height)` = 4rem
- CTA button: `border-radius: 9999px` (pill), `padding: 6px` inner, positioned right-most
**Feature Cards:**
- Grid: 3 columns at 1024px+, 2 columns at 480–1024px, 1 column below 480px
- Card padding: `--space-xl` (24px) internal
- Chip / category label: `border-radius: var(--radius-sm)` = 18px, `padding: var(--space-sm) var(--space-md)` (8px 12px)
- Heading: `--f-heading-04` (Waldenburg 400, 1.5rem, -0.01em tracking)
- Gap between cards: `--space-xl` (24px)
**Section Text Blocks:**
- Max-width constrained to `--container-width` with `--outer-gutter` side margins
- Section heading: `--f-heading-02` or `--f-heading-03`
- Body text: `--f-paragraph-01` or `--f-description-02`
- Vertical rhythm between heading and body: `--space-xl` (24px)
**Alternating Content Rows:**
- 2-column flex, `gap: --space-2xl` (32px) or `--space-3xl` (48px)
- Column ratio: approximately 50/50 or 55/45 (inferred — no visual confirmation)
- Odd rows: text left, visual right; even rows: visual left, text right (inferred)
### 5.3 Visual Hierarchy
- **H1 at computed 48px, weight 300 (Waldenburg light)** — large, editorial, negative-tracked. This is deliberately un-bold.
- **CTAs are black-fill pill buttons** with near-white text — high contrast, not colourful
- **Orange (`--orange-500: #F36F1C`)** appears only on hover states and accent highlights — never as a fill on primary CTAs
- **Scale transforms** (hover:scale-105, hover:scale-[1.02]) are used as primary interactive feedback instead of colour change
- **Whitespace rhythm:** sections separated by `--spacing-outer-content: 6.25rem` (100px) vertical padding
- **Chip labels** (18px radius) categorise feature cards and appear above headings
- **Logo strip** uses muted/greyscale treatment (inferred from "trusted by leading" social proof pattern)
### 5.4 Content Patterns
**Feature Card Pattern (repeating):**
```
[Category Chip — WaldenburgFH uppercase, radius-sm]
[Heading — f-heading-04, Waldenburg 400]
[Description — f-description-03, Inter 400]
[Optional CTA link — f-ui-02 or inline text link]
```
**Section Header Pattern (repeating):**
```
[Eyebrow label — f-ui-03, WaldenburgFH, uppercase, orange or black]
[H2 Heading — f-heading-02 or f-heading-03, Waldenburg 300]
[Sub-description — f-description-01 or f-paragraph-01, Inter]
[CTA button or link]
```
**Blog Card Pattern:**
```
[Image — hover:scale-1.075 zoom effect]
[Date meta — f-ui-05, Inter, neutral-400]
[Title — f-heading-04 or f-heading-05]
[Excerpt — f-description-blog, Inter 17px]
```
---
## 6. Component Patterns
### 6.1 Button
**Anatomy:** `[leading icon?] [label text] [trailing icon?]`
**Token Mappings:**
| State | Background | Text | Border | Transform |
|---|---|---|---|---|
| default | `hsl(var(--shadcn-primary))` ≈ `#171717` | `hsl(var(--shadcn-primary-foreground))` ≈ `#FAFAFA` | none | scale(1) |
| hover | `var(--neutral-800)` `#464646` | same | none | scale(1) |
| focus-visible | same | same | outline `hsl(var(--shadcn-ring))` 2px offset 2px | same |
| active | `var(--neutral-900)` `#3D3D3D` | same | none | scale(0.98) |
| disabled | `hsl(var(--shadcn-primary))` at 40% opacity | same at 40% | none | none |
| loading | same as default | hidden (spinner shown) | none | none |
**Typography:** `--f-ui-01` (WaldenburgFH 700, 1.125rem, uppercase, 0.03em tracking)
**Radius:** `var(--radius-md)` = 50px (pill)
**Padding:** `--space-md` `--space-xl` = `12px 24px`
**Transition:** `color, background-color, border-color var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1)`
```tsx
import { forwardRef, ButtonHTMLAttributes } from 'react'
import { Loader2 } from 'lucide-react'
import { cn } from '@/lib/utils'
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'outline'
size?: 'sm' | 'md' | 'lg'
isLoading?: boolean
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant = 'primary', size = 'md', isLoading, disabled, children, ...props }, ref) => {
const base = [
'inline-flex items-center justify-center gap-2',
'font-bold uppercase tracking-[0.03em]',
'rounded-[50px]', /* var(--radius-md) */
'transition-[color,background-color,border-color]',
'duration-[0.15s]', /* var(--duration-fast) */
'ease-[ease]', /* var(--ease-default) */
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
'focus-visible:outline-[var(--black)]',
'disabled:opacity-40 disabled:cursor-default',
'active:scale-[0.98]',
]
const variants = {
primary: 'bg-[var(--black)] text-[var(--white-50)] hover:bg-[var(--neutral-800)]',
secondary: 'bg-[hsl(var(--shadcn-secondary))] text-[hsl(var(--shadcn-secondary-foreground))] hover:bg-[var(--neutral-100)]',
outline: 'bg-transparent text-[var(--black)] border border-[hsl(var(--shadcn-border))] hover:bg-[var(--neutral-50)]',
}
const sizes = {
sm: 'px-[var(--space-md)] py-[var(--space-xs)] text-[0.75rem]', /* 12px 6px */
md: 'px-[var(--space-xl)] py-[var(--space-md)] text-[0.875rem]', /* 24px 12px */
lg: 'px-[var(--space-2xl)] py-[var(--space-lg)] text-[1.125rem]', /* 32px 16px */
}
return (
<button
ref={ref}
disabled={disabled || isLoading}
className={cn(base, variants[variant], sizes[size], className)}
style={{ fontFamily: 'var(--font-waldenburg-fh)' }}
{...props}
>
{isLoading ? (
<>
<Loader2
className="animate-spin"
size={16}
aria-hidden="true"
/>
<span className="sr-only">Loading…</span>
<span aria-hidden="true">{children}</span>
</>
) : children}
</button>
)
}
)
Button.displayName = 'Button'
export default Button
```
---
### 6.2 Input
**Anatomy:** `[label] [input field] [helper text | error message]`
**Token Mappings:**
| State | Border | Background | Text | Label |
|---|---|---|---|---|
| default | `hsl(var(--shadcn-input))` ≈ `#E5E5E5` | `hsl(var(---shadcn-background))` `#FFF` | `var(--black)` | `var(--neutral-600)` |
| hover | `var(--neutral-400)` | same | same | same |
| focus | `hsl(var(--shadcn-ring))` ≈ `#0A0A0A` 2px | same | same | `var(--black)` |
| disabled | `var(--neutral-100)` | `var(--neutral-50)` | `var(--neutral-400)` | `var(--neutral-400)` |
| error | `hsl(var(--shadcn-destructive))` | same | same | `hsl(var(--shadcn-destructive))` |
**Radius:** `var(--radius-sm)` = 18px
**Padding:** `var(--space-sm) var(--space-lg)` = `8px 16px`
**Typography:** `--f-description-03` (Inter 400, 1rem, 0.01em)
```tsx
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
label?: string
error?: string
helperText?: string
}
function Input({ label, error, helperText, disabled, id, ...props }: InputProps) {
return (
<div className="flex flex-col gap-[var(--space-xs)]">
{label && (
<label
htmlFor={id}
className={cn(
'text-[0.875rem] font-medium',
disabled ? 'text-[var(--neutral-400)]' : 'text-[var(--black)]'
)}
style={{ fontFamily: 'var(--font-inter)' }}
>
{label}
</label>
)}
<input
id={id}
disabled={disabled}
className={cn(
'w-full rounded-[18px] px-[var(--space-lg)] py-[var(--space-sm)]',
'border bg-white text-[var(--black)]',
'text-[1rem] leading-[140%] tracking-[0.01em]',
'transition-[border-color] duration-[0.15s] ease-[ease]',
'placeholder:text-[var(--neutral-400)]',
'focus:outline-none focus:border-[var(--black)] focus:ring-0',
'hover:border-[var(--neutral-400)]',
'disabled:bg-[var(--neutral-50)] disabled:border-[var(--neutral-100)]',
'disabled:text-[var(--neutral-400)] disabled:cursor-default',
error
? 'border-[hsl(var(--shadcn-destructive))]'
: 'border-[hsl(var(--shadcn-input))]'
)}
style={{ fontFamily: 'var(--font-inter)' }}
{...props}
/>
{(error || helperText) && (
<p
className={cn(
'text-[0.75rem] leading-[140%] tracking-[0.02em]',
error ? 'text-[hsl(var(--shadcn-destructive))]' : 'text-[var(--neutral-600)]'
)}
style={{ fontFamily: 'var(--font-inter)' }}
role={error ? 'alert' : undefined}
>
{error ?? helperText}
</p>
)}
</div>
)
}
```
---
### 6.3 Nav Item
**Anatomy:** `[icon?] [label text]`
**Token Mappings:**
| State | Text | Background | Transform |
|---|---|---|---|
| default | `var(--black)` | transparent | none |
| hover | `var(--black)` | `rgba(0,0,0,0.05)` | none |
| focus-visible | `var(--black)` | transparent | none; outline `var(--black)` |
| active | `var(--black)` | `rgba(0,0,0,0.1)` | none |
| current (selected) | `var(--black)` | `var(--neutral-50)` | none |
| disabled | `var(--neutral-400)` | transparent | none |
**Typography:** `--f-ui-03` (WaldenburgFH 700, 0.875rem, uppercase, 0.05em)
**Transition:** `background-color var(--duration-fast) var(--ease-default)`
```tsx
interface NavItemProps {
href: string
label: string
isCurrent?: boolean
icon?: React.ReactNode
}
function NavItem({ href, label, isCurrent, icon }: NavItemProps) {
return (
<a
href={href}
aria-current={isCurrent ? 'page' : undefined}
className={cn(
'inline-flex items-center gap-[var(--space-xs)]',
'px-[var(--space-md)] py-[var(--space-sm)]',
'rounded-[var(--radius-sm)]',
'text-[0.875rem] font-bold uppercase tracking-[0.05em]',
'text-[var(--black)] no-underline',
'transition-[background-color] duration-[0.15s] ease-[ease]',
'hover:bg-[rgba(0,0,0,0.05)]',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
'focus-visible:outline-[var(--black)]',
isCurrent && 'bg-[var(--neutral-50)]'
)}
style={{ fontFamily: 'var(--font-waldenburg-fh)' }}
>
{icon && <span aria-hidden="true">{icon}</span>}
{label}
</a>
)
}
```
---
### 6.4 Chip / Category Tag
**Anatomy:** `[label text]`
**Token Mappings:**
| State | Background | Text | Border |
|---|---|---|---|
| default | `var(--neutral-100)` | `var(--black)` | none |
| hover | `var(--neutral-200)` | `var(--black)` | none |
| selected | `var(--black)` | `var(--white-50)` | none |
**Radius:** `var(--radius-sm)` = **18px** (extracted directly — chip elements)
**Padding:** `var(--space-xs) var(--space-md)` = `6px 12px`
**Typography:** `--f-ui-04` (WaldenburgFH 700, 0.75rem, uppercase, 0.05em)
```tsx
function Chip({ label, selected, onClick }: { label: string; selected?: boolean; onClick?: () => void }) {
return (
<button
onClick={onClick}
className={cn(
'inline-flex items-center px-[var(--space-md)] py-[var(--space-xs)]',
'rounded-[18px] text-[0.75rem] font-bold uppercase tracking-[0.05em]',
'transition-[background-color,color] duration-[0.15s] ease-[ease]',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--black)]',
selected
? 'bg-[var(--black)] text-[var(--white-50)]'
: 'bg-[var(--neutral-100)] text-[var(--black)] hover:bg-[var(--neutral-200)]'
)}
style={{ fontFamily: 'var(--font-waldenburg-fh)' }}
>
{label}
</button>
)
}
```
---
### 6.5 Tab
**Anatomy:** `[icon?] [label] [active indicator bar]`
**Token Mappings:**
| State | Text | Border-bottom | Background |
|---|---|---|---|
| default | `var(--neutral-500)` | none | transparent |
| hover | `var(--black)` | `var(--neutral-200)` 2px | transparent |
| active/selected | `var(--black)` | `var(--black)` 2px | transparent |
| focus-visible | `var(--black)` | same + outline | transparent |
**Typography:** WaldenburgHF 700, 16px, 24px line-height, 0.32px tracking (from computed tab styles)
**Padding:** `18px 0px` (vertical padding, no horizontal — width-based spacing)
**Gap:** `8px` between icon and label
---
### 6.6 Feature Card
**Anatomy:** `[category chip] [heading] [description] [optional CTA]`
```tsx
interface FeatureCardProps {
category: string
heading: string
description: string
ctaLabel?: string
ctaHref?: string
}
function FeatureCard({ category, heading, description, ctaLabel, ctaHref }: FeatureCardProps) {
return (
<article
className={cn(
'flex flex-col gap-[var(--space-lg)]',
'p-[var(--space-xl)] rounded-[var(--shadcn-radius)]',
'border border-[hsl(var(--shadcn-border))]',
'bg-[hsl(var(---shadcn-background))]',
'transition-transform duration-[0.15s] ease-[ease]',
'hover:scale-[1.02]'
)}
>
<Chip label={category} />
<h3
className="text-[1.5rem] font-normal leading-[130%] tracking-[-0.01em] text-[var(--black)]"
style={{ fontFamily: 'var(--font-waldenburg)' }}
>
{heading}
</h3>
<p
className="text-[1rem] font-normal leading-[140%] tracking-[0.01em] text-[var(--neutral-600)]"
style={{ fontFamily: 'var(--font-inter)' }}
>
{description}
</p>
{ctaLabel && ctaHref && (
<a
href={ctaHref}
className={cn(
'mt-auto text-[0.875rem] font-bold text-[var(--black)]',
'underline-offset-2 hover:underline',
'transition-colors duration-[0.15s]'
)}
style={{ fontFamily: 'var(--font-waldenburg)' }}
>
{ctaLabel}
</a>
)}
</article>
)
}
```
---
## 7. Elevation & Depth
```css
/* ── Shadows ── */
/* Code block / card with elevation (from computed code element) */
--shadow-card:
rgba(0, 0, 0, 0.4) 0px 0px 1px 0px,
rgba(0, 0, 0, 0.04) 0px 1px 1px 0px,
rgba(0, 0, 0, 0.04) 0px 2px 4px 0px;
/* Extracted: high confidence — from code element computed style */
/* Overlay backdrop */
--overlay-darker-plus: rgba(0, 0, 0, 0.4); /* Modal backdrop, overlays */
/* ── Borders ── */
/* Default element border */
border: 1px solid hsl(var(--shadcn-border)); /* ≈ #E5E5E5 */
/* Input border */
border: 1px solid hsl(var(--shadcn-input)); /* ≈ #E5E5E5 */
/* Hover border (dark) */
border: 1px solid rgba(0, 0, 0, 0.6); /* .hover:border-overlay-darkest */
/* ── Z-Index Scale ── (reconstructed: moderate confidence) */
--z-base: 0; /* Normal flow */
--z-raised: 10; /* Cards, tooltips within a section */
--z-overlay: 100; /* Drawers, dropdowns */
--z-modal: 200; /* Modal dialogs */
--z-nav: 300; /* Sticky navigation — always on top */
--z-toast: 400; /* Toast notifications */
```
### Layering Principles
- ElevenLabs uses **flat surfaces** as the primary treatment — cards use thin borders (`1px solid hsl(var(--shadcn-border))`), not heavy shadows
- **Shadow is used sparingly** — only the `--shadow-card` value (subtle 3-layer spread) is confirmed from extracted elements
- **Backdrop filters** are not used in the base UI (computed `backdropFilter: none` across all elements)
- **Scale transforms** (`hover:scale-[1.02]` to `hover:scale-[1.075]`) provide the depth/lift effect instead of shadow-on-hover
---
## 8. Motion
```css
/* ── Duration Tokens ── */
--duration-fast: 0.15s; /* Colour / bg transitions on interactive elements */
--duration-base: 0.3s; /* General UI transitions, panel open/close */
--duration-slow: 0.36s; /* Larger layout transitions (div elements) */
/* ── Easing ── */
--ease-default: ease; /* Default for most transitions */
/* Note: interactive button transitions use cubic-bezier(0.4, 0, 0.2, 1) explicitly */
/* ── Standard Transition (button / interactive) ── */
/* Extracted from role_button computed styles */
transition:
color var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1),
background-color var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1),
border-color var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1),
text-decoration-color var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1),
fill var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1),
stroke var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1);
/* Checkbox/toggle: background 0.2s linear */
transition: background var(--duration-fast) linear;
```
### Keyframe Animations
```css
/* Text reveal — word-by-word blur entrance */
@keyframes text-reveal-word {
0% { opacity: 0; transform: scaleY(0.95) scaleX(0.92); filter: blur(12px); }
15% { opacity: 0.1; }
40% { transform: scaleY(1) scaleX(1); }
60% { transform: scaleY(1) scaleX(1); filter: blur(0px); }
100% { transform: scaleY(1) scaleX(1); filter: blur(0px); opacity: 1; }
}
/* Fade in — simple opacity */
@keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
/* Horizontal slide with blur — demo/showcase elements */
@keyframes ds-slide {
0% { transform: translateX(-150%) scale(var(--ds-scale)); filter: blur(20px); }
15% { filter: blur(0px); }
85% { filter: blur(0px); }
100% { transform: translateX(calc(100vw)) scale(var(--ds-scale)); filter: blur(20px); }
}
/* Translate Y entrance */
@keyframes fadeTranslateYIn {
0% { opacity: 0; transform: translateY(var(--translate-y-from, 100%)); }
100% { opacity: 1; transform: translateY(0px); }
}
/* Translate X entrance */
@keyframes fadeTranslateXIn {
0% { opacity: 0; transform: translateX(var(--translate-x-from, 100%)); }
100% { opacity: 1; transform: translateX(0px); }
}
/* Pop — subtle scale bounce */
@keyframes pop {
0% { transform: scale(1); }
40% { transform: scale(1.04); }
70% { transform: scale(0.97); }
100% { transform: scale(1); }
}
/* Scale Y fade in */
@keyframes fadeInScaleY {
0% { opacity: 0; transform: scaleY(1.5); }
100% { opacity: 1; transform: scaleY(1); }
}
/* Shimmer text */
@keyframes shimmer-text {
0% { background-position: 100% 0px; }
100% { background-position: -100% 0px; }
}
/* Ping — notification pulse */
@keyframes ping {
75%, 100% { transform: scale(2); opacity: 0; }
}
```
### Motion Rules
- **Scale transforms are the primary hover mechanism** — prefer `hover:scale-[1.02]` for cards, `hover:scale-105` for images
- **Text-reveal-word** is reserved for hero/display text entrances — do not use for body text
- **Reduce motion:** wrap animations in `@media (prefers-reduced-motion: reduce) { animation: none; transition-duration: 0.01ms; }`
- **Never animate layout properties** (`width`, `height`, `margin`) — only transform, opacity, filter, background-color
- `ds-slide` is a specialised full-viewport scroll animation — do not use for standard UI transitions
---
## 9. Anti-Patterns & Constraints
1. **NEVER use `font-family: Inter` for hero headings or section titles → Why it fails:** AI agents default to Inter for all text because it's in the font stack, producing generic-looking SaaS output. The Waldenburg–Inter split is ElevenLabs' core brand differentiator — Waldenburg for headings/labels, Inter for paragraphs only. **What to do instead:** Always check the `--f-{role}-font-family` token — headings use `var(--font-waldenburg)`, UI labels use `var(--font-waldenburg-fh)`, paragraphs use `var(--font-inter)`.
2. **NEVER use `border-radius: 8px` on buttons → Why it fails:** The shadcn default `--shadcn-radius: 0.5rem` (8px) bleeds into button styling when agents copy shadcn patterns, producing rounded-rectangle buttons that contradict the ElevenLabs pill aesthetic. The button radius census clearly shows `50px` (8 elements) is the brand standard. **What to do instead:** Always apply `border-radius: var(--radius-md)` = `50px` (or `rounded-[50px]` in Tailwind) to any primary or secondary button.
3. **NEVER use raw hex from HSL shadcn tokens → Why it fails:** Tokens like `--shadcn-border: 0 0% 89.8%` are stored as bare HSL channel values (no `hsl()` wrapper). An agent that writes `color: var(--shadcn-border)` will output `color: 0 0% 89.8%` — an invalid CSS value that silently fails. **What to do instead:** Always wrap: `hsl(var(--shadcn-border))`, `hsl(var(--shadcn-primary))`, etc.
4. **NEVER construct Tailwind class names dynamically → Why it fails:** Tailwind's JIT compiler only includes classes present as complete static strings. Writing `` `bg-${variant}` `` or `bg-[var(--color-${name})]` at runtime produces classes that are never generated, resulting in no styling applied. **What to do instead:** Use a lookup object (`const variantMap = { primary: 'bg-[var(--black)]', ... }`) with static string values, or use `style={{ backgroundColor: 'var(--black)' }}`.
5. **NEVER use spacing values not on the token scale → Why it fails:** Agents invent arbitrary values like `p-3` (12px = fine), `p-5` (20px = off-scale), `mt-7` (28px = off-scale), breaking the visual rhythm. The ElevenLabs spacing scale is 6/8/12/16/24/32/48px — note that **4px is NOT in the scale** (--space-xs starts at 6px). **What to do instead:** Use `--space-xs/sm/md/lg/xl/2xl/3xl` or their exact pixel equivalents only.
6. **NEVER add heavy drop shadows to cards and panels → Why it fails:** Agents copy generic "card" patterns with `box-shadow: 0 4px 6px rgba(0,0,0,0.1)` because that's what most design systems use. ElevenLabs uses flat borders (`1px solid hsl(var(--shadcn-border))`) as the primary surface separator. Only code blocks and specific elevated elements use the subtle `--shadow-card` (0px 0px 1px + 1px + 2px 4px). **What to do instead:** Use `border border-[hsl(var(--shadcn-border))]` for cards; only apply `--shadow-card` to floating/elevated elements confirmed to need it.
7. **NEVER omit focus-visible states → Why it fails:** Agents frequently implement hover states and skip focus states entirely. ElevenLabs has a specific focus system: `.effect-focus:focus-visible` uses `outline-color: var(--black)`, while inverse contexts use `--neutral-100`. An unstyled focus ring is an accessibility failure and a design inconsistency. **What to do instead:** Every interactive element must have `focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--black)]` (or the inverse variant on dark surfaces).
8. **NEVER use warm colours (orange, yellow) as primary button fills → Why it fails:** `--orange-500: #F36F1C` appears in the token set and agents may use it as a CTA colour because it's visually prominent. It is used only for hover states and accent highlights — **never as a button background fill**. The primary CTA is always black (`var(--black)`) or near-black. **What to do instead:** Primary buttons: `bg-[var(--black)]`. Orange only appears in `hover:text-[var(--orange-500)]` or decorative accent roles.
9. **NEVER use positive letter-spacing on large headings → Why it fails:** Agents apply default or positive tracking to all type, but ElevenLabs large headings (`--f-heading-01` through `--f-heading-03`) use **negative** letter-spacing (-0.01em to -0.03em). Positive tracking on large type creates an airy, unfocused look that contradicts the editorial precision of the brand. **What to do instead:** At font sizes ≥ 1.5rem (24px), apply negative tracking from the corresponding `--f-heading-*-letter-spacing` token. Only UI labels (uppercase, small) use positive tracking (0.02em–0.05em).
10. **NEVER use `!important` to override token values → Why it fails:** When an agent can't get a style to apply, it reaches for `!important`, which breaks the cascade and makes dark mode, theme overrides, and component state variants impossible to apply correctly. This is especially harmful in a shadcn/Tailwind system where the cascade is intentional. **What to do instead:** Debug specificity — use a more specific selector, move the style to the correct layer (component → token → base), or use a CSS custom property override at the component root.
---
## Appendix A: Complete Token Reference
Every token extracted from the source. §0 CORE TOKENS is the primary AI signal; this appendix is reference material an AI can cross-check against when a curated role is missing.
```css
/* Colours (128) */
--grid-column-bg: rgba(127,255,255,0.25);
---shadcn-background: 0 0% 100%;
--shadcn-ring: 0 0% 3.9%;
--shadcn-primary: 0 0% 9%;
--shadcn-primary-foreground: 0 0% 98%;
--shadcn-muted: 0 0% 96.1%;
--shadcn-muted-foreground: 0 0% 45.1%;
--shadcn-destructive: 0 84.2% 60.2%;
--shadcn-border: 0 0% 89.8%;
--page-background-color: #FDFCFC;
--black: #000;
--blue-50: #F2F5FC;
--blue-100: #E1E8F9;
--blue-200: #C8D5F4;
--blue-300: #A1BAEC;
--blue-400: #7294E3;
--blue-500: #5D79DF;
--blue-600: #4056CE;
--blue-700: #3C48B9;
--blue-800: #384094;
--blue-900: #353B73;
--blue-950: #252846;
--current: currentColor;
--cyan-50: #EEFBFD;
--cyan-100: #D3F4FA;
--cyan-200: #ADEAF4;
--cyan-300: #74D9EC;
--cyan-400: #4EC7E0;
--cyan-500: #19A2C1;
--cyan-600: #1783A3;
--cyan-700: #1A6984;
--cyan-800: #1E566C;
--cyan-900: #1D495C;
--cyan-950: #0D2F3F;
--green-50: #ECFDF4;
--green-100: #D1FAE3;
--green-200: #A7F3CC;
--green-300: #6EE7B1;
--green-400: #2DD28D;
--green-500: #10B978;
--green-600: #059661;
--green-700: #047851;
--green-800: #065F41;
--green-900: #064E37;
--green-950: #022C20;
--inherit: inherit;
--magenta-50: #FCF2FB;
--magenta-100: #FBE4FB;
--magenta-200: #F8D3F5;
--magenta-300: #F0B2EA;
--magenta-400: #E273D5;
--magenta-500: #D65CC8;
--magenta-600: #B83DA5;
--magenta-700: #973086;
--magenta-800: #7A296B;
--magenta-900: #642656;
--magenta-950: #3F0D35;
--orange-50: #FFF7ED;
--orange-100: #FEECD6;
--orange-200: #FCD5AC;
--orange-300: #F9B778;
--orange-400: #F58633;
--orange-500: #F36F1C;
--orange-600: #E45512;
--orange-700: #BD3F11;
--orange-800: #963316;
--orange-900: #792C15;
--orange-950: #492104;
--purple-50: #FBF6FE;
--purple-100: #F6EBFC;
--purple-200: #EEDBF9;
--purple-300: #E1BEF4;
--purple-400: #CF94EC;
--purple-500: #C47DE5;
--purple-600: #A94BD2;
--purple-700: #9139B7;
--purple-800: #7A3396;
--purple-900: #632A79;
--purple-950: #32123E;
--red-50: #FEF3F2;
--red-100: #FDE4E3;
--red-200: #FDCDCB;
--red-300: #FAABA7;
--red-400: #F57A74;
--red-500: #EB524B;
--red-600: #D7332B;
--red-700: #B52720;
--red-800: #96231E;
--red-900: #7D231F;
--red-950: #440D0B;
--teal-50: #EAFDF9;
--teal-100: #CEF8EF;
--teal-200: #9EF0DE;
--teal-300: #66E1CC;
--teal-400: #37C8B5;
--teal-500: #1FAD9D;
--teal-600: #168D81;
--teal-700: #166F67;
--teal-800: #165A55;
--teal-900: #174A46;
--teal-950: #072C2B;
--transparent: transparent;
--overlay-darker-plus: rgba(0,0,0,0.4);
--yellow-50: #FCFCEA;
--yellow-100: #FAF9C7;
--yellow-200: #F6F092;
--yellow-300: #EFDE44;
--yellow-400: #EACE25;
--yellow-500: #DAB718;
--yellow-600: #BC8F12;
--yellow-700: #966812;
--yellow-800: #7D5316;
--yellow-900: #6A4419;
--yellow-950: #3E240A;
--white-50: #FFF;
--neutral-200: #DCDCDC;
--neutral-400: #949494;
--neutral-600: #6E6E6E;
--white-200: #F5F3F1;
--eggshell: #FDFCFC;
--neutral-50: #F2F2F2;
--neutral-100: #E5E5E5;
--neutral-300: #BDBDBD;
--neutral-500: #767676;
--neutral-700: #525252;
--neutral-800: #464646;
--neutral-900: #3D3D3D;
--neutral-950: #1C1C1C;
/* Typography (197) */
--container-width: min(100%,81.5rem);
--f-description-01-font-family: var(--font-waldenburg);
--waldenburgFH: var(--font-waldenburg-fh);
--jetbrainsMono: var(--font-jetbrains-mono);
--f-description-02-font-family: var(--font-inter);
--f-ui-01-font-weight: 700;
--f-display-01-font-size: 6.25rem;
--f-display-01-line-height: 95%;
--contextual-nav-height: 4rem;
--f-display-02-line-height: 100%;
--f-heading-01-font-weight: 300;
--f-heading-01-font-size: 3.75rem;
--f-heading-01-line-height: 105%;
--f-heading-01-letter-spacing: -0.03em;
--tw-font-size-6xl: 3rem;
--f-ui-01-line-height: 110%;
--tw-line-height-4xl: 2.25rem;
--f-heading-03-line-height: 120%;
--f-description-01-letter-spacing: -0.02em;
--f-description-01-font-weight: 400;
--tw-line-height-base: 1.5rem;
--f-description-01-line-height: 130%;
--f-heading-04-letter-spacing: -0.01em;
--tw-font-size-2xl: 1.25rem;
--f-heading-05-line-height: 135%;
--f-heading-05-letter-spacing: 0em;
--f-description-02-font-size: 1.125rem;
--f-description-02-line-height: 140%;
--f-description-03-font-size: 1rem;
--f-description-04-font-size: 0.875rem;
--f-ui-04-font-size: 0.75rem;
--f-description-01-font-size: 1.375rem;
--f-description-02-letter-spacing: 0.01em;
--f-body-01-line-height: 160%;
--f-ui-01-letter-spacing: 0.03em;
--f-ui-01-text-transform: uppercase;
--f-ui-02-letter-spacing: 0.02em;
--f-ui-03-letter-spacing: 0.05em;
--f-ui-07-font-size: 0.625rem;
--f-description-blog-font-size: 1.0625rem;
--f-description-blog-line-height: 30px;
--container-width-absolute: min(100vw,81.5rem);
--tw-font-size-2xs: 0.8125rem;
--tw-line-height-xs: 1.3125rem;
--tw-font-size-sm: 0.9375rem;
--tw-line-height-lg: 1.5625rem;
--tw-line-height-base-loose: 1.75rem;
--tw-line-height-lg-loose: 1.875rem;
--tw-line-height-xl: 1.625rem;
--tw-line-height-2xl: 1.6875rem;
--tw-line-height-3xl: 2rem;
--tw-line-height-5xl: 2.625rem;
--tw-line-height-6xl: 3.25rem;
--font-size-xs: 13px; /* 34 elements — e.g. p "Persuasive voices th", p "Playful and engaging", p "Expressive voices th" /* mined from computed styles */ */
--font-size-sm: 14px; /* 22 elements — e.g. p "Access a library of ", p "Our most consistent ", p "Aug 2023" /* mined from computed styles */ */
--font-size-md: 15px; /* 51 elements — e.g. h3 "All-in-one AI editor", h3 "Ultra-realistic spee", h3 "Music" /* mined from computed styles */ */
--font-size-lg: 16px; /* 39 elements — e.g. h2 "Powering the best en", h2 "Trusted by leading d", h3 "ElevenCreative" /* mined from computed styles */ */
--font-size-xl: 18px; /* 93 elements — e.g. h3 "Text to Speech API", h3 "Speech to Text API", h3 "Music API" /* mined from computed styles */ */
--font-size-2xl: 20px; /* 3 elements — e.g. h3 "Introducing Flows in", h3 "Introducing ElevenLa", h3 "Introducing Expressi" /* mined from computed styles */ */
--font-size-3xl: 36px; /* 8 elements — e.g. h2 "Two platforms built ", h2 "Create, edit and loc", h2 "Deploy agents that t" /* mined from computed styles */ */
--font-weight-semibold: 500; /* 31 elements — e.g. h3 "ElevenCreative", h3 "ElevenAgents", h3 "All-in-one AI editor" /* mined from computed styles */ */
--line-height-tight: 22px; /* 75 elements — e.g. h3 "All-in-one AI editor", h3 "Ultra-realistic spee", h3 "Music" /* mined from computed styles */ */
--line-height-normal: 24px; /* 38 elements — e.g. h2 "Powering the best en", h2 "Trusted by leading d", h3 "ElevenCreative" /* mined from computed styles */ */
--line-height-loose: 28.8px; /* 88 elements — e.g. p "NVIDIA", p "Clay", p "Duolingo" /* mined from computed styles */ */
--font-waldenburg: "Waldenburg", "Waldenburg Fallback", sans-serif;
--font-waldenburg-fh: "WaldenburgFH", "WaldenburgFH Fallback", sans-serif;
--font-inter: "Inter", "Inter Fallback", sans-serif;
--f-display-01-font-family: var(--font-waldenburg-fh);
--f-display-01-font-weight: 700;
--f-display-02-font-family: var(--font-waldenburg-fh);
--f-display-02-font-size: 4rem;
--f-display-02-font-weight: 700;
--f-heading-01-font-family: var(--font-waldenburg);
--f-heading-02-font-family: var(--font-waldenburg);
--f-heading-02-font-size: 3rem;
--f-heading-02-font-weight: 300;
--f-heading-02-line-height: 110%;
--f-heading-02-letter-spacing: -0.03em;
--f-heading-03-font-family: var(--font-waldenburg);
--f-heading-03-font-size: 2.25rem;
--f-heading-03-font-weight: 300;
--f-heading-03-letter-spacing: -0.02em;
--f-heading-04-font-family: var(--font-waldenburg);
--f-heading-04-font-size: 1.5rem;
--f-heading-04-font-weight: 400;
--f-heading-04-line-height: 130%;
--f-heading-05-font-family: var(--font-waldenburg);
--f-heading-05-font-size: 1.25rem;
--f-heading-05-font-weight: 400;
--f-subhead-01-font-family: var(--font-waldenburg);
--f-subhead-01-font-size: 1.375rem;
--f-subhead-01-font-weight: 700;
--f-subhead-01-line-height: 140%;
--f-subhead-01-letter-spacing: 0.01em;
--f-subhead-02-font-family: var(--font-waldenburg);
--f-subhead-02-font-size: 1.125rem;
--f-subhead-02-font-weight: 700;
--f-subhead-02-line-height: 140%;
--f-subhead-02-letter-spacing: 0.01em;
--f-subhead-03-font-family: var(--font-waldenburg);
--f-subhead-03-font-size: 1rem;
--f-subhead-03-font-weight: 700;
--f-subhead-03-line-height: 140%;
--f-subhead-03-letter-spacing: 0.01em;
--f-subhead-04-font-family: var(--font-waldenburg);
--f-subhead-04-font-size: 1rem;
--f-subhead-04-font-weight: 400;
--f-subhead-04-line-height: 140%;
--f-subhead-05-font-family: var(--font-waldenburg);
--f-subhead-05-font-size: 0.875rem;
--f-subhead-05-font-weight: 400;
--f-subhead-05-line-height: 120%;
--f-description-02-font-weight: 400;
--f-description-03-font-family: var(--font-inter);
--f-description-03-font-weight: 400;
--f-description-03-line-height: 140%;
--f-description-03-letter-spacing: 0.01em;
--f-description-04-font-family: var(--font-inter);
--f-description-04-font-weight: 400;
--f-description-04-line-height: 140%;
--f-description-04-letter-spacing: 0.01em;
--f-description-05-font-family: var(--font-inter);
--f-description-05-font-size: 1rem;
--f-description-05-font-weight: 400;
--f-description-05-line-height: 140%;
--f-description-05-letter-spacing: 0.01em;
--f-paragraph-01-font-family: var(--font-inter);
--f-paragraph-01-font-size: 1.125rem;
--f-paragraph-01-font-weight: 400;
--f-paragraph-01-line-height: 140%;
--f-paragraph-01-letter-spacing: 0em;
--f-paragraph-02-font-family: var(--font-inter);
--f-paragraph-02-font-size: 1rem;
--f-paragraph-02-font-weight: 400;
--f-paragraph-02-line-height: 140%;
--f-paragraph-02-letter-spacing: 0em;
--f-paragraph-03-font-family: var(--font-inter);
--f-paragraph-03-font-size: 0.875rem;
--f-paragraph-03-font-weight: 400;
--f-paragraph-03-line-height: 140%;
--f-paragraph-03-letter-spacing: 0em;
--f-paragraph-04-font-family: var(--font-inter);
--f-paragraph-04-font-size: 0.75rem;
--f-paragraph-04-font-weight: 400;
--f-paragraph-04-line-height: 140%;
--f-paragraph-04-letter-spacing: 0em;
--f-body-01-font-family: var(--font-inter);
--f-body-01-font-size: 1.125rem;
--f-body-01-font-weight: 400;
--f-ui-01-font-family: var(--font-waldenburg-fh);
--f-ui-01-font-size: 1.125rem;
--f-ui-02-font-family: var(--font-inter);
--f-ui-02-font-size: 0.875rem;
--f-ui-02-font-weight: 400;
--f-ui-02-line-height: 140%;
--f-ui-03-font-family: var(--font-waldenburg-fh);
--f-ui-03-font-size: 0.875rem;
--f-ui-03-font-weight: 700;
--f-ui-03-line-height: 110%;
--f-ui-03-text-transform: uppercase;
--f-ui-04-font-family: var(--font-waldenburg-fh);
--f-ui-04-font-weight: 700;
--f-ui-04-line-height: 110%;
--f-ui-04-letter-spacing: 0.05em;
--f-ui-04-text-transform: uppercase;
--f-ui-05-font-family: var(--font-inter);
--f-ui-05-font-size: 0.75rem;
--f-ui-05-font-weight: 400;
--f-ui-05-line-height: 140%;
--f-ui-05-letter-spacing: 0.02em;
--f-ui-06-font-family: var(--font-waldenburg-fh);
--f-ui-06-font-size: 0.875rem;
--f-ui-06-font-weight: 700;
--f-ui-06-line-height: 110%;
--f-ui-06-letter-spacing: 0.05em;
--f-ui-07-font-family: var(--font-inter);
--f-ui-07-font-weight: 400;
--f-ui-07-line-height: 140%;
--f-ui-07-letter-spacing: 0.02em;
--f-ui-08-font-family: var(--font-inter);
--f-ui-08-font-size: 0.75rem;
--f-ui-08-font-weight: 400;
--f-ui-08-line-height: 140%;
--f-description-blog-font-family: var(--font-inter);
--f-description-blog-font-weight: 400;
--f-description-blog-letter-spacing: 0.01em;
--f-body-blog-font-family: var(--font-inter);
--f-body-blog-font-size: 1.0625rem;
--f-body-blog-font-weight: 400;
--f-body-blog-line-height: 30px;
--tw-font-size-xs: 0.875rem;
--tw-font-size-base: 1rem;
--tw-font-size-lg: 1.0625rem;
--tw-font-size-xl: 1.125rem;
--tw-font-size-3xl: 1.5rem;
--tw-font-size-4xl: 2rem;
--tw-font-size-5xl: 2.25rem;
/* Spacing (33) */
--inner-gutter: 20px;
--outer-gutter: 64px;
--spacing-outer-gutter: 4rem;
--spacing-inner-gutter: 1.25rem;
--spacing-container-gutter: 0.625rem;
--spacing-outer-content: 6.25rem;
--spacing-content-wide: 10rem;
--spacing-content-xwide: 12.5rem;
--tw-trim-top-2xs: 0.25rem;
--tw-trim-bottom-2xs: 0.28125rem;
--tw-trim-top-2xs-loose: 0.34375rem;
--tw-trim-top-base: 0.375rem;
--tw-trim-top-xs-loose: 0.4375rem;
--tw-trim-bottom-base: 0.40625rem;
--tw-trim-top-base-loose: 0.5rem;
--tw-trim-top-lg-loose: 0.53125rem;
--tw-trim-top-3xl-loose: 0.5625rem;
--tw-trim-bottom-3xl: 0.46875rem;
--tw-trim-bottom-3xl-loose: 0.59375rem;
--space-xs: 6px; /* 27 elements — e.g. div .tw-flex, div .tw-flex, div .tw-flex /* mined from computed styles */ */
--space-sm: 8px; /* 40 elements — e.g. div .tw-grid, div .tw-grid, div .tw-py-2 /* mined from computed styles */ */
--space-md: 12px; /* 36 elements — e.g. a .tw-group, a .tw-group, a .inline-flex /* mined from computed styles */ */
--space-lg: 16px; /* 27 elements — e.g. div .tw-py-2, div .tw-py-2, div .tw-py-2 /* mined from computed styles */ */
--space-xl: 24px; /* 36 elements — e.g. div .tw-relative, div .tw-relative, div .tw-relative /* mined from computed styles */ */
--space-2xl: 32px; /* 16 elements — e.g. div .tw-relative, div .tw-relative, div .tw-grid /* mined from computed styles */ */
--space-3xl: 48px; /* 27 elements — e.g. div .tw-relative, div .tw-relative, div .tw-flex /* mined from computed styles */ */
--space-xs: 6px;
--space-sm: 8px;
--space-md: 12px;
--space-lg: 16px;
--space-xl: 24px;
--space-2xl: 32px;
--space-3xl: 48px;
/* Radius (9) */
--shadcn-radius: 0.5rem;
--radius-sm: 18px; /* 3 elements — e.g. a .tw-py-2 "ElevenCreative", a .tw-py-2 "ElevenAgents", a .tw-py-2 "ElevenAPI" /* mined from computed styles */ */
--radius-md: 50px; /* 8 elements — e.g. button .cb-btn "Reject All", button .cb-btn "Customize", button .cb-btn "Accept All Cookies" /* mined from computed styles */ */
--radius-lg: 50%; /* 2 elements — e.g. button .cb-orb-button, button .cb-orb-button /* mined from computed styles */ */
--radius-full: 100px; /* 4 elements — e.g. input .cb-toggle-checkbox, input .cb-toggle-checkbox, input .cb-toggle-checkbox /* mined from computed styles */ */
--radius-sm: 18px;
--radius-md: 50px;
--radius-full: 100px;
--radius-lg: 50%;
/* Effects (4) */
--breakpoint: "xxxl";
--grid-columns: 12;
--env: "dev";
--shadow-card: rgba(0, 0, 0, 0.4) 0px 0px 1px 0px,
rgba(0, 0, 0, 0.04) 0px 1px 1px 0px,
rgba(0, 0, 0, 0.04) 0px 2px 4px 0px;
/* Motion (22) */
----motion-text-reveal-word: @keyframes text-reveal-word {
0% { opacity: 0; transform: scaleY(0.95) scaleX… <0.3KB elided>; /* @keyframes text-reveal-word */
----motion-text-reveal-fill: @keyframes text-reveal-fill {
100% { background-size: 0px 100%; }
}; /* @keyframes text-reveal-fill */
----motion-ping: @keyframes ping {
75%, 100% { transform: scale(2); opacity: 0; }
}; /* @keyframes ping */
----motion-fade-in: @keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes fade-in */
----motion-spin: @keyframes spin {
100% { transform: rotate(1turn); }
}; /* @keyframes spin */
----motion-enter: @keyframes enter {
0% { opacity: var(--tw-enter-opacity,1); transform: transl… <0.3KB elided>; /* @keyframes enter */
----motion-exit: @keyframes exit {
100% { opacity: var(--tw-exit-opacity,1); transform: transl… <0.3KB elided>; /* @keyframes exit */
----motion-fadeTranslateXIn: @keyframes fadeTranslateXIn {
0% { opacity: 0; transform: translateX(var(--translate-x-from,100%)); }
100% { opacity: 1; transform: translateX(0px); }
}; /* @keyframes fadeTranslateXIn */
----motion-fadeTranslateYIn: @keyframes fadeTranslateYIn {
0% { opacity: 0; transform: translateY(var(--translate-y-from,100%)); }
100% { opacity: 1; transform: translateY(0px); }
}; /* @keyframes fadeTranslateYIn */
----motion-ds-slide: @keyframes ds-slide {
0% { transform: translateX(-150%) scale(var(--ds-scale)… <0.2KB elided>; /* @keyframes ds-slide */
----motion-pulse: @keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}; /* @keyframes pulse */
----motion-opacity: @keyframes opacity {
0% { opacity: 0.5; }
50% { opacity: 1; }
100% { opacity: 0.5; }
}; /* @keyframes opacity */
----motion-pop: @keyframes pop {
0% { transform: scale(1); }
40% { transform: scale(1.04); }
70% { transform: scale(0.97); }
100% { transform: scale(1); }
}; /* @keyframes pop */
----motion-fadeInScaleY: @keyframes fadeInScaleY {
0% { opacity: 0; transform: scaleY(1.5); }
100% { opacity: 1; transform: scaleY(1); }
}; /* @keyframes fadeInScaleY */
----motion-fadeIn: @keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}; /* @keyframes fadeIn */
----motion-shimmer-text: @keyframes shimmer-text {
0% { background-position: 100% 0px; }
100% { background-position: -100% 0px; }
}; /* @keyframes shimmer-text */
----motion-tw-pulse: @keyframes tw-pulse {
50% { opacity: 0.5; }
}; /* @keyframes tw-pulse */
----motion-tw-spin: @keyframes tw-spin {
100% { transform: rotate(1turn); }
}; /* @keyframes tw-spin */
--duration-fast: 0.15s; /* 18 elements — e.g. button, button, button /* mined from computed styles */ */
--duration-base: 0.3s; /* 33 elements — e.g. button, button, button /* mined from computed styles */ */
--duration-slow: 0.36s; /* 4 elements — e.g. div, div, div /* mined from computed styles */ */
--ease-default: ease; /* 91 elements — e.g. button, button, button /* mined from computed styles */ */
```
## Appendix B: Token Source Metadata
```
tokenSource: extracted-css-vars
confidence: high
properties found: 388 CSS custom properties
extraction site: elevenlabs.io
extraction date: [TBD - record at extraction time]
Curated token count: 39 tokens mapped to standard semantic roles
Original CSS variable names: PRESERVED exactly as extracted
Synthesised names: Only --z-* z-index scale and --shadow-card are synthetic
(annotated inline with confidence level)
Font source: Self-hosted WOFF2 via CDN (eleven-public-cdn.elevenlabs.io)
Fonts confirmed: Waldenburg (300/400/700), WaldenburgFH (700 condensed),
Inter (variable 100–900), Geist Mono (variable)
Fallbacks: Arial (Waldenburg Fallback, WaldenburgFH Fallback, Geist Mono Fallback)
Note: JetBrains Mono referenced via --jetbrainsMono variable but @font-face
declaration not found in extraction — may be loaded separately
Framework: Next.js + Tailwind CSS v4 (CSS vars via @theme — note --tw-* prefix tokens)
UI Library: shadcn/ui (confirmed by --shadcn-* variable prefix, 0 0% 100% HSL format)
Icons: Lucide
Shadcn token format note:
All --shadcn-* tokens are stored as bare HSL channel values (e.g. "0 0% 100%")
WITHOUT the hsl() wrapper. This is the shadcn convention.
ALWAYS use: hsl(var(--shadcn-primary)), NOT var(--shadcn-primary) directly in CSS.
Border radius note:
The --radius-md: 50px value was mined from 8 cookie-banner button elements.
The brand primary CTA button uses border-radius: 9999px (from button_primary
computed style). Both represent pill-shaped buttons. Use --radius-md (50px)
for standard buttons; 9999px is safe for any pill button.
Breakpoints:
Only two breakpoints detected: 480px (mobile) and 1024px (desktop).
No explicit tablet breakpoint between these values.
Confidence annotations:
Colour tokens: high (direct CSS var extraction)
Typography: high (both CSS vars and computed styles confirm)
Spacing scale: high (--space-* vars directly extracted)
Radius: high (mined from computed element styles)
Motion: high (direct CSS var extraction + computed transitions)
Z-index scale: reconstructed: moderate confidence (no z-index vars found;
inferred from typical shadcn/Next.js nav patterns)
Shadow tokens: extracted: high confidence (from code element computed boxShadow)
Page sections: inferred: moderate confidence (no screenshots; derived from
component inventory + layout digest structural signals)
```More from the gallery
Browse all kits →You may also like

Contra
MITPlayful yet professional design system with teal and purple accents, bold typography, and vibrant accent surfaces—built for modern SaaS platforms and landing pages
03
lightboldsaaslanding-page

DoorDash
MITClean, accessible food-delivery system with DoorDash's signature red accent, light neutral palette, and system-font typography—built for rapid product development
03
lightecommsaasmobile

Mercedes-Benz
MITLuxe, minimalist design system with sharp black-and-white contrast and serif typography, crafted for premium automotive and lifestyle brands
05
darkminimalboldecomm