@worca/app 1.2.0 → 1.3.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +42 -0
  2. package/agents/memoryDefragmenter.meta.json +24 -0
  3. package/agents/worca-cc-code-reviewer.md +6 -1
  4. package/agents/worca-cc-implementer.md +6 -1
  5. package/agents/worca-cc-memory-defragmenter.md +32 -0
  6. package/agents/worca-cc-planner.md +5 -1
  7. package/package.json +5 -2
  8. package/src/cli/render.mjs +36 -0
  9. package/src/cli/worca-cc.mjs +137 -8
  10. package/src/core/agent-registry.mjs +12 -34
  11. package/src/core/artifacts.mjs +132 -8
  12. package/src/core/ask/catalog.mjs +32 -7
  13. package/src/core/ask/comment-deps.mjs +5 -2
  14. package/src/core/ask/events.mjs +65 -2
  15. package/src/core/ask/limits.mjs +9 -0
  16. package/src/core/ask/mcp-stdio.mjs +10 -0
  17. package/src/core/ask/memory-deps.mjs +107 -0
  18. package/src/core/ask/metrics-deps.mjs +124 -0
  19. package/src/core/ask/metrics-proposal.mjs +175 -0
  20. package/src/core/ask/prompt.mjs +53 -10
  21. package/src/core/ask/proposal.mjs +49 -2
  22. package/src/core/ask/spawn.mjs +21 -4
  23. package/src/core/ask/store.mjs +14 -5
  24. package/src/core/ask/tool-deps.mjs +26 -2
  25. package/src/core/ask/tools.mjs +439 -6
  26. package/src/core/ask/turn.mjs +163 -4
  27. package/src/core/ask/workflow-deps.mjs +226 -0
  28. package/src/core/auto/classify.mjs +352 -0
  29. package/src/core/auto/fingerprint.mjs +141 -0
  30. package/src/core/auto/match.mjs +30 -0
  31. package/src/core/auto/model.mjs +23 -0
  32. package/src/core/auto/proposal.mjs +132 -0
  33. package/src/core/auto/recipes.mjs +75 -0
  34. package/src/core/auto/repo-look.mjs +46 -0
  35. package/src/core/claude-runner.mjs +132 -11
  36. package/src/core/config.mjs +120 -3
  37. package/src/core/db.mjs +44 -1
  38. package/src/core/diff-comments.mjs +55 -9
  39. package/src/core/frontmatter.mjs +75 -0
  40. package/src/core/git-info.mjs +233 -26
  41. package/src/core/graph/builtin-workflows.mjs +50 -0
  42. package/src/core/graph/executor.mjs +11 -3
  43. package/src/core/index-html.mjs +17 -0
  44. package/src/core/memory-store.mjs +441 -0
  45. package/src/core/memory-sync.mjs +300 -0
  46. package/src/core/metrics/ledger.mjs +47 -0
  47. package/src/core/metrics/lock.mjs +117 -0
  48. package/src/core/metrics/read.mjs +303 -0
  49. package/src/core/metrics/record.mjs +389 -0
  50. package/src/core/metrics/sync.mjs +1100 -0
  51. package/src/core/onboarding.mjs +99 -0
  52. package/src/core/orchestrator.mjs +394 -7
  53. package/src/core/phases.mjs +16 -3
  54. package/src/core/pipeline-delete.mjs +1 -1
  55. package/src/core/plugin-store.mjs +2 -10
  56. package/src/core/preflight.mjs +2 -3
  57. package/src/core/projects.mjs +16 -1
  58. package/src/core/run-harness.mjs +458 -32
  59. package/src/core/run-report.mjs +896 -0
  60. package/src/core/settings.mjs +162 -0
  61. package/src/core/sources.mjs +4 -1
  62. package/src/core/store.mjs +5 -0
  63. package/src/core/workflow-export.mjs +2 -0
  64. package/src/core/workflow-share.mjs +1 -0
  65. package/src/core/workflows.mjs +43 -23
  66. package/src/core/workspaces.mjs +37 -8
  67. package/src/shared/graph/agent-meta.mjs +5 -2
  68. package/src/shared/graph/assemble.mjs +455 -0
  69. package/src/shared/graph/flow-layout.mjs +249 -0
  70. package/src/shared/graph/geometry.mjs +48 -28
  71. package/src/shared/graph/isomorphic.mjs +101 -0
  72. package/src/shared/report-reasons.mjs +58 -0
  73. package/src/shared/team-metrics/aggregate.mjs +341 -0
  74. package/src/shared/team-metrics/workspace-match.mjs +13 -0
  75. package/ui/public/about-links.mjs +21 -0
  76. package/ui/public/app.js +3715 -479
  77. package/ui/public/artifact-view.mjs +135 -0
  78. package/ui/public/ask-model.mjs +18 -1
  79. package/ui/public/ask-panel.mjs +1359 -214
  80. package/ui/public/ask-run-card.mjs +209 -0
  81. package/ui/public/assets/worca-logo-mask.png +0 -0
  82. package/ui/public/assets/worca-mark-mask.png +0 -0
  83. package/ui/public/auto-build.mjs +95 -0
  84. package/ui/public/auto-proposal.mjs +174 -0
  85. package/ui/public/comment-thread.mjs +55 -0
  86. package/ui/public/getting-started.mjs +261 -0
  87. package/ui/public/graph/composer.mjs +41 -5
  88. package/ui/public/graph/inspector.mjs +3 -1
  89. package/ui/public/graph/model.mjs +1 -0
  90. package/ui/public/graph/run-hosts.mjs +73 -12
  91. package/ui/public/graph/view.mjs +218 -50
  92. package/ui/public/guide-spot.mjs +215 -0
  93. package/ui/public/index.html +423 -25
  94. package/ui/public/memory-view.mjs +192 -0
  95. package/ui/public/node-tunables.mjs +201 -0
  96. package/ui/public/report-run.mjs +75 -0
  97. package/ui/public/results-view.mjs +25 -0
  98. package/ui/public/source-pane.mjs +16 -2
  99. package/ui/public/stats-view.mjs +2 -2
  100. package/ui/public/style.css +1450 -303
  101. package/ui/public/team-metrics-surfaces.mjs +452 -0
  102. package/ui/public/team-metrics-view.mjs +533 -0
  103. package/ui/public/thinking-orb.mjs +46 -8
  104. package/ui/server.mjs +1282 -193
@@ -8,46 +8,79 @@
8
8
  @font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');}
9
9
 
