# Frontend Design Cookbook This cookbook defines the visual system for the frontend so every new change extends the existing style instead of inventing a new one. ## Design intent - Core tone: light editorial, calm and information-first. - Product feel: premium personal logbook, not generic SaaS dashboard. - Contrast model: neutral paper and ink do most of the work; accents are restrained. ## Non-negotiables - Keep layouts readable first. Aesthetic details support hierarchy, not the other way around. - Use one visual language across the app shell, cards, forms, tables, and actions. - Prefer subtle depth (borders, layered paper, soft shadows) over loud gradients. - Keep motion purposeful and short; always preserve `prefers-reduced-motion` behavior. ## Typography - Display/headings: `Cormorant Infant`. - Body/UI text: `Manrope`. - Use display typography for page titles and section heads only. - Keep paragraph text in body font for legibility. ## Color system Global neutrals are defined in `frontend/src/app.css` using CSS variables. - `--background`, `--card`, `--foreground`, `--muted-foreground`, `--border` - `--page-accent` drives route-level emphasis. - `--page-accent-soft` is the low-contrast companion tint. ### Domain accents (muted and professional) - Dashboard: `--accent-dashboard` - Products: `--accent-products` - Routines: `--accent-routines` - Skin: `--accent-skin` - Health labs: `--accent-health-labs` - Health medications: `--accent-health-meds` The app shell assigns a domain class per route and maps it to `--page-accent`. ## Where to use accent color Use accent for: - active navigation state - important buttons and key badges - focus ring tint and hover border tint - section separators and small status markers Do not use accent for: - full-page backgrounds - body text - large surfaces that reduce readability Guideline: accent should occupy roughly 10-15% of visual area per screen. ## Layout rules - Use the app shell spacing rhythm from `app.css` (`.app-main`, editorial cards). - Keep max content width constrained for readability. - Prefer asymmetry in hero/summary areas, but keep forms and dense data grids regular. ### Shared page wrappers Use these wrappers before introducing route-specific structure: - `editorial-page`: standard constrained content width for route pages. - `editorial-hero`: top summary strip for title, subtitle, and primary actions. - `editorial-panel`: primary surface for forms, tables, and ledgers. - `editorial-toolbar`: compact action row under hero copy. - `editorial-backlink`: standard top-left back navigation style. - `editorial-alert`, `editorial-alert--error`, `editorial-alert--success`: feedback banners. ## Component rules - Reuse UI primitives under `frontend/src/lib/components/ui/*`. - Keep primitive APIs stable when changing visual treatment. - Style via tokens and shared classes, not one-off hardcoded colors. - New variants must be documented in this file. ### Existing shared utility patterns These classes are already in use and should be reused: - Lists and ledgers: `routine-ledger-row`, `products-mobile-card`, `health-entry-row` - Group headers: `products-section-title` - Table shell: `products-table-shell` - Tabs shell: `products-tabs`, `editorial-tabs` - Health semantic pills: `health-kind-pill*`, `health-flag-pill*` ## Forms and data views - Inputs should remain high-contrast and calm. - Validation/error states should be explicit and never color-only. - Tables and dense lists should prioritize scanning: spacing, row separators, concise metadata. ### DRY form primitives - Use shared form components for repeated native select markup: - `frontend/src/lib/components/forms/SimpleSelect.svelte` - `frontend/src/lib/components/forms/GroupedSelect.svelte` - Use shared checkbox helper for repeated label+hint toggles: - `frontend/src/lib/components/forms/HintCheckbox.svelte` - Use shared input field helper for repeated label+input rows: - `frontend/src/lib/components/forms/LabeledInputField.svelte` - Use shared section card helper for repeated titled form panels: - `frontend/src/lib/components/forms/FormSectionCard.svelte` - Use shared class tokens from: - `frontend/src/lib/components/forms/form-classes.ts` - Prefer passing option labels from route files via `m.*` to keep i18n explicit. ### Select policy (performance + maintainability) - Default to native `