Pillar 3 — The Knowledge Game (library + corkboard + canvas: smooth, juicy, addictive — mastery + discovery + collection + crafting, to "plug pieces together and think in new ways")
+
+
+
+
Problem
+
The output tab is information-rich and genuinely good — the problem is purely presentation and flow. From a current-state audit:
+
+
28 flat tabs. Verdict, ELI5, Technical, Use-Cases, Skip-If, Enables, Pros-Cons, Alternatives, Health, Red-Flags, Tech-Stack, + Deep-Dive/Systems/Ideate/Prioritize/SKTPG, + Docs/Maintenance/License/Diff/Fits-Stack, + Similar/Versus/Synergies/Connections/Combine, + Ask/Canvas. No sense of what to read first or in what order.
+
No narrative, weak wayfinding. The Verdict landing tries to be everything (11 stacked sections, flat hierarchy); the Decision control (Adopt/Trial/Hold/Reject) is buried ~2000px down; key info is previewed on Verdict but fully rendered elsewhere with no jump links; fit verdict, red flags, and tech stack each render in two places.
+
Opaque "lenses," hidden prerequisites. "Lens" is never explained; Canvas silently needs Deep Dive first; library tabs need 2+ scans; multi-stage runs give no progress/ETA.
+
+
+
Goals
+
+
Reorganize the output tab into a four-act narrative: Decide → Understand → Go Deeper → Act.
+
Add real hierarchy, wayfinding (preview → jump), and lens clarity (label + prerequisite + time estimate + live progress).
+
Preserve every piece of information, all functionality, all deep links, and per-repo position recall. Nothing is removed.
+
+
+
Non-goals
+
+
No rewrite of individual section internals or the analysis pipeline (background.js runners, prompts, parsers stay as-is).
+
No gamification / motion juice (that is Pillar 3).
+
No settings redesign, no new analysis features.
+
One folded-in exception: the small circular library↔output navigation fix (central to "flow" and cheap).
+
+
+
Structure: chosen approach
+
Four Acts, two-tier navigation. Four primary acts as the top-level nav; each act opens its own focused, bounded view containing its grouped sections. The user always knows which act they are in; never an endless scroll. Keyboard navigation preserved. Cleanest fit for the zero-build codebase.
+
+
The four acts — complete section mapping
+
Default = shown immediately after a scan. On-demand = user triggers an AI run.
+
+
+ ① DECIDE
+
"should I use this, and what do I do about it?" — the landing
Extract a pure act-model module (e.g. output-acts.js), no DOM/network, exporting: ACTS, sectionToAct(), routeForHash() / hashForRoute(), LEGACY_SLUG_MAP + resolveLegacySlug(), and keyboardMap. output-tab.js consumes it to render the act shell and route; section render functions stay as-is and mount into act containers. Routing/grouping logic becomes unit-testable independent of the DOM.
+
+
Constraints honored
+
+
Zero-build, zero-dep, vanilla ES modules. Reorganize output-tab.html + output-tab.js; no framework/bundler/deps.
+
Mono Ink brand, stop-slop/human voice, no emoji on product surfaces, motion behind prefers-reduced-motion (reuse --dur-*/--ease-*).
+
No DOM test environment — pure logic to vitest; DOM glue via node --check + a *-demo.html harness.
vitest (pure): act-model completeness (every slug maps to exactly one act/section), legacy-slug resolution, hash round-trip, keyboard map.
+
node --check on glue.
+
Visual: an output-tab demo harness; Playwright screenshots at 320 / 768 / 1024 / 1440; reduced-motion; accessibility (keyboard, focus, contrast).
+
Existing suite green; eslint . 0 errors; HTML parse gate passes.
+
+
+
Migration / rollout
+
+
Build the pure act-model module + act shell + routing (tested first).
+
Move sections into acts group-by-group, keeping tests green.
+
Add the legacy-hash redirect so existing #slug links resolve.
+
Preserve auto-save, lens runners, and all message contracts (front-end only).
+
+
+
Acceptance criteria
+
+
All ~28 destinations reachable, grouped into the four acts.
+
Decision control in Decide, visible without scrolling.
+
No element rendered twice as a source of truth — previews jump to the canonical section.
+
Every lens shows what-it-does + prerequisite + time estimate + live progress.
+
Old deep links resolve; keyboard nav works; per-repo recall works.
+
Verdict landing scannable with clear hierarchy.
+
All existing tests pass + new act-model tests; eslint . 0 errors; HTML gate passes.
+
+
+
+ Resolved decisions: Four Acts (two-tier nav) · decision control → top of Decide · library-relational features → Act (gamified depth deferred to Pillar 3) · circular library↔output nav folded into A.
+
+
+
+
+
+
+
diff --git a/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md
new file mode 100644
index 0000000..dc492e0
--- /dev/null
+++ b/docs/superpowers/specs/2026-06-16-output-tab-four-acts-design.md
@@ -0,0 +1,153 @@
+# Output Tab — Four-Act Narrative (Pillar A)
+
+- **Date:** 2026-06-16
+- **Status:** Approved (design) — pending implementation plan
+- **Surface:** the extension's analysis/verdict view (`output-tab.html` + `output-tab.js`)
+- **Part of:** a 3-pillar "make the app simpler to use and digest" effort
+ - **Pillar A — Output-tab narrative** ← *this spec, building first*
+ - **Pillar B — Cross-app journey** (circular nav, entry points, save/discovery clarity)
+ - **Pillar 3 — The Knowledge Game** (library + corkboard + canvas made smooth, juicy, and addictive; mastery + discovery + collection + crafting, in service of "plug pieces together and think in new ways")
+
+## Problem
+
+The output tab is information-rich and genuinely good — the problem is purely presentation and flow. From a current-state audit:
+
+1. **28 flat tabs.** Verdict, ELI5, Technical, Use-Cases, Skip-If, Enables, Pros-Cons, Alternatives, Health, Red-Flags, Tech-Stack, + Deep-Dive/Systems/Ideate/Prioritize/SKTPG, + Docs/Maintenance/License/Diff/Fits-Stack, + Similar/Versus/Synergies/Connections/Combine, + Ask/Canvas. No sense of what to read first or in what order.
+2. **No narrative, weak wayfinding.** The Verdict landing tries to be everything (11 stacked sections, flat hierarchy); the **Decision control (Adopt/Trial/Hold/Reject) is buried ~2000px down**; key info is *previewed* on Verdict but *fully* rendered elsewhere with no jump links; fit verdict, red flags, and tech stack each render in two places.
+3. **Opaque "lenses," hidden prerequisites.** "Lens" is never explained; Canvas silently needs Deep Dive first; library tabs need 2+ scans; multi-stage runs give no progress/ETA.
+
+## Goals
+
+- Reorganize the output tab into a **four-act narrative**: **Decide → Understand → Go Deeper → Act**.
+- Add real hierarchy, wayfinding (preview → jump), and lens clarity (label + prerequisite + time estimate + live progress).
+- **Preserve every piece of information**, all functionality, all deep links, and per-repo position recall. Nothing is removed.
+
+## Non-goals
+
+- No rewrite of individual section internals or the analysis pipeline (`background.js` runners, prompts, parsers stay as-is).
+- No gamification / motion juice (that is Pillar 3).
+- No settings redesign, no new analysis features.
+- **One folded-in exception:** the small circular library↔output navigation fix (it is central to "flow" and cheap).
+
+## Structure: chosen approach
+
+**Four Acts, two-tier navigation.** Four primary acts as the top-level nav; each act opens its own focused, bounded view containing its grouped sections. The user always knows which act they are in; never an endless scroll. Keyboard navigation preserved. Cleanest fit for the zero-build codebase.
+
+## The four acts — complete section mapping
+
+Every current destination keeps a home. "Default" = shown immediately after a scan; "On-demand" = user triggers an AI run.
+
+### ① DECIDE — *"should I use this, and what do I do about it?"* (the landing)
+
+| Element | Default/On-demand | Notes |
+|---|---|---|
+| Fit verdict (level + label + why) | Default | Anchored at top |
+| Bottom line (one-liner) | Default | |
+| **Decision control** (Adopt/Trial/Hold/Reject + note) | Default | **Moved to the top** (was buried at page bottom) |
+| At-a-glance facts (health score, stars/license/language, pros/cons/flag counts) | Default | Compact summary row |
+| Top red flags (up to 3) | Default | Distinct "warning" treatment; link to full list in Understand |
+| Where-to-start cards (`start_here`) | Default (if present) | |
+| Since-last-scan diff callout | Default (if prior scan) | fit/health change |
+| "Worth noting" highlights | Default | Now **anchor** to their home section (no context-thrash navigation) |
+
+### ② UNDERSTAND — *deep reading; all pre-computed, no waiting*
+
+| Element | Default/On-demand | Notes |
+|---|---|---|
+| ELI5 (+ analogies) | Default | |
+| Technical | Default | |
+| Use Cases (4-grid) | Default | |
+| Skip If (4-grid) | Default | |
+| Enables | Default | |
+| Pros / Cons (full) | Default | Verdict shows counts → jump here |
+| Red Flags (full list) | Default | Decide shows top 3 → jump to the canonical full list here |
+| Alternatives | Default | |
+| Health (full: 4 signals + summary) | Default | **Add metric explanations** (what each signal means) |
+| Tech Stack (full: built_with + key_dependencies) | Default | Verdict shows language chips → jump here |
+
+De-duplication rule: where Verdict shows a preview (fit, top flags, tech stack), the **full** version lives here and Verdict links to it. One source of truth per element.
+
+### ③ GO DEEPER — *on-demand lenses about THIS repo; each a labeled card*
+
+Each lens renders as a card with: **name · one-line "what it does" · prerequisite badge (if any) · time estimate · live stage progress.**
+
+| Lens | Prerequisite | Notes |
+|---|---|---|
+| Deep Dive (atoms → lineage → Feynman) | — | ~90s, 3 stages with progress |
+| Canvas / Blueprint | **Needs Deep Dive** | prereq badge shown |
+| Systems (PDCA/DMAIC/Loops/TOC) | — | framework chips |
+| Ideate (SCAMPER/Lateral/TRIZ/Morph) | — | framework chips |
+| Prioritize (Eisenhower/Pareto) | — | framework chips |
+| SKTPG | — | auto-run by default (toggle) |
+| Docs Quality | — | |
+| Maintenance | — | can be slow on large repos; show progress |
+| License | library context | |
+| Since Last Scan | prior scan | |
+
+### ④ ACT — *do something with it*
+
+| Element | Notes |
+|---|---|
+| Save | clear saved-state feedback |
+| Ask this repo | requires a completed scan — state this up front |
+| Share | |
+| **Against your library:** Similar · Versus · Synergies · Connections · Combine · Fits-My-Stack | Honest "needs N scans" unlock states. The **deeper, gamified treatment of these is Pillar 3**; here they get a clean home + honest states. |
+
+## Navigation & interaction
+
+- **Persistent header** — repo name, meta pills (stars/license/language), fit chip — always visible across acts.
+- **Primary nav** — four acts (`DECIDE · Understand · Go Deeper · Act`). Default landing = **Decide**.
+- **Secondary nav within an act** — for Understand, a section list with hierarchy; for Go Deeper / Act, a grid of labeled cards.
+- **Keyboard** — `1`–`4` select acts; within-act secondary keys for sections; preserve existing `r` (rerun), `f` (fresh), `l` (library), `o` (open source).
+- **Deep-linking** — new hash scheme (`#decide`, `#understand/health`, `#deeper/deep-dive`, `#act/versus`). A **legacy slug map** translates every old `#slug` to its new act/section so existing links and bookmarks still resolve.
+- **Per-repo recall** — extend the stored position (`repolens_tab_`) to remember act + section.
+
+## Component design (for isolation + testability)
+
+Extract a **pure act-model module** (e.g. `output-acts.js`), no DOM/network, exporting:
+
+- `ACTS` — the ordered acts and the sections grouped under each.
+- `sectionToAct(sectionId)` — which act owns a section.
+- `routeForHash(hash)` / `hashForRoute(act, section)` — round-trippable hash routing.
+- `LEGACY_SLUG_MAP` + `resolveLegacySlug(slug)` — old `#slug` → new route.
+- `keyboardMap` — key → act/section.
+
+`output-tab.js` consumes this module to render the act shell and route; section render functions stay as-is and mount into act containers. This keeps the routing/grouping logic unit-testable independently of the DOM.
+
+## Constraints honored
+
+- **Zero-build, zero-dep, vanilla ES modules.** Reorganize `output-tab.html` + `output-tab.js`; no framework, no bundler, no new runtime deps.
+- **Brand = Mono Ink**, stop-slop/human voice, **no emoji on product surfaces**, motion behind `prefers-reduced-motion` (reuse `--dur-*` / `--ease-*` tokens).
+- **No DOM test environment** — pure logic to vitest; DOM/SW glue via `node --check` + a `*-demo.html` harness.
+- **No `background.js` contract changes** — message types (`DEEP_DIVE`, `SKTPG`, `MAINTENANCE`, …) are unchanged; this is a front-end reorganization only.
+
+## Testing
+
+- **vitest (pure):** act-model completeness (every current slug maps to exactly one act/section), legacy-slug resolution, hash round-trip, keyboard map.
+- **`node --check`** on `output-tab.js` / HTML glue.
+- **Visual:** an `output-tab` demo harness (`*-demo.html`); Playwright screenshots at 320 / 768 / 1024 / 1440; reduced-motion behavior; accessibility (keyboard nav, focus order, contrast).
+- Existing suite stays green; `eslint .` 0 errors; HTML parse gate passes.
+
+## Migration / rollout
+
+1. Build the pure act-model module + the act shell + routing (tested first).
+2. Move sections into acts group-by-group, keeping tests green at each step.
+3. Add the legacy-hash redirect so existing `#slug` links resolve.
+4. Preserve auto-save, lens runners, and all message contracts (front-end only).
+
+## Acceptance criteria
+
+- [ ] All ~28 destinations reachable, grouped into the four acts.
+- [ ] Decision control lives in Decide, visible without scrolling.
+- [ ] No element rendered twice as a source of truth — previews jump to the canonical section.
+- [ ] Every lens shows what-it-does + prerequisite + time estimate + live progress.
+- [ ] Old deep links resolve via the legacy map; keyboard nav works; per-repo recall works.
+- [ ] Verdict landing is scannable with clear hierarchy.
+- [ ] All existing tests pass + new act-model tests; `eslint .` 0 errors; HTML gate passes.
+
+## Resolved decisions
+
+- Structure = Four Acts, two-tier nav.
+- Decision control → top of Decide.
+- Library-relational features → Act (deeper gamified treatment deferred to Pillar 3).
+- Circular library↔output nav fix folded into A.
From 2a4fce3395394bde23b23a40493240973e75eade Mon Sep 17 00:00:00 2001
From: ares <285551516+New1Direction@users.noreply.github.com>
Date: Tue, 16 Jun 2026 18:30:45 -0700
Subject: [PATCH 02/13] docs(plan): output-tab Four-Act narrative
implementation plan
Bite-sized TDD plan: pure output-acts.js model (full code + tests),
two-tier nav, act-aware show(), then targeted UX fixes (decision-to-top,
highlights anchor, previews jump, run-all relocation) + circular library
nav. Keeps all panels/render/show + deep links; no background.js changes.
Includes a rendered HTML overview for review.
---
.../2026-06-16-output-tab-four-acts.html | 183 ++++++
.../plans/2026-06-16-output-tab-four-acts.md | 577 ++++++++++++++++++
2 files changed, 760 insertions(+)
create mode 100644 docs/superpowers/plans/2026-06-16-output-tab-four-acts.html
create mode 100644 docs/superpowers/plans/2026-06-16-output-tab-four-acts.md
diff --git a/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html
new file mode 100644
index 0000000..8036db7
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.html
@@ -0,0 +1,183 @@
+
+
+
+
+
+ Output Tab — Four-Act Narrative — Implementation Plan
+
+
+
+
+
+
+
Output Tab — Four-Act Narrative
+
+ Implementation plan · Pillar A · 2026-06-16 · branch feat/output-tab-four-acts
+ Overview for review. The exact step-by-step code (TDD steps, commands, commits) lives in the companion .md.
+
+
+
+
+ Goal. Restructure the flat 28-tab nav into a four-act narrative (Decide → Understand → Go Deeper → Act) — keeping every panel, render function, and deep link — via a pure act-model module and a two-tier nav, then a few targeted UX fixes.
+
+
+
Architecture
+
Keep the existing #t0–#t27 panels, their render functions, and show(n) behavior. Add a pure, unit-tested output-acts.js that groups tab indices into four ordered acts. Replace the flat nav markup with a two-tier nav (primary act row + a secondary row showing only the active act's tabs), generated from the model. Make show(n) also highlight the owning act and render its secondary row. No background.js / message-contract changes.
+
+
+ Why this is lower-risk than a rewrite (confirmed by reading the code):
+
+
Slugs already exist (TAB_SLUGS) and show() already writes the hash + per-repo recall — so deep links and restore already work; the model just adds "which act owns this tab."
+
Lens labeling already exists — per-tab BEST-FOR / SKIP-IF / COST tooltips + the "?" guide + Deep-Dive staged progress. Mostly a matter of surfacing under Go Deeper, not new work.
+
The nav is one block + one click handler — swapping flat→two-tier is contained.
+
+
+
+ One coupling fixed:show() currently toggles panels by DOM index (idx === n), relying on panel order matching tab number. Task 4 switches to selecting by id (#t{n}) so it stays correct regardless of order.
+
+
+
The four acts (tab grouping)
+
+
Decide — Verdict (the landing; decision control moves to the top here)
+
Understand — ELI5, Technical, Use Cases, Skip If, Enables, Pros/Cons, Red Flags, Alternatives, Health, Tech Stack
+
Go Deeper — Deep Dive, Canvas, Systems, Ideate, Prioritize, SKTPG, Docs Quality, Maintenance, License, Since Last Scan
+
Act — Fits MY Stack, Similar, Versus, Synergies, Connections, Combine, Ask (Save/Share stay in the header)
+
+
All 28 indices map to exactly one act (verified by a unit test).
+
+
Tasks
+
+
+ Phase 1 — Foundation
+
+
Task 1 · Pure act model create
+
output-acts.js + tests/output-acts.test.js
+
Full TDD: ACTS, TAB_LABELS, actForTab(), tabsForAct(), ACT_ORDER. Tests assert every index 0–27 is covered exactly once, plus helper correctness.
+
+
+
+
+ Phase 2 — Two-tier nav
+
+
Task 2 · Nav containers + styles modify
+
output-tab.html
+
Replace the flat .tab-nav + dropdown menus with two containers (#act-nav, #act-subnav) and Mono-Ink styles (secondary row reuses .tab-btn).
+
+
+
Task 3 · Render the nav from the model modify
+
output-tab.js
+
Import the model; renderActNav() (primary acts) + renderSubNav(actId) (active act's tabs). Buttons keep data-tab so the existing show() path is reused.
+
+
+
+
+ Phase 3 — Routing
+
+
Task 4 · show() selects by id + tracks the act modify
+
output-tab.js
+
Panels by #t{n}; set the active act button + render/mark its secondary row; hash + per-repo recall kept verbatim.
Act click → show its first tab; subnav click → show(n). Remove the old dropdown handlers; re-point the explainer tooltips at the persistent #act-subnav (delegated, survives re-renders).
+
+
+
Task 6 · Deep-link/restore order modify if needed
+
output-tab.js
+
Ensure renderActNav() runs before the initial hash/recall route resolves; show() handles the rest.
+
+
+
+
+ Phase 4 — Targeted UX fixes
+
+
Task 7 · Decision control to the top of Decide modify
+
output-tab.js, output-tab.html
+
Re-anchor the Adopt/Trial/Hold/Reject block after the fit chip + bottom line (was buried at the bottom). Internals unchanged.
+
+
+
Task 8 · Highlights anchor, not cross-navigate modify
+
output-tab.js (renderHighlights)
+
A highlight click switches to its section and scrolls it into view (reduced-motion aware) instead of silently swapping context.
+
+
+
Task 9 · Previews jump to canonical (dedupe) modify
+
output-tab.js
+
Ensure each Verdict preview (tech stack, top flags) has a jump to its full section (15, 8). Previews stay — one source of truth.
+
+
+
Task 10 · "Run all lenses" in the Go-Deeper subnav modify
+
output-tab.js (renderSubNav)
+
Relocate the run-all control (from the removed Lenses dropdown) into the Go-Deeper secondary row.
+
+
+
+
+ Phase 5 — Folded-in journey win
+
+
Task 11 · Circular library ↔ output nav modify
+
output-tab.js, library.js
+
One clear, reversible path each way (focus/reuse an existing tab rather than orphaning new ones).
28 destinations → four acts: Tasks 1–5. Decision to top: Task 7. Dedupe/jumps: Task 9. Highlights anchor: Task 8.
+
Deep links + per-repo recall preserved (slugs unchanged): Tasks 4, 6. Keyboard nav preserved; verified in Task 12.
+
Circular nav (folded-in B win): Task 11.
+
Partial vs spec: "live progress for every lens" is real for Deep Dive but Maintenance/Docs only show a thinking state — richer per-lens progress needs background.js streaming, which the spec puts out of scope. Deliberate follow-up.
+
+
+
Out of scope (per spec)
+
Gamification/juice (Pillar 3), settings redesign, new analysis features, rewriting section internals or the analysis pipeline.
+
+
+
+
+
+
diff --git a/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md
new file mode 100644
index 0000000..45a4172
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-16-output-tab-four-acts.md
@@ -0,0 +1,577 @@
+# Output Tab — Four-Act Narrative — Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Restructure the output tab's flat 28-tab nav into a four-act narrative (Decide → Understand → Go Deeper → Act) — keeping every panel, render function, and deep link — by introducing a pure act-model module and a two-tier nav, then a few targeted UX fixes.
+
+**Architecture:** Keep the existing `#t0`–`#t27` panels, their render functions, and `show(n)` **unchanged in behavior**. Add a pure, unit-tested `output-acts.js` that groups tab indices into four ordered acts. Replace the flat `.tab-nav` markup with a two-tier nav (primary act row + a secondary row showing only the active act's tabs), generated from the act model. Make `show(n)` also highlight the owning act and render its secondary row. Layer on targeted UX fixes (decision-to-top, previews→jumps, highlights-anchor) as isolated tasks. No `background.js` / message-contract changes.
+
+**Tech Stack:** Vanilla ES modules (zero-build, no deps), Vitest (pure logic only — no DOM env), `node --check` for DOM glue, existing `*-demo.html` harness + Playwright for visual checks. Brand: Mono Ink, motion behind `prefers-reduced-motion` (`--dur-*`/`--ease-*` tokens already in `themes.css`).
+
+---
+
+## Why this is lower-risk than a rewrite
+
+Confirmed by reading the current code:
+- **Slugs already exist** (`TAB_SLUGS` in `output-tab.js:2200`) and `show()` already writes `#slug` + persists `repolens_tab_`. So existing deep links and per-repo recall **already work** — the act model only adds "which act owns this tab" on top.
+- **Lens labeling already exists** — `initScanTips()` (`output-tab.js:2257`) shows BEST-FOR / SKIP-IF / COST tooltips per tab, and the `?`-guide lists every lens with cost. Deep Dive already has staged progress (`ddProgressHtml`). So "label lenses" is mostly **surfacing what exists** under the Go-Deeper act, not new work.
+- The nav is a single `.tab-nav` block (`output-tab.html:845-885`) and one click handler (`output-tab.js:2231`). Swapping flat→two-tier is contained.
+
+⚠️ **One coupling to fix:** `show(n)` toggles panels via `forEach((c, idx) => ... idx === n)` (`output-tab.js:2212`) — it relies on `.tab-content` DOM order matching the tab index. Today that holds (`#t0`…`#t27` are in order). Task 6 changes this to select by id (`#t${n}`) so it stays correct regardless of DOM order.
+
+---
+
+## File Structure
+
+- **Create** `output-acts.js` — pure act model: `ACTS`, `TAB_LABELS`, `actForTab()`, `tabsForAct()`, `ACT_ORDER`. No DOM, no imports. One responsibility: the tab↔act grouping + labels.
+- **Create** `tests/output-acts.test.js` — completeness + helper tests.
+- **Modify** `output-tab.html` — replace the `.tab-nav` inner markup (845-885) with two-tier containers (`#act-nav`, `#act-subnav`); keep all `#t0`–`#t27` panels untouched.
+- **Modify** `output-tab.js` — import the act model; render the two-tier nav; make `show(n)` select panels by id and set the active act + secondary row; update the nav click handler.
+- **Modify** the verdict/decision render in `output-tab.js` (Task 8) — move decision control to the top.
+- **Modify** `renderHighlights` in `output-tab.js` (Task 10) — anchor instead of cross-navigate.
+
+---
+
+## Phase 1 — Foundation: the pure act model
+
+### Task 1: Create the act model
+
+**Files:**
+- Create: `output-acts.js`
+- Test: `tests/output-acts.test.js`
+
+- [ ] **Step 1: Write the failing test**
+
+```js
+// tests/output-acts.test.js
+import { describe, it, expect } from 'vitest';
+import { ACTS, ACT_ORDER, TAB_LABELS, actForTab, tabsForAct } from '../output-acts.js';
+
+describe('act model', () => {
+ it('orders the four acts', () => {
+ expect(ACT_ORDER).toEqual(['decide', 'understand', 'deeper', 'act']);
+ });
+
+ it('covers every tab index 0..27 exactly once', () => {
+ const all = ACTS.flatMap((a) => a.tabs).sort((x, y) => x - y);
+ expect(all).toEqual(Array.from({ length: 28 }, (_, i) => i));
+ expect(new Set(all).size).toBe(28); // no duplicates
+ });
+
+ it('maps a tab to its owning act', () => {
+ expect(actForTab(9)).toBe('decide');
+ expect(actForTab(7)).toBe('understand'); // Health
+ expect(actForTab(10)).toBe('deeper'); // Deep Dive
+ expect(actForTab(17)).toBe('act'); // Versus
+ expect(actForTab(99)).toBeNull();
+ });
+
+ it('lists tabs for an act in display order', () => {
+ expect(tabsForAct('decide')).toEqual([9]);
+ expect(tabsForAct('understand')[0]).toBe(0); // ELI5 leads
+ expect(tabsForAct('nope')).toEqual([]);
+ });
+
+ it('has a label for every tab it groups', () => {
+ for (const t of ACTS.flatMap((a) => a.tabs)) {
+ expect(typeof TAB_LABELS[t]).toBe('string');
+ expect(TAB_LABELS[t].length).toBeGreaterThan(0);
+ }
+ });
+});
+```
+
+- [ ] **Step 2: Run it and confirm it fails**
+
+Run: `npx vitest run tests/output-acts.test.js`
+Expected: FAIL — `Cannot find module '../output-acts.js'`.
+
+- [ ] **Step 3: Write the module**
+
+```js
+// output-acts.js
+// Pure act model for the output tab. Groups the existing tab indices (the #t0..#t27
+// panels) into four ordered "acts" — Decide, Understand, Go Deeper, Act — for a
+// two-tier nav. No DOM, no network, no imports: this is the testable contract the
+// nav rendering and show() build on. Tab indices and slugs are unchanged from the
+// existing TAB_SLUGS, so deep links and per-repo recall keep working.
+
+export const ACTS = [
+ { id: 'decide', label: 'Decide', tabs: [9] },
+ { id: 'understand', label: 'Understand', tabs: [0, 1, 2, 3, 4, 5, 8, 6, 7, 15] },
+ { id: 'deeper', label: 'Go Deeper', tabs: [10, 27, 11, 12, 13, 14, 21, 22, 23, 24] },
+ { id: 'act', label: 'Act', tabs: [25, 16, 17, 18, 19, 20, 26] },
+];
+
+export const ACT_ORDER = ACTS.map((a) => a.id);
+
+// Tab index → human label (mirrors the current nav button text; used to render
+// the secondary row from the model instead of hardcoded HTML).
+export const TAB_LABELS = {
+ 9: 'Verdict',
+ 0: 'ELI5', 1: 'Technical', 2: 'Use Cases', 3: 'Skip If', 4: 'Enables',
+ 5: 'Pros / Cons', 8: 'Red Flags', 6: 'Alternatives', 7: 'Health', 15: 'Tech Stack',
+ 10: 'Deep Dive', 27: 'Canvas', 11: 'Systems', 12: 'Ideate', 13: 'Prioritize',
+ 14: 'SKTPG', 21: 'Docs Quality', 22: 'Maintenance', 23: 'License', 24: 'Since Last Scan',
+ 25: 'Fits MY Stack?', 16: 'Similar', 17: 'Versus', 18: 'Synergies',
+ 19: 'Connections', 20: 'Combine', 26: 'Ask',
+};
+
+const ACT_BY_TAB = (() => {
+ const m = {};
+ for (const a of ACTS) for (const t of a.tabs) m[t] = a.id;
+ return m;
+})();
+
+/** @returns {string|null} the act id owning tab `n`, or null. */
+export function actForTab(n) {
+ return Object.prototype.hasOwnProperty.call(ACT_BY_TAB, n) ? ACT_BY_TAB[n] : null;
+}
+
+/** @returns {number[]} the tab indices in an act, in display order. */
+export function tabsForAct(id) {
+ const a = ACTS.find((x) => x.id === id);
+ return a ? a.tabs : [];
+}
+```
+
+- [ ] **Step 4: Run tests and confirm they pass**
+
+Run: `npx vitest run tests/output-acts.test.js`
+Expected: PASS (5 tests).
+
+- [ ] **Step 5: Lint the new module**
+
+Run: `npx eslint output-acts.js tests/output-acts.test.js`
+Expected: 0 errors.
+
+- [ ] **Step 6: Commit**
+
+```bash
+git add output-acts.js tests/output-acts.test.js
+git commit -m "feat(output): pure four-act model for the output tab"
+```
+
+---
+
+## Phase 2 — Two-tier nav
+
+### Task 2: Replace the flat nav markup with two-tier containers
+
+**Files:**
+- Modify: `output-tab.html:845-885` (the `.tab-nav` block)
+
+- [ ] **Step 1: Replace the markup**
+
+Replace the entire `
…
` block (current lines 845-885, the flat buttons + Lenses/Library menus) with two empty containers that `output-tab.js` will populate from the act model:
+
+```html
+
+
+
+```
+
+- [ ] **Step 2: Add the nav styles**
+
+Add to the `