10
10
  :root{
11
- --bg:#F1F1EF;
12
- --panel:#FFFFFF;
13
- --ink:#19191B;
14
- --ink-2:#5C5C63;
15
- --ink-3:#9A9AA1;
16
- --line:#ECECEA;
17
- --line-2:#E3E3E0;
18
- --field:#F6F6F4;
19
-
20
- --green-bg:#E2F3DF; --green:#5BAE5B; --green-ink:#2F7A38;
21
- --peach-bg:#FCEEDA; --peach:#EFA63C; --peach-ink:#B5751A;
22
- --red-bg:#FBE3E0; --red:#E76A5A; --red-ink:#C5483A;
23
- --blue-bg:#DEEFF7; --blue:#5BA6CC; --blue-ink:#3782A8;
24
- --violet-bg:#EAE6F8; --violet:#8C7FD6; --violet-ink:#6353B8;
25
- --amber-bg:#FCE8C8; --amber:#E6962A; --amber-ink:#A66510;
26
- --seq:#B7B7BC;
11
+ /* Theme (spec 2026-09-04 §4.1): every colour token is light-dark(<light>, <dark>).
12
+ The light arm is the "Refined" palette exactly as it always was; the dark arm is
13
+ the warm-charcoal palette of spec §3. The MODE is the color-scheme property:
14
+ `light dark` here follows the OS; the two [data-theme] rules after this block
15
+ force one. The six status bases have equal arms and stay plain (D13).
16
+ Never restate a token's hex anywhere else — several tests count occurrences. */
17
+ color-scheme:light dark;
18
+
19
+ --bg:light-dark(#F1F1EF,#161614);
20
+ --canvas-2:light-dark(#FBFBF9,#1B1B19);
21
+ --panel:light-dark(#FFFFFF,#222220);
22
+ --surface:light-dark(#FFFFFF,#34342F);
23
+ --field:light-dark(#F6F6F4,#2C2C29);
24
+ --field-focus:light-dark(#FFFFFF,#2E2E2B);
25
+ --ink:light-dark(#19191B,#ECECE8);
26
+ --ink-2:light-dark(#5C5C63,#B4B4AE);
27
+ --ink-3:light-dark(#9A9AA1,#9E9E98);
28
+ --on-ink:light-dark(#FFFFFF,#161614);
29
+ --on-status:light-dark(#FFFFFF,#161614);
30
+ --line:light-dark(#ECECEA,#30302D);
31
+ --line-2:light-dark(#E3E3E0,#494944);
32
+
33
+ --green-bg:light-dark(#E2F3DF,#1C2F1D); --green:#5BAE5B; --green-ink:light-dark(#2F7A38,#8FD48F);
34
+ --peach-bg:light-dark(#FCEEDA,#33261A); --peach:#EFA63C; --peach-ink:light-dark(#B5751A,#F2B96A);
35
+ --red-bg:light-dark(#FBE3E0,#34201D); --red:#E76A5A; --red-ink:light-dark(#C5483A,#F08C7E);
36
+ --blue-bg:light-dark(#DEEFF7,#1A2A33); --blue:#5BA6CC; --blue-ink:light-dark(#3782A8,#86C4E3);
37
+ --blue-ink-strong:light-dark(#2B6A8C,#86C4E3); /* inline link text at small sizes: 5.9:1 on white (--blue-ink is 3.8:1) */
38
+ --violet-bg:light-dark(#EAE6F8,#262336); --violet:#8C7FD6; --violet-ink:light-dark(#6353B8,#B3A8EE);
39
+ --amber-bg:light-dark(#FCE8C8,#332715); --amber:#E6962A; --amber-ink:light-dark(#A66510,#F0B45A);
40
+ --seq:light-dark(#B7B7BC,#8E8E92); /* text role too (.ask-thinking-meter): 4.85:1 on panel */
27
41
 
28
42
  /* Question/ask amber wash (design §9, C3). --amber-bg is the SOLID amber; this
29
- is the pale field it sits on. Task 11 adds --amber-wash-2/--amber-line/
30
- --radio-ring beside it. */
31
- --amber-wash:#FEF7EC;
32
-
33
- /* Question panel (design §9): the remaining literals in the Running mockup that
34
- no existing token already carries. The two hexes §9 also lists as "new" are
35
- NOT added — they are already the values of --violet (:24) and --peach-ink
36
- (:21); use those tokens.
37
- Do NOT name those two hexes here, or anywhere else in this stylesheet: Task 12
38
- asserts each appears EXACTLY ONCE, and its regex reads the raw file, so a
39
- mention inside a comment counts as a second occurrence and reds the test. */
40
- --amber-wash-2:#FEFAF3; --amber-line:#F5D9A8; --radio-ring:#D6D6D2;
43
+ is the pale field it sits on, with its line and the radio ring. */
44
+ --amber-wash:light-dark(#FEF7EC,#322816);
45
+ --amber-wash-2:light-dark(#FEFAF3,#2B2314); --amber-line:light-dark(#F5D9A8,#6A5228); --radio-ring:light-dark(#D6D6D2,#4A4A45);
46
+ /* Ask Worca run card head wash (mockup 2026-09-06): Worca-authored, same hue as the Auto tag. */
47
+ --violet-wash:light-dark(#F6F4FC,#211E2E);
48
+
49
+ /* Semantic tokens introduced by the theme work (spec §3.2). Each light arm is
50
+ the literal it replaced, so the light theme did not move. */
51
+ --on-ink-wash:light-dark(rgba(255,255,255,.18),rgba(22,22,20,.18));
52
+ --on-ink-wash-2:light-dark(rgba(255,255,255,.22),rgba(22,22,20,.22));
53
+ --on-ink-code:light-dark(rgba(255,255,255,.14),rgba(22,22,20,.14));
54
+ --panel-wash:light-dark(rgba(255,255,255,.7),rgba(236,236,232,.12));
55
+ --knob:light-dark(#FFFFFF,#ECECE8);
56
+ --scrim:light-dark(rgba(25,25,27,.42),rgba(0,0,0,.62));
57
+ --scrim-soft:light-dark(rgba(25,25,27,.34),rgba(0,0,0,.55));
58
+ --selection:light-dark(rgba(25,25,27,.16),rgba(236,236,232,.22));
59
+ --ava-a:light-dark(#CFCFCA,#4A4A46); --ava-b:light-dark(#A8A8A2,#6A6A64);
60
+ --h-blue-ink:light-dark(#2E6E8E,#9FD3EE); --h-green-ink:light-dark(#3B7C3B,#9BD69B); --h-peach-ink:light-dark(#8A5A16,#F2C27A);
61
+ --drop-ring:light-dark(#D8EFD6,#2A4A2C);
62
+ --trunc-ink:light-dark(#994466,#E39BBE);
63
+ --chip-ink:light-dark(#555555,#B4B4AE);
41
64
 
42
65
  --r-card:24px;
43
66
  --r-ctrl:14px;
44
- --shadow:0 6px 28px rgba(25,25,27,.05), 0 1px 2px rgba(25,25,27,.04);
45
- --shadow-soft:0 2px 12px rgba(25,25,27,.04);
67
+ --shadow:0 6px 28px light-dark(rgba(25,25,27,.05),rgba(0,0,0,.45)), 0 1px 2px light-dark(rgba(25,25,27,.04),rgba(0,0,0,.35));
68
+ --shadow-soft:0 2px 12px light-dark(rgba(25,25,27,.04),rgba(0,0,0,.35));
69
+ --shadow-pop:0 6px 28px light-dark(rgba(25,25,27,.10),rgba(0,0,0,.55)),0 1px 2px light-dark(rgba(25,25,27,.06),rgba(0,0,0,.4));
70
+ --shadow-sheet:0 18px 60px light-dark(rgba(25,25,27,.14),rgba(0,0,0,.65)),0 2px 6px light-dark(rgba(25,25,27,.06),rgba(0,0,0,.4));
71
+ --shadow-hover:0 6px 18px light-dark(rgba(25,25,27,.10),rgba(0,0,0,.55));
72
+ --shadow-menu:0 12px 34px light-dark(rgba(25,25,27,.12),rgba(0,0,0,.6));
73
+ --knob-shadow:0 1px 3px light-dark(rgba(0,0,0,.18),rgba(0,0,0,.6));
46
74
  --ask-dock-clearance:96px;
47
75
 
48
76
  --sans:'Poppins',system-ui,-apple-system,BlinkMacSystemFont,sans-serif;
49
77
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
50
78
  }
79
+ :root[data-theme="light"]{color-scheme:light;}
80
+ :root[data-theme="dark"]{color-scheme:dark;}
81
+ /* Paper is white: a forced dark scheme would print light ink on it. (@media print
82
+ is a medium query, not a scheme query — D5 holds.) */
83
+ @media print{:root{color-scheme:light;}}
51
84
 
52
85
  /* ---------- base reset ---------- */
53
86
  *{box-sizing:border-box;}
@@ -78,7 +111,7 @@ body{
78
111
  .sidebar{
79
112
  width:298px;flex:0 0 298px;
80
113
  background:var(--panel);
81
- padding:26px 18px 22px;
114
+ padding:26px 18px 10px;
82
115
  display:flex;flex-direction:column;
83
116
  border-right:1px solid var(--line);
84
117
  overflow-y:auto;
@@ -86,51 +119,64 @@ body{
86
119
  width .2s cubic-bezier(.65,.02,.28,1);
87
120
  }
88
121
  .brand{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 8px;margin-bottom:24px;}
89
- .brand .logo{height:36px;width:auto;display:block;}
122
+ .brand .logo{display:block;height:34px;aspect-ratio:512/190;background:var(--ink);
123
+ -webkit-mask:url(/assets/worca-logo-mask.png) center/contain no-repeat;mask:url(/assets/worca-logo-mask.png) center/contain no-repeat;}
90
124
 
91
- .nav{display:flex;flex-direction:column;gap:4px;flex:1 1 auto;}
125
+ .nav{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;}
92
126
  .nav button{
93
127
  display:flex;align-items:center;gap:13px;width:100%;margin:0;
94
- padding:11px 13px;border:0;border-radius:13px;
128
+ padding:8px 13px;border:0;border-radius:13px;
95
129
  background:transparent;color:var(--ink-2);
96
- font-family:inherit;font-size:inherit;line-height:inherit;font-weight:500;
130
+ font-family:inherit;font-size:13px;line-height:inherit;font-weight:500;
97
131
  text-align:left;cursor:pointer;
98
132
  transition:background .15s,color .15s;
99
133
  }
100
134
  .nav button svg{width:19px;height:19px;flex:0 0 auto;stroke-width:1.9;}
101
135
  .nav button:hover{background:var(--field);color:var(--ink);}
102
- .nav button.active{background:var(--ink);color:#fff;}
103
- .nav button.active svg{stroke:#fff;}
136
+ .nav button.active{background:var(--ink);color:var(--on-ink);}
137
+ .nav button.active svg{stroke:var(--on-ink);}
104
138
  .nav button:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
105
- .nav-sect{font-size:10.5px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
106
- color:var(--ink-3);padding:14px 13px 2px;user-select:none;}
107
- .nav-sep{margin-top:auto;border-top:1px solid var(--line);}
139
+ /* Sentence case, not caps: the markup already ships "Activity"/"Build"/"Manage",
140
+ so the label is whatever the HTML says. The .11em tracking and the 10.5px size
141
+ existed to keep ALL-CAPS legible; sentence case needs neither, and at 10.5px a
142
+ lowercase x-height reads a size smaller than caps did, so the size goes up as
143
+ the tracking comes down.
144
+ The padding is deliberately lopsided — 24px above, 5px below. A heading
145
+ belongs to the items UNDER it, so the big gap has to fall between groups, not
146
+ between a heading and its own first row. */
147
+ .nav-sect{font-size:11.5px;font-weight:600;letter-spacing:.01em;text-transform:none;
148
+ color:var(--ink-3);padding:24px 13px 5px;user-select:none;}
149
+ /* Settings is the only row that hangs between two edges — the divider above it
150
+ and the spend card below — so both gaps are set here and in .side-foot's
151
+ padding-top, and they must stay equal. 8 + the 2px .nav gap = the 10px the
152
+ foot pads with. */
153
+ .nav-sep{margin-top:auto;margin-bottom:8px;border-top:1px solid var(--line);}
108
154
  /* Primary action: outlined at rest so it doesn't fight the dark current-view
109
155
  fill; border thickness is absorbed into padding to keep row height equal. */
110
156
  .nav button.nav-cta{border:1.5px solid var(--ink);color:var(--ink);font-weight:600;
111
- padding:9.5px 11.5px;}
157
+ padding:6.5px 11.5px;}
112
158
  .nav button.nav-cta:hover{background:var(--field);}
113
- .nav button.nav-cta.active{background:var(--ink);border-color:var(--ink);color:#fff;}
159
+ .nav button.nav-cta.active{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
114
160
  .nav-count{margin-left:auto;min-width:22px;height:22px;padding:0 7px;border-radius:999px;
115
161
  display:grid;place-items:center;font-size:11.5px;font-weight:700;}
116
- .nav-count.n-amber{background:var(--amber);color:#fff;}
162
+ .nav-count.n-amber{background:var(--amber);color:var(--on-status);}
117
163
  .nav-count.n-grey{background:var(--field);color:var(--ink-3);}
118
- .nav button.active .nav-count{background:rgba(255,255,255,.18);color:#fff;}
164
+ .nav button.active .nav-count{background:var(--on-ink-wash);color:var(--on-ink);}
119
165
  /* Running split-badges: green = work in flight, amber = paused count. Green is
120
166
  applied by app.js ONLY while the count is >0 — at zero the badge falls back to
121
167
  n-grey, the inert-inventory treatment History/Projects/Workspaces use, so a
122
168
  permanently green pill cannot dilute the green that should catch the eye.
123
169
  Both keep their colour on the dark active fill (the generic active rule above
124
170
  would wash them into translucent white). */
125
- .nav-count.n-run{background:var(--green);color:#fff;}
126
- .nav-count.n-paused{background:var(--amber);color:#fff;position:relative;margin-left:6px;}
171
+ .nav-count.n-run{background:var(--green);color:var(--on-status);}
172
+ .nav-count.n-paused{background:var(--amber);color:var(--on-status);position:relative;margin-left:6px;}
127
173
  .nav-count[hidden]{display:none;} /* author display:grid beats the UA [hidden] rule */
128
- .nav button.active .nav-count.n-run{background:var(--green);color:#fff;}
129
- .nav button.active .nav-count.n-paused{background:var(--amber);color:#fff;}
174
+ .nav button.active .nav-count.n-run{background:var(--green);color:var(--on-status);}
175
+ .nav button.active .nav-count.n-paused{background:var(--amber);color:var(--on-status);}
130
176
  /* Tiny pause flag pinned at the badge's top-right corner. Scoped under
131
177
  .nav-count so it outranks the generic `.nav button svg` sizing rule. */
132
178
  .nav-count .pause-flag{position:absolute;top:-5px;right:-6px;width:13px;height:13px;padding:2px;
133
- border-radius:50%;background:var(--amber-ink);border:1.5px solid var(--panel);fill:#fff;}
179
+ border-radius:50%;background:var(--amber-ink);border:1.5px solid var(--panel);fill:var(--on-status);}
134
180
 
135
181
  /* Parent roll-up "needs you" dot on the Running nav item (sidebar + topnav) */
136
182
  .nav-rollup {
@@ -138,7 +184,7 @@ body{
138
184
  background: var(--amber); margin-left: 6px; flex: 0 0 auto;
139
185
  animation: pulse 1.3s ease-in-out infinite;
140
186
  }
141
- .nav button.active .nav-rollup { background: #fff; }
187
+ .nav button.active .nav-rollup { background: var(--on-ink); }
142
188
 
143
189
  /* Child pipeline rows nested under Running — tree-connector style (mirrors the
144
190
  sub-agents tree: a vertical spine on the left with a branch into each dot). */
@@ -220,10 +266,14 @@ body{
220
266
  .side-project .sp-select{padding:11px 38px 11px 13px;font-size:13.5px;font-weight:600;border-radius:12px;}
221
267
  .nav-label{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
222
268
  color:var(--ink-3);padding:8px 12px 6px;}
223
- .side-foot{margin-top:auto;display:flex;flex-direction:column;gap:14px;padding-top:14px;}
269
+ /* The three numbers are one number: the toggle hangs between the spend card and
270
+ the rail's bottom edge exactly as Settings hangs between the divider and that
271
+ same card, so padding-top (above Settings), gap (above the toggle) and
272
+ .sidebar's padding-bottom (below it) all read 10px. */
273
+ .side-foot{margin-top:auto;display:flex;flex-direction:column;gap:10px;padding-top:10px;}
224
274
  .user{display:flex;align-items:center;gap:11px;padding:6px 8px;}
225
275
  .user .ava{width:36px;height:36px;border-radius:50%;flex:0 0 auto;
226
- background:linear-gradient(135deg,#cfcfca,#a8a8a2);}
276
+ background:linear-gradient(135deg,var(--ava-a),var(--ava-b));}
227
277
  .user .who{font-weight:600;line-height:1.2;}
228
278
  .user .who small{display:block;color:var(--ink-3);font-weight:500;font-size:11.5px;}
229
279
 
@@ -242,12 +292,12 @@ body{
242
292
  The compact top-nav (<1080px) is a SIBLING above the views inside .main, so a
243
293
  plain height:100% here would push the track past the viewport and
244
294
  overflow:hidden would clip both screens' bottoms off-screen. */
245
- body.view-history .main{display:flex;flex-direction:column;overflow:hidden;padding:0;}
295
+ body.view-history .main,body.view-projects .main{display:flex;flex-direction:column;overflow:hidden;padding:0;}
246
296
  /* .main's 32px gutter goes with padding:0, so the compact top-nav (<1080px, a
247
297
  SIBLING of the views inside .main) must re-apply it or it lands 20px left of
248
298
  the list content, which keeps its own 32px on .hist-screen. flex:0 0 auto
249
299
  stops the wrapped 9-button nav from being squeezed once .main is a column. */
250
- body.view-history .topnav{margin:12px 32px 0;flex:0 0 auto;}
300
+ body.view-history .topnav,body.view-projects .topnav{margin:12px 32px 0;flex:0 0 auto;}
251
301
  .topbar{display:flex;align-items:flex-start;justify-content:space-between;
252
302
  gap:24px;margin-bottom:22px;}
253
303
  .topbar h1{font-size:26px;font-weight:700;letter-spacing:-.025em;margin:0 0 4px;}
@@ -285,7 +335,7 @@ body.view-history .topnav{margin:12px 32px 0;flex:0 0 auto;}
285
335
  .n-red{background:var(--red-bg);color:var(--red-ink);}
286
336
  .n-blue{background:var(--blue-bg);color:var(--blue-ink);}
287
337
  .n-violet{background:var(--violet-bg);color:var(--violet-ink);}
288
- .n-amber{background:var(--amber);color:#fff;}
338
+ .n-amber{background:var(--amber);color:var(--on-status);}
289
339
  .n-grey{background:var(--field);color:var(--ink-3);}
290
340
 
291
341
  /* ---------- Grid ---------- */
@@ -316,7 +366,7 @@ input[type="text"],input[type="number"],textarea,select{
316
366
  .input::placeholder,.textarea::placeholder,
317
367
  input[type="text"]::placeholder,input[type="number"]::placeholder,textarea::placeholder{color:var(--ink-3);}
318
368
  .input:focus,.select:focus,.textarea:focus,
319
- input[type="text"]:focus,input[type="number"]:focus,textarea:focus,select:focus{outline:none;background:#fff;border-color:var(--ink);}
369
+ input[type="text"]:focus,input[type="number"]:focus,textarea:focus,select:focus{outline:none;background:var(--field-focus);border-color:var(--ink);}
320
370
  .input:focus-visible,.select:focus-visible,.textarea:focus-visible,
321
371
  input[type="text"]:focus-visible,input[type="number"]:focus-visible,textarea:focus-visible,select:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
322
372
  .textarea,textarea{resize:vertical;min-height:120px;line-height:1.5;}
@@ -344,10 +394,10 @@ input[type="file"]{font-size:12.5px;color:var(--ink-3);background:transparent;bo
344
394
  .info-tip:hover{border-color:var(--ink);color:var(--ink);}
345
395
  .info-tip:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
346
396
  /* The shared floating bubble (created once by app.js, filled per icon). */
347
- .info-bubble{position:fixed;z-index:70;background:var(--ink);color:#fff;border-radius:10px;
397
+ .info-bubble{position:fixed;z-index:70;background:var(--ink);color:var(--on-ink);border-radius:10px;
348
398
  padding:10px 13px;font-size:12px;line-height:1.5;max-width:340px;box-shadow:var(--shadow);
349
399
  pointer-events:none;}
350
- .info-bubble code{font-family:var(--mono);font-size:11px;background:rgba(255,255,255,.14);
400
+ .info-bubble code{font-family:var(--mono);font-size:11px;background:var(--on-ink-code);
351
401
  border-radius:4px;padding:1px 4px;}
352
402
  .info-bubble .tip-desc{display:block;}
353
403
  .info-bubble .tip-line{display:block;margin-top:6px;font-family:var(--mono);font-size:10.5px;letter-spacing:.02em;opacity:.75;}
@@ -358,7 +408,7 @@ input[type="file"]{font-size:12.5px;color:var(--ink-3);background:transparent;bo
358
408
  .icon-btn{width:48px;flex:0 0 48px;border-radius:var(--r-ctrl);border:1.5px solid var(--line-2);
359
409
  background:var(--field);cursor:pointer;display:grid;place-items:center;color:var(--ink-2);
360
410
  font-size:18px;transition:background .15s,color .15s;}
361
- .icon-btn:hover{background:#fff;color:var(--ink);}
411
+ .icon-btn:hover{background:var(--surface);color:var(--ink);}
362
412
 
363
413
  /* project selector row */
364
414
  .project-row{display:flex;gap:11px;align-items:center;}
@@ -385,7 +435,7 @@ input[type="file"]{font-size:12.5px;color:var(--ink-3);background:transparent;bo
385
435
  .seg{display:inline-flex;background:var(--field);border-radius:12px;padding:4px;gap:4px;}
386
436
  .seg button{font-family:inherit;font-weight:600;font-size:13px;color:var(--ink-2);
387
437
  background:transparent;border:none;padding:8px 20px;border-radius:9px;cursor:pointer;transition:.15s;}
388
- .seg button.on{background:#fff;color:var(--ink);box-shadow:var(--shadow-soft);}
438
+ .seg button.on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-soft);}
389
439
  .seg button:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
390
440
 
391
441
  /* Settings tab strip. .seg gives the pill chrome; this only spaces it from the
@@ -405,7 +455,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
405
455
  /* file picker */
406
456
  .file{display:flex;align-items:center;gap:13px;background:var(--field);border:1.5px dashed var(--line-2);
407
457
  border-radius:var(--r-ctrl);padding:13px 15px;}
408
- .file .pick{background:#fff;border:1px solid var(--line-2);border-radius:9px;padding:8px 14px;
458
+ .file .pick{background:var(--surface);border:1px solid var(--line-2);border-radius:9px;padding:8px 14px;
409
459
  font-family:inherit;font-weight:600;font-size:12.5px;cursor:pointer;color:var(--ink);white-space:nowrap;}
410
460
  .file .state{color:var(--ink-3);font-size:12.5px;}
411
461
  .file-load{display:inline-block;margin-top:8px;}
@@ -458,7 +508,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
458
508
  .ta-hl > textarea.textarea,
459
509
  .ta-hl > textarea.textarea:focus{display:block;position:relative;z-index:1;
460
510
  background:transparent;color:transparent;caret-color:var(--ink);}
461
- .ta-hl > textarea.textarea::selection{background:rgba(25,25,27,.16);}
511
+ .ta-hl > textarea.textarea::selection{background:var(--selection);}
462
512
  /* font-weight/style/variant/stretch are the ONLY text-layout properties the two
463
513
  layers do not already share: Chrome's UA `font: -webkit-small-control`
464
514
  shorthand on <textarea> resets them, while this div would inherit them from
@@ -470,7 +520,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
470
520
  .ta-hl-back{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;
471
521
  line-height:1.5;white-space:pre-wrap;overflow-wrap:break-word;border-color:transparent;
472
522
  font-weight:400;font-style:normal;font-variant:normal;font-stretch:normal;}
473
- .ta-hl:focus-within .ta-hl-back{background:#fff;}
523
+ .ta-hl:focus-within .ta-hl-back{background:var(--field-focus);}
474
524
  .mention-ok{color:var(--blue-ink);}
475
525
 
476
526
  /* High Contrast forces the textarea's transparent text back to CanvasText while
@@ -487,7 +537,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
487
537
  .switch{width:44px;height:26px;border-radius:999px;background:var(--line-2);position:relative;
488
538
  cursor:pointer;flex:0 0 auto;transition:background .18s;}
489
539
  .switch::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
490
- background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.18);transition:left .18s;}
540
+ background:var(--knob);box-shadow:var(--knob-shadow);transition:left .18s;}
491
541
  .switch.on{background:var(--green);}
492
542
  .switch.on::after{left:21px;}
493
543
  .switch:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
@@ -495,10 +545,10 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
495
545
 
496
546
  /* ---------- buttons ---------- */
497
547
  .actions{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:22px;}
498
- .btn-ghost{background:#fff;border:1.5px solid var(--line-2);color:var(--ink);font-family:inherit;
548
+ .btn-ghost{background:var(--surface);border:1.5px solid var(--line-2);color:var(--ink);font-family:inherit;
499
549
  font-weight:600;font-size:13.5px;padding:13px 20px;border-radius:999px;cursor:pointer;transition:.15s;}
500
550
  .btn-ghost:hover{background:var(--field);}
501
- .btn-go{display:inline-flex;align-items:center;gap:9px;background:var(--ink);color:#fff;border:none;
551
+ .btn-go{display:inline-flex;align-items:center;gap:9px;background:var(--ink);color:var(--on-ink);border:none;
502
552
  font-family:inherit;font-weight:600;font-size:14px;padding:14px 28px;border-radius:999px;cursor:pointer;
503
553
  transition:transform .15s,filter .15s;}
504
554
  .btn-go:hover{transform:translateY(-1px);filter:brightness(1.08);}
@@ -506,13 +556,13 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
506
556
 
507
557
  /* generic .btn / .btn-primary (question + gate JS, old markup) restyled to pills */
508
558
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
509
- background:#fff;border:1.5px solid var(--line-2);color:var(--ink);font-family:inherit;
559
+ background:var(--surface);border:1.5px solid var(--line-2);color:var(--ink);font-family:inherit;
510
560
  font-weight:600;font-size:13.5px;padding:13px 20px;border-radius:999px;cursor:pointer;
511
561
  transition:background .15s,filter .15s,transform .15s,border-color .15s;}
512
562
  .btn:hover:not(:disabled){background:var(--field);}
513
563
  .btn:disabled{opacity:.45;cursor:not-allowed;}
514
564
  .btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
515
- .btn-primary{background:var(--ink);border-color:var(--ink);color:#fff;}
565
+ .btn-primary{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
516
566
  .btn-primary:hover:not(:disabled){background:var(--ink);transform:translateY(-1px);filter:brightness(1.08);}
517
567
  .btn-danger{background:var(--red-bg);border-color:transparent;color:var(--red-ink);}
518
568
  .btn-danger:hover:not(:disabled){background:var(--red-bg);filter:brightness(.97);}
@@ -543,7 +593,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
543
593
  .agents-head{display:flex;align-items:center;gap:10px;padding:11px 14px;border-bottom:1px solid var(--line);}
544
594
  .agents-title{font-weight:700;font-size:13px;}
545
595
  .agents-wf{flex:0 0 auto;font-size:11.5px;font-weight:600;color:var(--ink-2);
546
- background:#fff;border:1px solid var(--line-2);border-radius:999px;padding:2px 9px;
596
+ background:var(--surface);border:1px solid var(--line-2);border-radius:999px;padding:2px 9px;
547
597
  max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
548
598
  .agents-wf:empty{display:none;}
549
599
  .agents-summary{color:var(--ink-3);font-size:12px;flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
@@ -555,7 +605,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
555
605
  .agents-actions{display:flex;gap:6px;flex:0 0 auto;}
556
606
  .agents-actions .btn-mini{font-size:11.5px;padding:5px 10px;}
557
607
 
558
- .agent-row{border-top:1px solid var(--line);background:#fff;}
608
+ .agent-row{border-top:1px solid var(--line);background:var(--panel);}
559
609
  .agent-row:first-child{border-top:none;}
560
610
  .agent-row-head{display:flex;align-items:center;gap:10px;width:100%;padding:10px 14px;
561
611
  background:none;border:none;font-family:inherit;font-size:13px;text-align:left;cursor:pointer;color:inherit;}
@@ -579,7 +629,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
579
629
  .agent-desc{display:block;margin-bottom:9px;color:var(--ink-3);font-size:12px;line-height:1.45;overflow-wrap:anywhere;}
580
630
  .agent-row-body .picks{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;}
581
631
  .agent-row-body .select-wrap{width:180px;}
582
- .agent-row-body .select{padding:10px 36px 10px 13px;font-size:13px;border-radius:11px;background:#fff;border-color:var(--line-2);}
632
+ .agent-row-body .select{padding:10px 36px 10px 13px;font-size:13px;border-radius:11px;background:var(--surface);border-color:var(--line-2);}
583
633
  .agent-origin{display:block;margin-top:4px;color:var(--ink-3);font-size:11.5px;}
584
634
  .fb-field{margin-bottom:10px;}
585
635
  .fb-field:last-child{margin-bottom:0;}
@@ -625,10 +675,15 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
625
675
  .advanced[open] .adv-chev{transform:rotate(90deg);}
626
676
  .advanced-body{padding-top:12px;}
627
677
  .advanced-body .switch-row{margin-top:4px;}
678
+ /* `.switch-row{display:flex}` (:537) beats the UA [hidden] rule (this file's own footgun), so the
679
+ Auto row and its hint need explicit rules. The .sw-input bridge (:3370) requires `.switch` to be
680
+ the input's NEXT sibling — the markup keeps them adjacent. */
681
+ #hitl-row[hidden]{display:none;}
682
+ #hitl-row[hidden]+#hitlHint{display:none;}
628
683
 
629
684
  /* per-step model/effort controls (app.js: .step-config / .step-model / .step-effort / .step-current) */
630
685
  .step-config{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px;}
631
- .step-config select{width:auto;font-size:12.5px;padding:8px 30px 8px 11px;border-radius:10px;background:#fff;border-color:var(--line-2);}
686
+ .step-config select{width:auto;font-size:12.5px;padding:8px 30px 8px 11px;border-radius:10px;background:var(--surface);border-color:var(--line-2);}
632
687
  .step-config select:disabled{opacity:.6;cursor:not-allowed;}
633
688
  .step-current{flex-basis:100%;width:100%;text-align:right;margin-top:2px;color:var(--ink-3);font-size:11.5px;}
634
689
 
@@ -639,7 +694,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
639
694
  .btn-clear{background:var(--field);border:none;border-radius:10px;padding:8px 15px;font-family:inherit;
640
695
  font-weight:600;font-size:12.5px;cursor:pointer;color:var(--ink-2);transition:.15s;}
641
696
  .btn-clear:hover{background:var(--line-2);}
642
- .log{background:#fff;border:1px solid var(--line);border-radius:16px;min-height:260px;max-height:380px;overflow-y:auto;
697
+ .log{background:var(--panel);border:1px solid var(--line);border-radius:16px;min-height:260px;max-height:380px;overflow-y:auto;
643
698
  padding:18px 20px;font-family:var(--mono);font-size:12.5px;line-height:1.85;color:var(--ink-2);
644
699
  white-space:pre-wrap;word-break:break-word;}
645
700
  .log .t{color:var(--ink-3);}
@@ -730,7 +785,10 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
730
785
  the global 100%-width select rule; min-width:0 lets bar and pills shrink) */
731
786
  .log-filters{display:flex;gap:6px;align-items:center;flex-wrap:nowrap;min-width:0;}
732
787
  .log-filters .log-f{font:inherit;font-size:12px;padding:4px 6px;border:1px solid var(--line);border-radius:8px;
733
- background:#fff;color:var(--ink-2);max-width:150px;width:auto;min-width:0;}
788
+ background:var(--surface);color:var(--ink-2);max-width:150px;width:auto;min-width:0;}
789
+ /* input[type=search] is outside the ::placeholder rule at the top of the file; the UA
790
+ default grey is 2.6:1 on the dark --surface. Light: #5C5C63 instead of #757575 — both pass. */
791
+ .log-filters .log-search::placeholder{color:var(--ink-2);}
734
792
  /* search is the only pill that grows (own max-width beats the pill cap above);
735
793
  copy pins to the bar's right edge via the auto margin */
736
794
  .log-filters .log-search{flex:1 1 160px;max-width:340px;}
@@ -773,7 +831,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
773
831
  .qblock{padding:13px 0 0;}
774
832
  .qtext{font-weight:500;font-size:13px;margin:0 0 9px;display:flex;align-items:flex-start;
775
833
  gap:9px;line-height:1.45;}
776
- .qtext .qn{flex:0 0 auto;width:19px;height:19px;border-radius:50%;background:var(--ink);color:#fff;
834
+ .qtext .qn{flex:0 0 auto;width:19px;height:19px;border-radius:50%;background:var(--ink);color:var(--on-ink);
777
835
  font-family:var(--mono);font-size:10.5px;font-weight:600;display:grid;place-items:center;margin-top:1px;}
778
836
  /* the option column and the free-text field line up under the number circle */
779
837
  .qopts{display:flex;flex-direction:column;align-items:stretch;gap:7px;margin:0 0 7px;padding-left:28px;}
@@ -834,12 +892,38 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
834
892
  becomes space-between, and `margin-right:auto` on the counter achieves that
835
893
  WITHOUT a second .qpanel-foot rule that the footer test would then contradict. */
836
894
  .qanswered{margin-right:auto;font:500 11.5px var(--mono);color:var(--ink-3);}
895
+
896
+ /* ---------- the `workflow` question arm (spec §7.4): Auto's proposal in a qpanel ---------- */
897
+ .qpanel-workflow .qpanel-head .qcount{font-family:var(--mono);font-weight:600;letter-spacing:.06em;}
898
+ .qbody{display:flex;flex-direction:column;margin-top:12px;}
899
+ .qbody>*{min-width:0;}
900
+ .qnote{margin:12px 0;padding:10px 12px;background:var(--amber-wash-2);border:1px solid var(--amber-line);border-radius:10px;font-size:13px;line-height:1.5;color:var(--ink-2);}
901
+ .qnote b{font-weight:600;color:var(--ink);}
902
+ /* The revise echo already carries its own 12px bottom margin — one child-selector
903
+ deeper than the generic name margin below, so it wins wherever both match. */
904
+ .ask-wfcard-body>.qnote+.ask-wfcard-namewrap{margin-top:0;}
905
+ .qtune{width:100%;border-collapse:collapse;table-layout:fixed;margin-top:16px;font-size:13px;}
906
+ .qtune th{text-align:left;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);font-weight:400;height:32px;padding:0 8px;border-bottom:1px solid var(--line);white-space:nowrap;}
907
+ .qtune td{height:44px;padding:0 8px;border-bottom:1px solid var(--line);vertical-align:middle;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
908
+ .qtune th:first-child,.qtune td:first-child{padding-left:0;}
909
+ .qtune td:first-child{font-weight:500;color:var(--ink);}
910
+ .qtune .select-wrap{width:150px;max-width:100%;}
911
+ .qtune .select-wrap select{height:34px;border-radius:10px;}
912
+ .qtune-sw{display:inline-block;position:relative;vertical-align:middle;}
913
+ /* (no disabled rule here: `.sw-input:disabled + .switch{opacity:.5;cursor:not-allowed}` already exists) */
914
+ .qfree-area{margin-top:12px;min-height:64px;resize:vertical;line-height:1.5;}
915
+ .qfree-area[hidden]{display:none;}
916
+ .qfree.qfree-err{border-color:var(--red);}
917
+ .qcancel{margin-right:auto;height:36px;padding:0 8px;border:0;border-radius:999px;background:transparent;color:var(--red-ink);font-family:inherit;font-weight:600;font-size:13px;cursor:pointer;}
918
+ .qcancel:hover{background:var(--red-bg);}
919
+ .qcancel:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
920
+ .qopen[hidden]{display:none;}
837
921
  .rd-questions .qanswered{font-size:12.5px;}
838
922
 
839
923
  /* ---------- Gate (cycle gate) ---------- */
840
924
  .gate-intro{font-size:13px;color:var(--ink-2);margin:0 0 14px;line-height:1.5;}
841
925
  .issues{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:9px;}
842
- .issue{background:#fff;border:1px solid var(--line);border-left-width:3px;border-radius:11px;padding:12px 14px;}
926
+ .issue{background:var(--panel);border:1px solid var(--line);border-left-width:3px;border-radius:11px;padding:12px 14px;}
843
927
  .issue.sev-critical{border-left-color:var(--red);}
844
928
  .issue.sev-major{border-left-color:var(--peach);}
845
929
  .issue.sev-minor{border-left-color:var(--amber);}
@@ -891,7 +975,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
891
975
  .retained-banner ul{margin:9px 0;padding-left:20px;}
892
976
  .retained-banner li+li{margin-top:8px;}
893
977
  .retained-banner code{display:block;margin-top:4px;padding:7px 9px;border-radius:8px;
894
- background:rgba(255,255,255,.7);color:var(--ink);font-family:var(--mono);font-size:11.5px;
978
+ background:var(--panel-wash);color:var(--ink);font-family:var(--mono);font-size:11.5px;
895
979
  white-space:pre-wrap;word-break:break-all;}
896
980
  .retained-banner a{color:var(--amber-ink);font-weight:700;}
897
981
  .hist-empty{color:var(--ink-3);font-size:13px;padding:22px 4px;text-align:center;}
@@ -908,7 +992,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
908
992
  font-size:12.5px;color:var(--ink-2);cursor:pointer;white-space:nowrap;
909
993
  transition:border-color .12s,color .12s,background .12s;}
910
994
  .hist-pill:hover{border-color:var(--ink-3);color:var(--ink);}
911
- .hist-pill.active{background:var(--ink);border-color:var(--ink);color:#fff;}
995
+ .hist-pill.active{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
912
996
  .hist-pill .pill-count{font-size:11px;font-weight:600;opacity:.7;}
913
997
 
914
998
  /* ---------- History per-project sticky sections (All Projects view) ---------- */
@@ -919,7 +1003,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
919
1003
  .hist-group-head .pill-count{font-size:11.5px;font-weight:600;color:var(--ink-3);}
920
1004
 
921
1005
  /* ---------- Saved-markdown viewer ---------- */
922
- .viewer{font-family:var(--mono);font-size:12.5px;line-height:1.7;background:#FBFBF9;border:1px solid var(--line);
1006
+ .viewer{font-family:var(--mono);font-size:12.5px;line-height:1.7;background:var(--canvas-2);border:1px solid var(--line);
923
1007
  border-radius:16px;padding:18px 20px;max-height:480px;overflow:auto;white-space:pre-wrap;word-break:break-word;margin:0;}
924
1008
 
925
1009
  /* ---------- scrollbars ---------- */
@@ -955,7 +1039,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
955
1039
  of the (locked) Refined stylesheet: the viewer modal + the responsive
956
1040
  top-nav shown only when the sidebar is hidden (<1080px). */
957
1041
  .viewer-modal{position:fixed;inset:0;z-index:50;display:grid;place-items:center;
958
- padding:24px;background:rgba(25,25,27,.42);}
1042
+ padding:24px;background:var(--scrim);}
959
1043
  /* Confirm dialog must stack ABOVE the plugin/wizard modal (equal .viewer-modal z-index,
960
1044
  but #confirm-modal precedes #plugin-modal in the DOM). */
961
1045
  #confirm-modal.viewer-modal{z-index:60;}
@@ -986,7 +1070,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
986
1070
  background:transparent;color:var(--ink-2);font-family:inherit;font-weight:600;font-size:13px;
987
1071
  cursor:pointer;transition:.15s;}
988
1072
  .topnav button:hover{background:var(--field);color:var(--ink);}
989
- .topnav button.active{background:var(--ink);color:#fff;}
1073
+ .topnav button.active{background:var(--ink);color:var(--on-ink);}
990
1074
  .topnav button:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
991
1075
  .topnav-sep{flex:0 0 1px;background:var(--line-2);margin:6px 2px;}
992
1076
  }
@@ -1029,6 +1113,12 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1029
1113
  the bare `.diff-add`/`.diff-del` rules further down. */
1030
1114
  .hist-diff{display:inline-flex;gap:6px;font-family:var(--mono);font-size:12px;font-weight:700;}
1031
1115
 
1116
+ /* Spec §7.5: the "Auto → ‹workflow name›" badge, in all three headers. */
1117
+ .auto-badge{display:inline-flex;align-items:center;max-width:220px;padding:3px 9px;border-radius:999px;font-size:10.5px;font-weight:700;letter-spacing:.04em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
1118
+ background:var(--violet-bg);color:var(--violet-ink);flex:0 0 auto;}
1119
+ .auto-badge[hidden]{display:none;}
1120
+ .auto-badge.is-deciding{background:var(--amber-bg);color:var(--amber-ink);}
1121
+ .rc-acts .auto-badge{max-width:160px;}
1032
1122
  .hist-merge{font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:3px 8px;border-radius:999px;white-space:nowrap;}
1033
1123
  .hist-merge[hidden]{display:none;}
1034
1124
  .hist-merge.ok{background:var(--green-bg);color:var(--green-ink);}
@@ -1043,7 +1133,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1043
1133
  UA anchor — browser blue, underlined — and MERGED would lose its grey. */
1044
1134
  .hist-pr-link,.hd-pr-link{font-size:12px;font-weight:600;color:var(--green-ink);text-decoration:none;white-space:nowrap;}
1045
1135
  .hist-pr-link:hover,.hd-pr-link:hover{text-decoration:underline;}
1046
- .hist-pr-link.merged,.hd-pr-link.merged{color:var(--muted, #888);}
1136
+ .hist-pr-link.merged,.hd-pr-link.merged{color:var(--ink-3);}
1047
1137
 
1048
1138
  /* Discard-worktree button. The class moved from the retired card accordion to the
1049
1139
  detail screen's banner block; nothing about it was card-position-dependent. */
@@ -1054,8 +1144,8 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1054
1144
  .hist-discard[hidden]{display:none;}
1055
1145
  /* This block is SHARED with the Plugins view's `.pl-remove`; the retired
1056
1146
  `.hist-delete` arms were removed from the selector lists, the block stays. */
1057
- .pl-remove{display:inline-flex;align-items:center;gap:6px;background:var(--red-ink,#d9534f);
1058
- border:1.5px solid var(--red-ink,#d9534f);color:#fff;font-family:inherit;font-weight:600;
1147
+ .pl-remove{display:inline-flex;align-items:center;gap:6px;background:var(--red-ink);
1148
+ border:1.5px solid var(--red-ink);color:var(--on-status);font-family:inherit;font-weight:600;
1059
1149
  font-size:12px;padding:6px 12px;border-radius:8px;cursor:pointer;}
1060
1150
  .pl-remove:hover:not(:disabled){filter:brightness(0.95);}
1061
1151
  .pl-remove:disabled{opacity:.6;cursor:default;}
@@ -1073,7 +1163,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1073
1163
  .export-done.hidden{display:none;}
1074
1164
  .export-done-head{display:flex;align-items:center;gap:10px;font-size:14px;margin-bottom:12px;}
1075
1165
  .export-done-check{display:grid;place-items:center;width:26px;height:26px;border-radius:999px;
1076
- background:var(--green-bg,#e6f4ea);color:var(--green-ink,#1e6b3a);font-weight:700;font-size:14px;}
1166
+ background:var(--green-bg);color:var(--green-ink);font-weight:700;font-size:14px;}
1077
1167
  .export-done-lines{display:grid;grid-template-columns:max-content 1fr;gap:6px 14px;margin:0;font-size:12.5px;}
1078
1168
  .export-done-lines dt{color:var(--ink-3);font-weight:600;}
1079
1169
  .export-done-lines dd{margin:0;color:var(--ink);word-break:break-all;}
@@ -1087,20 +1177,21 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1087
1177
  .export-row{padding:4px 2px;display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
1088
1178
  .export-conflict-row{flex-direction:column;align-items:flex-start;}
1089
1179
  .export-tag{display:inline-block;min-width:58px;text-align:center;border-radius:6px;padding:1px 6px;font-weight:700;font-size:11px;}
1090
- .export-create{background:var(--green-bg,#e6f7ec);color:var(--green-ink,#137a3b);}
1180
+ .export-create{background:var(--green-bg);color:var(--green-ink);}
1091
1181
  .export-update{background:var(--field);color:var(--ink);}
1092
1182
  .export-no-op{background:var(--field);color:var(--ink-3);}
1093
- .export-warn,.export-conflict{background:var(--red-bg,#fde8e8);color:var(--red-ink,#b42323);}
1183
+ .export-warn,.export-conflict{background:var(--red-bg);color:var(--red-ink);}
1094
1184
  .export-orphan{background:var(--field);color:var(--ink-3);}
1095
1185
  .export-choices{display:flex;gap:12px;margin:4px 0 2px 64px;}
1096
- .export-choice{font-size:12.5px;color:var(--ink-2);cursor:pointer;}
1186
+ .export-choice{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink-2);cursor:pointer;}
1187
+ .export-choice input[type="radio"]{margin:0;}
1097
1188
  /* Per-agent fan-out toggle in the New Pipeline rows. */
1098
1189
  .fanout-toggle {
1099
1190
  display: inline-flex;
1100
1191
  align-items: center;
1101
1192
  gap: 6px;
1102
1193
  font-size: 12px;
1103
- color: var(--muted, #888);
1194
+ color: var(--ink-3);
1104
1195
  white-space: nowrap;
1105
1196
  cursor: pointer;
1106
1197
  user-select: none;
@@ -1137,16 +1228,40 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1137
1228
  .ws-head:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
1138
1229
  .ws-h-meta{flex:1;min-width:0;display:flex;flex-wrap:wrap;align-items:center;gap:8px;}
1139
1230
  .ws-h-meta .ws-name{font-weight:600;font-size:15px;letter-spacing:-.01em;color:var(--ink);}
1140
- .ws-h-meta .ws-projects{display:block;width:100%;font-family:var(--mono);font-size:12px;color:var(--ink-3);}
1231
+ .ws-h-meta .ws-projects{display:block;width:100%;font-size:12.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
1232
+ .ws-projects .mono{font-size:12px;color:var(--ink-2);}
1233
+ .ws-projects .tm-home-mark{margin-right:5px;}
1234
+ .ws-sum-warn{color:var(--amber-ink);} .ws-sum-bad{color:var(--red-ink);}
1235
+ .tm-icon{width:14px;height:14px;color:var(--ink-2);flex:0 0 auto;}
1141
1236
  .ws-stale[hidden]{display:none;}
1142
1237
  .ws-actions{display:flex;align-items:center;gap:8px;flex:0 0 auto;}
1143
1238
  .ws-actions .btn-ghost{padding:7px 12px;font-size:12px;}
1144
- .ws-card .chev{width:15px;height:15px;flex:0 0 auto;color:var(--ink-3);}
1145
1239
  .ws-detail{padding:0 20px 18px;border-top:1px dashed var(--line-2);}
1146
1240
  .ws-detail[hidden]{display:none;}
1147
- .ws-desc-view{margin-top:14px;}
1241
+ .ws-desc{margin-top:14px;padding-top:12px;border-top:1px solid var(--line);}
1242
+ /* The wizard's project rows show each path as a sub-line (new on this branch): --ink-2 clears
1243
+ 4.5:1 on white, the generic .opt-sub --ink-3 does not. */
1244
+ .wiz-proj.opt-row .opt-sub{color:var(--ink-2);} /* three classes: outranks the generic .opt-row .opt-sub declared later */
1245
+ .ws-desc-view{margin-top:8px;}
1148
1246
  .ws-desc-edit[hidden]{display:none;}
1149
- .ws-delete{display:inline-flex;align-items:center;gap:6px;background:var(--red-ink,#d9534f);border:1.5px solid var(--red-ink,#d9534f);color:#fff;font-family:inherit;font-weight:600;font-size:12px;padding:7px 12px;border-radius:8px;cursor:pointer;}
1247
+ .ws-desc-edit .md-tabs{margin-bottom:8px;}
1248
+ .ws-desc-preview[hidden]{display:none;}
1249
+ /* A markdown-by-contract body (workspace description, its edit preview, a task-source
1250
+ body) keeps the .viewer frame but drops the pre look once it actually rendered:
1251
+ sans type, normal flow (marked emits its own breaks) and no stray outer margins. */
1252
+ .viewer.artifact-markdown,.sp-prev-body.artifact-markdown{white-space:normal;font-family:var(--sans);font-size:13px;line-height:1.55;}
1253
+ .artifact-markdown>:first-child{margin-top:0;}
1254
+ .artifact-markdown>:last-child{margin-bottom:0;}
1255
+ .artifact-markdown :is(h1,h2,h3){font-size:14px;font-weight:600;}
1256
+ .artifact-markdown h1{font-size:15px;}
1257
+ .artifact-markdown :is(ul,ol){padding-left:22px;margin:6px 0;}
1258
+ .artifact-markdown li{margin:2px 0;}
1259
+ .artifact-markdown p{margin:6px 0;}
1260
+ .md-preview{min-height:72px;}
1261
+ .md-preview:empty::before{content:'Nothing to preview yet';color:var(--ink-2);}
1262
+ #wiz-desc-tabs{margin-left:auto;}
1263
+ #wiz-desc-preview[hidden]{display:none;}
1264
+ .ws-delete{display:inline-flex;align-items:center;gap:6px;background:var(--red-ink);border:1.5px solid var(--red-ink);color:var(--on-status);font-family:inherit;font-weight:600;font-size:12px;padding:7px 12px;border-radius:8px;cursor:pointer;}
1150
1265
  .ws-delete:hover:not(:disabled){filter:brightness(0.95);}
1151
1266
  .ws-delete:disabled{opacity:.6;cursor:default;}
1152
1267
 
@@ -1154,7 +1269,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1154
1269
  .wiz-step.hidden{display:none;}
1155
1270
  .wiz-proj-list{display:flex;flex-direction:column;gap:2px;border:1.5px solid var(--line-2);border-radius:var(--r-ctrl);padding:6px;background:var(--field);}
1156
1271
  .wiz-proj{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:10px;cursor:pointer;font-size:13.5px;color:var(--ink);}
1157
- .wiz-proj:hover{background:#fff;}
1272
+ .wiz-proj:hover{background:var(--surface);}
1158
1273
  .wiz-proj input{margin:0;cursor:pointer;}
1159
1274
  .wiz-proj.missing{color:var(--ink-3);cursor:not-allowed;}
1160
1275
 
@@ -1177,11 +1292,11 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1177
1292
  /* Phase track: graph → investigate → synthesize. */
1178
1293
  .wiz-phase-track{display:flex;align-items:center;justify-content:center;gap:10px;margin:6px 0 14px;}
1179
1294
  .wiz-phase-track [data-phase]{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);background:var(--field);border:1px solid var(--line);border-radius:999px;padding:6px 14px;}
1180
- .wiz-phase-track [data-phase].active{color:#fff;background:var(--ink);border-color:var(--ink);}
1295
+ .wiz-phase-track [data-phase].active{color:var(--on-ink);background:var(--ink);border-color:var(--ink);}
1181
1296
 
1182
1297
  /* History pill "WS" badge for workspace runs. */
1183
1298
  .hist-pill.ws::before{content:'WS';font-size:9px;font-weight:800;letter-spacing:.06em;background:var(--violet-bg);color:var(--violet-ink);border-radius:5px;padding:2px 5px;margin-right:2px;}
1184
- .hist-pill.ws.active::before{background:rgba(255,255,255,.22);color:#fff;}
1299
+ .hist-pill.ws.active::before{background:var(--on-ink-wash-2);color:var(--on-ink);}
1185
1300
 
1186
1301
  /* ========================================================================== */
1187
1302
  /* Run-flow — the SHARED decor the v2 graph renderer sits inside. The .run-flow */
@@ -1190,14 +1305,14 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1190
1305
  /* ties `.gv-world .node` and loses on source order — silently killing the v2 */
1191
1306
  /* status border colours. */
1192
1307
  /* ========================================================================== */
1193
- .run-flow-wrap{position:relative;margin:0 0 18px;border-radius:18px;border:1px solid var(--line);overflow-x:auto;overflow-y:hidden;background-color:#FBFBF9;background-image:radial-gradient(circle, var(--line-2) 1.1px, transparent 1.1px);background-size:22px 22px;}
1308
+ .run-flow-wrap{position:relative;margin:0 0 18px;border-radius:18px;border:1px solid var(--line);overflow-x:auto;overflow-y:hidden;background-color:var(--canvas-2);background-image:radial-gradient(circle, var(--line-2) 1.1px, transparent 1.1px);background-size:22px 22px;}
1194
1309
  .run-flow{position:relative;display:flex;align-items:center;gap:44px;padding:66px 30px 52px;width:max-content;min-width:100%;}
1195
1310
  /* Status badge (top-right pip). */
1196
1311
  .run-flow .nstat{position:absolute;top:-8px;right:-8px;width:21px;height:21px;border-radius:50%;display:grid;place-items:center;box-shadow:var(--shadow-soft);z-index:3;}
1197
1312
  .run-flow .nstat svg{width:12px;height:12px;}
1198
- .run-flow .nstat.done{background:var(--green);} .run-flow .nstat.done svg{stroke:#fff;stroke-width:3;}
1199
- .run-flow .nstat.paused{background:var(--amber);} .run-flow .nstat.paused svg{fill:#fff;}
1200
- .run-flow .nstat.stopped{background:var(--red);} .run-flow .nstat.stopped svg{stroke:#fff;stroke-width:3;}
1313
+ .run-flow .nstat.done{background:var(--green);} .run-flow .nstat.done svg{stroke:var(--on-status);stroke-width:3;}
1314
+ .run-flow .nstat.paused{background:var(--amber);} .run-flow .nstat.paused svg{fill:var(--on-status);}
1315
+ .run-flow .nstat.stopped{background:var(--red);} .run-flow .nstat.stopped svg{stroke:var(--on-status);stroke-width:3;}
1201
1316
 
1202
1317
  .run-flow .node.is-active{border-color:color-mix(in srgb, var(--c) 55%, var(--line-2));animation:nodeGlow 2.2s ease-in-out infinite;}
1203
1318
  .run-flow .node.is-paused{border-color:color-mix(in srgb, var(--amber) 55%, var(--line-2));animation:nodeGlowAmber 2.2s ease-in-out infinite;}
@@ -1283,8 +1398,8 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1283
1398
  text-transform:uppercase; letter-spacing:.04em; opacity:.6; line-height:20px; }
1284
1399
  .agent-chips { display:flex; flex-wrap:wrap; gap:6px; flex:1 1 auto; }
1285
1400
  .agent-chip { font-size:11px; padding:2px 8px; border:1px solid var(--line); border-radius:999px; }
1286
- .agent-chip.prod { background:#E2F3DF; }
1287
- .agent-chip.cons { background:#DEEFF7; }
1401
+ .agent-chip.prod { background:var(--green-bg); }
1402
+ .agent-chip.cons { background:var(--blue-bg); }
1288
1403
  .agent-io-none { font-size:11px; opacity:.45; line-height:20px; }
1289
1404
  .agent-chip.void { border-style:dashed; background:transparent; opacity:.75; }
1290
1405
  .agent-not-placeable { background:var(--amber-bg); color:var(--amber-ink); }
@@ -1313,7 +1428,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1313
1428
 
1314
1429
  /* (2) space between the header pills and the expanded markdown body */
1315
1430
  .agent-detail { margin-top:14px; }
1316
- .agent-origin.origin-user { background:#EAE6F8; }
1431
+ .agent-origin.origin-user { background:var(--violet-bg); }
1317
1432
  .agents-group-label { font-size:12px; font-weight:700; opacity:.65; margin:18px 0 8px; text-transform:uppercase; letter-spacing:.06em; }
1318
1433
  .agent-actions { display:flex; gap:8px; }
1319
1434
  .chip-select { display:flex; flex-wrap:wrap; gap:8px; }
@@ -1324,7 +1439,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1324
1439
  .pl-main/.pl-name), but the composer's copies of those rules are scoped under
1325
1440
  .gv-saved, so this view owns its own layout: card padding 0 so the head and the
1326
1441
  rows share one left edge; flex rows so the bin button sits on the right.
1327
- Static rows (no expand) — default cursor, no hover tint. */
1442
+ A keyed row is the control (see the shell block below); a keyless row keeps the default cursor. */
1328
1443
  #projects-list .saved-card{padding:0;overflow:hidden;}
1329
1444
  #projects-list .pl-item{border-bottom:1px solid var(--line);}
1330
1445
  #projects-list .pl-item:last-child{border-bottom:none;}
@@ -1340,21 +1455,47 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1340
1455
  font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;
1341
1456
  color:var(--ink-3);border:1px solid var(--line-2);border-radius:6px;padding:1px 6px;
1342
1457
  }
1343
- /* Neutral bin button — same size/shape as .pl-del but stays neutral on hover (no red, ever). */
1344
- .proj-del{
1345
- flex:0 0 auto;width:34px;height:34px;border-radius:10px;
1346
- border:1.5px solid var(--line-2);background:#fff;display:grid;place-items:center;
1347
- cursor:pointer;color:var(--ink-3);transition:.12s;align-self:center;
1348
- }
1349
- .proj-del:hover{border-color:var(--ink-3);color:var(--ink);background:var(--field);}
1350
- .proj-del:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
1351
- .proj-del svg{width:16px;height:16px;stroke-width:1.9;}
1458
+ /* ---------- Projects two-screen shell (twin of the History track) ---------- */
1459
+ .view[data-view="projects"]{flex:1 1 auto;min-height:0;padding:0;position:relative;}
1460
+ .proj-shell{position:relative;height:100%;overflow:hidden;}
1461
+ /* NO top padding on the scroller: the detail's sticky .pd-tabs must pin flush, as .hd-tabs does. */
1462
+ .proj-screen{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;padding:0 32px 40px;
1463
+ transition:transform .46s cubic-bezier(.65,.02,.28,1);}
1464
+ .proj-screen-list .topbar{padding-top:26px;}
1465
+ .proj-screen-list{transform:translateX(0);}
1466
+ .proj-screen-detail{transform:translateX(100%);padding:0;background:var(--bg);}
1467
+ .proj-shell.detail-open .proj-screen-list{transform:translateX(-100%);}
1468
+ .proj-shell.detail-open .proj-screen-detail{transform:translateX(0);}
1469
+ .proj-shell.no-anim .proj-screen{transition:none;}
1470
+ /* A keyed row IS the control (role=button): pointer + hover tint, the .hist-head idiom. The
1471
+ keyless row keeps #projects-list .pl-row's default cursor. */
1472
+ #projects-list .pl-row[role="button"]{cursor:pointer;transition:background .12s;}
1473
+ #projects-list .pl-row[role="button"]:hover{background:var(--field);}
1474
+ #projects-list .pl-row[role="button"]:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
1475
+ .proj-open{flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:30px;height:30px;
1476
+ border:1px solid var(--line);border-radius:9px;background:var(--panel);color:var(--ink-2);cursor:pointer;}
1477
+ .proj-open:hover{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
1478
+ /* Project page header: the card, title and Back ride the hd- rules; these are its own lines. */
1479
+ .pd-meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px;min-width:0;margin-top:10px;
1480
+ font-size:12.5px;color:var(--ink-2);overflow-wrap:anywhere;}
1481
+ .pd-actions{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:14px;}
1482
+ .pd-spacer{flex:1 1 24px;}
1483
+ .pd-error{margin-top:12px;color:var(--red-ink);font-size:12.5px;}
1484
+ .pd-error[hidden]{display:none;}
1485
+ /* Overview: a path is long with no natural break, so its value wraps at body size; the LAST RUN
1486
+ card is a real <button> — reset the UA look so it reads like its siblings. */
1487
+ .pd-ov-value.pd-ov-wrap{font-size:13px;overflow-wrap:anywhere;}
1488
+ .pd-ov-missing{color:var(--red-ink);}
1489
+ button.pd-ov-card{text-align:left;font:inherit;color:inherit;cursor:pointer;width:100%;}
1490
+ button.pd-ov-card:hover{border-color:var(--ink-3);}
1491
+ /* Memory tab: the same grid Settings → Memory paints (.mem-host); its message line sits above. */
1492
+ .pd-sec-memory .form-msg{margin:0 0 10px;}
1352
1493
 
1353
1494
  /* Guardrails row editors (used by the Guardrails view) */
1354
1495
  .gr-list{display:flex;flex-direction:column;margin-bottom:8px;}
1355
1496
  .gr-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:7px 0;border-bottom:1px solid var(--line);font-family:var(--mono);font-size:12.5px;}
1356
1497
  .gr-row:last-child{border-bottom:none;}
1357
- .gr-rm{flex:0 0 auto;width:26px;height:26px;border-radius:8px;border:1.5px solid var(--line-2);background:#fff;display:grid;place-items:center;cursor:pointer;color:var(--ink-3);font-size:11px;transition:.12s;}
1498
+ .gr-rm{flex:0 0 auto;width:26px;height:26px;border-radius:8px;border:1.5px solid var(--line-2);background:var(--surface);display:grid;place-items:center;cursor:pointer;color:var(--ink-3);font-size:11px;transition:.12s;}
1358
1499
  .gr-rm:hover{color:var(--red-ink);border-color:var(--red);background:var(--red-bg);}
1359
1500
  .gr-empty{color:var(--ink-3);font-size:12px;padding:6px 0;}
1360
1501
 
@@ -1366,30 +1507,30 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1366
1507
 
1367
1508
  /* ── domain tag: palette sections + filter chips, workflow badge + filter ── */
1368
1509
  .pal-chips{display:flex;flex-wrap:wrap;gap:6px;width:100%;margin-bottom:8px;}
1369
- .pal-chip{font-size:11px;padding:2px 9px;border-radius:999px;border:1px solid var(--line,#d8d8de);background:var(--card,#fff);cursor:pointer;text-transform:capitalize;}
1510
+ .pal-chip{font-size:11px;padding:2px 9px;border-radius:999px;border:1px solid var(--line);background:var(--panel);cursor:pointer;text-transform:capitalize;}
1370
1511
  .pal-chip.off{opacity:.45;text-decoration:line-through;}
1371
1512
  .pal-section{width:100%;display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;}
1372
1513
  .pal-section .pal-head{grid-column:1/-1;}
1373
1514
  .pal-section.collapsed .agent-pill,.pal-section.collapsed .pal-head{display:none;}
1374
- .pal-head{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted,#8a8a92);margin:6px 0 4px;}
1375
- .pl-domain{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--chip,#eee);color:var(--muted,#777);text-transform:capitalize;vertical-align:middle;}
1515
+ .pal-head{font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);margin:6px 0 4px;}
1516
+ .pl-domain{font-size:10px;padding:1px 6px;border-radius:999px;background:var(--field);color:var(--ink-3);text-transform:capitalize;vertical-align:middle;}
1376
1517
  .wf-filter{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px;}
1377
1518
 
1378
1519
  /* Run Results view (Layer 1 mechanical + Layer 2 overview) */
1379
1520
  .results-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:10px;}
1380
- .results-chip{font-size:12px;background:var(--chip-bg,#f1f1f4);border:1px solid var(--line);border-radius:999px;padding:2px 10px;}
1381
- .results-clean{color:var(--green-ink,#1a7f37);font-size:13px;padding:6px 0;}
1521
+ .results-chip{font-size:12px;background:var(--field);border:1px solid var(--line);border-radius:999px;padding:2px 10px;}
1522
+ .results-clean{color:var(--green-ink);font-size:13px;padding:6px 0;}
1382
1523
  .results-files{margin-top:10px;}
1383
1524
  .results-files-h{font-weight:700;font-size:13px;margin-bottom:4px;}
1384
1525
  .results-files ul{list-style:none;padding:0;margin:0;font-family:ui-monospace,monospace;font-size:12px;}
1385
1526
  .results-files li{padding:2px 0;}
1386
- .results-overview-btn{margin:6px 0;font-size:12px;padding:5px 12px;border:1px solid var(--line);border-radius:8px;background:#fff;cursor:pointer;}
1527
+ .results-overview-btn{margin:6px 0;font-size:12px;padding:5px 12px;border:1px solid var(--line);border-radius:8px;background:var(--surface);cursor:pointer;}
1387
1528
  .results-overview-btn:disabled{opacity:.6;cursor:default;}
1388
- .results-narrative{font-size:13px;line-height:1.5;background:var(--chip-bg,#f7f7fa);border-radius:10px;padding:10px 12px;margin:8px 0;}
1529
+ .results-narrative{font-size:13px;line-height:1.5;background:var(--field);border-radius:10px;padding:10px 12px;margin:8px 0;}
1389
1530
  .issue-origin{font-size:10px;text-transform:uppercase;letter-spacing:.05em;padding:1px 6px;border-radius:999px;font-weight:700;}
1390
1531
  .origin-agent{background:var(--blue-bg);color:var(--blue-ink);}
1391
- .origin-review{background:var(--chip-bg,#eee);color:#555;}
1392
- .results-trunc{font-size:11px;color:#946;margin-top:6px;}
1532
+ .origin-review{background:var(--field);color:var(--chip-ink);}
1533
+ .results-trunc{font-size:11px;color:var(--trunc-ink);margin-top:6px;}
1393
1534
 
1394
1535
  /* ---- Plugins view ---- */
1395
1536
  /* Available/Marketplaces render as one wrapper div inside the .run-list, so the
@@ -1414,8 +1555,8 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1414
1555
  .pl-consent-h{font-weight:700;font-size:12.5px;margin:10px 0 4px;}
1415
1556
  .pl-consent-row{font-size:12.5px;padding:2px 0;}
1416
1557
  .pl-secret{display:inline-flex;margin-left:8px;background:var(--red-bg);color:var(--red-ink);font-size:11px;font-weight:700;padding:2px 8px;border-radius:999px;}
1417
- .pl-setup-cmd{background:var(--chip-bg,#f7f7fa);border-radius:8px;padding:4px 8px;margin-top:3px;}
1418
- .pl-diffstat{background:var(--chip-bg,#f7f7fa);border-radius:10px;padding:10px 12px;font-size:12px;overflow-x:auto;max-height:220px;}
1558
+ .pl-setup-cmd{background:var(--field);border-radius:8px;padding:4px 8px;margin-top:3px;}
1559
+ .pl-diffstat{background:var(--field);border-radius:10px;padding:10px 12px;font-size:12px;overflow-x:auto;max-height:220px;}
1419
1560
  .pl-commit{font-size:12px;padding:2px 0;}
1420
1561
  .pl-doc-row{display:flex;align-items:baseline;gap:8px;padding:4px 0;font-size:12.5px;}
1421
1562
  .pl-doc-row .hint{margin-top:0;}
@@ -1440,10 +1581,10 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1440
1581
  .sp-results{margin-top:8px;max-height:220px;overflow:auto;border:1px solid var(--line);border-radius:12px;}
1441
1582
  .sp-row{display:flex;justify-content:space-between;gap:10px;padding:8px 12px;cursor:pointer;border-bottom:1px solid var(--line);font-size:13px;}
1442
1583
  .sp-row:last-child{border-bottom:none;}
1443
- .sp-row:hover{background:var(--chip-bg,#f7f7fa);}
1584
+ .sp-row:hover{background:var(--field);}
1444
1585
  .sp-row.sel{background:var(--green-bg);color:var(--green-ink);}
1445
1586
  .sp-row-meta{display:inline-flex;gap:6px;align-items:center;color:var(--ink-3);font-size:11.5px;flex:0 0 auto;}
1446
- .sp-label{background:var(--chip-bg,#f0f0f4);border-radius:999px;padding:1px 8px;font-weight:600;}
1587
+ .sp-label{background:var(--field);border-radius:999px;padding:1px 8px;font-weight:600;}
1447
1588
  .sp-updated{white-space:nowrap;}
1448
1589
  /* Task identifier ahead of the title: reads as an id, and never wraps — a long
1449
1590
  title gives way before the key does. */
@@ -1469,7 +1610,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1469
1610
  .pl-profile-bar .select{min-width:180px;}
1470
1611
 
1471
1612
  /* ---- Plugin provenance (results header, history cards) ---- */
1472
- .src-badge{display:inline-flex;gap:6px;align-items:center;font-size:11.5px;background:var(--chip-bg,#f0f0f4);border-radius:999px;padding:2px 10px;}
1613
+ .src-badge{display:inline-flex;gap:6px;align-items:center;font-size:11.5px;background:var(--field);border-radius:999px;padding:2px 10px;}
1473
1614
  .src-badge-plugin{font-weight:700;}
1474
1615
  .src-report-wrap{display:inline-flex;gap:8px;align-items:center;margin-left:10px;}
1475
1616
 
@@ -1494,8 +1635,8 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1494
1635
  .grv-editor-actions{justify-content:flex-end;margin-top:14px;}
1495
1636
  /* ---- Guardrail wizard (Step 1 + read-only view) ---- */
1496
1637
  .grv-wizard .grv-source-list{display:grid;gap:8px;margin:12px 0;max-height:46vh;overflow-y:auto;}
1497
- .grv-source-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--line,#d8d8de);border-radius:10px;cursor:pointer;}
1498
- .grv-source-row:hover{background:var(--chip-bg,#f7f7fa);}
1638
+ .grv-source-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--line);border-radius:10px;cursor:pointer;}
1639
+ .grv-source-row:hover{background:var(--field);}
1499
1640
  .grv-source-name{flex:1 1 auto;font-size:14px;}
1500
1641
  .grv-wizard-actions{justify-content:flex-end;margin-top:14px;}
1501
1642
  .grv-editor .switch.disabled{opacity:.5;pointer-events:none;}
@@ -1531,6 +1672,9 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1531
1672
  .stat-meter{display:block;height:6px;border-radius:999px;background:var(--blue-bg);margin-top:10px;overflow:hidden;}
1532
1673
  .stat-meter .stat-meter-fill{display:block;height:100%;border-radius:999px;background:var(--blue-ink);}
1533
1674
  .charts-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
1675
+ /* Team metrics stacks two charts-grids (weekly charts, then the breakdown tables);
1676
+ without this the rows touch while every other gap is 14px. */
1677
+ .charts-grid + .charts-grid{margin-top:14px;}
1534
1678
  .chart-card{padding:20px 22px;}
1535
1679
  .chart-fig{margin:0;}
1536
1680
  .chart-svg{display:block;width:100%;height:auto;}
@@ -1543,7 +1687,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1543
1687
  /* hit rect paints above the bars (DOM order) — hover must stay translucent */
1544
1688
  .ch-hit:hover{fill:var(--ink);fill-opacity:.05;}
1545
1689
  .ch-hit:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
1546
- .chart-tip{position:fixed;z-index:70;background:var(--ink);color:#fff;border-radius:10px;
1690
+ .chart-tip{position:fixed;z-index:70;background:var(--ink);color:var(--on-ink);border-radius:10px;
1547
1691
  padding:8px 11px;font-size:12px;line-height:1.45;pointer-events:none;box-shadow:var(--shadow);}
1548
1692
  .chart-tip .tip-head{font-weight:600;}
1549
1693
  .chart-tip .tip-val{font-family:var(--mono);}
@@ -1551,6 +1695,163 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1551
1695
  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
1552
1696
  clip:rect(0 0 0 0);white-space:nowrap;border:0;}
1553
1697
 
1698
+ /* ---------- Team metrics page (boards 1–3) ---------- */
1699
+ /* style.css has no global [hidden]{display:none} (see its own notes at :324 / :677): an author
1700
+ display:flex beats the UA [hidden] rule, so every hidden-toggled flex container needs this.
1701
+ .tm-enable-err is a .hint, and .hint{display:block} beats the UA [hidden] rule too, so without
1702
+ it the empty error line is always visible in the Enable dialog. */
1703
+ #tm-custom[hidden],#tm-sync[hidden],#tm-filters[hidden],.ws-home[hidden],#stats-tm-hint[hidden],
1704
+ .tm-enable-err[hidden],#wiz-metrics-pre[hidden]{display:none;}
1705
+ .tm-sync-error{white-space:pre-wrap;margin:0;}
1706
+ section[data-view="team-metrics"] .topbar{align-items:flex-start;}
1707
+ .sync-chip{margin-left:auto;display:flex;align-items:center;}
1708
+ .sync-chip-inner{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;padding:8px 12px;border:1px solid var(--line-2);border-radius:14px;background:var(--surface);font-size:12.5px;max-width:520px;}
1709
+ .sync-chip-inner .dot.green{background:var(--green);} .sync-chip-inner .dot.amber{background:var(--amber);} .sync-chip-inner .dot.red{background:var(--red);}
1710
+ .sync-chip-inner .tm-sync-error{flex-basis:100%;color:var(--red-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
1711
+ .tm-filter{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:18px;}
1712
+ .tm-scope-wrap .select{min-width:240px;}
1713
+ .tm-group{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink-2);margin-left:auto;}
1714
+ .tm-custom{display:flex;align-items:center;gap:6px;} .tm-custom .input{width:150px;}
1715
+ .tm-active-filters{display:flex;gap:8px;margin:-8px 0 14px;}
1716
+ .tm-home-hint{display:block;margin:-8px 0 14px;}
1717
+ .tm-stats-hint{margin-left:auto;align-self:center;}
1718
+ #tm-body.is-loading{opacity:.6;}
1719
+ /* Loading affordances (docs/team-metrics.md "Loading"): a shimmer bar for skeleton cells — the
1720
+ Ask panel's sweep, on a block — and the History Refresh spinner recipe on the chip's button. */
1721
+ .skel{display:inline-block;height:11px;width:60%;border-radius:6px;vertical-align:middle;
1722
+ background:linear-gradient(90deg,var(--field) 25%,var(--line) 50%,var(--field) 75%);background-size:220% 100%;
1723
+ animation:ask-shimmer 1.6s linear infinite;}
1724
+ .skel.w25{width:25%;}.skel.w40{width:40%;}.skel.w60{width:60%;}.skel.w70{width:70%;}
1725
+ .skel.skel-lg{height:22px;margin:6px 0;}
1726
+ .skel.skel-block{display:block;width:100%;height:150px;border-radius:10px;margin-top:10px;}
1727
+ .skel-row{display:flex;gap:14px;padding:9px 0;border-bottom:1px solid var(--line);}
1728
+ .skel-row:last-child{border-bottom:0;}
1729
+ .tm-skeleton .card-head{margin-bottom:6px;}
1730
+ .tm-skeleton .stat-sub .skel{margin-top:6px;}
1731
+ .tm-busy-spin{width:12px;height:12px;flex:0 0 auto;border-radius:50%;border:2px solid var(--line-2);border-top-color:var(--ink);animation:ws-spin .9s linear infinite;}
1732
+ .sync-chip-inner .tm-checking{color:var(--ink-2);}
1733
+ .tm-refresh.busy{position:relative;color:transparent;pointer-events:none;}
1734
+ .tm-refresh.busy::after{content:"";position:absolute;inset:0;margin:auto;width:12px;height:12px;border-radius:50%;
1735
+ border:2px solid var(--line-2);border-top-color:var(--ink);animation:ws-spin .9s linear infinite;}
1736
+ /* Workspace card while /scopes is out: the same table, shimmer cells, and a "checking metrics…" summary. */
1737
+ .ws-sum-pending{background:linear-gradient(90deg,var(--ink-3) 0%,var(--ink) 50%,var(--ink-3) 100%);background-size:220% 100%;
1738
+ -webkit-background-clip:text;background-clip:text;color:transparent;animation:ask-shimmer 2.4s linear infinite;}
1739
+ .ws-home-inner.is-pending .ws-projects-tbl td{padding-top:9px;padding-bottom:9px;}
1740
+ .tm-tbl{width:100%;border-collapse:collapse;font-size:12.5px;}
1741
+ .tm-tbl th{text-align:left;font-weight:600;color:var(--ink-3);padding:8px 10px;border-bottom:1px solid var(--line);white-space:nowrap;}
1742
+ .tm-tbl th[data-sort]{cursor:pointer;} .tm-tbl th.num,.tm-tbl td.num{text-align:right;}
1743
+ .tm-tbl td{padding:9px 10px;border-bottom:1px solid var(--line);}
1744
+ .tm-tbl tbody tr[data-filter-dim]{cursor:pointer;} .tm-tbl tbody tr[data-filter-dim]:hover,.tm-tbl tbody tr.on{background:var(--field);}
1745
+ .tm-tbl tr.dim td{color:var(--ink-3);}
1746
+ .tm-runs-foot{display:flex;align-items:center;gap:12px;margin-top:8px;}
1747
+ .tm-share{display:inline-block;width:90px;height:6px;border-radius:3px;background:var(--field);vertical-align:middle;}
1748
+ .tm-share-fill{display:block;height:100%;border-radius:3px;background:var(--blue);}
1749
+ .tm-runs{margin-top:18px;} .tm-runs-head{display:flex;align-items:center;justify-content:space-between;}
1750
+ .tm-run-tbl .tm-title{max-width:340px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
1751
+ .badge.grey{background:var(--field);color:var(--ink-2);}
1752
+ .tm-empty{display:grid;grid-template-columns:1fr 1fr;gap:14px;} .tm-empty .card{padding:22px;}
1753
+ .tm-step{font-size:11px;letter-spacing:.08em;font-weight:700;color:var(--ink-2);}
1754
+ .tm-empty-foot{display:block;margin-top:14px;}
1755
+ /* New light-theme text must clear 4.5:1 (the contrast proof's baseline shrinks, never grows):
1756
+ the empty state's hints and the muted history line use --ink-2, not --ink-3, and the inline
1757
+ link is a darker blue than --blue-ink (3.8:1 on white). */
1758
+ .tm-empty .hint,.tm-empty-foot{color:var(--ink-2);}
1759
+ .linkish{background:none;border:0;padding:0;color:var(--blue-ink-strong);font:inherit;cursor:pointer;text-decoration:underline;}
1760
+ @media (max-width:1080px){ .tm-empty{grid-template-columns:1fr;} .tm-group{margin-left:0;} }
1761
+ .hd-tm.st-ok{color:var(--green-ink)} .hd-tm.st-warn{color:var(--amber-ink)} .hd-tm.st-err{color:var(--red-ink)} .hd-tm.st-muted{color:var(--ink-2)}
1762
+
1763
+ /* Team metrics — Projects cell (board 4) */
1764
+ #projects-list .tm-slot{flex:0 1 420px;min-width:0;}
1765
+ /* border-left + padding-left are board 4's divider between the project row and the cell
1766
+ (mockup `.tm-cell{border-left:1px solid var(--line);padding-left:18px;min-width:420px}`);
1767
+ the 420px sizing lives on .tm-slot above so the cell itself can still wrap. */
1768
+ /* Two fixed rows (title / status) in column 1, the control column spanning both
1769
+ rows in column 2, and any hint on a full-width third row. A grid, not a
1770
+ wrapping flex line: the control used to fall under the status text whenever
1771
+ the 420px slot got tight, reading as detached from the "Team metrics" title. */
1772
+ .tm-cell{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-rows:auto auto;
1773
+ column-gap:14px;row-gap:3px;align-items:center;font-size:12.5px;
1774
+ padding-left:18px;border-left:1px solid var(--line);}
1775
+ .tm-cell .tm-line{grid-column:1;grid-row:2;display:flex;align-items:center;gap:8px;min-width:0;}
1776
+ /* One line, always: the dot never shrinks and a long status ellipsizes rather than
1777
+ wrapping under itself (the row's two-line shape is the whole point of the grid). */
1778
+ .tm-cell .tm-line .tm-dot{flex:0 0 auto;}
1779
+ .tm-cell .tm-status{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
1780
+ .tm-cell .muted,.ws-home .muted{color:var(--ink-3);} /* scoped: a global .muted would recolour .agents-summary.muted (:599) */
1781
+ .tm-cell .tm-label{grid-column:1;grid-row:1;font-weight:600;color:var(--ink-2);}
1782
+ /* board 8 aligns "Metrics home" and "Members" on one column (mockup `.ws-home .lbl{width:96px}`) */
1783
+ .ws-home .tm-label{width:96px;flex:0 0 auto;font-size:11.5px;font-weight:600;color:var(--ink-3);}
1784
+ .tm-cell .tm-hint{grid-column:1 / -1;grid-row:3;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
1785
+ /* The home note is explanatory, not a raw stderr line: let it wrap instead of truncating. */
1786
+ .tm-cell .tm-home-for{white-space:normal;line-height:1.4;}
1787
+ .tm-cell .tm-actions{grid-column:2;grid-row:1 / span 2;display:flex;align-items:center;gap:10px;justify-self:end;}
1788
+ .tm-dot.green{background:var(--green);} .tm-dot.amber{background:var(--amber);} .tm-dot.red{background:var(--red);} .tm-dot.grey{background:var(--ink-3);}
1789
+ /* Enable dialog (boards 5/6) */
1790
+ /* `.field > label` (display:block, margin-bottom) would otherwise beat this and stack the radio above the title */
1791
+ .radio-card,.field > label.radio-card{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border:1.5px solid var(--line-2);border-radius:var(--r-ctrl,14px);margin:8px 0 0;cursor:pointer;font-weight:500;font-size:13px;}
1792
+ .radio-card input[type="radio"]{flex:0 0 auto;margin:2px 0 0;}
1793
+ /* :has(), not a render-time .on class: changing the Attribution radio does not re-render the body */
1794
+ .radio-card:has(> input:checked){border-color:var(--ink);background:var(--field);}
1795
+ .radio-card.disabled{opacity:.55;cursor:not-allowed;}
1796
+ .radio-card-text{display:flex;flex-direction:column;gap:4px;}
1797
+ .tm-warn{margin-top:14px;padding:10px 12px;border-radius:12px;background:var(--amber-bg);color:var(--amber-ink);}
1798
+ .tm-delegate-wrap{margin-top:8px;}
1799
+ /* Wizard (board 7) */
1800
+ .wiz-track{display:flex;gap:18px;list-style:none;padding:0;margin:0 0 18px;font-size:12.5px;color:var(--ink-2);}
1801
+ .wiz-track li span{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--field);margin-right:6px;font-weight:700;}
1802
+ .wiz-track li.on{color:var(--ink);font-weight:600;} .wiz-track li.on span{background:var(--ink);color:var(--on-ink);}
1803
+ .wiz-list{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;}
1804
+ .wiz-row{display:flex;align-items:center;gap:14px;padding:12px 14px;border-top:1px solid var(--line);}
1805
+ /* The metrics-home picker's radio + slug: the label had no rule, so the radio touched the text. */
1806
+ .wiz-row-pick{display:flex;align-items:center;gap:10px;min-width:0;cursor:pointer;}
1807
+ .wiz-row-pick input[type="radio"]{flex:0 0 auto;margin:0;}
1808
+ /* In the 600px sheet the slug must not break mid-word, and a wrapped status keeps its dot on
1809
+ the first line instead of floating between the two. */
1810
+ .tm-home-list .wiz-row-pick{flex:1 1 auto;}
1811
+ .tm-home-list .wiz-row-name{white-space:nowrap;}
1812
+ /* fixed column: "On · since …" lines up across rows whether or not a second line follows */
1813
+ .tm-home-list .wiz-row-status{flex:0 0 200px;width:200px;align-items:flex-start;line-height:1.4;}
1814
+ .tm-home-list .wiz-row-status .tm-dot{flex:0 0 auto;margin-top:5px;}
1815
+ .wiz-row-status-lines{display:flex;flex-direction:column;min-width:0;}
1816
+ .wiz-row-status-sub{color:var(--ink-3);}
1817
+ .wiz-row:first-child{border-top:0;} .wiz-row.off{opacity:.55;}
1818
+ .wiz-row-status{display:flex;align-items:center;gap:8px;color:var(--ink-2);font-size:12.5px;margin-left:auto;}
1819
+ .wiz-metrics-actions{display:flex;align-items:center;gap:10px;}
1820
+ /* Workspace card (board 8): one projects table with the metrics home marked by the Team metrics icon */
1821
+ .ws-home{padding:12px 0 0;font-size:12.5px;}
1822
+ .ws-home[hidden]{display:none;}
1823
+ .ws-tbl-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
1824
+ .ws-tbl-actions{margin-left:auto;display:flex;align-items:center;gap:8px;}
1825
+ .ws-members-summary{color:var(--ink-3);font-size:12.5px;}
1826
+ .ws-projects-tbl{width:100%;border-collapse:collapse;margin-top:8px;font-size:12.5px;}
1827
+ .ws-projects-tbl th{text-align:left;font-weight:600;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);padding:6px 14px 6px 0;border-bottom:1px solid var(--line);}
1828
+ .ws-projects-tbl td{padding:7px 14px 7px 0;border-bottom:1px solid var(--line);vertical-align:top;color:var(--ink-2);line-height:1.5;}
1829
+ .ws-projects-tbl tr:last-child td{border-bottom:0;}
1830
+ .ws-projects-tbl tr[hidden]{display:none;}
1831
+ .ws-col-project{white-space:nowrap;color:var(--ink);}
1832
+ .tm-home-mark{display:inline-flex;align-items:center;vertical-align:-3px;}
1833
+ .ws-col-branch{white-space:normal;overflow-wrap:anywhere;}
1834
+ /* fixed proportions so the centred runs column sits between branch and status, not against status */
1835
+ .ws-projects-tbl{table-layout:fixed;}
1836
+ .ws-projects-tbl th:nth-child(1){width:31%;} .ws-projects-tbl th:nth-child(2){width:26%;} .ws-projects-tbl th:nth-child(3){width:27%;} .ws-projects-tbl th:nth-child(4){width:16%;}
1837
+ .ws-col-runs{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums;}
1838
+ .ws-projects-tbl th.ws-col-runs{text-align:right;}
1839
+ .ws-col-status{white-space:nowrap;}
1840
+ .ws-metric{display:flex;align-items:center;gap:7px;line-height:1.5;}
1841
+ .ws-mark{width:14px;height:14px;flex:0 0 auto;}
1842
+ .ws-mark.ok{color:var(--green);} .ws-mark.bad{color:var(--red-ink);}
1843
+ .ws-metric.bad{color:var(--red-ink);}
1844
+ .ws-member.home td{color:var(--ink);}
1845
+ .ws-members-more{margin-top:8px;}
1846
+ .ws-home-hint{display:flex;align-items:center;gap:6px;margin-top:8px;font-size:12px;color:var(--ink-3);line-height:1.45;}
1847
+ .ws-home-hint.warn{color:var(--amber-ink);}
1848
+ .ws-home-hint .tm-dot{flex:0 0 auto;}
1849
+ /* Group by, now in the Spend per week card head: compact, right-aligned by .card-head's space-between. */
1850
+ .chart-card .card-head .tm-group{margin:0;}
1851
+ .chart-card .card-head .select-sm{padding:5px 30px 5px 10px;font-size:12px;line-height:1.3;}
1852
+ .tm-route-list{list-style:none;padding:0;margin:8px 0 0;} .tm-route-list li.failed{color:var(--red-ink);}
1853
+ .tm-route-list .tm-stderr{white-space:pre-wrap;margin:4px 0 0;}
1854
+
1554
1855
  /* ---------- Sidebar spend indicator ---------- */
1555
1856
  .spend-ind{display:block;width:100%;text-align:left;border:1px solid var(--line);border-radius:var(--r-ctrl);
1556
1857
  background:var(--field);padding:10px 12px;cursor:pointer;font-family:inherit;}
@@ -1625,7 +1926,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1625
1926
 
1626
1927
  /* ── Chat connectivity (chat-connectivity-design.md §4.8) ─────────────────── */
1627
1928
  .pl-channels { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 8px; }
1628
- .pl-channel-warn { color: var(--red, #e5484d); font-weight: 600; }
1929
+ .pl-channel-warn { color: var(--red); font-weight: 600; }
1629
1930
  .pl-config-h { font-weight: 600; margin: 14px 0 6px; font-size: 13px; }
1630
1931
  .chat-events, .chat-channels { margin: 8px 0; }
1631
1932
  .chat-event-row { display: flex; gap: 8px; align-items: center; margin: 4px 0; cursor: pointer; }
@@ -1637,7 +1938,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1637
1938
  /* ---- Models view (configurable-models-design.md §4.10) ---- */
1638
1939
  .mv-list{display:grid;gap:18px;}
1639
1940
  .mv-section{display:grid;gap:10px;}
1640
- .mv-hide-builtin-row{display:grid;gap:6px;padding:10px 12px;border:1px solid var(--line-2,#e6e6ec);border-radius:10px;}
1941
+ .mv-hide-builtin-row{display:grid;gap:6px;padding:10px 12px;border:1px solid var(--line-2);border-radius:10px;}
1641
1942
  .mv-hide-builtin-row .hint{margin:0;}
1642
1943
  .mv-section-title{margin:4px 0 0;font-size:13px;text-transform:uppercase;letter-spacing:.04em;opacity:.75;}
1643
1944
  .mv-card{padding:16px 20px;display:flex;align-items:center;gap:14px;}
@@ -1646,7 +1947,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1646
1947
  .mv-name{font-size:14.5px;}
1647
1948
  .mv-summary{display:block;margin:6px 0 0;word-break:break-all;}
1648
1949
  .mv-card .btn-ghost{flex:0 0 auto;padding:7px 12px;font-size:12px;}
1649
- .mv-builtin{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 12px;border:1px solid var(--line-2,#e6e6ec);border-radius:10px;}
1950
+ .mv-builtin{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 12px;border:1px solid var(--line-2);border-radius:10px;}
1650
1951
  .mv-builtin .mv-summary{margin:0;flex:1 1 auto;text-align:right;}
1651
1952
  .mv-editor{padding:18px 22px;}
1652
1953
  .mv-editor-title{margin:0 0 14px;font-size:15px;}
@@ -1678,18 +1979,18 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1678
1979
  .mv-cost-rate{display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 8px;font-size:12.5px;}
1679
1980
  .mv-cost-rate-label{grid-column:1 / -1;}
1680
1981
  .mv-cost-rate .mv-cost-rate-in{min-width:0;font-family:var(--mono);font-size:12.5px;}
1681
- .mv-cost-rate-unit{color:var(--muted,#6b7280);font-size:11.5px;white-space:nowrap;}
1982
+ .mv-cost-rate-unit{color:var(--ink-3);font-size:11.5px;white-space:nowrap;}
1682
1983
 
1683
1984
  /* ---- Model plugins (design §9.6): plugin cards + export wizard ---- */
1684
1985
  .mv-secret{display:block;margin:4px 0 0;}
1685
- .mv-secret.err{color:var(--red,#c0392b);}
1986
+ .mv-secret.err{color:var(--red);}
1686
1987
  .mvx-step{display:grid;gap:8px;margin:0 0 16px;}
1687
1988
  .mvx-step-title{margin:0;font-size:13px;}
1688
1989
  .mvx-model{display:flex;align-items:center;gap:8px;font-size:13px;cursor:pointer;}
1689
1990
  .mvx-env-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
1690
1991
  .mvx-env-key{flex:0 0 34%;font-size:12.5px;word-break:break-all;}
1691
1992
  .mvx-env-row .select{flex:0 0 auto;}
1692
- .mvx-warn{color:var(--red,#c0392b);}
1993
+ .mvx-warn{color:var(--red);}
1693
1994
  .pl-baseurl{word-break:break-all;}
1694
1995
 
1695
1996
  /* ---------- History two-screen shell ---------- */
@@ -1709,19 +2010,19 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1709
2010
  /* style.css has NO base .mono rule (only ancestor-scoped ones), so class="mono"
1710
2011
  alone renders in Poppins. Scope a base rule to the new subtrees only — a
1711
2012
  global one would touch every other view. */
1712
- .hd .mono,.hist-card .mono,#shipit-modal .mono{font-family:var(--mono);}
2013
+ .hd .mono,.pd .mono,.hist-card .mono,#shipit-modal .mono{font-family:var(--mono);}
1713
2014
 
1714
2015
  /* Card, not a full-bleed band: same border/radius/shadow language as `.card`, and
1715
2016
  its own 20px/32px margin box supplies the inset the screen itself cannot —
1716
2017
  `.hist-screen-detail` keeps `padding:0` so the sticky `.hd-tabs` can still pin
1717
2018
  flush to the scrollport top. Inner padding drops 32 -> 24 so the title lands a
1718
2019
  card-like distance from the border instead of 56px from the viewport edge. */
1719
- .hd-header{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
2020
+ .hd-header,.pd-header{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
1720
2021
  box-shadow:var(--shadow);margin:20px 32px 0;padding:20px 24px 18px;}
1721
- .hd-row1{display:flex;align-items:center;gap:14px;}
1722
- .hd-title{margin:0;min-width:0;flex:1;font:700 22px/1.25 var(--sans);letter-spacing:-.02em;
2022
+ .hd-row1,.pd-row1{display:flex;align-items:center;gap:14px;}
2023
+ .hd-title,.pd-title{margin:0;min-width:0;flex:1;font:700 22px/1.25 var(--sans);letter-spacing:-.02em;
1723
2024
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
1724
- .hd-body{padding:0 32px 40px;}
2025
+ .hd-body,.pd-body{padding:0 32px 40px;}
1725
2026
  .hd-graph{margin-top:18px;}
1726
2027
  /* History detail only: a run-graph node is a link into the Logs tab's `source`
1727
2028
  filter (wireHdGraphLogLinks). `.linked` is added only when the run HAS a Logs
@@ -1791,23 +2092,55 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1791
2092
  .hd-branch-copy.copied + .hd-copied{display:inline;}
1792
2093
  .hd-spacer{flex:1 1 24px;}
1793
2094
  /* .btn-ghost (388-389) sets no `display` and already gives border-radius:999px —
1794
- these two icon+label buttons need the flex row themselves or their SVG lands on
2095
+ the icon+label buttons here need the flex row themselves or their SVG lands on
1795
2096
  the text baseline with no gap (unlike .hd-archive below, which ships its own).
1796
2097
  They also need .btn-ghost's `padding:13px 20px` cut to the compact scale, or the
1797
2098
  row mixes heights. Every other place this file pairs .btn-ghost with compact
1798
2099
  controls does the same override (.hist-pr, .ws-actions, .pl-actions,
1799
- .grv-actions, .mv-card). */
1800
- .hd-back,.hd-resume{display:inline-flex;align-items:center;gap:8px;padding:8px 15px;}
2100
+ .grv-actions, .mv-card).
2101
+ .hd-report has no icon, but it stands in the SAME row as .hd-archive and needs the
2102
+ same padding for the same reason: on .btn-ghost's own 13px it measured 48px beside
2103
+ a 38px Archive (headless Chrome, both themes). */
2104
+ .hd-back,.hd-resume,.hd-report,.pd-back,.pd-new,.pd-history{display:inline-flex;align-items:center;gap:8px;padding:8px 15px;}
1801
2105
  .hd-resume[hidden]{display:none;}
2106
+ /* Same trap as the fallback issue link in the report modal: the author `display`
2107
+ above beats the UA's `[hidden]{display:none}`, and this button ships hidden. */
2108
+ .hd-report[hidden]{display:none;}
2109
+
2110
+ /* ---- the header's ⋯ overflow menu (Archive + Report this run) ---- */
2111
+ /* The wrapper is the positioning context; the menu hangs off its right edge so it
2112
+ cannot push the row wider or escape the card on a narrow window. */
2113
+ .hd-more-wrap{position:relative;display:inline-flex;}
2114
+ .hd-more{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;padding:0;
2115
+ border:1.5px solid var(--line-2);border-radius:999px;background:var(--surface);color:var(--ink);
2116
+ cursor:pointer;transition:background .15s,border-color .15s;}
2117
+ .hd-more[hidden]{display:none;}
2118
+ .hd-more:hover,.hd-more[aria-expanded="true"]{background:var(--field);border-color:var(--ink-3);}
2119
+ .hd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:5;min-width:214px;
2120
+ display:flex;flex-direction:column;gap:2px;padding:6px;background:var(--panel);
2121
+ border:1px solid var(--line-2);border-radius:16px;box-shadow:var(--shadow-menu);}
2122
+ .hd-menu[hidden]{display:none;}
2123
+ /* Both items shed their pill dressing in here and become full-width rows. Higher
2124
+ specificity than the standalone rules above, which still hold nowhere else. */
2125
+ .hd-menu .hd-archive,.hd-menu .hd-report{width:100%;justify-content:flex-start;gap:10px;
2126
+ padding:9px 11px;border:0;border-radius:12px;background:transparent;
2127
+ font:600 13px var(--sans);text-align:left;}
2128
+ .hd-menu .hd-archive{color:var(--red-ink);}
2129
+ .hd-menu .hd-archive:hover:not([disabled]){background:var(--red-bg);border-color:transparent;}
2130
+ /* Amber, the exact twin of Archive's red: both rows report a problem, and reporting
2131
+ a run is a lighter act than destroying it. --amber-ink is the readable text tone in
2132
+ both themes (--amber itself is the solid chip colour). */
2133
+ .hd-menu .hd-report{color:var(--amber-ink);}
2134
+ .hd-menu .hd-report:hover{background:var(--amber-bg);}
1802
2135
  /* 9px, not the 8px its siblings use: this one is 12.5px type against .hd-back's
1803
2136
  13.5px, so equal padding renders it 36px tall in a row of 38px buttons
1804
2137
  (measured in headless Chrome). The extra pixel per side matches .hd-pr, which
1805
2138
  is the same type size and already pays it. */
1806
- .hd-archive{display:flex;align-items:center;gap:8px;padding:9px 15px;border:1.5px solid var(--red-bg);
2139
+ .hd-archive,.pd-remove{display:flex;align-items:center;gap:8px;padding:9px 15px;border:1.5px solid var(--red-bg);
1807
2140
  border-radius:999px;background:var(--panel);font:600 12.5px var(--sans);color:var(--red-ink);cursor:pointer;}
1808
2141
  .hd-archive[hidden]{display:none;}
1809
- .hd-archive:hover:not([disabled]){background:var(--red-bg);border-color:var(--red);}
1810
- .hd-archive[disabled]{opacity:.55;cursor:not-allowed;}
2142
+ .hd-archive:hover:not([disabled]),.pd-remove:hover:not([disabled]){background:var(--red-bg);border-color:var(--red);}
2143
+ .hd-archive[disabled],.pd-remove[disabled]{opacity:.55;cursor:not-allowed;}
1811
2144
  /* align-items:flex-start, NOT the default stretch: `.badge.hist-retained-badge`
1812
2145
  (696) and `.hist-discard` (856) are inline-flex with no width, so a stretching
1813
2146
  column blows both up to the full body width. Only the two BANNERS want the full
@@ -1829,41 +2162,41 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1829
2162
 
1830
2163
  /* Destructive confirm (spec §5.2). The id keeps it out of .btn-primary's way with
1831
2164
  no !important. confirmModal removes the class on close, so it never leaks. */
1832
- #confirm-ok.danger{background:var(--red-ink);border-color:var(--red-ink);color:#fff;}
2165
+ #confirm-ok.danger{background:var(--red-ink);border-color:var(--red-ink);color:var(--on-status);}
1833
2166
 
1834
2167
  /* ---------- History detail: section tabs ---------- */
1835
- .hd-tabs{position:sticky;top:0;z-index:5;display:flex;align-items:center;flex-wrap:wrap;gap:8px;
2168
+ .hd-tabs,.pd-tabs{position:sticky;top:0;z-index:5;display:flex;align-items:center;flex-wrap:wrap;gap:8px;
1836
2169
  padding:18px 0 14px;background:var(--bg);}
1837
- .hd-tab{display:flex;align-items:center;gap:9px;padding:10px 17px;border:1.5px solid var(--line);
2170
+ .hd-tab,.pd-tab{display:flex;align-items:center;gap:9px;padding:10px 17px;border:1.5px solid var(--line);
1838
2171
  border-radius:999px;background:var(--panel);font:600 13.5px var(--sans);color:var(--ink-2);cursor:pointer;}
1839
- .hd-tab:hover{border-color:var(--ink-3);color:var(--ink);}
1840
- .hd-tab.active{background:var(--ink);color:#fff;border-color:var(--ink);}
1841
- .hd-tab-badge{padding:2px 8px;border-radius:999px;background:var(--field);color:var(--ink-3);
2172
+ .hd-tab:hover,.pd-tab:hover{border-color:var(--ink-3);color:var(--ink);}
2173
+ .hd-tab.active,.pd-tab.active{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
2174
+ .hd-tab-badge,.pd-tab-badge{padding:2px 8px;border-radius:999px;background:var(--field);color:var(--ink-3);
1842
2175
  font:600 10.5px var(--mono);}
1843
- .hd-tab.active .hd-tab-badge{background:var(--blue-bg);color:var(--blue-ink);}
1844
- .hd-sec{margin-top:4px;}
2176
+ .hd-tab.active .hd-tab-badge,.pd-tab.active .pd-tab-badge{background:var(--blue-bg);color:var(--blue-ink);}
2177
+ .hd-sec,.pd-sec{margin-top:4px;}
1845
2178
  /* Explicit twin, not redundancy insurance: the UA [hidden] rule is (0,0,0) and
1846
2179
  loses to any author `display`, so the moment a later task gives .hd-sec (or a
1847
2180
  .hd-sec-* body) a display value, the inactive panels would all render at once. */
1848
- .hd-sec[hidden]{display:none;}
2181
+ .hd-sec[hidden],.pd-sec[hidden]{display:none;}
1849
2182
 
1850
2183
  /* ---------- History detail: Diff tab ---------- */
1851
2184
  .hd-diff{display:grid;grid-template-columns:minmax(280px,340px) 1fr;gap:18px;align-items:start;}
1852
2185
  .hd-diff{
1853
- --hd-count-add:#176B4D;
1854
- --hd-count-del:#B31D28;
2186
+ --hd-count-add:light-dark(#176B4D,#6CCB93);
2187
+ --hd-count-del:light-dark(#B31D28,#F0868E);
1855
2188
  }
1856
2189
  .hd-diff .diff-add{color:var(--hd-count-add);}
1857
2190
  .hd-diff .diff-del{color:var(--hd-count-del);}
1858
2191
  @media (max-width:900px){.hd-diff{grid-template-columns:1fr;}}
1859
2192
  .hd-diff-list,.hd-diff-pane{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;}
1860
2193
  .hd-diff-pane,.ask-md{
1861
- --hd-syntax-comment:#5B6167;
1862
- --hd-syntax-keyword:#B31D28;
1863
- --hd-syntax-type:#9A3E00;
1864
- --hd-syntax-string:#176B4D;
1865
- --hd-syntax-literal:#713BB8;
1866
- --hd-syntax-title:#075C82;
2194
+ --hd-syntax-comment:light-dark(#5B6167,#8B949E);
2195
+ --hd-syntax-keyword:light-dark(#B31D28,#FF7B72);
2196
+ --hd-syntax-type:light-dark(#9A3E00,#FFA657);
2197
+ --hd-syntax-string:light-dark(#176B4D,#7EE787);
2198
+ --hd-syntax-literal:light-dark(#713BB8,#D2A8FF);
2199
+ --hd-syntax-title:light-dark(#075C82,#79C0FF);
1867
2200
  }
1868
2201
  .hd-diff-list-head,.hd-diff-pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
1869
2202
  padding:15px 18px;border-bottom:1px solid var(--line);font-size:12.5px;}
@@ -1923,37 +2256,102 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1923
2256
  .hd-dl-row.hd-dl-del > *{background:var(--red-bg);}
1924
2257
  /* ---------- History detail: diff comments ---------- */
1925
2258
  /* A comment block is a REAL grid row spanning all three tracks — `.hd-dl-row` is
1926
- display:contents, so a card can never live inside a row (same rule as
1927
- `.hd-dl-hunk`/`.hd-diff-note` and `.hd-dl-more` above). */
1928
- .hd-cmt-block,.hd-cmt-detached{grid-column:1/-1;display:flex;flex-direction:column;gap:8px;
1929
- padding:10px 18px;background:var(--panel);border-top:1px solid var(--line);font:400 12px var(--sans);}
2259
+ display:contents, so a thread can never live inside a row (same rule as
2260
+ `.hd-dl-hunk` and `.hd-dl-more` above). The block is a quiet strip on the
2261
+ canvas tone; every comment on it is one raised surface card. */
2262
+ .hd-cmt-block,.hd-cmt-detached{grid-column:1/-1;display:flex;flex-direction:column;gap:14px;
2263
+ padding:14px 18px 16px;background:var(--canvas-2);border-top:1px solid var(--line);border-bottom:1px solid var(--line);
2264
+ font:400 12px var(--sans);}
1930
2265
  .hd-cmt-detached{border-top:1px solid var(--line-2);}
1931
2266
  .hd-cmt-detached-head{color:var(--ink-2);font-weight:600;font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;}
1932
- .hd-cmt-card{display:flex;flex-direction:column;gap:6px;padding:11px 13px;border:1.5px solid var(--line);
1933
- border-radius:16px;background:var(--panel);}
1934
- .hd-cmt-card.resolved{opacity:.55;}
1935
- .hd-cmt-head{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--ink-2);}
1936
- .hd-cmt-author{padding:2px 8px;border-radius:999px;background:var(--blue-bg);color:var(--blue-ink);font-weight:600;}
1937
- .hd-cmt-author.ask{background:var(--violet-bg);color:var(--violet-ink);}
1938
- .hd-cmt-time{color:var(--ink-2);}
1939
- .hd-cmt-tag{padding:2px 8px;border-radius:999px;background:var(--field);color:var(--ink-2);font-weight:600;}
1940
- .hd-cmt-sent{color:var(--ink-2);}
1941
- .hd-cmt-where{font-size:11px;color:var(--ink-2);}
1942
- .hd-cmt-quote{padding:5px 9px;border-radius:8px;background:var(--field);color:var(--ink-2);
2267
+
2268
+ /* A thread is a plain stack — the root card, then the indented reply column —
2269
+ and never a card itself. The rail sits at x=20px of the thread box and each
2270
+ reply row draws its own elbow, exactly like `.nav-child` under Running. */
2271
+ .hd-cmt-thread{position:relative;display:flex;flex-direction:column;max-width:720px;
2272
+ animation:wr-rise .18s cubic-bezier(.2,.7,.3,1) both;}
2273
+ .hd-cmt-card{background:var(--surface);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-soft);}
2274
+ .hd-cmt-block>.hd-cmt-card{max-width:720px;}
2275
+ .hd-cmt-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px 8px;min-height:20px;
2276
+ padding:12px 14px 0;font-size:11px;color:var(--ink-2);}
2277
+ .hd-cmt-author{font:600 12px var(--sans);color:var(--ink);}
2278
+ .hd-cmt-time{color:var(--ink-2);font-size:11px;}
2279
+ .hd-cmt-time::before{content:'·';margin-right:8px;color:var(--line-2);}
2280
+ .hd-cmt-tag{padding:2px 8px;border-radius:999px;background:var(--green-bg);color:var(--green-ink);font:600 10.5px var(--sans);}
2281
+ .hd-cmt-sent{padding:2px 8px;border-radius:999px;background:var(--field);color:var(--ink-2);font:500 10.5px var(--mono);}
2282
+ .hd-cmt-where{padding:6px 14px 0;font-size:11px;color:var(--ink-2);}
2283
+ .hd-cmt-quote{margin:6px 14px 0;padding:6px 10px;border-radius:8px;background:var(--field);color:var(--ink-2);
1943
2284
  font:400 11.5px var(--mono);white-space:pre-wrap;word-break:break-word;}
1944
- .hd-cmt-body{color:var(--ink);white-space:pre-wrap;word-break:break-word;}
1945
- .hd-cmt-card.resolved .hd-cmt-body{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
1946
- .hd-cmt-actions{display:flex;align-items:center;gap:12px;}
1947
- .hd-cmt-btn{border:none;background:none;padding:0;color:var(--blue-ink);
1948
- font:500 11.5px var(--sans);cursor:pointer;}
1949
- .hd-cmt-btn:hover{text-decoration:underline;}
1950
- .hd-cmt-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:3px;}
1951
- .hd-cmt-delete{color:var(--red-ink);}
1952
- .hd-cmt-composer{display:flex;flex-direction:column;gap:8px;}
1953
- .hd-cmt-input{width:100%;padding:8px 11px;border:1px solid var(--line-2);border-radius:10px;
1954
- background:var(--panel);color:var(--ink);font:400 12px var(--sans);resize:vertical;}
1955
- .hd-cmt-err{color:var(--red-ink);font-size:11.5px;}
2285
+ .hd-cmt-body{padding:6px 14px 12px;color:var(--ink);font:400 13px/1.5 var(--sans);white-space:pre-wrap;word-break:break-word;}
2286
+ .hd-cmt-body.ask-md{font:400 13px/1.5 var(--sans);white-space:normal;}
2287
+ .hd-cmt-body.ask-md>:first-child{margin-top:0;}
2288
+ .hd-cmt-body.ask-md>:last-child{margin-bottom:0;}
2289
+ .hd-cmt-thread.resolved .hd-cmt-body{color:var(--ink-2);}
2290
+ .hd-cmt-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;
2291
+ padding:8px 14px;border-top:1px solid var(--line);}
2292
+ .hd-cmt-actions{display:flex;align-items:center;gap:2px;margin-right:-4px;}
2293
+
2294
+ /* The Worca mark: inline in the head, left of the name, on every card Worca
2295
+ wrote (root or reply). Tinted var(--ink): black on light, white on dark. */
2296
+ .hd-cmt-mark{width:16px;height:16px;flex:0 0 auto;background:var(--ink);
2297
+ -webkit-mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;-webkit-mask-mode:luminance;
2298
+ mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;mask-mode:luminance;}
2299
+
2300
+ .hd-cmt-btn{height:26px;padding:0 9px;border:0;border-radius:8px;background:transparent;color:var(--ink-2);
2301
+ font:500 12px var(--sans);line-height:26px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;}
2302
+ .hd-cmt-btn:hover{background:var(--field);color:var(--ink);}
2303
+ .hd-cmt-btn:focus-visible{outline:2px solid var(--ink);outline-offset:1px;}
2304
+ .hd-cmt-btn:disabled{opacity:.5;cursor:default;}
2305
+ .hd-cmt-delete:hover{color:var(--red-ink);background:var(--red-bg);}
2306
+ .hd-cmt-toggle{display:inline-flex;align-items:center;gap:7px;margin-left:-9px;}
2307
+ .hd-cmt-btn.hd-cmt-reply{display:inline-flex;align-items:center;gap:7px;height:28px;padding:0 12px;line-height:1;
2308
+ border:1px solid var(--line-2);border-radius:999px;background:var(--surface);color:var(--ink);}
2309
+ .hd-cmt-btn.hd-cmt-reply:hover{border-color:var(--ink);background:var(--surface);color:var(--ink);}
2310
+ .hd-cmt-save{height:28px;padding:0 14px;border-radius:999px;background:var(--ink);color:var(--on-ink);
2311
+ font-weight:600;line-height:28px;}
2312
+ .hd-cmt-save:hover{background:var(--ink);color:var(--on-ink);filter:brightness(1.08);}
2313
+ .hd-cmt-err{padding:0 14px;color:var(--red-ink);font-size:11.5px;}
1956
2314
  .hd-cmt-err:empty{display:none;}
2315
+
2316
+ /* The reply column. Row geometry: the card's head line centre is 21px below the row
2317
+ top (1px border + 12px padding + half of the 15px name line), so the elbow is
2318
+ 31px tall counting the 10px column gap it starts in, and the spine picks up
2319
+ again at that same 21px. Every row — the user's, Worca's, the composer — reaches
2320
+ the card edge; nothing sits on the rail. */
2321
+ .hd-cmt-replies{display:flex;flex-direction:column;gap:10px;margin-top:10px;}
2322
+ .hd-cmt-thread.collapsed .hd-cmt-replies{display:none;}
2323
+ .hd-cmt-replies>.hd-cmt-reply-row{position:relative;display:block;padding:0 0 0 52px;}
2324
+ .hd-cmt-replies>.hd-cmt-reply-row::before{content:"";position:absolute;left:20px;top:-10px;width:30px;height:31px;
2325
+ border-left:1.5px solid var(--line-2);border-bottom:1.5px solid var(--line-2);
2326
+ border-bottom-left-radius:7px;pointer-events:none;}
2327
+ .hd-cmt-replies>.hd-cmt-reply-row:not(:last-child)::after{content:"";position:absolute;left:20px;top:21px;bottom:-10px;
2328
+ width:1.5px;background:var(--line-2);pointer-events:none;}
2329
+
2330
+ /* The composer is the same surface card with the focus ring moved onto the
2331
+ card, so the borderless textarea inside reads as part of it. */
2332
+ .hd-cmt-composer{display:flex;flex-direction:column;transition:border-color .15s,box-shadow .15s;}
2333
+ .hd-cmt-composer:focus-within{border-color:var(--ink);box-shadow:0 0 0 3px var(--selection);}
2334
+ .hd-cmt-composer-title{display:flex;align-items:center;justify-content:space-between;gap:10px;
2335
+ padding:12px 14px;border-bottom:1px solid var(--line);font:600 13px var(--sans);color:var(--ink);}
2336
+ .hd-cmt-tabs{display:inline-flex;gap:2px;padding:2px;border-radius:8px;background:var(--field);}
2337
+ .hd-cmt-tab{height:22px;padding:0 10px;border:0;border-radius:6px;background:transparent;color:var(--ink-2);
2338
+ font:500 11.5px var(--sans);cursor:pointer;}
2339
+ .hd-cmt-tab[aria-selected="true"]{background:var(--surface);color:var(--ink);box-shadow:var(--knob-shadow);}
2340
+ /* The same Text / Preview tab recipe for the other markdown editors (workspace description, wizard step 3). */
2341
+ .md-tabs{display:inline-flex;gap:2px;padding:2px;border-radius:8px;background:var(--field);}
2342
+ .md-tab{height:22px;padding:0 10px;border:0;border-radius:6px;background:transparent;color:var(--ink-2);
2343
+ font:500 11.5px var(--sans);cursor:pointer;}
2344
+ .md-tab[aria-selected="true"]{background:var(--surface);color:var(--ink);box-shadow:var(--knob-shadow);}
2345
+ .hd-cmt-input{width:100%;min-height:72px;padding:12px 14px;border:0;background:transparent;color:var(--ink);
2346
+ font:400 13px/1.5 var(--sans);resize:vertical;}
2347
+ .hd-cmt-input::placeholder{color:var(--ink-2);}
2348
+ .hd-cmt-input:focus{outline:none;}
2349
+ .hd-cmt-preview{padding:12px 14px;min-height:72px;}
2350
+ .hd-cmt-preview:empty::before{content:'Nothing to preview yet';color:var(--ink-2);}
2351
+ .hd-cmt-composer .hd-cmt-actions{justify-content:flex-end;gap:4px;margin:0;padding:0 12px 12px;}
2352
+ .hd-cmt-block[hidden],.hd-cmt-detached[hidden],.hd-cmt-thread[hidden],.hd-cmt-card[hidden],.hd-cmt-badge[hidden],.hd-cmt-add[hidden],.hd-cmt-input[hidden],.hd-cmt-preview[hidden]{display:none;}
2353
+ @media (prefers-reduced-motion: reduce){.hd-cmt-thread{animation:none;}}
2354
+ /* ---------- end diff comments ---------- */
1957
2355
  /* The `+` affordance rides inside the hovered row's code cell (one shared node), so
1958
2356
  the cell needs a positioning context. `left:0`, never a negative offset: a negative
1959
2357
  offset would overhang `.hd-dl-n-new`, which is `position:sticky; z-index:2` with an
@@ -1968,7 +2366,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1968
2366
  .hd-dl-code{position:relative;}
1969
2367
  .hd-cmt-add{position:absolute;left:0;top:50%;transform:translateY(-50%);
1970
2368
  width:16px;height:16px;display:grid;place-items:center;padding:0;
1971
- border:none;border-radius:5px;background:var(--blue);color:#fff;
2369
+ border:none;border-radius:5px;background:var(--blue);color:var(--on-status);
1972
2370
  font:600 12px var(--sans);line-height:1;cursor:pointer;z-index:1;}
1973
2371
  .hd-cmt-add:focus-visible{outline:2px solid var(--ink);outline-offset:1px;}
1974
2372
  .hd-cmt-badge{flex:0 0 auto;min-width:17px;padding:1px 6px;border-radius:999px;
@@ -1980,7 +2378,6 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
1980
2378
  .hd-diff-guarded{flex:0 0 auto;margin-left:auto;padding:1px 7px;border-radius:999px;
1981
2379
  background:var(--amber-bg);color:var(--amber-ink);font:600 10.5px var(--sans);white-space:nowrap;}
1982
2380
  /* Author `display` beats the UA [hidden] rule — every toggled class needs the twin. */
1983
- .hd-cmt-block[hidden],.hd-cmt-detached[hidden],.hd-cmt-card[hidden],.hd-cmt-badge[hidden],.hd-cmt-add[hidden]{display:none;}
1984
2381
  .hd-tree{display:block;}
1985
2382
  .hd-tree-group{display:block;}
1986
2383
  .hd-tree-group[hidden]{display:none;}
@@ -2059,11 +2456,27 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2059
2456
  .hd-ov-chip.clean,.hd-ov-chip.st-done{background:var(--green-bg);color:var(--green-ink);}
2060
2457
  .hd-ov-chip.warn,.hd-ov-chip.st-paused{background:var(--amber-bg);color:var(--amber-ink);}
2061
2458
  .hd-ov-chip.st-stopped,.hd-ov-chip.st-error{background:var(--red-bg);color:var(--red-ink);}
2062
- .hd-ov-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;}
2063
- .hd-ov-card{padding:20px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);}
2064
- .hd-ov-label{font:600 10.5px var(--sans);letter-spacing:.14em;color:var(--ink-3);}
2065
- .hd-ov-value{margin-top:10px;font-size:22px;color:var(--ink);}
2066
- .hd-ov-sub{margin-top:6px;font-size:11.5px;color:var(--ink-3);overflow-wrap:anywhere;}
2459
+ .hd-ov-grid,.pd-ov-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:18px;}
2460
+ .hd-ov-card,.pd-ov-card{padding:20px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);}
2461
+ /* Agent memory (agent-memory-design.md §6): what this run wrote into worca's memory. */
2462
+ .hd-ov-mem{padding:16px 20px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);display:flex;flex-direction:column;gap:8px;}
2463
+ .hd-ov-mem .mono{font-family:var(--mono);}
2464
+ .hd-mem-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px;}
2465
+ .hd-mem-node{color:var(--ink-3);min-width:90px;}
2466
+ /* A linked chip is a real <button> (B6): reset the UA look so it reads as the span next to it. The
2467
+ kind colour rules below are compound (.hd-mem-chip.hd-mem-*, 0,2,0) so they outrank
2468
+ button.hd-mem-chip's color reset (0,1,1) — source order alone would not. */
2469
+ .hd-mem-chip{padding:2px 8px;border-radius:999px;border:1px solid var(--line);font-size:12px;}
2470
+ button.hd-mem-chip{background:transparent;font:inherit;font-family:var(--mono);font-size:12px;line-height:inherit;color:inherit;cursor:pointer;}
2471
+ button.hd-mem-chip:hover{background:var(--field);}
2472
+ button.hd-mem-chip:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2473
+ .hd-mem-chip.hd-mem-add{color:var(--green-ink);}
2474
+ .hd-mem-chip.hd-mem-mod{color:var(--blue-ink);}
2475
+ .hd-mem-chip.hd-mem-del{color:var(--ink-3);text-decoration:line-through;}
2476
+ .hd-mem-chip.hd-mem-rej{color:var(--red-ink);}
2477
+ .hd-ov-label,.pd-ov-label{font:600 10.5px var(--sans);letter-spacing:.14em;color:var(--ink-3);}
2478
+ .hd-ov-value,.pd-ov-value{margin-top:10px;font-size:22px;color:var(--ink);}
2479
+ .hd-ov-sub,.pd-ov-sub{margin-top:6px;font-size:11.5px;color:var(--ink-3);overflow-wrap:anywhere;}
2067
2480
  .hd-ov-task{padding:22px 24px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);}
2068
2481
  .hd-ov-task-h{font:600 13px var(--sans);}
2069
2482
  /* overflow-wrap:anywhere like its sibling .hd-ov-sub — prompts routinely carry
@@ -2075,6 +2488,37 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2075
2488
  .hd-ov-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;}
2076
2489
  .hd-ov-tag{padding:6px 12px;border:1px solid var(--line);border-radius:999px;font-size:11.5px;color:var(--ink-2);}
2077
2490
 
2491
+ /* Settings → Memory and the project page's Memory tab (agent-memory-design.md §10).
2492
+ The namespace is `mem-*`: `mv-*` is Settings → Models. */
2493
+ .mem-host{display:grid;grid-template-columns:minmax(260px,1fr) minmax(0,2fr);gap:18px;align-items:start;}
2494
+ .mem-host > .mem-health{grid-column:1 / -1;}
2495
+ .mem-health-head{display:flex;flex-wrap:wrap;align-items:center;gap:12px;}
2496
+ .mem-counters{font-size:12.5px;color:var(--ink-3);}
2497
+ .mem-reasons{margin:12px 0 0 18px;padding:0;font-size:13px;color:var(--ink-2);}
2498
+ .mem-reasons li{margin:4px 0;}
2499
+ .mem-actions{margin-top:12px;align-items:center;gap:10px;}
2500
+ .mem-health-head .mem-defrag{margin-left:auto;}
2501
+ .mem-defrag svg{display:block;flex:none;}
2502
+ .mem-host-hint{display:block;margin-top:8px;}
2503
+ .mem-list,.mem-history{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:14px 16px;}
2504
+ .mem-list-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;}
2505
+ .mem-list-title{font:600 10.5px var(--sans);letter-spacing:.14em;color:var(--ink-3);text-transform:uppercase;}
2506
+ .mem-row{display:flex;align-items:center;gap:12px;padding:10px 8px;border-radius:var(--r-ctrl);cursor:pointer;}
2507
+ .mem-row:hover{background:var(--field);}
2508
+ .mem-row.on{background:var(--field);box-shadow:inset 0 0 0 1px var(--line-2);}
2509
+ .mem-row:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
2510
+ .mem-row-main{min-width:0;flex:1;}
2511
+ .mem-row-name{font-size:13px;color:var(--ink);}
2512
+ .mem-row-hook{font-size:12.5px;color:var(--ink-2);overflow-wrap:anywhere;}
2513
+ .mem-row-meta{font-size:11.5px;color:var(--ink-3);margin-top:2px;}
2514
+ .mem-editor{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);padding:16px;margin-bottom:18px;}
2515
+ .mem-editor .mem-text{min-height:260px;}
2516
+ .mem-snap{display:flex;align-items:center;gap:12px;padding:6px 8px;font-size:12.5px;}
2517
+ .mem-snap-id{color:var(--ink-2);}
2518
+ .mem-snap-count{color:var(--ink-3);flex:1;}
2519
+ .mem-host .mono{font-family:var(--mono);}
2520
+ @media (max-width:900px){.mem-host{grid-template-columns:1fr;}}
2521
+
2078
2522
  /* ---------- History detail: Agents tab ---------- */
2079
2523
  .hd-ag-group{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);
2080
2524
  overflow:hidden;margin-bottom:18px;}
@@ -2123,7 +2567,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2123
2567
  of its own — its colour, its removed underline and the MERGED grey all come from
2124
2568
  the `.hist-pr-link` selector lists at :848-:850, extended in place. */
2125
2569
  .hd-pr{padding:9px 18px;border:1.5px solid var(--ink);border-radius:999px;background:var(--ink);
2126
- font:600 12.5px var(--sans);color:#fff;cursor:pointer;flex:0 0 auto;}
2570
+ font:600 12.5px var(--sans);color:var(--on-ink);cursor:pointer;flex:0 0 auto;}
2127
2571
  .hd-pr[hidden]{display:none;}
2128
2572
  .hd-pr:hover{opacity:.88;}
2129
2573
  .hd-pr-link{flex:0 0 auto;font:600 12.5px var(--sans);}
@@ -2162,7 +2606,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2162
2606
  .shipit-branch{color:var(--ink);word-break:break-all;}
2163
2607
  .shipit-actions{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:22px;}
2164
2608
  .shipit-ok{padding:11px 22px;border:1.5px solid var(--ink);border-radius:999px;background:var(--ink);
2165
- font:600 13.5px var(--sans);color:#fff;cursor:pointer;}
2609
+ font:600 13.5px var(--sans);color:var(--on-ink);cursor:pointer;}
2166
2610
  .shipit-err{margin-top:12px;}
2167
2611
  /* MANDATORY twin: the node is `class="hint err" hidden`, and `.hint` (:283) sets
2168
2612
  display:block — an author rule always beats the UA `[hidden]{display:none}`.
@@ -2170,6 +2614,19 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2170
2614
  stray node in the a11y tree). */
2171
2615
  .shipit-err[hidden]{display:none;}
2172
2616
 
2617
+ /* Fork support: push-remote + base-repo selects. Left-aligned inside the centered
2618
+ card; the global select{width:100%} fills each grid cell. */
2619
+ .shipit-remotes{display:grid;grid-template-columns:1fr 1fr;gap:10px 12px;margin-top:14px;text-align:left;}
2620
+ .shipit-remotes[hidden]{display:none;}
2621
+ .shipit-remote-field label{display:block;margin:0 0 6px 2px;font:600 11.5px/1.2 var(--sans);color:var(--ink-2);
2622
+ text-transform:uppercase;letter-spacing:.04em;}
2623
+ .shipit-remotes .select{padding:10px 36px 10px 12px;font-size:13px;}
2624
+ .shipit-remotes .select-wrap::after{right:13px;}
2625
+ .shipit-remotes select:disabled{opacity:.55;cursor:not-allowed;}
2626
+ .shipit-remotes-hint{grid-column:1/-1;margin:0;font-size:12px;color:var(--ink-3);word-break:break-all;}
2627
+ .shipit-remotes-hint:empty{display:none;}
2628
+ @media (max-width:520px){.shipit-remotes{grid-template-columns:1fr;}}
2629
+
2173
2630
  /* Reduced motion for the three ship-it animations. This block MUST sit AFTER the
2174
2631
  rules that declare them: `@media` contributes no specificity, so naming
2175
2632
  `.shipit-card` in the kill list at :763 would tie at (0,1,0) and LOSE on source
@@ -2214,7 +2671,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2214
2671
  .hist-cmt-pill .hist-cmt-count{font-weight:700;}
2215
2672
  .hist-open{display:flex;align-items:center;justify-content:center;width:30px;height:30px;
2216
2673
  border:1px solid var(--line);border-radius:9px;background:var(--panel);color:var(--ink-2);cursor:pointer;}
2217
- .hist-open:hover{background:var(--ink);color:#fff;border-color:var(--ink);}
2674
+ .hist-open:hover{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
2218
2675
  /* "Copied" caption on the card — same CSS-only mechanism as .hd-copied */
2219
2676
  .hist-copied{display:none;font:500 11px var(--sans);color:var(--green-ink);}
2220
2677
  .hist-branch-copy.copied + .hist-copied{display:inline;}
@@ -2222,12 +2679,13 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2222
2679
  /* ---------- focus visibility (History redesign) ----------
2223
2680
  Every other interactive control in this stylesheet carries a ring (.btn,
2224
2681
  .btn-go, .btn-stop, .nav button, .hist-head, .seg button, .info-tip, .ws-head,
2225
- .proj-del, .ch-hit); none of the new controls did. `.btn-ghost` declares no
2682
+ .ch-hit); none of the new controls did. `.btn-ghost` declares no
2226
2683
  ring to inherit and carries no `btn` class, so `.hd-back`, `.hd-resume` and
2227
2684
  `.shipit-cancel` had nothing at all — which matters most for `.hd-back`, the
2228
2685
  node openHistDetail focuses programmatically, and for the `.hd-tab` tablist.
2229
2686
  `.hd-diff-file` already has its own (inset) ring and is not repeated here. */
2230
- .hd-tab:focus-visible,.hd-back:focus-visible,.hd-resume:focus-visible,
2687
+ .hd-tab:focus-visible,.hd-back:focus-visible,.hd-resume:focus-visible,.pd-tab:focus-visible,.pd-back:focus-visible,.pd-new:focus-visible,.pd-history:focus-visible,.pd-remove:focus-visible,.pd-sec:focus-visible,.proj-open:focus-visible,.pd-ov-link:focus-visible,
2688
+ .hd-more:focus-visible,.hd-report:focus-visible,
2231
2689
  .hd-archive:focus-visible,.hd-pr:focus-visible,.hd-pr-link:focus-visible,
2232
2690
  .hd-branch-copy:focus-visible,.hd-sec:focus-visible,.hist-open:focus-visible,
2233
2691
  .hist-branch-copy:focus-visible,.shipit-ok:focus-visible,.shipit-cancel:focus-visible{
@@ -2303,7 +2761,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2303
2761
  would show both buttons. Re-state it at the cluster's specificity. */
2304
2762
  .rc-acts .btn-pause[hidden],.rc-acts .btn-resume[hidden]{display:none;}
2305
2763
  .rc-open{border:1px solid var(--line);color:var(--ink-2);}
2306
- .rc-open:hover{background:var(--ink);color:#fff;border-color:var(--ink);}
2764
+ .rc-open:hover{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
2307
2765
  .rc-open:focus-visible,.rc-branch-copy:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2308
2766
  /* ---------- Running redesign: shared keyframes (C2 — declared ONCE, here) ----------
2309
2767
  @keyframes are name-resolved, not cascaded, so their position relative to the
@@ -2332,7 +2790,7 @@ fieldset.source legend{font-weight:600;font-size:13px;padding:0 6px;color:var(--
2332
2790
  width:32px;height:28px;padding:0;border:0;border-radius:999px;background:transparent;
2333
2791
  color:var(--ink-2);cursor:pointer;transition:background .15s,color .15s;}
2334
2792
  .run-density .rc-dseg:hover{color:var(--ink);}
2335
- .run-density .rc-dseg[aria-pressed="true"]{background:var(--ink);color:#fff;}
2793
+ .run-density .rc-dseg[aria-pressed="true"]{background:var(--ink);color:var(--on-ink);}
2336
2794
  .run-density .rc-dseg:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2337
2795
  /* One body per density. The other is display:none — which zeroes its scrollers, so
2338
2796
  setRunDensity stashes .log scrollTop + .run-flow-wrap scrollLeft across the flip. */
@@ -2495,7 +2953,7 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2495
2953
  .rd-tab{display:flex;align-items:center;gap:9px;padding:10px 17px;border:1.5px solid var(--line);
2496
2954
  border-radius:999px;background:var(--panel);font:600 13.5px var(--sans);color:var(--ink-2);cursor:pointer;}
2497
2955
  .rd-tab:hover{border-color:var(--ink-3);color:var(--ink);}
2498
- .rd-tab.active{background:var(--ink);color:#fff;border-color:var(--ink);}
2956
+ .rd-tab.active{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
2499
2957
  .rd-tab:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2500
2958
  .rd-tab-badge{padding:2px 8px;border-radius:999px;background:var(--field);color:var(--ink-3);
2501
2959
  font:600 10.5px var(--mono);}
@@ -2656,8 +3114,15 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2656
3114
  HOUSE RULE for this whole block: no comment inside a rule body, and no
2657
3115
  closing brace in any comment — ruleBody() stops its capture at the first one
2658
3116
  and both would break the tests. */
2659
- .brand .logo-mark{display:none;width:32px;height:32px;border-radius:50%;}
3117
+ .brand .logo-mark{display:none;width:32px;height:32px;border-radius:50%;background:var(--ink);
3118
+ -webkit-mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;-webkit-mask-mode:luminance;
3119
+ mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;mask-mode:luminance;}
3120
+ /* The foot is a column flex, so the button parks itself: flex-end pins it to
3121
+ the rail's right edge under the spend block while expanded, and the collapsed
3122
+ override below re-centres it in the 76px rail — `align-self` on the child
3123
+ out-ranks the `align-items:center` the collapsed foot sets. */
2660
3124
  .side-toggle{display:flex;align-items:center;justify-content:center;
3125
+ align-self:flex-end;
2661
3126
  width:30px;height:30px;flex:0 0 auto;padding:0;border:0;border-radius:9px;
2662
3127
  background:transparent;color:var(--ink);cursor:pointer;}
2663
3128
  .side-toggle svg{width:23px;height:23px;}
@@ -2670,21 +3135,27 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2670
3135
  gutter takes another 10px and shoves the icon column 5px off centre. Suppress
2671
3136
  it here only; the rail still scrolls by wheel and keyboard, and the base
2672
3137
  overflow-y is deliberately NOT restated (a test asserts it isn't). */
2673
- .sidebar.collapsed{width:76px;flex:0 0 76px;padding:22px 18px 18px;
3138
+ .sidebar.collapsed{width:76px;flex:0 0 76px;padding:26px 18px 10px;
2674
3139
  scrollbar-width:none;}
2675
3140
  .sidebar.collapsed::-webkit-scrollbar{width:0;height:0;}
2676
- .sidebar.collapsed .brand{flex-direction:column;gap:6px;margin-bottom:8px;padding:0;}
3141
+ /* The nav must not jump when the rail collapses: the first tile sits at
3142
+ 26 + 34 + 24 = 84px expanded (sidebar padding-top + wordmark + .brand
3143
+ margin-bottom), so the rail keeps the same 26px top padding above and makes
3144
+ up the difference below. 26, not 24, because the round mark is 32px tall
3145
+ against the wordmark's 34 — the gap absorbs the 2px so the sum still lands
3146
+ on 84. */
3147
+ .sidebar.collapsed .brand{flex-direction:column;gap:6px;margin-bottom:26px;padding:0;}
2677
3148
  .sidebar.collapsed .logo{display:none;}
2678
3149
  .sidebar.collapsed .logo-mark{display:block;}
2679
- .sidebar.collapsed .side-toggle{width:40px;height:40px;margin:10px 0 8px;border-radius:12px;}
2680
- /* The glyph is a panel outline with a fixed left divider, so it must NOT be
2681
- mirrored: scaleX(-1) would throw the divider to the right edge and claim the
2682
- sidebar had moved. Only the inner chevron turns round, and applySidebarCollapsed
2683
- (app.js:365) rewrites its `d` instead — the box stays put in both states.
2684
- Both glyph sizes are the originals +30% (18 -> 23 beside the wordmark,
2685
- 20 -> 26 on the rail). stroke-width lives in the markup, not here: at 1.2 in a
2686
- 24-unit viewBox both sizes land on a ~1.2px hairline, so neither state needs
2687
- walking back. */
3150
+ .sidebar.collapsed .side-toggle{width:40px;height:40px;margin:0;border-radius:12px;
3151
+ align-self:center;}
3152
+ /* One bare chevron, pointing wherever the rail is about to go. It is NOT
3153
+ mirrored in CSS: scaleX(-1) shifts a chevron's visual mass off the button's
3154
+ centre, so applySidebarCollapsed rewrites the path's `d` and the arrow stays
3155
+ optically centred in both states. Sizes: 23px under the spend block, 26px on
3156
+ the rail. stroke-width lives in the markup, not here — 2 in a 24-unit viewBox
3157
+ is a ~2px stroke at both sizes, which a lone arrow needs and the old boxed
3158
+ glyph did not. */
2688
3159
  .sidebar.collapsed .side-toggle svg{width:26px;height:26px;}
2689
3160
 
2690
3161
  /* `:not(.rail-tile)` is LOAD-BEARING on both rules below. Run tiles are
@@ -2722,8 +3193,8 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2722
3193
  hover-dead: the (0,4,1) fill would beat the (0,3,1) hover and nothing would
2723
3194
  change. brightness() keeps the mock's darker-on-hover intent inside the
2724
3195
  palette, and matches ten existing hover rules in this file. */
2725
- .sidebar.collapsed .nav button.nav-cta{background:var(--ink);color:#fff;}
2726
- .sidebar.collapsed .nav button.nav-cta svg{stroke:#fff;}
3196
+ .sidebar.collapsed .nav button.nav-cta{background:var(--ink);color:var(--on-ink);}
3197
+ .sidebar.collapsed .nav button.nav-cta svg{stroke:var(--on-ink);}
2727
3198
  .sidebar.collapsed .nav button.nav-cta:hover{filter:brightness(.55);}
2728
3199
 
2729
3200
  /* Section headers keep their text node — ui-nav-sections.test.mjs:26-35 asserts
@@ -2731,7 +3202,6 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2731
3202
  so that is NOT the reason.) 26px hairline, per the mock. */
2732
3203
  .sidebar.collapsed .nav-sect{width:26px;height:1px;margin:10px auto;padding:0;
2733
3204
  font-size:0;letter-spacing:0;background:var(--line);overflow:hidden;}
2734
- .sidebar.collapsed .nav-sep{width:26px;margin-top:auto;}
2735
3205
 
2736
3206
  .sidebar.collapsed .nav-count{position:absolute;top:-2px;right:-2px;margin:0;
2737
3207
  min-width:17px;height:17px;padding:0 4px;font-size:10px;
@@ -2758,8 +3228,13 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2758
3228
  .sidebar.collapsed .nav-rollup{position:absolute;right:-1px;bottom:-1px;margin:0;
2759
3229
  border:2px solid var(--panel);}
2760
3230
 
2761
- .sidebar.collapsed .side-foot{align-items:center;gap:8px;
2762
- padding-top:12px;border-top:1px solid var(--line);}
3231
+ /* The rail reproduces the expanded 10px on all four edges around Settings and
3232
+ the toggle. padding-top is 9, not 10, because the foot's own 1px border-top
3233
+ is what the tile is measured from — the two together are the 10. The nav-sep
3234
+ override does the same arithmetic against the 6px collapsed .nav gap. */
3235
+ .sidebar.collapsed .nav-sep{width:26px;margin-top:auto;margin-bottom:4px;}
3236
+ .sidebar.collapsed .side-foot{align-items:center;gap:10px;
3237
+ padding-top:9px;border-top:1px solid var(--line);}
2763
3238
 
2764
3239
  /* ---- rail run tiles ---- */
2765
3240
  /* Scoped `.nav .rail-tile` (0,2,0) for the same reason `.nav .nav-child` is
@@ -2789,7 +3264,7 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2789
3264
  free, on specificity: `.nav .nav-child.active` (:177) is (0,3,0) and
2790
3265
  `.nav-child.lingering` (:178) is only (0,2,0). */
2791
3266
  .nav .rail-tile.lingering{color:var(--ink-3);}
2792
- .nav .rail-tile.active{background:var(--ink);border-color:var(--ink);color:#fff;}
3267
+ .nav .rail-tile.active{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
2793
3268
  .nav .rail-tile:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2794
3269
  /* No `box-sizing:content-box`: the global border-box (:52) makes this a 9px
2795
3270
  total — a 5px core inside a 2px panel ring, exactly the mock. content-box
@@ -2810,7 +3285,7 @@ body.view-running .topnav{margin:12px 32px 0;flex:0 0 auto;}
2810
3285
  .nav .rail-tile .child-q{position:absolute;top:-5px;right:-5px;margin:0;
2811
3286
  display:flex;align-items:center;justify-content:center;
2812
3287
  width:15px;height:15px;border:2px solid var(--panel);border-radius:50%;
2813
- background:var(--amber);color:#fff;font-size:9px;font-weight:700;}
3288
+ background:var(--amber);color:var(--on-status);font-size:9px;font-weight:700;}
2814
3289
 
2815
3290
  /* ---- rail budget ring ---- */
2816
3291
  /* `.spend-ring` (0,1,0) ties `.spend-ind` (:1607-1608, 0,1,0) and wins the tie
@@ -2864,24 +3339,65 @@ body.rail-collapsed .ask-dock{left:76px;}
2864
3339
  .ask-pill{pointer-events:auto;display:flex;align-items:center;gap:10px;padding:11px 18px 11px 14px;
2865
3340
  border:1.5px solid var(--line-2);border-radius:999px;background:var(--panel);color:var(--ink);
2866
3341
  font-family:inherit;font-weight:600;font-size:13.5px;cursor:pointer;
2867
- box-shadow:0 6px 28px rgba(25,25,27,.10),0 1px 2px rgba(25,25,27,.06);transition:border-color .15s;}
3342
+ box-shadow:var(--shadow-pop);transition:border-color .15s;}
2868
3343
  .ask-pill:hover{border-color:var(--ink);}
2869
3344
  .ask-pill:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2870
3345
  .ask-pill[hidden]{display:none;}
2871
- .ask-pill-logo{width:22px;height:22px;border-radius:50%;}
3346
+ /* "Thinking" on the collapsed pill: the label shimmers, the same sweep the live
3347
+ thinking row paints on .ask-thinking-label (gradient clipped to the glyphs,
3348
+ swept by the shared ask-shimmer keyframes). At rest the label needs no rule:
3349
+ the pill's own color/weight paint it. Toggled with the .is-live class by
3350
+ ask-panel.mjs updateSendStop(), alongside the mark<->orb morph below. */
3351
+ .ask-pill.is-live .ask-pill-label{background:linear-gradient(100deg,var(--ink-3) 0%,var(--ink-3) 34%,var(--ink) 50%,var(--ink-3) 66%,var(--ink-3) 100%);
3352
+ background-size:220% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:ask-shimmer 2.4s linear infinite;}
3353
+ .ask-pill-logo{width:22px;height:22px;border-radius:50%;display:inline-block;flex:0 0 auto;background:var(--ink);
3354
+ -webkit-mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;-webkit-mask-mode:luminance;
3355
+ mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;mask-mode:luminance;}
3356
+ /* The mark slot: the masked logo and the pill's own thinking orb stacked in one
3357
+ 22px host. A CSS mask clips children, so the orb is a SIBLING of the masked
3358
+ span, absolutely stacked on it; the host is what the pill's flex row sizes,
3359
+ so the label and the kbd never move. The morph between them is these
3360
+ transitions, keyed off .is-live: lighting shrinks and fades the mark while
3361
+ the orb fades in (.52s — the canvas grows its dots out of the centre on the
3362
+ same clock, thinking-orb morphTo, so no CSS scale on the orb: a scaled
3363
+ canvas would blur them); resting is the slow, eased-out way back (.8s, over
3364
+ the wave's .45s fade). A transition reads its timing from the AFTER-change
3365
+ style, so the live rules carry the morph-in duration and the rest rules the
3366
+ morph-back one. Under prefers-reduced-motion the `*{transition:none}`
3367
+ blanket makes this an instant swap and the orb snaps its tween too; no rule
3368
+ of its own is needed. */
3369
+ .ask-pill-mark{position:relative;width:22px;height:22px;flex:0 0 auto;display:inline-block;line-height:0;}
3370
+ .ask-pill-mark>.ask-pill-logo{position:absolute;inset:0;
3371
+ transition:opacity .8s cubic-bezier(.22,1,.36,1),transform .8s cubic-bezier(.22,1,.36,1);}
3372
+ .ask-pill-mark>.ask-orb{position:absolute;inset:0;opacity:0;transition:opacity .8s cubic-bezier(.22,1,.36,1);}
3373
+ .ask-pill.is-live .ask-pill-mark>.ask-pill-logo{opacity:0;transform:scale(.35);
3374
+ transition-duration:.52s;transition-timing-function:cubic-bezier(.4,0,.7,.2);}
3375
+ .ask-pill.is-live .ask-pill-mark>.ask-orb{opacity:1;transition-duration:.52s;transition-timing-function:cubic-bezier(.2,.7,.3,1);}
2872
3376
  .ask-kbd{padding:3px 7px;border-radius:7px;background:var(--field);color:var(--ink-3);
2873
3377
  font-family:var(--mono);font-weight:400;font-size:10.5px;}
2874
3378
 
3379
+ /* Content cap. The sheet grows to the full dock, what is INSIDE it does not: the
3380
+ transcript column and the composer box share --ask-col-max and centre under it,
3381
+ so at the default 821px sheet nothing moves and a wide sheet reads as a column.
3382
+ --ask-col-inset is the box's distance from the sheet edge (the band padding until
3383
+ the cap bites, then the centring remainder) — the composer popovers stay children
3384
+ of the sheet (their max-height:70% means the sheet's height) and anchor to it.
3385
+ --ask-box-top is the sheet bottom → box top distance with an empty one-line
3386
+ composer: 14px band padding + box (1 border + 8 padding + ~36 textarea + 4 gap +
3387
+ 31 row + 8 padding + 1 border); the jump pill and the popovers float above it. */
2875
3388
  .ask-sheet{pointer-events:auto;position:relative;display:flex;flex-direction:column;overflow:hidden;
2876
- width:min(782px,100%);height:min(669px,calc(100% - 20px));max-width:100%;max-height:calc(100% - 20px);
3389
+ width:min(821px,100%);height:min(669px,calc(100% - 20px));max-width:100%;max-height:calc(100% - 20px);
3390
+ --ask-col-max:880px;--ask-col-inset:max(16px,calc(50% - var(--ask-col-max) / 2));--ask-box-top:103px;
2877
3391
  background:var(--panel);
2878
3392
  border:1px solid var(--line-2);border-radius:var(--r-card);
2879
- box-shadow:0 18px 60px rgba(25,25,27,.14),0 2px 6px rgba(25,25,27,.06);
3393
+ box-shadow:var(--shadow-sheet);
2880
3394
  animation:wr-rise .26s cubic-bezier(.2,.7,.3,1) both;}
2881
3395
  .ask-sheet[hidden]{display:none;}
2882
3396
 
2883
3397
  .ask-header{display:flex;align-items:center;gap:10px;padding:13px 14px 13px 16px;border-bottom:1px solid var(--line);}
2884
- .ask-header-logo{width:20px;height:20px;border-radius:50%;}
3398
+ .ask-header-logo{width:20px;height:20px;border-radius:50%;display:inline-block;flex:0 0 auto;background:var(--ink);
3399
+ -webkit-mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;-webkit-mask-mode:luminance;
3400
+ mask:url(/assets/worca-mark-mask.png) center/contain no-repeat;mask-mode:luminance;}
2885
3401
  .ask-title{font-weight:600;font-size:13px;color:var(--ink);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
2886
3402
  .ask-header-spacer,.ask-composer-spacer,.ask-activity-spacer,.ask-card-actions-spacer{flex:1 1 auto;}
2887
3403
  .ask-scope-btn{display:inline-flex;align-items:center;gap:5px;max-width:180px;height:30px;flex:none;padding:0 9px;
@@ -2896,9 +3412,23 @@ body.rail-collapsed .ask-dock{left:76px;}
2896
3412
  .ask-icon-btn:hover{background:var(--field);color:var(--ink);}
2897
3413
  .ask-icon-btn:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
2898
3414
 
3415
+ /* `overflow-anchor:auto` is the UA default, stated here on purpose: it is the
3416
+ only thing that keeps the text being read still while the activity block above
3417
+ it grows a tool row mid-turn, and a later `overflow-anchor:none` anywhere up
3418
+ the chain would silently switch it off. */
2899
3419
  .ask-transcript{position:relative;flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
2900
- padding:18px 20px 8px;display:flex;flex-direction:column;gap:16px;}
2901
- .ask-msg{display:flex;flex-direction:column;gap:6px;animation:wr-rise .2s cubic-bezier(.2,.7,.3,1) both;}
3420
+ padding:18px 20px 8px;overflow-anchor:auto;}
3421
+ /* .ask-transcript is only the scrollport; every message lands in this column
3422
+ (ask-panel.mjs renderTranscript), which carries the stack + gap and the cap. */
3423
+ .ask-transcript-col{width:100%;max-width:var(--ask-col-max);margin-inline:auto;display:flex;flex-direction:column;gap:16px;}
3424
+ .ask-msg{display:flex;flex-direction:column;gap:6px;}
3425
+ /* The entry rise is OPT-IN, per message. A live row is patched in place, but a
3426
+ structural flush (ask-start, ask-done, a new message) still rebuilds the whole
3427
+ column — so an `animation` on the bare `.ask-msg` replayed the 10px rise and
3428
+ the fade on every message already on screen. ask-panel.mjs stamps the
3429
+ attribute from its ledger of rows the transcript has shown before, and on
3430
+ nothing else. */
3431
+ .ask-msg[data-ask-enter]{animation:wr-rise .2s cubic-bezier(.2,.7,.3,1) both;}
2902
3432
  .ask-user-bubble{align-self:flex-end;max-width:78%;padding:10px 14px;border-radius:16px 16px 4px 16px;
2903
3433
  background:var(--field);color:var(--ink);font-size:13.5px;line-height:1.6;white-space:pre-wrap;overflow-wrap:anywhere;}
2904
3434
  .ask-user-pills{justify-content:flex-end;margin-top:0;}
@@ -2939,6 +3469,7 @@ body.rail-collapsed .ask-dock{left:76px;}
2939
3469
  this only restores a legible fill under the clipped background. */
2940
3470
  @media (prefers-reduced-motion: reduce){
2941
3471
  .ask-thinking-label{background:none;-webkit-background-clip:border-box;background-clip:border-box;color:var(--ink-2);}
3472
+ .ask-pill.is-live .ask-pill-label{background:none;-webkit-background-clip:border-box;background-clip:border-box;color:var(--ink-2);}
2942
3473
  }
2943
3474
  .ask-tool-row{display:flex;align-items:center;gap:9px;min-width:0;}
2944
3475
  .ask-tool-op{width:38px;flex:0 0 38px;font-family:var(--mono);font-size:10px;letter-spacing:.06em;
@@ -2997,14 +3528,11 @@ body.rail-collapsed .ask-dock{left:76px;}
2997
3528
 
2998
3529
  .ask-card{margin-top:2px;display:flex;flex-direction:column;gap:10px;padding:13px 15px;
2999
3530
  border:1.5px solid var(--line);border-radius:16px;background:var(--panel);}
3000
- .ask-card-title{font-weight:600;font-size:12.5px;color:var(--ink);}
3001
3531
  .ask-card-seg{display:flex;gap:4px;}
3002
3532
  .ask-card-seg-btn{padding:5px 12px;border:1px solid var(--line-2);border-radius:999px;background:transparent;
3003
3533
  color:var(--ink-2);font-family:inherit;font-weight:600;font-size:11px;cursor:pointer;transition:.15s;}
3004
3534
  .ask-card-seg-btn.on{background:var(--ink);border-color:var(--ink);color:var(--panel);}
3005
3535
  .ask-card-target{display:flex;flex-direction:column;gap:10px;}
3006
- .ask-card-field{display:flex;flex-direction:column;gap:4px;}
3007
- .ask-card-label{font-weight:600;font-size:10.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);}
3008
3536
  .ask-card :is(select,input[type="text"],textarea){font-size:12.5px;padding:8px 11px;border-radius:10px;}
3009
3537
  .ask-card textarea.ask-card-brief{min-height:0;height:auto;max-height:160px;resize:none;line-height:1.5;}
3010
3538
  .ask-card-members{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);}
@@ -3014,7 +3542,6 @@ body.rail-collapsed .ask-dock{left:76px;}
3014
3542
  .ask-card-scope-warn{font-size:12px;color:var(--amber-ink);background:var(--amber-wash);
3015
3543
  border:1px solid var(--amber-line);border-radius:8px;padding:6px 9px;}
3016
3544
  .ask-card-err:empty{display:none;}
3017
- .ask-card-actions{display:flex;align-items:center;gap:8px;}
3018
3545
  .ask-card-open-np{border:0;background:transparent;padding:0;color:var(--blue-ink);font-family:inherit;
3019
3546
  font-size:11.5px;cursor:pointer;}
3020
3547
  .ask-card-not-now{padding:8px 13px;border:0;border-radius:999px;background:transparent;color:var(--ink-2);
@@ -3029,15 +3556,226 @@ body.rail-collapsed .ask-dock{left:76px;}
3029
3556
  .ask-card-failed{color:var(--red-ink);}
3030
3557
  .ask-card-link{color:var(--blue-ink);}
3031
3558
 
3032
- .ask-jump{position:absolute;left:0;right:0;bottom:104px;margin:0 auto;width:max-content;
3559
+ /* ---------- run proposal card v2 (ui/public/ask-panel.mjs buildCardForm; mockup 2026-09-06) ----------
3560
+ The v1 card rules above still apply to this root (.ask-card); every override below
3561
+ is written at higher specificity than the rule it replaces. Tokens only. */
3562
+ .ask-card.ask-rp{gap:0;padding:0;overflow:hidden;border-radius:18px;border:1.5px solid var(--line-2);box-shadow:var(--shadow-soft);animation:wr-rise .26s cubic-bezier(.2,.7,.3,1) both;}
3563
+ .ask-rp>*{min-width:0;}
3564
+ .ask-rp-head{padding:16px 18px 14px;background:linear-gradient(180deg,var(--violet-wash),var(--panel) 92%);border-bottom:1px solid var(--line);}
3565
+ .ask-rp-eyebrow{display:flex;align-items:center;gap:8px;height:20px;}
3566
+ .ask-rp-kicker{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--violet-ink);font-weight:700;}
3567
+ .ask-rp-kicker::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--violet);margin-right:7px;vertical-align:1px;}
3568
+ .ask-rp-from{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);}
3569
+ .ask-rp-title{margin:8px 0 0;display:flex;align-items:center;gap:8px;}
3570
+ .ask-rp-edit{font-size:11px;color:var(--ink-3);white-space:nowrap;}
3571
+ .ask-rp-why{margin:6px 0 0;font-size:12.5px;line-height:1.55;color:var(--ink-2);max-width:66ch;}
3572
+ .ask-rp-sec{padding:14px 18px;border-bottom:1px solid var(--line);}
3573
+ .ask-rp-sec-head{display:flex;align-items:center;gap:10px;margin-bottom:10px;min-height:22px;flex-wrap:wrap;}
3574
+ .ask-rp-sec-title{font-weight:600;font-size:12.5px;color:var(--ink);}
3575
+ .ask-rp-sec-sub{font-size:11.5px;color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1 1 auto;}
3576
+ .ask-rp-mini{height:22px;padding:0 9px;border:0;border-radius:999px;background:transparent;color:var(--ink-2);font-family:inherit;font-size:11.5px;font-weight:600;cursor:pointer;}
3577
+ .ask-rp-mini:hover{background:var(--field);color:var(--ink);}
3578
+ .ask-rp .ask-card-seg{gap:3px;padding:3px;border-radius:999px;background:var(--field);margin-left:auto;}
3579
+ .ask-rp .ask-card-seg-btn{height:24px;padding:0 12px;border:0;font-size:11.5px;}
3580
+ .ask-rp .ask-card-seg-btn.on{background:var(--ink);color:var(--on-ink);}
3581
+ .ask-rp-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px 12px;}
3582
+ .ask-rp-grid.two{grid-template-columns:repeat(2,minmax(0,1fr));margin-top:10px;}
3583
+ .ask-rp-field{display:flex;flex-direction:column;gap:4px;min-width:0;}
3584
+ .ask-rp-label{font-weight:600;font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-3);}
3585
+ .ask-rp-hint{font-weight:400;text-transform:none;letter-spacing:0;}
3586
+ .ask-rp :is(select,input[type="text"]){height:36px;padding:0 12px;border:1px solid var(--line-2);border-radius:11px;background:var(--field);font-size:12.5px;}
3587
+ .ask-rp .ask-rp-title input{flex:1 1 auto;min-width:0;height:auto;border:0;background:transparent;padding:2px 0;font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.3;border-bottom:1.5px dashed transparent;border-radius:0;color:var(--ink);}
3588
+ .ask-rp .ask-rp-title input:hover{border-bottom-color:var(--line-2);}
3589
+ .ask-rp .ask-rp-title input:focus-visible{box-shadow:none;outline:none;border-bottom-color:var(--violet);background:transparent;}
3590
+ .ask-rp-wfdesc{font-size:11.5px;color:var(--ink-3);}
3591
+ .ask-rp-wfdesc b{font-weight:600;color:var(--ink-2);}
3592
+ .ask-rp-agents{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;overflow:hidden;background:var(--canvas-2);}
3593
+ .ask-rp-tile{display:flex;flex-direction:column;gap:8px;padding:10px 14px;border-top:1px solid var(--line);background:var(--panel);}
3594
+ .ask-rp-tile:first-child{border-top:0;}
3595
+ .ask-rp-tile.mod{background:var(--amber-wash);}
3596
+ .ask-rp-tile-l1{display:flex;align-items:center;gap:10px;min-width:0;flex-wrap:wrap;}
3597
+ .ask-rp-tile-l2{display:flex;align-items:center;gap:6px 18px;flex-wrap:wrap;padding-left:16px;}
3598
+ .ask-rp-acc{width:6px;height:26px;border-radius:3px;flex:0 0 auto;background:var(--ink-3);}
3599
+ .ask-rp-acc.violet{background:var(--violet);} .ask-rp-acc.blue{background:var(--blue);} .ask-rp-acc.green{background:var(--green);} .ask-rp-acc.peach{background:var(--peach);} .ask-rp-acc.red{background:var(--red);} .ask-rp-acc.amber{background:var(--amber);}
3600
+ .ask-rp-name{display:flex;flex-direction:column;min-width:0;line-height:1.25;flex:1 1 140px;}
3601
+ .ask-rp-name b{font-weight:600;font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--ink);}
3602
+ .ask-rp-name small{font-family:var(--mono);font-size:10px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3603
+ .ask-rp-m{color:var(--amber-ink);font-weight:700;}
3604
+ .ask-rp .ask-rp-tile select{height:32px;padding:0 10px;border-radius:10px;font-size:12px;background:var(--surface);}
3605
+ .ask-rp-model{flex:0 1 170px;}
3606
+ .ask-rp-eff{display:inline-flex;gap:2px;padding:2px;border-radius:999px;background:var(--field);border:1px solid var(--line);position:relative;}
3607
+ .ask-rp-eff button{height:24px;padding:0 7px;border:0;border-radius:999px;background:transparent;font-family:var(--mono);font-size:10.5px;font-weight:700;color:var(--ink-3);cursor:pointer;transition:.12s;}
3608
+ .ask-rp-eff button:hover{color:var(--ink);}
3609
+ .ask-rp-eff button.on{background:var(--ink);color:var(--on-ink);}
3610
+ .ask-rp-eff button[disabled]{opacity:.35;cursor:default;}
3611
+ .ask-rp-eff.unset button{visibility:hidden;}
3612
+ .ask-rp-eff.unset::after{content:"inherits workflow";position:absolute;inset:0;display:grid;place-items:center;font-family:var(--mono);font-size:10px;color:var(--ink-3);}
3613
+ .ask-rp-ctl{display:inline-flex;align-items:center;gap:8px;font-size:11.5px;color:var(--ink-2);}
3614
+ .ask-rp-ctl>span:first-child{font-family:var(--mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);}
3615
+ .ask-rp-sw{display:inline-flex;align-items:center;position:relative;}
3616
+ .ask-rp-sw input{position:absolute;opacity:0;width:1px;height:1px;}
3617
+ .ask-rp-knob{width:32px;height:18px;border-radius:999px;background:var(--line-2);position:relative;transition:.15s;cursor:pointer;}
3618
+ .ask-rp-knob::after{content:"";position:absolute;top:2px;left:2px;width:14px;height:14px;border-radius:50%;background:var(--knob);transition:.15s;}
3619
+ .ask-rp-sw input:checked+.ask-rp-knob{background:var(--ink);}
3620
+ .ask-rp-sw input:checked+.ask-rp-knob::after{transform:translateX(14px);}
3621
+ .ask-rp-sw input:disabled+.ask-rp-knob{opacity:.4;cursor:not-allowed;}
3622
+ .ask-rp-sw input:focus-visible+.ask-rp-knob{outline:2px solid var(--ink);outline-offset:2px;}
3623
+ .ask-rp-agents-foot{display:flex;align-items:center;gap:8px;padding:8px 14px;border-top:1px solid var(--line);font-size:11.5px;color:var(--ink-3);}
3624
+ .ask-rp-lane-msg{padding:12px 14px;font-size:12px;color:var(--ink-3);}
3625
+ .ask-card.ask-rp textarea.ask-rp-brief{width:100%;min-height:150px;max-height:420px;padding:12px 14px;border:1px solid var(--line-2);border-radius:12px;background:var(--field);font-size:13px;line-height:1.6;resize:vertical;}
3626
+ .ask-rp-brief-foot{display:flex;align-items:center;gap:12px;margin-top:8px;font-size:11.5px;color:var(--ink-3);flex-wrap:wrap;}
3627
+ .ask-rp-brief-foot kbd{font-family:var(--mono);font-size:10px;padding:1px 5px;border:1px solid var(--line-2);border-radius:5px;background:var(--panel);color:var(--ink-2);}
3628
+ .ask-rp-count{margin-left:auto;}
3629
+ .ask-rp-pills{display:flex;gap:6px;flex-wrap:wrap;}
3630
+ .ask-rp-pill{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 9px;border-radius:999px;background:var(--panel);border:1px solid var(--line-2);font-family:var(--mono);font-size:10.5px;color:var(--ink-2);}
3631
+ .ask-rp-pill button{border:0;background:none;padding:0;color:var(--ink-3);font-family:inherit;cursor:pointer;}
3632
+ .ask-rp-foot{display:flex;align-items:center;gap:10px;padding:12px 18px 14px;background:var(--canvas-2);flex-wrap:wrap;}
3633
+ .ask-rp-foot .ask-card-open-np{font-size:12px;font-weight:500;}
3634
+ .ask-rp-summary{font-family:var(--mono);font-size:10.5px;color:var(--ink-3);text-align:right;margin-left:auto;}
3635
+ .ask-rp-foot .ask-card-not-now{height:34px;padding:0 14px;font-size:12.5px;}
3636
+ .ask-rp-foot .ask-card-start{height:36px;padding:0 18px 0 15px;font-size:12.5px;color:var(--on-ink);box-shadow:var(--shadow-pop);}
3637
+ .ask-rp-foot .ask-card-start svg{width:11px;height:11px;}
3638
+ .ask-rp .ask-card-err{padding:0 18px 10px;}
3639
+ .ask-rp .ask-card-scope-warn{margin:12px 18px 0;}
3640
+ .ask-pop-at{width:288px;padding:6px;border-radius:14px;max-height:min(320px,60%);overflow-y:auto;}
3641
+ @media (max-width:640px){.ask-rp-grid,.ask-rp-grid.two{grid-template-columns:1fr;}}
3642
+ @media (prefers-reduced-motion: reduce){.ask-card.ask-rp{animation:none;} .ask-rp *{transition:none!important;}}
3643
+
3644
+ /* ---------- workflow card chrome (ui/public/ask-panel.mjs buildWorkflowCard; mockup 2026-09-05 §A-§C) ---------- */
3645
+ .ask-card.ask-wfcard{gap:0;padding:16px 18px;border-width:1px;animation:wr-rise .2s cubic-bezier(.2,.7,.3,1) both;}
3646
+ .ask-wfcard>*{min-width:0;}
3647
+ .ask-wfcard-head{display:flex;align-items:center;gap:8px;height:24px;}
3648
+ .ask-wfcard-title{font-weight:600;font-size:15px;line-height:1.35;color:var(--ink);white-space:nowrap;}
3649
+ .ask-wfcard-round{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:999px;background:var(--field);color:var(--ink-2);font-family:var(--mono);font-size:10.5px;white-space:nowrap;}
3650
+ .ask-wfcard-spacer,.ask-wfcard-actions .ask-card-actions-spacer{flex:1 1 auto;}
3651
+ .ask-wfcard-tag{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:999px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;background:var(--violet-bg);color:var(--violet-ink);white-space:nowrap;}
3652
+ .ask-wfcard-head+.ask-wfcard-body{margin-top:12px;}
3653
+ .ask-wfcard-body>.ask-wfcard-hint{margin-top:8px;font-size:12px;line-height:1.5;color:var(--ink-3);}
3654
+ .ask-wfcard-saved{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:600;line-height:1.35;color:var(--ink);}
3655
+ .ask-wfcard-saved svg{flex:0 0 auto;stroke:var(--green);}
3656
+ .ask-wfcard-saved span{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3657
+ .ask-wfcard-savedline{margin-top:4px;font-size:13px;line-height:1.55;color:var(--ink-2);}
3658
+ .ask-wfcard-savedline+.ask-wfcard-graph{margin-top:16px;}
3659
+ .ask-wfcard .ask-card-err{margin-top:8px;}
3660
+ .ask-wfcard-actions{display:flex;align-items:center;gap:8px;margin-top:20px;}
3661
+ .ask-wfcard-actions .ask-card-start,.ask-wfcard-actions .ask-card-not-now,.ask-wfcard-actions .ask-card-open-np{height:36px;font-size:13px;}
3662
+ .ask-wfcard-actions .ask-card-start{padding:0 18px;}
3663
+ .ask-wfcard-actions .ask-card-not-now{padding:0 16px;}
3664
+ /* .ask-pop-chip itself lives with the other popover panels (below .ask-pop): both
3665
+ selectors are (0,1,0) on the same element, so a rule written here would lose its
3666
+ radius to .ask-pop's on source order alone. */
3667
+ .ask-pop-cap{padding:8px 10px 4px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3668
+ .ask-pop-chip .ask-model-item.on{background:var(--field);}
3669
+ .ask-pop-effort{display:flex;align-items:center;gap:4px;padding:8px 10px 6px;}
3670
+ .ask-pop-effort-label{font-size:12px;color:var(--ink-2);margin-right:auto;white-space:nowrap;}
3671
+ .ask-pop-effort .ask-effort-pill{width:auto;height:24px;padding:0 8px;border:1px solid var(--line-2);border-radius:999px;background:transparent;color:var(--ink-2);font-weight:600;font-size:11px;white-space:nowrap;}
3672
+ .ask-pop-effort .ask-effort-pill.on{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
3673
+ .ask-pop-effort-none{font-size:11px;color:var(--ink-3);}
3674
+ @media (prefers-reduced-motion: reduce){.ask-card.ask-wfcard{animation:none;}}
3675
+
3676
+ /* ---------- metrics card chrome (ui/public/ask-panel.mjs buildMetricsCard; docs/team-metrics.md "Ask Worca") ---------- */
3677
+ .ask-card.ask-mcard{gap:0;padding:16px 18px;border-width:1px;}
3678
+ .ask-mcard>*{min-width:0;}
3679
+ .ask-mcard-head{display:flex;align-items:center;gap:8px;height:24px;}
3680
+ .ask-mcard-title{font-weight:600;font-size:15px;line-height:1.35;color:var(--ink);white-space:nowrap;}
3681
+ .ask-mcard-kind{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:999px;background:var(--field);color:var(--ink-2);font-family:var(--mono);font-size:10.5px;white-space:nowrap;}
3682
+ .ask-mcard-body{margin-top:12px;display:flex;flex-direction:column;gap:6px;font-size:13px;line-height:1.5;color:var(--ink-2);}
3683
+ .ask-mcard-summary{display:flex;align-items:flex-start;gap:8px;font-weight:600;color:var(--ink);}
3684
+ .ask-mcard-summary svg{flex:0 0 auto;margin-top:3px;stroke:var(--green);}
3685
+ .ask-mcard-target{font-size:12.5px;color:var(--ink-3);}
3686
+ .ask-mcard-note{font-size:12.5px;color:var(--ink-3);font-style:italic;}
3687
+ .ask-mcard-effects{margin:4px 0 0;padding-left:18px;font-size:12.5px;color:var(--ink-2);}
3688
+ .ask-mcard-effects li{margin:2px 0;}
3689
+ .ask-mcard-detail{font-size:12.5px;color:var(--ink-2);}
3690
+ .ask-mcard-failed{font-size:12.5px;color:var(--red-ink);}
3691
+ .ask-mcard-hint{font-size:12px;color:var(--ink-3);}
3692
+ .ask-mcard-results{list-style:none;margin:4px 0 0;padding:0;font-size:12.5px;}
3693
+ .ask-mcard-results li{padding:3px 0;}
3694
+ .ask-mcard-results li.is-failed{color:var(--red-ink);}
3695
+ .ask-mcard-results li.is-skipped{color:var(--ink-3);}
3696
+ .ask-mcard-actions{display:flex;align-items:center;gap:8px;margin-top:14px;}
3697
+ .ask-mcard.is-applied .ask-mcard-head{opacity:.9;}
3698
+
3699
+ /* ---------- Auto proposal body (ui/public/auto-proposal.mjs) — one body, two hosts (mockup §D/§F) ----------
3700
+ Rhythm top→bottom: name → 8 → reasoning → 16 → chips → 8 → fingerprint → 16 → graph → 12 → loops → 16 → match → 8 → meta.
3701
+ Per-child margins so every host keeps the same gaps. */
3702
+ .ask-wfcard-body{display:flex;flex-direction:column;min-width:0;}
3703
+ .ask-wfcard-body>*{margin:0;min-width:0;}
3704
+ .ask-wfcard-namerow{display:flex;align-items:baseline;gap:10px;}
3705
+ .ask-wfcard-namewrap+*{margin-top:8px;}
3706
+ /* The name leads the CARD order (no predecessor, no margin) but sits mid-list in the
3707
+ question panel (reason → signals → fingerprint → name → graph), where it would butt
3708
+ against the 11px mono fingerprint line. The `*+` guard keeps the card's first child flush. */
3709
+ .ask-wfcard-body>*+.ask-wfcard-namewrap{margin-top:12px;}
3710
+ .ask-wfcard-name{flex:0 1 auto;min-width:0;font-weight:600;font-size:15px;line-height:1.35;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3711
+ .ask-wfcard-edit{flex:0 0 auto;border:0;background:transparent;padding:0;color:var(--ink-3);font-family:var(--sans);font-size:11px;line-height:1.35;white-space:nowrap;cursor:pointer;border-radius:4px;}
3712
+ .ask-wfcard-edit svg{width:11px;height:11px;margin-right:4px;vertical-align:-1px;stroke:currentColor;fill:none;stroke-width:2;}
3713
+ .ask-wfcard-edit:hover{color:var(--ink);}
3714
+ .ask-wfcard-edit:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
3715
+ .ask-wfcard-nameedit[hidden],.ask-wfcard-namerow[hidden]{display:none;}
3716
+ .ask-wfcard-field{display:block;width:100%;height:36px;padding:0 12px;border:1px solid var(--line-2);border-radius:10px;background:var(--field);color:var(--ink);font-family:var(--sans);font-size:13px;font-weight:500;outline:none;}
3717
+ .ask-wfcard-field:focus{border-color:var(--ink);background:var(--field-focus);}
3718
+ .ask-wfcard-fieldhint{margin-top:8px;font-size:11px;line-height:1.35;color:var(--ink-3);}
3719
+ .ask-wfcard-reason{font-size:13px;line-height:1.55;color:var(--ink-2);max-width:62ch;}
3720
+ .ask-wfcard-signals{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px;}
3721
+ .ask-wfcard-sig{display:inline-flex;align-items:center;height:22px;padding:0 10px;border-radius:999px;font-family:var(--mono);font-size:11px;line-height:1;background:var(--field);color:var(--ink-2);white-space:nowrap;}
3722
+ .ask-wfcard-sig.kind{background:transparent;border:1px solid var(--ink);color:var(--ink);font-weight:700;}
3723
+ .ask-wfcard-sig.size{background:var(--violet-bg);color:var(--violet-ink);}
3724
+ .ask-wfcard-fp{margin-top:8px;font-family:var(--mono);font-size:11px;line-height:1.5;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3725
+ .ask-wfcard-fp .k{margin-right:8px;}
3726
+ .ask-wfcard-graph{position:relative;margin-top:16px;min-height:120px;overflow:hidden;border:1px solid var(--line);border-radius:12px;
3727
+ background:var(--canvas-2) radial-gradient(circle,var(--line-2) 1.1px,transparent 1.1px);background-size:22px 22px;transition:height .24s cubic-bezier(.2,.7,.3,1);}
3728
+ .ask-wfcard-loops{display:flex;flex-direction:column;gap:6px;margin-top:12px;padding:0;list-style:none;}
3729
+ .ask-wfcard-loop{position:relative;padding-left:22px;font-family:var(--mono);font-size:11px;line-height:1.5;color:var(--ink-2);}
3730
+ .ask-wfcard-loop::before{content:"↻";position:absolute;left:0;top:0;width:14px;text-align:center;color:var(--amber);font-size:13px;line-height:16px;}
3731
+ .ask-wfcard-loop b{font-weight:700;color:var(--amber-ink);}
3732
+ .ask-wfcard-match{position:relative;margin-top:16px;padding-left:24px;font-size:13px;line-height:1.55;color:var(--ink-2);}
3733
+ .ask-wfcard-match svg{position:absolute;left:0;top:3px;width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;}
3734
+ .ask-wfcard-match b{font-weight:600;color:var(--ink);}
3735
+ .ask-wfcard-match.is-hit{color:var(--green-ink);}
3736
+ .ask-wfcard-warnings{display:flex;flex-direction:column;gap:8px;margin-top:12px;}
3737
+ .ask-wfcard-warn{font-size:13px;line-height:1.5;color:var(--amber-ink);background:var(--amber-wash);border:1px solid var(--amber-line);border-radius:10px;padding:8px 12px;}
3738
+ .ask-wfcard-meta{margin-top:8px;font-family:var(--mono);font-size:11px;line-height:1.5;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums;}
3739
+ @media (prefers-reduced-motion: reduce){.ask-wfcard-graph{transition:none;}}
3740
+
3741
+ /* ---------- workflow card build (ui/public/auto-build.mjs; mockup §B/§F motion) ---------- */
3742
+ .ask-wfcard-graph .gv-world .node{transition:opacity .28s cubic-bezier(.2,.7,.3,1),translate .28s cubic-bezier(.2,.7,.3,1);}
3743
+ .ask-wfcard-graph .gv-world .node.is-hid{opacity:0;translate:0 8px;}
3744
+ .ask-wfcard-graph .gv-wires path.wire{transition:opacity .42s cubic-bezier(.4,0,.2,1);}
3745
+ .ask-wfcard-graph .gv-wires path.wire.is-hid,.ask-wfcard-graph .gv-world .wbadge.is-hid{opacity:0;}
3746
+ .ask-wfcard-match.is-hid,.ask-wfcard-loops.is-hid{opacity:0;}
3747
+ .ask-wfcard-match,.ask-wfcard-loops{transition:opacity .2s ease;}
3748
+ .ask-wfcard-trace{display:flex;flex-direction:column;margin:12px 0 0;padding:0;list-style:none;}
3749
+ .ask-wfcard-step{display:flex;align-items:center;gap:12px;height:28px;font-size:13px;color:var(--ink-3);}
3750
+ .ask-wfcard-step .st-ico{width:14px;height:14px;flex:0 0 14px;display:grid;place-items:center;}
3751
+ .ask-wfcard-step .st-dot{width:6px;height:6px;border-radius:50%;background:var(--ink-3);}
3752
+ .ask-wfcard-step .st-check{width:14px;height:14px;stroke:var(--green);fill:none;stroke-width:2.4;display:none;}
3753
+ .ask-wfcard-step .st-label{font-weight:500;white-space:nowrap;}
3754
+ .ask-wfcard-step .st-meter{font-family:var(--mono);font-size:11px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums;}
3755
+ .ask-wfcard-step.is-live .st-label{background:linear-gradient(100deg,var(--ink-3) 0%,var(--ink-3) 34%,var(--ink) 50%,var(--ink-3) 66%,var(--ink-3) 100%);
3756
+ background-size:220% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:ask-shimmer 2.4s linear infinite;}
3757
+ .ask-wfcard-step.is-live .st-dot,.ask-wfcard-step.is-done .st-dot{display:none;}
3758
+ .ask-wfcard-step.is-done{color:var(--ink-2);}
3759
+ .ask-wfcard-step.is-done .st-check{display:block;}
3760
+ @media (prefers-reduced-motion: reduce){
3761
+ .ask-wfcard-step.is-live .st-label{background:none;-webkit-background-clip:border-box;background-clip:border-box;color:var(--ink-2);animation:none;}
3762
+ }
3763
+
3764
+ .ask-jump{position:absolute;left:0;right:0;bottom:calc(var(--ask-box-top) + 9px);margin:0 auto;width:max-content;
3033
3765
  display:flex;align-items:center;gap:7px;padding:6px 12px;border:1px solid var(--line-2);border-radius:999px;
3034
3766
  background:var(--panel);color:var(--ink);font-family:inherit;font-weight:600;font-size:11.5px;cursor:pointer;
3035
- box-shadow:0 6px 18px rgba(25,25,27,.10);transition:border-color .15s;}
3767
+ box-shadow:var(--shadow-hover);transition:border-color .15s;}
3036
3768
  .ask-jump:hover{border-color:var(--ink);}
3037
3769
  .ask-jump[hidden]{display:none;}
3038
3770
  .ask-jump:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
3039
3771
 
3040
- .ask-composer{position:relative;flex:0 0 auto;border-top:1px solid var(--line);padding:10px 12px 11px;
3772
+ /* The band is the padded outer strip (no border-top: the box is the separation);
3773
+ the box holds chips → textarea → msg → row, rounded and bordered, on the same
3774
+ cap as the transcript column. Panel background, not field: the textarea keeps
3775
+ the contrast baseline (scripts/verify-theme-cdp.mjs) it has today. */
3776
+ .ask-composer{position:relative;flex:0 0 auto;padding:10px 16px 14px;display:flex;flex-direction:column;}
3777
+ .ask-composer-box{width:100%;max-width:var(--ask-col-max);margin-inline:auto;padding:8px 10px;
3778
+ border:1px solid var(--line-2);border-radius:16px;background:var(--panel);
3041
3779
  display:flex;flex-direction:column;gap:4px;}
3042
3780
  .ask-chips{display:flex;flex-wrap:wrap;gap:6px;padding:2px 4px 4px;}
3043
3781
  .ask-chips[hidden]{display:none;}
@@ -3082,11 +3820,19 @@ body.rail-collapsed .ask-dock{left:76px;}
3082
3820
  .ask-wt-btn[hidden]{display:none;}
3083
3821
 
3084
3822
  .ask-pop{position:absolute;z-index:3;background:var(--panel);border:1px solid var(--line-2);
3085
- padding:6px;box-shadow:0 12px 34px rgba(25,25,27,.12);border-radius:16px;}
3823
+ padding:6px;box-shadow:var(--shadow-menu);border-radius:16px;}
3086
3824
  .ask-pop-threads{top:46px;right:76px;width:326px;}
3087
- .ask-pop-scope{left:16px;bottom:44px;width:300px;max-height:min(420px,70%);overflow-y:auto;}
3088
- .ask-pop-model{right:30px;bottom:42px;width:292px;border-radius:18px;}
3089
- .ask-pop-runinfo{right:96px;bottom:44px;width:326px;z-index:4;}
3825
+ /* The composer popovers hug the box (--ask-col-inset, see .ask-sheet) and float
3826
+ just above it (--ask-box-top); agents/worktrees keep their old offsets left of
3827
+ the model popover. */
3828
+ .ask-pop-scope{left:var(--ask-col-inset);bottom:calc(var(--ask-box-top) + 6px);width:300px;max-height:min(420px,70%);overflow-y:auto;}
3829
+ .ask-pop-model{right:var(--ask-col-inset);bottom:calc(var(--ask-box-top) + 6px);width:292px;border-radius:18px;}
3830
+ .ask-pop-runinfo{right:calc(var(--ask-col-inset) + 66px);bottom:calc(var(--ask-box-top) + 6px);width:326px;z-index:4;}
3831
+ /* The chip picker (ask-panel.mjs openChipPicker) is the only JS-positioned panel: a band
3832
+ chip sits wherever the transcript scrolled it. Its rows are the WHOLE model catalog, so
3833
+ the menu outgrows the sheet, which clips -- the same cap .ask-pop-scope carries keeps
3834
+ the Effort row reachable, and chipPickerTop() flips it above the chip when that fits. */
3835
+ .ask-pop-chip{width:288px;padding:6px;border-radius:14px;max-height:min(420px,70%);overflow-y:auto;}
3090
3836
  .ask-pop-caption,.ask-pop-caption-row .ask-pop-caption{padding:8px 10px 6px;font-weight:600;font-size:10px;
3091
3837
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);}
3092
3838
  .ask-pop-caption-row{display:flex;align-items:baseline;gap:8px;}
@@ -3135,9 +3881,16 @@ body.rail-collapsed .ask-dock{left:76px;}
3135
3881
  /* Scoped to the threads rows -- .ask-dot elsewhere (agents popover, agent rows,
3136
3882
  the activity head) keeps showing its --seq dot. Here a dot means "this chat is
3137
3883
  live", so an idle row shows none; display, not visibility, so the 6px slot and
3138
- the row's 10px gap collapse with it and the title moves to the left edge. */
3884
+ the row's 10px gap collapse with it and the title moves to the left edge.
3885
+ Two independent arms: green = the chat's own turn is thinking, violet = the
3886
+ chat follows a live run (track_run / a card launch). Each span collapses on
3887
+ its own, so tracking-only shows one violet dot at the edge. Both armed: the
3888
+ spans sit under the pick's 10px gap, and the tracking dot pulls itself back
3889
+ 6px so the pair reads 4px apart instead of a full slot. */
3139
3890
  .ask-thread-dot{display:none;}
3140
3891
  .ask-thread-dot.ask-dot-live{display:block;}
3892
+ .ask-thread-dot.ask-dot-track{display:block;background:var(--violet);animation:wr-pulse 1.6s ease-in-out infinite;}
3893
+ .ask-thread-dot.ask-dot-live+.ask-thread-dot.ask-dot-track{margin-left:-6px;}
3141
3894
  .ask-thread-col{display:flex;flex-direction:column;gap:1px;min-width:0;}
3142
3895
  .ask-thread-title{font-weight:500;font-size:12.5px;color:var(--ink);display:-webkit-box;
3143
3896
  -webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;}
@@ -3153,9 +3906,9 @@ body.rail-collapsed .ask-dock{left:76px;}
3153
3906
  .ask-runinfo-name{font-family:var(--mono);font-size:11.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
3154
3907
  .ask-runinfo-sub{font-family:var(--mono);font-size:10px;color:var(--ink-3);}
3155
3908
  .ask-runinfo-elapsed{margin-left:auto;font-family:var(--mono);font-size:10px;color:var(--seq);}
3156
- /* .ask-pop-worktrees inherits .ask-pop-runinfo's right/bottom offset, which is
3909
+ /* .ask-pop-worktrees inherits .ask-pop-runinfo's bottom offset, which is
3157
3910
  calibrated for the AGENTS button; the worktrees button sits to its left. */
3158
- .ask-pop-worktrees{min-width:340px;right:187px;}
3911
+ .ask-pop-worktrees{min-width:340px;right:calc(var(--ask-col-inset) + 157px);}
3159
3912
  .ask-wt-row .ask-runinfo-sub.ask-wt-path{cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:260px;}
3160
3913
  .ask-wt-row .ask-thread-trash{flex:none;}
3161
3914
 
@@ -3166,9 +3919,9 @@ body.rail-collapsed .ask-dock{left:76px;}
3166
3919
  size as inline width/height and clamps it to the dock; the max-* pair on
3167
3920
  .ask-sheet above is the backstop that keeps a stale inline size inside the
3168
3921
  dock (the rail collapsing changes the dock width without a window resize).
3169
- The floor (JS-only, the stylesheet default 782×669: the sheet grows, never
3922
+ The floor (JS-only, the stylesheet default 821×669: the sheet grows, never
3170
3923
  shrinks) is not a CSS min-* on purpose — that would overflow narrow viewports
3171
- that width:min(782px,100%) handles today.
3924
+ that width:min(821px,100%) handles today.
3172
3925
  Corners: the sheet clips at its rounded corner (inner radius = --r-card minus
3173
3926
  the 1px border), so a square corner grip's straight inset lines fall almost
3174
3927
  entirely outside the clip and only a ~3px sliver ever shows. Each corner is
@@ -3194,17 +3947,77 @@ body.rail-collapsed .ask-dock{left:76px;}
3194
3947
  grip's visible band hugs the border, well outside the button box. */
3195
3948
  .ask-header .ask-icon-btn{position:relative;z-index:6;}
3196
3949
 
3950
+ /* ---------- run progress card (ui/public/ask-run-card.mjs; the live view of a pipeline run in the transcript) ----------
3951
+ Stateless: every value is repainted from the app's run store or GET /api/ask/runs/:id. Tokens only.
3952
+ The run-state ornaments are restated for THIS host: the run-monitor block is scoped to its own host class
3953
+ (pinned by test/ui-run-hosts.test.mjs), and keyframes are name-resolved — referenced here, declared once there.
3954
+ Reduced motion: the dock blanket (.ask-dock *{animation:none !important;}) covers every ELEMENT below — never a
3955
+ pseudo-element (they do not inherit `animation`), so nothing here animates a ::before/::after (D25; pinned). Pips scale with
3956
+ --gv-scale (geometry.mjs) because the flow card is drawn at 0.65 while the world transform stays identity.
3957
+ Every rule that restates a v2-canvas base rule carries .gv-world: the base lives LATER in this file, so a
3958
+ two-class .ask-rc-graph .wbadge would tie on specificity and lose (the budget pill would keep painting its
3959
+ "3×" under the fired "2×"). Pinned by the cascade test in test/ui-ask-style.test.mjs. */
3960
+ .ask-card.ask-rc{gap:0;padding:16px 18px;border-width:1px;animation:wr-rise .2s cubic-bezier(.2,.7,.3,1) both;}
3961
+ .ask-rc>*{min-width:0;}
3962
+ .ask-rc-head{display:flex;align-items:center;gap:8px;height:28px;}
3963
+ .ask-rc-kicker{display:inline-flex;align-items:center;height:20px;padding:0 8px;border-radius:999px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;background:var(--violet-bg);color:var(--violet-ink);white-space:nowrap;}
3964
+ .ask-rc-pill{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:999px;font-family:var(--mono);font-size:11px;font-weight:700;white-space:nowrap;}
3965
+ .ask-rc-dot{width:8px;height:8px;border-radius:50%;background:currentColor;flex:0 0 auto;}
3966
+ .ask-rc.is-live .ask-rc-dot{animation:dotpulse 1.3s ease-in-out infinite;}
3967
+ .ask-rc-pill.st-peach{background:var(--peach-bg);color:var(--h-peach-ink);}
3968
+ .ask-rc-pill.st-blue{background:var(--blue-bg);color:var(--h-blue-ink);}
3969
+ .ask-rc-pill.st-violet{background:var(--violet-bg);color:var(--violet-ink);}
3970
+ .ask-rc-pill.st-green{background:var(--green-bg);color:var(--h-green-ink);}
3971
+ .ask-rc-pill.st-red{background:var(--red-bg);color:var(--red-ink);}
3972
+ .ask-rc-pill.st-amber{background:var(--amber-bg);color:var(--amber-ink);}
3973
+ .ask-rc-spacer{flex:1 1 auto;}
3974
+ .ask-rc-open{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:999px;background:var(--ink);color:var(--panel);font-weight:600;font-size:12px;text-decoration:none;white-space:nowrap;transition:.15s;}
3975
+ .ask-rc-open:hover{filter:brightness(1.08);}
3976
+ .ask-rc-open:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
3977
+ .ask-rc-title{margin-top:12px;font-weight:600;font-size:15px;line-height:1.35;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
3978
+ .ask-rc-sub{margin-top:4px;font-family:var(--mono);font-size:10.5px;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3979
+ .ask-rc-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:14px;}
3980
+ .ask-rc-stat{display:flex;flex-direction:column;gap:3px;padding:9px 11px;border:1px solid var(--line);border-radius:12px;background:var(--field);}
3981
+ .ask-rc-stat-k{font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3);}
3982
+ .ask-rc-stat-v{font-family:var(--mono);font-size:14px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;}
3983
+ .ask-rc-active{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px;}
3984
+ .ask-rc-active[hidden]{display:none;}
3985
+ .ask-rc-agent{--c:var(--ink-3);display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px 0 7px;border-radius:999px;border:1px solid color-mix(in srgb, var(--c) 45%, var(--line));background:color-mix(in srgb, var(--c) 12%, var(--panel));color:var(--ink);font-size:11.5px;font-weight:600;white-space:nowrap;}
3986
+ .ask-rc-agent-dot{width:7px;height:7px;border-radius:50%;background:var(--c);flex:0 0 auto;animation:dotpulse 1.3s ease-in-out infinite;}
3987
+ .ask-rc-banner{margin-top:12px;padding:9px 12px;border-radius:10px;font-size:12.5px;font-weight:600;color:var(--amber-ink);background:var(--amber-wash);border:1px solid var(--amber-line);}
3988
+ .ask-rc-banner[hidden]{display:none;}
3989
+ .ask-rc-reason{margin-top:10px;font-size:12px;color:var(--red-ink);}
3990
+ .ask-rc-reason[hidden]{display:none;}
3991
+ .ask-rc-graph{position:relative;margin-top:14px;min-height:120px;overflow:hidden;border:1px solid var(--line);border-radius:12px;cursor:pointer;
3992
+ background:var(--canvas-2) radial-gradient(circle,var(--line-2) 1.1px,transparent 1.1px);background-size:22px 22px;transition:height .24s cubic-bezier(.2,.7,.3,1);}
3993
+ .ask-rc-graph[hidden]{display:none;}
3994
+ .ask-rc-graph .gv-world .node.is-active{border-color:color-mix(in srgb, var(--c) 55%, var(--line-2));animation:nodeGlow 2.2s ease-in-out infinite;}
3995
+ .ask-rc-graph .gv-world .node.is-paused{border-color:color-mix(in srgb, var(--amber) 55%, var(--line-2));animation:nodeGlowAmber 2.2s ease-in-out infinite;}
3996
+ .ask-rc-graph .gv-world .node.is-stopped,.ask-rc-graph .gv-world .node.is-error{border-color:color-mix(in srgb, var(--red) 50%, var(--line-2));box-shadow:0 0 0 3px color-mix(in srgb, var(--red) 13%, transparent),var(--shadow-soft);}
3997
+ .ask-rc-graph .gv-world .node.is-skipped{opacity:.35;border-style:dashed;}
3998
+ .ask-rc-graph .gv-world .node.is-done::after,.ask-rc-graph .gv-world .node.is-paused::after,.ask-rc-graph .gv-world .node.is-stopped::after,.ask-rc-graph .gv-world .node.is-error::after{content:"";position:absolute;top:calc(-8px * var(--gv-scale));right:calc(-8px * var(--gv-scale));width:calc(21px * var(--gv-scale));height:calc(21px * var(--gv-scale));border-radius:50%;box-shadow:var(--shadow-soft);z-index:3;color:var(--on-status);font:800 calc(12px * var(--gv-scale))/calc(21px * var(--gv-scale)) var(--sans);text-align:center;}
3999
+ .ask-rc-graph .gv-world .node.is-done::after{content:"✓";background:var(--green);}
4000
+ .ask-rc-graph .gv-world .node.is-paused::after{content:"❚❚";font-size:calc(8px * var(--gv-scale));background:var(--amber);}
4001
+ .ask-rc-graph .gv-world .node.is-stopped::after,.ask-rc-graph .gv-world .node.is-error::after{content:"×";background:var(--red);}
4002
+ .ask-rc-graph .gv-world .node:has(> .ngate)::after{content:none;}
4003
+ .ask-rc-graph .gv-world .ngate{animation:dotpulse 1.3s ease-in-out infinite;}
4004
+ .ask-rc-graph .gv-wires path.wire-live{stroke-dasharray:6 6;stroke-width:2.4;animation:wireDash .6s linear infinite;}
4005
+ .ask-rc-graph .gv-world .wbadge{font-size:0;line-height:0;padding:0;border:0;background:none;}
4006
+ .ask-rc-graph .wbadge:not(:has(> .wfired)){display:none;}
4007
+ .ask-rc-graph .gv-world .wbadge .wfired{display:inline-block;margin:0;padding:1px 7px;border-radius:999px;background:var(--amber-bg);color:var(--amber-ink);border:1px solid var(--amber);font:700 10px/1.4 var(--mono);}
4008
+
3197
4009
  /* ---------- Ask Worca dock clearance ---------- */
3198
4010
  /* The dock is a fixed overlay -- .ask-dock above: 26px dock padding-bottom plus the
3199
4011
  ~47px pill occludes a ~73px strip at the bottom of every scrollport, while the page
3200
- gutters reserve only 40px. One late override lifts the BOTTOM padding of all five
4012
+ gutters reserve only 40px. One late override lifts the BOTTOM padding of all seven
3201
4013
  scroll gutters to --ask-dock-clearance: 96px = 73px strip + breathing room. Source
3202
- order is load-bearing -- this must follow the base rules at :234, :1718, :1742,
3203
- :2312, :2335 and precede the reduced-motion block below. The -list screen classes
3204
- are targeted, NOT .run-screen/.hist-screen, so the -detail scrollports keep
3205
- padding:0 for their sticky tab bars and take clearance via .rd-body/.hd-body
3206
- instead; body.view-history/.view-running .main keep padding:0 by specificity. */
3207
- .main,.run-screen-list,.hist-screen-list,.rd-body,.hd-body{padding-bottom:var(--ask-dock-clearance);}
4014
+ order is load-bearing -- this must follow the .main, .run-screen/.rd-body,
4015
+ .hist-screen/.hd-body and .proj-screen/.pd-body base rules and precede the
4016
+ reduced-motion block below. The -list screen classes are targeted, NOT
4017
+ .run-screen/.hist-screen/.proj-screen, so the -detail scrollports keep padding:0 for
4018
+ their sticky tab bars and take clearance via .rd-body/.hd-body/.pd-body instead;
4019
+ body.view-history/.view-running/.view-projects .main keep padding:0 by specificity. */
4020
+ .main,.run-screen-list,.hist-screen-list,.proj-screen-list,.rd-body,.hd-body,.pd-body{padding-bottom:var(--ask-dock-clearance);}
3208
4021
 
3209
4022
  /* ---------- native control skins (checkbox / radio / switch / rows) -------- */
3210
4023
  /* Everything the browser used to draw for itself. The mark is the one .qopt
@@ -3345,7 +4158,7 @@ input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}
3345
4158
  width:18px;height:18px;border:none;border-radius:50%;background:var(--line-2);
3346
4159
  color:var(--ink-2);font:600 11px/1 var(--sans);cursor:pointer;display:grid;
3347
4160
  place-items:center;padding:0;}
3348
- .field-clear:hover{background:var(--ink-3);color:#fff;}
4161
+ .field-clear:hover{background:var(--ink-3);color:var(--on-ink);}
3349
4162
  .field-clear[hidden]{display:none;}
3350
4163
  /* the OS disclosure triangle, everywhere — .advanced (:601) already did it locally */
3351
4164
  .disclosure > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;}
@@ -3362,7 +4175,166 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3362
4175
  (0,1,0) `animation:none` here would LOSE the source-order tie against any
3363
4176
  `animation:wr-*` rule appended after it — exactly the trap documented at
3364
4177
  :748-763 for the four legacy names and at :1927-1940 for the ship-it set. */
4178
+ /* ---------- Getting started (docs/getting-started.md) ---------- */
4179
+ /* The shelf sits ABOVE the New pipeline form at the form's own width (.grid.single
4180
+ caps the card at 864px, centred), so it reads as the page's first card, not a
4181
+ side panel. Painted by getting-started.mjs; [hidden] when hidden or unknown. */
4182
+ .gs-host{max-width:960px;margin:0 auto;}
4183
+ .gs-host[hidden]{display:none;}
4184
+ .gs-card{padding:20px 22px 22px;}
4185
+ .gs-head{display:flex;align-items:baseline;gap:12px;margin-bottom:14px;}
4186
+ .gs-head h2{margin:0;flex:1;font-size:16px;font-weight:600;}
4187
+ .gs-progress{font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);}
4188
+ .gs-hide{background:none;border:0;padding:0;font:inherit;font-size:12.5px;color:var(--ink-2);cursor:pointer;
4189
+ text-decoration:underline;text-underline-offset:3px;}
4190
+ .gs-hide:hover{color:var(--ink);}
4191
+ /* Equal tiles that fill the row and wrap 4 -> 2 -> 1: symmetric, never a 3+1 orphan. */
4192
+ .gs-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;}
4193
+ @media (max-width:760px){.gs-tiles{grid-template-columns:repeat(2,minmax(0,1fr));}}
4194
+ @media (max-width:440px){.gs-tiles{grid-template-columns:1fr;}}
4195
+ .gs-tile{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
4196
+ border:1.5px solid var(--line);border-radius:var(--r-ctrl);background:var(--surface);
4197
+ padding:12px 14px 13px;font:inherit;font-size:13px;line-height:1.35;color:var(--ink);text-align:left;cursor:pointer;
4198
+ transition:border-color .2s,transform .15s;}
4199
+ .gs-tile:hover{border-color:var(--violet);transform:translateY(-1px);}
4200
+ .gs-tile:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
4201
+ /* Unfinished tiles arrive in sequence — the tile lands, then its drawing paints
4202
+ (backwards fill keeps it invisible until its turn). */
4203
+ .gs-tile.reveal{animation:gs-tile-in .4s ease-out backwards;animation-delay:var(--tile-delay,0s);}
4204
+ @keyframes gs-tile-in{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}
4205
+ .gs-vig{width:96px;margin:2px 0 0;}
4206
+ .gs-vig svg{width:100%;height:auto;display:block;}
4207
+ .gs-label{font-weight:600;}
4208
+ .gs-mark{position:absolute;top:10px;right:10px;width:20px;height:20px;border-radius:50%;
4209
+ border:1.5px solid var(--line-2);display:grid;place-items:center;color:transparent;font-size:11px;font-weight:700;
4210
+ transition:background .3s,border-color .3s,color .3s;}
4211
+ /* Done recedes: the mark fills with ink (the wizard tracker's own idiom), the
4212
+ label mutes and strikes, the drawing loses its colour. What is still to do
4213
+ keeps full ink and its accent — the shelf IS a progress meter. */
4214
+ .gs-tile.done .gs-mark{background:var(--ink);border-color:var(--ink);color:var(--on-ink);}
4215
+ .gs-tile.done .gs-label{color:var(--ink-2);font-weight:500;text-decoration:line-through;text-decoration-thickness:1px;}
4216
+ .gs-tile.done .gs-vig{opacity:.45;filter:saturate(.3);}
4217
+
4218
+ /* Vignette vocabulary: hollow nodes, wires, frames; ONE accent (violet) per scene. */
4219
+ .gs-node{fill:var(--panel);stroke:var(--ink-3);stroke-width:2;}
4220
+ .gs-node.gs-accent{fill:var(--violet);stroke:var(--violet);}
4221
+ .gs-wire{fill:none;stroke:var(--ink-3);stroke-width:2.2;stroke-linecap:round;}
4222
+ .gs-wire.gs-accent{stroke:var(--violet);}
4223
+ .gs-frame{fill:var(--field);stroke:var(--ink-3);stroke-width:2;}
4224
+ .gs-glyph{fill:none;stroke:var(--ink);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
4225
+ .gs-spark.gs-accent{fill:var(--violet);stroke:none;}
4226
+ .gs-chart{fill:none;stroke:var(--violet);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;}
4227
+ .gs-ring-mark{fill:none;stroke:var(--violet);stroke-width:2;opacity:.45;}
4228
+ /* Motion grammar: pop (overshoot) for marks, a slow draw for wires. Every element's
4229
+ delay is its own slot plus the tile's slot, so one vignette finishes before the
4230
+ next begins. `.static` (a done tile) paints the finished picture, no motion. */
4231
+ .play .gs-pop{transform-box:fill-box;transform-origin:center;
4232
+ animation:gs-pop .45s cubic-bezier(.2,1.6,.4,1) both;animation-delay:calc(var(--tile-delay,0s) + var(--d,0s));}
4233
+ @keyframes gs-pop{from{opacity:0;transform:scale(.2);}to{opacity:1;transform:none;}}
4234
+ .play .gs-draw{stroke-dasharray:1;stroke-dashoffset:1;
4235
+ animation:gs-draw var(--t,.6s) cubic-bezier(.45,0,.3,1) both;animation-delay:calc(var(--tile-delay,0s) + var(--d,0s));}
4236
+ @keyframes gs-draw{to{stroke-dashoffset:0;}}
4237
+
4238
+ /* Sidebar pill under New pipeline: mounted by app.js (not in the shell — the 10-button
4239
+ nav census stays), styled by .nav button; the count wears the accent. */
4240
+ .gs-pill-host[hidden]{display:none;}
4241
+ /* The pill wears the guide's own violet and its halo, so it reads as "the tour is
4242
+ here" from any view — the one animated thing in the rail. */
4243
+ .nav button.gs-pill{font-weight:600;color:var(--violet-ink);border:1.5px solid var(--violet);padding:6.5px 11.5px;
4244
+ animation:gs-pill-glow 2.4s ease-out infinite;}
4245
+ .nav button.gs-pill:hover{background:var(--violet-bg);color:var(--violet-ink);}
4246
+ .nav button.gs-pill.active{background:var(--violet-bg);border-color:var(--violet);color:var(--violet-ink);animation:none;}
4247
+ .nav button.gs-pill.active svg{stroke:var(--violet-ink);}
4248
+ .nav button.gs-pill.active .gs-pill-count{background:var(--panel);color:var(--violet-ink);}
4249
+ .nav button.gs-pill svg{stroke:var(--violet-ink);}
4250
+ /* Violet ink on the violet wash (not white on solid violet: 3.4:1 at 11px fails the light gate). */
4251
+ .nav button.gs-pill .gs-pill-count{background:var(--violet-bg);color:var(--violet-ink);font-family:var(--mono);font-size:11px;}
4252
+ @keyframes gs-pill-glow{
4253
+ 0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--violet) 50%,transparent);}
4254
+ 70%{box-shadow:0 0 0 9px color-mix(in srgb,var(--violet) 0%,transparent);}
4255
+ 100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--violet) 0%,transparent);}
4256
+ }
4257
+
4258
+ /* Settings › General › Getting started */
4259
+ .gs-settings-row{display:flex;align-items:center;gap:16px;justify-content:space-between;}
4260
+ .gs-settings-row .btn{white-space:nowrap;flex:0 0 auto;}
4261
+ .gs-settings-text{margin:0;color:var(--ink-2);font-size:13px;line-height:1.5;}
4262
+
4263
+ /* ---------- Welcome + Connect Claude Code dialogs ---------- */
4264
+ .ob-welcome{width:min(92vw,600px);padding:30px 34px 26px;animation:wr-rise .28s cubic-bezier(.2,.7,.3,1) both;}
4265
+ .ob-eyebrow{margin:0 0 6px;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);}
4266
+ .ob-headline{margin:0;font-size:27px;font-weight:600;letter-spacing:-.01em;line-height:1.2;}
4267
+ .ob-headline em{font-style:italic;color:var(--violet-ink);}
4268
+ .ob-hero{display:block;width:100%;height:auto;margin:10px 0 12px;}
4269
+ .ob-thread{stroke-width:2.5;}
4270
+ .ob-loop{stroke:var(--ink-3);stroke-dasharray:1;}
4271
+ .ob-doors{display:flex;flex-direction:column;gap:8px;}
4272
+ .ob-door{display:flex;align-items:center;gap:12px;width:100%;padding:12px 14px;
4273
+ border:1.5px solid var(--line-2);border-radius:var(--r-ctrl);background:var(--surface);color:var(--ink);
4274
+ font:inherit;font-weight:600;font-size:14px;text-align:left;cursor:pointer;transition:border-color .15s,background .15s;}
4275
+ .ob-door:hover{border-color:var(--ink);background:var(--field);}
4276
+ .ob-door:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
4277
+ .ob-door-icon{display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:var(--violet-bg);color:var(--violet-ink);flex:0 0 auto;}
4278
+ .ob-door-icon svg{width:19px;height:19px;}
4279
+ .ob-door-arrow{margin-left:auto;color:var(--ink-2);font-size:18px;line-height:1;}
4280
+ .ob-skip{display:block;margin:16px auto 0;background:none;border:0;padding:0;font:inherit;font-size:13px;color:var(--ink-2);
4281
+ cursor:pointer;text-decoration:underline;text-underline-offset:3px;}
4282
+ .ob-skip:hover{color:var(--ink);}
4283
+ .ob-claude{width:min(92vw,560px);padding:24px;}
4284
+ .ob-claude-lead,.ob-claude-note{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-2);}
4285
+ .ob-claude-lead strong{color:var(--ink);}
4286
+ .ob-claude code{font-family:var(--mono);font-size:12px;background:var(--field);padding:1px 5px;border-radius:6px;}
4287
+ .ob-claude-cmd{margin:12px 0;padding:12px 14px;background:var(--field);border-radius:12px;overflow:auto;}
4288
+ .ob-claude-cmd code{background:none;padding:0;font-size:12.5px;}
4289
+ .ob-claude-note a{color:var(--blue-ink-strong);}
4290
+ .ob-claude-status{min-height:18px;margin-top:12px;font-size:13px;line-height:1.45;}
4291
+ .ob-claude-status.ok{color:var(--green-ink);}
4292
+ .ob-claude-status.err{color:var(--red-ink);}
4293
+
4294
+ /* ---------- Spotlight guide (guide-spot.mjs) ---------- */
4295
+ /* Layering: spotlight ABOVE the Ask dock (40) and BELOW every .viewer-modal (50),
4296
+ so a dialog the target opens simply covers it. The target is elevated over the
4297
+ scrim by z-index (no cutout mask) and stays fully interactive; `.guide-lift`
4298
+ raises an ancestor that owns a stacking context the target cannot escape.
4299
+ `pointer` (a target inside an open dialog) drops the scrim and rides above the
4300
+ modal layer instead. */
4301
+ .guide-scrim{position:fixed;inset:0;z-index:44;background:var(--scrim);}
4302
+ /* !important: a control may carry its own id-level position/z-index (#prompt has z-index:1) that
4303
+ would otherwise beat this transient class and leave the ringed control UNDER the scrim. */
4304
+ .guide-target{position:relative !important;z-index:45 !important;}
4305
+ .guide-lift{z-index:45 !important;}
4306
+ .guide-lift-static{position:relative;}
4307
+ /* A lifted select wrapper keeps its chevron ON TOP of the elevated select (the
4308
+ pseudo-element would otherwise paint under the child's z-index). */
4309
+ .select-wrap.guide-lift::after{z-index:46;}
4310
+ /* The ring never fades — it is the answer to "which control?". The pulse is a
4311
+ halo radiating OUT of it, so the mark stays solid and the motion draws the eye. */
4312
+ .guide-ring{position:fixed;z-index:46;pointer-events:none;border:2.5px solid var(--violet);border-radius:18px;
4313
+ animation:guide-pulse 1.8s ease-out infinite;}
4314
+ @keyframes guide-pulse{
4315
+ 0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--violet) 55%,transparent);}
4316
+ 100%{box-shadow:0 0 0 14px color-mix(in srgb,var(--violet) 0%,transparent);}
4317
+ }
4318
+ .guide-balloon{position:fixed;z-index:47;display:flex;flex-direction:column;align-items:flex-start;gap:6px;
4319
+ max-width:300px;padding:11px 14px 10px;background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r-ctrl);
4320
+ box-shadow:var(--shadow-pop);color:var(--ink);font-size:13px;line-height:1.45;}
4321
+ .guide-balloon::before{content:'';position:absolute;top:-6px;left:calc(var(--arrow-x,20px) - 5px);width:10px;height:10px;
4322
+ background:var(--panel);border-left:1px solid var(--line-2);border-top:1px solid var(--line-2);transform:rotate(45deg);}
4323
+ .guide-balloon.above::before{top:auto;bottom:-6px;transform:rotate(225deg);}
4324
+ .guide-skip{background:none;border:0;padding:0;font:inherit;font-size:12px;color:var(--ink-2);cursor:pointer;
4325
+ text-decoration:underline;text-underline-offset:3px;}
4326
+ .guide-skip:hover{color:var(--ink);}
4327
+ .guide-ring[hidden],.guide-balloon[hidden]{display:none;}
4328
+ .guide-layer.pointer .guide-ring{z-index:72;}
4329
+ .guide-layer.pointer .guide-balloon{z-index:73;}
4330
+
4331
+
3365
4332
  @media (prefers-reduced-motion: reduce){
4333
+ /* Getting started: tiles land drawn, vignettes paint finished, the guide ring holds a still halo. */
4334
+ .gs-tile.reveal,.play .gs-pop,.play .gs-draw,.ob-welcome,.guide-ring,.nav button.gs-pill{animation:none;}
4335
+ .nav button.gs-pill{box-shadow:0 0 0 3px color-mix(in srgb,var(--violet) 25%,transparent);}
4336
+ .play .gs-draw{stroke-dashoffset:0;}
4337
+ .guide-ring{box-shadow:0 0 0 6px color-mix(in srgb,var(--violet) 30%,transparent);}
3366
4338
  /* #stop-modal is a top-level overlay, outside the shell — named explicitly. */
3367
4339
  #stop-modal .card{animation:none;}
3368
4340
  /* PSEUDO-ELEMENTS DO NOT INHERIT `animation`, so the `*` blanket below cannot
@@ -3381,6 +4353,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3381
4353
  .run-shell one below. */
3382
4354
  .ask-dock *{animation:none !important;}
3383
4355
  .run-shell *{animation:none !important;}
4356
+ .proj-shell *{animation:none !important;}
3384
4357
  }
3385
4358
 
3386
4359
  /* ========================================================================== */
@@ -3393,7 +4366,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3393
4366
  /* every property they leak. (The UNSCOPED v1 `.node` rules are gone.) */
3394
4367
  /* ========================================================================== */
3395
4368
  .gv-canvas{position:relative;overflow:hidden;touch-action:none;user-select:none;-webkit-user-select:none;
3396
- background:#FBFBF9 radial-gradient(circle,var(--line-2) 1.1px,transparent 1.1px);background-size:22px 22px;}
4369
+ background:var(--canvas-2) radial-gradient(circle,var(--line-2) 1.1px,transparent 1.1px);background-size:22px 22px;}
3397
4370
  .gv-stage{position:absolute;inset:0;outline:none;}
3398
4371
  .gv-stage.panning{cursor:grabbing;}
3399
4372
  .gv-stage.space{cursor:grab;}
@@ -3409,29 +4382,52 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3409
4382
  .gv-wires path.ghost.legal{stroke:var(--green);stroke-dasharray:none;}
3410
4383
  .gv-wires path.ghost.illegal{stroke:var(--red);}
3411
4384
  .gv-world .node{position:absolute;left:0;top:0;display:block;padding:0;gap:0;align-items:stretch;z-index:2;
3412
- width:var(--gv-node-w);background:#fff;border:var(--gv-border) solid var(--line-2);border-radius:16px;
4385
+ width:var(--gv-node-w);background:var(--panel);border:var(--gv-border) solid var(--line-2);border-radius:calc(16px * var(--gv-scale));
3413
4386
  box-shadow:var(--shadow-soft);cursor:grab;transition:box-shadow .12s;}
3414
4387
  .gv-world .node::before{content:none;}
3415
4388
  .gv-world .node:hover{box-shadow:var(--shadow);}
3416
4389
  .gv-world .node.sel{outline:2px solid var(--ink);outline-offset:2px;}
3417
4390
  .gv-world .node.dragging{cursor:grabbing;transition:none;}
3418
4391
  .gv-static .node,.gv-static .wbadge{pointer-events:none;}
3419
- .gv-world .nhead{height:var(--gv-head-h);display:flex;align-items:center;gap:8px;padding:0 11px;
3420
- border-radius:14.5px 14.5px 0 0;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
3421
- .gv-world .nhead svg{width:15px;height:15px;flex:0 0 auto;stroke-width:1.85;}
4392
+ .gv-world .nhead{height:var(--gv-head-h);display:flex;align-items:center;gap:calc(8px * var(--gv-scale));padding:0 calc(11px * var(--gv-scale));
4393
+ border-radius:calc(14.5px * var(--gv-scale)) calc(14.5px * var(--gv-scale)) 0 0;font-size:max(9px,calc(13px * var(--gv-scale)));font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
4394
+ .gv-world .nhead svg{width:calc(15px * var(--gv-scale));height:calc(15px * var(--gv-scale));flex:0 0 auto;stroke-width:1.85;}
3422
4395
  .gv-world .nhead .tt{overflow:hidden;text-overflow:ellipsis;}
3423
- .gv-world .h-flow{background:var(--ink);color:#fff;}
4396
+ .gv-world .h-flow{background:var(--ink);color:var(--on-ink);}
3424
4397
  .gv-world .h-violet{background:var(--violet-bg);color:var(--violet-ink);}
3425
- .gv-world .h-blue{background:#DEEFF7;color:#2E6E8E;}
3426
- .gv-world .h-green{background:#E2F3DF;color:#3B7C3B;}
4398
+ .gv-world .h-blue{background:var(--blue-bg);color:var(--h-blue-ink);}
4399
+ .gv-world .h-green{background:var(--green-bg);color:var(--h-green-ink);}
3427
4400
  .gv-world .h-red{background:var(--red-bg);color:var(--red-ink);}
3428
- .gv-world .h-peach{background:#FCEEDA;color:#8A5A16;}
4401
+ .gv-world .h-peach{background:var(--peach-bg);color:var(--h-peach-ink);}
3429
4402
  .gv-world .h-amber{background:var(--amber-bg);color:var(--amber-ink);}
3430
4403
  .gv-world .nbody{padding:var(--gv-pad-t) 0 var(--gv-pad-b);}
3431
- .gv-world .prow{position:relative;height:var(--gv-row-h);display:flex;align-items:center;gap:7px;padding:0 13px;}
4404
+ /* the chip band (A2/A26): model · effort · flags, ONE line between the head and the body, on the panel (never on a
4405
+ tinted head). Chips are the mockup's one unfloored font — 10px mono, 13px tall at .65 — so the band's inner 137px
4406
+ holds "Sonnet 5 · medium · asks" (mockup F); the model chip ellipsises first. */
4407
+ .gv-world .nband{height:var(--gv-band-h);display:flex;align-items:center;gap:3px;padding:0 calc(3px * var(--gv-scale));overflow:hidden;}
4408
+ .gv-world .bchip{display:inline-block;flex:0 0 auto;height:calc(20px * var(--gv-scale));line-height:calc(20px * var(--gv-scale));padding:0 calc(6.15px * var(--gv-scale));
4409
+ border-radius:999px;font-family:var(--mono);font-size:10px;font-weight:700;white-space:nowrap;min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;}
4410
+ /* 6.15 / 4.6 × 0.65 = the mockup's 4px / 3px chip paddings (its .fl-chip is fixed px; ours scales, no hard-coded px in node CSS) */
4411
+ .gv-world .bchip.model{flex:0 1 auto;background:var(--ink);color:var(--on-ink);}
4412
+ .gv-world .bchip.model.is-unset{background:var(--field);color:var(--ink-3);}
4413
+ .gv-world .bchip.effort{background:var(--field);color:var(--ink-2);}
4414
+ .gv-world .bchip.flag{padding:0 calc(4.6px * var(--gv-scale));background:var(--amber-bg);color:var(--amber-ink);}
4415
+ .gv-world .bchip.flag.q{background:var(--red-bg);color:var(--red-ink);}
4416
+ .gv-world button.bchip{border:0;font-family:var(--mono);font-weight:700;cursor:pointer;color:inherit;}
4417
+ .gv-world button.bchip:hover,.gv-world button.bchip[aria-expanded="true"]{box-shadow:0 0 0 2px var(--line-2);}
4418
+ .gv-world button.bchip:focus-visible{outline:2px solid var(--ink);outline-offset:1px;}
4419
+ /* A36: a port row is ONE line by construction (its height is --gv-row-h); at the 9px floor the Task/OR captions
4420
+ ("prompt + attached files", "forwards freshest input") wrapped to two lines inside the 15.6px row and ate --gv-pad-b
4421
+ (measured in Chrome at 0.65: .prow.cap scrollHeight 19 vs clientHeight 16). The mockup's .fl .prow is nowrap; a caption
4422
+ that STILL does not fit ellipsises. NO overflow:hidden on .prow itself — the port dots hang outside it. */
4423
+ .gv-world .prow{position:relative;height:var(--gv-row-h);display:flex;align-items:center;gap:calc(7px * var(--gv-scale));padding:0 calc(13px * var(--gv-scale));white-space:nowrap;}
4424
+ .gv-world .prow.cap .pt{min-width:0;overflow:hidden;text-overflow:ellipsis;}
3432
4425
  .gv-world .prow.out{justify-content:flex-end;}
3433
- .gv-world .prow .pn{font-size:12.5px;font-weight:500;}
3434
- .gv-world .prow .pt{font:10px/1.3 var(--mono);color:var(--ink-3);}
4426
+ /* nowrap without a guard would let a long port NAME (plugin agents mint their own ids)
4427
+ spill past the card border at every scale — .pn is a flex item, so it needs min-width:0
4428
+ before it will shrink. Same treatment the caption above gets. */
4429
+ .gv-world .prow .pn{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:max(9px,calc(12.5px * var(--gv-scale)));font-weight:500;}
4430
+ .gv-world .prow .pt{font-family:var(--mono);font-size:max(9px,calc(10px * var(--gv-scale)));line-height:1.3;color:var(--ink-3);}
3435
4431
  .gv-world .prow .pt.cond{color:var(--amber-ink);}
3436
4432
  .gv-world .prow .mla{margin-left:auto;}
3437
4433
  /* The global .chip (:692) is a 7px/13px page pill — ~28px tall inside a 24px
@@ -3439,12 +4435,13 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3439
4435
  with a loop / fan-out input (the "loop" / "⤫N" pills seen on running cards).
3440
4436
  Same override the palette needs (.ap .chip); metrics mirror the loop wire's
3441
4437
  .wbadge so "loop" on the port and "2×" on the wire read as one family. */
3442
- .gv-world .prow .chip{flex:0 0 auto;font:700 10px/1.4 var(--mono);padding:1px 7px;border-radius:999px;
4438
+ .gv-world .prow .chip{flex:0 0 auto;font-family:var(--mono);font-weight:700;font-size:max(9px,calc(10px * var(--gv-scale)));line-height:1.4;
4439
+ padding:calc(1px * var(--gv-scale)) calc(7px * var(--gv-scale));border-radius:999px;
3443
4440
  white-space:nowrap;background:var(--field);color:var(--ink-3);}
3444
4441
  .gv-world .prow .chip.am{background:var(--amber-bg);color:var(--amber-ink);}
3445
4442
  .gv-world .prow .chip.fan{background:var(--blue-bg);color:var(--blue-ink);}
3446
4443
  .gv-world .psep{height:var(--gv-sep-h);position:relative;}
3447
- .gv-world .psep::after{content:"";position:absolute;left:13px;right:13px;top:4px;height:1px;background:var(--line);}
4444
+ .gv-world .psep::after{content:"";position:absolute;left:calc(13px * var(--gv-scale));right:calc(13px * var(--gv-scale));top:calc(4px * var(--gv-scale));height:1px;background:var(--line);}
3448
4445
  /* dot centre = row centre: top = (ROW_H − DOT)/2; x overhang = DOT/2 + BORDER,
3449
4446
  so the anchor lands exactly on node.x / node.x + NODE_W. */
3450
4447
  .gv-world .dot,.gv-world .gdot{position:absolute;top:calc((var(--gv-row-h) - var(--gv-dot)) / 2);
@@ -3453,21 +4450,26 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3453
4450
  .gv-world .prow.out .dot{right:calc(-1 * (var(--gv-dot) / 2 + var(--gv-border)));}
3454
4451
  .gv-world .dot.md{background:var(--ink);}
3455
4452
  .gv-world .dot.json{background:var(--blue);}
3456
- .gv-world .dot.void{background:#fff;border:2px solid var(--ink-3);}
3457
- .gv-world .dot.any{background:#fff;border:2px solid var(--ink);}
3458
- .gv-world .dia{position:absolute;top:8px;right:calc(-1 * (4px + var(--gv-border)));width:8px;height:8px;
4453
+ .gv-world .dot.void{background:var(--panel);border:calc(2px * var(--gv-scale)) solid var(--ink-3);}
4454
+ .gv-world .dot.any{background:var(--panel);border:calc(2px * var(--gv-scale)) solid var(--ink);}
4455
+ .gv-world .dia{position:absolute;top:calc(8px * var(--gv-scale));right:calc(-1 * (4px * var(--gv-scale) + var(--gv-border)));width:calc(8px * var(--gv-scale));height:calc(8px * var(--gv-scale));
3459
4456
  background:var(--amber);border-radius:2px;transform:rotate(45deg);}
3460
- .gv-world .gdot{background:var(--field);border:2px dashed var(--seq);}
4457
+ .gv-world .gdot{background:var(--field);border:calc(2px * var(--gv-scale)) dashed var(--seq);}
3461
4458
  .gv-world .prow.gate .pn,.gv-world .prow.gate .pt{color:var(--ink-3);}
3462
- .gv-world .prow.gate.wired .gdot{background:#fff;border-color:var(--ink);}
4459
+ .gv-world .prow.gate.wired .gdot{background:var(--panel);border-color:var(--ink);}
3463
4460
  .gv-world .prow.gate.wired .pn{color:var(--ink);}
3464
- .gv-world .prow.drop-ok .dot,.gv-world .prow.drop-ok .gdot{transform:scale(1.35);box-shadow:0 0 0 3px #D8EFD6;border-color:var(--green);}
4461
+ .gv-world .prow.drop-ok .dot,.gv-world .prow.drop-ok .gdot{transform:scale(1.35);box-shadow:0 0 0 3px var(--drop-ring);border-color:var(--green);}
3465
4462
  .gv-world .prow.drop-bad .dot,.gv-world .prow.drop-bad .gdot{box-shadow:0 0 0 3px var(--red-bg);border-color:var(--red);}
3466
4463
  .gv-world .npip{position:absolute;top:-7px;left:-7px;width:14px;height:14px;border-radius:50%;
3467
- background:var(--red);border:2px solid #fff;cursor:pointer;z-index:3;}
4464
+ background:var(--red);border:2px solid var(--panel);cursor:pointer;z-index:3;}
4465
+ /* the wire badge is the SECOND unfloored font (A26/A35 — the mockup's .fl .wbadge{font-size:10px;line-height:14px}); at scale 1 this is today's 10px/1.4 */
3468
4466
  .gv-world .wbadge{position:absolute;transform:translate(-50%,-50%);z-index:2;background:var(--amber-bg);
3469
- color:var(--amber-ink);border:1px solid var(--amber);border-radius:999px;padding:1px 7px;
3470
- font:10px/1.4 var(--mono);pointer-events:none;}
4467
+ color:var(--amber-ink);border:1px solid var(--amber);border-radius:999px;padding:calc(1px * var(--gv-scale)) calc(7px * var(--gv-scale));
4468
+ font-family:var(--mono);font-size:10px;line-height:14px;pointer-events:none;}
4469
+ /* flow mode (A3): the stage is as tall as its rows — the host reads it back — and the world never transforms */
4470
+ .gv-stage.gv-flow{position:relative;inset:auto;width:100%;}
4471
+ /* A35: a flow host is never inside a click-to-open card, so its cards/badges may take pointer events (head + chip tooltips) */
4472
+ .gv-static.gv-flow .node,.gv-static.gv-flow .wbadge{pointer-events:auto;}
3471
4473
  /* Run-mode executions footer (P6 fills it through view.setFooter, which is the
3472
4474
  ONE writer of a run card's height). Heights MUST stay var(--gv-foot-h) /
3473
4475
  var(--gv-exec-row-h): nodeSize bills FOOT_H for the first footer LINE and
@@ -3513,7 +4515,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3513
4515
  .gv-world .ngate{position:absolute;top:-7px;right:-7px;width:15px;height:15px;border-radius:50%;
3514
4516
  background:var(--amber-bg);color:var(--amber-ink);border:1px solid var(--amber);
3515
4517
  font:9px/13px var(--sans);text-align:center;z-index:3;}
3516
- .gv-world .nrun{position:absolute;top:-9px;right:16px;display:flex;gap:6px;background:#fff;
4518
+ .gv-world .nrun{position:absolute;top:-9px;right:16px;display:flex;gap:6px;background:var(--panel);
3517
4519
  border:1px solid var(--line-2);border-radius:999px;padding:1px 8px;font:10px/1.4 var(--mono);color:var(--ink-3);}
3518
4520
  .gv-world .wbadge .wfired{margin-left:5px;font-weight:700;}
3519
4521
  .gv-chip{position:absolute;z-index:6;pointer-events:none;background:var(--red-bg);color:var(--red-ink);
@@ -3542,7 +4544,7 @@ html{scrollbar-color:var(--line-2) transparent;scrollbar-width:thin;}
3542
4544
  input.gv-name{width:auto;flex:0 1 340px;min-width:140px;border:1.5px solid transparent;background:var(--field);
3543
4545
  font:600 15px var(--sans);letter-spacing:-.01em;color:var(--ink);padding:8px 11px;border-radius:11px;
3544
4546
  text-overflow:ellipsis;transition:background .15s,border-color .15s;}
3545
- input.gv-name:focus{background:#fff;border-color:var(--ink);outline:none;}
4547
+ input.gv-name:focus{background:var(--field-focus);border-color:var(--ink);outline:none;}
3546
4548
  input.gv-name:focus-visible{outline:none;}
3547
4549
  .gv-errchip{background:var(--red-bg);color:var(--red-ink);border:1px solid var(--red);border-radius:999px;
3548
4550
  padding:4px 11px;font:600 11.5px var(--sans);cursor:pointer;flex:0 0 auto;white-space:nowrap;}
@@ -3575,6 +4577,21 @@ input.gv-name:focus-visible{outline:none;}
3575
4577
  .gv-ins-rail[data-tab="agents"] > .gv-ins-body{display:none;}
3576
4578
  .gv-ins-rail[data-tab="info"] > .gv-agents-pane{display:none;}
3577
4579
 
4580
+ /* The nav cluster rides the canvas, clear of the rail: 352px is the open rail's
4581
+ 340 plus a 12px gutter, 40px the collapsed 28 plus the same gutter — the
4582
+ INSET_OPEN / INSET_COLLAPSED pair above, so change them together. The sibling
4583
+ selector only works because #gv-nav FOLLOWS #gv-ins-rail in index.html. */
4584
+ .gv-nav{position:absolute;z-index:6;bottom:12px;right:352px;display:flex;flex-direction:column;gap:6px;}
4585
+ .gv-ins-rail[data-open="collapsed"] ~ .gv-nav{right:40px;}
4586
+ .gv-nav-btn{width:30px;height:30px;padding:0;display:grid;place-items:center;
4587
+ border:1px solid var(--line-2);border-radius:9px;background:var(--panel);color:var(--ink-2);
4588
+ box-shadow:var(--shadow-soft);cursor:pointer;line-height:1;font-family:inherit;
4589
+ transition:background .12s,color .12s,opacity .12s;}
4590
+ .gv-nav-btn:hover:not(:disabled){background:var(--field);color:var(--ink);}
4591
+ .gv-nav-btn:disabled{opacity:.42;cursor:default;box-shadow:none;}
4592
+ .gv-nav-btn:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
4593
+ .gv-nav-btn svg{display:block;}
4594
+
3578
4595
  .gv-ins-bar{flex:0 0 auto;display:flex;align-items:center;gap:7px;padding:5px 9px 5px 0;
3579
4596
  border-bottom:1px solid var(--line);}
3580
4597
  .gv-ins-rail[data-open="collapsed"] .gv-ins-bar{padding:0;border-bottom:none;}
@@ -3596,7 +4613,7 @@ input.gv-name:focus-visible{outline:none;}
3596
4613
  .gv-tab{flex:1 1 0;padding:5px 0;border:none;border-radius:8px;background:transparent;color:var(--ink-3);
3597
4614
  font:600 12px var(--sans);font-family:inherit;cursor:pointer;transition:background .12s,color .12s;}
3598
4615
  .gv-tab:hover{color:var(--ink);}
3599
- .gv-tab[aria-selected="true"]{background:#fff;color:var(--ink);box-shadow:var(--shadow-soft);}
4616
+ .gv-tab[aria-selected="true"]{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-soft);}
3600
4617
  .gv-tab:focus-visible{outline:2px solid var(--ink);outline-offset:-2px;}
3601
4618
 
3602
4619
  .gv-ins-pane{flex:1 1 auto;min-width:0;min-height:0;overflow:auto;}
@@ -3619,12 +4636,14 @@ input.gv-name:focus-visible{outline:none;}
3619
4636
  padding, 14px text) are far too heavy for a 308px rail. */
3620
4637
  .ins-panel .ins-select,.ins-panel .ins-number{width:100%;padding:8px 11px;font-size:12.5px;border-radius:10px;
3621
4638
  background:var(--field);border:1.5px solid transparent;color:var(--ink);font-family:inherit;}
3622
- .ins-panel .ins-select:focus,.ins-panel .ins-number:focus{background:#fff;border-color:var(--ink);outline:none;}
4639
+ .ins-panel .ins-select:focus,.ins-panel .ins-number:focus{background:var(--field-focus);border-color:var(--ink);outline:none;}
3623
4640
  /* `select{appearance:none}` (global) strips the native arrow and the product
3624
- draws its own with .select-wrap::after — which the rail has no wrapper for,
3625
- so the chevron rides in as a background image instead. */
3626
- .ins-panel .ins-select{padding-right:30px;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%235C5C63' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
3627
- background-repeat:no-repeat;background-position:right 11px center;}
4641
+ draws its own with .select-wrap::after — so the rail's `select()` now wraps it in
4642
+ .ins-select-wrap and the chevron is a token-coloured ::after (dark mode: a baked-hex data-URI cannot follow the ink). */
4643
+ .ins-panel .ins-select{padding-right:30px;}
4644
+ .ins-select-wrap{position:relative;display:block;}
4645
+ .ins-select-wrap::after{content:"";position:absolute;right:12px;top:50%;width:8px;height:8px;
4646
+ border-right:1.8px solid var(--ink-2);border-bottom:1.8px solid var(--ink-2);transform:translateY(-65%) rotate(45deg);pointer-events:none;}
3628
4647
  .ins-tog{display:flex;align-items:flex-start;gap:10px;padding:9px 11px;
3629
4648
  border:1px solid var(--line);border-radius:12px;background:var(--field);}
3630
4649
  .ins-tog input[type="checkbox"]{width:15px;height:15px;flex:0 0 auto;margin:1px 0 0;accent-color:var(--ink);cursor:pointer;}
@@ -3650,9 +4669,9 @@ input.gv-name:focus-visible{outline:none;}
3650
4669
  .ins-pitem .dot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;}
3651
4670
  .ins-pitem .dot.md{background:var(--ink);}
3652
4671
  .ins-pitem .dot.json{background:var(--blue);}
3653
- .ins-pitem .dot.any{background:#fff;border:2px solid var(--ink);}
3654
- .ins-pitem .dot.void{background:#fff;border:2px solid var(--ink-3);}
3655
- .ins-pitem .gdot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#fff;border:2px dashed var(--seq);}
4672
+ .ins-pitem .dot.any{background:var(--panel);border:2px solid var(--ink);}
4673
+ .ins-pitem .dot.void{background:var(--panel);border:2px solid var(--ink-3);}
4674
+ .ins-pitem .gdot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:var(--panel);border:2px dashed var(--seq);}
3656
4675
  .ins-pitem .pn{font-size:12px;font-weight:500;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
3657
4676
  .ins-pitem .pt{font:10px/1.4 var(--mono);color:var(--ink-3);white-space:nowrap;}
3658
4677
  .ins-pitem .mla{margin-left:auto;}
@@ -3668,11 +4687,11 @@ input.gv-name:focus-visible{outline:none;}
3668
4687
  color:var(--ink);font-family:inherit;font-size:12.5px;font-weight:500;}
3669
4688
  .pal-filter::placeholder{color:var(--ink-3);}
3670
4689
  .pal-filter::-webkit-search-decoration,.pal-filter::-webkit-search-cancel-button{-webkit-appearance:none;}
3671
- .pal-filter:focus{outline:none;background:#fff;border-color:var(--ink);}
4690
+ .pal-filter:focus{outline:none;background:var(--field-focus);border-color:var(--ink);}
3672
4691
  .pal-filter:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
3673
4692
  .gv-palette{flex:1 1 auto;min-height:0;overflow:auto;padding:13px 13px 18px;}
3674
4693
  .gv-pal-err{padding:22px 4px;text-align:center;font-size:13px;color:var(--ink-3);}
3675
- .gv-retry{border:1.5px solid var(--line-2);background:#fff;color:var(--ink);font-family:inherit;
4694
+ .gv-retry{border:1.5px solid var(--line-2);background:var(--surface);color:var(--ink);font-family:inherit;
3676
4695
  font-weight:600;font-size:12px;padding:5px 13px;border-radius:999px;cursor:pointer;}
3677
4696
  .gv-retry:hover{background:var(--field);}
3678
4697
 
@@ -3699,7 +4718,7 @@ input.gv-name:focus-visible{outline:none;}
3699
4718
  .pills{display:flex;flex-direction:column;gap:7px;}
3700
4719
  .pills[hidden]{display:none;}
3701
4720
  .ap{display:flex;align-items:center;gap:9px;min-width:0;border:1.5px solid var(--line-2);border-radius:12px;
3702
- background:#fff;padding:9px 11px;cursor:grab;text-align:left;font-family:inherit;color:var(--ink);
4721
+ background:var(--panel);padding:9px 11px;cursor:grab;text-align:left;font-family:inherit;color:var(--ink);
3703
4722
  box-shadow:var(--shadow-soft);transition:transform .12s,box-shadow .12s,border-color .12s;user-select:none;}
3704
4723
  .ap:hover:not(:disabled){transform:translateY(-1px);box-shadow:var(--shadow);}
3705
4724
  .ap:active:not(:disabled){cursor:grabbing;transform:none;}
@@ -3714,7 +4733,7 @@ input.gv-name:focus-visible{outline:none;}
3714
4733
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
3715
4734
  .ap .chip{flex:0 0 auto;background:var(--field);color:var(--ink-3);font-weight:700;font-size:10px;padding:1px 7px;}
3716
4735
  .gv-drag-ghost{position:fixed;z-index:99;pointer-events:none;border:1.5px dashed var(--ink-3);border-radius:12px;
3717
- background:#fff;padding:6px 10px;font:600 12px var(--sans);opacity:.9;box-shadow:var(--shadow);}
4736
+ background:var(--panel);padding:6px 10px;font:600 12px var(--sans);opacity:.9;box-shadow:var(--shadow);}
3718
4737
 
3719
4738
  /* ---------- the editor's legend footer ---------- */
3720
4739
  /* The key describes the CANVAS, so it belongs to the editor card as a whole —
@@ -3735,7 +4754,7 @@ input.gv-name:focus-visible{outline:none;}
3735
4754
  .gv-saved-tab{display:flex;align-items:center;gap:8px;padding:7px 13px;border:1.5px solid var(--line);
3736
4755
  border-radius:999px;background:var(--panel);font:600 12.5px var(--sans);color:var(--ink-2);cursor:pointer;}
3737
4756
  .gv-saved-tab:hover{border-color:var(--ink-3);color:var(--ink);}
3738
- .gv-saved-tab.active{background:var(--ink);color:#fff;border-color:var(--ink);}
4757
+ .gv-saved-tab.active{background:var(--ink);color:var(--on-ink);border-color:var(--ink);}
3739
4758
  .gv-saved-tab:focus-visible{outline:2px solid var(--ink);outline-offset:2px;}
3740
4759
  .gv-saved-tab-badge{padding:1px 7px;border-radius:999px;background:var(--field);color:var(--ink-3);font:600 10.5px var(--mono);}
3741
4760
  .gv-saved-tab.active .gv-saved-tab-badge{background:var(--blue-bg);color:var(--blue-ink);}
@@ -3752,7 +4771,7 @@ input.gv-name:focus-visible{outline:none;}
3752
4771
  /* The thumbnail is a fixed TILE at the head of the row: the SVG carries its own
3753
4772
  width/height, so a percentage box would leave it stranded in dead space. */
3754
4773
  .gv-saved .pl-thumb{flex:0 0 auto;width:140px;height:54px;display:grid;place-items:center;overflow:hidden;
3755
- border:1px solid var(--line-2);border-radius:10px;background:#FBFBF9;}
4774
+ border:1px solid var(--line-2);border-radius:10px;background:var(--canvas-2);}
3756
4775
  .gv-saved .pl-thumb svg{display:block;}
3757
4776
  .gv-saved .pl-thumb.is-empty{border-style:dashed;color:var(--ink-3);font:10px/1 var(--mono);
3758
4777
  letter-spacing:.08em;text-transform:uppercase;}
@@ -3765,6 +4784,7 @@ input.gv-name:focus-visible{outline:none;}
3765
4784
  .gv-saved .pl-legacy,.gv-saved .pl-origin{flex:0 0 auto;background:var(--field);border:1px solid var(--line);color:var(--ink-3);
3766
4785
  border-radius:999px;padding:3px 10px;font-size:11px;font-weight:600;}
3767
4786
  .gv-saved .pl-origin{font-family:var(--mono);letter-spacing:-.01em;}
4787
+ .gv-saved .pl-origin.pl-auto{background:var(--violet-bg);border-color:var(--violet-bg);color:var(--violet-ink);font-family:var(--sans);letter-spacing:.04em;}
3768
4788
  /* Delete: the bin icon in the pipeline Archive button's dress (.hd-archive — red
3769
4789
  ink on a red-bg hairline pill, fills on hover), icon-only at row-action size. */
3770
4790
  .gv-saved .pl-del{flex:0 0 auto;width:34px;height:34px;border-radius:999px;border:1.5px solid var(--red-bg);
@@ -3782,14 +4802,14 @@ input.gv-name:focus-visible{outline:none;}
3782
4802
 
3783
4803
  /* ---------- save dialog ---------- */
3784
4804
  .save-dialog{border:none;border-radius:18px;padding:0;box-shadow:var(--shadow);max-width:420px;width:92vw;}
3785
- .save-dialog::backdrop{background:rgba(25,25,27,.34);}
4805
+ .save-dialog::backdrop{background:var(--scrim-soft);}
3786
4806
  .save-dialog .sd-body{padding:20px 22px 18px;display:flex;flex-direction:column;gap:14px;}
3787
4807
  .save-dialog .sd-title{margin:0;font-size:16px;font-weight:700;letter-spacing:-.015em;}
3788
4808
  .save-dialog .sd-field{display:flex;flex-direction:column;gap:6px;}
3789
4809
  .save-dialog .sd-field label{font-weight:600;font-size:12.5px;color:var(--ink-2);}
3790
4810
  .save-dialog .sd-field input{width:100%;border:1.5px solid transparent;background:var(--field);
3791
4811
  border-radius:11px;padding:10px 12px;font:13px var(--sans);color:var(--ink);}
3792
- .save-dialog .sd-field input:focus{outline:none;background:#fff;border-color:var(--ink);}
4812
+ .save-dialog .sd-field input:focus{outline:none;background:var(--field-focus);border-color:var(--ink);}
3793
4813
  .save-dialog .sd-note{margin:0;font-size:12px;line-height:1.5;color:var(--ink-2);
3794
4814
  background:var(--field);border-radius:11px;padding:9px 12px;}
3795
4815
  .save-dialog .sd-msg{margin:0;font-size:12px;line-height:1.5;color:var(--ink-3);white-space:pre-line;}
@@ -3820,6 +4840,11 @@ input.gv-name:focus-visible{outline:none;}
3820
4840
  fills, so the stage rect === the wrap's padding box. A static host may be
3821
4841
  widened inline (native horizontal scroll, D5); monitor wraps never scroll. */
3822
4842
  .run-flow.gv-host{position:absolute;top:0;left:0;bottom:0;width:auto;min-width:100%;padding:0;margin:0;display:block;gap:0;}
4843
+ /* The Auto deciding placeholder (spec §7.3). The host never gets gv-host/gv-wrap-static
4844
+ (mountRunGraph adds those), so it supplies its own box; (0,2,0) beats the base .run-flow. */
4845
+ .run-flow.auto-deciding-host{display:flex;align-items:center;justify-content:center;min-height:120px;padding:24px;width:auto;}
4846
+ .auto-deciding{gap:12px;}
4847
+ .auto-deciding .auto-deciding-label{font-size:13px;}
3823
4848
  .run-flow-wrap.gv-wrap{user-select:none;-webkit-user-select:none;}
3824
4849
  .run-flow-wrap.gv-wrap-monitor{overflow:hidden;height:var(--run-host-h,360px);}
3825
4850
  .rc-detailed .run-flow-wrap.gv-wrap-static{height:300px;overflow-x:auto;overflow-y:hidden;} /* additive (Running D17) */
@@ -3832,7 +4857,7 @@ input.gv-name:focus-visible{outline:none;}
3832
4857
  .run-flow.gv-host .gv-world .node.is-error{border-color:color-mix(in srgb, var(--red) 50%, var(--line-2));box-shadow:0 0 0 3px color-mix(in srgb, var(--red) 13%, transparent),var(--shadow-soft);}
3833
4858
  .run-flow.gv-host .gv-world .node.is-skipped{opacity:.35;border-style:dashed;}
3834
4859
  /* settled pips (v1's .nstat, as pseudo-elements: the view creates no pip DOM) */
3835
- .run-flow.gv-host .gv-world .node.is-done::after,.run-flow.gv-host .gv-world .node.is-paused::after,.run-flow.gv-host .gv-world .node.is-stopped::after,.run-flow.gv-host .gv-world .node.is-error::after{content:"";position:absolute;top:-8px;right:-8px;width:21px;height:21px;border-radius:50%;box-shadow:var(--shadow-soft);z-index:3;color:#fff;font:800 12px/21px var(--sans);text-align:center;}
4860
+ .run-flow.gv-host .gv-world .node.is-done::after,.run-flow.gv-host .gv-world .node.is-paused::after,.run-flow.gv-host .gv-world .node.is-stopped::after,.run-flow.gv-host .gv-world .node.is-error::after{content:"";position:absolute;top:-8px;right:-8px;width:21px;height:21px;border-radius:50%;box-shadow:var(--shadow-soft);z-index:3;color:var(--on-status);font:800 12px/21px var(--sans);text-align:center;}
3836
4861
  .run-flow.gv-host .gv-world .node.is-done::after{content:"✓";background:var(--green);}
3837
4862
  .run-flow.gv-host .gv-world .node.is-paused::after{content:"❚❚";font-size:8px;background:var(--amber);}
3838
4863
  .run-flow.gv-host .gv-world .node.is-stopped::after,.run-flow.gv-host .gv-world .node.is-error::after{content:"×";background:var(--red);}
@@ -3872,10 +4897,26 @@ input.gv-name:focus-visible{outline:none;}
3872
4897
  /* quiescence banner (.rd-banners / .hd-banners / History Overview note) */
3873
4898
  .run-warn{margin:0;padding:11px 15px;border-radius:12px;background:var(--amber-bg);color:var(--amber-ink);font-size:12.5px;font-weight:600;border:1px solid color-mix(in srgb, var(--amber) 45%, transparent);align-self:stretch;}
3874
4899
  .run-warn[hidden]{display:none;}
3875
- /* engaged-wheel hint chip (D8) */
3876
- .rg-hint{position:absolute;right:12px;bottom:10px;padding:4px 9px;border-radius:999px;background:color-mix(in srgb, var(--ink) 72%, transparent);color:#fff;font-size:10.5px;font-weight:600;pointer-events:none;opacity:0;transition:opacity .15s;z-index:5;}
4900
+ /* gesture hint chip (D10) */
4901
+ .rg-hint{position:absolute;left:12px;bottom:10px;padding:4px 9px;border-radius:999px;background:color-mix(in srgb, var(--ink) 72%, transparent);color:var(--on-ink);font-size:10.5px;font-weight:600;pointer-events:none;opacity:0;transition:opacity .15s;z-index:5;}
3877
4902
  .run-flow-wrap.gv-wrap-monitor:hover > .rg-hint{opacity:1;}
3878
- .run-flow-wrap.rg-engaged > .rg-hint{opacity:0;}
4903
+ /* The whole monitor canvas is a pan surface (drag from a card, a wire or the
4904
+ void), so the stage AND the card body advertise `grab`. Everything is scoped
4905
+ to .gv-wrap-monitor (D19): `gv-host` is on the Running LIST CARD's host too,
4906
+ and that preview has no gestures at all. `cursor` is inherited only by
4907
+ children that declare none, and the cards do — :4346 default, :4360/:4368
4908
+ pointer, :4391 History's pointer — so a live pan says `grabbing` through the
4909
+ house blanket idiom (`X, X *{… !important}`) rather than a specificity arms
4910
+ race. Measured in Chrome 152: without the blanket the cursor under a dragged
4911
+ card reads `default` while the stage reads `grabbing`. The clickable rows,
4912
+ gate and link keep `pointer` at rest — they are later at equal specificity. */
4913
+ .gv-wrap-monitor .run-flow.gv-host .gv-world .node{cursor:grab;}
4914
+ .gv-wrap-monitor .run-flow.gv-host .gv-stage{cursor:grab;}
4915
+ .gv-wrap-monitor .run-flow.gv-host .gv-stage.panning,.gv-wrap-monitor .run-flow.gv-host .gv-stage.panning *{cursor:grabbing !important;}
4916
+ /* The composer's own `.gv-nav` is rail-aware (right:352px). A run wrap has no
4917
+ inspector rail, so the cluster hugs the corner; the hint chip sits bottom-LEFT
4918
+ so the two never overlap. Later in the file AND more specific — either wins. */
4919
+ .run-flow-wrap.gv-wrap-monitor > .gv-nav{right:12px;bottom:12px;}
3879
4920
  @media (prefers-reduced-motion:reduce){
3880
4921
  .run-flow.gv-host .gv-wires path.wire-live,.run-flow.gv-host .gv-world .ngate,
3881
4922
  .run-flow.gv-host .gv-world .xfoot .xq.is-active,.run-flow.gv-host .gv-world .xfoot .xrow.is-active .led{animation:none;}
@@ -3893,3 +4934,109 @@ input.gv-name:focus-visible{outline:none;}
3893
4934
  .run-strip .rchip.is-active{color:var(--c);}
3894
4935
  .run-strip .rchip.is-paused{color:var(--amber-ink);}
3895
4936
  .run-strip .rchip.is-error,.run-strip .rchip.is-stopped{color:var(--red-ink);}
4937
+
4938
+ /* ---------- per-step artifacts (Phase 3 UI) ---------- */
4939
+ /* Run-level grouped browser (Running + History "Artifacts" tab): one card per
4940
+ node, a step header, and clickable artifact rows. Mirrors the .rd-ag-group card
4941
+ shell so the two detail tabs read as one system. */
4942
+ .artifact-group{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-card);overflow:hidden;}
4943
+ .artifact-group + .artifact-group{margin-top:14px;}
4944
+ .artifact-group-head{display:flex;align-items:center;flex-wrap:wrap;gap:12px;padding:15px 20px;border-bottom:1px solid var(--line);}
4945
+ .artifact-group-head b{font-size:13.5px;font-weight:600;letter-spacing:-.01em;}
4946
+ .artifact-cycle{padding:8px 20px 0;font-size:10.5px;letter-spacing:.02em;text-transform:uppercase;color:var(--ink-3);}
4947
+ .artifact-empty{padding:18px 20px;color:var(--ink-2);}
4948
+
4949
+ /* Per-node affordance inside an Agents-tab group card. */
4950
+ .node-artifacts{flex:0 0 100%;margin-top:8px;padding-top:8px;border-top:1px solid var(--line);}
4951
+ .artifact-toggle{appearance:none;border:1px solid var(--line-2);background:var(--field);color:var(--ink);
4952
+ font:600 11.5px var(--sans);padding:4px 12px;border-radius:999px;cursor:pointer;}
4953
+ .artifact-toggle:hover{border-color:var(--blue);color:var(--blue-ink);}
4954
+ .artifact-toggle[aria-expanded="true"]{background:var(--blue-bg);color:var(--blue-ink);border-color:var(--blue);}
4955
+ .artifact-list{display:flex;flex-direction:column;gap:6px;margin-top:8px;}
4956
+ /* An author `display:flex` outranks the UA's `[hidden]{display:none}`, so the
4957
+ collapsed state (`body.hidden = true` in buildNodeArtifactAffordance) must be
4958
+ restated here or the toggle can never close the list. */
4959
+ .artifact-list[hidden]{display:none;}
4960
+
4961
+ /* A single clickable artifact row (kind chip · name · byte size). */
4962
+ .artifact-group .artifact-row{border-top:1px solid var(--line);}
4963
+ .artifact-group-head + .artifact-row,.artifact-cycle + .artifact-row{border-top:none;}
4964
+ .artifact-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;
4965
+ appearance:none;border:none;background:transparent;cursor:pointer;
4966
+ padding:11px 20px;font:500 12.5px var(--sans);color:var(--ink);}
4967
+ .artifact-list .artifact-row{padding:8px 12px;border:1px solid var(--line-2);border-radius:10px;background:var(--field);}
4968
+ .artifact-row:hover{background:var(--field);}
4969
+ .artifact-list .artifact-row:hover{border-color:var(--blue);}
4970
+ .artifact-kind{flex:0 0 auto;font-size:10px;font-weight:700;letter-spacing:.02em;text-transform:uppercase;
4971
+ padding:2px 8px;border-radius:6px;background:var(--violet-bg);color:var(--violet-ink);}
4972
+ .artifact-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
4973
+ .artifact-bytes{margin-left:auto;flex:0 0 auto;font-size:11px;color:var(--ink-3);}
4974
+
4975
+ /* Typed viewers rendered into the shared #viewer modal by renderArtifact. The
4976
+ host resets the enclosing <pre>'s white-space:pre so each viewer owns its own. */
4977
+ .artifact-view{white-space:normal;}
4978
+ .artifact-text,.artifact-json,.artifact-diff{margin:0;font-family:var(--mono);font-size:12px;line-height:1.55;
4979
+ white-space:pre-wrap;word-break:break-word;color:var(--ink);}
4980
+ .artifact-diff{white-space:pre;overflow-x:auto;}
4981
+ .artifact-diff-line{display:block;}
4982
+ .artifact-diff-line.add{background:var(--green-bg);color:var(--green-ink);}
4983
+ .artifact-diff-line.del{background:var(--red-bg);color:var(--red-ink);}
4984
+ .artifact-diff-line.hunk{color:var(--blue-ink);background:var(--field);}
4985
+ .artifact-diff-line.meta{color:var(--ink-3);}
4986
+ .artifact-markdown{font-family:var(--sans);font-size:13.5px;line-height:1.6;color:var(--ink);}
4987
+ .artifact-markdown h1,.artifact-markdown h2,.artifact-markdown h3{line-height:1.3;margin:1em 0 .5em;}
4988
+ .artifact-markdown pre{background:var(--field);border:1px solid var(--line);border-radius:10px;
4989
+ padding:12px;overflow-x:auto;font-family:var(--mono);font-size:12px;}
4990
+ .artifact-markdown code{font-family:var(--mono);font-size:.92em;}
4991
+ .artifact-markdown :not(pre) > code{background:var(--field);border-radius:5px;padding:1px 5px;}
4992
+ .artifact-markdown a{color:var(--blue-ink);}
4993
+ .artifact-markdown table{border-collapse:collapse;}
4994
+ .artifact-markdown th,.artifact-markdown td{border:1px solid var(--line-2);padding:5px 9px;}
4995
+
4996
+ /* ---- Report this run modal ---- */
4997
+ /* Wider than a confirm (it carries a JSON preview), narrower than the viewer. */
4998
+ .report-modal .card{width:min(680px,100%);}
4999
+ /* Every action lives in a sticky header instead of at the foot of a scrolling card.
5000
+ The card is the scroll container (.viewer-modal .card{overflow:auto}), so `top:0`
5001
+ sticks to its padding edge; the negative margins pull the block out over the card's
5002
+ 24px padding so its opaque background covers the full width AND the strip above it,
5003
+ which the JSON preview would otherwise scroll through. The radius keeps it from
5004
+ painting square corners over the card's rounded ones. */
5005
+ /* top:-24px, not 0. A sticky element clamps at the SCROLLPORT's top inset, which for
5006
+ this card is its padding edge — 24px below the border. At top:0 the block pins there
5007
+ and the 24px strip above it stays transparent, so the form scrolls through it in
5008
+ plain sight (measured over CDP: the opt-in labels showed above the title). Pulling
5009
+ the inset up by exactly the card's padding pins the block flush to the border edge
5010
+ instead, where its own background covers the strip. */
5011
+ .report-modal .report-top{position:sticky;top:-24px;z-index:2;background:var(--panel);
5012
+ margin:-24px -24px 16px;padding:24px 24px 14px;border-bottom:1px solid var(--line);
5013
+ border-radius:var(--r-card) var(--r-card) 0 0;}
5014
+ /* The error/filed slots carry their own top margin, and the header's padding closes
5015
+ the block — a margin here would only add a gap when both are hidden, which is most
5016
+ of the time. */
5017
+ .report-modal .report-top .card-head{margin-bottom:0;}
5018
+ .report-head-actions{display:flex;align-items:center;gap:9px;}
5019
+ /* Wrap rather than overflow the 680px card on a narrow window. */
5020
+ .report-modal .confirm-actions{flex-wrap:wrap;}
5021
+ .report-field{margin-bottom:14px;}
5022
+ .report-field > label{display:block;font-weight:600;font-size:12.5px;margin-bottom:6px;}
5023
+ .report-field textarea.textarea{resize:vertical;min-height:64px;font-size:13.5px;}
5024
+ .report-modal #report-preview{max-height:300px;margin:0;font-size:12px;}
5025
+ .report-optins .confirm-checkbox + .confirm-checkbox{margin-top:8px;}
5026
+ .report-optin-hint{display:block;margin-top:3px;color:var(--ink-2);font-size:11.5px;line-height:1.4;}
5027
+ .report-error{margin:10px 0 0;color:var(--red-ink);font-size:12.5px;}
5028
+ .report-error[hidden]{display:none;}
5029
+ .report-filed{margin:10px 0 0;font-size:12.5px;}
5030
+ .report-filed[hidden]{display:none;}
5031
+ /* The issue link is an <a> so it opens in a real new tab; keep it button-shaped.
5032
+ SCOPED to .report-modal: an unscoped `.confirm-actions a.btn` would reach into every
5033
+ confirm/export/stop dialog in the app, and the :not([href]) rule below would silently
5034
+ grey out any future anchor another modal adds before it has an href. */
5035
+ .report-modal .confirm-actions a.btn{display:inline-flex;align-items:center;text-decoration:none;}
5036
+ /* …but an author `display` beats the UA's `[hidden]{display:none}` at any specificity,
5037
+ so the rule above would render the fallback link while app.js believes it is hidden.
5038
+ (`el.hidden` is true, the element is on screen — jsdom cannot see this, CDP can.) */
5039
+ .report-modal .confirm-actions a.btn[hidden]{display:none;}
5040
+ /* No href => the preview is still building. Make that legible rather than letting a
5041
+ dead-looking button sit there (D24). */
5042
+ .report-modal .confirm-actions a.btn:not([href]){opacity:.5;pointer-events:none;}