# Design Tokens This file maps the shipped dark visual system to its implementation source in `web/styles.css`. `DESIGN.md` is the portable design contract; the `:root` custom properties in `web/styles.css` are the runtime source of truth. ## Architecture - Replace tokens and component definitions in place. Do not append a legacy-compatible theme override layer. - Keep shared primitives in `:root`; keep component behavior in its existing semantic rule group. - Business-component rules must not use `!important`. - Only accessibility utilities (`.sr-only`, `[hidden]`) and `prefers-reduced-motion` enforcement may force priority. - Do not restore warm-paper, white-card, cobalt-action, cream, or light-theme aliases. New code must consume the dark semantic tokens directly. - Keep administrator and cashier portals as independent route-level surfaces even when they share tokens and component primitives. ## Typography | Token | Value | Use | | --- | --- | --- | | `--font-ui` | `"Microsoft YaHei UI", "PingFang SC", "Noto Sans CJK SC", system-ui, sans-serif` | Chinese-first interface, navigation, fields, status, and headings | | `--font-data` | `"Segoe UI", "Microsoft YaHei UI", system-ui, sans-serif` | Amounts, dates, ratios, account suffixes, and dashboard metrics | Body type is `13px/1.55`. Page headlines use `clamp(26px, 3vw, 35px)` with `1.15` line height. The sign-in statement alone uses `clamp(38px, 5vw, 70px)`. Letter spacing stays at `0`; numeric evidence uses `font-variant-numeric: tabular-nums`. ## Color Primitives ### Canvas and Surfaces | Token | Value | Use | | --- | --- | --- | | `--color-bg` | `#050505` | Continuous application canvas | | `--color-bg-soft` | `#0a0a0a` | Soft near-black tonal alternative | | `--color-nav` | `#0a0a0a` | Navigation frame fallback | | `--color-surface` | `rgba(22, 22, 22, 0.82)` | Primary neutral graphite glass | | `--color-surface-solid` | `#161616` | Opaque graphite fallback | | `--color-surface-raised` | `#1c1c1c` | Raised or denser surface | | `--color-surface-muted` | `rgba(255, 255, 255, 0.035)` | Quiet inset field and row treatment | ### Structure and Ink | Token | Value | Use | | --- | --- | --- | | `--color-line` | `rgba(255, 255, 255, 0.09)` | Default glass, row, and field boundary | | `--color-line-strong` | `rgba(255, 255, 255, 0.16)` | Hover, dialog, and transient boundaries | | `--color-ink` | `#f2f7f4` | Primary headings, values, and action labels | | `--color-ink-soft` | `#a6b0aa` | Operational body copy and secondary values | | `--color-ink-muted` | `#89938d` | Metadata, helper copy, cutoff dates, and descriptions | `--color-ink-muted` has a verified 5.73:1 contrast ratio on the primary graphite glass. Do not reduce it. ### Action and State | Token | Value | Use | | --- | --- | --- | | `--color-primary` | `#37eb89` | Primary commands, focus, active icons, and confirmed progress | | `--color-primary-strong` | `#70ffae` | Primary hover and high-emphasis command state | | `--color-primary-dark` | `#08160e` | Text and icons on filled emerald controls | | `--color-primary-wash` | `rgba(55, 235, 137, 0.11)` | Selected and highlighted emerald fields | | `--color-positive` | `#37eb89` | Confirmed and successful state | | `--color-positive-wash` | `rgba(55, 235, 137, 0.10)` | Confirmed-state background | | `--color-warning` | `#ffbc52` | Review, incomplete, expiring, or recoverable caution | | `--color-warning-wash` | `rgba(255, 188, 82, 0.11)` | Warning background | | `--color-danger` | `#ff626d` | Blocked, overdue, failed, or destructive consequence | | `--color-danger-wash` | `rgba(255, 98, 109, 0.11)` | Danger background | | `--color-info` | `#66a8ff` | Neutral evidence guidance | | `--color-info-wash` | `rgba(102, 168, 255, 0.11)` | Informational callout background | Emerald is the only global action accent. Amber and red must always be accompanied by status text. Never use color alone to imply financial direction or accounting classification. ## Shape | Token | Value | Use | | --- | --- | --- | | `--radius-sm` | `10px` | Compact identifiers and control-adjacent shapes | | `--radius-md` | `16px` | Inset evidence, role cards, and compact grouped content | | `--radius-lg` | `22px` | Panels, metric cards, alerts, dialogs, and account cards | | `--radius-xl` | `28px` | Floating sidebar and sign-in form | Observed component-specific radii remain local: fields use `11px`, primary controls `13px`, navigation rows `14px`, and statuses `8px`. Do not promote every one-off dimension into a global token. ## Depth | Token | Value | Use | | --- | --- | --- | | `--shadow-panel` | `0 24px 70px rgba(0, 0, 0, 0.34), inset 0 1px rgba(255, 255, 255, 0.035)` | Sidebar, dialog, toast, and sign-in form | | `--shadow-low` | `0 12px 32px rgba(0, 0, 0, 0.22), inset 0 1px rgba(255, 255, 255, 0.025)` | Panels, metrics, alerts, and account cards | | `--shadow-glow` | `0 0 28px rgba(55, 235, 137, 0.12)` | Focused search and selected identity cues | Glass surfaces pair background, boundary, blur, and shadow. Do not add shadow without the corresponding surface and border logic, and do not nest glass surfaces as decoration. ## Motion | Token | Value | Use | | --- | --- | --- | | `--duration-fast` | `150ms` | Hover, focus, row, field, and button state changes | | `--duration-standard` | `260ms` | Metric movement and mobile sidebar structure | | `--ease-out` | `cubic-bezier(0.22, 1, 0.36, 1)` | Entrances and structural transitions | First load uses a `440ms` entrance with a `38ms` stagger capped at `260ms`. It runs once. Repeat navigation uses `180ms` and cancels any prior view animation before starting. Reduced-motion mode forces animations and transitions to `0.01ms`. ## Component Contracts ### Application Frame - Desktop: 252px application column, 234px floating sidebar, 18px viewport offset, 78px sticky top bar. - Main content: maximum width 1560px and 32px desktop inset. - 1180px: sidebar compresses to an icon rail; four metrics become two columns. - 900px: global search hides and complex ledgers recompose. - 720px: 242px off-canvas sidebar, 64px top bar, 13px main inset, two-up metrics. - 460px: metric cards gain height for wrapping; role selection becomes one column. ### Buttons and Fields - Primary and secondary buttons have a 40px minimum height; icon buttons are stable 40px squares. - Primary uses emerald fill with dark ink; secondary uses graphite wash with a hairline border. - Fields have a 40px minimum height, 11px radius, dark inset fill, persistent visible label, and emerald focus treatment. - Keyboard focus uses a two-pixel emerald outline with three-pixel offset. ### Metric Cards - Exactly four prominent metrics lead each portal home view. - Desktop minimum height is 142px with 20px padding; mobile minimum height is 128px with 15px padding, increasing at very narrow width. - Interactive cards require native button semantics or equivalent role, focusability, and keyboard activation. - A metric contains a label, stable numeric or status value, icon tile, and consequence line. Warning and danger color only the relevant signal. ### Panels, Ledgers, and Tables - Major panels use graphite glass, a hairline border, 22px radius, low shadow, and backdrop blur. - Use dividers and tonal rows inside a panel, not nested floating cards. - Data tables retain a minimum width and horizontal scrolling so financial evidence is not discarded. - Amounts and dates use tabular figures. Every balance view keeps its cutoff and unresolved amount visible. ### Status and Feedback - Status chips are 23px high with 8px radius and `2px 8px` padding. - Success, warning, danger, and neutral states always include explicit text. - Dialogs use the strong boundary and panel shadow; mobile dialogs become full-screen with square outer corners. - Toasts use the same raised graphite material as other transient layers. ## Change Checklist 1. Update the existing `:root` primitive instead of adding a duplicate alias. 2. Update every affected component state in its current rule group. 3. Verify administrator and cashier routes independently at desktop and mobile widths. 4. Verify focus visibility, text status, muted-text contrast, stable metric dimensions, and reduced motion. 5. Search `web/styles.css` for new business-rule `!important`; only approved accessibility and reduced-motion rules may remain. 6. Confirm no warm-paper, cobalt, cream, or light-theme override vocabulary has been introduced.