בס״ד

Hook Street — Design System & Dashboard Pattern

docs/DESIGN_SYSTEM.md · last changed (pre-VM history) · rendered from GitHub master

Hook Street — Design System & Dashboard Pattern

Last updated: 2026-05-27. Status: LIVING reference. Applies to every briefing, report, PWA, and dashboard — workspace, MIS, BOS, Eden, client work.

Sam locked the house look 2026-05-27: "Everything in reporting and looks has that blue and similar bubbly layout… which is great." Use this everywhere so the lessons from the obligations PWA + the briefings carry across. One learns → all get it.

1. The house visual language

2. The audience-scoped dashboard pattern (one source → many views)

The obligations PWA is the prototype. The pattern generalizes:
- One data source, many scoped views. Same feed, filtered per audience. Chanie = personal/household only. Mildred = business + the lanes Sam allows (per the OWN/FLAG/OFF-LIMITS model). Sam = everything. Temp user = a defined subset.
- Default to the safe/narrow view. Personal is the default; the broader view is an opt-in tucked in "settings," never the front door. ?view=all (or per-audience param) widens it.
- Sam back-end-controls what each person sees — by keyword/lane/account filters (e.g. hide Hook Street / Florida / business), editable in one place. Sensitive data (full debt balances, etc.) renders only on the gated + authenticated version, never a public page.
- Personal touch. Time-of-day greeting by name, a warm line, date + Hebrew date + weather + a small delight (birthstone), Friday candle-lighting. Make it theirs.
- Honest "coming soon." Only when the data genuinely isn't available yet — never as a cop-out for data we already hold. Flag what needs a look + say what to do about it.

3. Security / hosting model

4. Channels (recap, see docs/CHANNELS.md)

Telegram/notify = plain ASCII only (emoji/Unicode → "??"). Portal = read. Email = formal. Chat = building.

5. Where this applies next

Adopt this look + pattern when touching: MIS daily report emails, BOS reports/Mildred briefing, Eden client deliverables, every outputs/ briefing, and the per-person dashboards (Chanie live; Mildred + Sam + temp views = the build direction).

6. Mobile-first dense rendering — the 2026 rules (added 2026-05-28)

Sam is iPhone-first. "Compact, viewable, noticeable — NOT crunched." Apple HIG quality. These rules supersede earlier ad-hoc sizing across all outputs/ HTML. Full skill: hookstreet-skills/mobile-rendering. Canonical demo: outputs/2026-05-28_13-32_audit_system-diagnosis-v2.html.

Typography
- Body: 15px / line-height 1.4. Meta: 13px. Monospace timestamps: 11px. Never below 11px. Inputs ≥ 16px (iOS auto-zoom threshold).
- Headings line-height 1.2 with letter-spacing: -0.01em (Apple default tightening).
- Pills/badges line-height 1.15.
- Always include font-feature-settings: "tnum" on any column of numbers, dates, or money (prevents jitter, visually compresses).
- System font stack first: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif.

Spacing — 4px grid, no 20 / no 32 inside cards
- Card padding 12px (NOT 16-20). Card-to-card gap 8px. Section gap 16px. Hero padding 12-16px.
- Tokens: --s1:4 --s2:8 --s3:12 --s4:16 --s5:20 --s6:24. Use these, not arbitrary numbers.
- Target line length 38-55ch (max-width: 60ch on prose).

Hero (THE biggest mobile mistake to avoid)
- h1 19-22px, one line max, drop the subtitle on mobile or inline it with ·.
- Hero total height ≤ 12% of fold (≤ 100px on iPhone). The 30%-of-screen hero is a marketing-site reflex; dashboards live by density.
- Meta on one line, white-space:nowrap; overflow:hidden; text-overflow:ellipsis so it never wraps to 2 lines.

Status — STOP putting sentences in pills
- Pills: 1-2 WORDS, max ~14 chars, never wrap. (Live, Half, Spec'd, Stuck.)
- For longer state: use an 8px colored DOT + inline regular-weight text. Example: <span class="dot warn"></span><strong>Half.</strong> Links are placeholders; expand-bug fixed today.
- Dot colors: ok #10b981 · warn #f59e0b · bad #ef4444 · spec'd #3b82f6 · generic #8b5cf6.

Tables — collapse to definition-list cards below 640px
- Forget responsive <table> shoehorning. On mobile, each row = <article class="surf"> with <h3> + state inline, path on a <p class="path">, description on <p class="desc">. Optional <dl> for label/value pairs.
- On ≥640px, container query (@container (min-width:640px)) switches the same markup back to grid columns.

Viewport + safe area + dvh
- <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">viewport-fit=cover is required or env(safe-area-inset-*) returns 0.
- Outer wrapper: padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) ....
- Use dvh not vh for full-height regions (kills the Safari URL-bar jump).

Modern CSS — safe in 2026
- Container queries, :has(), text-wrap: balance/pretty, subgrid, color-mix(), light-dark() — all ship in iOS Safari 17.2+. No polyfill needed.

Best-in-class references (model on, in this order)
1. Linear mobile — densest list that still breathes; 8px dots, no pill backgrounds.
2. Stripe Dashboard mobile — relaxed financial density; collapse to two-line cards.
3. Apple Health — canonical HIG-quality forced-light; tabular numerals everywhere.
4. Things 3 — white-space discipline at high density; state via glyph, never badge.

One-liner takeaway: 8px colored dot + tabular-numeral text on a 4px grid, 12px card padding, 1.4 line-height, dvh + safe-area, container queries for table→card collapse.

Source trail · docs/DESIGN_SYSTEM.md @ master · rendered 2026-07-02 7:23 PM EDT by scripts/build-docs.py · the .md in the repo is the truth; this page is the phone-readable view