CE Brand Kit

For AI

Alle Guidelines, Tokens und Constraints auf einer Seite — optimiert fuer LLMs und AI-Code-Tools

Diese Seite buendelt das gesamte Design System als Text. Teile die URL mit deinem AI-Tool (ChatGPT, Claude, v0, Cursor) — es versteht dann alle Regeln und kann Code generieren der zum Brand passt. Die Inhalte werden bei jedem Build aus den Quelldateien in packages/brand-kit/ generiert.

1

Overview

Guidelines.md
# Coffee Elements — Design System Overview

> Coffee Elements is a specialty coffee roaster with locations in Cologne and Muenster.
> The brand identity is built on earth tones, monochrome typography, and clean layouts.

## Design Philosophy

- **Monochrome + Accent**: The entire brand runs on a neutral zinc scale. Red, emerald, and yellow accents are reserved for status indicators (error, success, warning) — never for decoration.
- **Three Fonts, Three Roles**: Pressura (headings), Pressura Mono (buttons/labels/prices), Inter (body). No exceptions, no mixing within a role.
- **4px Grid**: All spacing follows strict multiples of 4px. No arbitrary values.
- **Token-First**: Every color, shadow, and border uses semantic CSS Custom Properties (`--ce-*`). Dark mode works via token swap — no structural changes.

## Package Contents

| Path | Purpose |
|---|---|
| `design-tokens.css` | Resolved token values with usage comments |
| `design-system.json` | Tokens as JSON for programmatic tools |
| `guidelines/` | This directory — Figma Make format guidelines |
| `tailwind/preset.js` | Full Tailwind preset (theme + component classes) |
| `tailwind/preset-tokens-only.js` | Theme only, no ce-* classes (Shopify) |
| `tailwind/preset-shopify.js` | Shopify breakpoints (750/1000/1200px) |
| `css/components.css` | Compiled CSS (no Tailwind needed) |
| `css/components.min.css` | Minified CSS |
| `components/*.md` | Component implementation specs |

## Guidelines Structure

Read in this order:

1. **`setup.md`** — Installation, Tailwind config, presets
2. **`foundations/`** — Color, typography, spacing, dark mode + responsive
3. **`composition/`** — Visual hierarchy, layout patterns, surface rules
4. **`components/`** — When to use which component, decision logic

Each guideline file is short (< 150 lines) and focused on one topic.
For exact CSS values, refer to `components/*.md` specs.

## Core Rules

1. **Only values from design-tokens.css** — `--ce-surface-card` not `#FFFFFF`
2. **Font assignments are strict** — see `foundations/typography.md`
3. **Missing value = ask** — set `TODO: VERIFY` comment, never invent
4. **Dark mode = token swap only** — `.dark` class on `<html>`, no layout changes
5. **Icons from Remixicon only** — no custom SVG paths
6. **Use ce-* component classes** — read specs before building new components
7. **Composition rules define guardrails** — see `composition/` directory
2

Setup

setup.md
# Setup — Consumer Integration

## Install

```bash
npm install @panoptia/coffee-elements-brand-kit
```

## Tailwind Projects (Next.js, Astro, etc.)

```js
// tailwind.config.js
module.exports = {
  presets: [require('@panoptia/coffee-elements-brand-kit/tailwind/preset')],
  content: ['./src/**/*.{html,js,tsx,liquid}']
}
```

The preset provides: theme extension (colors, fonts, spacing, shadows, radius), dark mode via `.dark` class, and component classes with `ce-` prefix.

## Shopify Projects

Two options depending on your CSS strategy:

### Option A: Tokens + Own Component CSS

```js
// tailwind.config.js — theme + CSS Custom Properties, no ce-* classes
module.exports = {
  presets: [require('@panoptia/coffee-elements-brand-kit/tailwind/preset-tokens-only')],
  content: ['./src/**/*.{html,js,tsx,liquid}']
}
```

### Option B: Shopify Breakpoints

```js
// tailwind.config.js — Shopify-specific breakpoints (750/1000/1200px)
module.exports = {
  presets: [require('@panoptia/coffee-elements-brand-kit/tailwind/preset-shopify')],
  content: ['./src/**/*.{html,js,tsx,liquid}']
}
```

## Projects Without Tailwind

```css
@import '@panoptia/coffee-elements-brand-kit/css/components.css';
```

All values resolved (hex/px), no Tailwind needed.

## Fonts

Font files are NOT included in the package. Host separately:

| File | Weight | Family |
|---|---|---|
| `gt-pressura-light.woff2` | 300 | Pressura |
| `gt-pressura-regular.woff2` | 500 | Pressura |
| `gt-pressura-mono.woff2` | 400, 500 | Pressura Mono |
| Inter | 400 | Google Fonts or CDN |

See `components/font-integration.md` for @font-face declarations per platform.

## Icons

```bash
npm install remixicon
```

Only Remixicon. No other icon libraries, no emoji, no custom SVG paths.

## Claude Code Integration

Copy `guidelines/Guidelines.md` reference into your project's `CLAUDE.md`:

