# Lyra frontend: the "Pressing Plant" design system **Date:** 2026-07-12 **Status:** approved (design comp signed off), implementing **Comp:** https://claude.ai/code/artifact/af6f9654-619d-4245-b3dd-602a6427934a ## Intent Give Lyra a real visual identity instead of unstyled raw HTML. Direction: **Liner Notes / "Pressing Plant"** — the app presented as *a record label's internal catalog for an audience of one*. The acquisition pipeline reads as a pressing plant. The metaphor lives in the **chrome only** (masthead, section names, catalog/matrix numbers, deadwax etch styling); **functional labels stay literal and legible** (Downloading, Verifying, Needs attention) so nothing is obscured. Single-user homelab tool → license to be bold. This is a **tool, not a document**: information design first (summary before detail, state encoded as form — severity stripe + chip — not just prose), editorial typography second. ## Design language (the reusable reference) ### Color — deliberately off the AI-editorial cliché (no cream, no vermilion) Two-color-print feel: manila/kraft paper + warm ink + one bold **deep spruce** accent. Tokens are CSS custom properties on `:root`; both themes get equal care. Semantic status colors are **separate from the accent**. | Token | Day (light) | Night (dark) | Use | |---|---|---|---| | `--paper` | `#E7DFCC` | `#14130F` | ground | | `--paper-2` | `#DED5BE` | `#1D1B16` | recessed panel | | `--ink` | `#1B1A17` | `#E9E1CD` | primary text | | `--graphite` | `#726D5F` | `#938C7B` | secondary text / mono meta | | `--rule` | `rgba(ink,.16)` | `rgba(ink,.16)` | hairlines | | `--rule-2` | `rgba(ink,.30)` | `rgba(ink,.28)` | stronger rules | | `--accent` | `#1F5138` | `#5BB487` | the one bold move; links, active nav, "pressed" | | `--accent-ink` | `#F3EEDF` | `#10120F` | text on accent | | `--live` (semantic) | `#9A6B1E` amber | `#D2A24E` | work in progress | | `--alert` (semantic) | `#99392B` clay | `#D8695A` | needs attention (errors only) | Theme mechanics: define tokens on `:root`; redefine under `@media (prefers-color-scheme: dark)`; **also** redefine under `:root[data-theme="light"]` and `:root[data-theme="dark"]` so an explicit in-app toggle wins in both directions. Style components through tokens only, never inside the media query. Faint paper grain via a tiled radial-gradient. **Sharp corners** (radius 0–2px) — letterpress/label feel, and it dodges the `rounded-lg` cliché. ### Type — serif/mono tension is the concept - **Display + editorial:** **Fraunces** (OFL variable serif; soft, optical, warm), self-hosted via `next/font/local` (woff2 vendored under `web/src/fonts/`, subset to latin). The comp used a Palatino system stack as a stand-in; the real app ships Fraunces. - **Machine voice (all metadata, labels, data, progress):** a system **mono** stack (`ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace`) — zero weight, reliable. Uppercase mono labels get `letter-spacing: 0.12–0.22em`. - Scale (rem): masthead `clamp(2.6, 6vw, 3.7)`, job title `1.42`, tile value `2.5`, body `1.0`, section head `0.78` mono, meta/labels `0.62–0.72` mono. `text-wrap: balance` on headings; running text ~65ch; `font-variant-numeric: tabular-nums` on all aligned digits. ### Motifs Masthead wordmark + tagline + live worker dot + "Pressing № NNNN" catalog mark; contents-bar nav (hairline top/bottom, active item underlined in accent); summary tiles (hairline grid); dept section headers (mono small-caps + rule fill + count); tracklist job rows with a left **severity stripe**; mono **status chip**; thin ruled **progress bar** (indeterminate variant for search); **deadwax matrix** etch line for pressed items (`Lyra·A0430 — FLAC 24/48`); colophon footer. ### Motion (restrained) Live-dot pulse; indeterminate progress slide; hover underlines. All gated by `@media (prefers-reduced-motion: reduce)`. No scattered effects. ## Architecture Hand-rolled CSS, no framework (matches the lightweight Next 15 / React 19 stack). - **`web/src/app/globals.css`** (new) — token definitions (both themes), base/reset, paper grain, focus-visible, reduced-motion. Imported once in the root layout. - **`web/src/app/design.css`** (new, or co-located module) — the component classes (masthead, contents nav, tiles, dept header, job row, chip, bar, pressed list, buttons, inputs). Plain global classes keep it simple and shared across pages. - **Fonts:** `web/src/fonts/` vendored Fraunces woff2 + `next/font/local` wiring, exposed as a CSS variable on `
`. - **App shell:** `web/src/app/layout.tsx` gains the shared chrome — a `