|
| 1 | +<style> |
| 2 | + /* ── Demo-A design artifact · dock choreography showcase (#14638, tree line F1 of #13158) ── |
| 3 | + Design DNA: the cockpit plan SSOT (fleet-manager-cockpit-plan.html). Dual-mode from birth |
| 4 | + per #14681: every color below is a SEMANTIC token; the [data-mode] swap IS the thesis. */ |
| 5 | + :root, [data-mode="dark"] { |
| 6 | + --ground:#0b0e13; --panel:#141a23; --panel-2:#1a212c; --rail:#0e131a; |
| 7 | + --line:#262f3d; --line-soft:#1c242f; |
| 8 | + --ink:#d6dce6; --ink-dim:#8b97a8; --ink-faint:#5a6575; |
| 9 | + --signal:#5eead4; --ok:#34d399; --warn:#f5b544; --hot:#f4718b; |
| 10 | + --pane-a:#22485f; --pane-b:#3b3560; --pane-c:#2e5243; --pane-d:#5b3d49; |
| 11 | + --shadow:0 24px 60px -30px #000; |
| 12 | + } |
| 13 | + [data-mode="light"] { |
| 14 | + --ground:#f5f7fa; --panel:#ffffff; --panel-2:#eef1f6; --rail:#e8ecf2; |
| 15 | + --line:#c9d2de; --line-soft:#dde3ec; |
| 16 | + --ink:#1c2430; --ink-dim:#4a5568; --ink-faint:#8a94a6; |
| 17 | + --signal:#0d9488; --ok:#059669; --warn:#b45309; --hot:#be123c; |
| 18 | + --pane-a:#bfdbef; --pane-b:#d4cff0; --pane-c:#c3e6d4; --pane-d:#eccdd6; |
| 19 | + --shadow:0 24px 60px -30px #94a3b8; |
| 20 | + } |
| 21 | + --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace; |
| 22 | + *{box-sizing:border-box} |
| 23 | + body{background:var(--ground);transition:background .3s} |
| 24 | + .wrap{max-width:1180px;margin:0 auto;padding:0 24px 96px;color:var(--ink); |
| 25 | + font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;line-height:1.6} |
| 26 | + .eyebrow{font-family:ui-monospace,Menlo,monospace;font-size:11.5px;letter-spacing:.22em; |
| 27 | + text-transform:uppercase;color:var(--signal);margin:0} |
| 28 | + h1{font-size:clamp(30px,4.4vw,46px);line-height:1.08;letter-spacing:-.02em;margin:14px 0 0;font-weight:640} |
| 29 | + h2{font-size:24px;letter-spacing:-.01em;margin:0 0 4px;font-weight:620} |
| 30 | + h3{font-size:15px;margin:0;font-weight:620} |
| 31 | + .lede{font-size:19px;color:var(--ink-dim);max-width:66ch;margin:18px 0 0} |
| 32 | + .sec{margin-top:72px} |
| 33 | + .sec-head{display:flex;align-items:baseline;gap:14px;border-bottom:1px solid var(--line); |
| 34 | + padding-bottom:12px;margin-bottom:26px} |
| 35 | + .sec-num{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--ink-faint);letter-spacing:.1em} |
| 36 | + .muted{color:var(--ink-dim)} .faint{color:var(--ink-faint)} |
| 37 | + .mono{font-family:ui-monospace,Menlo,monospace} |
| 38 | + p{margin:12px 0 0} |
| 39 | + |
| 40 | + header{padding-top:56px;position:relative} |
| 41 | + .mode-toggle{position:absolute;top:56px;right:0;font-family:ui-monospace,Menlo,monospace; |
| 42 | + font-size:11.5px;color:var(--ink-dim);background:var(--panel);border:1px solid var(--line); |
| 43 | + border-radius:7px;padding:7px 12px;cursor:pointer} |
| 44 | + .mode-toggle:hover{color:var(--signal);border-color:var(--signal)} |
| 45 | + .kicker-row{display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center;margin-top:22px; |
| 46 | + font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--ink-faint)} |
| 47 | + .kicker-row b{color:var(--ink-dim);font-weight:500} |
| 48 | + |
| 49 | + /* thumbnail moment */ |
| 50 | + .thumb{margin-top:26px;border:1px solid var(--line);border-radius:12px;overflow:hidden; |
| 51 | + background:var(--panel);box-shadow:var(--shadow);padding:22px} |
| 52 | + .thumb-line{font-size:15px;color:var(--ink-dim)} .thumb-line b{color:var(--ink)} |
| 53 | + |
| 54 | + /* storyboard */ |
| 55 | + .scene{border:1px solid var(--line);border-radius:11px;overflow:hidden;background:var(--panel);margin-top:20px} |
| 56 | + .scene-head{display:flex;align-items:center;gap:13px;padding:14px 18px;background:var(--panel-2); |
| 57 | + border-bottom:1px solid var(--line-soft)} |
| 58 | + .scene-id{font-family:ui-monospace,Menlo,monospace;font-size:12px;font-weight:700; |
| 59 | + color:var(--ground);background:var(--signal);padding:3px 9px;border-radius:6px} |
| 60 | + .scene-dur{margin-left:auto;font-family:ui-monospace,Menlo,monospace;font-size:11.5px;color:var(--ink-faint)} |
| 61 | + .scene-body{padding:16px 18px;display:grid;grid-template-columns:1fr 1fr;gap:18px} |
| 62 | + .board{background:var(--rail);border:1px solid var(--line-soft);border-radius:9px;padding:12px} |
| 63 | + .board-label{font-family:ui-monospace,Menlo,monospace;font-size:10.5px;letter-spacing:.12em; |
| 64 | + text-transform:uppercase;color:var(--ink-faint);margin-bottom:10px} |
| 65 | + .stage{display:grid;gap:4px;height:150px} |
| 66 | + .pane{border-radius:5px;display:grid;place-items:center;font-family:ui-monospace,Menlo,monospace; |
| 67 | + font-size:10.5px;color:var(--ink);opacity:.92;min-height:0;min-width:0} |
| 68 | + .tabbar{display:flex;gap:3px;height:16px;margin-bottom:3px} |
| 69 | + .tab{flex:1;border-radius:3px 3px 0 0;opacity:.6} .tab.active{opacity:1} |
| 70 | + .rail-edge{width:14px;border-radius:4px;display:grid;place-items:center; |
| 71 | + font-size:8.5px;writing-mode:vertical-rl;color:var(--ink-dim);background:var(--panel-2);border:1px dashed var(--line)} |
| 72 | + .scene-notes{padding:0 18px 16px;display:grid;grid-template-columns:1fr 1fr;gap:18px} |
| 73 | + .note h4{font-family:ui-monospace,Menlo,monospace;font-size:10.5px;letter-spacing:.12em; |
| 74 | + text-transform:uppercase;color:var(--signal);margin:0 0 6px;font-weight:600} |
| 75 | + .note ol,.note ul{margin:0;padding-left:18px;font-size:13px;color:var(--ink-dim)} |
| 76 | + .note li{margin-top:4px} .note li b{color:var(--ink);font-weight:600} |
| 77 | + .op{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--signal)} |
| 78 | + |
| 79 | + /* tour UX */ |
| 80 | + .tourbar{border:1px solid var(--line);border-radius:11px;background:var(--panel);padding:14px 18px; |
| 81 | + display:flex;align-items:center;gap:16px;margin-top:8px} |
| 82 | + .tour-btn{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--ground); |
| 83 | + background:var(--signal);border:0;border-radius:6px;padding:7px 13px;font-weight:600} |
| 84 | + .tour-caption{font-size:13.5px;color:var(--ink-dim);flex:1} |
| 85 | + .tour-caption b{color:var(--ink)} |
| 86 | + .tour-progress{display:flex;gap:5px} |
| 87 | + .tp{width:26px;height:5px;border-radius:3px;background:var(--line)} |
| 88 | + .tp.done{background:var(--signal)} |
| 89 | + |
| 90 | + .tokens{width:100%;border-collapse:collapse;font-size:13px;margin-top:8px} |
| 91 | + .tokens th,.tokens td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line-soft)} |
| 92 | + .tokens th{font-family:ui-monospace,Menlo,monospace;font-size:10.5px;letter-spacing:.1em; |
| 93 | + text-transform:uppercase;color:var(--ink-faint);font-weight:600} |
| 94 | + .tokens td:first-child{font-family:ui-monospace,Menlo,monospace;color:var(--signal);font-size:12px} |
| 95 | + .swatch{display:inline-block;width:12px;height:12px;border-radius:3px;vertical-align:-1px; |
| 96 | + border:1px solid var(--line);margin-right:7px} |
| 97 | + |
| 98 | + .honest{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--warn); |
| 99 | + border-radius:9px;padding:16px 18px;margin-top:8px;font-size:14px;color:var(--ink-dim)} |
| 100 | + .honest b{color:var(--ink)} |
| 101 | + @media (max-width:820px){.scene-body,.scene-notes{grid-template-columns:1fr}} |
| 102 | +</style> |
| 103 | + |
| 104 | +<div class="wrap" id="artifact-root" data-mode="dark"> |
| 105 | + <header> |
| 106 | + <p class="eyebrow">Demo A · Design Artifact · #14638 (tree F1 of #13158)</p> |
| 107 | + <button class="mode-toggle" onclick="var r=document.getElementById('artifact-root');r.dataset.mode=r.dataset.mode==='dark'?'light':'dark';this.textContent=r.dataset.mode==='dark'?'☾ dark — toggle':'☀ light — toggle'">☾ dark — toggle</button> |
| 108 | + <h1>Layouts that rebuild themselves — smoothly, on command, while everything keeps running.</h1> |
| 109 | + <p class="lede">The 30-second stranger test: within one scene they must SEE panes split, regroup, and tuck away as <b style="color:var(--ink)">continuous animated motion</b> — and understand no pane ever reloaded. Within three scenes they must notice nobody is dragging: <b style="color:var(--ink)">an agent is driving the layout through the Neural Link.</b></p> |
| 110 | + <div class="kicker-row"> |
| 111 | + <span>Consumes <b>#14625 NL tools</b></span><span>Script <b>#14661 (tour)</b></span> |
| 112 | + <span>Player <b>#14640 (runner)</b></span><span>Proof <b>#14591 (e2e replay)</b></span> |
| 113 | + <span>Modes <b>light + dark (#14681)</b> — toggle ↗</span> |
| 114 | + </div> |
| 115 | + </header> |
| 116 | + |
| 117 | + <!-- 01 · THE FRAMING --> |
| 118 | + <section class="sec"> |
| 119 | + <div class="sec-head"><span class="sec-num">01</span><h2>The thumbnail moment</h2></div> |
| 120 | + <div class="thumb"> |
| 121 | + <p class="thumb-line"><b>The video freeze-frame that earns the click:</b> a four-pane workspace mid-morph — two panes visibly gliding into a shared tab group while a third slides to the edge as a labeled rail tab — with the caption <span class="mono" style="color:var(--signal)">"an agent is re-docking this workspace, live."</span> Motion IS the message: every transition is animated re-parenting, never a flicker of remount. A ticking clock pane stays visibly ticking through every scene as the object-permanence witness.</p> |
| 122 | + </div> |
| 123 | + </section> |
| 124 | + |
| 125 | + <!-- 02 · SCENES --> |
| 126 | + <section class="sec"> |
| 127 | + <div class="sec-head"><span class="sec-num">02</span><h2>Three scenes, storyboarded</h2> |
| 128 | + <span class="faint mono" style="margin-left:auto;font-size:12px">ops = shipped dockZone.v1 vocabulary only · exact JSON descriptors bind in the tour script (#14661) against the live schema — never invented here</span></div> |
| 129 | + |
| 130 | + <!-- scene 1 --> |
| 131 | + <div class="scene"> |
| 132 | + <div class="scene-head"><span class="scene-id">S1</span><h3>Split choreography — one pane becomes a studio</h3><span class="scene-dur">~25s · 4 ops</span></div> |
| 133 | + <div class="scene-body"> |
| 134 | + <div class="board"><div class="board-label">Before — single pane</div> |
| 135 | + <div class="stage" style="grid-template:1fr / 1fr"> |
| 136 | + <div class="pane" style="background:var(--pane-a)">EDITOR <span style="opacity:.6">· clock 09:41:07 ⟳</span></div> |
| 137 | + </div> |
| 138 | + </div> |
| 139 | + <div class="board"><div class="board-label">After — three-way studio</div> |
| 140 | + <div class="stage" style="grid-template:2fr 1fr / 2fr 1fr"> |
| 141 | + <div class="pane" style="background:var(--pane-a)">EDITOR ⟳</div> |
| 142 | + <div class="pane" style="background:var(--pane-b);grid-row:1/3">PREVIEW</div> |
| 143 | + <div class="pane" style="background:var(--pane-c)">TERMINAL</div> |
| 144 | + </div> |
| 145 | + </div> |
| 146 | + </div> |
| 147 | + <div class="scene-notes"> |
| 148 | + <div class="note"><h4>Operation beats</h4> |
| 149 | + <ol> |
| 150 | + <li><span class="op">split</span> editor → <b>right</b> (preview enters, 50/50)</li> |
| 151 | + <li><span class="op">resizeSplit</span> → editor takes 2/3 (the golden-ratio settle)</li> |
| 152 | + <li><span class="op">split</span> editor → <b>bottom</b> (terminal enters low)</li> |
| 153 | + <li><span class="op">resizeSplit</span> → terminal to 1/3 height</li> |
| 154 | + </ol> |
| 155 | + </div> |
| 156 | + <div class="note"><h4>Motion + camera</h4> |
| 157 | + <ul> |
| 158 | + <li><b>FLIP re-parent:</b> entering pane grows from its drop edge (280ms, standard-decelerate); siblings yield with the SAME easing — one choreography, not two animations.</li> |
| 159 | + <li><b>Splitter settle:</b> resize eases 180ms; no scroll-jank in the yielding pane (observe_motion assertable).</li> |
| 160 | + <li><b>Camera:</b> full workspace, static; the clock ticks through all 4 beats.</li> |
| 161 | + </ul> |
| 162 | + </div> |
| 163 | + </div> |
| 164 | + </div> |
| 165 | + |
| 166 | + <!-- scene 2 --> |
| 167 | + <div class="scene"> |
| 168 | + <div class="scene-head"><span class="scene-id">S2</span><h3>Tab dance — density without loss</h3><span class="scene-dur">~20s · 3 ops</span></div> |
| 169 | + <div class="scene-body"> |
| 170 | + <div class="board"><div class="board-label">Before — the S1 studio</div> |
| 171 | + <div class="stage" style="grid-template:2fr 1fr / 2fr 1fr"> |
| 172 | + <div class="pane" style="background:var(--pane-a)">EDITOR ⟳</div> |
| 173 | + <div class="pane" style="background:var(--pane-b);grid-row:1/3">PREVIEW</div> |
| 174 | + <div class="pane" style="background:var(--pane-c)">TERMINAL</div> |
| 175 | + </div> |
| 176 | + </div> |
| 177 | + <div class="board"><div class="board-label">After — tabbed right column + fourth arrival</div> |
| 178 | + <div class="stage" style="grid-template:2fr 1fr / 2fr 1fr"> |
| 179 | + <div class="pane" style="background:var(--pane-a)">EDITOR ⟳</div> |
| 180 | + <div style="grid-row:1/3;display:flex;flex-direction:column"> |
| 181 | + <div class="tabbar"><div class="tab active" style="background:var(--pane-b)"></div><div class="tab" style="background:var(--pane-c)"></div><div class="tab" style="background:var(--pane-d)"></div></div> |
| 182 | + <div class="pane" style="background:var(--pane-b);flex:1">PREVIEW <span style="opacity:.6">(3 tabs)</span></div> |
| 183 | + </div> |
| 184 | + <div class="pane" style="background:var(--pane-d)">LOGS</div> |
| 185 | + </div> |
| 186 | + </div> |
| 187 | + </div> |
| 188 | + <div class="scene-notes"> |
| 189 | + <div class="note"><h4>Operation beats</h4> |
| 190 | + <ol> |
| 191 | + <li><span class="op">moveItem→tab</span> terminal INTO preview (tab group forms)</li> |
| 192 | + <li><span class="op">split</span> editor → bottom: <b>logs</b> arrives (fourth resident)</li> |
| 193 | + <li><span class="op">moveItem→tab</span> logs into the right group; active-tab handoff visible</li> |
| 194 | + </ol> |
| 195 | + </div> |
| 196 | + <div class="note"><h4>Motion + camera</h4> |
| 197 | + <ul> |
| 198 | + <li><b>Tab-fold:</b> the folding pane shrinks toward the target tab-strip slot while its tab fades in (240ms) — the tab IS the pane, relocated, and the motion says so.</li> |
| 199 | + <li><b>Active-tab pulse:</b> one subtle signal-color pulse on handoff; never a blink.</li> |
| 200 | + <li><b>Camera:</b> slow push-in on the right column for beat 3; clock still ticking top-left.</li> |
| 201 | + </ul> |
| 202 | + </div> |
| 203 | + </div> |
| 204 | + </div> |
| 205 | + |
| 206 | + <!-- scene 3 --> |
| 207 | + <div class="scene"> |
| 208 | + <div class="scene-head"><span class="scene-id">S3</span><h3>Auto-hide wave — the workspace breathes</h3><span class="scene-dur">~25s · 4 ops</span></div> |
| 209 | + <div class="scene-body"> |
| 210 | + <div class="board"><div class="board-label">Before — the S2 den</div> |
| 211 | + <div class="stage" style="grid-template:2fr 1fr / 2fr 1fr"> |
| 212 | + <div class="pane" style="background:var(--pane-a)">EDITOR ⟳</div> |
| 213 | + <div class="pane" style="background:var(--pane-b);grid-row:1/3">PREVIEW +2</div> |
| 214 | + <div class="pane" style="background:var(--pane-d)">LOGS</div> |
| 215 | + </div> |
| 216 | + </div> |
| 217 | + <div class="board"><div class="board-label">After — focus mode, rails armed</div> |
| 218 | + <div class="stage" style="grid-template:1fr / 14px 1fr 14px"> |
| 219 | + <div class="rail-edge">LOGS</div> |
| 220 | + <div class="pane" style="background:var(--pane-a)">EDITOR — full stage ⟳</div> |
| 221 | + <div class="rail-edge">PREVIEW</div> |
| 222 | + </div> |
| 223 | + </div> |
| 224 | + </div> |
| 225 | + <div class="scene-notes"> |
| 226 | + <div class="note"><h4>Operation beats</h4> |
| 227 | + <ol> |
| 228 | + <li><span class="op">setItemAutoHidden</span> logs → true (tucks to left rail, #14654's affordance)</li> |
| 229 | + <li><span class="op">setItemAutoHidden</span> preview-group → true (right rail; editor floods the stage)</li> |
| 230 | + <li>hover-reveal moment: preview slides over as overlay, releases (#14660's contract — shown, not persisted)</li> |
| 231 | + <li><span class="op">setItemAutoHidden</span> ×2 → false: the wave rolls back, layout restores</li> |
| 232 | + </ol> |
| 233 | + </div> |
| 234 | + <div class="note"><h4>Motion + camera</h4> |
| 235 | + <ul> |
| 236 | + <li><b>Tuck:</b> pane collapses toward its edge into the labeled rail tab (260ms); the editor's expansion is the SAME transaction — one breath, not two events.</li> |
| 237 | + <li><b>Reveal:</b> overlay slides 200ms, dismiss 160ms with grace delay — the D2 state machine rendered honestly.</li> |
| 238 | + <li><b>Camera:</b> static full stage; the finale is the reverse wave — a layout remembering itself.</li> |
| 239 | + </ul> |
| 240 | + </div> |
| 241 | + </div> |
| 242 | + </div> |
| 243 | + </section> |
| 244 | + |
| 245 | + <!-- 03 · TOUR MODE UX --> |
| 246 | + <section class="sec"> |
| 247 | + <div class="sec-head"><span class="sec-num">03</span><h2>Tour mode — the screenplay surface</h2> |
| 248 | + <span class="faint mono" style="margin-left:auto;font-size:12px">one script (#14661) = the demo · the e2e spec · the video take</span></div> |
| 249 | + <div class="tourbar"> |
| 250 | + <button class="tour-btn">▶ tour</button> |
| 251 | + <span class="tour-caption"><b>S2 · beat 1/3</b> — the agent folds the terminal into a tab group: <span class="mono">moveItem→tab(terminal → preview)</span></span> |
| 252 | + <span class="tour-progress"><i class="tp done"></i><i class="tp done"></i><i class="tp done"></i><i class="tp done"></i><i class="tp done"></i><i class="tp"></i><i class="tp"></i><i class="tp"></i><i class="tp"></i><i class="tp"></i><i class="tp"></i></span> |
| 253 | + </div> |
| 254 | + <p class="muted" style="font-size:14px;max-width:74ch">The tour bar is the only demo chrome: play/pause, the current beat's caption (scene · beat · the operation in vocabulary terms — the caption teaches the API by narrating it), and beat-progress pips. Manual-drive stays available the whole time (grab any splitter, drag any tab — the tour yields, a <span class="mono">⟲ resume tour</span> affordance appears). Recording profile (#14589-F7): tour mode, captions on, reduced-motion OFF asserted, mode per take — the same run twice is the same video.</p> |
| 255 | + </section> |
| 256 | + |
| 257 | + <!-- 04 · VISUAL IDENTITY --> |
| 258 | + <section class="sec"> |
| 259 | + <div class="sec-head"><span class="sec-num">04</span><h2>Visual identity — semantic tokens, two modes</h2></div> |
| 260 | + <table class="tokens"> |
| 261 | + <tr><th>token</th><th>role</th><th>dark</th><th>light</th></tr> |
| 262 | + <tr><td>--ground / --panel / --rail</td><td>stage depths (page · card · well)</td><td><span class="swatch" style="background:#0b0e13"></span>near-black blues</td><td><span class="swatch" style="background:#f5f7fa"></span>cool paper</td></tr> |
| 263 | + <tr><td>--signal</td><td>the one accent: live action, tour chrome, active tab pulse</td><td><span class="swatch" style="background:#5eead4"></span>teal-mint</td><td><span class="swatch" style="background:#0d9488"></span>deep teal (AA on paper)</td></tr> |
| 264 | + <tr><td>--pane-a…d</td><td>pane identities — muted, content-like, never candy</td><td>4 dusk hues</td><td>4 chalk hues</td></tr> |
| 265 | + <tr><td>--ink / -dim / -faint</td><td>type ramp (3 steps, no more)</td><td>cool grays ↑</td><td>slate grays ↓</td></tr> |
| 266 | + </table> |
| 267 | + <p class="muted" style="font-size:14px;max-width:74ch">This artifact's own toggle (top right) demonstrates the #14681 thesis: mode = a token-set swap, zero component knowledge. Reconciliation with the FM module floor happens at build time (F2): where the relocated <span class="mono">tokens.css</span> already names an equivalent, the demo consumes the module token and this table records the mapping — the demo and the cockpit must read as one family (post-veto: one app, one design DNA).</p> |
| 268 | + </section> |
| 269 | + |
| 270 | + <!-- 05 · HONEST STATE --> |
| 271 | + <section class="sec"> |
| 272 | + <div class="sec-head"><span class="sec-num">05</span><h2>Honest state — what this mock promises vs what ships today</h2></div> |
| 273 | + <div class="honest"> |
| 274 | + <b>Real today (shipped dockZone.v1 + landed #14625 tools):</b> every S1–S3 operation class — split, resizeSplit, moveItem→tab, setItemAutoHidden — executes semantically with animated transitions, agent-drivable end-to-end. <b>Designed here, building in the tree:</b> the edge-rail affordance (#14654) and reveal/dismiss timing (#14660) for S3's beats 1–3; the tour runner (#14640) and this screenplay as its script (#14661). <b>Deliberately absent:</b> perspectives and multi-window pop-out — that is Demo B (#14590, spec-gated), and blending the two would blur both stories. No performance numbers appear anywhere in the demo (#13032 guardrail; the motion must simply LOOK effortless — a claim the viewer verifies with their own eyes). |
| 275 | + </div> |
| 276 | + </section> |
| 277 | +</div> |
0 commit comments