```markdown
## Design System

Source of Truth: `node_modules/@panoptia/coffee-elements-brand-kit/`

Before implementing any component:
1. Read `guidelines/Guidelines.md` for core rules
2. Read the relevant `guidelines/` file for the feature area
3. Read `components/*.md` for exact CSS values
4. Use semantic tokens only (`--ce-*`), never raw palette values
```

## Updates

```bash
npm outdated @panoptia/coffee-elements-brand-kit  # Check for new version
npm update @panoptia/coffee-elements-brand-kit     # Install update
```
3

Color

foundations/color.md
# Color — Semantic Tokens & Decision Tree

## Palette (Raw — Do NOT Use Directly)

The brand runs on a neutral zinc scale with three accent colors for status only.

| Scale | Range | Purpose |
|---|---|---|
| ce-zinc | 50–950 | Entire brand: surfaces, text, borders |
| ce-red | 200–500 | Error states, sale badges |
| ce-emerald | 200–500 | Success states, availability |
| ce-yellow | 200–500 | Warning states, highlights |

**NEVER use palette values directly.** Always use semantic tokens below.

## Semantic Tokens — Surfaces

Use for `background-color`.

| Token | Light | Dark | When to use |
|---|---|---|---|
| `--ce-surface-page` | #FBFBFC | #18191A | `<body>`, full-width sections |
| `--ce-surface-card` | #FFFFFF | #232528 | Cards, modals, dropdowns |
| `--ce-surface-muted` | #F3F3F3 | #313337 | Code blocks, input backgrounds |
| `--ce-surface-subtle` | #EDEEEF | #313337 | Table headers, hover states |
| `--ce-surface-invert` | #18191A | #FBFBFC | Primary buttons, inverted tags |
| `--ce-surface-invert-hover` | #313337 | #EDEEEF | Primary button hover |

## Semantic Tokens — Text

Use for `color`.

| Token | Light | Dark | When to use |
|---|---|---|---|
| `--ce-text-heading` | #18191A | #FBFBFC | Headings, nav items, important labels |
| `--ce-text-body` | #313337 | #EDEEEF | Body text, descriptions |
| `--ce-text-secondary` | #575A61 | #B6B7BB | Supporting text, metadata, prices |
| `--ce-text-tertiary` | #69727D | #69727D | Captions, timestamps, helper text |
| `--ce-text-muted` | #B6B7BB | #69727D | Placeholders, disabled text |
| `--ce-text-on-invert` | #FFFFFF | #18191A | Text on inverted backgrounds |

## Semantic Tokens — Borders

Use for `border-color`.

| Token | Light | Dark | When to use |
|---|---|---|---|
| `--ce-border-default` | #EDEEEF | #454850 | Cards, tables, inputs |
| `--ce-border-strong` | #D1D1D4 | #575A61 | Hover borders, emphasis |
| `--ce-border-muted` | #F3F3F3 | #313337 | Very subtle, barely visible |

## Decision Tree — Which Color When?

### "I need a background"
- Page-level section? → `--ce-surface-page`
- Content container (card, modal)? → `--ce-surface-card`
- Input field, code block? → `--ce-surface-muted`
- Table header, subtle hover? → `--ce-surface-subtle`
- Button, inverted tag? → `--ce-surface-invert`

### "I need text color"
- Heading, nav link, label? → `--ce-text-heading`
- Paragraph, description? → `--ce-text-body`
- Price, metadata, supporting? → `--ce-text-secondary`
- Caption, timestamp, helper? → `--ce-text-tertiary`
- Placeholder, disabled? → `--ce-text-muted`
- On dark/inverted bg? → `--ce-text-on-invert`

### "I need a border"
- Standard separation? → `--ce-border-default`
- Hover emphasis? → `--ce-border-strong`
- Barely visible? → `--ce-border-muted`

## Allowed Pairings

| Text | Surface | Context |
|---|---|---|
| heading | page | Headings on page |
| heading | card | Headings in cards |
| body | page / card | Body text |
| secondary | card | Supporting text |
| tertiary | card | Captions, helpers |
| on-invert | invert | Buttons, tags, overlays |

## Forbidden Pairings

| Text | Surface | Reason |
|---|---|---|
| muted | muted | Contrast too low (2.1:1) |
| on-invert | page | White on near-white |
| tertiary | subtle | Contrast borderline |

## Contrast Rules

- Minimum 4.5:1 for text < 24px
- Minimum 3:1 for headings >= 24px
- When in doubt: choose the darker text token
4

Typography

foundations/typography.md
# Typography — Font Families, Scale & Constraints

## Three Fonts, Three Roles (Strict)

| Font | Role | Use for | NEVER use for |
|---|---|---|---|
| **Pressura** | Headings, Display, Navigation | H1–H6, nav links, section headers, card titles | Body, buttons, labels, prices |
| **Pressura Mono** | Buttons, UI, Labels | All buttons, prices, badges, breadcrumbs, form labels, table headers, copyright | Body, headings, paragraphs |
| **Inter** | Body, Descriptions | Paragraphs, descriptions, long-form text, list items | Headings, buttons, labels, prices |

No other fonts. No mixing within a role. No exceptions.

## Font Files

| File | Weight | Maps to |
|---|---|---|
| gt-pressura-light.woff2 | 300 | Nav links, hero headings, subtitles |
| gt-pressura-regular.woff2 | 500 | Section headings, card titles |
| gt-pressura-mono.woff2 | 400 | Prices, labels, captions |
| gt-pressura-mono.woff2 | 500 | All buttons |
| Inter (Google Fonts/CDN) | 400 | All body text |

## Typography Scale

### Pressura (Headings)

| Element | Size | Weight | Line-Height |
|---|---|---|---|
| H1 (Hero) | 54px | 300 | 64px |
| Subtitle | 28px | 300 | 36px |
| H2 (Section) | 24px | 500 | 32px |
| H3 | 18px | 500 | — |
| H3 Small | 16px | 500 | — |
| Nav Link | 15px | 300 | — |
| Footer Heading | 16px | 500 | — |

### Pressura Mono (UI)

| Element | Size | Weight | Line-Height | Notes |
|---|---|---|---|---|
| Button Default | 15px | 500 | — | |
| Button Outline | 13px | 500 | — | |
| Button Compact | 12px | 500 | — | |
| Price | 14px | 400 | — | |
| Caption | 12px | 400 | — | |
| Breadcrumb | 12px | 400 | 16px | |
| Label/Badge | 11px | 400 | — | uppercase, tracking-wider |

### Inter (Body)

| Element | Size | Weight | Line-Height |
|---|---|---|---|
| Intro Paragraph | 28px | 400 | 36px |
| Body | 16px | 400 | 24px |
| Body Small | 14px | 400 | 22px |
| Footer Link | 14px | 400 | 28px |

## Responsive Typography

Font sizes do NOT change between breakpoints. Two exceptions:

| Element | Desktop (>= 768px) | Mobile (< 768px) |
|---|---|---|
| H1 (Hero) | 54px / 300 / 64px LH | 28px / 300 / 36px LH |
| Subtitle | 28px / 300 / 36px LH | 19px / 300 / 28px LH |

Everything else stays identical across all breakpoints.

## Decision Tree — Which Font?

- Writing a heading or navigation item? → **Pressura**
- Writing a button label, price, badge, or breadcrumb? → **Pressura Mono**
- Writing body text, a description, or list item? → **Inter**
- Unsure? → If it's interactive UI → Pressura Mono. If it's content → Inter.
5

Spacing

foundations/spacing.md
# Spacing — 4px Base Grid

## The Grid

All spacing uses multiples of 4px. No exceptions.

| Token | px | Common Use |
|---|---|---|
| xs | 4 | Tight inline gaps (icon + label) |
| sm | 8 | Small gaps between related items, button icon gap |
| md | 12 | Medium gaps, closely connected elements |
| base | 16 | Default padding mobile, compact cards |
| lg | 20 | Card body padding, standard section gaps |
| xl | 24 | Header/footer padding desktop, section padding |
| 2xl | 32 | Large section padding desktop |
| 3xl | 48 | Section margins desktop |
| 4xl | 64 | Page-level vertical rhythm between section blocks |

## Forbidden Values

**NEVER use:** 5, 7, 10, 15, 18, 22, 30px or any non-grid value.

If a design requires 10px, use 8px (sm) or 12px (md). Round to the nearest grid step.

## Consistency Rule

Within a single component: use consistent spacing steps. Do not mix 8px gap here and 12px gap there without reason. If you choose gap-sm (8px), use it throughout — or deliberately step one level up/down.

## Decision Tree — Which Spacing?

### "I need padding inside a component"
- Compact element (badge, small card)? → **base (16px)**
- Standard card body? → **lg (20px)**
- Header/footer? → **xl (24px)** desktop, **base (16px)** mobile
- Large panel? → **2xl (32px)**

### "I need gap between elements"
- Icon next to label? → **xs (4px)** or **sm (8px)**
- Items in a list/row? → **sm (8px)** or **md (12px)**
- Cards in a grid? → **base (16px)** or **lg (20px)**
- Sections on a page? → **3xl (48px)** or **4xl (64px)**

### "I need page-level margin"
- Between major sections? → **4xl (64px)**
- Between subsections? → **3xl (48px)**
- Mobile: reduce by one step (64px → 48px, 48px → 32px)

## Border Radius

| Value | Token | Use |
|---|---|---|
| 6px | — | Images (rounded-md), compact buttons, nav hover |
| 8px | --radius-sm | Buttons, inputs, small cards, badges, code blocks |
| 12px | — | Cards in showcases |
| 16px | --radius-lg | Bento cards, modals, large containers |
| 9999px | --radius-full | Pills, circular avatars, round elements |

**Images always use 6px (rounded-md)** — not the token scale.
6

Modes

foundations/modes.md
# Modes — Dark Mode & Responsive Breakpoints

## Dark Mode

Activated via `.dark` class on `<html>`. All semantic tokens swap automatically.

### The Rule

**Dark mode = token swap. Nothing else.**

No structural changes. No different components. No different layouts. Only colors swap.

### What Changes

All `--ce-surface-*`, `--ce-text-*`, `--ce-border-*` tokens swap to dark equivalents. See `foundations/color.md` for the full mapping.

### Special Cases

| Element | Light Mode | Dark Mode |
|---|---|---|
| Shadows | Low opacity (0.08, 0.16) | Higher opacity (0.24, 0.36) |
| Monochrome logos/icons | `--ce-logo-filter: none` | `--ce-logo-filter: invert(1)` |
| Photos/images | No change | No change (never invert) |
| `--ce-surface-invert` | Dark bg (#18191A) | Light bg (#FBFBFC) |
| Forms (inputs) | bg: surface-muted | bg: surface-muted (auto-swaps) |
| Code blocks | bg: surface-muted | bg: surface-card |
| Accent colors | 500 variants (red, emerald, yellow) | 400 variants (lighter for contrast) |

### Constraints

- `--ce-surface-invert` is for buttons and tags only — never for full sections
- Never add a manual dark mode override. If a token doesn't look right in dark mode, the token mapping is wrong — fix the token, don't patch the component.
- Table tokens (`--ce-table-*`) swap automatically via rgba — no manual override needed.

## Responsive Breakpoints

Mobile first. Two main breakpoints plus container queries.

### @media Breakpoints

| Name | Value | Use |
|---|---|---|
| (default) | < 768px | Mobile — single column, hamburger nav |
| md | >= 768px | Tablet/Desktop — multi-column, desktop nav |
| xl | >= 1280px | Wide desktop — expanded grids |

### Shopify Breakpoints (preset-shopify.js)

| Name | Value |
|---|---|
| sm | 750px |
| md | 1000px |
| lg | 1200px |

### @container Sizes

For component-level responsive behavior (product grids, card layouts):

| Size | Columns |
|---|---|
| @3xl | 2 columns |
| @4xl | 3 columns |
| @5xl | 4 columns |

### When @media vs @container

- Layout depends on **viewport**? → `@media` (header, footer, sidebar visibility)
- Layout depends on **container width**? → `@container` (product grid columns, card layout)

### What Changes Per Breakpoint

| Property | Mobile (< 768px) | md (>= 768px) | xl (>= 1280px) |
|---|---|---|---|
| Grid columns | 1 | 2 | 3 |
| Header height | 56px | 80px | 80px |
| Header nav | Hamburger | Desktop links | Desktop links |
| Footer grid | 2-col | 3-col | 6-col |
| Page padding | px-4 | px-6 / px-8 | px-6 / px-8 |

### What Does NOT Change

- Font sizes (exception: H1 Hero, Subtitle — see typography.md)
- Border radius
- Shadows
- Colors
- Spacing within components
7

Hierarchy

composition/hierarchy.md
# Visual Hierarchy — Weight & Type Scale Assignment

## Hierarchy Levels

Every page follows a consistent visual weight system. Larger/bolder elements draw attention first.

| Level | Element Type | Font | Size | Weight | Token |
|---|---|---|---|---|---|
| 1 | Hero headline | Pressura | 54px | 300 | --ce-text-heading |
| 2 | Subtitle / Intro | Pressura / Inter | 28px | 300 / 400 | --ce-text-heading / --ce-text-body |
| 3 | Section heading | Pressura | 24px | 500 | --ce-text-heading |
| 4 | Card title / H3 | Pressura | 18px | 500 | --ce-text-heading |
| 5 | Body text | Inter | 16px | 400 | --ce-text-body |
| 6 | Supporting text | Inter | 14px | 400 | --ce-text-secondary |
| 7 | Caption / Label | Pressura Mono | 12px / 11px | 400 | --ce-text-tertiary |

## Section Patterns

### Hero Section
- H1: Pressura 54px/300 (28px on mobile)
- Subtitle: Pressura 28px/300 or Inter 28px/400
- Optional CTA button below
- FLAT layout (no card container)

### Content Section
- H2: Pressura 24px/500
- Body: Inter 16px/400
- Optional card grid below
- Can be FLAT or BENTO

### Card Content
- Title: Pressura 18px/500
- Description: Inter 14px/400 or 16px/400
- Price: Pressura Mono 14px/400
- Action: Pressura Mono button

## Transitions Between Levels

Never skip more than one hierarchy level. A section heading (Level 3) should not be followed directly by a caption (Level 7). Acceptable flow: H2 → Body → Caption.

## Emphasis Patterns

| Need | Method | Example |
|---|---|---|
| Primary emphasis | Larger size, heading color | H2 section title |
| Secondary emphasis | Same size, secondary color | Price, metadata |
| De-emphasis | Smaller size, tertiary/muted | Captions, timestamps |
| Interactive emphasis | Font change (Pressura Mono) | Buttons, links |

### Constraints

- ONE H1 per page maximum
- Section headings (H2) introduce major content blocks
- Card titles (H3) are always inside a card — never floating
- Prices always use Pressura Mono, never body font
- Labels/badges: uppercase + tracking-wider, always Pressura Mono 11px
8

Layout

composition/layout.md
# Layout — Container, Padding, Alignment & Grid

## Max Content Width

**1140px**, centered. All page content stays within this boundary.

## Page Padding

| Breakpoint | Horizontal Padding |
|---|---|
| Mobile (< 768px) | px-4 (16px) |
| md (>= 768px) | px-6 (24px) or px-8 (32px) |

## Responsive Grid

### @media-Based (Page-Level)

| Breakpoint | Columns | Use |
|---|---|---|
| < 768px | 1 | Mobile stacked layout |
| md (>= 768px) | 2 | Tablet/desktop split |
| xl (>= 1280px) | 3 | Wide desktop grid |

### @container-Based (Component-Level)

| Size | Columns | Use |
|---|---|---|
| @3xl | 2 | Product grids in narrow containers |
| @4xl | 3 | Product grids in medium containers |
| @5xl | 4 | Product grids in wide containers |

### Decision: @media vs @container

- Layout changes with **viewport size**? → `@media` (header, footer, sidebar)
- Layout changes with **container width**? → `@container` (product grid, card layout)

## Sidebar Layouts

- Mobile: stacked (sidebar above content)
- Desktop (>= md): side-by-side
- Sidebar collapse: transition-transform 200ms

## Alignment Rules

- Content edges align with the page container (1140px max-width)
- Cards in a grid: equal widths, equal gaps
- Buttons in a row: same visual height (see `components/button.md`)
- Text alignment: left-aligned by default. Center only for hero sections.

## Grid Gap

Standard gap between grid items follows the spacing scale:

| Context | Gap |
|---|---|
| Card grid | base (16px) or lg (20px) |
| Button row | sm (8px) or md (12px) |
| Icon + text | xs (4px) or sm (8px) |
| Section spacing | 3xl (48px) or 4xl (64px) |

## Header & Footer

| Component | Height Desktop | Height Mobile |
|---|---|---|
| Header | 80px | 56px |
| Footer | auto (content) | auto (content) |

Header is NOT sticky. Footer grid: 2-col (mobile) → 3-col (md) → 6-col (xl).

## Constraints

- Never exceed 1140px content width
- Never use arbitrary breakpoints (only md: 768px, xl: 1280px)
- Never center body text (only hero headings)
- Grid gaps must follow the 4px spacing grid
- Sidebar always left, content always right (desktop)
9

Surfaces

composition/surfaces.md
# Surfaces — FLAT vs BENTO, Cards & Backgrounds

## Two Surface Patterns

Every content area uses one of two patterns. Never mix them within the same context.

### FLAT — Content Directly on Page Surface

No card container. Content sits on `--ce-surface-page`.

**Use for:**
- Hero sections
- Brand logos
- Large headings / display text
- Full-width image banners

**Styling:**
- Background: `var(--ce-surface-page)`
- No shadow, no border
- Padding: py-16 px-8 (desktop), reduced on mobile

### BENTO — Content in Cards

Content wrapped in card containers with shadow and border.

**Use for:**
- Product grids
- Feature lists
- Info/team cards
- Contact sections

**Styling:**
- Background: `var(--ce-surface-card)`
- Border: 1px solid `var(--ce-border-default)`
- Border-radius: 16px (`--radius-lg`)
- Shadow: `var(--ce-shadow-card)`
- Hover: `var(--ce-shadow-card-hover)`, transition 200ms

## Shadows

Only three shadows exist. Do not invent others.

| Token | Light | Dark | Use |
|---|---|---|---|
| `--ce-shadow-card` | 0 8px 36px rgba(0,0,0,0.08) | rgba(0,0,0,0.24) | Default card state |
| `--ce-shadow-card-hover` | 0 8px 36px rgba(0,0,0,0.16) | rgba(0,0,0,0.36) | Card hover |
| `--ce-shadow-elevated` | 0 0 31px rgba(183,183,183,0.5) | rgba(0,0,0,0.4) | Dropdowns, modals |

## Image Banner Overlay

Full-width image with overlay banner:

- Container: border-radius 16px, overflow hidden
- Image: aspect-ratio 16:9, object-cover
- Overlay: `var(--ce-surface-invert)` at 85% opacity, `backdrop-filter: blur(8px)`
- Headline: Pressura 24px/500, white
- Body text: Inter 14px/400, white at 70% opacity
- Buttons: Primary (white bg, dark text) + Outline (white border at 40%)
- Padding: 32px horizontal, 24px vertical (desktop: 40px / 32px)

## Table Surfaces

| Token | Light | Dark | Use |
|---|---|---|---|
| `--ce-table-header-bg` | rgba(128,128,128,0.07) | rgba(255,255,255,0.05) | Table header row |
| `--ce-table-row-alt-bg` | rgba(0,0,0,0.024) | rgba(255,255,255,0.03) | Zebra striping (odd rows) |
| `--ce-table-border` | rgba(128,128,128,0.5) | rgba(255,255,255,0.15) | Cell borders |
| `--ce-dotted-border` | rgba(0,0,0,0.1) | rgba(255,255,255,0.08) | Dotted dividers |

Zebra striping: use for tables > 5 rows with uniform columns. NOT for key-value tables or menu lists.

## Forbidden Patterns

- **Card inside card** — never nest cards
- **FLAT element with shadow/border** — if it has a shadow, it's a card (BENTO)
- **Shadows outside the three defined** — no custom box-shadow values
- **Opacity values outside allowed set** — only 0.5 (disabled), 0.6 (inactive logos), 0.7 (banner body text), 0.85 (banner overlay)
- **@keyframes animations** — only `transition` allowed (exception: `scale(0.98)` on active)
- **z-index without documentation** — only for modals (50) and dropdowns, and comment it
10

Overview

components/overview.md
# Components — Catalog & Decision Logic

## Component Matrix

Which components are pure CSS vs. require consumer-side JavaScript.

### Pure CSS (class applies, done)

| Component | Classes | Spec |
|---|---|---|
| Buttons | `ce-btn-primary`, `ce-btn-outline` | `components/buttons.md` |
| Cards | `ce-card` | `components/cards.md` |
| Tags & Badges | `ce-tag-*`, `ce-badge-*` | `components/tags-badges.md` |
| USP Bar | `ce-usp-bar` | `components/usp-bar.md` |
| Inputs / Textarea | `ce-input`, `ce-textarea` | `components/formulare.md` |
| Tables | `ce-table-header`, `ce-table-cell` | `components/tables.md` |
| Typography | `ce-heading-*`, `ce-body`, `ce-price` | — |

### Requires JavaScript

| Component | Classes | JS Needed For | Spec |
|---|---|---|---|
| Filter Pill | `ce-filter-pill` | Active-state toggle | `components/category-filter.md` |
| Accordion | `ce-accordion__*` | Open/close, ARIA | `components/interaktiv.md` |
| Tabs | `ce-tabs__*` | Panel show/hide | `components/interaktiv.md` |
| Modal | `ce-modal` | Focus trap, overlay | `components/interaktiv.md` |
| Slider | `ce-slider` | Carousel logic, dots | `components/slider.md` |
| Hero Slider | `ce-hero-slider` | Auto-play, arrows | `components/hero-slider.md` |
| Brand Filter | `ce-brand-filter__*` | Filter logic | `components/markenfilter.md` |
| Header | — (spec only) | Consumer implements | `components/header.md` |
| Footer | — (spec only) | Consumer implements | `components/footer.md` |

## Decision Tree — Which Component?

### "I need a call to action"
- Primary action (checkout, submit)? → **Primary Button**
- Secondary action (cancel, back)? → **Outline Button**
- Compact inline action? → **Compact Button**
- See `components/button.md` for details.

### "I need to display content"
- Product with image + price? → **Product Card**
- Information block? → **Card** (generic)
- Key-value data? → **Table**
- Short label/category? → **Tag or Badge**

### "I need navigation"
- Page-level path? → **Breadcrumb**
- Multi-page results? → **Pagination**
- In-page sections? → **Anchor Links**
- See `components/navigation.md` for details.

### "I need user input"
- Text entry? → **Input** or **Textarea**
- Selection from options? → **Select** or **Radio**
- Toggle? → **Checkbox**
- See `components/form.md` for details.

### "I need to filter content"
- Category toggle? → **Filter Pill** (JS)
- Brand selection? → **Brand Filter** (JS)

## New Components

Before creating a new component:

1. Check if an existing component can be extended (add a variant, not a new pattern)
2. Use the same token logic: `--ce-surface-*` for backgrounds, `--ce-text-*` for colors
3. Prefix class with `ce-`
4. Define in `@layer components`
5. Create a spec file in `components/`
11

Button

components/button.md
# Button — Variants, States & Constraints

## Variants

| Variant | Font | Size | Padding | Radius | Height |
|---|---|---|---|---|---|
| Primary Default | Pressura Mono 15px/500 | — | py-2.5 px-5 | 8px | ~40px |
| Primary Small / Outline Small | Pressura Mono 15px/500 | — | py-1.5 px-3 | 8px | ~32px |
| Primary Compact / Outline Compact | Pressura Mono 12px/500 | — | py-1 px-2.5 | 6px | ~24px |

## Decision Tree — Which Button?

- **Primary action** (Add to Cart, Submit, Checkout)? → `ce-btn-primary`
- **Secondary action** (Cancel, Back, View Details)? → `ce-btn-outline`
- **Header/card inline action** (smaller context)? → Small variant
- **Tag-like inline action** (very compact)? → Compact variant

## States

| State | Primary | Outline |
|---|---|---|
| Default | bg: surface-invert, color: on-invert | bg: transparent, border: border-strong, color: secondary |
| Hover | bg: surface-invert-hover | border: border-strong, color: heading |
| Active | transform: scale(0.98) | transform: scale(0.98) |
| Focus | outline: 2px solid heading, offset 2px | outline: 2px solid heading, offset 2px |
| Disabled | bg: surface-muted, color: muted | border: border-muted, color: muted |

All transitions: 200ms ease.

## Consistency Rule

All buttons in the same context (header row, card footer, form actions) must have the **same visual height**. If one button is Default size, all buttons in that row are Default size.

## Icon Buttons

- Icon inside button: 16px, `currentColor`
- Icon-only button: same padding as text button, same height
- Icon + text: gap-sm (8px) between icon and label

## Constraints

- ALL buttons use Pressura Mono — never Pressura or Inter
- Hover changes background OR border — never both simultaneously
- Disabled: `cursor: not-allowed` — no custom disabled colors
- Active press: `scale(0.98)` only — no other transforms
- Focus outline is mandatory on all interactive buttons

For exact CSS values, see `components/buttons.md`.
12

Card

components/card.md
# Card — Types, Selection & Constraints

## Card Types

| Type | Use | Image | Spec |
|---|---|---|---|
| Product Card | Shop items with price | 200px height, object-contain | `components/product-cards.md` |
| Category Card | Category navigation | Full-width, object-cover | `components/cards.md` |
| Team Card | Team member profiles | Square/round avatar | `components/cards.md` |
| Service Card | Service offerings | Optional icon/image | `components/cards.md` |
| Menu Card | Cafe menu items | No image | `components/cards.md` |
| Contact Card | Contact info | No image | `components/cards.md` |
| Course Card | Workshop/course listings | Full-width image | `components/cards.md` |

## Decision Tree — Which Card?

- Showing a product with price? → **Product Card**
- Navigating to a category? → **Category Card**
- Listing team members? → **Team Card**
- Describing a service? → **Service Card**
- Showing menu items with prices? → **Menu Card**
- Displaying contact information? → **Contact Card**
- Listing workshops/courses? → **Course Card**

## Base Card Styling

All cards share:
- Background: `var(--ce-surface-card)`
- Border: 1px solid `var(--ce-border-default)`
- Border-radius: 16px (`--radius-lg`)
- Shadow: `var(--ce-shadow-card)`
- Hover: shadow → `var(--ce-shadow-card-hover)`, transition 200ms

## Product Cards Specifically

- Entire card is a link (`<a>` tag, not a button)
- Image area: 200px height, `object-contain`, centered
- Price: Pressura Mono 14px/400, `--ce-text-secondary`
- Grid: responsive via @container queries (@3xl: 2 cols, @4xl: 3 cols, @5xl: 4 cols)

## Constraints

- **Never nest cards** — a card inside a card is forbidden
- **Never add shadow to FLAT elements** — shadow = card (BENTO pattern)
- Cards always have border AND shadow — not one without the other
- Card padding: lg (20px) for body area
- Card hover: shadow change only — no background color change, no border change

For exact CSS values, see `components/cards.md` and `components/product-cards.md`.
13

Header

components/header.md
# Header — Structure, Responsive & Constraints

## Layout

| Breakpoint | Height | Nav Type | Elements |
|---|---|---|---|
| Mobile (< 768px) | 56px | Hamburger menu | Logo, hamburger icon, cart icon |
| Desktop (>= 768px) | 80px | Horizontal links | Logo, nav links, search, cart |

## Structure

Desktop (left to right):
1. Logo (left)
2. Navigation links (center or left-aligned)
3. Search + Cart icons (right)

Mobile:
1. Hamburger icon (left)
2. Logo (center)
3. Cart icon (right)

## Styling

- Background: `var(--ce-surface-card)`
- Border-bottom: 1px solid `var(--ce-border-default)`
- Nav links: Pressura 15px/300
- Nav link hover: bg `var(--ce-surface-muted)`, border-radius 6px, padding 6px 12px

## Constraints

- Header is **NOT sticky** — it scrolls with the page
- Consumer implements the header — the brand kit provides specs, not a ready-made component
- All interactive icons: 18px (desktop), 24px (mobile hamburger/close)
- Icons from Remixicon only
- Cart badge (if present): Pressura Mono 11px, ce-surface-invert background

For exact CSS values, see `components/header.md`.
14

Footer

components/footer.md
# Footer — Grid, Variants & Constraints

## Grid Layout

| Breakpoint | Columns |
|---|---|
| Mobile (< 768px) | 2 columns |
| md (>= 768px) | 3 columns |
| xl (>= 1280px) | 6 columns |

## Content Sections

Typical footer contains:
1. Brand/about section (logo + short text)
2. Navigation links (grouped by category)
3. Contact information
4. Social media icons
5. Legal links (Impressum, Datenschutz)
6. Copyright line

## Styling

- Background: can be `--ce-surface-page` (light) or `--ce-surface-invert` (dark)
- Footer headings: Pressura 16px/500
- Footer links: Inter 14px/400, line-height 28px
- Social icons: 18px, Remixicon
- Copyright: Pressura Mono 12px/400

## Dark Footer Variant

When footer uses `--ce-surface-invert` background:
- All text: `--ce-text-on-invert`
- Links: white, hover opacity change
- Logo: apply `--ce-logo-filter-invert` (invert to white)

## Constraints

- Consumer implements the footer — brand kit provides specs only
- Social icons: line style except Facebook (fill)
- Footer links have generous line-height (28px) for touch targets
- Legal links in a separate row at the bottom

For exact CSS values, see `components/footer.md`.
15

Navigation

components/navigation.md
# Navigation — Breadcrumb, Pagination & Anchor Links

## Breadcrumb

- Font: Pressura Mono 12px/400, line-height 16px
- Separator: `/` or `>` in `--ce-text-muted`
- Current page: `--ce-text-heading` (no link)
- Previous pages: `--ce-text-secondary`, hover → `--ce-text-heading`

## Pagination

- Container: flex row, gap-sm (8px)
- Page numbers: Pressura Mono 14px/400
- Active page: `--ce-surface-invert` bg, `--ce-text-on-invert` color, radius-sm
- Inactive: `--ce-text-secondary`, hover → `--ce-text-heading`
- Previous/Next arrows: Remixicon 16px

## Anchor Links (In-Page Navigation)

- Font: Pressura Mono 13px/500
- Style: similar to outline button (border, radius-sm)
- Active section: `--ce-surface-invert` bg, `--ce-text-on-invert`
- Smooth scroll behavior

## Decision Tree

- User needs to know where they are in the site? → **Breadcrumb**
- Multi-page list (products, articles)? → **Pagination**
- Long page with sections? → **Anchor Links**

## Constraints

- Breadcrumb always at the top of the page, below header
- Pagination centered below content
- All navigation text uses Pressura Mono — not Inter, not Pressura

For exact CSS values, see `components/navigation.md`.
16

Form

components/form.md
# Forms — Inputs, Validation & States

## Input Types

| Type | Class | Notes |
|---|---|---|
| Text Input | `ce-input` | Single-line text entry |
| Textarea | `ce-textarea` | Multi-line text entry |
| Select | `ce-select` | Dropdown selection |
| Radio | — | Standard radio with label |
| Checkbox | — | Standard checkbox with label |

## Styling

- Background: `var(--ce-surface-muted)`
- Border: 1px solid `var(--ce-border-default)`
- Border-radius: 8px (`--radius-sm`)
- Font: Inter 16px/400 (input value), Pressura Mono 12px/400 (label)
- Padding: base (16px) horizontal, sm (8px) to md (12px) vertical

## States

| State | Visual Change |
|---|---|
| Default | border-default, surface-muted bg |
| Focus | border-strong, outline 2px solid heading with 2px offset |
| Error | border ce-red-500, error message below |
| Disabled | opacity 0.5, cursor not-allowed |

## Labels

- Font: Pressura Mono 12px/400
- Color: `--ce-text-secondary`
- Position: above the input
- Required indicator: `*` in `--ce-red-500`

## Validation Messages

- Font: Inter 14px/400
- Error: `--ce-red-500`
- Success: `--ce-emerald-500`
- Position: below the input, gap-xs (4px)

## Decision Tree

- Short text (name, email)? → **Input**
- Long text (message, description)? → **Textarea**
- Choose one from a list? → **Select** (many options) or **Radio** (few options)
- Toggle on/off? → **Checkbox**

## Constraints

- All form labels use Pressura Mono — not Inter
- Input values use Inter — not Pressura Mono
- Focus outline is mandatory on all form elements
- Dark mode: inputs use surface-muted (auto-swaps)

For exact CSS values, see `components/formulare.md`.
17

Tag

components/tag.md
# Tags & Badges — Types, Selection & Constraints

## Types

| Type | Use | Example |
|---|---|---|
| Brand Tag | Identify brand/roaster | "Kliewe", "Partner" |
| Category Count | Show item count | "Kaffee (12)" |
| Status Badge | Indicate state | "Neu", "Sale", "Ausverkauft" |

## Styling

- Font: Pressura Mono 11px/400, uppercase, tracking-wider
- Border-radius: 9999px (`--radius-full`) for pills
- Padding: xs (4px) vertical, sm (8px) to md (12px) horizontal

### Color Variants

| Variant | Background | Text |
|---|---|---|
| Default | `--ce-surface-muted` | `--ce-text-secondary` |
| Inverted | `--ce-surface-invert` | `--ce-text-on-invert` |
| Success | `--ce-emerald-200` | emerald-800 or dark equivalent |
| Error / Sale | `--ce-red-200` | red-800 or dark equivalent |
| Warning | `--ce-yellow-200` | yellow-800 or dark equivalent |

## Decision Tree

- Labeling a brand or category? → **Brand Tag** (default or inverted)
- Showing a count next to a category? → **Category Count**
- Indicating product status? → **Status Badge** (success/error/warning)

## Constraints

- Tags are ALWAYS Pressura Mono — never Inter or Pressura
- Tags are ALWAYS uppercase with letter-spacing
- Tags use `--radius-full` (pill shape) — never square or rounded-sm
- Accent colors (red, emerald, yellow) are for status badges only — never decorative
- In dark mode, accent badges use 400 variants (lighter) for contrast

For exact CSS values, see `components/tags-badges.md`.
18

Table

components/table.md
# Tables — Patterns, Striping & Constraints

## Table Types

| Type | Zebra Striping | Use |
|---|---|---|
| Data Table | Yes | Product lists, order history, > 5 rows |
| Spec Table | No | Key-value pairs, component specs |
| Menu List | No | Cafe menu items with dotted dividers |

## Decision Tree

- Tabular data with > 5 uniform rows? → **Data Table** (with zebra)
- Key-value pairs (specs, properties)? → **Spec Table** (no zebra)
- Menu items with prices? → **Menu List** (dotted dividers)

## Styling

### Header Row

- Background: `var(--ce-table-header-bg)`
- Font: Pressura Mono 12px/400
- Color: `--ce-text-heading`

### Body Cells

- Font: Inter 14px/400 (text), Pressura Mono 14px/400 (numbers/prices)
- Color: `--ce-text-body`
- Border: 1px solid `var(--ce-table-border)`

### Zebra Striping (Data Tables Only)

- Odd rows: `var(--ce-table-row-alt-bg)`
- Even rows: transparent
- No alternating border colors — only background

### Dotted Dividers (Menu Lists)

- Border: 1px dotted `var(--ce-dotted-border)`
- Between items, not around them

## Container

- Border-radius: 16px (`--radius-lg`) on the table container
- Overflow: hidden (to clip rounded corners)
- Border: 1px solid `var(--ce-border-default)`

## Constraints

- Table headers ALWAYS use Pressura Mono — not Inter
- Numbers and prices in tables use Pressura Mono
- Descriptive text in tables uses Inter
- Zebra striping only for data tables > 5 rows
- All table tokens swap automatically in dark mode (rgba-based)

For exact CSS values, see `components/tables.md`.
19

Design Tokens (CSS)

design-tokens.css
/* ================================================================
   COFFEE ELEMENTS — DESIGN TOKENS
   Single Source of Truth for all implementations.

   HOW TO USE THIS FILE:
   - Read this file to understand all design decisions
   - Use the semantic tokens (--ce-surface-*, --ce-text-*, --ce-border-*)
   - NEVER use raw palette values directly — always go through semantics
   - Copy :root and .dark blocks into your theme CSS
   - Font files must be hosted separately (see Font Stack section)

   STRUCTURE:
   1. Palette         — Raw color values (don't use directly)
   2. Semantic Tokens  — What to actually use in components
   3. Dark Mode        — Token swaps for .dark class
   4. Font Stack       — Three font families and their roles
   5. Typography Scale — Font sizes per element type
   6. Spacing          — 4px base grid
   7. Border Radius    — Two sizes + full
   8. Shadows          — Card and elevated states
   9. Transitions      — Default timing
   10. Component Patterns — Button, icon, and layout rules
   ================================================================ */


