Files
boc/design/DESIGN_SYSTEM.md
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

399 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design System Documentation
## quiXzoom & Landvex
> Last updated: 2026-06-24
> Status: Production-ready v1.0
---
## Table of Contents
1. [Token System Architecture](#1-token-system-architecture)
2. [quiXzoom Brand Rules](#2-quixzoom-brand-rules)
3. [Landvex Brand Rules](#3-landvex-brand-rules)
4. [Shared Constraints](#4-shared-constraints)
5. [Typography Deep-Dive](#5-typography-deep-dive)
6. [Spacing & Grid](#6-spacing--grid)
7. [PR Audit Checklist](#7-pr-audit-checklist)
8. [Do / Don't Reference](#8-do--dont-reference)
---
## 1. Token System Architecture
### How It Works
Each brand ships a single CSS custom properties file (`:root { ... }`). All component CSS references these tokens — **never raw values**.
```
design/
├── quixzoom-tokens.css ← Import first, sets all --qx-* vars
├── landvex-tokens.css ← Import first, sets all --lv-* vars
├── quixzoom-hero.html ← Self-contained, inline tokens
└── landvex-hero.html ← Self-contained, inline tokens
```
### Token Naming Convention
| Prefix | Brand |
|--------|-------|
| `--qx-` | quiXzoom |
| `--lv-` | Landvex |
### Token Categories
Every token file provides these exact categories in this order:
1. **Grayscale** — 4 stops from white → deep carbon
2. **Accent colors** — primary + secondary + alpha variants
3. **Semantic aliases** — bg, text-primary, border, etc. (reference grayscale/accents)
4. **Spacing** — 8px-grid-aligned steps
5. **Typography** — font stacks, locked type scale, weights, line-heights, tracking
6. **Easing** — named timing functions + duration values
7. **Border radius** — 5-step scale
8. **Shadow system** — layered shadows appropriate to each theme
9. **Z-index scale** — consistent stacking context
10. **Transition helpers** — shorthand transition values
### Why Semantic Aliases?
```css
/* ✅ Correct — uses semantic alias */
color: var(--qx-text-primary);
/* ❌ Wrong — hardcodes the raw color */
color: #FFFFFF;
/* ❌ Also wrong — bypasses semantic layer */
color: var(--qx-white);
```
Semantic aliases (`--qx-text-primary`, `--lv-bg-surface`) let you reskin a component
for dark/light variants by swapping token values — not rewriting component CSS.
---
## 2. quiXzoom Brand Rules
### Philosophy
**Sport-Tech / Nike-vibes.** Energy, kinetic motion, dark precision.
quiXzoom never feels corporate. It feels like it was built by athletes, for athletes.
### Theme
- **Always dark-first.** Default background: `--qx-deep-carbon` (`#0D0D0D`)
- **Light theme is only permitted** for marketing landing pages with explicit design approval
### Colors
| Token | Value | Use |
|-------|-------|-----|
| `--qx-neon-primary` | `#00FF87` | CTAs, highlights, focus rings, glow effects |
| `--qx-neon-secondary` | `#00D1FF` | Links, hover states, secondary actions |
| `--qx-deep-carbon` | `#0D0D0D` | Page background |
| `--qx-gray-700` | `#2A2A2A` | Surface / card backgrounds |
**Accent usage rules:**
- Neon green (`--qx-neon-primary`) is the **only** primary CTA color
- Never use neon on a light background — contrast degrades to unusable
- Glow effects (box-shadow with neon alpha) are **permitted** on CTAs only
- Never use neon as body text color — always gray-400 or white for prose
### Typography
- **Font:** Inter (900 Black for display, 700 Bold for headings, 400 Regular for body)
- **Display sizes:** `--qx-text-xl` (64px) desktop, `--qx-text-lg` (48px) minimum
- **Locked scale:** 12 / 16 / 24 / 48 / 64px — no values between these
- **Letter spacing on display:** always `-0.03em`
- **Line height on display:** always `1.0` — never more
### Animation
- **Signature easing:** `--qx-ease-snap` = `cubic-bezier(0.16, 1, 0.3, 1)`
- **All hero animations** use `ease-enter` = `cubic-bezier(0.22, 1, 0.36, 1)`
- **Stagger hero elements:** 0.1s increments (eyebrow → headline → sub → CTA)
- **Respect prefers-reduced-motion** — wrap animations in media query
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
```
### Forbidden in quiXzoom
- ❌ Light backgrounds (without explicit approval)
- ❌ Serif fonts
- ❌ Rounded corners above `--qx-radius-md` (8px) on interactive elements
- ❌ Easing other than the defined set
- ❌ More than 2 accent colors in a single view
- ❌ Drop shadows without neon tinting in dark context
---
## 3. Landvex Brand Rules
### Philosophy
**German Enterprise / Siemens-vibes.** Precision, system, authority.
Landvex never feels playful. It feels like the most reliable tool in the room.
### Theme
- **Always light-first.** Default background: `--lv-white` (`#FFFFFF`)
- **Dark theme is not supported** — Landvex has no dark mode in v1
### Colors
| Token | Value | Use |
|-------|-------|-----|
| `--lv-enterprise-blue` | `#1B4FBF` | CTAs, links, active states, accent rules |
| `--lv-enterprise-dark` | `#0F2E6E` | Hover/pressed on blue elements |
| `--lv-gray-200` | `#DEDEDE` | Separator lines, dividers |
| `--lv-gray-800` | `#222222` | Primary body text |
**Accent usage rules:**
- Enterprise blue is reserved for **interactive** elements only (buttons, links, focus)
- Never use enterprise blue as a background color for large areas
- Never use more than one accent color per screen
- Decorative use of blue (icon fills, rule lines) is permitted at reduced opacity
### Typography
- **Sans:** IBM Plex Sans — headings, labels, body, UI
- **Serif:** IBM Plex Serif — long-form editorial content, quotes, executive reports only
- **Mono:** IBM Plex Mono — code, API keys, data tables
- **Body line-height:** always `1.55` (`--lv-leading-base`) — non-negotiable
- **Display sizes:** `--lv-text-lg` (48px) max, `--lv-text-md` (24px) for sections
- **Tracking on overlines/labels:** `0.080.10em` with uppercase
### Separator Lines
Thin horizontal rules are core to Landvex's visual language.
Use `border-top: 1px solid var(--lv-border)` to:
- Divide major content sections
- Separate items in lists
- Create structural grouping without whitespace alone
**Never use decorative thick rules**`border-top` should always be `1px`.
The only permitted `2px` rule is `--lv-separator-accent` used to highlight the active tab/section.
### Grid
- **Base unit:** 8px (`--lv-grid-base`)
- **All spacing values must be multiples of 8px**
- **Exception:** 4px (`--lv-space-xs`) permitted only for internal component padding (badges, labels)
- **Content max-width:** `--lv-container-lg` (1200px) for standard pages
### Forbidden in Landvex
- ❌ Dark backgrounds
- ❌ Neon or high-saturation accent colors
- ❌ Rounded corners above `--lv-radius-md` (4px) on structural elements
- ❌ Animation durations above `--lv-dur-slow` (350ms)
- ❌ Drop shadows with colored glow
- ❌ Text ALL-CAPS for body copy (labels/overlines only)
- ❌ Font weights below 400 for body text
- ❌ Decorative illustrations or icons — data visualization only
---
## 4. Shared Constraints
These rules apply to **both brands** without exception.
### Currency
- ✅ Always use **EUR (€)** or **USD ($)**
- ❌ Never use SEK or any other currency in UI copy or examples
### Responsiveness
- **iPhone-first** — design for 390px viewport, scale up
- Test breakpoints: `390px` / `640px` / `1024px` / `1440px`
- No horizontal scroll at any breakpoint above 320px
### Performance
- No external CSS frameworks (Bootstrap, Tailwind, etc.)
- No JavaScript required for hero sections — pure HTML/CSS
- Google Fonts loaded with `display=swap` — always
- Images must have `width` and `height` attributes — prevent CLS
### Accessibility
- Semantic HTML: `<nav>`, `<section>`, `<h1>` one per page, `<aside>`
- All interactive elements must have visible focus styles
- `aria-label` on all navigation regions
- Decorative elements marked `aria-hidden="true"`
- Color is never the sole indicator of state
### Type Scale — Locked
Both brands use the **same locked type scale**:
| Token | Size | Use |
|-------|------|-----|
| `*-text-xs` | 12px | Labels, captions, badges, overlines |
| `*-text-sm` | 16px | Body text, nav links, button labels |
| `*-text-md` | 24px | Section headings, card titles |
| `*-text-lg` | 48px | Page-level headings |
| `*-text-xl` | 64px | Hero display (quiXzoom primary, Landvex upper bound) |
**No interpolated values between steps.** If 20px looks right, it's wrong — use 16px or 24px.
---
## 5. Typography Deep-Dive
### quiXzoom Typography
```
Display (hero): Inter Black 900 / 64px / lh 1.0 / ls -0.03em
Heading 1: Inter Black 900 / 48px / lh 1.0 / ls -0.02em
Heading 2: Inter Bold 700 / 24px / lh 1.2 / ls -0.01em
Body: Inter Regular 400 / 16px / lh 1.5 / ls 0
Label/Eyebrow: Inter Bold 700 / 12px / lh 1 / ls +0.15em / UPPERCASE
```
**Why Inter?**
Inter's tight metrics at high weights create the dense, athletic look appropriate for
a sport-tech product. The `-0.03em` letter-spacing on display text echoes Nike/Adidas
brand typography conventions.
### Landvex Typography
```
Display (hero): IBM Plex Serif Semibold 600 / 48px / lh 1.2 / ls -0.01em
Heading 2: IBM Plex Sans Semibold 600 / 24px / lh 1.35 / ls 0
Body: IBM Plex Sans Regular 400 / 16px / lh 1.55 / ls 0
Caption: IBM Plex Sans Regular 400 / 12px / lh 1.55 / ls 0
Label/Overline: IBM Plex Sans Medium 500 / 12px / lh 1 / ls +0.10em / UPPERCASE
Data/Code: IBM Plex Mono Regular 400 / 14px / lh 1.5 / ls 0
```
**Why IBM Plex?**
IBM Plex is the house typeface of IBM — the canonical German-enterprise-technology voice.
Its Sans variant has mechanical precision without coldness. Its Serif variant provides
editorial gravity for boardroom-level reports. The family cohesion eliminates font-pairing risk.
**line-height 1.55:**
The `1.55` body line-height is Landvex's typographic signature. It provides maximum
reading comfort for high text-density layouts (1218 words per line) without
requiring increased font size. Never change this value.
---
## 6. Spacing & Grid
### 8px Base Grid
Both systems use an 8px base unit. All spacing must be a multiple of 8.
```
4px = --qx-space-xs / --lv-space-0.5 → micro (badge padding only)
8px = --qx-space-sm / --lv-space-1 → tight grouping
16px = --qx-space-md / --lv-space-2 → standard gap
24px = --lv-space-3 → section internal padding (Landvex only)
32px = --qx-space-lg / --lv-space-4 → section spacing
48px = --lv-space-6 → large section gap
64px = --qx-space-xl / --lv-space-8 → major section break / hero padding
96px = --qx-space-2xl / --lv-space-12 → page-level rhythm
128px = --qx-space-3xl / --lv-space-16 → XL layout breathing
```
### When to Use 4px
4px is **only** permitted for:
- Internal padding on small components (badge pill, tag, inline chip)
- Icon-to-text gap in compact lists
- Fine-tuning vertical rhythm within a text block
Never use 4px as a layout spacing unit.
---
## 7. PR Audit Checklist
Copy this block into your PR description when touching design files.
```markdown
## Design System Audit
### Token Compliance
- [ ] No hardcoded hex values in component CSS
- [ ] No hardcoded px values outside of the locked type scale
- [ ] All spacing values are multiples of 8px
- [ ] Semantic aliases used (e.g. `--qx-text-primary` not `--qx-white`)
### Brand Rules
- [ ] quiXzoom: dark background maintained
- [ ] Landvex: light background maintained
- [ ] Currency is EUR or USD only — no SEK
- [ ] Type scale uses only: 12 / 16 / 24 / 48 / 64px
- [ ] No external CSS frameworks added
### quiXzoom Specifics (if applicable)
- [ ] Neon green used only for interactive/CTA elements
- [ ] Easing uses `--qx-ease-snap` or `--qx-ease-enter`
- [ ] Hero animation stagger is ≤ 1.0s total
- [ ] `prefers-reduced-motion` respected
### Landvex Specifics (if applicable)
- [ ] Body line-height is `1.55`
- [ ] Separator lines are `1px solid var(--lv-border)`
- [ ] All spacing is on 8px grid
- [ ] No rounded corners above `--lv-radius-md` (4px) on structural elements
- [ ] No colored shadows
### Accessibility
- [ ] One `<h1>` per page
- [ ] All interactive elements have focus styles
- [ ] Decorative elements have `aria-hidden="true"`
- [ ] Color is not the sole indicator of state
- [ ] `<img>` tags have `alt`, `width`, and `height`
### Responsiveness
- [ ] Tested at 390px (iPhone 14)
- [ ] Tested at 640px (tablet)
- [ ] Tested at 1024px (desktop)
- [ ] No horizontal scroll at any breakpoint
```
---
## 8. Do / Don't Reference
### quiXzoom
| ✅ Do | ❌ Don't |
|-------|----------|
| Use `--qx-neon-primary` for CTAs | Use neon on light backgrounds |
| Use Inter Black 900 for display | Use system fonts for display |
| Animate with `--qx-ease-snap` | Use `ease-in-out` or `linear` |
| Keep display line-height at `1.0` | Add padding between headline words |
| Use dark overlays for card hover | Use light overlays or color fills |
| Price in EUR / USD | Price in SEK |
### Landvex
| ✅ Do | ❌ Don't |
|-------|----------|
| Use `1px solid var(--lv-border)` for dividers | Use thick rules or decorative lines |
| Keep body `line-height: 1.55` | Change body line-height for "breathing" |
| Use IBM Plex Serif for editorial | Use IBM Plex Serif for UI labels |
| Use 8px-grid spacing always | Use arbitrary pixel values |
| Use `--lv-enterprise-blue` for interactive only | Paint large areas enterprise-blue |
| Animate with `--lv-ease-standard` | Use spring/bounce easing |
| Price in EUR / USD | Price in SEK |
---
*Design system maintained by the quiXzoom/Landvex platform team.*
*Questions → design@quixzoom.com / design@landvex.com*