Zendesk
MIT
Modern SaaS design system with dark green and lime accents, built for customer support platforms and enterprise applications
Colour (35)
color.cardbgvar(--zendesk-surface-card)
color.inputbgvar(--zendesk-surface-input)
color.tooltipbgvar(--zendesk-surface-white)
color.bordercard1px solid rgba(0, 0, 0, 0)
color.cardborder1px solid rgba(0, 0, 0, 0)
color.inputbordervar(--zendesk-border-default)
color.bordersubtle1px solid rgba(17, 17, 13, 0.18)
color.btnprimarybgvar(--zendesk-accent)
color.brandsurface1rgb(32, 53, 36)
color.btndisabledbgvar(--zendesk-disabled-bg)
color.tooltipbordervar(--zendesk-border-subtle)
color.zendeskaccentrgb(209, 244, 112)
color.primitivewhitergb(255, 255, 255)
color.brandprimaryctargb(209, 244, 112)
color.primitivelime300rgb(209, 244, 112)
color.zendeskbgsurfacergb(32, 53, 36)
color.zendesktextmutedrgb(144, 145, 140)
color.primitivegreen900rgb(32, 53, 36)
color.zendeskdisabledbgrgb(75, 75, 57)
color.primitiveneutral50rgb(245, 245, 242)
color.zendeskborderfocusrgb(17, 17, 13)
color.zendesksurfacecardrgb(245, 245, 242)
color.zendesktextinversergb(245, 245, 242)
color.zendesktextprimaryrgb(17, 17, 13)
color.primitiveneutral400rgb(144, 145, 140)
color.primitiveneutral600rgb(89, 89, 68)
color.primitiveneutral700rgb(75, 75, 57)
color.primitiveneutral950rgb(17, 17, 13)
color.zendeskbordersubtlergba(17, 17, 13, 0.18)
color.zendeskhoveroverlayrgba(17, 17, 13, 0.08)
color.zendesksurfaceinputrgba(17, 17, 13, 0.05)
color.zendesksurfacewhitergb(255, 255, 255)
color.zendesktextdisabledrgb(46, 46, 35)
color.zendeskactiveoverlayrgba(17, 17, 13, 0.20)
color.zendeskborderdefaultrgba(17, 17, 13, 0.47)
Spacing (30)
spacing.spacetabletextrapadding0px
spacing.spacexs4px
spacing.zendeskspacexs4px
spacing.spacetextmarginsm8px
spacing.spacesm12px
spacing.zendeskspacesm12px
spacing.spacelinkmarginsm16px
spacing.spacetextmarginmd16px
spacing.spacelg20px
spacing.zendeskspacelg20px
spacing.spacelinkmarginmd24px
spacing.spacetextmarginlg24px
spacing.spacecontentmarginsm24px
spacing.spacespace32px
spacing.spacebuttonmargin32px
spacing.zendeskspacexl40px
spacing.spaceglobalpadding40px
spacing.spacesectionpaddinghorizontal40px
spacing.space2xl48px
spacing.zendeskspace2xl48px
spacing.spacecontentmarginmd56px
spacing.spacemodalpaddinghorizontal56px
spacing.zendeskspace3xl72px
spacing.spacecontentmarginlg72px
spacing.space3xl88px
spacing.zendeskspacemd88px
spacing.spacescrollpadding88px
spacing.spacesectionpadding104px
spacing.spacesectionpaddingvertical104px
spacing.contentwidth1600px
Radius (13)
inputradiusvar(--zendesk-radius-full)
tooltipradiusvar(--zendesk-radius-lg)
btnprimaryradiusvar(--zendesk-radius-lg)
radiussm2px
zendeskradiussm2px
radiusmd4px
zendeskradiusmd4px
radiuslg8px
zendeskradiuslg8px
radiusfull12px
zendeskradiusfull12px
cardradius16px
radius40px
Shadow (5)
effect.shadowmdrgba(0,0,0,0.08) 0px 16px 28px 0px
effect.shadowsmrgba(0,0,0,0.08) 0px 8px 24px 0px
effect.shadowfocusrgb(255,255,255) 0 2px 4px, rgb(17,17,13) 0 4px 12px
effect.motionslideupblur@keyframes slideUpBlur {
0% { opacity: 0.01
effect.shadowinsetdefaultrgba(17,17,13,0.47) 0 0 0 1px inset
# layout.md — Zendesk Design System
---
## 0. Quick Reference
**Stack:** Next.js · CSS custom properties · Styled Components · Bootstrap grid
**Token source:** extracted-css-vars (19 CSS vars) + curated zendesk-* aliases (medium confidence)
**How to apply:** Use as `var(--zendesk-accent)` in CSS, `style={{ background: 'var(--zendesk-accent)' }}` in JSX, or `bg-[var(--zendesk-accent)]` in Tailwind.
```css
:root {
/* Colour */
--zendesk-bg-surface: rgb(32, 53, 36); /* dark green hero/section bg */
--zendesk-accent: rgb(209, 244, 112); /* ONLY CTA bg — lime green */
--zendesk-text-primary: rgb(17, 17, 13); /* near-black body/heading text */
--zendesk-text-inverse: rgb(245, 245, 242); /* off-white text on dark bg */
--zendesk-surface-card: rgb(245, 245, 242); /* card background */
/* Typography */
--zendesk-font-family: "Vanilla Sans", Arial, sans-serif;
--zendesk-font-size-xs: 14px;
--zendesk-font-size-sm: 15px;
--zendesk-font-size-md: 16px;
--zendesk-font-size-lg: 18px;
--zendesk-font-size-xl: 26px;
--zendesk-font-size-2xl: 42px;
--zendesk-font-size-3xl: 68px;
--zendesk-font-weight-regular: 400;
--zendesk-font-weight-medium: 500;
--zendesk-font-weight-semibold: 600;
--zendesk-font-weight-bold: 700;
/* Spacing */
--space-textMarginSm: 8px;
--space-textMarginMd: 16px;
--space-textMarginLg: 24px;
--space-globalPadding: 40px;
--space-sectionPadding: 104px;
--space-contentMarginSm: 24px;
--space-contentMarginMd: 56px;
--space-contentMarginLg: 72px;
--space-buttonMargin: 32px;
--contentWidth: 1600px;
/* Radius */
--zendesk-radius-sm: 2px;
--zendesk-radius-md: 4px;
--zendesk-radius-lg: 8px;
--zendesk-radius-full: 12px; /* inputs; NOTE: --radius: 40px on page root */
/* Motion */
--zendesk-duration-fast: 0.1s;
--zendesk-duration-base: 0.25s;
--zendesk-duration-slow: 0.6s;
--zendesk-ease-default: ease;
}
```
```tsx
// Primary CTA Button — production-ready
<a
href="/trial"
style={{
display: 'inline-block',
backgroundColor: 'var(--zendesk-accent)', /* rgb(209,244,112) */
color: 'var(--zendesk-text-primary)',
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-lg)', /* 18px */
fontWeight: 'var(--zendesk-font-weight-semibold)',
borderRadius: 'var(--zendesk-radius-lg)', /* 8px */
padding: '14px 28px',
transition: `all var(--zendesk-duration-slow) cubic-bezier(0.7, 0, 0.3, 1)`,
textDecoration: 'none',
}}
>
Kostenlos testen
</a>
```
<!-- Quick Reference truncated to fit the 75-line cap. See later sections for the full design system. -->
## 1. Design Direction & Philosophy
### Character & Mood
Zendesk's marketing homepage projects **confident enterprise minimalism with a natural edge**. The palette — dark forest green (`rgb(32, 53, 36)`) hero against near-black body text and a sharp acid-lime CTA (`rgb(209, 244, 112)`) — reads as premium, modern, and slightly editorial. The custom typeface "Vanilla Sans" is a geometric humanist sans that feels neither sterile nor casual; it bridges corporate credibility with approachability.
### What this design does
- Uses **high contrast light/dark section alternation**: dark green hero sections against light off-white (`rgb(245, 245, 242)`) card/body sections.
- Employs **large, commanding typographic scale** (68px h1, 42px h2) with medium weight (500) — bold without heaviness.
- Uses **restraint in colour**: exactly two brand colours (dark green surface + lime accent), everything else is neutral near-black/near-white.
- Applies **slow, cubic-bezier transitions** (`0.6s cubic-bezier(0.7, 0, 0.3, 1)`) for premium tactility.
### What this design explicitly rejects
- **Rounded pill buttons** — despite `--radius: 40px` existing on the root, CTA buttons use `4px–8px` radius (sharp, considered)
- **Warm colour palettes** — the green is cool and natural, not yellow-warm
- **Drop shadows as primary depth signal** — depth is achieved through surface colour contrast, not heavy shadows
- **Serif or display typefaces** — Vanilla Sans exclusively
- **Generic system fonts** — never render with Inter, Roboto, or the system-ui stack
---
## 2. Colour System
### Tier 1 — Primitives
```css
/* Raw values — do not use directly in components */
:root {
--primitive-green-900: rgb(32, 53, 36); /* darkest brand green */
--primitive-lime-300: rgb(209, 244, 112); /* acid lime accent */
--primitive-neutral-950: rgb(17, 17, 13); /* near-black */
--primitive-neutral-50: rgb(245, 245, 242); /* off-white */
--primitive-white: rgb(255, 255, 255); /* pure white (tooltips, link bg) */
--primitive-neutral-700: rgb(75, 75, 57); /* disabled state bg */
--primitive-neutral-600: rgb(89, 89, 68); /* disabled button bg variant */
--primitive-neutral-400: rgb(144, 145, 140); /* muted/placeholder borders */
}
```
### Tier 2 — Semantic Aliases
```css
:root {
/* Surfaces */
--zendesk-bg-surface: var(--primitive-green-900); /* hero, dark sections; original: --brand-surface-1 */
--zendesk-surface-card: var(--primitive-neutral-50); /* card backgrounds */
--zendesk-surface-input: rgba(17, 17, 13, 0.05); /* input field fill */
--zendesk-surface-white: var(--primitive-white); /* tooltip, dropdown bg */
/* Text */
--zendesk-text-primary: var(--primitive-neutral-950); /* all body + heading text on light */
--zendesk-text-inverse: var(--primitive-neutral-50); /* text on dark green bg */
--zendesk-text-disabled: rgb(46, 46, 35); /* disabled text */
--zendesk-text-muted: var(--primitive-neutral-400); /* secondary/placeholder text */
/* Actions */
--zendesk-accent: var(--primitive-lime-300); /* PRIMARY CTA bg only; original: --brand-primary-cta */
--zendesk-border-default: rgba(17, 17, 13, 0.47); /* input inset border */
--zendesk-border-subtle: rgba(17, 17, 13, 0.18); /* tooltip border */
--zendesk-border-focus: var(--primitive-neutral-950); /* focus outline colour */
/* States */
--zendesk-disabled-bg: var(--primitive-neutral-700); /* rgb(75,75,57) */
--zendesk-hover-overlay: rgba(17, 17, 13, 0.08); /* radio/checkbox hover */
--zendesk-active-overlay: rgba(17, 17, 13, 0.20); /* radio/checkbox active */
}
```
### Tier 3 — Component Tokens
```css
:root {
/* Button */
--btn-primary-bg: var(--zendesk-accent);
--btn-primary-text: var(--zendesk-text-primary);
--btn-primary-radius: var(--zendesk-radius-lg); /* 8px */
--btn-disabled-bg: var(--zendesk-disabled-bg);
/* Card */
--card-bg: var(--zendesk-surface-card);
--card-radius: 16px; /* extracted from computed styles */
--card-border: 1px solid rgba(0, 0, 0, 0);
/* Input */
--input-bg: var(--zendesk-surface-input);
--input-radius: var(--zendesk-radius-full); /* 12px */
--input-border: var(--zendesk-border-default);
/* Tooltip */
--tooltip-bg: var(--zendesk-surface-white);
--tooltip-border: var(--zendesk-border-subtle);
--tooltip-radius: var(--zendesk-radius-lg); /* 8px */
}
```
### Colour Usage Table
| Token | Value | Usage |
|---|---|---|
| `--zendesk-bg-surface` | `rgb(32, 53, 36)` | Dark hero/feature section backgrounds |
| `--zendesk-accent` | `rgb(209, 244, 112)` | **Primary CTA button background only** |
| `--zendesk-text-primary` | `rgb(17, 17, 13)` | All body copy, headings on light bg |
| `--zendesk-text-inverse` | `rgb(245, 245, 242)` | Headings/text on dark green bg |
| `--zendesk-surface-card` | `rgb(245, 245, 242)` | Card, tag, badge backgrounds |
| `--zendesk-disabled-bg` | `rgb(75, 75, 57)` | Disabled button/input backgrounds |
---
## 3. Typography System
**Primary typeface:** `"Vanilla Sans"` — Zendesk's proprietary geometric humanist sans-serif. Self-hosted at `web-assets.zendesk.com`. Available weights: 100, 200, 300, 400, 500, 600, 700, 900 (normal + italic).
**CJK fallback:** `"Noto Sans JP"` for Japanese markets.
```css
/* Font stack */
--zendesk-font-family: "Vanilla Sans", Arial, sans-serif;
--zendesk-font-family-cjk: "Noto Sans JP", "Vanilla Sans", Arial, sans-serif;
```
### Composite Typography Tokens
```css
/* ── Display / Hero ── */
.type-display {
/* h1 — hero headline */
font-family: var(--zendesk-font-family);
font-size: 68px; /* --zendesk-font-size-3xl */
font-weight: 500; /* --zendesk-font-weight-medium */
line-height: 71.4px; /* 1.05 ratio */
letter-spacing: normal;
}
/* ── Heading XL ── */
.type-heading-xl {
/* h2 large — section titles (Von Branchenführern, etc.) */
font-family: var(--zendesk-font-family);
font-size: 42px; /* --zendesk-font-size-2xl */
font-weight: 500; /* --zendesk-font-weight-medium */
line-height: 48.3px; /* --line-height-loose */
letter-spacing: normal;
}
/* ── Heading LG ── */
.type-heading-lg {
/* h3 — feature section subtitles, testimonial headers */
font-family: var(--zendesk-font-family);
font-size: 26px; /* --zendesk-font-size-xl */
font-weight: 500; /* --zendesk-font-weight-medium */
line-height: 32.5px; /* 1.25 ratio */
letter-spacing: normal;
}
/* ── Heading SM ── */
.type-heading-sm {
/* h2 small — card titles, feature labels */
font-family: var(--zendesk-font-family);
font-size: 18px; /* --zendesk-font-size-lg */
font-weight: 600; /* --zendesk-font-weight-semibold */
line-height: 26.1px; /* 1.45 ratio */
letter-spacing: normal;
}
/* ── Body MD ── */
.type-body-md {
/* Standard body copy, nav links */
font-family: var(--zendesk-font-family);
font-size: 16px; /* --zendesk-font-size-md */
font-weight: 400; /* --zendesk-font-weight-regular */
line-height: 23.2px; /* --line-height-normal */
letter-spacing: normal;
}
/* ── Body SM ── */
.type-body-sm {
/* Caption, small labels, metadata */
font-family: var(--zendesk-font-family);
font-size: 14px; /* --zendesk-font-size-xs */
font-weight: 400; /* --zendesk-font-weight-regular */
line-height: 18.2px; /* --line-height-tight */
letter-spacing: normal;
}
/* ── Button / CTA ── */
.type-button {
font-family: var(--zendesk-font-family);
font-size: 18px; /* --zendesk-font-size-lg — primary CTA */
font-weight: 600; /* --zendesk-font-weight-semibold */
line-height: 23px;
letter-spacing: normal;
}
/* ── Input ── */
.type-input {
font-family: var(--zendesk-font-family);
font-size: 15px; /* --zendesk-font-size-sm */
font-weight: 400; /* --zendesk-font-weight-regular */
line-height: 21px; /* 1.4 ratio */
letter-spacing: normal;
}
```
### Weight Usage Guide
| Weight | Token | Usage |
|---|---|---|
| 400 | `--zendesk-font-weight-regular` | Body copy, labels, input text |
| 500 | `--zendesk-font-weight-medium` | h1, h2 large, h3, nav links |
| 600 | `--zendesk-font-weight-semibold` | h2 small, card titles, CTA buttons |
| 700 | `--zendesk-font-weight-bold` | Stat callouts, event dates, emphasis |
---
## 4. Spacing & Layout
```css
:root {
/* ── Extracted raw spacing tokens (preserve exact names) ── */
--space-textMarginSm: 8px; /* between label and sub-element */
--space-textMarginMd: 16px; /* paragraph margin, link margin sm */
--space-textMarginLg: 24px; /* heading bottom margin, content margin sm */
--space-tabletExtraPadding: 0px; /* tablet extra padding (currently unused) */
--space-space: 32px; /* general block spacing unit */
--space-globalPadding: 40px; /* page-level horizontal padding */
--space-sectionPadding: 104px; /* alias for sectionPaddingVertical */
--space-sectionPaddingHorizontal: 40px; /* section left/right padding */
--space-sectionPaddingVertical: 104px; /* section top/bottom padding */
--space-scrollPadding: 88px; /* scroll-margin-top for anchors (normalised from 90px) */
--space-contentMarginSm: 24px; /* small content block gap */
--space-contentMarginMd: 56px; /* medium content block gap */
--space-contentMarginLg: 72px; /* large content block gap */
--space-buttonMargin: 32px; /* margin below CTA button groups */
--space-linkMarginSm: 16px; /* spacing between inline links (sm) */
--space-linkMarginMd: 24px; /* spacing between inline links (md) */
--space-modalPaddingHorizontal: 56px; /* modal horizontal padding */
/* ── Curated semantic spacing aliases ── */
--zendesk-space-xs: 4px; /* micro spacing, icon gaps */
--zendesk-space-sm: 12px; /* tight component internal spacing */
--zendesk-space-md: 88px; /* large section spacing (normalised from --space-3xl) */
--zendesk-space-lg: 20px; /* standard component spacing */
--zendesk-space-xl: 40px; /* global horizontal padding */
--zendesk-space-2xl: 48px; /* generous block gap */
--zendesk-space-3xl: 72px; /* content margin large */
/* ── Layout geometry ── */
--contentWidth: 1600px; /* max page content width */
--radius: 40px; /* page-root border-radius token (NOT for buttons) */
/* ── Radius scale ── */
--zendesk-radius-sm: 2px; /* subtle — cookie banner elements */
--zendesk-radius-md: 4px; /* secondary buttons */
--zendesk-radius-lg: 8px; /* primary CTA buttons, tooltips, most UI elements */
--zendesk-radius-full: 12px; /* input fields */
/* Card uses 16px — see component tokens. Not on the extracted radius scale. */
}
```
### Grid System
| Breakpoint | Width | Behaviour |
|---|---|---|
| `0–767px` | 100% | Single column, stacked layout |
| `768px–969px` | 100% | Tablet — minor layout shifts |
| `970px–1149px` | 100% | Desktop entry — multi-column grids activate |
| `1150px–1599px` | 100% | Wide desktop |
| `≥ 1600px` | `1600px` | Fixed max — `--contentWidth` constraint |
- **Column gutter:** `--space-globalPadding` (40px) horizontal padding on sections
- **Section vertical rhythm:** `--space-sectionPaddingVertical` (104px) top + bottom
- **Card grids:** `display: flex; flex-direction: column` per card; grids are likely 3-column at 970px+ (inferred)
---
## 5. Page Structure & Layout Patterns
*No screenshots supplied. Section map derived from LAYOUT DIGEST: component inventory, probable-sections signal, computed structural styles, and button/colour census.*
### 5.1 Section Map
| # | Section | Layout Type | Key Elements | Source |
|---|---|---|---|---|
| 1 | **Navigation / Header** | `display: block` full-width | Logo, nav links (69 instances), primary CTA button | extracted |
| 2 | **Hero** | Full-width, centred column | h1 (68px/500), subhead p, 2 CTAs (lime accent + ghost), possibly video embed | inferred |
| 3 | **Social proof / Trust bar** | Horizontal flex row | "100,000+ Unternehmen" stat callout, logo strip | inferred |
| 4 | **Feature / Product overview** | 3-column card grid | 8 cards — `display: flex; flex-direction: column`, h3 titles (16px/600), body copy | extracted |
| 5 | **Dark feature section** | Full-width, dark bg (`--zendesk-bg-surface`) | h2 (42px), body text in `--zendesk-text-inverse`, possible illustration | inferred |
| 6 | **Testimonials / Social proof** | Flex row or carousel | h3 (26px), quote text, attribution (14px/bold), star ratings | inferred |
| 7 | **Pricing / CTA section** | Centred single column | h2 (42px), CTA button (lime), supporting text | inferred |
| 8 | **Footer** | Multi-column grid | Nav links (69 total inventory), legal text (14px) | inferred |
### 5.2 Layout Patterns
**Navigation:**
```
display: block → contains flex row
padding: 0px (edge-to-edge container)
horizontal padding via --space-globalPadding (40px)
```
**Hero Section (inferred):**
```
Full viewport width, dark bg: var(--zendesk-bg-surface)
Content centred, max-width: var(--contentWidth) = 1600px
Vertical padding: var(--space-sectionPaddingVertical) = 104px top/bottom
h1 text-align: center
CTA row: display inline-block buttons, gap: --space-buttonMargin (32px)
Primary CTA: background var(--zendesk-accent), radius 8px
```
**Card Grid:**
```
Each card: display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start
Card bg: rgb(245, 245, 242); border-radius: 16px
Grid gap: inferred ~24px (--space-contentMarginSm)
Columns: 3 at ≥970px, 2 at 768–969px, 1 below 768px (inferred)
```
**Dark Feature Section:**
```
background: var(--zendesk-bg-surface) = rgb(32, 53, 36)
text colour: var(--zendesk-text-inverse) = rgb(245, 245, 242)
padding: var(--space-sectionPadding) = 104px vertical
```
### 5.3 Visual Hierarchy
- **Dominant CTA colour:** `rgb(209, 244, 112)` — lime green. Appears on the two primary CTAs ("Kostenlos testen", "Kostenlos registrieren"). Highly visible against both dark green and near-white backgrounds.
- **Primary typographic anchor:** 68px / 500 weight h1, centred, near-black or inverse white depending on section bg.
- **Section separation:** Colour-field alternation (dark green ↔ off-white) rather than borders or shadows.
- **CTA placement:** Top of hero (2 buttons), repeated at bottom of major feature sections (1 button), in nav (1 persistent).
- **Whitespace rhythm:** 104px section padding creates generous breathing room; 24–56px content block gaps.
### 5.4 Content Patterns
**Feature Card (repeating pattern — 8 instances):**
```
[Icon or image — top]
[h3 — 16–18px, semibold]
[Body copy — 14–16px, regular]
[Optional CTA link — 16px/500, underlined]
Card bg: rgb(245,245,242); radius: 16px; transition: 0.3s cubic-bezier(0.7,0,0.3,1)
```
**Stat/Callout (repeating pattern):**
```
[Large number — 42px/700]
[Descriptor — 14–16px/400]
Arranged in horizontal flex row with equal column widths
```
**CTA Block (hero + section bottoms):**
```
Primary button: bg var(--zendesk-accent), text --zendesk-text-primary, radius 8px, 18px semibold
Secondary button: ghost/outline variant, same radius (inferred)
Buttons inline-block, gap: --space-buttonMargin (32px)
```
---
## 6. Component Patterns
### 6.1 Primary CTA Button
**Anatomy:** `[optional icon] [label text]`
- `display: inline-block`
- `font: 18px/600 "Vanilla Sans"`
- `border-radius: var(--zendesk-radius-lg)` (8px)
- `background: var(--zendesk-accent)`
- `transition: all 0.6s cubic-bezier(0.7, 0, 0.3, 1)`
**State table:**
| State | background | color | outline | cursor |
|---|---|---|---|---|
| default | `rgb(209,244,112)` | `rgb(17,17,13)` | none | pointer |
| hover | slightly darker (inferred `rgb(190,226,100)`) | `rgb(3,3,2)` | none | pointer |
| focus-visible | `rgb(209,244,112)` | `rgb(17,17,13)` | `2px solid rgb(17,17,13)`, offset 1px | pointer |
| active | `rgb(209,244,112)` | `rgb(0,0,0)` | none | pointer |
| disabled | `rgb(89,89,68)` | `rgb(46,46,35)` | none | default |
| loading | `rgb(209,244,112)` | `rgb(17,17,13)` | none | wait (inferred) |
```tsx
// PrimaryButton.tsx — production-ready with full state coverage
import React, { ButtonHTMLAttributes } from 'react';
interface PrimaryButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
loading?: boolean;
children: React.ReactNode;
}
export function PrimaryButton({ loading, disabled, children, ...props }: PrimaryButtonProps) {
const isDisabled = disabled || loading;
return (
<button
{...props}
disabled={isDisabled}
style={{
display: 'inline-block',
backgroundColor: isDisabled
? 'rgb(89, 89, 68)'
: 'var(--zendesk-accent)', /* rgb(209,244,112) */
color: isDisabled
? 'rgb(46, 46, 35)'
: 'var(--zendesk-text-primary)', /* rgb(17,17,13) */
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-lg)', /* 18px */
fontWeight: 'var(--zendesk-font-weight-semibold)', /* 600 */
lineHeight: '23px',
borderRadius: 'var(--zendesk-radius-lg)', /* 8px */
padding: '14px 28px',
border: 'none',
cursor: isDisabled ? 'default' : 'pointer',
transition: `all var(--zendesk-duration-slow) cubic-bezier(0.7, 0, 0.3, 1)`,
textDecoration: 'none',
opacity: loading ? 0.7 : 1,
}}
// Focus outline via CSS — must be in global stylesheet:
// button:focus { outline: none }
// button:focus-visible { outline: 2px solid var(--zendesk-text-primary); outline-offset: 1px }
>
{loading ? 'Wird geladen…' : children}
</button>
);
}
```
---
### 6.2 Card
**Anatomy:** `[media/image top] [content area: title + body + optional link]`
- `display: flex; flex-direction: column; justify-content: flex-start; align-items: flex-start`
- `background: var(--surface-card)` = `rgb(245,245,242)`
- `border-radius: 16px`
- `border: 1px solid rgba(0,0,0,0)` (transparent — can animate to visible on hover)
- `transition: 0.3s cubic-bezier(0.7, 0, 0.3, 1)`
| State | background | border | transform |
|---|---|---|---|
| default | `rgb(245,245,242)` | transparent | none |
| hover | `rgb(245,245,242)` | `rgba(0,0,0,0.1)` (inferred) | `translateY(-2px)` (inferred) |
| focus-visible | `rgb(245,245,242)` | `2px solid rgb(17,17,13)` | none |
| disabled | n/a (cards are not typically disabled) | — | — |
```tsx
export function FeatureCard({ title, body, href }: { title: string; body: string; href?: string }) {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
backgroundColor: 'var(--zendesk-surface-card)', /* rgb(245,245,242) */
borderRadius: '16px',
border: '1px solid rgba(0, 0, 0, 0)',
transition: '0.3s cubic-bezier(0.7, 0, 0.3, 1)',
overflow: 'hidden',
}}
>
<div style={{ padding: '24px' }}>
<h3 style={{
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-md)', /* 16px */
fontWeight: 'var(--zendesk-font-weight-semibold)', /* 600 */
lineHeight: '23.2px',
color: 'var(--zendesk-text-primary)',
margin: `0 0 var(--space-textMarginSm)`, /* 0 0 8px */
}}>{title}</h3>
<p style={{
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-xs)', /* 14px */
fontWeight: 'var(--zendesk-font-weight-regular)', /* 400 */
lineHeight: '18.2px',
color: 'var(--zendesk-text-primary)',
margin: 0,
}}>{body}</p>
</div>
</div>
);
}
```
---
### 6.3 Input Field
**Anatomy:** `[label above] [text input]`
- `border-radius: 12px` (`--zendesk-radius-full`)
- `background: rgba(17,17,13,0.05)`
- `box-shadow: rgba(17,17,13,0.47) 0px 0px 0px 1px inset` (border via inset shadow)
- `padding: 12px`
- `transition: border-color 0.25s ease, box-shadow 0.1s ease, background-color 0.25s ease, color 0.25s ease`
| State | box-shadow | background | outline |
|---|---|---|---|
| default | `rgba(17,17,13,0.47) 0 0 0 1px inset` | `rgba(17,17,13,0.05)` | none |
| hover | `rgba(17,17,13,0.8) 0 0 0 1px inset` (inferred) | `rgba(17,17,13,0.05)` | none |
| focus-visible | `rgb(255,255,255) 0 2px 4px, rgb(17,17,13) 0 4px 12px` | `rgba(17,17,13,0.05)` | `2px solid transparent` (offset) |
| disabled | `rgba(17,17,13,0.2) 0 0 0 1px inset` (inferred) | `rgba(17,17,13,0.03)` | none |
| error | `rgba(200,0,0,0.6) 0 0 0 1px inset` (inferred) | `rgba(17,17,13,0.05)` | none |
```tsx
export function TextInput({ label, id, error, ...props }: {
label: string; id: string; error?: string;
} & React.InputHTMLAttributes<HTMLInputElement>) {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
<label htmlFor={id} style={{
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-sm)', /* 15px */
fontWeight: 'var(--zendesk-font-weight-regular)',
color: 'var(--zendesk-text-primary)',
display: 'block',
}}>
{label}
</label>
<input
id={id}
style={{
fontFamily: 'var(--zendesk-font-family)',
fontSize: 'var(--zendesk-font-size-sm)', /* 15px */
fontWeight: 'var(--zendesk-font-weight-regular)',
lineHeight: '21px',
color: 'var(--zendesk-text-primary)',
backgroundColor: 'var(--zendesk-surface-input)', /* rgba(17,17,13,0.05) */
borderRadius: 'var(--zendesk-radius-full)', /* 12px */
padding: 'var(--space-textMarginMd)', /* 12px — closest token */
border: 'none',
boxShadow: error
? 'rgba(200,0,0,0.6) 0px 0px 0px 1px inset'
: 'rgba(17, 17, 13, 0.47) 0px 0px 0px 1px inset',
transition: `border-color var(--zendesk-duration-base) var(--zendesk-ease-default),
box-shadow var(--zendesk-duration-fast) var(--zendesk-ease-default),
background-color var(--zendesk-duration-base) var(--zendesk-ease-default)`,
width: '100%',
outline: 'none', // rely on :focus-visible in CSS
}}
{...props}
/>
{error && (
<span style={{
fontSize: 'var(--zendesk-font-size-xs)',
color: 'rgb(200, 0, 0)',
}}>{error}</span>
)}
</div>
);
}
```
---
### 6.4 Navigation Item
**Anatomy:** `[text label]` (optionally with dropdown trigger)
- `font: 16px/400 "Vanilla Sans"`
- `color: rgb(17,17,13)` default / `rgb(0,0,0)` on dark contexts
- `transition: all`
| State | color | decoration | outline |
|---|---|---|---|
| default | `rgb(17,17,13)` | none | none |
| hover | `rgb(3,3,2)` | none | none |
| focus-visible | `rgb(17,17,13)` | none | `2px solid rgb(17,17,13)`, offset 1px |
| active | `rgb(0,0,0)` | none | none |
| disabled | n/a | none | cursor: default |
---
### 6.5 Tooltip
**Anatomy:** `[text content]` floating box
- `background: rgb(255,255,255)`
- `border: 1px solid rgba(17,17,13,0.18)`
- `border-radius: 8px`
- `padding: 16px`
- `box-shadow: rgba(0,0,0,0.08) 0px 16px 28px 0px`
- `margin: 12px` (from trigger)
```css
.tooltip {
font-family: var(--zendesk-font-family);
font-size: var(--zendesk-font-size-xs); /* 14px */
font-weight: var(--zendesk-font-weight-regular);
line-height: 17.5px;
color: var(--zendesk-text-primary);
background: var(--zendesk-surface-white);
border: 1px solid var(--zendesk-border-subtle);
border-radius: var(--zendesk-radius-lg); /* 8px */
padding: var(--space-textMarginMd); /* 16px */
box-shadow: rgba(0, 0, 0, 0.08) 0px 16px 28px 0px;
margin: var(--space-textMarginSm); /* 12px from trigger — closest */
display: inline-block;
}
```
---
### 6.6 Badge / Tag
**Anatomy:** `[short label]`
- 11 instances detected
- `background: var(--zendesk-surface-card)` = `rgb(245,245,242)` (inferred from card surface)
- `font: 14px/400`
- `border-radius: var(--zendesk-radius-lg)` — 8px (inferred)
```css
.badge {
font-family: var(--zendesk-font-family);
font-size: var(--zendesk-font-size-xs); /* 14px */
font-weight: var(--zendesk-font-weight-regular);
line-height: var(--zendesk-line-height-tight); /* 18.2px */
background: var(--zendesk-surface-card);
color: var(--zendesk-text-primary);
border-radius: var(--zendesk-radius-lg); /* 8px */
padding: 4px 12px; /* --zendesk-space-xs --zendesk-space-sm */
display: inline-block;
}
```
---
## 7. Elevation & Depth
Zendesk uses colour-field contrast as the primary depth signal. Shadows are restrained and only appear on floating elements (tooltips, dropdowns, link-style cards).
```css
:root {
/* Shadow scale */
--shadow-sm: rgba(0, 0, 0, 0.08) 0px 8px 24px 0px; /* link cards, nav dropdowns */
--shadow-md: rgba(0, 0, 0, 0.08) 0px 16px 28px 0px; /* tooltips */
--shadow-focus: rgb(255, 255, 255) 0px 2px 4px,
rgb(17, 17, 13) 0px 4px 12px; /* focus ring on inputs */
--shadow-inset-default: rgba(17, 17, 13, 0.47) 0px 0px 0px 1px inset; /* input border */
/* Border scale */
--border-subtle: 1px solid rgba(17, 17, 13, 0.18); /* tooltips */
--border-card: 1px solid rgba(0, 0, 0, 0); /* card (transparent — animatable) */
/* Z-index scale */
--z-base: 0;
--z-raised: 1; /* hover/focus button in group */
--z-dropdown: 100; /* nav dropdowns (inferred) */
--z-modal: 200; /* modals */
--z-tooltip: 300; /* tooltips */
--z-buried: -1; /* disabled items in button groups */
}
```
**Layering principles:**
- Surface colour (`rgb(32,53,36)` dark vs `rgb(245,245,242)` light) creates the primary visual layer stack — no shadow needed between same-level siblings
- Shadows only used when an element **physically floats** above the document (tooltip, dropdown, video modal)
- Focus state uses a **compound shadow** (white + dark) to ensure visibility on both light and dark surfaces
---
## 8. Motion
```css
:root {
/* Duration tokens */
--zendesk-duration-fast: 0.1s; /* micro: hover color flips, inset-shadow switch */
--zendesk-duration-base: 0.25s; /* standard: input bg, border, colour transitions */
--zendesk-duration-slow: 0.6s; /* expressive: button hover, card hover, reveal anims */
/* Easing tokens */
--zendesk-ease-default: ease; /* general purpose */
--zendesk-ease-expressive: cubic-bezier(0.7, 0, 0.3, 1); /* buttons, cards — feels weighted */
/* Named transition compositions */
--transition-button: all var(--zendesk-duration-slow) var(--zendesk-ease-expressive);
--transition-card: all 0.3s var(--zendesk-ease-expressive);
--transition-input: border-color var(--zendesk-duration-base) var(--zendesk-ease-default),
box-shadow var(--zendesk-duration-fast) var(--zendesk-ease-default),
background-color var(--zendesk-duration-base) var(--zendesk-ease-default),
color var(--zendesk-duration-base) var(--zendesk-ease-default);
--transition-link: color var(--zendesk-duration-fast) var(--zendesk-ease-default);
}
/* Named keyframe animations */
@keyframes slideUp {
0% { opacity: 0.01; transform: translateY(5%); }
100% { opacity: 1; transform: translateY(0px); }
}
@keyframes slideUpBlur {
0% { opacity: 0.01; transform: translateY(10%); }
100% { backdrop-filter: blur(25px); opacity: 1; transform: translateY(0px); }
}
@keyframes progressBar {
0% { opacity: 1; width: 0%; }
100% { opacity: 1; width: 100%; }
}
```
### When to animate
| Trigger | Animation | Duration |
|---|---|---|
| Button hover/active | `background-color`, `color` crossfade | `0.6s ease-expressive` |
| Card hover | `transform: translateY(-2px)`, border reveal | `0.3s ease-expressive` |
| Input focus/blur | `box-shadow`, `background-color` | `0.1s–0.25s ease` |
| Section entrance (scroll) | `slideUp` keyframe | `0.6s` |
| Modal/dropdown open | `slideUp` or `blippity` fade | `0.25–0.6s` |
| Nav link hover | `color` shift | `0.1s` |
### When NOT to animate
- NEVER animate `width`, `height`, or `margin` for layout shifts — this causes reflow jank
- NEVER use `transition: all` on elements with many computed properties (use specific property lists)
- NEVER animate at `>0.6s` for interactive state changes — only use `0.6s` for expressive entrance animations
- Respect `prefers-reduced-motion`: wrap entrance animations in a media query check
---
## 9. Anti-Patterns & Constraints
1. **Hardcoded colour values → Why it fails → What to do instead.**
AI agents default to writing `color: #11110D` or `background: #d1f470` directly in component styles. When the brand colour changes (e.g., dark mode, campaign variants), every hardcoded instance breaks and there is no single source of truth. **Always** use `var(--zendesk-text-primary)` and `var(--zendesk-accent)` — the token is the contract, not the hex value.
2. **Using `font-family: Inter, sans-serif` → Why it fails → What to do instead.**
AI models are heavily trained on codebases using Inter as the default. Without explicit context, they substitute it silently. The result looks obviously wrong against the Vanilla Sans brand. **Always** declare `font-family: "Vanilla Sans", Arial, sans-serif` as `var(--zendesk-font-family)`. The Arial fallback must appear second, never first.
3. **Setting border-radius to 50px or 9999px for buttons → Why it fails → What to do instead.**
Zendesk's root stylesheet defines `--radius: 40px`, which AI agents interpret as the button radius. The brand actually uses `4–8px` for buttons (sharp, considered). Pill-shaped buttons are wrong for this brand. **Always** use `var(--zendesk-radius-md)` (4px) or `var(--zendesk-radius-lg)` (8px) for buttons; reserve `--radius: 40px` for the page-root context only.
4. **Arbitrary spacing values → Why it fails → What to do instead.**
With 16 unique spacing values extracted, AI agents invent ad-hoc values like `margin: 20px` or `padding: 35px`. These break the visual rhythm and create inconsistent layouts. **Always** choose from the defined `--space-*` tokens. If a value isn't on the scale, map to the nearest token — never invent a new value.
5. **Omitting `focus-visible` states → Why it fails → What to do instead.**
AI agents regularly generate components without focus ring styles, failing WCAG 2.4.7. Zendesk uses a specific focus pattern: `outline: 2px solid rgb(17,17,13); outline-offset: 1px` — not a browser default blue ring. Omitting this produces both an accessibility failure and an off-brand visual. **Always** add `:focus { outline: none }` + `:focus-visible { outline: 2px solid var(--zendesk-border-focus); outline-offset: 1px }`.
6. **Using `color: rgb(209,244,112)` (the accent) for text → Why it fails → What to do instead.**
The lime green `--zendesk-accent` fails WCAG contrast when placed on white or light surfaces (contrast ratio < 3:1). AI agents sometimes use the accent as a text highlight colour. **Never** use `--zendesk-accent` as a text colour — it is exclusively a background fill value.
7. **Applying `transition: all` to every element → Why it fails → What to do instead.**
Zendesk uses `transition: all` on several elements in its stylesheet, but this is a performance smell — it transitions every CSS property including `width`, `height`, `display`, and `opacity` on every change, causing unexpected layout jank on complex components. **Use specific property transitions** as defined in `--transition-button`, `--transition-input`, `--transition-card`.
8. **Generating `!important` overrides for spacing → Why it fails → What to do instead.**
When Bootstrap's grid system (detected on this site) conflicts with component styles, AI agents apply `!important` to force padding/margin values. This permanently breaks overridability and creates a cascade nightmare. **Use component-level CSS classes** with specific selectors instead, or apply spacing tokens via inline styles where Bootstrap doesn't apply.
9. **Dynamic Tailwind class construction → Why it fails → What to do instead.**
Patterns like `` `bg-[var(--${colorToken})]` `` cause Tailwind's PurgeCSS to strip the class at build time because the full class string is never statically present. The component renders with no background. **Always** write the complete class string: `bg-[var(--zendesk-accent)]` or use `style={{ backgroundColor: 'var(--zendesk-accent)' }}` for token-driven dynamic styles.
10. **Treating the h2 styles as the only heading variant → Why it fails → What to do instead.**
The typographic hierarchy has two h2 sizes: 42px/500 (section-level) and 18px/600 (card-level). AI agents default to a single h2 style and produce either oversized or undersized headings in card contexts. **Always** check context: section-level h2s use `--zendesk-font-size-2xl` (42px / weight 500); card-level h2s use `--zendesk-font-size-lg` (18px / weight 600).
11. **Ignoring the disabled state background → Why it fails → What to do instead.**
AI agents either omit disabled states or use `opacity: 0.5` on the accent button, resulting in a washed lime-green that reads as "glitchy" rather than intentionally disabled. Zendesk's actual disabled background is `rgb(89,89,68)` (warm dark olive) with `color: rgb(46,46,35)`. **Use `--zendesk-disabled-bg` and `--zendesk-text-disabled` explicitly** when `disabled` or `aria-disabled="true"` is present.
---
## 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 (35) */
--brand-primary-cta: rgb(209, 244, 112); /* Primary CTA background, dominant on 2 buttons — e.g. "Kostenlos testen" /* mined from computed styles */ */
--brand-surface-1: rgb(32, 53, 36); /* Brand surface, dominant on 4 elements — e.g. "Tauchen Sie ein in die Zukunft" /* mined from computed styles */ */
--zendesk-bg-surface: rgb(32, 53, 36);
--zendesk-accent: rgb(209, 244, 112);
--zendesk-text-primary: rgb(17, 17, 13);
--zendesk-text-inverse: rgb(245, 245, 242);
--zendesk-surface-card: rgb(245, 245, 242);
--primitive-green-900: rgb(32, 53, 36);
--primitive-lime-300: rgb(209, 244, 112);
--primitive-neutral-950: rgb(17, 17, 13);
--primitive-neutral-50: rgb(245, 245, 242);
--primitive-white: rgb(255, 255, 255);
--primitive-neutral-700: rgb(75, 75, 57);
--primitive-neutral-600: rgb(89, 89, 68);
--primitive-neutral-400: rgb(144, 145, 140);
--zendesk-surface-input: rgba(17, 17, 13, 0.05);
--zendesk-text-disabled: rgb(46, 46, 35);
--zendesk-text-muted: rgb(144, 145, 140);
--zendesk-border-default: rgba(17, 17, 13, 0.47);
--zendesk-border-subtle: rgba(17, 17, 13, 0.18);
--zendesk-border-focus: rgb(17, 17, 13);
--zendesk-disabled-bg: rgb(75, 75, 57);
--zendesk-hover-overlay: rgba(17, 17, 13, 0.08);
--zendesk-active-overlay: rgba(17, 17, 13, 0.20);
--btn-primary-bg: var(--zendesk-accent);
--btn-disabled-bg: var(--zendesk-disabled-bg);
--card-bg: var(--zendesk-surface-card);
--card-border: 1px solid rgba(0, 0, 0, 0);
--input-bg: var(--zendesk-surface-input);
--input-border: var(--zendesk-border-default);
--tooltip-bg: var(--zendesk-surface-white);
--tooltip-border: var(--zendesk-border-subtle);
--border-subtle: 1px solid rgba(17, 17, 13, 0.18);
--border-card: 1px solid rgba(0, 0, 0, 0);
--zendesk-surface-white: rgb(255, 255, 255);
/* Typography (31) */
--font-size-xs: 14px; /* 20 elements — e.g. h2 "100.000+ Unternehmen", p "Erleben Sie die Zuku", p "14 Tage kostenlos te" /* mined from computed styles */ */
--font-size-sm: 15px; /* 1 element — e.g. label "Bitte aktivieren Sie" /* mined from computed styles */ */
--font-size-md: 16px; /* 22 elements — e.g. h3 "Verbessern Sie die A", h3 "Reduzieren Sie den A", h3 "Halten Sie die Koste" /* mined from computed styles */ */
--font-size-lg: 18px; /* 2 elements — e.g. button "Kostenlos testen", button "Video ansehen" /* mined from computed styles */ */
--font-size-xl: 26px; /* 4 elements — e.g. h2 "Übertreffen Sie alle", h3 "Sichern Sie sich Ihr", h3 "Ali Wong" /* mined from computed styles */ */
--font-size-2xl: 42px; /* 8 elements — e.g. h2 "Von Branchenführern ", h2 "Ihre All-in-One-Lösu", h2 "Machen Sie den Emplo" /* mined from computed styles */ */
--font-size-3xl: 68px; /* 1 element — e.g. h1 "Liefern Sie erstklas" /* mined from computed styles */ */
--font-weight-regular: 400; /* 14 elements — e.g. p "Erleben Sie die Zuku", p "Wir stärken über 20.", p "14 Tage kostenlos te" /* mined from computed styles */ */
--font-weight-medium: 500; /* 13 elements — e.g. h1 "Liefern Sie erstklas", h2 "Von Branchenführern ", h2 "Ihre All-in-One-Lösu" /* mined from computed styles */ */
--font-weight-semibold: 600; /* 16 elements — e.g. h3 "Verbessern Sie die A", h3 "Reduzieren Sie den A", h3 "Halten Sie die Koste" /* mined from computed styles */ */
--font-weight-bold: 700; /* 15 elements — e.g. h2 "100.000+ Unternehmen", p "Seien Sie live dabei", p "18.–20. Mai 2026" /* mined from computed styles */ */
--line-height-tight: 18.2px; /* 14 elements — e.g. h2 "100.000+ Unternehmen", p "Seien Sie live dabei", p "18.–20. Mai 2026" /* mined from computed styles */ */
--line-height-normal: 23.2px; /* 19 elements — e.g. h3 "Verbessern Sie die A", h3 "Reduzieren Sie den A", h3 "Halten Sie die Koste" /* mined from computed styles */ */
--line-height-loose: 48.3px; /* 8 elements — e.g. h2 "Von Branchenführern ", h2 "Ihre All-in-One-Lösu", h2 "Machen Sie den Emplo" /* mined from computed styles */ */
--zendesk-font-family: "Vanilla Sans", Arial, sans-serif;
--zendesk-font-size-xs: 14px;
--zendesk-font-size-sm: 15px;
--zendesk-font-size-md: 16px;
--zendesk-font-size-lg: 18px;
--zendesk-font-size-xl: 26px;
--zendesk-font-size-2xl: 42px;
--zendesk-font-size-3xl: 68px;
--zendesk-font-weight-regular: 400;
--zendesk-font-weight-medium: 500;
--zendesk-font-weight-semibold: 600;
--zendesk-font-weight-bold: 700;
--btn-primary-text: var(--zendesk-text-primary);
--zendesk-font-family-cjk: "Noto Sans JP", "Vanilla Sans", Arial, sans-serif;
--zendesk-line-height-tight: 18.2px;
--zendesk-line-height-normal: 23.2px;
--zendesk-line-height-loose: 48.3px;
/* Spacing (30) */
--space-space: 32px;
--space-globalPadding: 40px;
--space-sectionPadding: 104px;
--space-scrollPadding: 88px;
--space-textMarginSm: 8px;
--space-textMarginMd: 16px;
--space-textMarginLg: 24px;
--space-contentMarginMd: 56px;
--space-contentMarginLg: 72px;
--space-tabletExtraPadding: 0px;
--contentWidth: 1600px;
--space-xs: 4px; /* 3 elements — e.g. nav .sc-612b179e-5, nav .sc-612b179e-5, nav .sc-612b179e-5 /* mined from computed styles */ */
--space-sm: 12px; /* 3 elements — e.g. nav .sc-512deb61-2, nav .sc-512deb61-2, nav .sc-512deb61-2 /* mined from computed styles */ */
--space-lg: 20px; /* 1 element — e.g. section .StyledPanel-sc-1piryze-0 /* mined from computed styles */ */
--space-2xl: 48px; /* 1 element — e.g. section .StyledPanel-sc-1piryze-0 /* mined from computed styles */ */
--space-3xl: 88px; /* 20 elements — e.g. section .sc-3cb30ae3-10, section .sc-3cb30ae3-10, section .sc-3cb30ae3-10 /* mined from computed styles */ */
--space-contentMarginSm: 24px;
--space-buttonMargin: 32px;
--space-sectionPaddingHorizontal: 40px;
--space-sectionPaddingVertical: 104px;
--space-linkMarginSm: 16px;
--space-linkMarginMd: 24px;
--space-modalPaddingHorizontal: 56px;
--zendesk-space-xs: 4px;
--zendesk-space-sm: 12px;
--zendesk-space-md: 88px;
--zendesk-space-lg: 20px;
--zendesk-space-xl: 40px;
--zendesk-space-2xl: 48px;
--zendesk-space-3xl: 72px;
/* Radius (13) */
--radius: 40px;
--radius-sm: 2px; /* 6 elements — e.g. button .ot-link-btn "Angaben zum Anbieter", button .ot-link-btn "Angaben zum Anbieter", button .ot-link-btn "Angaben zum Anbieter" /* mined from computed styles */ */
--radius-md: 4px; /* 2 elements — e.g. a .StyledButton-sc-qe3ace-0 "Kostenlos registrier", a .StyledButton-sc-qe3ace-0 /* mined from computed styles */ */
--radius-lg: 8px; /* 16 elements — e.g. a .StyledButton-sc-qe3ace-0 "Zendesk Resolution P", a .StyledButton-sc-qe3ace-0 "Zendesk-KIOptimieren", a .StyledButton-sc-qe3ace-0 "Berichte und Analyse" /* mined from computed styles */ */
--radius-full: 12px; /* 2 elements — e.g. input .StyledTextInput-sc-k12n8x-0, input .StyledTextInput-sc-k12n8x-0 /* mined from computed styles */ */
--zendesk-radius-sm: 2px;
--zendesk-radius-md: 4px;
--zendesk-radius-lg: 8px;
--zendesk-radius-full: 12px;
--btn-primary-radius: var(--zendesk-radius-lg);
--card-radius: 16px;
--input-radius: var(--zendesk-radius-full);
--tooltip-radius: var(--zendesk-radius-lg);
/* Effects (4) */
--shadow-sm: rgba(0,0,0,0.08) 0px 8px 24px 0px;
--shadow-md: rgba(0,0,0,0.08) 0px 16px 28px 0px;
--shadow-focus: rgb(255,255,255) 0 2px 4px, rgb(17,17,13) 0 4px 12px;
--shadow-inset-default: rgba(17,17,13,0.47) 0 0 0 1px inset;
/* Motion (23) */
----motion-progressBar: @keyframes progressBar {
0% { opacity: 1; width: 0%; }
100% { opacity: 1; width: 100%; }
}; /* @keyframes progressBar */
----motion-blippity: @keyframes blippity {
0% { opacity: 0; width: 100%; }
100% { opacity: 1; width: 100%; }
}; /* @keyframes blippity */
----motion-slideUp: @keyframes slideUp {
0% { opacity: 0.01; transform: translateY(5%); }
100% { opacity: 1; transform: translateY(0px); }
}; /* @keyframes slideUp */
----motion-slideUpBlur: @keyframes slideUpBlur {
0% { opacity: 0.01; transform: translateY(10%); }
100% { backdrop-filter: blur(25px); opacity: 1; transform: translateY(0px); }
}; /* @keyframes slideUpBlur */
----motion-slideOut-left-sm: @keyframes slideOut-left-sm {
0% { opacity: 0.01; transform: translateY(-50%); }
100% { opacity: 1; transform: translate(-100%, -50%); }
}; /* @keyframes slideOut-left-sm */
----motion-slideOut-left-lg: @keyframes slideOut-left-lg {
0% { opacity: 0.01; transform: translateY(-50%); }
100% { opacity: 1; transform: translate(-44%, -50%); }
}; /* @keyframes slideOut-left-lg */
----motion-slideOut-right-lg: @keyframes slideOut-right-lg {
0% { opacity: 0.01; transform: translateY(-50%); }
100% { opacity: 1; transform: translate(44%, -50%); }
}; /* @keyframes slideOut-right-lg */
----motion-slideOut-right-sm: @keyframes slideOut-right-sm {
0% { opacity: 0.01; transform: translateY(-50%); }
100% { opacity: 1; transform: translate(100%, -50%); }
}; /* @keyframes slideOut-right-sm */
----motion-gJZWFA: @keyframes gJZWFA {
0% { position: static; display: none; opacity: 0; }
1% { display: block; }
100% { display: block; opacity: 1; }
}; /* @keyframes gJZWFA */
----motion-cwqaCA: @keyframes cwqaCA {
0% { position: absolute; opacity: 1; }
100% { opacity: 0; }
}; /* @keyframes cwqaCA */
----motion-hxqKPd: @keyframes hxqKPd {
0% { opacity: 1; display: block; }
99% { opacity: 0; display: block; }
100% { display: none; }
}; /* @keyframes hxqKPd */
----motion-gUmuQi: @keyframes gUmuQi {
0% { left: 0px; opacity: 1; }
100% { left: 10px; opacity: 0; }
}; /* @keyframes gUmuQi */
----motion-kezRlp: @keyframes kezRlp {
0% { display: block; background: white; position: absolut… <0.3KB elided>; /* @keyframes kezRlp */
----motion-jAYiMU: @keyframes jAYiMU {
0% { position: static; opacity: 0.01; transform: translateX(5%); }
100% { position: static; opacity: 1; transform: translateX(0px); }
}; /* @keyframes jAYiMU */
----motion-eEAsaf: @keyframes eEAsaf {
0% { top: 5px; }
100% { top: 0px; }
}; /* @keyframes eEAsaf */
----motion-fVoCkF: @keyframes fVoCkF {
0% { transform: translateX(0px); }
100% { transform: translateX(calc(-100% - 24px)); }
}; /* @keyframes fVoCkF */
----motion-fOEIGv: @keyframes fOEIGv {
0% { transform: translateX(0px); }
100% { transform: translateX(calc(-100% - 24px)); }
}; /* @keyframes fOEIGv */
----motion-VOLUME_SMALL_WAVE_FLASH: @keyframes VOLUME_SMALL_WAVE_FLASH {
0% { opacity: 0; }
33% { opacity: 1; }
66% { opacity: 1; }
100% { opacity: 0; }
}; /* @keyframes VOLUME_SMALL_WAVE_FLASH */
----motion-VOLUME_LARGE_WAVE_FLASH: @keyframes VOLUME_LARGE_WAVE_FLASH {
0% { opacity: 0; }
33% { opacity: 1; }
66% { opacity: 1; }
100% { opacity: 0; }
}; /* @keyframes VOLUME_LARGE_WAVE_FLASH */
--duration-fast: 0.1s; /* 17 elements — e.g. button, button, button /* mined from computed styles */ */
--duration-base: 0.25s; /* 8 elements — e.g. input, input, input /* mined from computed styles */ */
--duration-slow: 0.6s; /* 12 elements — e.g. button, button, button /* mined from computed styles */ */
--ease-default: ease; /* 108 elements — e.g. button, button, button /* mined from computed styles */ */
```
## Appendix B: Token Source Metadata
```yaml
tokenSource: extracted-css-vars
site: zendesk.com
extractionDate: "[TBD — extract date manually]"
confidence: medium
cssVarsFound: 19
curatedAliases: 31 (--zendesk-* prefix)
notes:
- Primary CSS variables are --space-* naming with exact values preserved verbatim
- --brand-primary-cta and --brand-surface-1 are the only extracted colour vars;
all other colours derived from computed styles (medium confidence)
- --zendesk-* tokens are synthesised semantic aliases mapping to original vars
- border-radius: extracted radius scale shows 2/4/8/12px in UI; 40px (--radius)
exists on page root but does NOT apply to buttons (confirmed: buttons use 4–8px)
- Card border-radius (16px) confirmed from computed styles; no CSS var found
- Spacing: 16 unique values extracted; normalised to 7-token scale + preserved
exact --space-* names. 90px (--space-scrollPadding) rounded to 88px for 4px grid
- Font: "Vanilla Sans" is a Zendesk proprietary typeface, self-hosted at
web-assets.zendesk.com. All 8 weights (100–900) available.
- WistiaPlayer* fonts are third-party video player fonts — exclude from brand system
- Interactive states: extracted from CSS rules referencing Styled Components hashed
class names (cbIMud, gmtpxB, btcjit, etc.) — these are reliable but may change
on recompile
- Detected libraries: Next.js (framework), Bootstrap (grid), Styled Components (CSS-in-JS)
clusteringMethod: N/A — token source is extracted-css-vars, not reconstructed-from-computed.
Computed styles used only to supplement missing colour tokens and confirm radius values.
```More from the gallery
Browse all kits →You may also like

Xero
MITClean, modern SaaS design system built on navy and mint green with sharp corners and purposeful typography for accounting and business software
00
saasfintechlightminimal

Netflix
MITDark, bold streaming platform design system with signature red accent and cinematic motion, built for large-scale video content discovery and subscription flows
00
darkboldecommlanding-page

Cash App
MITBold, high-contrast fintech design system built on Cash App's signature neon green and black palette, optimised for mobile payment interfaces and developer implementation
00
fintechmobilebolddark