/* ================================================================
   1. PALETTE — Raw color values

   These are the raw brand colors. Do NOT use these directly in
   components. Use the semantic tokens in section 2 instead.
   The palette exists so semantic tokens can reference it.
   ================================================================ */

:root {
  /* Neutral scale (ce-zinc) — the entire brand is built on this */
  --ce-zinc-50:  #FBFBFC;  /* Lightest — page background (light mode) */
  --ce-zinc-100: #F3F3F3;  /* Muted surfaces */
  --ce-zinc-200: #EDEEEF;  /* Borders, subtle surfaces */
  --ce-zinc-300: #D1D1D4;  /* Strong borders */
  --ce-zinc-400: #B6B7BB;  /* Muted text, disabled states */
  --ce-zinc-500: #69727D;  /* Tertiary text */
  --ce-zinc-600: #575A61;  /* Secondary text */
  --ce-zinc-700: #454850;  /* Dark borders (dark mode) */
  --ce-zinc-800: #313337;  /* Body text, muted surfaces (dark mode) */
  --ce-zinc-900: #232528;  /* Card background (dark mode) */
  --ce-zinc-950: #18191A;  /* Darkest — headings, inverted surfaces */

  /* Accent Red — error states, sale badges */
  --ce-red-200: #FECACA;  /* Light backgrounds, subtle indicators */
  --ce-red-300: #FCA5A5;  /* Badge backgrounds, hover states */
  --ce-red-400: #F87171;  /* Dark mode accent, strong indicators */
  --ce-red-500: #D93F33;  /* Primary accent (light mode) */

  /* Accent Emerald — success states, availability indicators */
  --ce-emerald-200: #A7F3D0;  /* Light backgrounds, subtle indicators */
  --ce-emerald-300: #6EE7B7;  /* Badge backgrounds, hover states */
  --ce-emerald-400: #34D399;  /* Dark mode accent, strong indicators */
  --ce-emerald-500: #10B981;  /* Primary accent (light mode) */

  /* Accent Yellow — warning states, highlight badges */
  --ce-yellow-200: #FDE68A;  /* Light backgrounds, subtle indicators */
  --ce-yellow-300: #FCD34D;  /* Badge backgrounds, hover states */
  --ce-yellow-400: #FBBF24;  /* Dark mode accent, strong indicators */
  --ce-yellow-500: #F59E0B;  /* Primary accent (light mode) */

  /* Table — semantic tokens for tabular data */
  --ce-table-header-bg:  rgba(128, 128, 128, 0.07);  /* Table header background */
  --ce-table-row-alt-bg: rgba(0, 0, 0, 0.024);       /* Alternating row background */
  --ce-table-border:     rgba(128, 128, 128, 0.5);    /* Table cell borders */
  --ce-dotted-border:    rgba(0, 0, 0, 0.1);          /* Dotted dividers (menus, specs) */
}


