Atlas HELM — Design Philosophy (Living Doc)¶
🔴 Status: v2.0 · set 2026-05-29 (session
340d5f53Phase 210 mid-arc checkpoint, after the 4-bento arc landed in sessions386fd1f6/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.jsACT 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 inssp-book.js(61KB). Overview bento lives inrender.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-freshnessink anddata-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)¶
- Cold-user wedge test: Does this tab answer a question DIFFERENT from every other already-bento'd tab?
- Today = "what do I do RIGHT NOW?"
- Overview = "how is my whole book shaped?"
- Books (per SSP) = "how is THIS one person's book shaped?"
- Customers = "WHICH customers right now?" (every card surfaces NAMED individuals — wedge that prevented this being a Books-clone)
-
If the new tab's question collapses to one of the above, it's duplication. Polish the existing tab instead.
-
Composition test: Does the tab have 5+ distinct stories that want differently-sized real estate?
- 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").
- 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)¶
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.
- Sticky hero column —
position: stickyon 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. - 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).
- 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.
- "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).
- 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.
- 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: literalgrid-column/row spanoverride ongrid-template-areasslots cascades layout bugs and breaks bento composition (§3). Inline drawer preserves layout integrity. Literal 2×2 deferred to Phase 207b if wanted. - 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-haloadds subtle cyan outline +--cyan-glowbox-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). - Quiet-day creative space — ≥3 cards empty → grid collapses into 1 "// HORIZON CLEAR" panel with "go deep on X" suggestion. Queued.
- "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.
- 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:
- Designer control. Path A gives us deliberate composition. Each card has a NAMED HOME.
- 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.mjsetc. - 🚨 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:
- 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."
- 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.
- Regression-risk test — If I propagate this, what could break? If the answer is "nothing visible, just code-paths" → it's tidy-bug, defer.
- 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."
- 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.
- 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(:rootblock) - 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)