Family Home Lab: portal, dsh (chat+plugins), transcriber, music/media tools, home dash

This commit is contained in:
2026-08-26 11:30:34 +10:00
commit 1110dbc978
62 changed files with 4237 additions and 0 deletions

144
DESIGN.md Normal file
View File

@@ -0,0 +1,144 @@
# 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.