|
| 1 | +<!doctype html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="utf-8"> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 6 | + <title>Output Tab — Four-Act Narrative — Implementation Plan</title> |
| 7 | + <style> |
| 8 | + :root { |
| 9 | + --ink:#0f1115; --surface:#fff; --paper:#f6f7f9; --grey:#6b7280; --line:#e5e7eb; |
| 10 | + --cobalt:#2563eb; --electric:#1d4ed8; --good:#15803d; --warn:#b45309; --radius:12px; |
| 11 | + } |
| 12 | + * { box-sizing:border-box; } |
| 13 | + body { margin:0; background:var(--paper); color:var(--ink); |
| 14 | + font:16px/1.65 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif; -webkit-font-smoothing:antialiased; } |
| 15 | + .wrap { max-width:880px; margin:0 auto; padding:56px 24px 96px; } |
| 16 | + header.doc { border-left:4px solid var(--cobalt); padding:4px 0 4px 20px; margin-bottom:32px; } |
| 17 | + header.doc h1 { font-size:1.9rem; line-height:1.15; margin:0 0 10px; letter-spacing:-0.02em; } |
| 18 | + .meta { color:var(--grey); font-size:0.92rem; } |
| 19 | + .meta strong { color:var(--ink); } |
| 20 | + .callout { background:var(--surface); border:1px solid var(--line); border-left:4px solid var(--cobalt); |
| 21 | + border-radius:8px; padding:12px 18px; margin:16px 0; font-size:0.94rem; } |
| 22 | + .callout.warn { border-left-color:var(--warn); } |
| 23 | + h2 { font-size:1.3rem; margin:40px 0 12px; padding-bottom:8px; border-bottom:1px solid var(--line); letter-spacing:-0.01em; } |
| 24 | + h3 { font-size:1.02rem; margin:22px 0 8px; } |
| 25 | + p { margin:10px 0; } |
| 26 | + ul { padding-left:22px; } li { margin:5px 0; } |
| 27 | + code { background:var(--paper); border:1px solid var(--line); border-radius:5px; padding:1px 6px; |
| 28 | + font-size:0.84em; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; } |
| 29 | + .phase { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:6px 22px 18px; margin:16px 0; } |
| 30 | + .phase .ph-tag { display:inline-block; margin:16px 0 2px; font-weight:700; letter-spacing:.03em; color:var(--electric); font-size:.95rem; } |
| 31 | + .task { border-top:1px solid var(--line); padding:12px 0; } |
| 32 | + .task:first-of-type { border-top:none; } |
| 33 | + .task .t-name { font-weight:650; } |
| 34 | + .task .files { color:var(--grey); font-size:.85rem; margin-top:3px; } |
| 35 | + .task .files code { font-size:.8em; } |
| 36 | + .task .what { margin-top:4px; font-size:.94rem; } |
| 37 | + .pill { display:inline-block; font-size:.72rem; font-weight:700; padding:2px 8px; border-radius:999px; |
| 38 | + border:1px solid var(--line); color:var(--grey); margin-right:6px; } |
| 39 | + .pill.new { color:var(--good); border-color:#bbf7d0; background:#f0fdf4; } |
| 40 | + .pill.mod { color:var(--warn); border-color:#fde68a; background:#fffbeb; } |
| 41 | + footer { margin-top:48px; color:var(--grey); font-size:.85rem; border-top:1px solid var(--line); padding-top:16px; } |
| 42 | + </style> |
| 43 | +</head> |
| 44 | +<body> |
| 45 | +<div class="wrap"> |
| 46 | + |
| 47 | + <header class="doc"> |
| 48 | + <h1>Output Tab — Four-Act Narrative</h1> |
| 49 | + <div class="meta"> |
| 50 | + <strong>Implementation plan</strong> · Pillar A · 2026-06-16 · branch <code>feat/output-tab-four-acts</code><br> |
| 51 | + Overview for review. The exact step-by-step code (TDD steps, commands, commits) lives in the companion <code>.md</code>. |
| 52 | + </div> |
| 53 | + </header> |
| 54 | + |
| 55 | + <div class="callout"> |
| 56 | + <strong>Goal.</strong> 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. |
| 57 | + </div> |
| 58 | + |
| 59 | + <h2>Architecture</h2> |
| 60 | + <p>Keep the existing <code>#t0</code>–<code>#t27</code> panels, their render functions, and <code>show(n)</code> behavior. Add a pure, unit-tested <code>output-acts.js</code> 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 <code>show(n)</code> also highlight the owning act and render its secondary row. No <code>background.js</code> / message-contract changes.</p> |
| 61 | + |
| 62 | + <div class="callout"> |
| 63 | + <strong>Why this is lower-risk than a rewrite</strong> (confirmed by reading the code): |
| 64 | + <ul> |
| 65 | + <li><strong>Slugs already exist</strong> (<code>TAB_SLUGS</code>) and <code>show()</code> already writes the hash + per-repo recall — so deep links and restore <em>already work</em>; the model just adds "which act owns this tab."</li> |
| 66 | + <li><strong>Lens labeling already exists</strong> — per-tab BEST-FOR / SKIP-IF / COST tooltips + the "?" guide + Deep-Dive staged progress. Mostly a matter of <em>surfacing</em> under Go Deeper, not new work.</li> |
| 67 | + <li>The nav is one block + one click handler — swapping flat→two-tier is contained.</li> |
| 68 | + </ul> |
| 69 | + </div> |
| 70 | + <div class="callout warn"> |
| 71 | + <strong>One coupling fixed:</strong> <code>show()</code> currently toggles panels by DOM index (<code>idx === n</code>), relying on panel order matching tab number. Task 4 switches to selecting by id (<code>#t{n}</code>) so it stays correct regardless of order. |
| 72 | + </div> |
| 73 | + |
| 74 | + <h2>The four acts (tab grouping)</h2> |
| 75 | + <ul> |
| 76 | + <li><strong>Decide</strong> — Verdict (the landing; decision control moves to the top here)</li> |
| 77 | + <li><strong>Understand</strong> — ELI5, Technical, Use Cases, Skip If, Enables, Pros/Cons, Red Flags, Alternatives, Health, Tech Stack</li> |
| 78 | + <li><strong>Go Deeper</strong> — Deep Dive, Canvas, Systems, Ideate, Prioritize, SKTPG, Docs Quality, Maintenance, License, Since Last Scan</li> |
| 79 | + <li><strong>Act</strong> — Fits MY Stack, Similar, Versus, Synergies, Connections, Combine, Ask (Save/Share stay in the header)</li> |
| 80 | + </ul> |
| 81 | + <p class="meta">All 28 indices map to exactly one act (verified by a unit test).</p> |
| 82 | + |
| 83 | + <h2>Tasks</h2> |
| 84 | + |
| 85 | + <div class="phase"> |
| 86 | + <span class="ph-tag">Phase 1 — Foundation</span> |
| 87 | + <div class="task"> |
| 88 | + <div class="t-name">Task 1 · Pure act model <span class="pill new">create</span></div> |
| 89 | + <div class="files"><code>output-acts.js</code> + <code>tests/output-acts.test.js</code></div> |
| 90 | + <div class="what">Full TDD: <code>ACTS</code>, <code>TAB_LABELS</code>, <code>actForTab()</code>, <code>tabsForAct()</code>, <code>ACT_ORDER</code>. Tests assert every index 0–27 is covered exactly once, plus helper correctness.</div> |
| 91 | + </div> |
| 92 | + </div> |
| 93 | + |
| 94 | + <div class="phase"> |
| 95 | + <span class="ph-tag">Phase 2 — Two-tier nav</span> |
| 96 | + <div class="task"> |
| 97 | + <div class="t-name">Task 2 · Nav containers + styles <span class="pill mod">modify</span></div> |
| 98 | + <div class="files"><code>output-tab.html</code></div> |
| 99 | + <div class="what">Replace the flat <code>.tab-nav</code> + dropdown menus with two containers (<code>#act-nav</code>, <code>#act-subnav</code>) and Mono-Ink styles (secondary row reuses <code>.tab-btn</code>).</div> |
| 100 | + </div> |
| 101 | + <div class="task"> |
| 102 | + <div class="t-name">Task 3 · Render the nav from the model <span class="pill mod">modify</span></div> |
| 103 | + <div class="files"><code>output-tab.js</code></div> |
| 104 | + <div class="what">Import the model; <code>renderActNav()</code> (primary acts) + <code>renderSubNav(actId)</code> (active act's tabs). Buttons keep <code>data-tab</code> so the existing show() path is reused.</div> |
| 105 | + </div> |
| 106 | + </div> |
| 107 | + |
| 108 | + <div class="phase"> |
| 109 | + <span class="ph-tag">Phase 3 — Routing</span> |
| 110 | + <div class="task"> |
| 111 | + <div class="t-name">Task 4 · show() selects by id + tracks the act <span class="pill mod">modify</span></div> |
| 112 | + <div class="files"><code>output-tab.js</code></div> |
| 113 | + <div class="what">Panels by <code>#t{n}</code>; set the active act button + render/mark its secondary row; hash + per-repo recall kept verbatim.</div> |
| 114 | + </div> |
| 115 | + <div class="task"> |
| 116 | + <div class="t-name">Task 5 · Two-tier click handling + tooltips <span class="pill mod">modify</span></div> |
| 117 | + <div class="files"><code>output-tab.js</code></div> |
| 118 | + <div class="what">Act click → show its first tab; subnav click → show(n). Remove the old dropdown handlers; re-point the explainer tooltips at the persistent <code>#act-subnav</code> (delegated, survives re-renders).</div> |
| 119 | + </div> |
| 120 | + <div class="task"> |
| 121 | + <div class="t-name">Task 6 · Deep-link/restore order <span class="pill mod">modify if needed</span></div> |
| 122 | + <div class="files"><code>output-tab.js</code></div> |
| 123 | + <div class="what">Ensure <code>renderActNav()</code> runs before the initial hash/recall route resolves; show() handles the rest.</div> |
| 124 | + </div> |
| 125 | + </div> |
| 126 | + |
| 127 | + <div class="phase"> |
| 128 | + <span class="ph-tag">Phase 4 — Targeted UX fixes</span> |
| 129 | + <div class="task"> |
| 130 | + <div class="t-name">Task 7 · Decision control to the top of Decide <span class="pill mod">modify</span></div> |
| 131 | + <div class="files"><code>output-tab.js</code>, <code>output-tab.html</code></div> |
| 132 | + <div class="what">Re-anchor the Adopt/Trial/Hold/Reject block after the fit chip + bottom line (was buried at the bottom). Internals unchanged.</div> |
| 133 | + </div> |
| 134 | + <div class="task"> |
| 135 | + <div class="t-name">Task 8 · Highlights anchor, not cross-navigate <span class="pill mod">modify</span></div> |
| 136 | + <div class="files"><code>output-tab.js</code> (<code>renderHighlights</code>)</div> |
| 137 | + <div class="what">A highlight click switches to its section and scrolls it into view (reduced-motion aware) instead of silently swapping context.</div> |
| 138 | + </div> |
| 139 | + <div class="task"> |
| 140 | + <div class="t-name">Task 9 · Previews jump to canonical (dedupe) <span class="pill mod">modify</span></div> |
| 141 | + <div class="files"><code>output-tab.js</code></div> |
| 142 | + <div class="what">Ensure each Verdict preview (tech stack, top flags) has a jump to its full section (15, 8). Previews stay — one source of truth.</div> |
| 143 | + </div> |
| 144 | + <div class="task"> |
| 145 | + <div class="t-name">Task 10 · "Run all lenses" in the Go-Deeper subnav <span class="pill mod">modify</span></div> |
| 146 | + <div class="files"><code>output-tab.js</code> (<code>renderSubNav</code>)</div> |
| 147 | + <div class="what">Relocate the run-all control (from the removed Lenses dropdown) into the Go-Deeper secondary row.</div> |
| 148 | + </div> |
| 149 | + </div> |
| 150 | + |
| 151 | + <div class="phase"> |
| 152 | + <span class="ph-tag">Phase 5 — Folded-in journey win</span> |
| 153 | + <div class="task"> |
| 154 | + <div class="t-name">Task 11 · Circular library ↔ output nav <span class="pill mod">modify</span></div> |
| 155 | + <div class="files"><code>output-tab.js</code>, <code>library.js</code></div> |
| 156 | + <div class="what">One clear, reversible path each way (focus/reuse an existing tab rather than orphaning new ones).</div> |
| 157 | + </div> |
| 158 | + </div> |
| 159 | + |
| 160 | + <div class="phase"> |
| 161 | + <span class="ph-tag">Phase 6 — Verification</span> |
| 162 | + <div class="task"> |
| 163 | + <div class="t-name">Task 12 · Full pass</div> |
| 164 | + <div class="what"><code>vitest run</code> (857 + 5 new) · <code>eslint .</code> 0 errors · <code>check:html</code> · <code>node --check</code> · Playwright screenshots at 320/768/1024/1440 + deep-link, keyboard, reduced-motion, a11y checks.</div> |
| 165 | + </div> |
| 166 | + </div> |
| 167 | + |
| 168 | + <h2>Spec coverage & honest gaps</h2> |
| 169 | + <ul> |
| 170 | + <li>28 destinations → four acts: Tasks 1–5. Decision to top: Task 7. Dedupe/jumps: Task 9. Highlights anchor: Task 8.</li> |
| 171 | + <li>Deep links + per-repo recall preserved (slugs unchanged): Tasks 4, 6. Keyboard nav preserved; verified in Task 12.</li> |
| 172 | + <li>Circular nav (folded-in B win): Task 11.</li> |
| 173 | + <li><strong>Partial vs spec:</strong> "live progress for every lens" is real for Deep Dive but Maintenance/Docs only show a thinking state — richer per-lens progress needs <code>background.js</code> streaming, which the spec puts out of scope. <strong>Deliberate follow-up.</strong></li> |
| 174 | + </ul> |
| 175 | + |
| 176 | + <h2>Out of scope (per spec)</h2> |
| 177 | + <p>Gamification/juice (Pillar 3), settings redesign, new analysis features, rewriting section internals or the analysis pipeline.</p> |
| 178 | + |
| 179 | + <footer>RepoLens · Pillar A implementation plan · review, then execute task-by-task (subagent-driven or inline).</footer> |
| 180 | + |
| 181 | +</div> |
| 182 | +</body> |
| 183 | +</html> |
0 commit comments