Skip to content

Atlas HELM — Design Philosophy (Living Doc)

🔴 Status: v2.0 · set 2026-05-29 (session 340d5f53 Phase 210 mid-arc checkpoint, after the 4-bento arc landed in sessions 386fd1f6/d5943817/7d86a59c/1271fa43/57998126) · INTENTIONALLY FLUID. Expected lifespan: Always evolving. Iterate every session that touches HELM visual surfaces. Promoted from: Sush's directive 2026-05-29 — "document everything and add todos so when we move between sessions each session understands this philosophy and we will keep it fluid to make room for evolution — the idea is to make the best tool so that I feel like using and it provides immense value for me to keep going back." Owner: Sush + Atlas, co-designed each session. Atlas writes here; Sush approves direction shifts. 🆕 v2.0 (Phase 210): Mid-arc cold-eye review after the 4-bento system landed (Today / Overview / Books / Customers). New sections §0.5 (checkpoint), §3.6 (eligibility + wedge test), §3.7 (patterns by confidence), §8.5 (implementation debt), §9.5 (bias checks). Rubber-duck pushed back on 7 over-claims; demotions adopted.


0 · Why this doc exists

HELM is Sush's daily-driver cockpit. Every session that touches a visual surface (today-tab, overview-tab, customer card, scout card, etc.) MUST read this file first. Without a shared philosophy, sessions drift into "fix what's in front of me" mode and the cumulative result is inconsistency.

This doc is the constitution. The phase queue (~/.copilot/atlas-portfolio-phases.md) is the calendar. Together they make a design system that survives session amnesia.

Cardinal commitment: The goal is to make a tool Sush wants to open. Immense value. Pull, not push. If a design decision doesn't move us closer to that, kill it.


0.5 · Mid-arc checkpoint (Phase 210 · v2.0)

After the 4-bento arc landed (Today / Overview / Books × 3 SSPs / Customers), a cold-eye review surfaced three buckets. Future sessions inherit this calibration as the starting point.

