@giamme/forge 0.0.0-stage → 0.9.0

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 (152) hide show
  1. package/CHANGELOG.md +205 -0
  2. package/LICENSE +21 -0
  3. package/README.md +194 -2
  4. package/SKILL.md +123 -0
  5. package/VERSION +1 -0
  6. package/docs/README.md +26 -0
  7. package/docs/add-ons.md +33 -0
  8. package/docs/artifacts.md +69 -0
  9. package/docs/commands.md +315 -0
  10. package/docs/dataset.md +20 -0
  11. package/docs/decomposed-runs.md +268 -0
  12. package/docs/development.md +95 -0
  13. package/docs/forge-ui.md +92 -0
  14. package/docs/fractal.md +181 -0
  15. package/docs/install.md +160 -0
  16. package/docs/memory.md +156 -0
  17. package/docs/models.md +118 -0
  18. package/docs/reviews.md +231 -0
  19. package/docs/safety.md +55 -0
  20. package/docs/troubleshooting.md +54 -0
  21. package/forge +79 -0
  22. package/package.json +27 -4
  23. package/references/dataset.md +329 -0
  24. package/references/decompose.md +667 -0
  25. package/references/fractal-dashboard.md +21 -0
  26. package/references/fractal.md +307 -0
  27. package/references/harnesses.md +365 -0
  28. package/references/jev.md +865 -0
  29. package/references/memory.md +228 -0
  30. package/references/planning.md +42 -0
  31. package/references/ripwire.md +47 -0
  32. package/references/runtime.md +64 -0
  33. package/references/solo.md +113 -0
  34. package/references/ui.md +112 -0
  35. package/registry.tsv +81 -0
  36. package/scripts/forge-artifact.sh +78 -0
  37. package/scripts/forge-contract.py +430 -0
  38. package/scripts/forge-dataset.py +6 -0
  39. package/scripts/forge-dispatch.sh +671 -0
  40. package/scripts/forge-fail-first.py +195 -0
  41. package/scripts/forge-fractal-dispatch.sh +4 -0
  42. package/scripts/forge-fractal-options.sh +54 -0
  43. package/scripts/forge-fractal.py +6 -0
  44. package/scripts/forge-guard.py +266 -0
  45. package/scripts/forge-install-fractal.sh +4 -0
  46. package/scripts/forge-install-ripwire.sh +52 -0
  47. package/scripts/forge-install.sh +135 -0
  48. package/scripts/forge-jev-options.sh +259 -0
  49. package/scripts/forge-jev.py +6 -0
  50. package/scripts/forge-lib-plans.sh +785 -0
  51. package/scripts/forge-lib-review.sh +494 -0
  52. package/scripts/forge-lib-task.sh +302 -0
  53. package/scripts/forge-lib-verify.sh +30 -0
  54. package/scripts/forge-memory.sh +575 -0
  55. package/scripts/forge-metrics.sh +39 -0
  56. package/scripts/forge-parallel-options.sh +76 -0
  57. package/scripts/forge-parallel.sh +1717 -0
  58. package/scripts/forge-plan-check.py +118 -0
  59. package/scripts/forge-prompt.py +45 -0
  60. package/scripts/forge-ripwire.py +136 -0
  61. package/scripts/forge-route.py +344 -0
  62. package/scripts/forge-runs.py +121 -0
  63. package/scripts/forge-runtime.py +586 -0
  64. package/scripts/forge-schedule.py +312 -0
  65. package/scripts/forge-shadow.py +305 -0
  66. package/scripts/forge-solo.sh +347 -0
  67. package/scripts/forge-ui-options.sh +42 -0
  68. package/scripts/forge-ui.py +435 -0
  69. package/scripts/forge-update.sh +71 -0
  70. package/scripts/forge-verify-coverage.py +956 -0
  71. package/scripts/forge-version.py +240 -0
  72. package/scripts/forge_dataset/__init__.py +439 -0
  73. package/scripts/forge_dataset/capture.py +330 -0
  74. package/scripts/forge_dataset/checks.py +109 -0
  75. package/scripts/forge_dataset/cli.py +233 -0
  76. package/scripts/forge_dataset/export.py +1009 -0
  77. package/scripts/forge_dataset/harvest.py +716 -0
  78. package/scripts/forge_dataset/importer.py +412 -0
  79. package/scripts/forge_dataset/outcomes.py +275 -0
  80. package/scripts/forge_dataset/routing.py +278 -0
  81. package/scripts/forge_fractal/__init__.py +84 -0
  82. package/scripts/forge_fractal/bridge.py +46 -0
  83. package/scripts/forge_fractal/cli.py +202 -0
  84. package/scripts/forge_fractal/dashboard.css +138 -0
  85. package/scripts/forge_fractal/dashboard.html +41 -0
  86. package/scripts/forge_fractal/dashboard.js +687 -0
  87. package/scripts/forge_fractal/decomposition.py +262 -0
  88. package/scripts/forge_fractal/execution.py +659 -0
  89. package/scripts/forge_fractal/inspection.py +261 -0
  90. package/scripts/forge_fractal/install.py +158 -0
  91. package/scripts/forge_fractal/invocation.py +94 -0
  92. package/scripts/forge_fractal/pipeline.py +124 -0
  93. package/scripts/forge_fractal/selection.py +179 -0
  94. package/scripts/forge_jev/__init__.py +376 -0
  95. package/scripts/forge_jev/backtest.py +322 -0
  96. package/scripts/forge_jev/cli.py +980 -0
  97. package/scripts/forge_jev/client.py +418 -0
  98. package/scripts/forge_jev/corpus.py +156 -0
  99. package/scripts/forge_jev/coupling.py +244 -0
  100. package/scripts/forge_jev/features.py +24 -0
  101. package/scripts/forge_jev/gates.py +100 -0
  102. package/scripts/forge_jev/memory.py +163 -0
  103. package/scripts/forge_jev/outcome.py +49 -0
  104. package/scripts/forge_jev/predict.py +204 -0
  105. package/scripts/forge_jev/questions.py +661 -0
  106. package/scripts/forge_jev/review.py +73 -0
  107. package/scripts/forge_jev/routing.py +271 -0
  108. package/scripts/forge_jev/subset.py +123 -0
  109. package/scripts/forge_jev/verify.py +453 -0
  110. package/scripts/forge_registry.py +140 -0
  111. package/ui/README.md +347 -0
  112. package/ui/THIRD_PARTY_NOTICES.md +177 -0
  113. package/ui/docs/api.md +970 -0
  114. package/ui/forge_ui/__init__.py +20 -0
  115. package/ui/forge_ui/__main__.py +135 -0
  116. package/ui/forge_ui/diffs.py +454 -0
  117. package/ui/forge_ui/executions.py +436 -0
  118. package/ui/forge_ui/export.py +214 -0
  119. package/ui/forge_ui/findings.py +132 -0
  120. package/ui/forge_ui/fractal.py +582 -0
  121. package/ui/forge_ui/models.py +216 -0
  122. package/ui/forge_ui/reader.py +1424 -0
  123. package/ui/forge_ui/server.py +312 -0
  124. package/ui/forge_ui/static/D-DINCondensed-Bold.woff2 +0 -0
  125. package/ui/forge_ui/static/app.js +1079 -0
  126. package/ui/forge_ui/static/cloud3d.js +647 -0
  127. package/ui/forge_ui/static/cloudmodel.js +375 -0
  128. package/ui/forge_ui/static/cloudui.js +397 -0
  129. package/ui/forge_ui/static/convo.js +295 -0
  130. package/ui/forge_ui/static/datatable.js +232 -0
  131. package/ui/forge_ui/static/diffview.js +235 -0
  132. package/ui/forge_ui/static/favicon.svg +1 -0
  133. package/ui/forge_ui/static/files.js +776 -0
  134. package/ui/forge_ui/static/findings3d.js +134 -0
  135. package/ui/forge_ui/static/gantt.js +97 -0
  136. package/ui/forge_ui/static/graph.js +266 -0
  137. package/ui/forge_ui/static/icons.js +94 -0
  138. package/ui/forge_ui/static/index.html +67 -0
  139. package/ui/forge_ui/static/iso.js +816 -0
  140. package/ui/forge_ui/static/leaderboard.js +311 -0
  141. package/ui/forge_ui/static/map3d.js +45 -0
  142. package/ui/forge_ui/static/modelstats.js +249 -0
  143. package/ui/forge_ui/static/notify.js +179 -0
  144. package/ui/forge_ui/static/panel.js +562 -0
  145. package/ui/forge_ui/static/runmodel.js +667 -0
  146. package/ui/forge_ui/static/scene3d.js +1471 -0
  147. package/ui/forge_ui/static/search.js +120 -0
  148. package/ui/forge_ui/static/shell.js +137 -0
  149. package/ui/forge_ui/static/stagectl.js +150 -0
  150. package/ui/forge_ui/static/style.css +1073 -0
  151. package/ui/forge_ui/static/theme.js +25 -0
  152. package/ui/forge_ui/transcripts.py +608 -0
