# DESIGN.md — Family Home Lab Console > Design system for the family console portal (`console.home.lab`). > Base system: **Notion marketing design language** (awesome-design-md) — warm daylight document calm, one structural blue, decorative sticker palette. > Stack context: server-rendered FastAPI + Jinja2 + **HTMX**. No SPA build chain; tokens map to CSS custom properties in `portal/static/tokens.css`. ## Brand Personality The console reads as a **well-organised family desk**: warm paper-soft canvas, near-black confident type, exactly one dependable blue for actions. Each tool gets its own sticker colour so family members can find "their" tools at a glance — colour decorates, never structures. The login screen is the single dark indigo "night band" moment; everything after login is daylight. ## Colors ### Surface | Token | Value | Use | |---|---|---| | `{colors.canvas-soft}` | `#f6f5f4` | App canvas / page background | | `{colors.canvas}` / `{colors.surface}` | `#ffffff` | Cards, panels, nav bar, inputs, iframes wells | | `{colors.hairline}` | `#e6e6e6` | 1px borders, dividers | ### Text | Token | Value | Use | |---|---|---| | `{colors.ink}` | `#000000` (~95% alpha rendered) | Headings, primary text | | `{colors.ink-secondary}` | `#31302e` | Body copy | | `{colors.ink-muted}` | `#615d59` | Supporting text, descriptions | | `{colors.ink-faint}` | `#a39e98` | Captions, metadata, placeholders | ### Structural accents | Token | Value | Use | |---|---|---| | `{colors.primary}` | `#0075de` | Login/submit buttons, inline links, active tab, focus rings — the only action colour | | `{colors.primary-active}` | `#005bab` | Pressed state of primary buttons | | `{colors.on-primary}` | `#ffffff` | Text on primary fills | | `{colors.secondary}` | `#213183` | Deep indigo — **login screen background and header greeting band only** | ### Sticker palette (decorative ONLY — never paints CTAs or structure) Assigned permanently to tool categories: | Token | Value | Category assignment | |---|---|---| | `{colors.accent-sky}` | `#62aef0` | Chat (dsh instances) | | `{colors.accent-purple}` | `#d6b6f6` | Image tools (Photopea) | | `{colors.accent-pink}` | `#ff64c8` | Video tools | | `{colors.accent-orange}` | `#dd5b00` | Audio tools | | `{colors.accent-teal}` | `#2a9d99` | Documents (future) | | `{colors.accent-green}` | `#1aae39` | Status ticks ("online", success toasts) | | `{colors.accent-purple-deep}` | `#391c57` | Deep shade within illustrations only | | `{colors.accent-orange-deep}` | `#793400` | Deep shade within illustrations only | Semantic status reuses stickers: green = online/saved, orange = busy/starting, faint grey = offline. ## Typography Font: **Inter** (self-hosted woff2 in `static/fonts/`; substitute for NotionInter). Fallbacks: `-apple-system, system-ui, "Segoe UI", Helvetica, Arial`. OpenType `lnum` enabled on numerals. | Token | Size | Weight | LH | Tracking | Use | |---|---|---|---|---|---| | `{typography.display-1}` | 48px | 700 | 1.05 | −1.5px | Login headline ("Good evening, Sam") on indigo band | | `{typography.heading-1}` | 32px | 700 | 1.1 | −0.8px | Dashboard greeting, section headlines | | `{typography.heading-2}` | 22px | 700 | 1.27 | −0.25px | Tool category headings | | `{typography.title}` | 17px | 600 | 1.4 | −0.125px | Tool card names | | `{typography.body-md}` | 15px | 400 | 1.5 | 0 | Default body | | `{typography.body-sm}` | 14px | 400 | 1.4 | 0 | Dense UI, table rows | | `{typography.button}` | 15px | 500 | 1.4 | 0 | Button labels | | `{typography.caption}` | 13px | 400 | 1.43 | 0 | Metadata, timestamps | | `{typography.eyebrow}` | 12px | 600 | 1.33 | +0.125px | Category pills, badges | Principle: heavy 700 headlines with explicit negative tracking vs calm 400 body. No decorative typography. ## Layout - Base unit **8px**. Tokens: xxs 4 · xs 8 · sm 12 · md 16 · lg 24 · xl 28 · xxl 32. - Dashboard container: centred, max-width **1200px**, generous gutters (`{spacing.xxl}` desktop). - Tool grid: responsive auto-grid — 3-up desktop → 2-up tablet (≤840px) → single column mobile (≤600px). - Whitespace groups; sections separated by large vertical gaps, no rules. - Touch targets ≥44×44px on mobile. - Iframe/embed view: full-width white well below a slim sticky tool bar. ## Elevation | Level | Treatment | Use | |---|---|---| | 0 Flat | Hairline border only | Default tool cards | | 1 Soft | Layered micro-shadow: `rgba(0,0,0,.01) 0 .175px 1px, rgba(0,0,0,.02) 0 .8px 3px, rgba(0,0,0,.027) 0 2px 8px, rgba(0,0,0,.04) 0 4px 18px` | Hovered/raised cards, floating elements | | 2 Elevated | Deeper stack ending `rgba(0,0,0,.05) 0 23px 52px` | Modals, popovers | Never hard drop-shadows. ## Shapes | Token | Value | Use | |---|---|---| | `{rounded.xs}` | 4px | Text inputs, chips | | `{rounded.sm}` | 5px | Menu items, list rows, status pills | | `{rounded.md}` | 8px | Utility buttons, smaller cards | | `{rounded.lg}` | 12px | Tool cards, iframe wells, modals | | `{rounded.full}` | 9999px | Pill CTAs, avatar circles, icon buttons | Inputs stay tight (4px); CTAs pill. Never swap. ## Components ### Screens 1. **Login screen** (`ex-auth-form-card` + hero-band): full-viewport deep indigo `{colors.secondary}` band; white display-1 greeting; centred white auth card (`{rounded.lg}`, Level-2 shadow) with username + password `text-input`s and one `button-primary` "Sign in". Subtle starfield/sticker dots decoration. This is the page's only dark moment. 2. **Dashboard** (post-login): sticky slim `nav-bar` (white, wordmark left, user avatar + logout right); heading-1 time-aware greeting ("Good morning, Sam"); tool grid grouped by category with eyebrow pills in category sticker colours; each tool a `tool-card`. 3. **Tool embed view**: sticky tool bar (white, back arrow, tool title, open-in-new-tab `button-utility`) above a full-width white iframe well (`{rounded.lg}`, hairline). Falls back to link-out card if the tool forbids framing. 4. **Admin panel** (Sam only): same chrome; user management rows, add-user form, service status list. ### Core primitives - **`nav-bar`** — white surface, body-sm links, md padding, hairline bottom edge. - **`button-primary`** — blue fill, on-primary text, pill, brief `scale(0.97)` press → `{colors.primary-active}`. - **`button-secondary`** — white, ink text, pill, Level-1 shadow. - **`button-utility`** — white, ink text, `{rounded.md}`, `4px 14px` padding, hairline border. - **`tool-card`** — white, `{rounded.lg}`, padding lg, hairline (Level-0); hover lifts to Level-1. Contains: 40px circular icon tile filled with the category's sticker colour (white glyph), title typography, caption description, status dot (green/orange/faint), and launch affordance (inline-embed vs new-tab shown as small caption chip). - **`category-pill`** — eyebrow type, white surface, category sticker-coloured text + dot, pill, `4px 8px`. - **`text-input`** — white, ink text, body-sm, 1px `rgb(221,221,221)` border, `{rounded.xs}`, 6px+ padding; focus adds Level-1 shadow + blue ring. - **`status-dot`** — 8px circle: `{colors.accent-green}` online, `{colors.accent-orange}` starting, `{colors.ink-faint}` offline. - **`modal-card`** — feature-card chrome + Level-2 shadow (confirmations, add-user dialog). - **`toast`** — card shape + medium shadow, green tick sticker for success. ## HTMX Behaviour Notes - Tool grid refreshes via `hx-get` polling every 30s (status dots update without reload). - Login posts via standard form (full redirect — session cookie set server-side). - Embed view swaps into `
` with `hx-push-url` so browser back works. - Loading states use a subtle opacity pulse on cards (never spinners-on-stickers). ## Do's and Don'ts ### Do - Keep the app on `{colors.canvas-soft}`; cards/fields pure white. - Reserve `{colors.primary}` strictly for sign-in, submit, links, active state. - Give each tool category its fixed sticker colour (see table) used only in icon tiles and category pills. - Apply negative tracking explicitly on headings. - One dark moment per session: the login screen. - Hairlines + layered micro-shadows for depth. ### Don't - Don't paint buttons or structural fills with sticker colours. - Don't introduce a second accent alongside `{colors.primary}`. - Don't round inputs like pills or vice versa. - Don't use heavy drop-shadows. - Don't repeat dark bands inside the dashboard. - Don't render pages on clinical pure-white backgrounds.