Shopify
MIT
Dark, sophisticated commerce design system with teals and blacks, optimised for merchant dashboards and high-conversion product pages
Layout StudioImport this kit into a Studio project and start editing.
CLI installRun it in any project. No account needed.
npx @layoutdesign/context install shopify# layout.md — Shopify.com Design System
---
## 0. Quick Reference
> Copy-paste into `CLAUDE.md` or `.cursorrules` for immediate AI context.
**Stack:** HTML/CSS with Tailwind + Bootstrap detected. Tokens reconstructed from computed styles (low confidence — 1 CSS custom property found). Use as `var(--shopify-*)` in CSS, `style={{ prop: 'var(--shopify-token)' }}` in JSX, or `bg-[var(--shopify-token)]` in Tailwind.
```css
:root {
/* Surface */
--shopify-bg-surface: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%);
--shopify-bg-card: rgb(2, 9, 10);
--shopify-color-text: rgb(255, 255, 255);
--shopify-color-text-muted: rgb(113, 113, 122);
/* Typography */
--shopify-font-display: NeueHaasGrotesk, Helvetica, Arial, sans-serif;
--shopify-font-body: "Shopify Sans", Helvetica, Arial, sans-serif;
--shopify-font-ui: Inter-Variable, Helvetica, Arial, sans-serif;
--shopify-font-size-sm: 14px; --shopify-font-size-md: 16px;
--shopify-font-size-xl: 20px; --shopify-font-size-2xl: 48px;
--shopify-font-size-h1: 96px; --shopify-font-size-3xl: 55px;
/* Spacing */
--shopify-space-md: 24px; --shopify-space-lg: 32px;
--shopify-space-xl: 40px; --shopify-space-2xl: 64px;
--shopify-space-3xl: 90px;
/* Radius */
--shopify-radius-sm: 4px; --shopify-radius-md: 12px;
--shopify-radius-full: 30px;
/* Motion */
--shopify-duration-fast: 0.2s; --shopify-duration-base: 0.3s;
--shopify-ease-default: ease;
}
```
```tsx
// Primary CTA Button — Shopify pill style
<button style={{
fontFamily: 'var(--shopify-font-body)',
fontSize: 'var(--shopify-font-size-sm)',
borderRadius: 'var(--shopify-radius-full)',
padding: '12px 24px',
background: '#fff',
color: '#000',
transition: `all var(--shopify-duration-base) var(--shopify-ease-default)`,
}}>
Start for free
</button>
```
**NEVER rules:**
- NEVER use `font-family: Inter` or `Arial` alone — always use the full stack with fallbacks
- NEVER use `border-radius > 30px` on buttons — pill = exactly `30px`
- NEVER use warm colours (reds, oranges, yellows) — palette is exclusively dark teal/green/black/white
- NEVER hardcode hex colours — always reference a `--shopify-*` token
- NEVER use spacing values not in the defined scale (24, 32, 40, 64, 90px)
- NEVER use font-weight values other than 330, 400, 500, 550 — these are non-standard, do not substitute 300/400/500/600
**Full design system → see layout.md**
---
## 1. Design Direction & Philosophy
### Character & Mood
Shopify's marketing site is **dark, refined, and technically authoritative**. The aesthetic is premium-dark: deep teal-to-near-black gradients, high-contrast white typography, and generous whitespace that communicates scale and confidence. The design conveys that Shopify is infrastructure — serious, reliable, and massive.
### Typographic Personality
Two distinct type roles: **NeueHaasGrotesk** (display/headings) carries editorial weight at extreme sizes (55–96px), while **Shopify Sans** (body/UI) maintains brand ownership at utility sizes. The heading weights are unusually light (330–400) at large sizes — the scale carries the hierarchy, not weight. This is a deliberate design choice: **do not compensate with heavier weights**.
### Aesthetic Constraints — What This Design Explicitly Rejects
- **No light backgrounds** — the brand surface is a dark teal gradient, never white or light grey
- **No warm colour accents** — the only accent is a muted teal/green from the gradient; no orange, yellow, or red UI elements
- **No sharp corners on interactive elements** — buttons use full pill radius (30px); cards use 12px; never 0px on clickable surfaces
- **No decorative illustration** — photography and product UI screenshots carry visual weight, not icons or illustrations
- **No tight spacing** — sections breathe with 64–90px vertical rhythm
- **No heavy font weights at large sizes** — display headings are weight 330–400, never 700+ at heading scale
- **No generic system fonts** — NeueHaasGrotesk and Shopify Sans are brand-owned; Inter-Variable is used only for form UI
---
## 2. Colour System
### Tier 1: Primitives
```css
/* ── Primitive Colour Values ── */
:root {
/* Teal family */
--primitive-teal-900: rgb(6, 21, 24); /* Deepest dark teal — gradient end */
--primitive-teal-800: rgb(2, 9, 10); /* Near-black teal — card backgrounds */
--primitive-teal-700: rgb(10, 44, 48); /* Mid dark teal — gradient start */
/* Neutral / Ink */
--primitive-white: rgb(255, 255, 255); /* Pure white */
--primitive-black: rgb(0, 0, 0); /* Pure black */
--primitive-zinc-500: rgb(113, 113, 122); /* Muted zinc — tab/inactive text */
/* Modal surface (inferred from oklch value) */
--primitive-surface-overlay: oklch(0.21 0.006 285.885); /* ~rgb(32,34,42) dark blue-grey modal */
/* Cookie banner accents — third-party UI, NOT brand design system */
--primitive-green-400: rgb(34, 197, 94); /* Cookie save hover — NOT brand */
--primitive-green-300: rgb(122, 235, 159);/* Cookie accept border hover — NOT brand */
--primitive-red-400: rgb(255, 102, 105); /* Cookie reject border hover — NOT brand */
}
```
### Tier 2: Semantic Aliases
```css
/* ── Semantic Colour Tokens ── */
:root {
/* Backgrounds */
--shopify-bg-surface: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%);
/* Primary page background — dark teal gradient */
/* reconstructed: medium confidence, inferred from body/page wrapper */
--shopify-bg-card: rgb(2, 9, 10);
/* Card/section dark background */
/* reconstructed: high confidence, from card element */
--shopify-bg-card-gradient: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%);
/* Feature card gradient background (cls_card) */
/* extracted: high confidence */
--shopify-bg-overlay: oklch(0.21 0.006 285.885);
/* Modal/drawer background — dark blue-grey */
/* extracted: high confidence, from modal element */
/* Text */
--shopify-color-text: rgb(255, 255, 255); /* Primary text — all headings, body on dark */
--shopify-color-text-muted: rgb(113, 113, 122); /* Inactive/tab/secondary text */
/* reconstructed: high confidence, from tab element */
/* Borders */
--shopify-color-border: rgb(229, 231, 235); /* Subtle border — light grey on dark */
/* reconstructed: low confidence — observed only on zero-width borders */
/* Interactive — cookie banner only, do not use in brand UI */
--shopify-color-interactive-save: rgb(34, 197, 94); /* Cookie save bg hover */
--shopify-color-interactive-accept: rgb(122, 235, 159); /* Cookie accept border hover */
--shopify-color-interactive-reject: rgb(255, 102, 105); /* Cookie reject border hover */
}
```
### Tier 3: Component Tokens
```css
/* ── Component Colour Applications ── */
:root {
/* Buttons */
--shopify-btn-primary-bg: rgb(255, 255, 255); /* White fill on dark surface */
/* reconstructed: moderate confidence, inferred from dark-bg context */
--shopify-btn-primary-text: rgb(0, 0, 0); /* Black text on white button */
--shopify-btn-primary-bg-hover: rgb(0, 0, 0); /* Inverts on hover */
--shopify-btn-primary-text-hover: rgb(255, 255, 255);
/* Cards */
--shopify-card-bg: rgb(2, 9, 10);
--shopify-card-bg-feature: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%);
/* Nav */
--shopify-nav-bg: rgba(0, 0, 0, 0); /* Transparent — overlays gradient surface */
--shopify-nav-text: rgb(255, 255, 255);
/* Modal */
--shopify-modal-bg: oklch(0.21 0.006 285.885);
--shopify-modal-text: rgb(255, 255, 255);
}
```
### Colour Usage Table
| Token | Value | Usage |
|---|---|---|
| `--shopify-bg-surface` | teal gradient | Page/section backgrounds |
| `--shopify-bg-card` | `rgb(2,9,10)` | Opaque card surfaces |
| `--shopify-bg-card-gradient` | teal gradient | Feature/highlight cards |
| `--shopify-color-text` | `#fff` | All primary text |
| `--shopify-color-text-muted` | `rgb(113,113,122)` | Inactive tabs, secondary labels |
| `--shopify-btn-primary-bg` | `#fff` | CTA button fill |
| `--shopify-btn-primary-text` | `#000` | CTA button label |
> ⚠️ The cookie banner (`#dux-privacy`) uses green/red hover states that belong to a **third-party consent library**, not the Shopify brand system. NEVER apply these colours to brand UI components.
---
## 3. Typography System
### Font Stack Declaration
```css
@font-face {
font-family: "Shopify Sans";
src: url("https://cdn.shopify.com/static/fonts/ShopifySans--regular.woff2") format("woff2"),
url("https://cdn.shopify.com/static/fonts/ShopifySans/ShopifySans-Regular.woff") format("woff");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Shopify Sans";
src: url("https://cdn.shopify.com/oxygen/static-assets/ShopifySans-Medium.woff2") format("woff2");
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Shopify Sans";
src: url("https://cdn.shopify.com/oxygen/static-assets/ShopifySans-Black.woff2") format("woff2");
font-weight: 900;
font-style: normal;
font-display: swap;
}
:root {
--shopify-font-display: NeueHaasGrotesk, Helvetica, Arial, sans-serif;
/* Headings & large display text only — extracted: high confidence */
--shopify-font-body: "Shopify Sans", Helvetica, Arial, sans-serif;
/* Body copy, buttons, links, nav — extracted: high confidence */
--shopify-font-ui: Inter-Variable, Helvetica, Arial, sans-serif;
/* Form inputs, labels, dropdowns, modals — extracted: high confidence */
}
```
### Weight Scale
```css
:root {
--shopify-font-weight-regular: 330; /* NeueHaasGrotesk light-ish — display headings */
--shopify-font-weight-medium: 400; /* Shopify Sans regular — body, h4, nav */
--shopify-font-weight-semibold: 500; /* Shopify Sans — emphasis, pullquotes */
--shopify-font-weight-bold: 550; /* Shopify Sans — primary CTAs, skip links */
}
```
> ⚠️ **These are non-standard numeric weights.** Do NOT substitute 300/400/500/600 — these exact values are required to trigger the correct font file via variable font axis.
### Composite Typography Groups
```css
:root {
/* ── DISPLAY / H1 ── */
/* font-family: var(--shopify-font-display) */
/* font-size: 96px */
/* font-weight: 400 (--shopify-font-weight-medium) */
/* line-height: 96px (1:1 — tight) */
/* letter-spacing: normal */
/* color: var(--shopify-color-text) */
/* margin-bottom: var(--shopify-space-2xl) [64px] */
/* extracted: high confidence from h1 computed styles */
/* ── HEADING / H2 ── */
/* font-family: var(--shopify-font-display) */
/* font-size: 96px */
/* font-weight: 400 */
/* line-height: 96px */
/* letter-spacing: 2.4px */
/* color: var(--shopify-color-text) */
/* margin-bottom: var(--shopify-space-lg) [32px] */
/* extracted: high confidence from h2 computed styles */
/* ── SECTION HEADING / H3 ── */
/* font-family: var(--shopify-font-display) */
/* font-size: 55px (--shopify-font-size-3xl) */
/* font-weight: 330 (--shopify-font-weight-regular) */
/* line-height: 64px */
/* letter-spacing: normal */
/* color: var(--shopify-color-text) */
/* extracted: high confidence from h3 computed styles */
/* ── SUBHEADING / H4 ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 20px (--shopify-font-size-xl) */
/* font-weight: 400 (--shopify-font-weight-medium) */
/* line-height: 28px (--shopify-line-height-loose) */
/* letter-spacing: normal */
/* color: var(--shopify-color-text) */
/* reconstructed: moderate confidence from h4 elements */
/* ── LARGE BODY / LEAD ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 18px (--shopify-font-size-lg) */
/* font-weight: 500 (--shopify-font-weight-semibold) */
/* line-height: 28px (--shopify-line-height-loose) */
/* letter-spacing: normal */
/* color: var(--shopify-color-text) */
/* reconstructed: moderate confidence — testimonial/pullquote role */
/* ── BODY ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 16px (--shopify-font-size-md) */
/* font-weight: 400 */
/* line-height: 24px (--shopify-line-height-normal) */
/* letter-spacing: normal */
/* color: var(--shopify-color-text) */
/* extracted: high confidence from card/p elements */
/* ── BODY SMALL ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 14px (--shopify-font-size-sm) */
/* font-weight: 400 */
/* line-height: 21px */
/* letter-spacing: normal */
/* extracted: high confidence — most frequent text size (119 elements) */
/* ── CAPTION / META ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 12px (--shopify-font-size-xs) */
/* font-weight: 400 */
/* line-height: 16px */
/* letter-spacing: normal */
/* reconstructed: moderate confidence */
/* ── UI / INPUT ── */
/* font-family: var(--shopify-font-ui) */
/* font-size: 16px (--shopify-font-size-md) */
/* font-weight: 400 */
/* line-height: 24px (--shopify-line-height-normal) */
/* letter-spacing: normal */
/* extracted: high confidence from input/dropdown computed styles */
/* ── LABEL / FORM ── */
/* font-family: var(--shopify-font-ui) */
/* font-size: 14px (--shopify-font-size-sm) */
/* font-weight: 400 */
/* line-height: 20px */
/* letter-spacing: normal */
/* extracted: high confidence from label computed styles */
/* ── BUTTON ── */
/* font-family: var(--shopify-font-body) */
/* font-size: 14px (--shopify-font-size-sm) */
/* font-weight: 400 */
/* line-height: 21px */
/* letter-spacing: normal */
/* extracted: high confidence from button_primary / role_button */
}
```
### Typography Pairing Rules
| Role | Font | Size | Weight |
|---|---|---|---|
| H1 / H2 (hero) | NeueHaasGrotesk | 96px | 400 |
| H3 (section) | NeueHaasGrotesk | 55px | **330** |
| H4 (sub-section) | Shopify Sans | 20px | 400 |
| Body / Card text | Shopify Sans | 16px | 400 |
| Body Small / CTA | Shopify Sans | 14px | 400–550 |
| Inputs / Form UI | Inter-Variable | 16px | 400 |
| Labels | Inter-Variable | 14px | 400 |
> **Critical:** NeueHaasGrotesk is DISPLAY ONLY — never use it for body, buttons, or UI. Shopify Sans is BRAND CONTENT — never use it for form elements. Inter-Variable is FORM UI ONLY.
---
## 4. Spacing & Layout
```css
:root {
/* ── Spacing Scale ── */
--shopify-space-xs: 10px; /* Tight internal padding — reconstructed: low confidence (off 4px grid) */
--shopify-space-sm: 16px; /* Base unit / rem-base equivalent — extracted: low confidence */
--shopify-space-md: 24px; /* Standard component padding — extracted: high confidence */
--shopify-space-lg: 32px; /* H2 margin-bottom, card gaps — extracted: high confidence */
--shopify-space-xl: 40px; /* Section element spacing — extracted: high confidence */
--shopify-space-2xl: 64px; /* H1 margin-bottom, modal margin-top — extracted: high confidence */
--shopify-space-3xl: 90px; /* Section vertical padding — extracted: high confidence */
/* ── Card/Section Internal Padding ── */
--shopify-card-padding-top: 72px; /* Card top padding (from card element) — extracted: high confidence */
/* Input padding: 24px 16px 8px (top/right/bottom — floating label pattern) */
/* ── Layout ── */
--shopify-container-max: 1280px; /* Inferred standard max-width — reconstructed: moderate confidence */
--shopify-container-padding: var(--shopify-space-md); /* 24px horizontal gutter */
/* ── Grid ── */
/* Nav: flex row, no gap specified */
/* Cards: display:grid, gap: 0 (sections butt together with -1px margin overlap) */
/* Dropdown: flex column, gap: 4px, justify:center, align:center */
/* Feature cards (cls_card): flex column, justify:space-between */
/* ── Z-index Scale ── */
--shopify-z-base: 0;
--shopify-z-card: 10;
--shopify-z-nav: 100;
--shopify-z-modal: 200;
--shopify-z-overlay: 300;
}
```
### Spacing Grid Notes
- **Primary rhythm:** 24 → 32 → 40 → 64 → 90px vertical cadence
- `10px` and `90px` are extracted but off the strict 4px grid — treat `10px` as a legacy exception, prefer `8px` or `12px` for new spacing
- Card sections use `margin: -1px 0px` to achieve seamless edge-to-edge stacking with no visible gap
- The input element uses a **floating label pattern**: `padding: 24px 16px 8px` (top-heavy to leave room for the label above the text)
### Breakpoints
```css
/* reconstructed: moderate confidence — Tailwind defaults inferred from library detection */
--shopify-bp-sm: 640px;
--shopify-bp-md: 768px;
--shopify-bp-lg: 1024px;
--shopify-bp-xl: 1280px;
--shopify-bp-2xl: 1536px;
```
---
## 5. Page Structure & Layout Patterns
> **Source:** Layout Digest + Component Inventory. No screenshots available. Rows marked **(inferred)** are derived from component inventory and structural signals, not visually confirmed.
### 5.1 Section Map
| Order | Section | Layout Type | Approx. Height | Key Elements |
|---|---|---|---|---|
| 1 | Navigation / Header | `flex row` | 60–80px | Logo, nav links, CTA button — transparent over gradient |
| 2 | Hero | Block, full-width | 600–800px (inferred) | H1 (96px), subhead, pill CTA button, gradient surface |
| 3 | Feature Card Grid | `display:grid`, full-width | 500–900px (inferred) | 49 card instances — grid of feature/product cards |
| 4 | Section: Quick Start (inferred) | Block, contained | ~400px (inferred) | H2 "Schnell loslegen", body copy, CTA |
| 5 | Section: Merchant Social Proof (inferred) | Block | ~500px (inferred) | H3 55px, testimonial text 18px/500w, merchant quotes |
| 6 | Section: Channel / Platform Feature (inferred) | Block or grid | ~600px (inferred) | H3 "Einfach über alle Kanäle", feature list |
| 7 | Tab/Interactive Section (inferred) | Inline tabs | ~400px (inferred) | Tab items at 55px/330w in muted colour → active in white |
| 8 | Developer / Ecosystem Feature (inferred) | Block | ~400px (inferred) | H2, code-like UI, green accent |
| 9 | Modal / Drawer (inferred) | `display:block`, overlaid | Viewport height | Modal with `8px 8px 0 0` radius — slides up from bottom |
| 10 | Footer (inferred) | Grid or flex | ~300px (inferred) | Nav links, legal, Shopify logo |
### 5.2 Layout Patterns
**Navigation:**
- `display: flex; flex-direction: row; padding: 0px`
- Transparent background overlaying the page gradient
- No explicit gap — spacing between items via margin or padding on children
**Hero Section:**
- Full-width, background is `--shopify-bg-surface` (teal gradient)
- H1 at 96px, bottom margin 64px — creates strong vertical breathing room before the next element
- CTA button: `border-radius: 30px` (pill), white fill on dark surface
**Card Grid:**
- `display: grid` with `gap: 0` and `margin: -1px 0px` — cards stack seamlessly edge-to-edge
- Card top padding: `72px` — intentional top-heavy internal spacing
- Feature cards (`cls_card`): `flex column; justify-content: space-between` — content top, CTA bottom
- Feature card radius: `12px` (`--shopify-radius-md`)
**Dropdown / Megamenu:**
- `display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 4px`
- Appears as a vertically stacked column of links
**Modal:**
- `display: block; margin-top: 64px` — inset from top of viewport
- `border-radius: 8px 8px 0 0` — rounded only at top (sheet pattern, slides up from bottom)
- Transition: `0.3s cubic-bezier(0.4, 0, 0.2, 1)` — material-style ease-in-out
### 5.3 Visual Hierarchy
- **Primary CTA colour:** White fill (`#fff`) on dark teal surface — maximum contrast
- **Heading scale creates hierarchy through size, not weight** — 96px → 55px → 20px, all light-medium weights
- **Tab inactive state:** `rgb(113, 113, 122)` muted zinc → white on active — colour alone distinguishes state (no weight change)
- **Cards dominate whitespace** — 49 card instances; the page is heavily card-based with 72px top padding per card
- **Gradient direction** is top-to-bottom (teal → near-black) — darker at the bottom of the page, creates a sense of depth
### 5.4 Content Patterns
**Feature Card Pattern (most common — 49 instances):**
```
[Card container: flex column, justify-between, 12px radius, gradient bg]
[Top: Heading h3/h4 + body text]
[Bottom: CTA link or button]
```
**Hero Pattern:**
```
[Full-width gradient section]
[H1 96px, weight 400, margin-bottom 64px]
[Subhead or body text]
[Pill CTA: white bg, black text, 30px radius]
```
**Tab/Accordion Section:**
```
[Tab labels: 55px/330w NeueHaasGrotesk — inactive: rgb(113,113,122), active: #fff]
[Content panel switches on tab selection]
```
**Section Heading Pattern:**
```
[H2 or H3 — NeueHaasGrotesk, 96px or 55px, weight 330–400]
[Body paragraph — Shopify Sans 16–18px]
[Spacing gap: 32–64px between heading and content]
```
---
## 6. Component Patterns
### 6.1 Button (Primary — Pill)
**Anatomy:** Container (pill border-radius) → Label text → [optional] Icon
**Token-to-Property Mapping:**
| State | Background | Text | Border | Shadow | Transform |
|---|---|---|---|---|---|
| Default | `#fff` | `#000` | none | none | none |
| Hover | `#000` | `#fff` | none | none | none |
| Focus | `#fff` | `#000` | 2px offset outline | none | none |
| Active | `rgba(255,255,255,0.85)` | `#000` | none | none | `scale(0.98)` |
| Disabled | `rgba(255,255,255,0.3)` | `rgba(0,0,0,0.5)` | none | none | none |
| Loading | `rgba(255,255,255,0.7)` | transparent | none | none | none |
```tsx
// Production-ready Primary Button — Shopify design system
import { ButtonHTMLAttributes, ReactNode } from 'react';
interface ShopifyButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode;
loading?: boolean;
variant?: 'primary' | 'ghost';
}
export function ShopifyButton({
children,
loading = false,
disabled = false,
variant = 'primary',
...props
}: ShopifyButtonProps) {
const isPrimary = variant === 'primary';
return (
<button
{...props}
disabled={disabled || loading}
style={{
/* Typography — Button composite */
fontFamily: 'var(--shopify-font-body)',
fontSize: 'var(--shopify-font-size-sm)', /* 14px */
fontWeight: 'var(--shopify-font-weight-bold)', /* 550 */
lineHeight: '21px',
letterSpacing: 'normal',
textDecoration: 'none',
textAlign: 'center',
/* Shape */
borderRadius: 'var(--shopify-radius-full)', /* 30px pill */
padding: '12px var(--shopify-space-md)', /* 12px 24px */
border: 'none',
display: 'inline-block',
cursor: disabled || loading ? 'not-allowed' : 'pointer',
/* Colour */
backgroundColor: disabled
? 'rgba(255,255,255,0.3)'
: isPrimary ? '#fff' : 'transparent',
color: disabled
? 'rgba(0,0,0,0.5)'
: isPrimary ? '#000' : '#fff',
opacity: loading ? 0.7 : 1,
/* Motion */
transition: `all var(--shopify-duration-base) var(--shopify-ease-default)`,
}}
onMouseEnter={(e) => {
if (!disabled && !loading && isPrimary) {
(e.target as HTMLButtonElement).style.backgroundColor = '#000';
(e.target as HTMLButtonElement).style.color = '#fff';
}
}}
onMouseLeave={(e) => {
if (!disabled && !loading && isPrimary) {
(e.target as HTMLButtonElement).style.backgroundColor = '#fff';
(e.target as HTMLButtonElement).style.color = '#000';
}
}}
aria-busy={loading}
>
{loading ? (
<span aria-hidden="true" style={{ opacity: 0 }}>{children}</span>
) : children}
</button>
);
}
```
---
### 6.2 Feature Card (cls_card pattern)
**Anatomy:** Card container (flex col, gradient bg, 12px radius) → Content area (heading + body) → CTA (bottom)
**State mapping:**
| State | Background | Shadow | Radius |
|---|---|---|---|
| Default | `--shopify-bg-card-gradient` | `--shopify-shadow-md` | `12px` |
| Hover | Same (no lift effect confirmed) | Same | `12px` |
| Focus | Same + outline | Same | `12px` |
```tsx
interface FeatureCardProps {
heading: string;
body: string;
ctaLabel: string;
ctaHref: string;
}
export function FeatureCard({ heading, body, ctaLabel, ctaHref }: FeatureCardProps) {
return (
<div
style={{
/* Layout */
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
/* Shape */
borderRadius: 'var(--shopify-radius-md)', /* 12px */
padding: '0',
/* Colour */
backgroundImage: 'var(--shopify-bg-card-gradient)',
color: 'var(--shopify-color-text)',
/* Elevation */
boxShadow: 'var(--shopify-shadow-md)',
/* Motion */
transition: `all var(--shopify-duration-base) var(--shopify-ease-default)`,
}}
>
{/* Content top */}
<div style={{ padding: 'var(--shopify-space-md)' }}>
<h3 style={{
fontFamily: 'var(--shopify-font-display)',
fontSize: 'var(--shopify-font-size-2xl)', /* 48px */
fontWeight: 'var(--shopify-font-weight-regular)', /* 330 */
lineHeight: '56px',
margin: '0 0 var(--shopify-space-lg)',
color: 'var(--shopify-color-text)',
}}>
{heading}
</h3>
<p style={{
fontFamily: 'var(--shopify-font-body)',
fontSize: 'var(--shopify-font-size-md)', /* 16px */
fontWeight: 'var(--shopify-font-weight-medium)', /* 400 */
lineHeight: 'var(--shopify-line-height-normal)', /* 24px */
color: 'var(--shopify-color-text)',
margin: 0,
}}>
{body}
</p>
</div>
{/* CTA bottom */}
<div style={{ padding: 'var(--shopify-space-md)' }}>
<a
href={ctaHref}
style={{
fontFamily: 'var(--shopify-font-body)',
fontSize: 'var(--shopify-font-size-sm)',
fontWeight: 'var(--shopify-font-weight-bold)',
color: 'var(--shopify-color-text)',
textDecoration: 'underline',
}}
>
{ctaLabel}
</a>
</div>
</div>
);
}
```
---
### 6.3 Navigation
**Anatomy:** `<nav>` (flex row) → Logo → Nav links → CTA button
**State mapping:**
| State | Text | Background | Transition |
|---|---|---|---|
| Default | `#fff` | transparent | — |
| Hover | `#fff` (opacity shift inferred) | transparent | `0.3s ease` |
| Focus | `#fff` + outline | transparent | — |
| Active | `#fff` | transparent | — |
```tsx
export function ShopifyNav() {
return (
<nav
role="navigation"
style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'var(--shopify-nav-bg)', /* transparent */
padding: '0 var(--shopify-space-md)',
fontFamily: 'var(--shopify-font-ui)',
fontSize: 'var(--shopify-font-size-md)', /* 16px */
fontWeight: 'var(--shopify-font-weight-medium)',
lineHeight: 'var(--shopify-line-height-normal)',
color: 'var(--shopify-color-text)',
transition: `all var(--shopify-duration-base) var(--shopify-ease-default)`,
}}
>
{/* Logo slot */}
<div style={{ marginRight: 'auto' }}>Shopify</div>
{/* Nav links */}
<ul style={{ display: 'flex', flexDirection: 'row', gap: 'var(--shopify-space-lg)', listStyle: 'none', margin: 0, padding: 0 }}>
{['Features', 'Pricing', 'Enterprise'].map((item) => (
<li key={item}>
<a
href="#"
style={{
color: 'var(--shopify-color-text)',
textDecoration: 'none',
transition: `all var(--shopify-duration-fast) var(--shopify-ease-default)`,
}}
>
{item}
</a>
</li>
))}
</ul>
{/* CTA */}
<ShopifyButton style={{ marginLeft: 'var(--shopify-space-lg)' }}>
Start for free
</ShopifyButton>
</nav>
);
}
```
---
### 6.4 Input (Floating Label)
**Anatomy:** Container → Input element → Floating Label (positioned above)
**State mapping:**
| State | Border | Label | Background |
|---|---|---|---|
| Default | `rgb(229,231,235)` 1px | Visible above text | transparent |
| Hover | `#fff` (inferred) | Same | transparent |
| Focus | `#fff` 1px + glow (inferred) | Floated up | transparent |
| Active | Same as focus | Floated | transparent |
| Disabled | `rgba(229,231,235,0.3)` | Dimmed | transparent |
| Error | `rgb(255,102,105)` (inferred) | Error colour | transparent |
```tsx
export function ShopifyInput({ label, id, disabled, error }: {
label: string; id: string; disabled?: boolean; error?: string;
}) {
return (
<div style={{ position: 'relative', display: 'block' }}>
<input
id={id}
disabled={disabled}
style={{
fontFamily: 'var(--shopify-font-ui)',
fontSize: 'var(--shopify-font-size-md)',
fontWeight: 'var(--shopify-font-weight-medium)',
lineHeight: 'var(--shopify-line-height-normal)',
color: 'var(--shopify-color-text)',
backgroundColor: 'rgba(255,255,255,0.05)',
border: `1px solid ${error ? 'rgb(255,102,105)' : 'rgb(229,231,235)'}`,
borderRadius: 'var(--shopify-radius-sm)',
padding: 'var(--shopify-space-md) var(--shopify-space-sm) 8px',
/* 24px top | 16px sides | 8px bottom — floating label space */
width: '100%',
outline: 'none',
transition: `all var(--shopify-duration-base) var(--shopify-ease-default)`,
opacity: disabled ? 0.5 : 1,
cursor: disabled ? 'not-allowed' : 'text',
}}
placeholder=" "
aria-invalid={!!error}
aria-describedby={error ? `${id}-error` : undefined}
/>
<label
htmlFor={id}
style={{
fontFamily: 'var(--shopify-font-ui)',
fontSize: 'var(--shopify-font-size-sm)',
fontWeight: 'var(--shopify-font-weight-medium)',
lineHeight: '20px',
color: 'var(--shopify-color-text-muted)',
position: 'absolute',
top: '8px',
left: 'var(--shopify-space-sm)',
transition: `all var(--shopify-duration-fast) var(--shopify-ease-default)`,
pointerEvents: 'none',
}}
>
{label}
</label>
{error && (
<span id={`${id}-error`} role="alert" style={{
fontFamily: 'var(--shopify-font-ui)',
fontSize: 'var(--shopify-font-size-xs)',
color: 'rgb(255,102,105)',
display: 'block',
marginTop: '4px',
}}>
{error}
</span>
)}
</div>
);
}
```
---
### 6.5 Tab / Interactive Selector
**Anatomy:** Tab container (inline) → Tab items → Active tab indicator (colour change)
**State mapping:**
| State | Text Colour | Font Weight | Font Size |
|---|---|---|---|
| Inactive | `rgb(113, 113, 122)` | 330 | 55px |
| Active / Hover | `rgb(255, 255, 255)` | 330 | 55px |
| Focus | `#fff` + outline | 330 | 55px |
> ⚠️ Tabs use the H3 type scale (55px NeueHaasGrotesk weight 330) — these are large, editorial-style tabs, not standard UI tabs.
```tsx
export function ShopifyTab({ label, active, onClick }: {
label: string; active: boolean; onClick: () => void;
}) {
return (
<button
role="tab"
aria-selected={active}
onClick={onClick}
style={{
fontFamily: 'var(--shopify-font-display)',
fontSize: 'var(--shopify-font-size-3xl)', /* 55px */
fontWeight: 'var(--shopify-font-weight-regular)', /* 330 */
lineHeight: '64px',
letterSpacing: 'normal',
color: active
? 'var(--shopify-color-text)' /* #fff */
: 'var(--shopify-color-text-muted)', /* rgb(113,113,122) */
background: 'transparent',
border: 'none',
padding: 0,
cursor: 'pointer',
display: 'inline',
textAlign: 'start',
transition: `color var(--shopify-duration-base) var(--shopify-ease-default)`,
}}
>
{label}
</button>
);
}
```
---
## 7. Elevation & Depth
```css
:root {
/* ── Shadow Tokens ── */
--shopify-shadow-sm:
rgba(0,0,0,0.1) 0px 20px 25px -5px,
rgba(0,0,0,0.1) 0px 8px 10px -6px;
/* Large diffuse drop shadow — for floating elements, elevated panels */
/* extracted: high confidence */
--shopify-shadow-md:
rgba(0,0,0,0.1) 0px 8px 8px 0px,
rgba(0,0,0,0.1) 0px 4px 4px 0px,
rgba(0,0,0,0.1) 0px 2px 2px 0px,
rgba(0,0,0,0.1) 0px 0px 0px 1px,
rgba(255,255,255,0.03) 0px 1px 0px 0px inset;
/* Feature card shadow — layered ambient + 1px border-ring + subtle inset highlight */
/* extracted: high confidence from cls_card element */
--shopify-shadow-modal:
rgb(15, 18, 20) 0px 8px 48px 0px,
rgba(66, 71, 76, 0.06) 0px 4px 8px 0px,
rgba(0, 0, 0, 0.9) 0px 0px 1px 0px;
/* Modal/sheet shadow — deep colour shadow for dark-on-dark contexts */
/* extracted: high confidence from modal element */
/* ── Border Tokens ── */
--shopify-border-subtle: 1px solid rgb(229, 231, 235);
/* Subtle divider on dark backgrounds — low contrast intentionally */
/* reconstructed: moderate confidence */
--shopify-border-ring: 0px 0px 0px 1px rgba(0,0,0,0.1);
/* 1px outer ring via box-shadow (part of --shopify-shadow-md) */
/* ── Z-Index Scale ── */
--shopify-z-base: 0; /* Default document flow */
--shopify-z-card: 10; /* Raised cards / sticky elements */
--shopify-z-nav: 100; /* Site navigation */
--shopify-z-modal: 200; /* Modal dialogs / drawers */
--shopify-z-overlay: 300; /* Full-screen overlays / cookie banners */
}
```
### Layering Principles
- **All shadows are dark on dark** — shadows use `rgba(0,0,0,*)` not coloured shadows, because the surface is already a dark gradient
- `--shopify-shadow-md` includes an inset highlight (`rgba(255,255,255,0.03) 0px 1px 0px 0px inset`) that simulates a top-edge light reflection on dark cards — never omit this on feature cards
- The modal shadow uses `rgb(15,18,20)` (a near-black with slight warmth) as the primary shadow colour, not pure black — preserves depth on the near-black surface
- Cards use `margin: -1px` overlap instead of borders or gaps for seamless grid stacking
---
## 8. Motion
```css
:root {
/* ── Duration Tokens ── */
--shopify-duration-fast: 0.2s;
/* Micro-interactions: icon states, hover colour changes, focus rings */
/* extracted: high confidence (4 elements) */
--shopify-duration-base: 0.3s;
/* Standard transitions: nav links, button hover, card states, modal open */
/* extracted: high confidence (42 elements — most common) */
--shopify-duration-slow: 0.5s;
/* Page-level: image reveals, hero entrance animations, large layout shifts */
/* extracted: high confidence (5 elements — buttons and images) */
/* ── Easing Tokens ── */
--shopify-ease-default: ease;
/* Standard easing — used on 189 elements; the universal default */
/* extracted: high confidence */
--shopify-ease-modal: cubic-bezier(0.4, 0, 0.2, 1);
/* Material-style ease-in-out — used on modal transitions only */
/* extracted: high confidence from modal transition property */
}
```
### Motion Rules
| Context | Duration | Easing |
|---|---|---|
| Hover colour (links, tabs) | `0.2s` | `ease` |
| Button bg swap | `0.3s` | `ease` |
| Nav link | `0.3s` | `ease` |
| Card state | `0.3s` | `ease` |
| Modal open/close | `0.3s` | `cubic-bezier(0.4, 0, 0.2, 1)` |
| Image/hero reveal | `0.5s` | `ease` |
**When to animate:**
- All interactive state changes (hover, focus, active) — always use `var(--shopify-duration-base)`
- Modal entrance/exit — use `var(--shopify-ease-modal)` specifically
- Large image transitions — use `var(--shopify-duration-slow)`
**When NOT to animate:**
- Layout shifts between breakpoints — no transition on `display` changes
- Screen reader focus management — no animation on `aria-*` state changes
- Loading skeleton → content swap — use instant swap, not fade
---
## 9. Anti-Patterns & Constraints
1. **Hardcoded hex colours → Why it fails → What to do instead.**
AI agents default to writing `color: #ffffff` or `background: #0a2c30` directly in components. This breaks theming and makes design system updates require component-level changes across the codebase. When hex values appear inline, future colour updates silently miss components. **Always use `var(--shopify-*)` tokens** — even when the token value seems obvious (e.g. `var(--shopify-color-text)` not `#fff`).
2. **Using Inter or Arial as the primary font → Why it fails → What to do instead.**
AI agents almost universally default to `font-family: Inter, sans-serif` or `font-family: Arial`. On Shopify.com, NeueHaasGrotesk owns all display/heading text and Shopify Sans owns all body/UI text. Using a generic fallback immediately breaks brand identity. **Use the three-stack system**: NeueHaasGrotesk for headings, "Shopify Sans" for body, Inter-Variable for form UI — each with full Helvetica/Arial/sans-serif fallback chain.
3. **Applying standard 400/600/700 font weights → Why it fails → What to do instead.**
AI agents substitute standard weights (e.g. `font-weight: 300` for light, `font-weight: 600` for semi-bold). Shopify's weight scale is `330 / 400 / 500 / 550` — non-standard numeric values that map to specific variable font axes. Substituting `600` for `550` or `300` for `330` triggers a different weight appearance from the font engine. **Only use the four defined values: 330, 400, 500, 550.**
4. **Using `border-radius: 8px` on buttons → Why it fails → What to do instead.**
AI agents commonly apply `8px` as a "modern rounded" button radius. Shopify's buttons are pill-shaped at `30px`. Applying `8px` creates a visually inconsistent, non-brand button. The `8px` radius belongs exclusively to the **modal** (which is 8px for its sheet-style top corners only). **Use `var(--shopify-radius-full)` (30px) on all CTA buttons.**
5. **Using warm accent colours → Why it fails → What to do instead.**
AI agents commonly introduce orange, amber, or yellow for highlights and hover states — these are common design-system conventions. Shopify's entire palette is cold: dark teal, near-black, white, and zinc-grey. Any warm tone immediately reads as off-brand. **The only permitted "accent" is white (#fff) on the dark surface.** Do not introduce any colour not in the defined colour system.
6. **Copying cookie banner hover states into brand UI → Why it fails → What to do instead.**
The extraction contains `rgb(34, 197, 94)` (green) and `rgb(255, 102, 105)` (red) from the `#dux-privacy` consent manager — a third-party library. AI agents pattern-match these as "the site's accent colours." They are not. **Never use these green/red values in brand components.** They belong only to the cookie consent overlay.
7. **Using `gap` values not in the spacing scale → Why it fails → What to do instead.**
AI agents routinely introduce arbitrary gap values like `gap: 20px`, `gap: 48px`, or `gap: 1rem`. Shopify's spacing scale is `10 / 16 / 24 / 32 / 40 / 64 / 90px`. Off-scale values break the vertical rhythm. **Use only defined `--shopify-space-*` tokens for all margin, padding, and gap values.**
8. **Applying card grid gaps → Why it fails → What to do instead.**
When reproducing the card grid, AI agents add `gap: 16px` or `gap: 24px` between cards. The actual pattern uses `display: grid; gap: 0; margin: -1px 0px` — cards butt together seamlessly with a 1px overlap to hide any rendering gap. **Set `gap: 0` and `margin: -1px 0px` on grid card containers** to replicate the edge-to-edge stacking.
9. **Using a light-mode surface in any section → Why it fails → What to do instead.**
AI agents occasionally generate sections with white or light-grey backgrounds for "visual relief." Shopify's design has no light-mode surfaces — every section is on the dark teal gradient or near-black card background. A white section reads as a rendering error. **Every section background must use `var(--shopify-bg-surface)` or `var(--shopify-bg-card)`.**
10. **Using `transition: all` without a duration → Why it fails → What to do instead.**
Computed styles show `transition: all` as a resolved value, but without a duration specified, browsers default to `0s` — no animation. AI agents copy `transition: all` and assume it works. **Always explicitly specify duration and easing:** `transition: all var(--shopify-duration-base) var(--shopify-ease-default)`.
---
## 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 (33) */
----gradient-cls_card-bg: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%); /* Gradient from cls_card background /* reconstructed */ */
--shopify-bg-surface: linear-gradient(rgb(10,44,48), rgb(6,21,24) 80%);
--shopify-bg-card: rgb(2, 9, 10);
--shopify-color-text: rgb(255, 255, 255);
--shopify-color-text-muted: rgb(113, 113, 122);
--primitive-teal-900: rgb(6, 21, 24);
--primitive-teal-800: rgb(2, 9, 10);
--primitive-teal-700: rgb(10, 44, 48);
--primitive-white: rgb(255, 255, 255);
--primitive-black: rgb(0, 0, 0);
--primitive-zinc-500: rgb(113, 113, 122);
--primitive-surface-overlay: oklch(0.21 0.006 285.885);
--primitive-green-400: rgb(34, 197, 94);
--primitive-green-300: rgb(122, 235, 159);
--primitive-red-400: rgb(255, 102, 105);
--shopify-bg-card-gradient: linear-gradient(rgb(10,44,48), rgb(6,21,24) 80%);
--shopify-bg-overlay: oklch(0.21 0.006 285.885);
--shopify-color-border: rgb(229, 231, 235);
--shopify-color-interactive-save: rgb(34, 197, 94);
--shopify-color-interactive-accept: rgb(122, 235, 159);
--shopify-color-interactive-reject: rgb(255, 102, 105);
--shopify-btn-primary-bg: rgb(255, 255, 255);
--shopify-btn-primary-text: rgb(0, 0, 0);
--shopify-btn-primary-bg-hover: rgb(0, 0, 0);
--shopify-btn-primary-text-hover: rgb(255, 255, 255);
--shopify-card-bg: rgb(2, 9, 10);
--shopify-card-bg-feature: linear-gradient(rgb(10, 44, 48), rgb(6, 21, 24) 80%);
--shopify-nav-bg: rgba(0,0,0,0);
--shopify-nav-text: rgb(255, 255, 255);
--shopify-modal-bg: oklch(0.21 0.006 285.885);
--shopify-modal-text: rgb(255, 255, 255);
--shopify-border-subtle: 1px solid rgb(229, 231, 235);
--shopify-border-ring: 0px 0px 0px 1px rgba(0,0,0,0.1);
/* Typography (30) */
--font-size-xs: 12px; /* 11 elements — e.g. p "In jeden Shop integr", p "Website erstellen", p "Überall verkaufen" /* mined from computed styles */ */
--font-size-sm: 14px; /* 119 elements — e.g. p "Du könntest bereits ", p "Mehr Kunden gewinnen", p "Egal, wie groß, komp" /* mined from computed styles */ */
--font-size-md: 16px; /* 64 elements — e.g. p "Schneller Einstieg", p "Zu Shopify wechseln", p "Große Marken vertrau" /* mined from computed styles */ */
--font-size-lg: 18px; /* 19 elements — e.g. p "Millionen von Händle", p "Nach einem TV-Auftri", p "Die in Berlin ansäss" /* mined from computed styles */ */
--font-size-xl: 20px; /* 21 elements — e.g. h3 "Shopify", h3 "Ökosystem", h3 "Ressourcen" /* mined from computed styles */ */
--font-size-2xl: 48px; /* 5 elements — e.g. h3 "Der Checkout mit der", h3 "Felsenfest und blitz", h3 "Die aktuellste Techn" /* mined from computed styles */ */
--font-size-3xl: 55px; /* 9 elements — e.g. h2 "Schnell loslegen", h3 "Einfach über alle Ka", h3 "Verkaufe schneller, " /* mined from computed styles */ */
--font-weight-regular: 330; /* 18 elements — e.g. h2 "Die eine Commerce-Pl", h2 "Hier werden Entwickl", h2 "Schnell loslegen" /* mined from computed styles */ */
--font-weight-medium: 400; /* 203 elements — e.g. h4 "Schneller Einstieg", h4 "Einzigartige Skalier", h4 "Neue Maßstäbe setzen" /* mined from computed styles */ */
--font-weight-semibold: 500; /* 21 elements — e.g. p "Millionen von Händle", p "Nach einem TV-Auftri", p "Die in Berlin ansäss" /* mined from computed styles */ */
--font-weight-bold: 550; /* 5 elements — e.g. a "Direkt zum Inhalt", a "Kostenlos starten", a "Kostenlos starten" /* mined from computed styles */ */
--line-height-normal: 24px; /* 65 elements — e.g. p "Schneller Einstieg", p "Zu Shopify wechseln", p "Große Marken vertrau" /* mined from computed styles */ */
--line-height-loose: 28px; /* 20 elements — e.g. h4 "Schneller Einstieg", h4 "Einzigartige Skalier", h4 "Neue Maßstäbe setzen" /* mined from computed styles */ */
--shopify-font-display: NeueHaasGrotesk, Helvetica, Arial, sans-serif;
--shopify-font-body: "Shopify Sans", Helvetica, Arial, sans-serif;
--shopify-font-ui: Inter-Variable, Helvetica, Arial, sans-serif;
--shopify-font-size-sm: 14px;
--shopify-font-size-md: 16px;
--shopify-font-size-xl: 20px;
--shopify-font-size-2xl: 48px;
--shopify-font-size-h1: 96px;
--shopify-font-size-3xl: 55px;
--shopify-font-weight-regular: 330;
--shopify-font-weight-medium: 400;
--shopify-font-weight-semibold: 500;
--shopify-font-weight-bold: 550;
--shopify-font-size-xs: 12px;
--shopify-font-size-lg: 18px;
--shopify-line-height-normal: 24px;
--shopify-line-height-loose: 28px;
/* Spacing (22) */
--rem-base: 16px;
--space-xs: 10px; /* 31 elements — e.g. a .level3-link, a .level3-link, a .level3-link /* mined from computed styles */ */
--space-md: 24px; /* 55 elements — e.g. footer .relative, footer .relative, div .flex /* mined from computed styles */ */
--space-lg: 32px; /* 33 elements — e.g. div .container, div .container, div .gap-y-[68px] /* mined from computed styles */ */
--space-xl: 40px; /* 45 elements — e.g. div .gap-y-[68px], div .gap-y-[68px], div .gap-y-[68px] /* mined from computed styles */ */
--space-2xl: 64px; /* 95 elements — e.g. section .grid, section .grid, section .grid /* mined from computed styles */ */
--space-3xl: 90px; /* 20 elements — e.g. footer .relative, footer .relative, div .gap-y-[68px] /* mined from computed styles */ */
--shopify-space-md: 24px;
--shopify-space-lg: 32px;
--shopify-space-xl: 40px;
--shopify-space-2xl: 64px;
--shopify-space-3xl: 90px;
--shopify-space-xs: 10px;
--shopify-space-sm: 16px;
--shopify-card-padding-top: 72px;
--shopify-container-max: 1280px;
--shopify-container-padding: var(--shopify-space-md);
--shopify-bp-sm: 640px;
--shopify-bp-md: 768px;
--shopify-bp-lg: 1024px;
--shopify-bp-xl: 1280px;
--shopify-bp-2xl: 1536px;
/* Radius (9) */
--radius-sm: 4px; /* 7 elements — e.g. svg .[object, div .p-1 "Buy now", div .p-1 "Buy now" /* mined from computed styles */ */
--radius-md: 12px; /* 5 elements — e.g. button .fixed "Warum wir Shopify en", div .bg-[linear-gradient(0deg,#061518_20%,#0a2c30)], div .rounded-xl "Point of Sale für de" /* mined from computed styles */ */
--radius-lg: 20px 20px 0px 0px; /* 1 element — e.g. div .bg-devCard /* mined from computed styles */ */
--radius-full: 30px; /* 4 elements — e.g. button .button "Ablehnen", button .button "Cookies akzeptieren", button .button "Ablehnen" /* mined from computed styles */ */
--shopify-radius-sm: 4px;
--shopify-radius-md: 12px;
--shopify-radius-full: 30px;
--shopify-radius-lg: 20px 20px 0px 0px;
--shopify-radius-modal: 8px 8px 0px 0px;
/* Effects (5) */
--shadow-sm: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0… <0.2KB elided>; /* 1 element — e.g. button .fixed /* mined from computed styles */ */
--shadow-md: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0… <0.3KB elided>; /* 4 elements — e.g. div .bg-[linear-gradient(0deg,#061518_20%,#0a, div .rounded-xl, div .relative /* mined from computed styles */ */
--shopify-shadow-sm: rgba(0,0,0,0.1) 0px 20px 25px -5px, rgba(0,0,0,0.1) 0px 8px 10px -6px;
--shopify-shadow-md: rgba(0,0,0,0.1) 0px 8px 8px 0px, rgba(0,0,0,0.1) 0px 4px 4px 0px, rgba(0,0,0,0.1) 0px 2px 2px 0px, rgba(0,0,0,0.1) 0px 0px 0px 1px, rgba(255,255,255,0.03) 0px 1px 0px 0px inset;
--shopify-shadow-modal: rgb(15,18,20) 0px 8px 48px 0px, rgba(66,71,76,0.06) 0px 4px 8px 0px, rgba(0,0,0,0.9) 0px 0px 1px 0px;
/* Motion (4) */
--duration-fast: 0.2s; /* 4 elements — e.g. button, svg, svg /* mined from computed styles */ */
--duration-base: 0.3s; /* 42 elements — e.g. a, svg, svg /* mined from computed styles */ */
--duration-slow: 0.5s; /* 5 elements — e.g. button, img, img /* mined from computed styles */ */
--ease-default: ease; /* 189 elements — e.g. button, button, button /* mined from computed styles */ */
```
## Appendix B: Token Source Metadata
```
tokenSource: reconstructed-from-computed
confidence: low
cssVarsFound: 1 (--rem-base: 16px only)
syntheticTokenCount: 31 curated + ~15 supplemental
```
**Extraction method:** Computed styles were collected for 16 key element types (h1, h2, h3, body, button_primary, input, label, link, card, checkbox, modal, tab, dropdown, role_button, role_navigation, cls_card). Token values were clustered by:
- **Colours:** Hue family clustering — teal family (3 values), white, black, zinc-grey, and modal overlay identified. Cookie banner colours isolated as third-party.
- **Spacing:** Values mapped to a named scale (xs through 3xl) anchored to the extracted CSS custom properties (`--space-xs`, `--space-md`, `--space-lg`, etc.)
- **Typography:** Clustered into 4 font-size groups (xs/sm/md/lg/xl/2xl/3xl) matching named CSS vars. Weights clustered at `330/400/500/550` from 5 distinct values found.
- **Border-radius:** 4 distinct values found (4px/12px/20px 20px 0 0/30px). Pill identification: 30px on `button.button` elements (cookie consent) and role_button — confirmed as pill pattern. Modal has separate 8px top-only radius (cookie/modal sheet pattern, separate from brand button radius).
- **Shadows:** Two distinct stacking patterns identified — diffuse large shadow (`--shopify-shadow-sm`) and layered card shadow with inset highlight (`--shopify-shadow-md`). Modal has unique deep-colour shadow.
- **Motion:** Consistent `ease` easing (189 elements), three distinct durations (0.2/0.3/0.5s), single outlier `cubic-bezier` on modal.
**Confidence notes:**
- Typography weights (330/400/500/550) — **high confidence** — consistent across many elements, match extracted CSS var names
- Button primary colour (#fff on dark) — **moderate confidence** — inferred from dark surface context; no confirmed hover state from brand buttons
- Container max-width (1280px) — **moderate confidence** — inferred from Tailwind `xl` breakpoint default
- Cookie banner states — **excluded from brand system** — third-party library (`#dux-privacy`), not Shopify design system
- Font families — **high confidence** — confirmed from `@font-face` declarations and computed styles
- NeueHaasGrotesk as display-only font — **high confidence** — exclusively found on h1/h2/h3/tab/card elements
**Libraries detected:** Tailwind CSS, Bootstrap. Tailwind v3 (no CSS vars via `@theme`), Bootstrap class names detected but Tailwind appears to be the primary utility framework.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