@@ -0,0 +1,1073 @@
1
+ /* forge-ui: a signal box route-setting desk for forge runs.
2
+ The run is an inlaid track diagram on an enamelled panel; lamps have fixed meanings (white route set, amber occupied,
3
+ green clear, red failed, unlit pending); every heading is an engraved plate; every toggle is a push button with a lamp;
4
+ numbers sit in describer windows. Three plies only: the panel, a module on it, a popover over both.
5
+ Colours are light-dark() pairs: <html data-theme> (theme.js) or the system setting picks the side. The 3D stage reads
6
+ --stage-*, --st and --sev resolved through a probe (iso.js), so every colour it uses lives here. */
7
+
8
+ @font-face {
9
+ font-family: "D-DIN Condensed";
10
+ src: url(D-DINCondensed-Bold.woff2) format("woff2");
11
+ font-weight: 700;
12
+ font-style: normal;
13
+ font-display: swap;
14
+ }
15
+
16
+ /* ---------- tokens ---------- */
17
+ :root {
18
+ color-scheme: light dark;
19
+ /* enamel, modules and glass */
20
+ --desk: light-dark(#c9d0c7, #0d110f);
21
+ --stage-bg: light-dark(#c6cec4, #0e1210);
22
+ --module: light-dark(#f1f3ee, #171d1a);
23
+ --module-2: light-dark(#e4e8e1, #1e2521);
24
+ --key: light-dark(#f8f9f5, #222a26);
25
+ --key-hover: light-dark(#ffffff, #29322d);
26
+ --field: light-dark(#fbfcf9, #101513);
27
+ --glass: light-dark(#121715, #070a08);
28
+ --glass-ink: #ece8d9;
29
+ --glass-dim: #8f9a92;
30
+ --wash: light-dark(#ffffff, #26302b);
31
+ /* ink and engraving */
32
+ --ink: light-dark(#111613, #e4e8e2);
33
+ --ink-2: light-dark(#38413b, #bac3bd);
34
+ --muted: light-dark(#4b554e, #8f9b94);
35
+ --rule: light-dark(#c1c8bf, #29322d);
36
+ --rule-2: light-dark(#97a098, #3e4943);
37
+ --plate: light-dark(#151a17, #e2ddcd);
38
+ --plate-ink: light-dark(#eef1ea, #141916);
39
+ /* lamps: one meaning each */
40
+ --route: light-dark(#18201b, #f4efdf);
41
+ --lamp-off: light-dark(#a3aca4, #3f4943);
42
+ --lamp-green: light-dark(#1d7a39, #5bd57d);
43
+ --lamp-amber: light-dark(#9c6c00, #f4c443);
44
+ --lamp-red: light-dark(#bf3127, #ff5f53);
45
+ --lamp-edge: light-dark(rgb(0 0 0 / .18), rgb(0 0 0 / .4));
46
+ /* the same lamps lit on the 3D plate: on a pale panel a lit lamp is saturated, not darkened for text */
47
+ --lit-green: light-dark(#2fae55, #5bd57d);
48
+ --lit-amber: light-dark(#d8b000, #f4c443); /* blending toward the pale panel pulls amber to orange: it starts yellower */
49
+ --lit-red: light-dark(#e0392e, #ff5f53);
50
+ /* the time an attempt spent in each phase: a grey ramp, with the model's own time lit */
51
+ --ph-1: light-dark(#b9c1b8, #36403a);
52
+ --ph-2: light-dark(#8e988f, #59645d);
53
+ --ph-3: light-dark(#5f6a63, #86918a);
54
+ --ph-4: light-dark(#323b35, #b7c0ba);
55
+ --warn-ink: light-dark(#7a4f00, #f4c443);
56
+ --warn-wash: light-dark(#f6e7bf, #2b2412);
57
+ /* review severity: a ramp of its own, never a status colour */
58
+ --sev-p0: light-dark(#a1145d, #ff52a8);
59
+ --sev-p1: light-dark(#783ebd, #c18dff);
60
+ --sev-p2: light-dark(#335dbd, #88a9ff);
61
+ --sev-p3: light-dark(#56635b, #a7b2ab);
62
+ /* the 3D stage: body, hairlines and the accent of what is live */
63
+ --stage-accent: var(--lamp-amber);
64
+ --stage-body: light-dark(#f3f5f0, #161c19);
65
+ --stage-line: light-dark(#454f48, #4f5b54);
66
+ --stage-major: light-dark(#6f7a72, #36413b);
67
+ --stage-edge: light-dark(#9aa49b, #242c28);
68
+ --stage-recess: light-dark(#dce1d9, #0b0e0c);
69
+ /* depth: three plies */
70
+ --shadow-c: light-dark(rgb(17 26 20 / .26), rgb(0 0 0 / .62));
71
+ --ply-1: 0 1px 0 light-dark(rgb(17 26 20 / .06), rgb(0 0 0 / .4)), 0 12px 30px -14px var(--shadow-c);
72
+ --ply-2: 0 2px 6px light-dark(rgb(17 26 20 / .1), rgb(0 0 0 / .45)), 0 24px 54px -18px var(--shadow-c);
73
+ /* shape, space, type, motion */
74
+ --r-module: 12px;
75
+ --r-key: 6px;
76
+ --r-small: 4px;
77
+ --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-8: 32px;
78
+ --gap: 12px;
79
+ --font-ui: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
80
+ --font-plate: "D-DIN Condensed", "Arial Narrow", "Roboto Condensed", system-ui, sans-serif;
81
+ --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
82
+ --t-xs: .786rem; --t-sm: .893rem; --t-base: 1rem; --t-md: 1.125rem; --t-lg: 1.266rem; --t-xl: 1.424rem;
83
+ --relay: 80ms linear;
84
+ --ease-out: cubic-bezier(.2, 0, 0, 1);
85
+ --dur-1: 150ms;
86
+ /* panel sizes (shell.js sets them from the user's drags) */
87
+ --runs-w: 300px; --insp-w: 380px; --tasks-h: 208px; --rail-w: 48px;
88
+ font: 14px/1.5 var(--font-ui);
89
+ }
90
+ :root[data-theme=light] { color-scheme: light; }
91
+ :root[data-theme=dark] { color-scheme: dark; }
92
+
93
+ /* status: the lamp behind each forge state. Five lamps, one meaning each (--st; --st-lit on the 3D plate);
94
+ a hollow lamp is that lamp's family but not its plain case: passed without a merge, stopped, failed outside the code */
95
+ .st-merged, .st-pass, .st-accepted, .st-nochanges { --st: var(--lamp-green); --st-lit: var(--lit-green); }
96
+ .st-running, .st-interrupted { --st: var(--lamp-amber); --st-lit: var(--lit-amber); }
97
+ .st-pending, .st-none, .st-unknown, .st-invalidated { --st: var(--lamp-off); --st-lit: var(--lamp-off); }
98
+ .st-fail, .st-error, .st-conflict, .st-infra, .st-timeout, .st-blocked { --st: var(--lamp-red); --st-lit: var(--lit-red); }
99
+ [class^="st-"], [class*=" st-"] { --st-fill: var(--st); --st-ring: var(--lamp-edge); }
100
+ .st-accepted, .st-nochanges, .st-interrupted, .st-infra, .st-timeout, .st-blocked { --st-fill: transparent; --st-ring: var(--st); }
101
+ /* review severity is a shape (P0 spike, P1 diamond, P2 cone, P3 pin) on a ramp of its own, never a status lamp */
102
+ .sev-P0 { --sev: var(--sev-p0); --sev-shape: polygon(50% 0, 100% 100%, 0 100%); }
103
+ .sev-P1 { --sev: var(--sev-p1); --sev-shape: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
104
+ .sev-P2 { --sev: var(--sev-p2); --sev-shape: polygon(0 8%, 100% 8%, 50% 100%); }
105
+ .sev-P3 { --sev: var(--sev-p3); --sev-shape: circle(45%); }
106
+ .sev-none { --sev: var(--muted); --sev-shape: circle(30%); }
107
+
108
+ /* ---------- base ---------- */
109
+ * { box-sizing: border-box; }
110
+ html { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; }
111
+ body { margin: 0; background: var(--desk); color: var(--ink); }
112
+ h1, h2, h3, p { margin: 0; }
113
+ h1, h2, h3 { text-wrap: balance; }
114
+ p, dd, li { text-wrap: pretty; }
115
+ h1 { font-size: var(--t-lg); font-weight: 650; }
116
+ h2 { font-size: var(--t-md); font-weight: 650; margin-bottom: var(--s-3); overflow-wrap: anywhere; }
117
+ a { color: inherit; text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 3px; transition: text-decoration-color var(--relay), color var(--relay); }
118
+ a:hover { text-decoration-color: currentColor; }
119
+ :focus-visible { outline: 2px solid var(--route); outline-offset: 2px; }
120
+ ::selection { background: var(--lamp-amber); color: #111613; }
121
+ input, textarea { caret-color: var(--lamp-amber); accent-color: var(--route); }
122
+ * { scrollbar-color: var(--rule-2) transparent; scrollbar-width: thin; }
123
+ .muted, .empty { color: var(--muted); }
124
+ .mono, pre, code { font-family: var(--mono); }
125
+ .mono { font-size: var(--t-sm); }
126
+ .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
127
+ .empty { padding: var(--s-4); overflow-wrap: anywhere; }
128
+ .empty p + p { margin-top: var(--s-3); }
129
+ /* the first screen with no runs at all (app.js renderFirstRun): what forge-ui shows and how to get a run */
130
+ .first-run { max-width: 640px; margin: var(--s-8) auto; padding: 0 var(--s-4); }
131
+ .first-run h1 { font-size: var(--t-xl); margin-bottom: var(--s-3); }
132
+ .first-run h2 { font-size: var(--t-base); margin: var(--s-6) 0 0; }
133
+ .first-run p { margin-top: var(--s-2); }
134
+ .warn { color: var(--warn-ink); font-weight: 600; }
135
+ .icon { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
136
+ pre { margin: var(--s-2) 0 0; padding: var(--s-3); background: var(--glass); color: var(--glass-ink); border-radius: var(--r-key); max-height: 320px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; tab-size: 4; line-height: 1.6; font-size: var(--t-sm); }
137
+ code { font-size: .9em; }
138
+ kbd { font-family: var(--mono); font-size: var(--t-xs); padding: 0 5px; border: 1px solid var(--rule-2); border-radius: var(--r-small); box-shadow: inset 0 -1px 0 var(--rule-2); color: var(--muted); background: var(--field); }
139
+
140
+ /* engraved plates: every heading of a region, set in condensed DIN capitals */
141
+ .plate, .insp-section h3, .map-repo h3, .fm-list h3, .diff-loose h3, .jump-group, .notify-kinds legend, .cloud-field legend, .stage-tip-meta, .module-title {
142
+ display: inline-block; font-family: var(--font-plate); font-weight: 700; font-size: .857rem; line-height: 1.25; letter-spacing: .07em; text-transform: uppercase;
143
+ padding: 2px 7px 1px; border-radius: 3px; background: var(--plate); color: var(--plate-ink); white-space: nowrap;
144
+ }
145
+
146
+ /* lamps: a round indicator; running sections blink */
147
+ .lamp, .led { display: inline-block; width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--st-fill, var(--lamp-off)); box-shadow: inset 0 0 0 1.5px var(--st-ring, var(--lamp-edge)); }
148
+ .led.st-running, .lamp.st-running, .lamp.blink { animation: lamp-blink 1s steps(1, end) infinite; }
149
+ @keyframes lamp-blink { 50% { opacity: .35; } }
150
+
151
+ /* status chips: a lamp and its legend */
152
+ .chip { display: inline-flex; align-items: center; gap: 5px; padding: 1px 7px 0 6px; border: 1px solid var(--rule); border-radius: var(--r-small); background: var(--key); color: var(--ink); white-space: nowrap;
153
+ font-family: var(--font-plate); font-weight: 700; font-size: .857rem; letter-spacing: .05em; text-transform: uppercase; line-height: 1.5; font-variant-numeric: tabular-nums; }
154
+ .chip::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--st-fill, var(--lamp-off)); box-shadow: inset 0 0 0 1.5px var(--st-ring, transparent); flex: none; }
155
+ .chips { display: flex; gap: var(--s-1); flex-wrap: wrap; }
156
+ .sev-chip { display: inline-flex; align-items: center; gap: 6px; font-family: var(--mono); font-size: var(--t-xs); white-space: nowrap; }
157
+ .sev-chip::before { content: ''; width: 9px; height: 9px; clip-path: var(--sev-shape, circle(30%)); background: var(--sev, var(--muted)); flex: none; }
158
+ .chip.sev-chip { font-family: var(--mono); font-weight: 600; letter-spacing: 0; text-transform: none; font-size: var(--t-xs); }
159
+ /* a model's name plate: the alias engraved, its effort beside it; the one way a model is shown */
160
+ .model-plate { display: inline-flex; align-items: stretch; vertical-align: middle; border: 1px solid var(--rule-2); border-radius: var(--r-small); overflow: hidden; white-space: nowrap; line-height: 1.55; }
161
+ .model-plate .mp-name { padding: 0 6px; background: var(--module-2); color: var(--ink); font-family: var(--font-plate); font-weight: 700; font-size: .857rem; letter-spacing: .06em; text-transform: uppercase; transition: background-color var(--relay); }
162
+ .model-plate .mp-effort { display: flex; align-items: center; padding: 0 6px; border-left: 1px solid var(--rule); color: var(--muted); font-family: var(--mono); font-size: var(--t-xs); }
163
+ .plates { display: inline-flex; flex-wrap: wrap; gap: 4px; }
164
+ .mid-path { display: flex; min-width: 0; white-space: nowrap; }
165
+ .mid-head { flex: 0 1 auto; min-width: 3ch; overflow: hidden; text-overflow: ellipsis; }
166
+ .mid-tail { flex: 0 0 auto; }
167
+ dd.mono:has(> .mid-path) { white-space: nowrap; overflow: hidden; }
168
+ .tag { align-self: flex-start; border: 1px solid var(--rule-2); border-radius: var(--r-small); padding: 0 5px; color: var(--muted); font-family: var(--font-plate); font-weight: 700; font-size: .786rem; letter-spacing: .06em; text-transform: uppercase; line-height: 1.5; }
169
+
170
+ /* ---------- controls: key caps, push buttons with lamps, fields ---------- */
171
+ button, select, input, textarea { font: inherit; color: var(--ink); }
172
+ button, a.button {
173
+ display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 32px; padding: 0 12px; position: relative;
174
+ border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--key); color: var(--ink); cursor: pointer; text-decoration: none;
175
+ font-family: var(--font-plate); font-weight: 700; font-size: .929rem; letter-spacing: .05em; text-transform: uppercase; line-height: 1; white-space: nowrap;
176
+ box-shadow: inset 0 -1px 0 light-dark(rgb(0 0 0 / .08), rgb(0 0 0 / .35));
177
+ transition: background-color var(--relay), border-color var(--relay), color var(--relay), scale var(--relay);
178
+ }
179
+ button:hover:not(:disabled), a.button:hover { background: var(--key-hover); border-color: var(--ink-2); }
180
+ button:active:not(:disabled), a.button:active { scale: .96; }
181
+ button:disabled { opacity: .45; cursor: default; }
182
+ button .icon, a.button .icon { width: 16px; height: 16px; stroke-width: 2; }
183
+ .primary, a.button.primary, button.primary { background: var(--route); border-color: var(--route); color: var(--desk); }
184
+ .primary:hover, a.button.primary:hover, button.primary:hover:not(:disabled) { background: var(--route); color: var(--desk); opacity: .9; }
185
+ .icon-btn { padding: 0; width: 32px; min-width: 32px; }
186
+ .icon-btn::after { content: ''; position: absolute; inset: -4px; }
187
+ .linkish { min-height: 0; padding: 0 2px; border: 0; background: none; box-shadow: none; color: var(--ink); font: inherit; letter-spacing: 0; text-transform: none; text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 3px; }
188
+ .linkish:hover:not(:disabled) { background: none; text-decoration-color: currentColor; }
189
+
190
+ /* a bank of push buttons: each one's lamp lights when it is pressed in */
191
+ .seg { display: inline-flex; align-items: stretch; gap: 0; border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--module-2); padding: 2px; }
192
+ .seg button { min-height: 28px; border: 0; border-radius: var(--r-small); background: none; box-shadow: none; padding: 0 10px 0 9px; color: var(--ink-2); }
193
+ .seg button::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--lamp-off); flex: none; transition: background-color var(--relay); }
194
+ .seg button:hover:not(:disabled) { background: var(--key); }
195
+ .seg button[aria-pressed=true] { background: var(--key); color: var(--ink); box-shadow: inset 0 0 0 1px var(--rule-2); }
196
+ .seg button::after, .module-tools button::after { content: ''; position: absolute; inset: -6px 0; } /* 40px tall hit areas */
197
+ .seg button[aria-pressed=true]::before { background: var(--route); }
198
+ .seg.icons button { padding: 0 7px; }
199
+ .seg.icons button::before { display: none; }
200
+
201
+ select, input[type=search], input[type=text], input[type=number], textarea {
202
+ min-height: 32px; padding: 0 10px; border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--field); color: var(--ink);
203
+ transition: border-color var(--relay);
204
+ }
205
+ select:hover, input[type=search]:hover, input[type=number]:hover { border-color: var(--ink-2); }
206
+ select { appearance: none; padding-right: 28px; cursor: pointer;
207
+ background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
208
+ background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
209
+ select:disabled { opacity: .45; cursor: default; }
210
+ /* disclosures: the drawn chevron, never the browser's triangle */
211
+ summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; }
212
+ summary::-webkit-details-marker { display: none; }
213
+ summary::before { content: ''; width: 6px; height: 6px; margin: 0 2px; border: solid currentColor; border-width: 0 1.5px 1.5px 0; rotate: -45deg; flex: none; transition: rotate var(--dur-1) var(--ease-out); }
214
+ details[open] > summary::before { rotate: 45deg; }
215
+ input::placeholder { color: var(--muted); }
216
+ input[type=checkbox] { width: 15px; height: 15px; margin: 0; accent-color: var(--route); }
217
+ input[type=range] { accent-color: var(--lamp-amber); }
218
+ label { cursor: pointer; }
219
+ .filters { display: flex; flex-wrap: wrap; align-items: end; gap: var(--s-2) var(--s-3); }
220
+ .filter { display: flex; flex-direction: column; gap: 3px; font-size: var(--t-xs); color: var(--muted); }
221
+ .filter > span:first-child { font-family: var(--font-plate); font-weight: 700; letter-spacing: .07em; text-transform: uppercase; font-size: .786rem; }
222
+ .filter.check { flex-direction: row; align-items: center; gap: 6px; color: var(--ink); font-size: var(--t-sm); min-height: 32px; }
223
+
224
+ /* describer windows: numbers on black glass */
225
+ .describer { display: inline-flex; align-items: baseline; gap: var(--s-3); padding: 3px 9px; border-radius: var(--r-key); background: var(--glass); color: var(--glass-ink); font-family: var(--mono); font-size: var(--t-xs); font-variant-numeric: tabular-nums; white-space: nowrap; }
226
+ .describer .dim { color: var(--glass-dim); }
227
+ .describer, pre { color-scheme: dark; }
228
+ .desc-count { display: inline-flex; align-items: center; gap: 5px; }
229
+ .desc-count .lamp { width: 7px; height: 7px; }
230
+
231
+ /* ---------- the desk header ---------- */
232
+ .topbar { display: flex; align-items: center; gap: var(--s-3); min-height: 52px; padding: 0 var(--s-3); background: var(--module); border-bottom: 1px solid var(--rule); position: relative; z-index: 6; flex: none; }
233
+ .brand { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; color: var(--ink); margin-right: var(--s-2); }
234
+ .brand-plate { font-family: var(--font-plate); font-weight: 700; font-size: 1.15rem; letter-spacing: .08em; text-transform: uppercase; padding: 3px 9px 1px; border-radius: 4px; background: var(--plate); color: var(--plate-ink); line-height: 1.2; }
235
+ .brand-sub { font-family: var(--font-plate); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-size: .857rem; }
236
+ .desk-nav { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--module-2); }
237
+ .top-link { display: inline-flex; align-items: center; gap: 7px; min-height: 28px; padding: 0 10px; border-radius: var(--r-small); text-decoration: none; color: var(--ink-2);
238
+ font-family: var(--font-plate); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; font-size: .929rem; transition: background-color var(--relay), color var(--relay); }
239
+ .top-link::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--lamp-off); }
240
+ .top-link:hover { background: var(--key); color: var(--ink); }
241
+ .top-link[aria-current=page] { background: var(--key); color: var(--ink); box-shadow: inset 0 0 0 1px var(--rule-2); }
242
+ .top-link[aria-current=page]::before { background: var(--route); }
243
+ .top-search { margin-left: auto; justify-content: space-between; gap: var(--s-3); min-width: 220px; color: var(--muted); font-family: var(--font-ui); font-weight: 400; text-transform: none; letter-spacing: 0; font-size: var(--t-sm); }
244
+ .top-search-label { display: inline-flex; align-items: center; gap: 8px; }
245
+ .desk-tools { display: inline-flex; align-items: center; gap: var(--s-2); }
246
+ .panel-bank button { padding: 0 9px 0 8px; }
247
+ .panel-bank .icon { display: none; width: 17px; height: 17px; }
248
+ @media (max-width: 1280px) { .panel-bank .panel-label { display: none; } .panel-bank .icon { display: block; } .panel-bank button { padding: 0 8px 0 7px; } .top-search { min-width: 0; } }
249
+ .bell { width: 32px; padding: 0; }
250
+ .bell .icon { width: 18px; height: 18px; }
251
+ .bell[aria-expanded=true] { border-color: var(--ink-2); }
252
+ .bell-count { position: absolute; top: -6px; right: -7px; min-width: 18px; padding: 0 4px; border-radius: 9px; background: var(--lamp-red); color: #fff; font-family: var(--mono); font-size: .714rem; font-weight: 700; line-height: 18px; letter-spacing: 0; font-variant-numeric: tabular-nums; }
253
+ .refresh-control { position: relative; display: inline-flex; align-items: center; gap: 7px; min-height: 32px; padding: 0 10px 0 9px; border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--key);
254
+ font-family: var(--font-plate); font-weight: 700; font-size: .929rem; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
255
+ .refresh-control input { position: absolute; opacity: 0; width: 1px; height: 1px; }
256
+ .refresh-control::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--lamp-off); }
257
+ .refresh-control:has(input:checked)::before { background: var(--lamp-green); }
258
+ .refresh-control:has(input:focus-visible) { outline: 2px solid var(--route); outline-offset: 2px; }
259
+ #errors { padding: var(--s-2) var(--s-4); background: var(--warn-wash); color: var(--warn-ink); border-bottom: 1px solid var(--rule); overflow-wrap: anywhere; position: relative; z-index: 5; flex: none; }
260
+ .snapshot-banner { padding: 7px var(--s-4); background: var(--module-2); border-bottom: 1px solid var(--rule); font-size: var(--t-sm); overflow-wrap: anywhere; flex: none; }
261
+ body.snapshot .desk-nav, body.snapshot #bell, body.snapshot .refresh-control { display: none; }
262
+
263
+ /* ---------- the shell: an app the height of the window; Immersive floats modules, Workbench docks them ---------- */
264
+ html, body { height: 100%; }
265
+ body { display: flex; flex-direction: column; overflow: hidden; }
266
+ .layout { position: relative; flex: 1; min-height: 0; }
267
+ main { min-width: 0; outline: none; }
268
+ .module { background: var(--module); border: 1px solid var(--rule); border-radius: var(--r-module); display: flex; flex-direction: column; min-height: 0; min-width: 0; }
269
+ .module-head { display: flex; align-items: center; gap: var(--s-2); min-height: 40px; padding: 4px 6px 4px 10px; border-bottom: 1px solid var(--rule); flex: none; }
270
+ .module-title { margin: 0; }
271
+ .module-count { font-family: var(--mono); font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
272
+ .module-tools { margin-left: auto; display: inline-flex; align-items: center; gap: var(--s-1); }
273
+ .module-tools button { min-height: 28px; }
274
+ .module-tools .icon-btn { width: 28px; min-width: 28px; }
275
+ .splitter { position: absolute; z-index: 5; touch-action: none; }
276
+ .splitter::after { content: ''; position: absolute; background: var(--route); opacity: 0; transition: opacity var(--relay); }
277
+ .splitter:hover::after, .splitter:focus-visible::after, .splitter.dragging::after { opacity: .7; }
278
+ .splitter:focus-visible { outline: none; }
279
+ .splitter.v { top: 0; bottom: 0; width: 10px; cursor: col-resize; }
280
+ .splitter.v::after { top: 0; bottom: 0; left: 4px; width: 2px; }
281
+ .splitter.h { left: 0; right: 0; height: 10px; cursor: row-resize; }
282
+ .splitter.h::after { left: 0; right: 0; top: 4px; height: 2px; }
283
+ body.resizing { cursor: col-resize; user-select: none; }
284
+ body.resizing.rows { cursor: row-resize; }
285
+
286
+ /* the runs module (the sidebar) */
287
+ .sidebar { overflow: hidden; }
288
+ .runs-tools { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-2); padding: var(--s-2) 10px; border-bottom: 1px solid var(--rule); }
289
+ .runs-tools input { width: 100%; }
290
+ #run-list { flex: 1; min-height: 0; overflow-y: auto; }
291
+ .run-item { display: grid; grid-template-columns: 12px minmax(0, 1fr); column-gap: 10px; row-gap: 2px; padding: 10px 12px; border-bottom: 1px solid var(--rule); text-decoration: none; color: var(--ink); min-width: 0; transition: background-color var(--relay); }
292
+ .run-item > :not(.run-lamp) { grid-column: 2; min-width: 0; }
293
+ .run-item .run-lamp { grid-column: 1; grid-row: 1; margin-top: 5px; }
294
+ .run-item:hover { background: var(--module-2); }
295
+ .run-item.selected { background: var(--wash); box-shadow: inset 0 0 0 1px var(--rule-2); }
296
+ .run-item.selected .run-lamp { box-shadow: 0 0 0 2px var(--module), 0 0 0 3px var(--route); }
297
+ .run-goal { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
298
+ .run-sub { display: flex; gap: var(--s-2); align-items: baseline; font-size: var(--t-xs); color: var(--muted); min-width: 0; white-space: nowrap; }
299
+ .run-sub .mono { font-size: var(--t-xs); overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
300
+ .run-sub .repo { color: var(--ink-2); font-weight: 600; flex: none; }
301
+ .run-sub .updated { margin-left: auto; flex: none; }
302
+ .run-item .chips { margin-top: 3px; }
303
+ .run-item .chip { font-size: .786rem; padding: 0 5px 0 4px; }
304
+ .updated, .verification { font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
305
+ .verification { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 2px; color: var(--muted); }
306
+ .run-item .tag { justify-self: start; }
307
+
308
+ /* a stage view fills the layout; content views scroll */
309
+ #main { position: absolute; inset: 0; overflow: auto; }
310
+ body[data-view=map] #main, body[data-view=run] #main, body[data-view=cloud] #main { overflow: hidden; }
311
+ .map-view, .run-view { position: absolute; inset: 0; margin: 0; }
312
+
313
+ /* Immersive: the runs, inspector and tasks modules float over the stage */
314
+ body[data-shell=immersive] { --L: calc(var(--runs-w) + 2 * var(--gap)); --R: calc(var(--insp-w) + 2 * var(--gap)); --B: calc(var(--tasks-h) + 2 * var(--gap)); }
315
+ body[data-shell=immersive][data-runs=closed] { --L: var(--gap); }
316
+ body[data-shell=immersive][data-insp=closed] { --R: var(--gap); }
317
+ body[data-shell=immersive][data-tasks=closed] { --B: calc(42px + 2 * var(--gap)); }
318
+ body[data-shell=immersive].no-tasks { --B: var(--gap); }
319
+ body.no-tasks .tasks-module { display: none; }
320
+ body[data-shell=workbench].no-tasks .run-view { grid-template-rows: auto minmax(0, 1fr) auto 0; }
321
+ body[data-shell=immersive] .sidebar { position: absolute; z-index: 4; left: var(--gap); top: var(--gap); bottom: var(--gap); width: var(--runs-w); box-shadow: var(--ply-1); }
322
+ body[data-shell=immersive][data-runs=closed] .sidebar { display: none; }
323
+ body[data-shell=immersive]:is([data-view=models], [data-view=waiting], [data-view=loading], [data-view=first-run]) #main { left: calc(var(--L) - var(--gap)); }
324
+ body[data-shell=immersive] .stage-row, body[data-shell=immersive] .stage-col { position: absolute; inset: 0; }
325
+ body[data-shell=immersive] .stage-col .stage-slot { position: absolute; inset: 0; }
326
+ body[data-shell=immersive] .insp-module { position: absolute; z-index: 3; right: var(--gap); top: var(--gap); bottom: var(--gap); width: var(--insp-w); box-shadow: var(--ply-1); }
327
+ body[data-shell=immersive][data-insp=closed] .insp-module { display: none; }
328
+ body[data-shell=immersive] .run-header { position: absolute; z-index: 3; left: var(--L); top: var(--gap); width: min(1040px, calc(100% - var(--L) - var(--R))); box-shadow: var(--ply-1); }
329
+ body[data-shell=immersive] .tasks-module { position: absolute; z-index: 3; left: var(--L); right: var(--R); bottom: var(--gap); height: var(--tasks-h); box-shadow: var(--ply-1); }
330
+ body[data-shell=immersive][data-tasks=closed] .tasks-module { height: auto; }
331
+ body[data-shell=immersive] .strip-wrap { position: absolute; z-index: 2; left: var(--L); right: var(--R); bottom: var(--B); }
332
+ body[data-shell=immersive] .stage-col .graph, body[data-shell=immersive] .stage-col .files-view { position: absolute; inset: 0; overflow: auto; padding: calc(var(--head-h, 132px) + 2 * var(--gap)) var(--R) calc(var(--B) + var(--gap)) var(--L); }
333
+ body[data-shell=immersive] .diff-view { position: absolute; z-index: 3; left: var(--L); right: var(--gap); top: var(--gap); bottom: var(--B); overflow: auto; padding: var(--s-4); box-shadow: var(--ply-1); }
334
+ body[data-shell=immersive] .run-view.diff-open .run-header { display: none; }
335
+ body[data-shell=immersive] .map-head-module { position: absolute; z-index: 3; left: var(--L); top: var(--gap); width: max-content; max-width: calc(100% - var(--L) - var(--gap)); box-shadow: var(--ply-1); }
336
+ body[data-shell=immersive] .map-view .stage-slot { position: absolute; inset: 0; }
337
+ body[data-shell=immersive] .map-cards { position: absolute; inset: 0; overflow: auto; padding: 170px var(--gap) var(--gap) var(--L); }
338
+ body[data-shell=immersive] .tasks-module .splitter.h { top: -5px; }
339
+ body[data-shell=immersive] .insp-module .splitter.v { left: -5px; }
340
+ body[data-shell=immersive] .sidebar .splitter.v { right: -5px; }
341
+
342
+ /* Workbench: the same modules docked in a grid, resized by their splitters */
343
+ body[data-shell=workbench] .layout { display: grid; grid-template-columns: var(--runs-w) minmax(0, 1fr); }
344
+ body[data-shell=workbench][data-runs=closed] .layout { grid-template-columns: var(--rail-w) minmax(0, 1fr); }
345
+ body[data-shell=workbench] .sidebar { position: relative; border-radius: 0; border-width: 0 1px 0 0; }
346
+ body[data-shell=workbench] #main { position: relative; inset: auto; }
347
+ body[data-shell=workbench] .sidebar .splitter.v { right: -5px; }
348
+ body[data-shell=workbench][data-runs=closed] .sidebar :is(.runs-tools, .module-title, .module-count, .run-item > :not(.run-lamp)) { display: none; }
349
+ body[data-shell=workbench][data-runs=closed] .sidebar .module-head { justify-content: center; padding: 4px; }
350
+ body[data-shell=workbench][data-runs=closed] .sidebar .module-tools { margin: 0; }
351
+ body[data-shell=workbench][data-runs=closed] .run-item { grid-template-columns: 12px; justify-content: center; padding: 10px 0; }
352
+ body[data-shell=workbench][data-runs=closed] .sidebar .splitter { display: none; }
353
+ body[data-shell=workbench] .run-view { display: grid; grid-template-columns: minmax(0, 1fr) var(--insp-w); grid-template-rows: auto minmax(0, 1fr) auto var(--tasks-h);
354
+ grid-template-areas: "head insp" "stage insp" "strip insp" "tasks insp"; }
355
+ body[data-shell=workbench][data-insp=closed] .run-view { grid-template-columns: minmax(0, 1fr) 0; }
356
+ body[data-shell=workbench][data-tasks=closed] .run-view { grid-template-rows: auto minmax(0, 1fr) auto auto; }
357
+ body[data-shell=workbench] .stage-row { display: contents; }
358
+ body[data-shell=workbench] .stage-col { grid-area: stage; position: relative; min-height: 0; }
359
+ body[data-shell=workbench] .stage-col .stage-slot, body[data-shell=workbench] .stage-col .graph, body[data-shell=workbench] .stage-col .files-view { position: absolute; inset: 0; overflow: auto; }
360
+ body[data-shell=workbench] .stage-col .graph, body[data-shell=workbench] .stage-col .files-view { padding: var(--s-4); }
361
+ body[data-shell=workbench] .insp-module { grid-area: insp; position: relative; border-radius: 0; border-width: 0 0 0 1px; }
362
+ body[data-shell=workbench][data-insp=closed] .insp-module { display: none; }
363
+ body[data-shell=workbench] .insp-module .splitter.v { left: -5px; }
364
+ body[data-shell=workbench] .run-header { grid-area: head; border-radius: 0; border-width: 0 0 1px; }
365
+ body[data-shell=workbench] .strip-wrap { grid-area: strip; padding: var(--s-2) var(--s-3) 0; }
366
+ body[data-shell=workbench] .tasks-module { grid-area: tasks; position: relative; border-radius: 0; border-width: 1px 0 0; }
367
+ body[data-shell=workbench] .tasks-module .splitter.h { top: -5px; }
368
+ body[data-shell=workbench] .run-view.diff-open .diff-view { grid-area: 2 / 1 / 5 / 3; overflow: auto; padding: var(--s-4); border-radius: 0; border-width: 0; }
369
+ body[data-shell=workbench] .map-view { display: grid; grid-template-rows: auto minmax(0, 1fr); }
370
+ body[data-shell=workbench] .map-head-module { border-radius: 0; border-width: 0 0 1px; }
371
+ body[data-shell=workbench] .map-view .stage-slot { position: relative; min-height: 0; }
372
+ body[data-shell=workbench] .map-view .stage-note { position: absolute; left: var(--gap); bottom: var(--gap); }
373
+ body[data-shell=workbench] .map-view .stage-slot, body[data-shell=workbench] .map-cards-host { grid-row: 2; grid-column: 1; }
374
+ body[data-shell=workbench] .map-cards-host { overflow: auto; }
375
+ body[data-shell=workbench] .map-cards { padding: var(--s-4); }
376
+
377
+ /* content views: the leaderboard and the waiting pages */
378
+ body:is([data-view=models], [data-view=waiting], [data-view=loading], [data-view=first-run]) #main { padding: var(--s-6) var(--s-6) var(--s-8); }
379
+
380
+ /* ---------- the stage: the panel the run is inlaid on ---------- */
381
+ .stage-slot { position: relative; background: var(--stage-bg); }
382
+ .stage-slot.stage-on, .stage-slot.stage-loading { height: 100%; }
383
+ .stage { position: absolute; inset: 0; }
384
+ .stage-canvas { display: block; width: 100%; height: 100%; touch-action: none; outline: none; }
385
+ .stage-canvas.pointing { cursor: pointer; }
386
+ .stage-canvas:focus-visible { outline: 2px solid var(--route); outline-offset: -2px; }
387
+ .stage-probe { position: absolute; width: 0; height: 0; overflow: hidden; visibility: hidden; }
388
+ .stage-note { margin: var(--s-2) 0 0; font-size: var(--t-sm); color: var(--muted); }
389
+ .stage-note:empty { display: none; }
390
+ body[data-shell] .stage-note { position: absolute; z-index: 2; left: var(--L, var(--gap)); bottom: calc(var(--B, var(--gap)) + 60px); margin: 0; padding: 4px 10px; border-radius: var(--r-key); background: var(--glass); color: var(--glass-ink); font-family: var(--mono); font-size: var(--t-xs); }
391
+ .stage-slot.stage-loading::after { content: 'Loading the 3D view…'; position: absolute; inset: 0; display: grid; place-items: center; color: var(--muted); font-family: var(--font-plate); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; font-size: .929rem; }
392
+ .stage-tip { position: absolute; left: 0; top: 0; z-index: 6; max-width: 320px; padding: 9px 11px; border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); pointer-events: none; font-size: var(--t-sm); }
393
+ .stage-tip-meta { font-size: .714rem; margin-bottom: 4px; }
394
+ .stage-tip-title { font-weight: 650; overflow-wrap: anywhere; }
395
+ .stage-tip-body { font-family: var(--mono); font-size: var(--t-xs); overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
396
+ .stage-tip-foot { color: var(--muted); font-size: var(--t-xs); margin-top: 3px; }
397
+ .stage-tip-body + .stage-tip-body { margin-top: 2px; }
398
+ .stage-tip-note { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--rule); color: var(--ink-2); font-size: var(--t-xs); text-wrap: pretty;
399
+ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
400
+ .stage-tip-note .sev-chip { margin-right: 6px; vertical-align: -1px; }
401
+ .stage:fullscreen { --L: var(--gap); --R: var(--gap); --B: var(--gap); background: var(--stage-bg); }
402
+
403
+ /* the stage's own keys (stagectl.js): a bank down the right edge of the free stage, the legend beside it */
404
+ .stage-ctl { position: absolute; z-index: 4; right: var(--R, var(--gap)); top: 50%; translate: 0 -50%; display: grid; gap: 2px; padding: 3px;
405
+ border: 1px solid var(--rule); border-radius: calc(var(--r-key) + 3px); background: var(--module); box-shadow: var(--ply-1); }
406
+ .stage-ctl[hidden] { display: none; }
407
+ body:not([data-view=run]) .stage-ctl { right: var(--gap); } /* the map has no inspector beside it */
408
+ body:not([data-view=run]) .stage-legend { right: calc(var(--gap) + 48px); }
409
+ .stage-ctl .icon-btn { border: 0; background: none; box-shadow: none; color: var(--ink-2); }
410
+ .stage-ctl .icon-btn:hover:not(:disabled) { background: var(--key); color: var(--ink); }
411
+ .stage-ctl .icon-btn[aria-pressed=true] { background: var(--key); color: var(--ink); box-shadow: inset 0 0 0 1px var(--rule-2); }
412
+ .stage-ctl .icon-btn::after { inset: -2px -4px; } /* 36 × 40 hit areas that never overlap */
413
+ .stage-ctl-rule { height: 1px; margin: 2px 4px; background: var(--rule); }
414
+ .stage-ctl-group { display: grid; gap: 2px; }
415
+ .stage-ctl .latch::before { content: ''; position: absolute; top: 4px; right: 4px; width: 5px; height: 5px; border-radius: 50%; background: var(--lamp-off); transition: background-color var(--relay); }
416
+ .stage-ctl .latch[aria-pressed=true]::before { background: var(--route); }
417
+ /* the stage has the keyboard: its bank says so (the canvas fills the window behind the modules, its own ring would be hidden) */
418
+ .stage:has(.stage-canvas:focus-visible) .stage-ctl { box-shadow: var(--ply-1), 0 0 0 2px var(--route); }
419
+ body[data-shell] .stage-canvas:focus-visible { outline: none; }
420
+ .stage-legend { position: absolute; z-index: 4; right: calc(var(--R, var(--gap)) + 48px); top: 50%; translate: 0 -50%; width: 264px; max-height: calc(100% - 2 * var(--gap));
421
+ overflow: auto; padding: 8px 12px 12px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); }
422
+ .stage-legend[hidden] { display: none; }
423
+ .stage-legend-head, .keys-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
424
+ .stage-legend-head .icon-btn, .keys-head .icon-btn { width: 28px; min-width: 28px; min-height: 28px; border: 0; background: none; box-shadow: none; }
425
+ .lg-sec + .lg-sec { margin-top: 10px; }
426
+ .lg-title { margin: 0 0 6px; font-size: .714rem; }
427
+ .stage-legend-head h3 { margin: 0; }
428
+ .lg-row { display: flex; align-items: center; gap: 8px; min-height: 22px; font-size: var(--t-sm); }
429
+ .lg-label { min-width: 0; overflow-wrap: anywhere; }
430
+ .lg-note { margin: 4px 0 0; color: var(--muted); font-size: var(--t-xs); text-wrap: pretty; }
431
+ .lg-sw { flex: none; display: inline-grid; place-items: center; width: 22px; height: 14px; }
432
+ .lamp-route { --st-fill: var(--route); --st-ring: var(--lamp-edge); }
433
+ .lg-sev::before { content: ''; width: 11px; height: 11px; clip-path: var(--sev-shape); background: var(--sev); }
434
+ .lg-sev.pale::before { width: 8px; height: 8px; opacity: .55; }
435
+ .lg-cable::before { content: ''; width: 22px; height: 0; border-top: 1px solid var(--ink-2); }
436
+ .lg-cable.cable-route::before { border-top: 2px solid var(--route); }
437
+ .lg-cable.cable-critical::before { border-top: 2px solid var(--stage-accent, var(--lamp-amber)); }
438
+ .lg-cable.cable-retry::before { border-top: 1px dashed var(--ink-2); }
439
+ .lg-cable.cable-escalation::before { border-top: 1.5px solid var(--stage-accent, var(--lamp-amber)); }
440
+ .lg-bead { position: relative; }
441
+ .lg-bead::before { content: ''; width: 22px; height: 0; border-top: 1px solid var(--ink-2); }
442
+ .lg-bead::after { content: ''; position: absolute; left: 9px; top: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--stage-accent, var(--lamp-amber)); }
443
+ .lg-ring::before { content: ''; width: 12px; height: 12px; border-radius: 50%; background: conic-gradient(var(--lamp-green) 0 70%, var(--lamp-off) 70% 100%); mask: radial-gradient(circle, transparent 3.5px, #000 4px); }
444
+ .lg-color::before { content: ''; width: 12px; height: 12px; border-radius: 3px; background: var(--sw); }
445
+ .lg-height { display: inline-flex; align-items: end; gap: 2px; height: 14px; }
446
+ .lg-height i { width: 5px; border: 1px solid var(--ink-2); border-bottom: 0; }
447
+ .lg-height i:nth-child(1) { height: 5px; } .lg-height i:nth-child(2) { height: 9px; } .lg-height i:nth-child(3) { height: 14px; }
448
+ .lg-sec:has(.lg-scale) .lg-row { display: block; }
449
+ .lg-scale { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 6px; width: 100%; height: auto; font-family: var(--mono); font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
450
+ .lg-bar { height: 6px; border-radius: 3px; background: linear-gradient(90deg, var(--lamp-off), var(--stage-accent, var(--lamp-amber))); }
451
+ .lg-scale + .lg-label:empty { display: none; }
452
+ dialog.keys-sheet { width: min(640px, calc(100vw - 24px)); padding: 14px 18px 18px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); }
453
+ dialog.keys-sheet::backdrop { background: light-dark(rgb(17 22 19 / .35), rgb(0 0 0 / .55)); }
454
+ .keys-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px 24px; }
455
+ .keys-group dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 5px 12px; margin: 0; font-size: var(--t-sm); }
456
+ .keys-group dt { display: flex; align-items: flex-start; gap: 3px; }
457
+ .keys-group dd { margin: 0; color: var(--ink-2); }
458
+
459
+ /* the View popover's banks: a push button per part of the drawing, its lamp lit while that part is drawn */
460
+ .layer-bank { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
461
+ .layer-key { justify-content: flex-start; min-height: 30px; padding: 0 8px; gap: 7px; color: var(--ink-2); }
462
+ .layer-key::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--lamp-off); flex: none; transition: background-color var(--relay); }
463
+ .layer-key[aria-pressed=true] { color: var(--ink); }
464
+ .layer-key[aria-pressed=true]::before { background: var(--route); }
465
+
466
+ /* ---------- the map of every run ---------- */
467
+ .map-head-module { padding: 8px 10px; display: grid; gap: var(--s-2); }
468
+ .filters-key { display: none; min-height: 28px; padding: 0 10px; }
469
+ .filters-key[aria-expanded=true] { background: var(--key-hover); border-color: var(--ink-2); }
470
+ .map-head { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
471
+ .map-head h1 { font-size: inherit; }
472
+ .map-head .push { margin-left: auto; }
473
+ .map-cards:empty { display: none; }
474
+ .map-repo { margin: 0 0 var(--s-5); }
475
+ .map-repo h3 { margin: 0 0 var(--s-2); }
476
+ .map-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--s-2); }
477
+ .map-card { display: grid; gap: 4px; padding: 10px 12px; border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--module); color: var(--ink); text-decoration: none; min-width: 0; transition: border-color var(--relay); }
478
+ .map-card::before { content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--st-fill, var(--lamp-off)); box-shadow: inset 0 0 0 1.5px var(--st-ring, transparent); }
479
+ .map-card.st-running::before { animation: lamp-blink 1s steps(1, end) infinite; }
480
+ .map-card:hover { border-color: var(--ink-2); }
481
+ .map-card strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
482
+ .map-card.dim { opacity: .38; }
483
+ .map-card .muted { font-size: var(--t-xs); }
484
+ .leds { display: flex; flex-wrap: wrap; gap: 3px; }
485
+ .leds .led { width: 7px; height: 7px; }
486
+
487
+ /* ---------- a run: describer, push-button bank, inspector, tasks ---------- */
488
+ .run-header { background: var(--module); border: 1px solid var(--rule); border-radius: var(--r-module); padding: 10px 12px; display: grid; gap: 8px; min-width: 0; }
489
+ .run-head-body { display: grid; gap: 6px; min-width: 0; }
490
+ .run-header { container-type: inline-size; }
491
+ .run-title-row { display: flex; align-items: center; gap: 6px var(--s-3); min-width: 0; }
492
+ .run-title-row > .lamp { margin-right: -4px; }
493
+ .run-title-row > h2 { flex: 1 1 auto; min-width: 14ch; margin: 0; font-size: var(--t-md); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
494
+ .run-where { flex: none; white-space: nowrap; color: var(--muted); font-size: var(--t-sm); } /* the id is copied: only the goal gives way */
495
+ .run-where .repo { font-weight: 600; color: var(--ink-2); }
496
+ .run-title-row > .describer { flex: none; }
497
+ @container (max-width: 860px) {
498
+ .run-title-row { flex-wrap: wrap; } .run-title-row > h2 { flex-basis: calc(100% - 24px); }
499
+ .run-title-row > .describer { flex: 0 1 auto; max-width: 100%; flex-wrap: wrap; white-space: normal; row-gap: 2px; }
500
+ }
501
+ .run-actions { display: flex; gap: 6px; flex: none; margin-left: auto; }
502
+ .run-actions button { min-height: 32px; padding: 0 10px; }
503
+ .run-head-body > details { border: 0; padding: 0; font-size: var(--t-sm); }
504
+ .run-head-body > details[open] { max-height: 40vh; overflow: auto; }
505
+ .run-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); padding-top: 8px; border-top: 1px solid var(--rule); }
506
+ .run-toolbar > button { min-height: 32px; }
507
+ .view-btn .icon-chevron-up { width: 13px; height: 13px; color: var(--muted); }
508
+ .overlays.popover { margin: 0; inset: auto; position: fixed; width: 260px; display: grid; gap: var(--s-2); padding: 10px 12px 12px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); }
509
+ .overlays.popover:not(:popover-open) { display: none; }
510
+ .overlays .plate { justify-self: start; }
511
+ .overlays .filter { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--s-2); }
512
+ .overlays .filter select { width: 150px; min-height: 28px; }
513
+ .overlays .filter.check { justify-content: flex-start; min-height: 28px; }
514
+ .replay { display: flex; align-items: center; gap: var(--s-2); flex: 1 1 320px; min-width: min(100%, 300px); }
515
+ .replay[hidden] { display: none; }
516
+ .replay input[type=range] { flex: 1; min-width: 72px; }
517
+ .replay [data-act=at] { font-size: var(--t-xs); white-space: nowrap; }
518
+ .replay [data-act=at]:empty { display: none; }
519
+ .replay button, .replay select { min-height: 28px; }
520
+ .replay .icon-btn { width: 28px; min-width: 28px; }
521
+ .insp-module { overflow: hidden; }
522
+ .inspector { flex: 1; min-height: 0; overflow: auto; padding: var(--s-3) var(--s-4) var(--s-5); position: relative; outline: none; }
523
+ .strip-wrap { overflow-x: auto; }
524
+ .strip-wrap[hidden], .graph[hidden] { display: none; }
525
+ .tasks-module { overflow: hidden; }
526
+ .tasks-module .run-tasks { flex: 1; min-height: 0; overflow: auto; }
527
+ body[data-tasks=closed] .tasks-module :is(.run-tasks, .splitter, .dt-tools) { display: none; }
528
+ body[data-tasks=closed] .tasks-module .module-head { border-bottom: 0; }
529
+ .run-tasks .dt, .run-tasks .dt-frame, .run-tasks .table-scroll { height: 100%; }
530
+ .run-tasks .table-scroll { border: 0; border-radius: 0; }
531
+ .run-tasks .empty { padding: var(--s-4); }
532
+
533
+ /* the inspector's content (panel.js) */
534
+ .insp-head { margin-bottom: var(--s-3); padding-right: 72px; }
535
+ .insp-head h2 { font-size: var(--t-md); line-height: 1.3; margin: 0 0 2px; }
536
+ .insp-kind { color: var(--muted); font-size: var(--t-sm); }
537
+ .insp-head .chip { margin-top: 4px; }
538
+ .inspector > .insp-close { position: absolute; right: var(--s-3); top: var(--s-3); min-height: 28px; padding: 0 9px; }
539
+ .insp-section { margin: var(--s-5) 0 0; }
540
+ .inspector > .insp-section:first-child { margin-top: var(--s-1); }
541
+ .insp-section h3 { margin: 0 0 var(--s-2); }
542
+ .fields { display: grid; grid-template-columns: minmax(96px, 128px) minmax(0, 1fr); gap: 5px var(--s-4); margin: 0 0 var(--s-3); font-size: var(--t-sm); }
543
+ dt { color: var(--muted); }
544
+ dd { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; min-width: 0; font-variant-numeric: tabular-nums; }
545
+ details { border-top: 1px solid var(--rule); padding: var(--s-2) 0; }
546
+ summary { cursor: pointer; font-weight: 600; overflow-wrap: anywhere; transition: color var(--relay); }
547
+ summary:hover { color: var(--ink-2); }
548
+ .inspector pre { max-height: 360px; font-size: var(--t-xs); }
549
+ .inspector p { margin: 6px 0; font-size: var(--t-sm); }
550
+ .attempt, .review { border: 1px solid var(--rule); border-radius: var(--r-key); padding: var(--s-2) 10px; margin: var(--s-2) 0; background: var(--module-2); }
551
+ .attempt-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-bottom: 4px; }
552
+ .exec-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 3px 0; font-size: var(--t-sm); }
553
+ .findings { list-style: none; padding: 0; margin: 6px 0; display: grid; gap: var(--s-2); }
554
+ .finding { position: relative; padding: 2px 0 2px 16px; }
555
+ .finding::before { content: ''; position: absolute; left: 2px; top: 8px; width: 7px; height: 7px; transform: rotate(45deg); background: var(--sev, var(--st, var(--rule-2))); }
556
+ .finding.plausible::before { background: transparent; box-shadow: inset 0 0 0 1.5px var(--sev, var(--st, var(--rule-2))); }
557
+ .finding-head { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
558
+ .finding p { margin: 4px 0; overflow-wrap: anywhere; }
559
+ .finding details { border: 0; padding: 2px 0; font-size: var(--t-xs); }
560
+ .crit a { font-family: var(--mono); }
561
+ ul.plain { list-style: none; padding: 0; margin: 4px 0; display: grid; gap: 4px; font-size: var(--t-sm); }
562
+ ul.plain li.current { font-weight: 650; }
563
+ pre.cmd { max-height: none; }
564
+ .phase-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; margin: 6px 0; background: var(--module-2); }
565
+ .phase { min-width: 2px; }
566
+ .phase-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: var(--t-xs); color: var(--muted); }
567
+ .phase-key { display: inline-flex; align-items: center; gap: 4px; }
568
+ .phase-key i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; }
569
+ .phase + .phase { box-shadow: inset 1px 0 var(--module); }
570
+ .ph-preparation { background: var(--ph-1); }
571
+ .ph-preflight { background: var(--ph-2); }
572
+ .ph-dispatch { background: var(--ph-3); }
573
+ .ph-model { background: var(--lamp-amber); }
574
+ .ph-snapshot { background: var(--ph-3); }
575
+ .ph-verification { background: var(--ph-4); }
576
+ .ph-finalization { background: var(--ph-2); }
577
+ .fractal-tree { list-style: none; margin: var(--s-2) 0; padding: 0; display: grid; gap: 3px; }
578
+ .ft-node { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: var(--t-sm); }
579
+ .ft-node > a { font-family: var(--mono); font-weight: 600; }
580
+ .ft-node > .diff-link.small { margin-left: auto; }
581
+ .ft-node.reserved > a { font-weight: 400; color: var(--muted); }
582
+ .ft-node .muted { font-size: var(--t-xs); }
583
+ .ft-d1 { padding-left: 16px; } .ft-d2 { padding-left: 32px; } .ft-d3 { padding-left: 48px; } .ft-d4 { padding-left: 64px; } .ft-d5 { padding-left: 80px; } .ft-d6 { padding-left: 96px; }
584
+ .ft-node:not(.ft-d0) { border-left: 1px solid var(--rule-2); margin-left: 4px; }
585
+
586
+ /* ---------- tables ---------- */
587
+ .table-scroll { overflow: auto; max-width: 100%; border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--module); }
588
+ table { width: 100%; border-collapse: separate; border-spacing: 0; text-align: left; font-variant-numeric: tabular-nums; }
589
+ th { position: sticky; top: 0; z-index: 1; background: var(--module-2); font-family: var(--font-plate); font-weight: 700; font-size: .857rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
590
+ th, td { padding: 7px 10px; vertical-align: top; border-bottom: 1px solid var(--rule); }
591
+ td { font-size: var(--t-sm); overflow-wrap: anywhere; }
592
+ tbody tr:last-child td { border-bottom: 0; }
593
+ tbody tr { transition: background-color var(--relay); }
594
+ tbody tr:hover { background: var(--module-2); }
595
+ tr.selected, tr.selected:hover { background: var(--wash); }
596
+ tr.selected td:first-child { box-shadow: inset 3px 0 0 -1px var(--route); }
597
+ td pre { margin: 0; min-width: 170px; max-height: 180px; }
598
+ .run-tasks table { width: max-content; min-width: 100%; }
599
+ .run-tasks td { max-width: 360px; }
600
+ .run-tasks td.mono, .run-tasks td[data-col=status], .run-tasks td[data-col=verdict], .run-tasks td[data-col=busy], .run-tasks td[data-col=findings], .run-tasks td[data-col=deps] { white-space: nowrap; overflow-wrap: normal; }
601
+ .run-tasks td[data-col=title] { min-width: 200px; max-width: 320px; }
602
+ .run-tasks tbody tr { cursor: pointer; }
603
+ .dt { min-width: 0; }
604
+ .dt-frame { position: relative; min-width: 0; }
605
+ .dt-frame::before, .dt-frame::after { content: ''; position: absolute; top: 1px; bottom: 1px; z-index: 2; width: 32px; pointer-events: none; opacity: 0; transition: opacity var(--dur-1) var(--ease-out); }
606
+ .dt-frame::before { left: 1px; background: linear-gradient(to right, var(--module), transparent); }
607
+ .dt-frame::after { right: 1px; background: linear-gradient(to left, var(--module), transparent); }
608
+ .dt-frame.more-left::before, .dt-frame.more-right::after { opacity: 1; }
609
+ .dt-bar { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-3); margin-bottom: 6px; }
610
+ .dt-status { font-size: var(--t-xs); }
611
+ .dt-columns-btn { min-height: 28px; padding: 0 9px; }
612
+ th .th-btn, th .th-label { display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 0; border: 0; background: none; box-shadow: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; white-space: inherit; text-align: inherit; }
613
+ th .th-btn:hover:not(:disabled) { background: none; color: var(--ink); }
614
+ th .th-btn:active:not(:disabled) { scale: 1; }
615
+ th[draggable=true] { cursor: grab; }
616
+ th.dragging { opacity: .45; }
617
+ th.drop-before { box-shadow: inset 2px 0 0 var(--route); }
618
+ th.drop-after { box-shadow: inset -2px 0 0 var(--route); }
619
+ th.lb-num .th-btn, th.lb-num .th-label { justify-content: flex-end; width: 100%; }
620
+ .th-sort { display: inline-flex; color: var(--rule-2); transition: color var(--relay); }
621
+ .th-sort .icon { width: 13px; height: 13px; }
622
+ th:hover .th-sort, .th-sort.on { color: var(--ink); }
623
+ .dt-menu { margin: 0; inset: auto; position: fixed; width: 260px; max-height: min(70vh, 520px); overflow: auto; padding: 8px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); }
624
+ .dt-menu-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 2px 8px; }
625
+ .dt-menu-head button { min-height: 26px; padding: 0 8px; }
626
+ .dt-menu-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
627
+ .dt-menu-list li { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 2px; padding: 1px 2px; border-radius: var(--r-small); }
628
+ .dt-menu-list li:hover { background: var(--module-2); }
629
+ .dt-menu-list label { display: flex; align-items: center; gap: 8px; min-height: 30px; font-size: var(--t-sm); }
630
+ .dt-step { min-height: 26px; width: 26px; padding: 0; border-color: transparent; background: none; box-shadow: none; }
631
+ .dt-step .icon { width: 14px; height: 14px; }
632
+
633
+ /* ---------- the 2D views: dependency graph, execution chart, concurrency strip ---------- */
634
+ .graph { overflow: auto; max-width: 100%; }
635
+ .graph svg { display: block; }
636
+ .fg-box { fill: var(--st, var(--lamp-off)); fill-opacity: .12; stroke: var(--st, var(--lamp-off)); }
637
+ .fg-bar { fill: var(--st, var(--lamp-off)); }
638
+ .fg-verdict { stroke: var(--lamp-red); }
639
+ .fg-verdict.fg-pass { stroke: var(--st, var(--lamp-green)); }
640
+ .fg-empty { color: var(--muted); padding: var(--s-3) 0; }
641
+ .gantt, .strip { display: block; font-family: var(--mono); }
642
+ .gt-lane { fill: var(--module-2); }
643
+ .gt-lane.gt-over { fill: var(--warn-wash); }
644
+ .gt-lane-label { fill: var(--muted); font-size: 11px; }
645
+ .gt-lane-label.gt-over { fill: var(--warn-ink); }
646
+ .gt-tick { stroke: var(--rule); stroke-width: 1; }
647
+ .gt-tick-label { fill: var(--muted); font-size: 10px; }
648
+ .gt-item { cursor: pointer; }
649
+ .gt-box { fill: var(--st, var(--lamp-off)); fill-opacity: .2; stroke: var(--st, var(--lamp-off)); stroke-width: 1.2; }
650
+ .gt-item:hover .gt-box, .gt-item:focus .gt-box { fill-opacity: .35; }
651
+ .gt-item:focus { outline: none; }
652
+ .gt-item.gt-sel .gt-box { stroke: var(--route); stroke-width: 2.5; }
653
+ .gt-item.gt-crit .gt-box { stroke-width: 2.4; }
654
+ .gt-ghost .gt-box { fill-opacity: .04; stroke-dasharray: 4 3; }
655
+ .gt-future { opacity: .3; }
656
+ .gt-seg { fill: var(--st, var(--lamp-off)); }
657
+ .gt-seg.gt-dwarf { fill-opacity: .55; }
658
+ .gt-label { fill: var(--ink); font-size: 10.5px; pointer-events: none; }
659
+ .gt-now { stroke: var(--lamp-amber); stroke-width: 2; }
660
+ .cc-area.cc-tasks { fill: var(--lamp-amber); fill-opacity: .2; stroke: none; }
661
+ .cc-line.cc-models { fill: none; stroke: var(--lamp-amber); stroke-width: 1.5; }
662
+ .cc-cap { stroke: var(--lamp-red); stroke-width: 1; stroke-dasharray: 5 4; }
663
+ .cc-cap-label { fill: var(--lamp-red); }
664
+ .strip-wrap .strip { background: var(--module); border: 1px solid var(--rule); border-radius: var(--r-key); }
665
+
666
+ /* ---------- the run cloud (cloudui.js over cloud3d.js) ---------- */
667
+ body.cloud-mode .sidebar { display: none !important; }
668
+ body.cloud-mode .layout { display: block; }
669
+ body.cloud-mode #main { position: absolute; inset: 0; padding: 0; }
670
+ .cloud-view { position: relative; height: 100%; margin: 0; overflow: hidden; background: var(--stage-bg); }
671
+ .cloud-view:fullscreen { width: 100vw; height: 100vh; }
672
+ .cloud-view .stage-note { display: none; }
673
+ .stage-slot.cloud { position: absolute; inset: 0; }
674
+ .stage-slot.cloud.stage-on, .stage-slot.cloud.stage-loading { height: auto; }
675
+ .cloud-view:not(.cloud-3d) .stage-slot.cloud { display: none; }
676
+ .stage-canvas.grabbing { cursor: grabbing; }
677
+ .cloud-ui { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
678
+ .cloud-ui > * { pointer-events: auto; }
679
+ .cloud-ui [hidden] { display: none !important; }
680
+ .cloud-bar { position: absolute; left: var(--gap); right: var(--gap); top: var(--gap); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2) var(--s-3); pointer-events: none; }
681
+ .cloud-bar > * { pointer-events: auto; }
682
+ .cloud-bar-left { display: flex; align-items: center; gap: var(--s-3); padding: 6px 10px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-1); }
683
+ .cloud-bar-left h1 { font-size: inherit; }
684
+ .cloud-count { font-family: var(--mono); font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
685
+ .cloud-bar-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 5px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-1); }
686
+ .cloud-filters-btn[aria-expanded=true] { border-color: var(--ink-2); background: var(--key-hover); }
687
+ .cloud-menu { position: relative; border: 0; padding: 0; }
688
+ .cloud-menu > summary { list-style: none; display: inline-flex; align-items: center; min-height: 32px; padding: 0 12px; border: 1px solid var(--rule-2); border-radius: var(--r-key); background: var(--key);
689
+ font-family: var(--font-plate); font-weight: 700; font-size: .929rem; letter-spacing: .05em; text-transform: uppercase; }
690
+ .cloud-menu > summary::-webkit-details-marker { display: none; }
691
+ .cloud-menu > summary::before { display: none; }
692
+ .cloud-menu > summary::after { content: ''; width: 6px; height: 6px; margin-left: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
693
+ .cloud-menu-body { position: absolute; right: 0; top: calc(100% + 6px); width: 280px; display: grid; gap: 6px; padding: 10px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-2); }
694
+ .cloud-menu-body p { font-size: var(--t-xs); }
695
+ .cloud-panel { position: absolute; left: var(--gap); top: 68px; bottom: var(--gap); width: 300px; overflow: auto; padding: 10px 12px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-1); }
696
+ .cloud-panel-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-2); }
697
+ .cloud-panel-head h2 { margin: 0; font-size: inherit; }
698
+ .cloud-panel input[type=search], .cloud-panel input[type=number] { width: 100%; }
699
+ .cloud-field { border: 0; border-top: 1px solid var(--rule); margin: 10px 0 0; padding: var(--s-2) 0 0; min-width: 0; }
700
+ .cloud-field legend { margin-bottom: 4px; }
701
+ .cloud-field .cloud-field { border-top: 0; margin-top: 4px; padding-top: 0; }
702
+ .cloud-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
703
+ .cloud-chip { min-height: 26px; padding: 0 8px; border-radius: 13px; font-size: .857rem; }
704
+ .cloud-chip[class*=' st-']::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--st); }
705
+ .cloud-chip[aria-pressed=true] { background: var(--wash); border-color: var(--route); color: var(--ink); box-shadow: inset 0 0 0 1px var(--route); }
706
+ .cloud-check-tools { display: flex; gap: var(--s-2); align-items: center; margin: 4px 0; }
707
+ .cloud-check-tools input { flex: 1; }
708
+ .cloud-checks { list-style: none; margin: 0; padding: 0; max-height: 200px; overflow: auto; }
709
+ .cloud-checks li { display: flex; align-items: center; gap: 6px; padding: 1px 0; }
710
+ .cloud-checks label { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; font-size: var(--t-sm); }
711
+ .cloud-check-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
712
+ .cloud-only { visibility: hidden; font-size: var(--t-xs); }
713
+ .cloud-checks li:hover .cloud-only, .cloud-only:focus-visible { visibility: visible; }
714
+ .cloud-select { display: flex; align-items: center; gap: var(--s-2); margin-top: 6px; font-size: var(--t-xs); color: var(--muted); }
715
+ .cloud-select select { flex: 1; min-width: 0; }
716
+ .cloud-range { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); margin-top: 4px; }
717
+ .cloud-range label { display: grid; gap: 2px; font-size: var(--t-xs); color: var(--muted); }
718
+ .cloud-legend { position: absolute; left: 324px; bottom: var(--gap); max-width: min(560px, calc(100% - 700px)); padding: 8px 12px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-1); font-size: var(--t-xs); }
719
+ .cloud-panel[hidden] ~ .cloud-legend { left: var(--gap); max-width: min(560px, calc(100% - 400px)); }
720
+ .cloud-legend-states { display: flex; flex-wrap: wrap; gap: 4px 12px; list-style: none; margin: 0 0 4px; padding: 0; }
721
+ .cloud-legend-states li { display: inline-flex; align-items: center; gap: 5px; }
722
+ .cloud-legend-how { color: var(--muted); }
723
+ .cloud-card { position: absolute; right: var(--gap); top: 68px; width: 340px; max-height: calc(100% - 80px); overflow: auto; padding: 10px 12px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-1); }
724
+ .cloud-card-head { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-xs); }
725
+ .cloud-card-close { margin-left: auto; width: 28px; min-height: 28px; padding: 0; }
726
+ .cloud-card h2 { margin: var(--s-2) 0 2px; font-size: var(--t-md); }
727
+ .cloud-card .leds { margin: var(--s-2) 0; }
728
+ .cloud-card .fields { grid-template-columns: 96px minmax(0, 1fr); margin-bottom: var(--s-2); }
729
+ .cloud-card-actions { display: flex; flex-wrap: wrap; gap: 6px; }
730
+ .cloud-toast { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); display: flex; gap: var(--s-3); align-items: center; padding: 8px 14px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-2); font-size: var(--t-sm); max-width: calc(100% - 24px); }
731
+ .cloud-list { position: absolute; inset: 68px var(--gap) var(--gap) 324px; overflow: auto; padding: 0 4px 24px; }
732
+ .cloud-view:has(.cloud-panel[hidden]) .cloud-list { left: var(--gap); }
733
+ .cloud-list-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 4px 0 8px; }
734
+ .cloud-view:not(.cloud-3d) .cloud-legend { display: none; }
735
+
736
+ /* ---------- quick jump (search.js) and notifications (notify.js) ---------- */
737
+ .notify-pop { position: fixed; z-index: 30; width: min(380px, calc(100vw - 16px)); max-height: min(70vh, 640px); overflow: auto; padding: 12px 14px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-2); }
738
+ .notify-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
739
+ .notify-head h2 { margin: 0; font-size: var(--t-base); }
740
+ .notify-kinds { border: 0; border-top: 1px solid var(--rule); margin: 6px 0; padding: var(--s-2) 0 0; display: grid; gap: 3px; }
741
+ .notify-kinds legend { margin-bottom: 4px; }
742
+ .notify-kinds label { font-size: var(--t-sm); display: flex; align-items: center; gap: 8px; }
743
+ .notify-browser { border-top: 1px solid var(--rule); padding: var(--s-2) 0; display: grid; gap: 6px; justify-items: start; }
744
+ .notify-browser p { font-size: var(--t-xs); }
745
+ .notify-log { list-style: none; margin: 0; padding: var(--s-2) 0 0; border-top: 1px solid var(--rule); display: grid; gap: var(--s-2); }
746
+ .notify-item { display: grid; grid-template-columns: 10px minmax(0, 1fr); column-gap: 8px; font-size: var(--t-sm); }
747
+ .notify-item::before { content: ''; grid-row: 1 / span 3; width: 8px; height: 8px; margin-top: 6px; border-radius: 50%; background: var(--lamp-off); }
748
+ .notify-item.unread::before { background: var(--route); }
749
+ .notify-item.bad::before { background: var(--lamp-red); }
750
+ .notify-item > * { grid-column: 2; }
751
+ .notify-item a { font-weight: 600; }
752
+ .notify-body { overflow-wrap: anywhere; }
753
+ .notify-when { font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
754
+ .notify-toast { position: fixed; z-index: 30; right: 16px; bottom: 16px; display: grid; gap: 2px; max-width: min(380px, calc(100vw - 32px)); padding: 10px 14px 10px 30px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); box-shadow: var(--ply-2); font-size: var(--t-sm); }
755
+ .notify-toast::before { content: ''; position: absolute; left: 12px; top: 16px; width: 9px; height: 9px; border-radius: 50%; background: var(--route); }
756
+ .notify-toast.bad::before { background: var(--lamp-red); }
757
+ .notify-toast a { font-weight: 650; }
758
+ .notify-toast[hidden], .notify-pop[hidden] { display: none; }
759
+ dialog.jump { width: min(680px, calc(100vw - 24px)); max-height: min(72vh, 720px); margin: 12vh auto auto; padding: 0; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); overflow: hidden; }
760
+ dialog.jump[open] { display: flex; flex-direction: column; }
761
+ dialog.jump::backdrop, dialog.export-dialog::backdrop { background: light-dark(rgb(17 22 19 / .35), rgb(0 0 0 / .55)); }
762
+ .jump-input { width: 100%; min-height: 52px; padding: 0 16px; border: 0; border-bottom: 1px solid var(--rule); border-radius: 0; background: transparent; color: var(--ink); font-size: var(--t-md); outline: none; }
763
+ .jump-list { list-style: none; margin: 0; padding: 6px; overflow: auto; flex: 1; min-height: 0; }
764
+ .jump-group { margin: 10px 8px 4px; }
765
+ .jump-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: var(--r-key); cursor: pointer; }
766
+ .jump-item[aria-selected=true] { background: var(--wash); box-shadow: inset 0 0 0 1px var(--rule-2); }
767
+ .jump-item .led { flex: none; }
768
+ .jump-text { display: grid; min-width: 0; }
769
+ .jump-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
770
+ .jump-label mark { background: none; color: inherit; font-weight: 750; text-decoration: underline; text-decoration-color: var(--lamp-amber); text-decoration-thickness: 2px; text-underline-offset: 3px; }
771
+ .jump-sub { color: var(--muted); font-size: var(--t-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
772
+ .jump-empty { padding: 14px 10px; color: var(--muted); }
773
+ .jump-foot { margin: 0; padding: 7px 14px; border-top: 1px solid var(--rule); color: var(--muted); font-size: var(--t-xs); }
774
+
775
+ /* ---------- the diff viewer (diffview.js), in the stage's place ---------- */
776
+ .run-view.diff-open > .run-toolbar, .run-view.diff-open > .stage-row, .run-view.diff-open > .strip-wrap { display: none; }
777
+ .diff-view { --add: light-dark(#dff0e2, #142a1b); --add-ink: light-dark(#1b6331, #8fd9a4); --del: light-dark(#f8e3e1, #331a18); --del-ink: light-dark(#9c2920, #ff9f97); --hunk: var(--module-2);
778
+ background: var(--module); border: 1px solid var(--rule); border-radius: var(--r-module); outline: none; }
779
+ .diff-view[hidden] { display: none; }
780
+ .diff-top { display: flex; align-items: center; gap: var(--s-3); }
781
+ .diff-top h2 { margin: 0; }
782
+ .diff-close { margin-left: auto; }
783
+ .diff-sources { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 6px; }
784
+ .diff-source { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 0 10px; border: 1px solid var(--rule-2); border-radius: var(--r-key); color: var(--ink); text-decoration: none; font-size: var(--t-sm); background: var(--key); }
785
+ .diff-source::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--lamp-off); }
786
+ .diff-source[aria-current=true] { box-shadow: inset 0 0 0 1px var(--route); font-weight: 650; }
787
+ .diff-source[aria-current=true]::before { background: var(--route); }
788
+ .diff-meta { margin: 4px 0 10px; font-size: var(--t-sm); }
789
+ .diff-note { padding: var(--s-3) 0; }
790
+ .diff-body { display: grid; grid-template-columns: minmax(200px, 280px) minmax(0, 1fr); gap: var(--s-4); align-items: start; }
791
+ .diff-files { position: sticky; top: 0; max-height: calc(100vh - 160px); overflow: auto; border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--module-2); padding: 6px; }
792
+ .diff-files ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
793
+ .diff-file-link { display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-radius: var(--r-small); color: var(--ink); text-decoration: none; font-family: var(--mono); font-size: var(--t-xs); min-width: 0; }
794
+ .diff-file-link:hover, .diff-file-link[aria-current=true] { background: var(--wash); }
795
+ .diff-dir { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; min-width: 0; }
796
+ .diff-body.no-files { grid-template-columns: minmax(0, 1fr); }
797
+ .diff-base { white-space: nowrap; flex: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; }
798
+ .diff-stat { margin-left: auto; white-space: nowrap; font-family: var(--mono); font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
799
+ .diff-add { color: var(--add-ink); } .diff-del { color: var(--del-ink); }
800
+ .diff-loose-link { margin-top: 6px; border-top: 1px solid var(--rule); border-radius: 0; font-family: inherit; color: var(--warn-ink); }
801
+ .diff-main { min-width: 0; display: grid; gap: var(--s-3); }
802
+ .diff-file { border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--field); overflow: hidden; scroll-margin-top: 12px; }
803
+ .diff-file-head { display: flex; align-items: center; gap: var(--s-2); padding: 7px 10px; background: var(--module-2); border-bottom: 1px solid var(--rule); flex-wrap: wrap; }
804
+ .diff-path { color: var(--ink); text-decoration: none; font-weight: 600; overflow-wrap: anywhere; }
805
+ .diff-path:hover { text-decoration: underline; }
806
+ .diff-file-findings { padding: 6px 10px; display: grid; gap: 6px; border-bottom: 1px solid var(--rule); }
807
+ .diff-scroll { overflow-x: auto; }
808
+ .diff-table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: var(--t-xs); line-height: 1.5; }
809
+ .diff-table td { padding: 0 8px; border: 0; vertical-align: top; max-width: none; min-width: 0; font-size: inherit; }
810
+ .diff-table tr:hover { background: none; }
811
+ .diff-table td.ln { width: 1%; min-width: 3.2em; text-align: right; color: var(--muted); user-select: none; border-right: 1px solid var(--rule); }
812
+ .diff-table td.mk { width: 1%; padding: 0 2px 0 8px; user-select: none; color: var(--muted); }
813
+ .diff-table td.code { white-space: pre; overflow-wrap: normal; }
814
+ .diff-line.add { background: var(--add); } .diff-line.add td.mk, .diff-line.add td.code { color: var(--add-ink); }
815
+ .diff-line.del { background: var(--del); } .diff-line.del td.mk, .diff-line.del td.code { color: var(--del-ink); }
816
+ .diff-line.meta td.code { color: var(--muted); font-style: italic; }
817
+ .diff-hunk td { background: var(--hunk); color: var(--muted); padding: 3px 10px; white-space: pre; }
818
+ .diff-pin > td { padding: 6px 10px 6px 7.4em; background: var(--module); font-family: var(--font-ui); font-size: var(--t-sm); white-space: normal; }
819
+ .diff-finding { position: relative; border: 1px solid var(--rule); border-radius: var(--r-key); padding: 6px 10px; background: var(--module); max-width: 900px; scroll-margin: 80px; transition: box-shadow var(--dur-1) var(--ease-out); } /* its chip carries the severity's shape */
820
+ .diff-finding.flash { box-shadow: 0 0 0 2px var(--route); }
821
+ .diff-finding-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: var(--t-xs); }
822
+ .diff-finding p { margin: 4px 0 0; overflow-wrap: anywhere; }
823
+ .diff-finding details { border: 0; padding: 2px 0 0; font-size: var(--t-xs); }
824
+ .diff-more { margin: 10px; }
825
+ .diff-loose { border: 1px solid var(--rule); border-radius: var(--r-key); padding: 10px 12px; display: grid; gap: var(--s-2); background: var(--module); }
826
+ .diff-loose h3 { justify-self: start; }
827
+ .diff-link { display: inline-block; margin-top: 6px; font-size: var(--t-sm); }
828
+ .diff-link.small { margin: 0; font-size: var(--t-xs); }
829
+ .exec-links { display: flex; flex-basis: 100%; justify-content: flex-end; gap: var(--s-3); }
830
+
831
+ /* ---------- an execution's conversation (convo.js), in the diff's place: a track with one station per event ---------- */
832
+ .convo-top { flex-wrap: wrap; }
833
+ .convo-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1) var(--s-3); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
834
+ .convo-tools { position: sticky; top: calc(-1 * var(--s-4)); z-index: 1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3);
835
+ margin: 0 calc(-1 * var(--s-4)) var(--s-3); padding: var(--s-2) var(--s-4); background: var(--module); border-bottom: 1px solid var(--rule); }
836
+ .convo-find { position: relative; display: flex; align-items: center; flex: 1 1 240px; max-width: 420px; }
837
+ .convo-find .icon { position: absolute; left: 9px; width: 16px; height: 16px; color: var(--muted); pointer-events: none; }
838
+ .convo-find input { width: 100%; padding-left: 32px; }
839
+ .convo-count { min-width: 7ch; font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
840
+ .convo-errs { font-size: var(--t-sm); }
841
+ .convo-err kbd { margin-left: 2px; text-transform: none; letter-spacing: 0; }
842
+ .convo-follow::before { content: ''; width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--lamp-off); transition: background-color var(--relay); }
843
+ .convo-follow[aria-pressed=true]::before { background: var(--route); }
844
+ .convo-err[hidden], .convo-follow[hidden] { display: none; }
845
+ .convo-status { display: grid; gap: var(--s-2); }
846
+ .convo-status:not(:empty) { margin-bottom: var(--s-3); }
847
+ .convo-list { list-style: none; margin: 0; padding: 0; max-width: 1040px; }
848
+ .ev { position: relative; display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: var(--s-3); padding-bottom: var(--s-4); scroll-margin: 96px; outline: none; }
849
+ .ev[hidden] { display: none; }
850
+ .ev::before { content: ''; position: absolute; left: 13.5px; top: 30px; bottom: 2px; width: 1px; background: var(--rule-2); }
851
+ .ev:last-child::before { display: none; }
852
+ .ev-gut { display: grid; place-items: center; width: 28px; height: 28px; border: 1px solid var(--rule-2); border-radius: 50%; background: var(--key); color: var(--ink-2);
853
+ transition: box-shadow var(--dur-1) var(--ease-out); }
854
+ .ev-gut .icon { width: 15px; height: 15px; }
855
+ .ev--message .ev-gut, .ev--result .ev-gut { background: var(--module-2); border-color: var(--ink-2); color: var(--ink); }
856
+ .ev.is-error .ev-gut { border-color: var(--lamp-red); color: var(--lamp-red); box-shadow: inset 0 0 0 1px var(--lamp-red); }
857
+ .ev:focus-visible .ev-gut { outline: 2px solid var(--route); outline-offset: 2px; }
858
+ .ev.flash .ev-gut { box-shadow: 0 0 0 4px color-mix(in srgb, var(--route) 35%, transparent); }
859
+ .ev-body { min-width: 0; padding-top: 3px; }
860
+ .ev-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-height: 22px; font-size: var(--t-sm); }
861
+ .ev-label { font-family: var(--font-plate); font-weight: 700; font-size: .857rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
862
+ .ev-toolname { font-size: var(--t-xs); }
863
+ .ev-cmdline { display: flex; align-items: flex-start; gap: var(--s-2); flex: 1 1 280px; min-width: 0; }
864
+ .ev-cmdline > .lamp { margin-top: calc((1lh - 9px) / 2); }
865
+ .ev-time { margin-left: auto; font-family: var(--mono); font-size: var(--t-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
866
+ .ev-tokens { font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
867
+ .ev-text { margin-top: 4px; max-width: 82ch; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.6; }
868
+ .ev--message .ev-text { font-size: var(--t-base); }
869
+ .ev-thought { color: var(--ink-2); }
870
+ .ev-cmd { flex: 1 1 auto; min-width: 0; font-family: var(--mono); font-size: var(--t-sm); white-space: pre-wrap; overflow-wrap: anywhere; }
871
+ .ev-cmd::before { content: '$ '; color: var(--muted); }
872
+ .ev-file { font-size: var(--t-xs); overflow-wrap: anywhere; }
873
+ .tag-bad { color: var(--lamp-red); border-color: currentColor; }
874
+ .ev-pre { margin-top: 6px; max-height: 420px; font-size: var(--t-xs); white-space: pre; overflow-wrap: normal; overflow-x: auto; }
875
+ .ev-patch { background: var(--field); color: var(--ink); border: 1px solid var(--rule); white-space: pre; overflow-wrap: normal; }
876
+ .ev-patch > span { display: block; min-height: 1lh; padding: 0 4px; margin: 0 -4px; }
877
+ .ev-patch > .add { background: var(--add); color: var(--add-ink); }
878
+ .ev-patch > .del { background: var(--del); color: var(--del-ink); }
879
+ .ev-fold { border: 0; padding: 4px 0 0; }
880
+ .ev-fold > summary { font-size: var(--t-xs); color: var(--muted); }
881
+ .ev--prompt .ev-fold, .ev--reasoning .ev-fold { padding: 0; }
882
+ .ev--prompt .ev-fold > summary, .ev--reasoning .ev-fold > summary { min-height: 22px; font-size: var(--t-sm); font-weight: 400; color: var(--ink-2); }
883
+ .ev-peek { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
884
+ .ev[data-kind=gap] > p { grid-column: 1 / -1; padding: var(--s-2) 0 var(--s-2) 40px; font-size: var(--t-sm); }
885
+
886
+ /* ---------- the model leaderboard (leaderboard.js, modelstats.js) ---------- */
887
+ .lb { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-4); min-width: 0; max-width: 1480px; }
888
+ .lb-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; }
889
+ .lb-head h1 { font-size: var(--t-xl); }
890
+ .lb-summary { font-size: var(--t-sm); font-variant-numeric: tabular-nums; }
891
+ .lb-caveat { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) 18px; padding: 10px 14px; border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--warn-wash); color: var(--ink); }
892
+ .lb-caveat p { flex: 1 1 420px; font-size: var(--t-sm); max-width: 92ch; }
893
+ .lb-caveat strong { color: var(--warn-ink); }
894
+ .lb-caveat .lb-explore { font-weight: 600; white-space: nowrap; }
895
+ .lb-count { align-self: center; font-size: var(--t-xs); font-variant-numeric: tabular-nums; }
896
+ .lb-notes { margin: 0; padding-left: 18px; color: var(--muted); font-size: var(--t-xs); display: grid; gap: 2px; }
897
+ .lb-section h2 { margin-bottom: 4px; }
898
+ .lb-lead { color: var(--muted); font-size: var(--t-sm); max-width: 96ch; margin-bottom: 10px; }
899
+ .lb-table th { white-space: normal; vertical-align: bottom; line-height: 1.2; }
900
+ .lb-table td { vertical-align: middle; white-space: nowrap; }
901
+ .lb-table .lb-num { text-align: right; }
902
+ .lb-zero { color: var(--muted); }
903
+ .lb-sub { display: block; font-size: var(--t-xs); color: var(--muted); }
904
+ .lb-model { font-weight: 600; }
905
+ .lb-alias { text-decoration: none; }
906
+ .lb-alias:hover .mp-name { background: var(--key-hover); }
907
+ .lb-few { margin-left: 6px; }
908
+ .lb-small td, .lb-small td a, .lb-small strong { color: var(--muted); }
909
+ .lb-rate-box { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
910
+ .lb-rate-text { display: inline-flex; align-items: baseline; justify-content: flex-end; gap: 6px; min-width: 6.5em; }
911
+ .lb-ci, .lb-vbar { display: block; flex: none; overflow: visible; }
912
+ .lb-ci-track { fill: var(--module-2); stroke: var(--rule); stroke-width: 1; }
913
+ .lb-ci-grid { fill: var(--rule-2); }
914
+ .lb-ci-band { fill: var(--lamp-amber); fill-opacity: .35; }
915
+ .lb-ci-tick { fill: var(--ink); }
916
+ .lb-small .lb-ci-band { fill: var(--muted); fill-opacity: .25; }
917
+ .lb-small .lb-ci-tick { fill: var(--muted); }
918
+ .lb-verdict-box { display: flex; align-items: center; gap: var(--s-2); }
919
+ .lb-verdict-text { font-size: var(--t-xs); }
920
+ .lb-vbar-track { fill: var(--module-2); }
921
+ .lb-vbar-seg { fill: var(--st, var(--muted)); }
922
+ .lb-p0 { color: var(--sev-p0); font-weight: 650; }
923
+ .lb-diff summary { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; list-style: none; min-height: 36px; }
924
+ .lb-diff summary::before { color: var(--muted); }
925
+ .lb-diff-name { font-weight: 650; }
926
+ .lb-diff summary .muted { font-size: var(--t-sm); font-weight: 400; font-variant-numeric: tabular-nums; }
927
+ .lb-diff .dt { margin-top: 10px; }
928
+ .lb-empty { border: 1px dashed var(--rule-2); border-radius: var(--r-key); background: var(--module); }
929
+ .lb-empty-title { font-weight: 650; color: var(--ink); }
930
+ .lb-empty button { margin-top: var(--s-3); }
931
+
932
+ /* ---------- exports ---------- */
933
+ dialog.export-dialog { width: min(560px, calc(100vw - 24px)); padding: 18px 20px; border: 1px solid var(--rule); border-radius: var(--r-module); background: var(--module); color: var(--ink); box-shadow: var(--ply-2); }
934
+ dialog.export-dialog h2 { margin-bottom: var(--s-2); }
935
+ .export-opt { display: flex; gap: 10px; align-items: flex-start; margin: var(--s-3) 0; }
936
+ .export-opt input { margin-top: 4px; }
937
+ .export-opt span { display: grid; gap: 2px; }
938
+ .export-opt .muted { font-size: var(--t-sm); }
939
+ .export-note:empty { display: none; }
940
+ .export-actions { display: flex; justify-content: flex-end; gap: var(--s-2); margin-top: 14px; }
941
+
942
+ /* ---------- Files: the run view's third mode (files.js), in the stage's place ---------- */
943
+ .run-view.files-open .stage-slot, .run-view.files-open .stage-note, .run-view.files-open #graph2d, .run-view.files-open .strip-wrap, .run-view.files-open .replay, .run-view.files-open .overlays { display: none; }
944
+ .files-view[hidden] { display: none; }
945
+ .files-view { min-width: 0; background: var(--desk); }
946
+ .fm { --fm-heat: var(--lamp-amber); --fm-plan: var(--muted); --fm-drift: var(--lamp-amber); --fm-bad: var(--lamp-red); --fm-overlap: var(--lamp-red); }
947
+ .fm-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
948
+ .fm-bar { align-items: center; margin-bottom: var(--s-2); }
949
+ .fm-bar .filter:not(.check) { flex-direction: row; align-items: center; gap: 6px; }
950
+ .fm-filter { width: min(280px, 60vw); }
951
+ .fm-toggles { display: flex; flex-wrap: wrap; gap: 2px 12px; }
952
+ .fm-tools { display: flex; gap: 6px; }
953
+ .fm-tools button { min-height: 28px; padding: 0 9px; }
954
+ .fm-swatch, .fm-ramp { display: inline-block; flex: none; vertical-align: middle; }
955
+ .fm-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; margin: 0 0 4px; font-size: var(--t-xs); color: var(--muted); }
956
+ .fm-key { display: inline-flex; align-items: center; gap: 5px; }
957
+ .fm-count { margin: 0 0 var(--s-2); font-size: var(--t-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
958
+ .fm-note { margin: 6px 0; font-size: var(--t-sm); }
959
+ .fm-empty { color: var(--muted); padding: var(--s-3) 0; }
960
+ .fm-scroll { overflow: auto; width: fit-content; max-width: 100%; max-height: min(72vh, 960px); border: 1px solid var(--rule); border-radius: var(--r-key); background: var(--module); overscroll-behavior: contain; }
961
+ .fm-sheet { width: max-content; }
962
+ .fm-headrow { display: flex; position: sticky; top: 0; z-index: 2; background: var(--module); border-bottom: 1px solid var(--rule); }
963
+ .fm-bodyrow { display: flex; }
964
+ .fm-corner, .fm-labels { position: sticky; left: 0; background: var(--module); border-right: 1px solid var(--rule); }
965
+ .fm-corner { z-index: 3; }
966
+ .fm-labels { z-index: 1; }
967
+ .fm svg { font-family: var(--mono); }
968
+ .fm-scroll svg { display: block; flex: none; }
969
+ .fm-axis { fill: var(--muted); font-size: 10.5px; letter-spacing: .04em; }
970
+ .fm-wave text { fill: var(--muted); font-size: 10px; }
971
+ .fm-wave line { stroke: var(--muted); stroke-width: 1; }
972
+ .fm-waveband { fill: var(--module-2); fill-opacity: .7; }
973
+ .fm-wavesep { stroke: var(--rule); stroke-width: 1; }
974
+ .fm-colhead { cursor: pointer; }
975
+ .fm-colhead text { fill: var(--ink); font-size: 11px; }
976
+ .fm-colhead:hover text { fill: var(--ink-2); text-decoration: underline; }
977
+ .fm-colhead.fm-sel text { font-weight: 700; }
978
+ .fm-st { fill: var(--st, var(--lamp-off)); }
979
+ .fm-colsel { fill: var(--wash); pointer-events: none; }
980
+ .fm-hover { fill: var(--route); fill-opacity: .07; pointer-events: none; }
981
+ .fm-zebra { fill: var(--module-2); fill-opacity: .55; }
982
+ .fm-dirband { fill: var(--module-2); }
983
+ .fm-hit { fill: transparent; }
984
+ .fm-label { fill: var(--ink); font-size: 12px; }
985
+ .fm-dirrow { cursor: pointer; }
986
+ .fm-dirrow .fm-label { font-weight: 650; }
987
+ .fm-dirrow:hover .fm-label { text-decoration: underline; }
988
+ .fm-tri { fill: var(--muted); }
989
+ .fm-num { fill: var(--muted); font-size: 10.5px; }
990
+ .fm-cell { cursor: pointer; }
991
+ .fm-touch { fill: var(--fm-heat); }
992
+ .fm-plan { fill: transparent; stroke: var(--fm-plan); stroke-width: 1.3; }
993
+ .fm-exist { fill: transparent; stroke: var(--fm-plan); stroke-width: 1.3; stroke-dasharray: 2.5 2; }
994
+ .fm-conflict { fill: none; stroke: var(--fm-bad); stroke-width: 2.2; }
995
+ .fm-hatch-bg { fill: var(--fm-drift); fill-opacity: .14; }
996
+ .fm-hatch-line { stroke: var(--fm-drift); stroke-width: 1.5; }
997
+ .fm-overlap { fill: var(--fm-overlap); stroke: var(--module); stroke-width: 1; }
998
+ .fm-colhead:focus, .fm-dirrow:focus, .fm-cell:focus, .fm-pop:focus { outline: none; }
999
+ .fm-colhead:focus-visible .fm-hit { stroke: var(--route); stroke-width: 2; }
1000
+ .fm-ring { fill: none; stroke: var(--route); stroke-width: 2; pointer-events: none; }
1001
+ .fm-dirrow:focus-visible .fm-hit { fill: var(--wash); }
1002
+ .fm-dirrow:focus-visible .fm-label { text-decoration: underline; }
1003
+ .fm-pop rect { fill: var(--module); stroke: var(--route); stroke-width: 1.2; }
1004
+ .fm-pop text { fill: var(--ink); font-size: 11.5px; text-decoration: underline; }
1005
+ .fm-pop:hover rect, .fm-pop:focus-visible rect { fill: var(--wash); stroke-width: 2; }
1006
+ .fm-lists { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 14px 28px; margin-top: var(--s-4); }
1007
+ .fm-list h3 { margin: 0 0 6px; cursor: help; }
1008
+ .fm-list ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: var(--t-sm); }
1009
+ .fm-list li { overflow-wrap: anywhere; }
1010
+ .fm-list p { font-size: var(--t-sm); }
1011
+ .fm-task { min-height: 0; padding: 0 2px; font-family: var(--mono); font-size: var(--t-xs); text-transform: none; letter-spacing: 0; font-weight: 500; border: 0; background: none; box-shadow: none; text-decoration: underline; text-decoration-color: var(--rule-2); text-underline-offset: 3px; }
1012
+ .fm-more { border: 0; padding: 4px 0 0; }
1013
+ .fm-more > summary { font-weight: 400; font-size: var(--t-sm); color: var(--muted); }
1014
+ .fm-more > ul { margin-top: 4px; }
1015
+
1016
+ /* ---------- narrow screens: one column, the runs module a drawer ---------- */
1017
+ @media (max-width: 760px) {
1018
+ .convo-tools { position: static; margin: 0 0 var(--s-3); padding: var(--s-2) 0; }
1019
+ .ev { grid-template-columns: 24px minmax(0, 1fr); column-gap: var(--s-2); }
1020
+ .ev::before { left: 11.5px; top: 26px; }
1021
+ .ev-gut { width: 24px; height: 24px; }
1022
+ html, body { height: auto; }
1023
+ body { overflow: auto; min-height: 100%; }
1024
+ .topbar { flex-wrap: wrap; gap: var(--s-2); padding: var(--s-2) var(--s-3); }
1025
+ .brand-sub, .top-search kbd, .top-search-label span { display: none; }
1026
+ .top-search { min-width: 0; margin-left: auto; }
1027
+ .desk-tools { width: 100%; flex-wrap: wrap; }
1028
+ .desk-tools .shell-switch { display: none; }
1029
+ .desk-tools .refresh-control { margin-left: auto; }
1030
+ .describer { flex-wrap: wrap; white-space: normal; row-gap: 2px; }
1031
+ .replay [data-act=at] { display: none; }
1032
+ .run-where { flex-basis: 100%; }
1033
+ .filters-key { display: inline-flex; margin-left: auto; }
1034
+ .map-head-module:not([data-filters=open]) #map-filters { display: none; }
1035
+ .map-head { flex-wrap: wrap; }
1036
+ body[data-shell] .layout { display: block; position: static; }
1037
+ body[data-shell] #main { position: static; inset: auto; overflow: visible; padding: var(--s-3); }
1038
+ body[data-shell] .sidebar { position: static; width: auto; height: auto; max-height: 50vh; margin: var(--s-3) var(--s-3) 0; box-shadow: none; border-radius: var(--r-module); border-width: 1px; }
1039
+ body[data-shell][data-runs=closed] .sidebar { display: none; }
1040
+ body[data-shell] .map-view, body[data-shell] .run-view { position: static; display: grid; gap: var(--s-3); }
1041
+ body[data-shell] .stage-row, body[data-shell] .stage-col { position: relative; display: block; inset: auto; }
1042
+ body[data-shell] .stage-col .stage-slot, body[data-shell] .map-view .stage-slot { position: relative; inset: auto; height: clamp(300px, 105vw, 62vh); border-radius: var(--r-module); overflow: hidden; }
1043
+ body[data-shell] .run-view .stage-col .stage-slot { height: clamp(240px, 72vw, 62vh); } /* a run's plate is wide: no empty bands above and below it */
1044
+ body[data-shell] .stage-col .graph, body[data-shell] .stage-col .files-view, body[data-shell] .map-cards { position: static; padding: 0; overflow: auto; }
1045
+ body[data-shell] :is(.run-header, .insp-module, .tasks-module, .diff-view, .map-head-module, .strip-wrap) { position: static; width: auto; max-width: none; height: auto; margin: 0; box-shadow: none; border-radius: var(--r-module); border-width: 1px; }
1046
+ body[data-shell] .tasks-module .run-tasks { max-height: 60vh; }
1047
+ body[data-shell] .stage-note { position: static; }
1048
+ .stage-ctl { top: auto; bottom: var(--gap); right: var(--gap); translate: none; grid-auto-flow: column; }
1049
+ .stage-ctl-rule { width: 1px; height: auto; margin: 4px 2px; }
1050
+ .stage-ctl :is([data-ctl=zoom-in], [data-ctl=zoom-out], [data-ctl=keys]) { display: none; }
1051
+ .stage-ctl-group { grid-auto-flow: column; }
1052
+ /* a phone's stage is too short to hold the legend: it opens as a sheet from the bottom of the screen */
1053
+ .stage-legend { position: fixed; z-index: 20; left: 0; right: 0; top: auto; bottom: 0; translate: none; width: auto; max-height: 70vh; border-radius: var(--r-module) var(--r-module) 0 0; padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
1054
+ .splitter { display: none !important; }
1055
+ .fields { grid-template-columns: 96px minmax(0, 1fr); gap: 6px 10px; }
1056
+ .diff-body { grid-template-columns: minmax(0, 1fr); }
1057
+ .diff-files { position: static; max-height: 240px; }
1058
+ .diff-pin > td { padding-left: 10px; }
1059
+ .lb-caveat .lb-explore { white-space: normal; }
1060
+ body.cloud-mode { overflow: hidden; height: 100%; }
1061
+ body.cloud-mode #main { position: absolute; }
1062
+ }
1063
+ @media (max-width: 900px) {
1064
+ .cloud-panel { width: auto; right: var(--gap); bottom: auto; max-height: 55%; top: 112px; }
1065
+ .cloud-card { left: var(--gap); width: auto; top: auto; bottom: var(--gap); max-height: 45%; }
1066
+ .cloud-legend { display: none; }
1067
+ .cloud-list { inset: 112px var(--gap) var(--gap) var(--gap); }
1068
+ }
1069
+
1070
+ /* ---------- motion: relays click, lamps blink; reduced motion keeps every state and drops the movement ---------- */
1071
+ @media (prefers-reduced-motion: reduce) {
1072
+ *, *::before, *::after { animation: none !important; transition-duration: 0ms !important; }
1073
+ }