Skip to content

Commit df19f00

Browse files
feat(design): Demo-A dock-choreography design artifact — 3 storyboarded scenes, tour UX, dual-mode (#14638) (#14690)
1 parent c876fc8 commit df19f00

1 file changed

Lines changed: 277 additions & 0 deletions

File tree

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
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

Comments
 (0)