|
| 1 | +--- |
| 2 | +name: lab |
| 3 | +category: core |
| 4 | +description: Use when designing or revamping a frontend section or whole page and you want to explore real-React variants in an isolated, dev-only lab before writing production code. Cook variants for one target at a time, lock the winner, watch an additive page assemble in /lab-view, then wire it properly. Forces real-stack previews (not throwaway HTML/Figma), desktop+mobile side by side, and a clean codebase with only the current target's scratch alive. |
| 5 | +--- |
| 6 | + |
| 7 | +# The Lab - variant-driven frontend design in the real stack |
| 8 | + |
| 9 | +Design-by-mockup lies. HTML comps and Figma frames never survive contact with the |
| 10 | +real component tree, the real responsive rules, or the real design tokens - so what |
| 11 | +the user approves is not what ships. The Lab fixes that: explore variants **in the |
| 12 | +real framework** (real components, real breakpoints) but **isolated from production**, |
| 13 | +build the page **additively** one locked target at a time, and only write production |
| 14 | +code once the whole assembled page is approved. |
| 15 | + |
| 16 | +## The Iron Laws |
| 17 | + |
| 18 | +``` |
| 19 | +1. ONE TARGET IN COOK |
| 20 | + Only the current target's variants exist as scratch code. Everything else is |
| 21 | + either a clean locked winner or not written yet. Never two targets in flight. |
| 22 | +
|
| 23 | +2. COOK EMPTIES ON LOCK |
| 24 | + The instant a target is locked, delete the losing variants and clear the cook. |
| 25 | + No variant graveyard. Git history is the backup if a loser is ever wanted back. |
| 26 | +
|
| 27 | +3. VIEW BEFORE CODE |
| 28 | + No production wiring until /lab-view (the whole assembled page) is approved. |
| 29 | + The lab is where decisions happen; production is where they get implemented. |
| 30 | +
|
| 31 | +4. SCAFFOLD IS THROWAWAY |
| 32 | + Scoped lab CSS, CDN fonts, and inline styles are prototype-only and NEVER ship. |
| 33 | + Final wiring re-implements with real design tokens + self-hosted fonts + proper |
| 34 | + folders. The lab buys speed of iteration, not shippable code. |
| 35 | +
|
| 36 | +5. DEV-ONLY |
| 37 | + Every lab route is gated by the framework's dev flag (e.g. import.meta.env.DEV). |
| 38 | + The lab must not exist in a production build. |
| 39 | +``` |
| 40 | + |
| 41 | +Violating the letter = violating the spirit. |
| 42 | + |
| 43 | +## The 3 moving pieces |
| 44 | + |
| 45 | +| Piece | What it is | |
| 46 | +|---|---| |
| 47 | +| **target** | The unit of work being refined. One section **or** one whole page - **never more than a page**. Bounds scope so the cook stays legible. | |
| 48 | +| **/lab-cook** | The kitchen. Renders **only the current target's variants**. Empties on lock. | |
| 49 | +| **/lab-view** | The connected additive page - every locked target stitched top-to-bottom. The realistic "this is the page" preview, before any production code. | |
| 50 | + |
| 51 | +Both routes share the same **site navbar** (so previews sit under realistic chrome) |
| 52 | +and a **toggleable mobile-view sidebar** (a ~390px phone frame mirroring the main |
| 53 | +preview), so desktop and mobile can be judged together on demand. |
| 54 | + |
| 55 | +## The harness layout (both routes) |
| 56 | + |
| 57 | +``` |
| 58 | +┌──────────────────────────────────────────────────┐ |
| 59 | +│ [lab navbar - plain, very low height] [☾/☀][▢] │ ← theme toggle · mobile-sidebar toggle |
| 60 | +├───────────────────────────────────────┬┄┄┄┄┄┄┄┄┄┄┄┤ |
| 61 | +│ ┌─ site navbar (shared) ────────────┐ ┊ mobile ┊ |
| 62 | +│ ├───────────────────────────────────┤ ┊ sidebar ┊ ← toggled on/off |
| 63 | +│ │ MAIN preview (desktop width) │ ┊ (~390px, ┊ from the navbar |
| 64 | +│ │ cook → current target variants │ ┊ mirrors ┊ |
| 65 | +│ │ view → full connected page │ ┊ main) ┊ |
| 66 | +│ └───────────────────────────────────┘ ┊ ┊ |
| 67 | +└───────────────────────────────────────┴┄┄┄┄┄┄┄┄┄┄┄┘ |
| 68 | +``` |
| 69 | + |
| 70 | +- **lab navbar** top-right has exactly two controls: `[ light · dark ]` theme toggle |
| 71 | + (preview both themes) and `[ mobile ]` toggle that **shows/hides the mobile-view |
| 72 | + sidebar** (the ~390px phone mirror). Default state is the project's choice; the |
| 73 | + point is mobile is one click away, judged beside desktop, before any lock. |
| 74 | +- **cook** main = the variants of the target in flight. |
| 75 | +- **view** main = every locked target, connected. |
| 76 | + |
| 77 | +Concrete React/route scaffolding: `references/harness-blueprint.md`. |
| 78 | + |
| 79 | +## The labcycle (CLUD) - per target |
| 80 | + |
| 81 | +| Step | Verb | What happens to the code | |
| 82 | +|---|---|---| |
| 83 | +| 1 | **Create** | Write N variants (default 3) of the target into the cook scratch. `/lab-cook` shows only these. | |
| 84 | +| 2 | **Update** | Not satisfied → rewrite the cook scratch with fresh variants, **same target**. Loop until satisfied. | |
| 85 | +| 3 | **Lock** | Promote the winner → extract into a clean locked component, add to the ordered locked list → it appears in `/lab-view`. | |
| 86 | +| 4 | **Destroy** | Delete the losing variants and **empty the cook scratch**. No dead code remains. | |
| 87 | +| 5 | **Next** | Repeat for the next target. | |
| 88 | + |
| 89 | +## Two phases |
| 90 | + |
| 91 | +**Phase 0 - Setup (once per project).** Build the harness: the lab navbar (+ theme & |
| 92 | +device toggles), the shared site navbar, the mobile-view sidebar, `/lab-cook`, |
| 93 | +`/lab-view`, and the cook→lock→view plumbing. All dev-gated. Carry any already-decided |
| 94 | +sections in as the first locked entries. |
| 95 | + |
| 96 | +**Phase 1 - Steady state (every target, repeats).** |
| 97 | + |
| 98 | +``` |
| 99 | +1. Ask TARGET → which section, or the whole page? (never more than a page) |
| 100 | +2. Ask 1-3 SCOPE Qs → pin direction/constraints BEFORE building (references/scope-questions.md) |
| 101 | +3. Build VARIANTS → default 3, in /lab-cook, desktop main + mobile sidebar |
| 102 | +4. UPDATE (iterate) → not happy? fresh variants, same target, loop |
| 103 | +5. LOCK → winner → /lab-view; cook empties (Iron Laws 1 & 2) |
| 104 | +6. → next target |
| 105 | +``` |
| 106 | + |
| 107 | +When **/lab-view is complete and approved** → leave the lab and do **final wiring** |
| 108 | +(below). The lab's job is done; nothing in it ships as-is. |
| 109 | + |
| 110 | +## Variant rules |
| 111 | + |
| 112 | +- **Default 3 per round.** Genuinely distinct - a different *idea* or layout per |
| 113 | + variant, not three recolors of one. If the user dislikes all three, the next round |
| 114 | + should change the *approach*, not nudge pixels. |
| 115 | +- **Always desktop + mobile.** Never present a desktop-only variant; the mobile |
| 116 | + sidebar exists for this. |
| 117 | +- **Honest content only.** Real metrics, real copy. No fabricated numbers, logos, or |
| 118 | + testimonials - placeholder lies poison the decision. |
| 119 | +- **Label every variant**: short name + one-line note on the trade-off. |
| 120 | +- **One question to lock.** After showing variants, ask which to lock (or what to |
| 121 | + change), then act. Do not assume. |
| 122 | + |
| 123 | +## Final wiring (handoff out of the lab) |
| 124 | + |
| 125 | +Once `/lab-view` is approved, re-implement for production - this is a separate phase, |
| 126 | +not part of the lab: |
| 127 | + |
| 128 | +| Throwaway (lab) | Ships (final) | |
| 129 | +|---|---| |
| 130 | +| scoped `lab.css`, hard-coded OKLCH | real design-system tokens (`design-tokens` skill) | |
| 131 | +| Google-fonts CDN `<link>` | self-hosted fonts (`@fontsource`, etc.) | |
| 132 | +| inline `style={{}}` | token-backed utilities / component styles | |
| 133 | +| `src/lab/` scratch | `components/sections/` proper folder + reusable parts | |
| 134 | +| dev-gated `/lab-view` | swap into the real production route | |
| 135 | + |
| 136 | +Then run `ship-gate` (and `designer_verify_implementation` if a `DESIGN.md` exists) |
| 137 | +before claiming done. |
| 138 | + |
| 139 | +## Red flags - STOP |
| 140 | + |
| 141 | +| Thought | Reality | |
| 142 | +|---|---| |
| 143 | +| "I'll keep all sections' variants in one registry" | That's a board, not a cook. One target's scratch at a time (Iron Law 1). | |
| 144 | +| "Lock it but keep the other two around just in case" | No graveyard. Delete on lock; git remembers (Iron Law 2). | |
| 145 | +| "The lab looks great, let me ship this code" | Lab CSS/fonts/inline are throwaway. Wire it properly first (Iron Law 4). | |
| 146 | +| "I'll just tweak the production landing directly" | Then you lose the isolated additive view. Use the lab. | |
| 147 | +| "Three variants but they're basically the same" | Distinct ideas, not recolors. Change the approach. | |
| 148 | +| "Show desktop now, mobile later" | Toggle the mobile sidebar on and judge both before locking. | |
| 149 | +| "I'll start building before asking scope" | Ask target + 1-3 scope Qs first, or you build the wrong thing. | |
| 150 | +| "Mount the lab route unconditionally" | Dev-gate it. The lab never ships (Iron Law 5). | |
| 151 | +| "Use realistic-looking fake stats" | Honest content only. Fake proof poisons the decision. | |
| 152 | + |
| 153 | +## Integration |
| 154 | + |
| 155 | +- **Upstream**: `designer` (a `DESIGN.md` contract sets the visual language each |
| 156 | + variant must honor) and `brainstorming` (settle intent before cooking). |
| 157 | +- **During**: `behaviour-analysis` on a locked target before moving on (states, |
| 158 | + edge cases, a11y). |
| 159 | +- **Final wiring**: `design-tokens` (migrate scoped CSS → tokens), `frontend-design` |
| 160 | + / `shadcn-expert` (production components), then `ship-gate` + `designer_verify_implementation`. |
| 161 | + |
| 162 | +The lab does not replace the design decision (that is `designer`); it is the place to |
| 163 | +make and validate that decision in the real stack, one target at a time, before |
| 164 | +committing production code. |
0 commit comments