/* ================================================================
   2. SEMANTIC TOKENS — Light Mode (default)

   USE THESE in all components. They swap automatically in dark mode.

   Naming convention (all prefixed --ce-*):
   --ce-surface-*  → background-color
   --ce-text-*     → color
   --ce-border-*   → border-color
   ================================================================ */

:root {
  /* Surfaces — use for background-color */
  --ce-surface-page:         #FBFBFC;  /* Page background. Use on <body> and full-width sections */
  --ce-surface-card:         #FFFFFF;  /* Card backgrounds, modals, dropdowns, popups */
  --ce-surface-muted:        #F3F3F3;  /* Code blocks, input backgrounds, muted areas */
  --ce-surface-subtle:       #EDEEEF;  /* Table headers, hover states, subtle separation */
  --ce-surface-invert:       #18191A;  /* Primary buttons, inverted elements */
  --ce-surface-invert-hover: #313337;  /* Primary button hover state */

  /* Text — use for color */
  --ce-text-heading:    #18191A;  /* Headings, important labels, nav items */
  --ce-text-body:       #313337;  /* Body text, descriptions */
  --ce-text-secondary:  #575A61;  /* Supporting text, metadata, prices */
  --ce-text-tertiary:   #69727D;  /* Captions, timestamps, helper text */
  --ce-text-muted:      #B6B7BB;  /* Placeholders, disabled text, dividers */
  --ce-text-on-invert:  #FFFFFF;  /* Text on --ce-surface-invert backgrounds */

  /* Borders — use for border-color */
  --ce-border-default:  #EDEEEF;  /* Default borders on cards, tables, inputs */
  --ce-border-strong:   #D1D1D4;  /* Hover borders, emphasized separation */
  --ce-border-muted:    #F3F3F3;  /* Very subtle borders, barely visible */

  /* Shadows — use for box-shadow */
  --ce-shadow-card:       0px 8px 36px 0px rgba(0, 0, 0, 0.08);   /* Default card shadow */
  --ce-shadow-card-hover: 0px 8px 36px 0px rgba(0, 0, 0, 0.16);   /* Card hover state */
  --ce-shadow-elevated:   0px 0px 31px 0px rgba(183, 183, 183, 0.5); /* Dropdowns, modals */

  /* Logo filter — apply via CSS filter to monochrome SVG logos */
  --ce-logo-filter:        none;       /* Light mode: logos stay dark */
  --ce-logo-filter-invert: invert(1);  /* Force-invert logos (use on dark backgrounds) */
}