Proven (locked, don't re-debate)

  • grid-template-areas (Path A) — designer control + named slots. Composes cleanly. Mobile collapse works. No retreats from this in any of the 4 tabs.
  • Cold-user wedge per tab — Today=NOW · Overview=BOOK SHAPE · Books=PERSON BOOK SHAPE · Customers=NAMED INDIVIDUALS. The wedge test is what stopped Customers from being a Books clone. See §3.6.
  • Fold-not-lose discipline — every dropped section gets FOLDED into a slot (Hero chips, tooltip, coverage strip), never just deleted. Preserves info density without preserving chrome.
  • Drill-zone sibling pattern — bento = SURVEY layer (top), drill zone = POWER-USER layer (full-width siblings below: tables, 54-card grids, deep-dive charts).
  • Plex Sans family swap — Phase 201 landed cleanly. Plex Serif italic for Atlas brief IS the signature voice move it was meant to be.
  • Tab-specific class prefix.today- .ov- .bb- .cb-. The Customers .cb-card (not .c360-card) decision saved a click-handler collision. Always pick a fresh prefix when bento'ing over an existing rich card.
  • Architecture-gate (Rule #5) for layout-shaped phases — for the bento arc specifically, surfacing 3-4 paths BEFORE writing renderer produced zero rework loops. This is reliable WHEN the work is layout/architecture-shaped. Don't claim the gate fires automatically for ad-hoc polish.

Provisional (used in 2-3 of 4 bentos · adopt OR diverge with a reason)

  • 3-beat Atlas brief structure — Customers cracked it (state → movement/risk → next action, composed at render-time, Plex Serif italic). Overview uses thesis + 3 bullets. Books renders pre-baked SSP insight prose. Today uses atlas-brief.js ACT TODAY / ON YOUR RADAR. Not universal — yet. Newer bentos can adopt the 3-beat shape; existing ones evolve only if the data shape makes it worth it.
  • Customer names italicised in cyan — Customers did this. Overview brief uses <em> with amber. Books escapes raw insight text. Not universal. When the surface mentions named customers, cyan italic is the right choice; not all briefs are name-dense.
  • Sub-nav ≤9 anchors capped at one row — Overview/Books/Customers all chose 9 (the latter two probably copied Overview's count). Today has no bento sub-nav at all. Promote as "cap at one visual row, ≤9 anchors" — not "exactly 9".
  • Sign-filtered delta strips — 3 +gainers + 2 −decliners (Customers movers). Used in Customers; Overview's diff strip is mixed-tone but not sign-filtered. Pattern works when you have a polar dataset.
  • Diversity-fill + severity-fill for Top-3 — Overview cracked, Books and Customers reused. Pattern is locked WHERE Top-3 is "ranked-list-of-things-from-a-bucket-pool." Today's hot-pipeline 3 slots are semantically distinct (closing-soon · past-close · stale) so the algorithm doesn't apply.
  • Rule #6 probe before renderer — fired explicitly in 202/204/205b, implicit in 205a. 20 min each time. Pattern paid back hours each invocation. Promote to MANDATORY for any new bento; treat as recommended for bento polish phases.

Drifted (we have a problem · needs cleanup)

  • 🔴 Amber discipline violated across 11 source files. var(--amber) is currently used as priority numbers, eyebrows, P2 chips, IMMINENT tag, sync-busy state, helm-pill-ok, active nav, scout buttons, hover transforms, focus rings, command buttons. The §5 audit named this in v1.0. We haven't fixed it. Needs a taxonomy audit (Row 211), not a blanket flip — some sites are legitimate stakes, some are pure chrome. See §5 for the 3-bucket classification.
  • 🟡 Sticky-hero (§6 add-on #1) marked ✅ in v1.5 was a fact-drift bug. Phase 203 shipped sticky-hero, Phase 203.1 hotfixed it, Phase 203.2 REVERTED it (Electron-specific visual bug not reproducible in headless Playwright). Status corrected in §6.
  • 🟡 Bento module placement is inconsistent. Today bento lives in today-tab.js (85KB). Books bento lives in ssp-book.js (61KB). Overview bento lives in render.js (209KB). Only Customers bento got its own module (customers-bento.js, 40KB). The real pain is Overview-in-render.js; Today/Books are tidy-bug not value-bug. See §8.5.
  • 🟡 Polish-layer "should-it-propagate" question never answered. data-freshness ink and data-empty="1" chip-collapse exist only in Today. The right question is not "propagate them everywhere" but "audit applicability per tab" — see §6 for the corrected reasoning.

What 4 bentos taught us about the doc itself

This doc was v1.0 BEFORE we shipped any bento. v1.5 added one tab's story-shape table per phase. v2.0 is the first time we're stepping back to ask "which patterns actually GENERALISE?" The honest answer is: fewer than v1.5 implied. Tightening the language here makes the doc more useful, not less ambitious.


1 · Cold-user persona — the "Sush walking up to HELM at 8:42 AM" test

Every design decision passes through this filter:

  • Who: Sush, Copilot Solution Engineer, MS NZ. Daily-driver — opens HELM first thing morning, mid-day, late-afternoon.
  • What he wants in priority order:
  • "What do I do RIGHT NOW?" (5-second answer)
  • "What's COMING UP today/tomorrow?"
  • "What did I MISS?" (only if it matters)
  • "What CHANGED since last time?" (delta surface)
  • "What's interesting?" (curiosity — Scout, brief insights)
  • What he doesn't want: kitchen-sink dashboards · stacked-rectangle uniformity · guilt-trip openings · empty-state noise · amber-overload · prose where data would do.

5-Second Test: When Sush opens any tab, can he get the answer to "what should I do right now?" in 5 seconds? If no, the tab fails the test.


2 · The Master Design Principle — Bento Mosaic

"We're not hard set on one type of card — we can have tall cards, rectangular cards, square cards all sitting adjacent to each other but working together to create a master layout. The page looks busy and purposeful and each card has a way of storytelling. Different storytelling will adopt different design but it all coexists and tightly live together like a creeper and a tree and a plant all exist together in harmony." — Sush, 2026-05-29

The principle in one line: Each card has a SHAPE that fits its STORY. Cards puzzle-piece into a master layout, not stack as uniform rectangles.

Why this works:

  • Shape = signal. A 2×2 square says "anchor metric." A 4×1 strip says "timeline/flow." A 1×3 tall says "ranked list." A 1×1 chip says "glance only." Cold user reads shape BEFORE content.
  • Density = clarity, not noise — when each card earns its shape, busy ≠ cluttered. Pinterest, Bloomberg Terminal, Linear, Apple iCloud all prove this.
  • Visual gravity — a large hero card surrounded by smaller satellites feels EARNED. Same hero alone-in-a-column feels arbitrary.
  • Ecosystem coexistence — different cards don't compete; they harmonize. Like a tree + creeper + plant in one ecosystem.

References that already do this well: - Apple iCloud / macOS Sonoma widgets - Linear's dashboard (Cmd+K + the homepage) - Vercel's project overview - Raycast Pro dashboard - PAC v0.2 cockpit (Sush's reference: Downloads/pac-v02-fullscreen.png) - Bloomberg Terminal (the data-density extreme)


3 · Story-Shape Mapping — what shape each card wants

Today tab

Card Story it tells Natural shape Why
Hero countdown "MBIE in 4h — THIS is next" 2×2 anchor square Gravity well. The single biggest pull.
Hero timeline "Shape of your remaining day" 4×1 horizontal strip Time IS horizontal. Sub-card under hero.
Top 3 actions "Do these 3 things" 1×3 stacked tall card Ranked list IS vertical. Must be visible without scroll.
Atlas brief (voice + actToday) "Atlas's read on the day" 2×3 tall narrative card Prose wants room to breathe. Serif voice (humanist).
Hot pipeline (3 signals) "3 money signals — each distinct" 3 × 1×1 squares in a row Each = own story, not bucket. Allow per-card iconography.
Needs action mail "5 threads need your reply" 1×2 tall list Vertical list IS the shape.
Chrono ribbon "Next 24h forward" 1×4 sticky right rail What it already is. Sticky on scroll.
Scout picks "3 internal repos worth a look" 3×1 horizontal strip at bottom OR chip teaser at top Curiosity teaser, not anchor.
Missed yesterday "1 thing slipped" TINY chrome chip Not card-worthy. Demote out of hero treatment.
Pulse preview "Top tasks" FOLD into Top 3 actions Duplicate of My Tasks tab.
Today meetings list "Time-sorted today" DROP Redundant with timeline.
DIGEST button "Generate Friday digest" CHIP in chrome Action, not content.

Outcome: 12 sections → ~8 cards + 2 chrome chips. Composes into a deliberate master grid.

Overview tab (Phase 204 · v4.0.5-overview-bento · 2026-05-29)

Cold-user reframe: Overview answers "how is my whole book shaped right now?" (book-level survey, this week, this quarter). Today tab answers "what do I do RIGHT NOW?" (next 24-48h). That division is the wedge — it lets us DROP the duplicate Today block from Overview entirely.

Card Story it tells Natural shape Why
Hero portfolio "Here's your book in 3 numbers + chips" 6×2 anchor Single biggest pull. Primary 3 (customers · open opps · total value) + secondary chips (util% · idle licenses) + since-snapshot delta strip below
Top 3 plays "3 highest-leverage moves this week" 3×2 stacked tall Ranked list IS vertical. Distilled from Top Signals' 6 categories via diversity-first + severity-fill
Atlas portfolio brief "Atlas's read on the whole book" 3×3 tall narrative Plex Serif italic — the "Atlas SPEAKING" voice. Light variant (1 thesis + 3 bullets), not wholesale composeBriefing (dense, doesn't fit serif)
Diff strip "What moved since last snapshot" 9×1 horizontal strip Compact mode: max 5 chips + "+N more" tail. Compresses the existing diff-grid auto-fit so it fits one row
3 SSP patches (Tam · Riki · Ben) "Health per book — parallel" 3 × 4-col row Each = own story, equal-weight. Stale-insight notice EMBEDDED inside each patch (no separate Atlas SSP commentary section)
Portfolio Pulse "8 cross-tab signals at a glance" 12×2 full-width block Slot defines footprint; internal .pulse-grid auto-flows. Don't hardcode 12×2 for forever-8
Pipeline by Stage "Funnel distribution + per-stage Atlas commentary" 12×1 strip Bars want horizontal room
Drill zone (BELOW bento, full-width sibling)
SSP Deep-Dive charts "Per-customer adoption inside each book" full-width stacked Drill, not bento. CSS Grid would force them into a slot they don't fit
Portfolio Leaderboard (54 rows) "Sortable everything" full-width table Drill, not bento
Today block (renderTodayViewSection) "Past-close, closing-soon..." DROP Duplicate of Today tab; wrong question for this tab
Adoption Rollup banner "8 Copilot footprint numbers" FOLD into Hero + Pulse 4 tiles already on Pulse; util% + idle → Hero chips
Pipeline KPI tiles "Book size, opps, total value, pipeline-by-SSP" FOLD into Hero + Patches First 3 = Hero numbers; SSP-breakdown = already in patches
Atlas SSP commentary (standalone) "Atlas's read per SSP" EMBED into each patch Tighter coupling, no separate section header

Outcome: 12 sections → 7 bento cards + drill zone with 2 wide surfaces. Sub-nav pills: 9 anchors (Book / Plays / Brief / Diff / SSPs / Pulse / Stages / Deep-dive / Leaderboard).

Implementation pattern: Same grid-template-areas + direct-child-with-grid-area approach as Today bento (§7), but Option B 12-col with NO sticky right rail because (a) Phase 203c sticky-hero bug still open — don't ship a second sticky surface, (b) momentum data already lives in Pulse B2/B3 movers, (c) Overview is survey, not next-move.

Books tab — per-SSP cockpit bento (Phase 205a · v4.0.6-books-bento · 2026-05-29)

Cold-user reframe: Books answers "how is THIS one person's book shaped right now?" — same survey shape as Overview, but scoped to one SSP. So Books bento = Overview bento minus the 3-patches row (only one SSP per cockpit). Cleanest pattern transfer in the bento queue. ONE renderBookBentoForSsp called 3× for Tam · Riki · Ben (identical topology, different data).

Card Story it tells Natural shape Why
Hero (per-SSP) "Tam's book in 3 numbers + chips" — # customers · # opps · $value + util / idle chips + since-snapshot delta (filtered to this SSP's owned opps) 6×2 anchor Same anchor weight as Overview hero
Top 3 plays "3 highest-leverage plays for Tam this week" 3×2 stacked tall Distilled from per-customer recs; allows priority-2 fallback for sparse books; category-diverse + severity-fill
Atlas brief (per-SSP) "Atlas's read on Tam's book" — Plex Serif italic prose 3×3 tall narrative Extracted from sspInsights[sspName]; lighter chrome than the wholesale renderAtlasCommentary wrap
Time-sensitive "What's hot this week in Tam's book" — compact chips 9×1 horizontal strip Format: Past close · 3 · $1.2M · Westpac (count + value + top customer per chip) · max 5 chips + "+N more"
Top 3 risks "3 risks to watch in Tam's book" 6×1 horizontal Separate pool from actions (CHURN RISK / ENABLEMENT / SENTIMENT / etc.) · same diversity-fill algorithm
Health snapshot "Quick-glance Tam-book health" 6×1 row of 3 mini-tiles idle-license customers · MoM decliners · weak admin posture — counts only, drill via Customers table
Stage funnel "Pipeline by sales stage in Tam's book" 12×1 wide strip Full-width bars, scopes to this SSP's owned opps
Drill zone (BELOW bento, full-width siblings per cockpit)
Customers table Sortable per-customer detail for this SSP full-width table Drill, not bento (tables don't bento)
All Opps table Every open opp owned by this SSP full-width table Drill, not bento
Header KPI strip (old renderHeader) "7 KPIs at top: customers / licenses / MAU / free / util / opps / pipeline" FOLD into Hero Don't duplicate the same numbers above + below bento — slim the header to chrome only
Atlas commentary as standalone section "Atlas brief" FOLD into bento Brief slot Same content, lighter chrome
Actions+Risks as one combined section "Recs" SPLIT into 2 slots Two distinct stories, two distinct shapes — better than nested columns

Outcome: 7 sections per cockpit → 7 bento cards + drill zone with 2 wide tables. Sub-nav pills per cockpit: 9 anchors (Hero / Plays / Brief / Time / Risks / Health / Funnel / Customers / All-opps) + COMPACT toggle.

Architectural note (compact toggle): Bento cards use .bb-card class (NOT .cockpit-section), so the existing COMPACT toggle only folds drill-zone tables — sensible "show me less" behaviour. Don't reuse .cockpit-section for bento cards; that's what made the COMPACT exemption clean.

Customers tab — survey-of-names bento (Phase 205b · v4.1.0-customers-bento · 2026-05-29)

Cold-user reframe: Customers answers "WHICH customers right now?" — every card surfaces NAMED individuals (Westpac · NZTA · Police) rather than aggregates. That's the wedge that earns this tab its own bento vs Overview (aggregates) and Books (per-SSP survey). Cold user lands and reads the NAMES first.

Card Story it tells Natural shape Why
Hero "54 customers · 26 active · $720M + the ONE customer of the week (top mover by name)" 6×2 anchor Single biggest pull. Lands a NAME (cotw) inside the anchor + 3 primary numbers (customers / open opps / total value) + util/idle/Lynx-coverage chips + since-snapshot delta
Top 3 to call "Westpac · BNZ · Genesis — and why (top rec per name, category-diverse)" 3×2 stacked tall Named individuals, not aggregates. Mirrors Overview top-3 algorithm (priority-1 first, category-diverse pass 1, fill pass 2, priority-2 fallback) but every row = ONE customer not ONE signal
Atlas brief (customer-set voice) "Atlas's read on your customer set as individuals — 3-beat narrative" 3×3 tall narrative Plex Serif italic. Composed at render-time (no pre-baked atlasInsight in current dist). 3-beat structure (rubber-duck #12): portfolio state → movement/risk → next action. Names italicised in cyan
Adoption movers strip "↗ NZTA +259% · ↗ Waikato +145% · ↘ Spark −18% · ..." 9×1 horizontal Sign-filtered chips (rubber-duck #8): top 3 positive gainers + top 2 negative decliners; "+N more" tail
Whitespace leaders "5,053 free Chat — NZ Police · 4,232 — MSD · ..." 6×1 horizontal Distinct from Top-3 (rubber-duck #7): pure free-Chat conversion pool by NAME, top 5
Health tiles "3 NAMED red-flag tiles: idle queens (top: NZTA · 240) · decliners (top: X · −Y%) · weak admin (top: Z · N%)" 6×1 row of 3 mini-tiles Each tile shows COUNT + TOP-1 NAME. Weak admin uses classifyAdminPosture.enabledScore not just flagAdminRisks (rubber-duck #9)
Lynx-coverage strip "Trust this tab — 52/54 with Lynx · 51 momentum · 52 free chat · 37 idle · 2 dark" 12×1 strip Honesty layer (rubber-duck #13). Industry/geo data = 0 in current snapshot, so this slot preserves the candor the old .c360-overview-caveat banner used to carry. Each chip tinted by completeness tone (full=green, partial=amber, empty=muted, dark=red)
Drill zone (BELOW bento, full-width siblings)
.c360-controls (existing) Power-user sort + filter chrome full-width Stays untouched. Sub-nav points at #c360-controls so existing JS sort/filter handlers keep working
.c360-grid 54 cards (existing) Rich per-customer detail (adoption funnel, momentum, conversion, penetration, admin posture, top rec, Atlas note, agent toolbar) full-width grid Stays untouched — the workhorse cards remain visually unchanged. Drill, not bento
Old .c360-overview-bar (6 stats) totals FOLDED into Hero chips Lynx-coverage already on Coverage strip; util/idle already on Hero chips
Old .c360-overview-caveat banner data freshness note FOLDED into Hero title tooltip + Coverage strip Same honesty, redistributed where each card lives

Outcome: 1 overview-bar + 1 caveat + 1 controls + 54 cards → 7 bento cards + drill zone (controls + 54 cards). Sub-nav pills: 9 anchors (Hero / Call / Brief / Movers / Whitespace / Health / Coverage / Filters / Grid). No COMPACT toggle (rubber-duck #3) — Customers tab doesn't have .cockpit-section semantics so a COMPACT would be a no-op.

Implementation pattern: Same grid-template-areas 12-col CSS Grid as Books/Overview. New src/customers-bento.js module exports renderCustomersBento(customers, snapshot, opts) + renderCustomersSubnav() + CUSTOMERS_BENTO_CSS. Bento cards use .cb-card chrome (NOT .c360-card — rubber-duck #5: the existing rich card has a global click-to-account-page handler bound by class; new bento cards must not inherit that). Mobile collapse @1100px to single column; sub-collapse @640px stacks the 3 hero numbers vertically (Plex Sans Condensed 36px $247M doesn't fit 91px columns).

Three Rule #6 probe wins (data shape verified BEFORE writing renderer): 1. Industry/geo data = 0/54 in current snapshot → slot 7 became Lynx-coverage strip instead (caught at probe stage, no wasted code) 2. atlasInsight = 0/54 → brief composed at render-time using a 3-beat structure (not pre-baked LLM prose) 3. 52/54 with Lynx · 51 MoM · 52 free chat · 37 idle confirmed → 6 of 7 slots have real signal to render


3.5 · When NOT to bento (added Phase 205a · 2026-05-29)

Not every tab should be bento. The bento mosaic is for survey tabs — where the cold-user question is "what's the shape?" and the answer-shape is a deliberate composition of differently-sized cards.

Tabs that ARE survey-shaped (and SHOULD bento): - Today — "what do I do RIGHT NOW?" - Overview — "how is my whole book shaped?" - Books (per SSP) — "how is this person's book shaped?" - Customers — "how is my customer set shaped?" (Phase 205b queued) - Activity — "what's flowing through my channels?" (Phase 205c queued — though may need a different bento flavour for time-stream content)

Tabs that are NOT survey-shaped (and should NOT bento): - Pipeline (Opportunities) — power-user sortable/filterable table. The cold-user question is "let me filter and sort to find specific opps." Forcing bento onto a 1,408-row table is anti-pattern — tables ARE tables. (Phase 205d will polish chrome to match bento tabs visually without bento'izing.)

The smell signal that a tab shouldn't bento: if the dominant content is ONE big sortable/filterable thing (table, list, feed), bento adds chrome without adding clarity. Polish the table's own chrome instead.

Counter-test: if the tab has 5+ distinct stories that want differently-sized real estate, bento is the right tool. If it has 1 dominant story and the rest are filter widgets, leave the table alone.

This insight was banked at Row 205 split (the original monolithic "bento-rest-tabs" row got split into 205a/b/c/d when surfacing that Pipeline doesn't fit). The architecture-gate (Rule #5) caught it; without that gate we'd have forced bento on a table.


3.6 · Bento eligibility + cold-user wedge test (added Phase 210 · v2.0)

§3.5 said when NOT to bento. This is the positive companion: what EARNS a tab its own bento.

The 2-question gate (both must be YES)

  1. Cold-user wedge test: Does this tab answer a question DIFFERENT from every other already-bento'd tab?
  2. Today = "what do I do RIGHT NOW?"
  3. Overview = "how is my whole book shaped?"
  4. Books (per SSP) = "how is THIS one person's book shaped?"
  5. Customers = "WHICH customers right now?" (every card surfaces NAMED individuals — wedge that prevented this being a Books-clone)
  6. If the new tab's question collapses to one of the above, it's duplication. Polish the existing tab instead.

  7. Composition test: Does the tab have 5+ distinct stories that want differently-sized real estate?

  8. Story = a coherent answer to a sub-question (e.g. "next meeting," "what moved this week," "who needs a call," "what's flowing through the funnel").
  9. If 1 dominant story + filter widgets → table/feed pattern, not bento (per §3.5).

Honest failure mode of the wedge test

The wedge test is a decision aid, not a guarantee. Tabs existed before bento. The wedge for Today/Overview/Books was retrofit during the bento exercise; only Customers had its wedge discovered live during architecture-gate. So treat the wedge as the test that prevents bad new bentos, not as proof that every existing bento is essential. The Activity-tab decision (Phase 205c queued) is the next real wedge check — "what's flowing through my channels?" may or may not earn a bento; it might be feeds-shaped (which we said in §3.5 don't bento).

What the drill zone is for (the relief valve)

Bento is the SURVEY layer. The drill zone (full-width siblings BELOW bento) is the POWER-USER layer. Every bento tab so far has one: - Today — chrono ribbon (sticky right rail, not a sibling — different pattern) - Overview — SSP deep-dive charts + 54-row leaderboard - Books — Customers table + All Opps table (per cockpit) - Customers — .c360-controls + 54 .c360-card grid (untouched workhorse)

The drill zone is where TABLES and 54-card grids live. Bento isn't trying to replace them; it's trying to make them findable by surfacing the shape above.


3.7 · Patterns by confidence level (added Phase 210 · v2.0)

A correction layer over §3 and §6. Use this to decide what to apply when you start a new HELM surface.

Locked (apply by default · don't re-debate)

Pattern Where verified
grid-template-areas with named slots (Path A) All 4 bentos
Direct-child grid anatomy (each slot = own <section>, not wrappers) Overview rubber-duck #1, all 4 bentos
Fold-not-lose for dropped sections All 4 bentos
Drill-zone sibling (full-width under bento) All 4 bentos
Tab-specific class prefix (.today- .ov- .bb- .cb-) All 4 bentos; Customers prevented click-handler collision
Mobile collapse @1100px (sub-collapse @640px for hero numbers) All 4 bentos; Customers found the 640px need at smoke time
Cold-user wedge test before adding a new bento tab Customers (the test that worked live)
Rule #5 architecture-gate for bento phases 4-of-4 zero rework loops
Rule #6 data-shape probe before renderer Mandatory; pays back hours per invocation
Inline phase-local CSS in renderer module Pattern from Today, repeated in Overview/Books/Customers (matches phase-local convention)
Each bento renders standalone (no cross-tab data deps) Build-time data → static HTML model

Provisional (use unless you have a reason not to · note the reason if you diverge)

Pattern Where verified When to diverge
3-beat Atlas brief (state → movement → action) Customers cracked, composable at render-time When you have pre-baked LLM prose (Books) OR a domain-specific structure (Today's ACT/RADAR)
Customer names italicised in cyan Customers brief When the surface isn't name-dense (Overview is signal-dense, not name-dense)
Sub-nav anchors cap (~7-9, one visual row) Overview/Books/Customers all 9 Today has none and works fine for a 4-card-row layout
Sign-filtered delta strips (mixed +/−) Customers movers When dataset is single-direction (e.g. only stale events)
Diversity-fill + severity-fill for Top-3 Overview/Books/Customers When the 3 slots are semantically distinct already (Today's hot-pipeline 3)
Slim chrome-only header (KPIs folded into Hero) Books (cockpit-head-slim) When the tab needs persistent KPI tiles for above-the-fold (e.g. trading dashboards)
Sub-nav anchors with scroll-margin-top: 96px Overview/Books/Customers When tab has no sub-nav (Today) — N/A, not an exception

Not universal (don't promote · these are context-specific patterns)

Pattern Where used Why not universal
data-freshness ink (fresh/ok/stale/unknown) Today only Only useful when cards have independent recency sources. Overview/Books/Customers cards all share one snapshot → ink would imply false precision. Audit per-card before propagating.
data-empty="1" chip-collapse Today single-row hot/scout slots only Scoped to slots where empty == nothing-to-show. Multi-row slots keep card shape per §3 so bento composition doesn't break on quiet days.
Sticky hero NOT shipped (Phase 203.2 revert) Open Electron-specific bug. Don't re-enable without Phase 203c investigation.
COMPACT toggle Books only (folds drill-zone tables) Books has .cockpit-section semantics that survive folding. Customers explicitly chose NO COMPACT (no .cockpit-section → it would be a no-op). Today has no .cockpit-section semantics in bento area.
Per-card sparklines Pending data layer (Row 203b) Needs time-series scrape; current data is per-snapshot only.
Right-side sticky chrono rail Today only Today's bento has a 9-col + 280px layout for the rail. Overview explicitly chose NO right rail (momentum already in Pulse). Don't add chrono pattern to other tabs without a 24h-forward dataset.

How to use this table

When you start a new HELM surface, ask in order: 1. Locked patterns → apply by default. 2. Provisional patterns → apply unless you can write a one-line reason in the row spec for diverging. 3. Not-universal patterns → don't pick up by default. If you think you need one, prove the context fit (e.g. "this tab has independent recency per card, so freshness ink earns its place").


4 · Typography System — IBM Plex Sans family + JetBrains Mono

Current (v1 — pre-bento)

--sans: "Inter", system-ui, sans-serif;
--mono: "JetBrains Mono", "Cascadia Code", monospace;

Target (v2 — bento-ready)

--sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
--sans-cond: "IBM Plex Sans Condensed", "IBM Plex Sans", sans-serif;
--serif: "IBM Plex Serif", Georgia, serif;
--mono: "JetBrains Mono", "Cascadia Code", "Consolas", monospace;

Why IBM Plex Sans over Inter

  • PAC uses it. Sush already loves PAC's feel. Don't ship a different sans than PAC.
  • More personality. Inter is the default SaaS sans (Linear, Vercel, Figma, GitHub, every YC startup) — neutral to the point of generic.
  • Engineered voice. Plex was designed by Bold Monday for IBM as their global voice — quietly humanist, slightly mechanical, distinctive at small sizes.
  • Full family. Sans + Sans Condensed + Serif + Mono all coexist visually. We get a typographic SYSTEM, not a single face.
  • Tabular figures + true italic — built in, no opt-in needed.

Family deployment plan

Surface Face Weight Use
Body / UI / card prose IBM Plex Sans 400 Default text
Card titles / hero countdown digits IBM Plex Sans Condensed 600/700 Tighter glyph, more impact at scale
Hero countdown numbers IBM Plex Sans Condensed 800 + tabular-nums Maximum gravity
Eyebrows / tags / status pills JetBrains Mono 400/700 uppercase "Data" voice
Code / verdicts / signal IDs JetBrains Mono 400 Code voice
Atlas brief narrative IBM Plex Serif italic 400 "Authored" voice — distinct from data feel
Numbers (money, counts, ages) IBM Plex Sans tabular-nums 500 Aligned columns

The Plex Serif for atlas-brief is the signature move — it tells the cold user "this is Atlas SPEAKING, not data being shown."

Font-weight contrast rules

  • 300 (extra light) — explicitly reserved (use sparingly, decorative only)
  • 400 — body default
  • 500 — emphasis inline, tabular numbers
  • 600 — card titles, hot signals
  • 700 — eyebrows, tags
  • 800 — hero numbers ONLY

5 · Color Discipline — Amber reserved for STAKES

Current palette (B2 production, locked at v3.0.0-foundation):

Token Hex Reserved for
--amber #c89853 STAKES SIGNAL ONLY — customer meeting imminent, money at risk, deadline urgent
--cyan #7a9aab Customer / account identity (cyan customer names, cyan-bordered EXTERNAL meetings)
--bg #050507 Page background (near-black)
--panel #0f0f12 Card background tier 1
--panel-2 #18181c Card background tier 2 (internal/focus blocks)
--border #1e1e23 Strong borders (interactive elements)
--border-soft #15151a Soft borders (chrome dividers — most cards)
--text-bright #e8e8e0 Hero text, active state
--text (slate) Body
--text-dim #777771 Tertiary, eyebrows
--text-muted #545450 Quaternary, empty-state placeholders
--ink-green / --red (TBD) Reserved for "yes/no" semantic states (Pulse status dot, "live" tag)

The "Amber Discipline" rule

When everything is amber, nothing is amber. Reserve amber for the SINGLE class of "customer × time × money at stake." If you find yourself adding var(--amber) to a non-stakes signal, use a slate/cyan/text-bright token instead.

Amber taxonomy (added Phase 210 · v2.0)

Spot-check of var(--amber) usages across 11 source files (today-tab, ssp-book, customers-bento, render, scout-tab, my-tasks-tab, engagement-tabs, atlas-brief, digest-tab, prep-packet, pulse-preview, feedback-buttons). The audit confirms §5's prediction: amber is overused. Three buckets:

Bucket Examples Verdict
A — Legitimate stakes signal .hero-countdown-tag-imminent, countdown digits, customer timeline block, hot-pipeline value, warning/partial coverage states, P2 priority chip when actually P2 Keep amber. This is what the token is for.
B — Semantic warn/partial/stale .bb-time-chip-warn, .cb-cov-chip-partial, .cb-health-tile-warn, helm-pill-ok (when "ok" means aging data) Move to a --warn token (or rename amber to a stakes-only token + introduce --warn). Currently aliased to amber, conceptually distinct.
C — Chrome / nav / decorative / generic .today-section-eyebrow, .helm-sub.active, .today-scout-ai, .today-weekly-digest, hover/focus rings, .today-action-pri (default amber even when P1), command-button colors, scout-pager-all Drop amber. Use slate ladder (text-bright / text / text-dim) or cyan for identity.

The current cumulative effect is that opening HELM presents an amber-saturated visual field where the IMMINENT customer meeting can't out-shout the active nav pill. Bucket C is the worst offender by volume.

What Row 211 should do (not a blanket flip)

DON'T: sed-replace var(--amber) everywhere. That breaks bucket A and B sites.

DO: classify each ~80 var(--amber) site into A / B / C. Bucket A: keep. Bucket B: introduce or use a --warn token (semantic), keep the same hex for now if needed. Bucket C: flip to slate ladder or cyan per the cyan-discipline rule.

Acceptance: after Row 211, opening HELM should produce visible amber ONLY in legitimate stakes contexts. The IMMINENT tag stands out again because nav/eyebrows/buttons stop competing with it.

The "Cyan Discipline" rule

Cyan = customer identity. If a token is referring to a customer (name, account, TPID), cyan. Otherwise not.


6 · Better-than-asked design moves (queued for future phases)

These are NOT in v1 bento. They're the evolution path. Status updated v2.0 (Phase 210) — sticky-hero correction + propagation reasoning.

  1. Sticky hero columnposition: sticky on hero card so it stays visible while satellites scroll. ❌ REVERTED. Phase 203 shipped, Phase 203.1 hotfixed, Phase 203.2 reverted due to Electron-specific visual bug (hero moving with scroll + overlapping below; not reproducible from headless Playwright). Open at Row 203c sticky-hero-investigation — needs HELM-side DevTools to diagnose. Do not re-enable without fix.
  2. Cards that grow/shrink with content — empty needs-action collapses to chip; full one expands. ⚠️ PARTIAL: Today only. Scoped to single-row hot/scout slots per §3.7 "not universal" — applying everywhere risks breaking bento composition. Per-tab applicability audit needed before propagating (Row 212).
  3. Mini sparklines INSIDE cards — hot pipeline gets 1-line WoW trend; scout gets star-momentum line. ⏸ DEFERRED to Row 203b. Rule #6 probe found no time-series data exists; building data layer first.
  4. "Pinned" pattern — Sush drag-pins a card to a pinned zone. Persists per-day via localStorage. Queued (Row 208 in v0.4 numbering; needs renumber).
  5. Card-level freshness ink — thin colored top-border per card (fresh/stale/unknown). Micro-status without real estate. ⚠️ PARTIAL: Today only. Per §3.7, propagating to Overview/Books/Customers would imply false precision because their cards share one snapshot's recency. Per-tab applicability audit needed (Row 212): a tab earns freshness ink only when its cards have independent recency sources.
  6. Two-state cards — click to expand 1×1 → 2×2 with detail. Click again to collapse. ⚠️ PARTIAL: inline drawer (Phase 207, v4.0.6-cross-card, 2026-06-01). Shipped as inline detail drawer (card grows vertically inside its grid slot via hidden <div class="card-drawer"> revealed by [data-expanded="1"] on parent), not literal 1×1→2×2 grid resize. Rationale: literal grid-column/row span override on grid-template-areas slots cascades layout bugs and breaks bento composition (§3). Inline drawer preserves layout integrity. Literal 2×2 deferred to Phase 207b if wanted.
  7. Cross-card hover halos — hover Westpac on Hot Pipeline → highlights Westpac everywhere (timeline block, needs-action row, hero if applicable). Bloomberg Terminal pattern. ✅ SHIPPED Phase 207 (v4.0.6-cross-card, 2026-06-01). JS event-delegation on [data-cross-card-target="1"][data-customer-tpid]; CSS .cross-card-halo adds subtle cyan outline + --cyan-glow box-shadow (composes additively with existing freshness ink). pointerover/pointerout with relatedTarget churn-guard avoids flicker between same-customer cards. focusin/focusout for keyboard. Top-3 cards intentionally excluded (atlas-brief prose lacks structured customer — see Phase 207 BUILD-LOG follow-ups for plumbing). Scout cards intentionally excluded (no customer association — MSFT internal repos). Today-tab only; cross-tab focus is Phase 209 (tab-to-tab-context).
  8. Quiet-day creative space — ≥3 cards empty → grid collapses into 1 "// HORIZON CLEAR" panel with "go deep on X" suggestion. Queued.
  9. "SINCE last open" delta strip — already exists at top; could be deeper (per-card delta hints). Time-aware greeting chip ✅ Phase 203 shipped (5 NZ-wallclock brackets); per-card delta hints remain queued.
  10. Tab-to-tab context preservation — selecting Westpac on Today carries to Customers tab. Queued.

7 · Implementation pattern — CSS Grid grid-template-areas (Path A)

The bento layout is built with explicit grid-template-areas per tab, not auto-flow. Two reasons:

  1. Designer control. Path A gives us deliberate composition. Each card has a NAMED HOME.
  2. PAC uses it. Sush already loves how PAC composes. Don't break what works.

Today tab — proposed master grid

12-col × N-row · 16px gap · max-width 1400px · 280px sticky right rail

┌──────────────────────────────────┬──────────────┐
│         HERO (col 1-6, row 1-2)   │              │
│                                   │              │
├──────────────────────────────────┤   CHRONO     │
│ TOP-3 (col 7-9, row 1-2)         │   RIBBON     │
│                                   │   (col 10-12,│
├──────────────────────────────────┤   row 1-N    │
│ TIMELINE (col 1-9, row 3) — strip │   sticky)    │
├────────────┬────────────┬────────┤              │
│ HOT-1      │ HOT-2      │ HOT-3  │              │
│ (col 1-3)  │ (col 4-6)  │ (col 7-9)│            │
├────────────┴────────────┴────────┤              │
│ NEEDS-ACTION (col 1-5, row 5-6)  │              │
│                                   │              │
├──────────────────────────────────┤              │
│ ATLAS-BRIEF (col 6-9, row 5-6)   │              │
│   serif italic, narrative voice  │              │
├──────────────────────────────────┤              │
│ SCOUT-1 │ SCOUT-2 │ SCOUT-3 (row 7)│            │
└──────────────────────────────────┴──────────────┘
                                    [missed chip in chrome top right]

CSS skeleton:

.today-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr) 280px;
  grid-template-areas:
    "hero hero hero hero hero hero top3 top3 top3 . . . chrono"
    "hero hero hero hero hero hero top3 top3 top3 . . . chrono"
    "timeline timeline timeline timeline timeline timeline timeline timeline timeline . . . chrono"
    "hot1 hot1 hot1 hot2 hot2 hot2 hot3 hot3 hot3 . . . chrono"
    "needs needs needs needs needs brief brief brief brief . . . chrono"
    "needs needs needs needs needs brief brief brief brief . . . chrono"
    "scout1 scout1 scout1 scout2 scout2 scout2 scout3 scout3 scout3 . . . chrono";
  gap: 16px;
  max-width: 1400px;
}
.today-hero { grid-area: hero; }
.today-top3 { grid-area: top3; }
.today-timeline-card { grid-area: timeline; }
.today-hot-1 { grid-area: hot1; }
/* ... etc ... */
.today-chrono { grid-area: chrono; position: sticky; top: 80px; }

Mobile/narrow-viewport graceful collapse

@media (max-width: 1100px) {
  .today-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      "hero" "top3" "timeline"
      "hot1" "hot2" "hot3"
      "needs" "brief"
      "scout1" "scout2" "scout3"
      "chrono";
  }
}

8 · Risks & guardrails

  • 🚨 Don't propagate to other tabs in same phase. Pilot on Today only. Validate. Then propagate.
  • 🚨 Card-content fit matters. A 1×3 tall card with 1 row of content looks broken. Set MIN-content thresholds per card; if not met, card disappears OR uses a minimum-content placeholder.
  • 🚨 Mobile collapse is non-negotiable. Electron's resizable window means narrow widths happen. Always test the 1-column fallback before shipping.
  • 🚨 Don't kill the regression suites. Each new card class needs smokes (verifying it renders / hides correctly). Add to smoke-bento-today.mjs etc.
  • 🚨 Standing Rule #1 (scope): M365 / Copilot / Agent 365 ONLY. Bento is design-system work, not scope expansion.
  • 🚨 Rule #7 (Render-is-Not-Done-Until-HELM-Shows-It): every bento phase ends with node scripts/build.mjs + mirror to installed HELM + visual confirmation in HELM (Sush).
  • 🚨 Don't let Inter and Plex coexist mid-migration. When swapping fonts, do it cleanly per tab — partial-state HELM looks worse than either old or new.

8.5 · Implementation debt surfaced at Phase 210 checkpoint

Three pain points worth naming, with priority calibrated to user-value not tidy-code.

High pain — render.js is 209KB and Overview bento is inside it

Overview bento added ~30KB of renderer + CSS to render.js (already the largest file at 209KB). Future Overview iterations get harder, and any non-Overview change in render.js (which orchestrates the whole HTML composition) risks accidentally touching bento code.

Resolution path: extract Overview bento → src/overview-bento.js exporting renderOverviewBento, renderOverviewSubnav, OVERVIEW_BENTO_CSS. Mirror the Customers pattern. Pure refactor, no visual change. ~2h.

Medium pain — duplicated bento CSS patterns across 4 files

Each bento renderer ships its own copy of: bento-card chrome (border/border-soft, panel/panel-2 fill, scroll-margin-top, mobile collapse), eyebrow styling, subnav pill styling, drill-zone divider. ~150-200 lines repeated 4 times.

Resolution path: extract a styles/bento-base.css with the shared chrome tokens + .bento-slot base class + .bento-subnav pattern. Each tab's <X>_BENTO_CSS becomes only its slot-specific styling. Saves ~400-600 lines net + makes the next bento tab (Activity, if it ever bentos) cheap to add.

Low pain — Today/Books bento extraction

Today bento lives in today-tab.js (85KB). Books bento lives in ssp-book.js (61KB). Both files are functional and the extraction is tidy-bug, not value-bug. Defer until next functional touch on those tabs. When you next add a feature inside today/books bento, extract as part of the same phase. Don't spend a refactor session on this alone.

Why this section exists

The rubber-duck at Phase 210 plan stage pushed back on "extract all 3 because Customers did it." That's tidy-code reasoning, not value reasoning. The honest priority order is: fix the file that hurts (render.js), share the chrome that duplicates (bento-base.css), leave the rest until you have a reason to touch them.


9 · The Iteration Mindset

Per Sush's directive: "we will constantly iterate this."

This doc is v1. Expect v2/v3/v10. Each session that touches HELM design should: 1. Read this doc first. 2. Apply the principles to the current task. 3. If a principle doesn't hold or a new pattern emerges, EDIT THIS DOC. Note the date + version bump. 4. Update the phase queue if the change opens new work.

What this doc is NOT: - Not a finished spec. It's a SHARED REFERENCE. - Not a contract — Sush can override any principle at any session start. - Not exhaustive — patterns we haven't tried yet aren't here yet.

What this doc IS: - The thing future-Atlas reads when Sush says "polish the X tab." - The thing that prevents session amnesia from causing visual drift. - The thing that turns 50 sessions of small fixes into a coherent system.


9.5 · Bias checks before promoting a pattern (added Phase 210 · v2.0)

Atlas typically writes both the philosophy AND the bentos themselves. That's a conflict-of-interest in self-review. Before adding a new "principle" to §3.7 "locked" or §6 "shipped", run this checklist:

  1. Coverage test — Am I promoting a pattern used by all 4 bentos, or only 2? If 2-3, it goes in §3.7 "provisional" not "locked."
  2. User-value test — Is this a user-value issue (Sush sees / uses / benefits) or a tidy-code preference (only I notice)? Tidy-code goes in §8.5 with priority "low," not in §3.7.
  3. Regression-risk test — If I propagate this, what could break? If the answer is "nothing visible, just code-paths" → it's tidy-bug, defer.
  4. Sush-validation test — Did Sush HELM-confirm the outcome, or did smoke just pass? Smoke green ≠ user-validated. If only smoke validated, mark "RC pending HELM" not "shipped."
  5. Universality test — Does the pattern survive Activity (feeds) / Pipeline (table) / Digest (single-stream)? Or is it survey-tab-only? Survey-only patterns go in the per-tab table in §3, not in §3.7.
  6. Honesty test — Was the pattern discovered during a phase, or retrofitted in the writeup? Retrofit framing is fine for a single decision (Customers wedge was a real discovery; Today/Overview/Books wedges were retrofit), but the doc should say so.

If a candidate fails 2+ checks, demote or drop. The doc's authority depends on its accuracy.


10 · Change log

Date Session Author Change
2026-05-29 386fd1f6 Atlas v1.0 — initial philosophy doc. Bento mosaic principle + IBM Plex Sans typography + Today tab story-shape mapping + Path A grid-template-areas + 8 better-than-asked queued features + amber/cyan discipline rules. Promoted from Sush's 2026-05-29 directive.
2026-05-29 7d86a59c Atlas v1.2 — Phase 203 polish-layer notes folded into §6 add-ons. (a) Sticky hero implementation requires both align-self: start AND min-height (220px on hero kept the anchor presence — without it the 2-row grid span lets content-sized hero shrink visually too much). Mobile @1100px disables sticky to avoid a pinned wall in single-column layout. (b) Freshness ink uses box-shadow: inset 0 2px 0 instead of border-top: 2px solid — same visual but no box-model impact, and the inset shadow doesn't fight the existing 1px border. Tokens reused (no new colors). Degraded PULSE manifests (overallStatus !== "complete") coerce fresh-age to "unknown" so the ink doesn't falsely vouch for a half-failed refresh. The "ok" tier (2-12h) has NO ink — absence = good news (Toyota Production System pattern). (c) Empty-card chip-collapse is SCOPED to single-row slots (hot/scout) only; multi-row named-area cards (top3/needs/brief) keep their layout shape per §3 (placeholder cards stay card-shaped to keep bento composition intentional on quiet days). (d) Sparklines DEFERRED to Phase 203b — Rule #6 probe found scout momentum is a single computed score with no time-series, and hot pipeline has no WoW value-trend stored. Building the data layer first (203b) before rendering. (e) Time-aware greeting chip is build-time — refreshes on every PULSE rebuild; acceptable for daily-driver pattern. New helpers computeFreshness + computeGreeting are unit-tested with fixed timestamps in smoke-today-bento-polish.mjs to avoid time-of-day flakes.
2026-05-29 1271fa43 Atlas v1.3 — Phase 204 (Overview bento) added a per-tab story-shape table in §3 (now grouped as "Today tab" + "Overview tab" sub-sections). Architecture-gate decision: Option B (12-col, no sticky right rail) picked over Option A (9-col + 280px sticky momentum rail). Two reasons logged: (1) Phase 203c sticky-hero bug is still open — don't ship a second sticky surface until we understand why the first one broke (Electron-specific, not reproducible from CLI); (2) momentum information already exists in Pulse B2/B3 (top movers ↑↓) — extracting to a rail duplicates without adding. Rubber-duck consulted at plan stage — caught 11 blind spots, all adopted: direct-child grid anatomy (each slot = own <section>; SSP patches split into 3 named children, never wrap .ssp-patch-grid), top-3 scoring (category-diversity pass first then severity-fill, not naive priority×magnitude), diff strip compact mode (max 5 chips + "+N more" tail), HELM-gated tag (RC only until Sush confirms in HELM), Hero hierarchy (primary 3 + secondary chips, not 5 equal-weight), brief lighter variant (1 thesis + 3 bullets, NOT wholesale composeBriefing), Pulse internal flex (slot defines footprint, .pulse-grid auto-flows), drill zone sibling not child, CSS inline in render.js (matches Today phase-local convention), subnav anchors on cells + scroll-margin-top: 96px, stale-insight warning preserved (embedded inside patches). NEW renderers: renderOverviewHero · renderOverviewTop3 · renderOverviewBriefCard · renderOverviewDiffStrip · renderOverviewSspPatchSlots · renderOverviewPulseBlock · renderOverviewStagesCard. NEW smoke scripts/smoke-overview-bento.mjs 80+ checks GREEN (static + Playwright DOM + geometry + mobile collapse + no-horizontal-overflow). Critical regressions GREEN: smoke-today-bento, smoke-today-bento-polish, smoke-e2e (Overview visible, all 7 other tabs visible, zero console errors). smoke-headless pre-existing failure (v0.2-era a[data-tab="customer"] selector) noted but unrelated. Tag v4.0.5-overview-bento shipped and Sush HELM-confirmed with strong positive: "OG i love the overview tab - so good. visually appealing enough space different card layout different barcharts etc. perfect work Atlas! good job!".
2026-05-29 1271fa43 Atlas v1.4 — Phase 205a (Books bento per-SSP cockpit) added a third story-shape table in §3 ("Books tab — per-SSP cockpit bento") AND added a brand-new §3.5 "When NOT to bento" sub-section banking the insight that surfaced when splitting Row 205 → 205a/b/c/d: Pipeline (Opportunities) is a power-user sortable table and SHOULD NOT bento. Tables ARE tables; bento is for survey tabs (where the cold-user question is "what's the shape?"). The smell signal: if dominant content is ONE big sortable/filterable thing (table/list/feed), bento adds chrome without adding clarity. Rubber-duck consulted at plan stage — caught 12 blind spots, all adopted: (1) pass diff to Books renderAllSspBookCockpits + scope-by-SSP-owner filter via bbScopeDiffToSsp; (2) don't duplicate header KPIs (move old renderHeader 7-KPI strip into .bb-hero and slim header to chrome-only cockpit-head-slim); (3) don't wrap renderAtlasCommentary wholesale (extract insight text only, render Books-specific brief with lighter chrome); (4) COMPACT toggle exemption (bento cards use .bb-card NOT .cockpit-section so COMPACT only folds drill-zone tables — sensible "show me less"); (5) hero utilization label precise ("book-wide" with tooltip explaining tenant-wide-not-Tam-owned); (6) actions/risks bucket helpers bbIsAction/bbIsRisk/bbPickTopRecs (allows priority-2 fallback for sparse books, includes RENEWAL/ADOPTION/PIPELINE categories the original split omitted); (7) time strip chip format count · value · top customer not just counts; (8) CSS export+import pattern (BOOKS_BENTO_CSS from ssp-book.js → injected once in render.js <style> block); (9) anchor IDs per-cockpit unique (tam-jump-*/riki-jump-*/ben-jump-* no collision); (10) explicit scroll-margin-top: 96px for .books-grid-bento > section[id] AND .books-drill [id]; (11) smoke checks beyond Overview parity (3 grids · 7 children each · drill sibling per cockpit · .bb-card not .cockpit-section for bento · no MACC/ACR/Azure text); (12) HELM-gated tag (RC only until Sush confirms). One renderBookBentoForSsp called 3× (Tam/Riki/Ben) — identical topology, different data. NEW smoke scripts/smoke-books-bento.mjs 100+ checks GREEN (more than Overview smoke because of 3-cockpit pattern verification). Critical regressions GREEN: smoke-overview-bento (Phase 204 unaffected), smoke-today-bento (Phase 202), smoke-today-bento-polish (Phase 203), smoke-e2e (zero console errors, all 7 tabs intact). Tag v4.0.6-books-bento held as RC pending Sush HELM verify (Rule #7).
2026-05-29 57998126 Atlas v1.5 — Phase 205b (Customers bento) added fourth story-shape table in §3 ("Customers tab — survey-of-names bento"). Cold-user wedge: Customers = NAMED INDIVIDUALS (vs Overview aggregates, vs Books per-SSP, vs Today next-24h). Architecture-gate (Rule #5) surfaced 4 paths; Sush picked Option D (survey-of-names bento above + existing 54-card grid as drill zone). Three Rule #6 probe wins: industry/geo=0/54 → slot 7 became Lynx-coverage strip · atlasInsight=0/54 → brief composed at render-time using 3-beat structure · 52/54 Lynx coverage confirmed → 6 of 7 slots have real signal. Rubber-duck consulted; 15 findings adopted. NEW src/customers-bento.js (40KB · the only standalone bento module in the project — pattern other 3 should adopt). Tag v4.1.0-customers-bento shipped, RC pending Sush HELM spot-check per the 205a-feedback lighter-checklist pattern.
2026-05-29 340d5f53 Atlas v2.0 — Mid-arc cold-eye checkpoint (Phase 210) after the 4-bento system landed. Rubber-duck pushed back on 7 over-claims; demotions adopted. Major structural changes: (1) NEW §0.5 Mid-arc checkpoint — three buckets (proven / provisional / drifted). Reframes which patterns are settled science vs still evolving. (2) NEW §3.6 Bento eligibility + cold-user wedge test — positive companion to §3.5 (what EARNS a bento, not just what doesn't). 2-question gate (wedge test + composition test). Honest failure mode noted: wedge for Today/Overview/Books was retrofit; only Customers had it discovered live. (3) NEW §3.7 Patterns by confidence — three-tier classification (locked / provisional / not-universal). Demoted from "universal" to "provisional or context-specific": 3-beat brief (only Customers full implementation), customer-names-in-cyan-italic (Customers only; Overview uses amber), sub-nav 9 anchors (Today has none; not universal), data-freshness ink (would imply false precision on Overview/Books/Customers single-snapshot data), data-empty="1" chip-collapse (Today single-row slots only by design). (4) §5 EXPANDED with amber taxonomy — 3-bucket classification (A: legitimate stakes / B: warn-partial-stale needing semantic --warn token / C: chrome-nav-decorative needing slate-or-cyan flip). Audit confirmed amber is in 11 source files used in all 3 buckets indiscriminately. Row 211 should be a taxonomy audit, NOT a blanket flip. (5) §6 CORRECTED fact-drift on sticky hero — was marked ✅ shipped in v1.5, actually REVERTED Phase 203.2 (Electron-specific bug not reproducible in headless Playwright). Status now ❌ open at Row 203c. (6) NEW §8.5 Implementation debt — render.js 209KB with Overview bento inside it is high-pain; duplicated bento CSS across 4 files is medium-pain; Today/Books bento module extraction is low-pain (tidy-bug, defer until next functional touch). (7) NEW §9.5 Bias checks before promoting a pattern — 6-item checklist (coverage / user-value / regression-risk / Sush-validation / universality / honesty) for the conflict-of-interest where Atlas writes both the doc AND the bentos. Convert §9.5 from earlier-draft confession to operational checklist. Net additions ~12KB. Critique-driven demotions made the doc more useful, not less ambitious. Follow-up rows proposed in phase queue: Row 211 (amber taxonomy audit · 2-3h) · Row 212 (polish-layer applicability audit + targeted propagation · 1-2h) · Row 213 (Overview bento extraction + bento-base.css shared chrome · 2-3h). Sush approves direction at next session kickoff.

11 · Quick cross-references

  • Phase queue: ~/.copilot/atlas-portfolio-phases.md — look for Phase 200+ "HELM Design Evolution"
  • Current theme tokens (B2 palette): styles/theme.css (:root block)
  • Story-shape source for current today-tab cards: src/today-tab.js
  • PAC reference theme: C:\ssClawy\pac-archive\src\renderer\src\shared\theme.css
  • PAC reference HTMLs: C:\ssClawy\pac-archive\ (5 mockup HTMLs from v0.2 cockpit)
  • Cosmos Atlas DNA (sparklines + per-card narrative): learning-docs/docs/reference/cosmos-philosophy.md
  • Standing rules: ~/.copilot/copilot-instructions.md (Rules #1–#7)