Files
family_home_lab/DESIGN.md

145 lines
8.3 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.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 `<main>` 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.