/* ================================================================
   3. DARK MODE — Token swaps

   Activated via .dark class on <html> or <body>.
   All semantic tokens swap — components don't need to change.

   RULE: Dark mode swaps tokens, not layouts. No structural
   changes, no different components. Just color swaps.
   ================================================================ */

.dark {
  --ce-surface-page:         #18191A;
  --ce-surface-card:         #232528;
  --ce-surface-muted:        #313337;
  --ce-surface-subtle:       #313337;
  --ce-surface-invert:       #FBFBFC;  /* Inverts: light bg for primary buttons */
  --ce-surface-invert-hover: #EDEEEF;

  --ce-text-heading:    #FBFBFC;
  --ce-text-body:       #EDEEEF;
  --ce-text-secondary:  #B6B7BB;
  --ce-text-tertiary:   #69727D;
  --ce-text-muted:      #69727D;
  --ce-text-on-invert:  #18191A;  /* Dark text on light inverted bg */

  --ce-border-default:  #454850;
  --ce-border-strong:   #575A61;
  --ce-border-muted:    #313337;

  --ce-shadow-card:       0px 8px 36px 0px rgba(0, 0, 0, 0.24);  /* Higher opacity */
  --ce-shadow-card-hover: 0px 8px 36px 0px rgba(0, 0, 0, 0.36);
  --ce-shadow-elevated:   0px 0px 31px 0px rgba(0, 0, 0, 0.4);

  /* Accents — lighter variants for better contrast on dark backgrounds */
  --ce-accent-red:     #F87171;
  --ce-accent-emerald: #34D399;
  --ce-accent-yellow:  #FBBF24;

  /* Table */
  --ce-table-header-bg:  rgba(255, 255, 255, 0.05);
  --ce-table-row-alt-bg: rgba(255, 255, 255, 0.03);
  --ce-table-border:     rgba(255, 255, 255, 0.15);
  --ce-dotted-border:    rgba(255, 255, 255, 0.08);

  --ce-logo-filter:        invert(1);  /* Dark mode: invert dark logos to white */
  --ce-logo-filter-invert: none;
}


/* ================================================================
   4. FONT STACK — Three families, strict assignment

   RULE: Never mix assignments. Each font has a fixed role.

   Font files (woff2):
   - gt-pressura-light.woff2      (weight 300)
   - gt-pressura-regular.woff2    (weight 500)
   - gt-pressura-mono.woff2       (weight 400, 500)
   - Inter: loaded via Google Fonts or CDN
   ================================================================ */

/*
   PRESSURA (font-family: 'Pressura', sans-serif)
   Role: Headings, display text, navigation links
   Weights: 300 (light — nav links, large headings)
            500 (medium — section headings, card titles)

   USE FOR: h1-h6, nav links, card titles, section headers
   NEVER FOR: body text, buttons, prices, labels
*/

/*
   PRESSURA MONO (font-family: 'Pressura Mono', sans-serif)
   Role: Buttons, UI elements, labels, prices, badges, captions
   Weights: 400 (regular — prices, labels)
            500 (medium — buttons)

   USE FOR: all buttons, price displays, category labels, badges,
            breadcrumbs, form labels, table headers, footer copyright
   NEVER FOR: body text, headings, paragraphs
*/

/*
   INTER (font-family: 'Inter', sans-serif)
   Role: Body text, descriptions, paragraphs
   Weight: 400 only

   USE FOR: paragraphs, descriptions, long-form text, list items
   NEVER FOR: headings, buttons, labels, prices
*/


/* ================================================================
   5. TYPOGRAPHY SCALE — Fixed sizes per element type

   Do not invent sizes. Use these exact values.
   ================================================================ */

/*
   Element              Font              Size    Weight  Line-Height
   -------              ----              ----    ------  -----------
   H1 (hero)            Pressura          54px    300     64px
   H2 (section)         Pressura          24px    500     32px
   Subtitle             Pressura          28px    300     36px
   Nav link             Pressura          15px    300     —
   Body text            Inter             16px    400     24px
   Intro paragraph      Inter             28px    400     36px
   Button (default)     Pressura Mono     15px    500     —
   Button (outline)     Pressura Mono     13px    500     —
   Button (compact)     Pressura Mono     12px    500     —
   Price                Pressura Mono     14px    400     —
   Label/Badge          Pressura Mono     11px    400     —  (uppercase, tracking-wider)
   Caption              Pressura Mono     12px    400     —
   Breadcrumb           Pressura Mono     12px    400     16px
   Small text           Inter             14px    400     22px
   Footer link          Inter             14px    400     28px
*/


/* ================================================================
   6. SPACING — 4px base grid

   All spacing uses multiples of 4px.
   Use these values for padding, margin, and gap.
   ================================================================ */

/*
   Token    Value    Common use
   -----    -----    ----------
   xs       4px      Tight inline gaps (icon + label)
   sm       8px      Small gaps between related items
   md       12px     Medium gaps, icon-to-text spacing
   base     16px     Default padding, standard gaps
   lg       20px     Card body padding, section gaps
   xl       24px     Section padding, header/footer padding
   2xl      32px     Large section padding (desktop)
   3xl      48px     Section margins (desktop)
   4xl      64px     Page-level vertical rhythm
*/


/* ================================================================
   7. BORDER RADIUS — Two sizes + full
   ================================================================ */

/*
   Token         Value     Use
   -----         -----     ---
   --radius-sm   8px       Buttons, inputs, small cards, badges
   --radius-lg   16px      Cards, modals, large containers, product tiles
   --radius-full 9999px    Pills, circular avatars, round buttons

   Images: use border-radius 6px (rounded-md) — NOT the token scale
*/


/* ================================================================
   8. SHADOWS
   ================================================================ */

/*
   --ce-shadow-card         Default card rest state (subtle, 8% opacity)
   --ce-shadow-card-hover   Card hover state (stronger, 16% opacity)
   --ce-shadow-elevated     Dropdowns, modals, floating elements

   Dark mode: opacity increases (0.08→0.24, 0.16→0.36)
*/


/* ================================================================
   9. TRANSITIONS — Default timing
   ================================================================ */

/*
   Default: 200ms ease (buttons, links, interactive elements)
   Extended: 300ms ease (cards, panels, larger surfaces)

   Properties to transition:
   - color (text hover)
   - background-color (button hover)
   - border-color (input focus, outline button hover)
   - box-shadow (card hover)
   - opacity (fade in/out)
   - transform (active press: scale(0.98))
*/


/* ================================================================
   10. COMPONENT PATTERNS

   These are the recurring patterns across all components.
   Implement these exactly — do not vary.
   ================================================================ */

/* --- BUTTONS ---

   All buttons use Pressura Mono. Three sizes:

   DEFAULT:  font-size 15px, font-weight 500, padding 10px 20px, border-radius 8px
   SMALL:    font-size 15px, font-weight 500, padding 6px 12px, border-radius 8px
   COMPACT:  font-size 12px, font-weight 500, padding 4px 10px, border-radius 6px

   PRIMARY variant:
     background: var(--ce-surface-invert)
     color: var(--ce-text-on-invert)
     hover: background var(--ce-surface-invert-hover)
     active: transform scale(0.98)
     disabled: background var(--ce-surface-muted), color var(--ce-text-muted), cursor not-allowed

   OUTLINE variant:
     background: transparent
     border: 1px solid var(--ce-border-strong)
     color: var(--ce-text-secondary)
     hover: border-color var(--ce-border-strong), color var(--ce-text-heading)
     active: transform scale(0.98)
     disabled: border var(--ce-border-muted), color var(--ce-text-muted), cursor not-allowed
*/

/* --- ICONS ---

   Library: Remixicon ONLY (https://remixicon.com)
   Style: line (never fill, unless explicitly required)
   SVG attributes: viewBox="0 0 24 24" fill="currentColor"

   Sizes:
   14px — inline text, USP bar items
   16px — inside buttons
   18px — footer social icons
   24px — mobile navigation hamburger/close
*/

/* --- CARDS ---

   background: var(--ce-surface-card)
   border: 1px solid var(--ce-border-default)
   border-radius: 16px (--radius-lg)
   box-shadow: var(--ce-shadow-card)
   hover: box-shadow var(--ce-shadow-card-hover)
   padding: 20px (body area)

   Product cards: entire card is clickable (<a> tag, not button)
   Image area: 200px height, object-contain, centered
*/

/* --- LAYOUT ---

   Two patterns:

   FLAT: Content directly on page surface, no card container.
         Use for: hero sections, brand logos, large headings.

   BENTO: Content in cards with shadow/border.
          Use for: product grids, team sections, feature lists.

   Page background: var(--ce-surface-page)
   Card background: var(--ce-surface-card)
   Max content width: 1140px, centered

   Responsive breakpoints:
   md: 768px  (tablet/desktop split)
   xl: 1280px (wide desktop)
*/

/* --- IMAGE BANNER ---

   Full-width image with overlay banner at bottom:

   Container: border-radius 16px, overflow hidden
   Image: aspect-ratio 16:9, object-cover
   Overlay: background var(--ce-surface-invert) at 85% opacity, backdrop-blur
   Headline: Pressura 24px/500, white
   Body text: Inter 14px/400, white at 70% opacity
   Buttons: Primary (white bg, dark text) + Outline (white border at 40%)
   Padding: 32px horizontal, 24px vertical (desktop: 40px / 32px)
*/
20

Design Tokens (JSON)

design-system.json
{
  "$schema": {
    "name": "Coffee Elements Design System",
    "version": "1.0.0",
    "description": "Machine-readable design token manifest for LLM agents. Contains all verified design tokens, component specs, and brand guidelines for the Coffee Elements web presence. Source of truth for autonomous design decisions.",
    "source": "Extracted from globals.css and codebase, verified against coffee-elements.de",
    "lastUpdated": "2026-03-27"
  },

  "palette": {
    "description": "Raw color values organized by hue. These are the primitive palette — use semantic tokens (see 'tokens') for actual UI decisions.",
    "zinc": {
      "50": "#FBFBFC",
      "100": "#F3F3F3",
      "200": "#EDEEEF",
      "300": "#D1D1D4",
      "400": "#B6B7BB",
      "500": "#69727D",
      "600": "#575A61",
      "700": "#454850",
      "800": "#313337",
      "900": "#232528",
      "950": "#18191A"
    },
    "red": {
      "200": "#FECACA",
      "300": "#FCA5A5",
      "400": "#F87171",
      "500": "#D93F33"
    },
    "emerald": {
      "200": "#A7F3D0",
      "300": "#6EE7B7",
      "400": "#34D399",
      "500": "#10B981"
    },
    "yellow": {
      "200": "#FDE68A",
      "300": "#FCD34D",
      "400": "#FBBF24",
      "500": "#F59E0B"
    }
  },

  "tokens": {
    "description": "Semantic design tokens mapped to palette values. Always use these instead of raw palette colors. Each token has a 'light' and 'dark' value.",
    "light": {
      "surfaces": {
        "description": "Background colors for page regions, cards, and containers.",
        "ce-surface-page": "#FBFBFC",
        "ce-surface-card": "#FFFFFF",
        "ce-surface-muted": "#F3F3F3",
        "ce-surface-subtle": "#EDEEEF",
        "ce-surface-invert": "#18191A",
        "ce-surface-invert-hover": "#313337"
      },
      "text": {
        "description": "Text colors ordered by visual prominence: heading (strongest) to muted (weakest). Use text-on-invert for text on inverted surfaces.",
        "ce-text-heading": "#18191A",
        "ce-text-body": "#313337",
        "ce-text-secondary": "#575A61",
        "ce-text-tertiary": "#69727D",
        "ce-text-muted": "#B6B7BB",
        "ce-text-on-invert": "#FFFFFF"
      },
      "borders": {
        "description": "Border colors ordered by visual weight.",
        "ce-border-default": "#EDEEEF",
        "ce-border-strong": "#D1D1D4",
        "ce-border-muted": "#F3F3F3"
      },
      "accents": {
        "description": "Accent colors for status indicators, highlights, and emphasis. Mapped from palette 500 values in light mode.",
        "ce-accent-red": "#D93F33",
        "ce-accent-emerald": "#10B981",
        "ce-accent-yellow": "#F59E0B"
      },
      "tables": {
        "description": "Semantic tokens for table components: header backgrounds, alternating rows, and border styles.",
        "ce-table-header-bg": "rgba(128, 128, 128, 0.07)",
        "ce-table-row-alt-bg": "rgba(0, 0, 0, 0.024)",
        "ce-table-border": "rgba(128, 128, 128, 0.5)",
        "ce-dotted-border": "rgba(0, 0, 0, 0.1)"
      }
    },
    "dark": {
      "surfaces": {
        "ce-surface-page": "#18191A",
        "ce-surface-card": "#232528",
        "ce-surface-muted": "#313337",
        "ce-surface-subtle": "#313337",
        "ce-surface-invert": "#FBFBFC",
        "ce-surface-invert-hover": "#EDEEEF"
      },
      "text": {
        "ce-text-heading": "#FBFBFC",
        "ce-text-body": "#EDEEEF",
        "ce-text-secondary": "#B6B7BB",
        "ce-text-tertiary": "#69727D",
        "ce-text-muted": "#69727D",
        "ce-text-on-invert": "#18191A"
      },
      "borders": {
        "ce-border-default": "#454850",
        "ce-border-strong": "#575A61",
        "ce-border-muted": "#313337"
      },
      "accents": {
        "ce-accent-red": "#F87171",
        "ce-accent-emerald": "#34D399",
        "ce-accent-yellow": "#FBBF24"
      },
      "tables": {
        "ce-table-header-bg": "rgba(255, 255, 255, 0.05)",
        "ce-table-row-alt-bg": "rgba(255, 255, 255, 0.03)",
        "ce-table-border": "rgba(255, 255, 255, 0.15)",
        "ce-dotted-border": "rgba(255, 255, 255, 0.08)"
      }
    }
  },

  "typography": {
    "description": "Font families, weights, and type scale. Pressura is the brand typeface for headings and navigation. Pressura Mono is used for interactive elements (buttons, labels, prices). Inter is the body text font.",
    "fontFamilies": {
      "heading": {
        "name": "Pressura",
        "usage": "Headings, navigation links",
        "weights": {
          "light": 300,
          "medium": 500
        }
      },
      "mono": {
        "name": "Pressura Mono",
        "usage": "Buttons, UI labels, prices, interactive elements",
        "weights": {
          "regular": 400,
          "medium": 500
        }
      },
      "body": {
        "name": "Inter",
        "usage": "Body text, paragraphs, descriptions",
        "weights": {
          "regular": 400
        }
      }
    },
    "scale": {
      "description": "Type scale with font-size and line-height. Values are in px for precision — convert to rem (÷16) when implementing.",
      "h1": {
        "fontSize": "54px",
        "lineHeight": "64px",
        "fontFamily": "Pressura",
        "usage": "Page hero titles"
      },
      "h2-section": {
        "fontSize": "24px",
        "lineHeight": "32px",
        "fontFamily": "Pressura",
        "usage": "Section headings"
      },
      "subtitle": {
        "fontSize": "28px",
        "lineHeight": "36px",
        "fontFamily": "Pressura",
        "usage": "Subtitles, large subheadings"
      },
      "intro": {
        "fontSize": "28px",
        "lineHeight": null,
        "fontFamily": "Inter",
        "usage": "Intro paragraphs, lead text"
      },
      "nav": {
        "fontSize": "24px",
        "lineHeight": null,
        "fontFamily": "Pressura",
        "usage": "Navigation menu items"
      },
      "body": {
        "fontSize": "16px",
        "lineHeight": "24px",
        "fontFamily": "Inter",
        "usage": "Default body text"
      },
      "button": {
        "fontSize": "15px",
        "lineHeight": null,
        "fontFamily": "Pressura Mono",
        "fontWeight": 500,
        "usage": "Primary buttons (filled)"
      },
      "button-outline": {
        "fontSize": "13px",
        "lineHeight": null,
        "fontFamily": "Pressura Mono",
        "fontWeight": 500,
        "usage": "Outline/secondary buttons"
      },
      "small": {
        "fontSize": "14px",
        "lineHeight": null,
        "fontFamily": "Inter",
        "usage": "Small text, supporting copy"
      },
      "breadcrumb": {
        "fontSize": "12px",
        "lineHeight": "16px",
        "fontFamily": "Pressura Mono",
        "usage": "Breadcrumbs, metadata"
      },
      "caption": {
        "fontSize": "12px",
        "lineHeight": null,
        "fontFamily": "Inter",
        "usage": "Captions, fine print"
      }
    }
  },

  "spacing": {
    "description": "Spacing scale based on a 4px base grid. Use these tokens for padding, margins, and gaps.",
    "baseUnit": "4px",
    "scale": {
      "xs": "4px",
      "sm": "8px",
      "md": "12px",
      "base": "16px",
      "lg": "20px",
      "xl": "24px",
      "2xl": "32px",
      "3xl": "48px",
      "4xl": "64px"
    }
  },

  "borderRadius": {
    "description": "Border radius tokens. Use 'sm' for buttons and cards, 'lg' for modals and large containers, 'full' for pills and avatars.",
    "sm": "8px",
    "lg": "16px",
    "full": "9999px"
  },

  "shadows": {
    "description": "Box shadow tokens. Dark mode uses higher opacity for visibility against dark surfaces.",
    "card": {
      "light": "0px 8px 36px 0px rgba(0, 0, 0, 0.08)",
      "dark": "0px 8px 36px 0px rgba(0, 0, 0, 0.24)",
      "usage": "Default card elevation"
    },
    "card-hover": {
      "light": "0px 8px 36px 0px rgba(0, 0, 0, 0.16)",
      "dark": "0px 8px 36px 0px rgba(0, 0, 0, 0.36)",
      "usage": "Card hover state — pair with transition"
    },
    "elevated": {
      "light": "0px 0px 31px 0px rgba(183, 183, 183, 0.5)",
      "dark": "0px 0px 31px 0px rgba(0, 0, 0, 0.4)",
      "usage": "Elevated UI elements (modals, popovers)"
    }
  },

  "icons": {
    "description": "Icon system configuration. All icons come from the Remixicon library — never generate SVG paths manually.",
    "library": "Remixicon",
    "defaultStyle": "line",
    "color": "currentColor",
    "svgAttributes": {
      "viewBox": "0 0 24 24",
      "fill": "currentColor"
    },
    "sizes": {
      "inline": {
        "size": "14px",
        "tailwind": "w-3.5 h-3.5",
        "usage": "Inline icons, USP icons, footer pill icons"
      },
      "button": {
        "size": "16px",
        "tailwind": "w-4 h-4",
        "usage": "Icons inside buttons"
      },
      "footer-social": {
        "size": "18px",
        "tailwind": "w-[18px] h-[18px]",
        "usage": "Social media icons in footer"
      },
      "mobile-nav": {
        "size": "24px",
        "tailwind": "w-6 h-6",
        "usage": "Mobile navigation hamburger and close icons"
      }
    }
  },

  "breakpoints": {
    "description": "Responsive breakpoints. Mobile-first approach — base styles are mobile, then override at md and xl.",
    "mobile": {
      "maxWidth": "767px",
      "description": "Default styles, no media query needed"
    },
    "md": {
      "minWidth": "768px",
      "description": "Tablet and small desktop"
    },
    "xl": {
      "minWidth": "1280px",
      "description": "Large desktop"
    },
    "containerQueries": {
      "description": "Container queries used for product grids. Apply @container on the grid parent element.",
      "sizes": ["@3xl", "@4xl", "@5xl"]
    }
  },

  "components": {
    "description": "Key component specifications with verified measurements. Use these as constraints when building or modifying components.",
    "header": {
      "desktop": {
        "height": "80px",
        "maxWidth": "1140px",
        "logoWidth": "190px"
      },
      "mobile": {
        "height": "56px",
        "logoWidth": "16px",
        "logoType": "icon-only"
      },
      "behavior": "static (not sticky)"
    },
    "footer": {
      "maxWidth": "1200px",
      "gridColumns": {
        "description": "6-column grid: 4 info columns + 2 contact columns",
        "total": 6,
        "infoColumns": 4,
        "contactColumns": 2
      },
      "responsiveGrid": {
        "mobile": "2 columns",
        "md": "3 columns",
        "xl": "6 columns"
      }
    },
    "buttons": {
      "primary": {
        "paddingY": "10px",
        "paddingX": "20px",
        "borderRadius": "8px",
        "fontSize": "15px",
        "fontWeight": 500,
        "fontFamily": "Pressura Mono"
      },
      "small": {
        "paddingY": "6px",
        "paddingX": "12px",
        "borderRadius": "8px",
        "fontSize": "15px",
        "fontWeight": 500,
        "fontFamily": "Pressura Mono"
      },
      "compact": {
        "paddingY": "4px",
        "paddingX": "10px",
        "borderRadius": "6px",
        "fontSize": "12px",
        "fontWeight": 500,
        "fontFamily": "Pressura Mono"
      }
    },
    "productCards": {
      "shadow": "card",
      "shadowHover": "card-hover",
      "transitionDuration": "300ms",
      "imageHeight": "200px",
      "imageObjectFit": "contain",
      "padding": {
        "shop": "p-5 (20px)",
        "review": "p-4 (16px)"
      }
    }
  },

  "transitions": {
    "description": "Animation and transition defaults. Use these for all interactive state changes (hover, focus, active).",
    "defaultDuration": "300ms",
    "defaultEasing": "ease",
    "commonProperties": [
      "opacity",
      "box-shadow",
      "background-color",
      "color",
      "transform"
    ]
  }
}