@tea-agent/loop-agent 0.13.0 → 0.15.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 (272) hide show
  1. package/AGENTS.md +157 -157
  2. package/CHANGELOG.md +116 -305
  3. package/README.md +357 -334
  4. package/bin/agent-worker.js +22 -22
  5. package/bin/loop-agent.js +21 -21
  6. package/dist/commands/cursor-prompt.js +6 -6
  7. package/dist/commands/init.js +505 -505
  8. package/dist/commands/loop-benchmark.js +11 -11
  9. package/dist/commands/pi-reuse-benchmark.js +16 -16
  10. package/dist/executors/pi-event-serializer.js +33 -11
  11. package/dist/sidecars/cursor-prompt/executor.js +1 -1
  12. package/dist/task/runtime.js +27 -27
  13. package/dist/worker/observe/spec-evidence.js +19 -10
  14. package/dist/worker/observe/static/api.js +46 -46
  15. package/dist/worker/observe/static/app.js +151 -150
  16. package/dist/worker/observe/static/constants.js +156 -148
  17. package/dist/worker/observe/static/copy.js +67 -67
  18. package/dist/worker/observe/static/dag-helpers.js +201 -172
  19. package/dist/worker/observe/static/dag-layout.d.ts +31 -31
  20. package/dist/worker/observe/static/dag-layout.js +83 -83
  21. package/dist/worker/observe/static/dag-model.js +72 -72
  22. package/dist/worker/observe/static/dom.js +122 -122
  23. package/dist/worker/observe/static/format-pool.d.ts +71 -0
  24. package/dist/worker/observe/static/format-pool.js +134 -67
  25. package/dist/worker/observe/static/format.js +317 -292
  26. package/dist/worker/observe/static/index.html +350 -308
  27. package/dist/worker/observe/static/kpi.js +100 -94
  28. package/dist/worker/observe/static/markdown-render.js +124 -0
  29. package/dist/worker/observe/static/relations.js +133 -133
  30. package/dist/worker/observe/static/router.js +93 -93
  31. package/dist/worker/observe/static/run-processing.js +148 -148
  32. package/dist/worker/observe/static/shell-chrome.js +74 -68
  33. package/dist/worker/observe/static/state.js +273 -267
  34. package/dist/worker/observe/static/styles.css +2504 -1902
  35. package/dist/worker/observe/static/views/batch.js +227 -227
  36. package/dist/worker/observe/static/views/dag-graph.js +172 -172
  37. package/dist/worker/observe/static/views/dag-inspector.js +530 -627
  38. package/dist/worker/observe/static/views/dag.js +371 -371
  39. package/dist/worker/observe/static/views/dashboard.js +86 -100
  40. package/dist/worker/observe/static/views/failures.js +143 -143
  41. package/dist/worker/observe/static/views/feature.js +492 -492
  42. package/dist/worker/observe/static/views/pool.js +708 -350
  43. package/dist/worker/observe/static/views/run.js +453 -453
  44. package/dist/worker/observe/static/views/session-timeline.js +771 -219
  45. package/dist/worker/observe/static/views/shell.js +7 -7
  46. package/dist/worker/observe/static/views/task.js +314 -314
  47. package/dist/worker/observe/static/views/timeline.js +163 -163
  48. package/dist/workflows/dag/canvas-observer.js +275 -275
  49. package/dist/workflows/dag/init-hybrid.js +27 -11
  50. package/docs/README.md +106 -104
  51. package/docs/architecture/README.md +26 -26
  52. package/docs/architecture/dag-execution.md +140 -140
  53. package/docs/architecture/evolution.md +54 -54
  54. package/docs/architecture/facts-and-state.md +71 -71
  55. package/docs/architecture/runtime-boundaries.md +191 -191
  56. package/docs/architecture/system-overview.md +93 -93
  57. package/docs/architecture/worker-and-feature.md +85 -85
  58. package/docs/harness-methodology-debugging.md +153 -153
  59. package/docs/harness-methodology-tdd.md +130 -130
  60. package/docs/harness-methodology-verification.md +27 -27
  61. package/docs/init-surface.manifest.json +304 -307
  62. package/docs/skills/README.md +7 -7
  63. package/docs/skills/vetted-skill-registry.md +29 -29
  64. package/docs/templates/adr.md +60 -60
  65. package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -94
  66. package/docs/templates/agent-dag-decision-envelope.schema.json +213 -213
  67. package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -117
  68. package/docs/templates/agent-dag-decision-gate.prompt.md +246 -246
  69. package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -98
  70. package/docs/templates/agent-dag-report.schema.json +473 -473
  71. package/docs/templates/agent-dag-review-verdict.prompt.md +68 -68
  72. package/docs/templates/agent-dag.base.json +190 -190
  73. package/docs/templates/agent-dag.final-verification.json +185 -185
  74. package/docs/templates/agent-dag.schema.json +411 -411
  75. package/docs/templates/agent-dag.supervised-implementation.json +620 -620
  76. package/docs/templates/backend-test-analysis.schema.json +44 -44
  77. package/docs/templates/backend-test-case-manifest.schema.json +190 -190
  78. package/docs/templates/backend-test-dag.classify.prompt.md +75 -75
  79. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +204 -204
  80. package/docs/templates/backend-test-dag.json +559 -559
  81. package/docs/templates/backend-test-dag.retrospect.prompt.md +139 -139
  82. package/docs/templates/backend-test-dag.review-cases.prompt.md +83 -83
  83. package/docs/templates/backend-test-execution.schema.json +133 -133
  84. package/docs/templates/backend-test-result.schema.json +99 -99
  85. package/docs/templates/branch-merge-report.md +0 -1
  86. package/docs/templates/exec-plan.md +64 -64
  87. package/docs/templates/feature-spec.md +53 -53
  88. package/docs/templates/frontend-design-contract.md +42 -42
  89. package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -17
  90. package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -16
  91. package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -16
  92. package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -16
  93. package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -16
  94. package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -16
  95. package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -21
  96. package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -29
  97. package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -28
  98. package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -28
  99. package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -29
  100. package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -27
  101. package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -28
  102. package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -28
  103. package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -27
  104. package/docs/templates/frontend-eval/metrics.md +138 -138
  105. package/docs/templates/frontend-eval/smoke-targets.md +53 -53
  106. package/docs/templates/frontend-implementation-contract.schema.json +27 -27
  107. package/docs/templates/frontend-task-constraints.md +35 -35
  108. package/docs/templates/frontend-task-requirement.md +70 -70
  109. package/docs/templates/frontend-test-dag.generate-cases.prompt.md +5 -5
  110. package/docs/templates/frontend-test-dag.json +23 -23
  111. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +3 -3
  112. package/docs/templates/frontend-test-dag.retrospect.prompt.md +3 -3
  113. package/docs/templates/frontend-test-dag.review-cases.prompt.md +3 -3
  114. package/docs/templates/frontend-test-dag.review-execution.prompt.md +3 -3
  115. package/docs/templates/harness.schema.json +221 -221
  116. package/docs/templates/hybrid-dag.json +188 -188
  117. package/docs/templates/init-evolution-review.md +35 -35
  118. package/docs/templates/interactive-ui-round2-experiment.md +66 -66
  119. package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -118
  120. package/docs/templates/knowledge-sync-dag.json +178 -178
  121. package/docs/templates/knowledge-sync-draft.schema.json +71 -71
  122. package/docs/templates/product-line/AGENTS.md +8 -8
  123. package/docs/templates/product-line/README.md +9 -9
  124. package/docs/templates/product-line/acceptance.yaml +14 -14
  125. package/docs/templates/product-line/closeout.yaml +9 -9
  126. package/docs/templates/product-line/design.md +13 -13
  127. package/docs/templates/product-line/links.md +10 -10
  128. package/docs/templates/product-line/requirement.md +17 -17
  129. package/docs/templates/product-line/task-graph.yaml +15 -15
  130. package/docs/templates/product-line/task.yaml +64 -64
  131. package/docs/templates/product-line/test-plan.md +7 -7
  132. package/docs/templates/production-readiness-checklist.md +57 -57
  133. package/docs/templates/progress-log.md +17 -17
  134. package/docs/templates/project-start-checklist.md +9 -9
  135. package/docs/templates/qa-report.md +48 -48
  136. package/docs/templates/sprint-contract.md +29 -29
  137. package/docs/templates/worker-dogfood-evidence.md +80 -80
  138. package/docs/templates/worker-dogfood-setup.md +68 -68
  139. package/examples/decision-gate-agent-dag.json +173 -173
  140. package/examples/example-dag.json +46 -46
  141. package/examples/hybrid-loop-agent-dag.json +188 -188
  142. package/harness.json +66 -66
  143. package/package.json +78 -52
  144. package/scripts/kb-bootstrap-init-skeleton.sh +240 -240
  145. package/scripts/kb-graph-incremental-prepare.mjs +386 -386
  146. package/scripts/kb-graph-materialize.mjs +105 -105
  147. package/scripts/kb-graph-promote.mjs +164 -164
  148. package/scripts/kb-query.mjs +554 -554
  149. package/skills/agent-worker/SKILL.md +39 -39
  150. package/skills/agent-worker/references/agent-worker-operator.md +60 -60
  151. package/skills/ai-engineering-context/SKILL.md +48 -48
  152. package/skills/analyze-product-dependencies/SKILL.md +67 -67
  153. package/skills/analyze-product-dependencies/agents/openai.yaml +4 -4
  154. package/skills/analyze-product-dependencies/references/api-documentation-schema.md +30 -30
  155. package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +28 -28
  156. package/skills/analyze-product-dependencies/references/example.md +76 -76
  157. package/skills/analyze-product-dependencies/references/forward-test-cases.md +35 -35
  158. package/skills/analyze-product-dependencies/references/input-contract.md +11 -11
  159. package/skills/analyze-product-dependencies/references/scouting-rules.md +61 -61
  160. package/skills/analyze-product-dependencies/scripts/test-validators.mjs +267 -267
  161. package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +101 -101
  162. package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +142 -142
  163. package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +76 -76
  164. package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +146 -146
  165. package/skills/analyze-product-requirements/SKILL.md +90 -90
  166. package/skills/analyze-product-requirements/agents/openai.yaml +4 -4
  167. package/skills/analyze-product-requirements/references/acceptance-criteria.md +91 -91
  168. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +56 -56
  169. package/skills/analyze-product-requirements/references/example.md +86 -86
  170. package/skills/analyze-product-requirements/references/forward-test-cases.md +66 -66
  171. package/skills/analyze-product-requirements/references/product-analysis-schema.md +32 -32
  172. package/skills/analyze-product-requirements/references/product-requirement-schema.md +33 -33
  173. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +35 -35
  174. package/skills/analyze-product-requirements/scripts/test-validators.mjs +193 -193
  175. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +69 -69
  176. package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +97 -97
  177. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +98 -98
  178. package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +156 -156
  179. package/skills/browser-tools/SKILL.md +196 -196
  180. package/skills/browser-tools/browser-content.js +103 -103
  181. package/skills/browser-tools/browser-cookies.js +35 -35
  182. package/skills/browser-tools/browser-eval.js +53 -53
  183. package/skills/browser-tools/browser-hn-scraper.js +108 -108
  184. package/skills/browser-tools/browser-nav.js +44 -44
  185. package/skills/browser-tools/browser-pick.js +162 -162
  186. package/skills/browser-tools/browser-screenshot.js +34 -34
  187. package/skills/browser-tools/browser-start.js +86 -86
  188. package/skills/browser-tools/package-lock.json +2556 -2556
  189. package/skills/browser-tools/package.json +19 -19
  190. package/skills/code-review-core/SKILL.md +20 -20
  191. package/skills/codebase-scout/SKILL.md +19 -19
  192. package/skills/frontend-design-review/SKILL.md +66 -66
  193. package/skills/frontend-design-review/references/review-checklist.md +40 -58
  194. package/skills/frontend-implementation/SKILL.md +49 -49
  195. package/skills/frontend-implementation/references/code-standards.md +32 -32
  196. package/skills/frontend-implementation/references/design-spec.md +46 -46
  197. package/skills/frontend-implementation/references/node-contracts.md +27 -27
  198. package/skills/frontend-review/SKILL.md +61 -59
  199. package/skills/frontend-review/references/review-findings.md +48 -47
  200. package/skills/frontend-verification/SKILL.md +55 -53
  201. package/skills/frontend-verification/references/verification-checklist.md +59 -68
  202. package/skills/grill-me/SKILL.md +10 -10
  203. package/skills/grill-with-docs/SKILL.md +88 -88
  204. package/skills/grill-with-docs/adr-format.md +47 -47
  205. package/skills/grill-with-docs/context-format.md +60 -60
  206. package/skills/init-capability-evolution/SKILL.md +70 -70
  207. package/skills/loop-agent/SKILL.md +151 -151
  208. package/skills/loop-agent/references/README.md +67 -67
  209. package/skills/loop-agent/references/command-reference.md +527 -527
  210. package/skills/loop-agent/references/docs-converge.md +126 -126
  211. package/skills/loop-agent/references/harness-policy.md +263 -263
  212. package/skills/loop-agent/references/hybrid-dag.md +243 -243
  213. package/skills/loop-agent/references/learned/README.md +21 -21
  214. package/skills/loop-agent/references/long-running-loop.md +57 -57
  215. package/skills/loop-agent/references/model-routing.md +36 -36
  216. package/skills/loop-agent/references/multi-worktree.md +54 -54
  217. package/skills/loop-agent/references/one-shot-runs.md +85 -85
  218. package/skills/loop-agent/references/orchestrator-and-interventions.md +169 -169
  219. package/skills/loop-agent/references/pi-prompt.md +23 -23
  220. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -84
  221. package/skills/loop-agent/references/post-implementation-and-patterns.md +44 -44
  222. package/skills/loop-agent/references/task-workflow.md +89 -89
  223. package/skills/loop-agent/references/verification-and-failure-handling.md +141 -141
  224. package/skills/playwright-cli/SKILL.md +420 -420
  225. package/skills/playwright-cli/references/element-attributes.md +23 -23
  226. package/skills/playwright-cli/references/playwright-tests.md +39 -39
  227. package/skills/playwright-cli/references/request-mocking.md +87 -87
  228. package/skills/playwright-cli/references/running-code.md +241 -241
  229. package/skills/playwright-cli/references/session-management.md +225 -225
  230. package/skills/playwright-cli/references/storage-state.md +275 -275
  231. package/skills/playwright-cli/references/test-generation.md +433 -433
  232. package/skills/playwright-cli/references/tracing.md +139 -139
  233. package/skills/playwright-cli/references/video-recording.md +143 -143
  234. package/skills/playwright-cli-case-generator/SKILL.md +74 -74
  235. package/skills/requesting-code-review/SKILL.md +101 -101
  236. package/skills/requesting-code-review/code-reviewer.md +168 -168
  237. package/skills/systematic-debugging/CREATION-LOG.md +119 -119
  238. package/skills/systematic-debugging/SKILL.md +296 -296
  239. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -158
  240. package/skills/systematic-debugging/condition-based-waiting.md +115 -115
  241. package/skills/systematic-debugging/defense-in-depth.md +122 -122
  242. package/skills/systematic-debugging/find-polluter.sh +63 -63
  243. package/skills/systematic-debugging/root-cause-tracing.md +169 -169
  244. package/skills/systematic-debugging/test-academic.md +14 -14
  245. package/skills/systematic-debugging/test-pressure-1.md +58 -58
  246. package/skills/systematic-debugging/test-pressure-2.md +68 -68
  247. package/skills/systematic-debugging/test-pressure-3.md +69 -69
  248. package/skills/test-driven-development/SKILL.md +20 -20
  249. package/skills/using-git-worktrees/SKILL.md +215 -215
  250. package/skills/verification-before-completion/SKILL.md +154 -154
  251. package/skills/webapp-testing/SKILL.md +19 -19
  252. package/docs/agent-dag-recovery-playbook.md +0 -195
  253. package/docs/agent-dag-runner.md +0 -67
  254. package/docs/cursor-prompt-sidecar.md +0 -36
  255. package/docs/decisions/README.md +0 -18
  256. package/docs/design/README.md +0 -167
  257. package/docs/development-principles.md +0 -73
  258. package/docs/exec-plans/README.md +0 -6
  259. package/docs/exec-plans/active/README.md +0 -12
  260. package/docs/exec-plans/completed/README.md +0 -107
  261. package/docs/feature-workflow.md +0 -414
  262. package/docs/loop-agent-harness.md +0 -142
  263. package/docs/production-readiness.md +0 -96
  264. package/docs/progress/README.md +0 -80
  265. package/docs/reports/README.md +0 -159
  266. package/docs/verification-matrix.md +0 -70
  267. package/scripts/check-product-line-docs.sh +0 -29
  268. package/scripts/check-task-pool-root.sh +0 -32
  269. package/scripts/kb-graph-incremental-prepare.sh +0 -5
  270. package/scripts/kb-graph-materialize.sh +0 -4
  271. package/scripts/kb-graph-promote.sh +0 -4
  272. package/scripts/kb-query.sh +0 -5
@@ -1,1902 +1,2504 @@
1
- :root {
2
- --canvas: #f7f7f4;
3
- --canvas-soft: #fafaf7;
4
- --surface: #ffffff;
5
- --surface-muted: #f0efe9;
6
- --surface-ink: #26251e;
7
- --ink: #26251e;
8
- --body: #5a5852;
9
- --muted: #807d72;
10
- --muted-soft: #a09c92;
11
- --hairline: #e6e5e0;
12
- --hairline-strong: #cfcdc4;
13
- --orange: #f54e00;
14
- --orange-active: #d04200;
15
- --blue: #3f6ea4;
16
- --green: #1f8a65;
17
- --amber: #a66a00;
18
- --red: #c72d53;
19
- --lavender: #e4daf1;
20
- --mint: #d8ead5;
21
- --peach: #f1d8cb;
22
- --gold: #d8b166;
23
- --space-1: 4px;
24
- --space-2: 8px;
25
- --space-3: 12px;
26
- --space-4: 16px;
27
- --space-5: 20px;
28
- --space-6: 24px;
29
- --space-8: 32px;
30
- --space-10: 40px;
31
- --space-12: 48px;
32
- --radius-sm: 4px;
33
- --radius-md: 6px;
34
- --radius-lg: 8px;
35
- --transition-fast: 160ms ease;
36
- --transition-base: 240ms ease;
37
- }
38
-
39
- * {
40
- box-sizing: border-box;
41
- }
42
-
43
- html {
44
- background: var(--canvas);
45
- scroll-behavior: smooth;
46
- }
47
-
48
- body {
49
- min-width: 320px;
50
- margin: 0;
51
- background: var(--canvas);
52
- color: var(--ink);
53
- font-family:
54
- system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
55
- font-size: 14px;
56
- line-height: 1.5;
57
- }
58
-
59
- button,
60
- input,
61
- select,
62
- textarea {
63
- font: inherit;
64
- }
65
-
66
- a {
67
- color: inherit;
68
- }
69
-
70
- code,
71
- pre,
72
- .output-block,
73
- .rank-node-id,
74
- .dag-node-label,
75
- .dag-node-meta,
76
- .dag-node-status,
77
- td:first-child,
78
- .meta-item dd,
79
- .header-refresh,
80
- .kpi-value,
81
- .risk-total,
82
- .process-timeline-time {
83
- font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
84
- }
85
-
86
- .skip-link {
87
- position: fixed;
88
- top: -64px;
89
- left: var(--space-4);
90
- z-index: 100;
91
- padding: 9px 12px;
92
- background: var(--orange);
93
- color: #fff;
94
- font-weight: 700;
95
- text-decoration: none;
96
- transition: top var(--transition-fast);
97
- }
98
-
99
- .skip-link:focus {
100
- top: var(--space-3);
101
- }
102
-
103
- #app {
104
- width: min(100% - 48px, 1680px);
105
- margin: 0 auto;
106
- padding-bottom: 56px;
107
- }
108
-
109
- .site-header {
110
- position: sticky;
111
- top: 0;
112
- z-index: 30;
113
- display: grid;
114
- grid-template-columns: auto auto 1fr;
115
- grid-template-areas: "brand nav status" "crumb crumb crumb";
116
- column-gap: var(--space-6);
117
- align-items: center;
118
- min-height: 76px;
119
- margin-bottom: var(--space-8);
120
- padding: 14px 0 12px;
121
- background: color-mix(in srgb, var(--canvas) 94%, transparent);
122
- border-bottom: 1px solid var(--hairline);
123
- backdrop-filter: blur(10px);
124
- }
125
-
126
- .logo {
127
- grid-area: brand;
128
- display: inline-flex;
129
- align-items: center;
130
- gap: 9px;
131
- color: var(--ink);
132
- font-size: 16px;
133
- font-weight: 650;
134
- letter-spacing: 0;
135
- text-decoration: none;
136
- }
137
-
138
- .logo > i {
139
- color: var(--orange);
140
- font-size: 20px;
141
- font-weight: 400;
142
- }
143
- .logo:hover {
144
- color: var(--orange-active);
145
- }
146
-
147
- .top-nav {
148
- grid-area: nav;
149
- display: inline-flex;
150
- align-items: center;
151
- gap: 4px;
152
- }
153
-
154
- .nav-link {
155
- display: inline-flex;
156
- align-items: center;
157
- gap: 7px;
158
- min-height: 36px;
159
- padding: 0 10px;
160
- border: 1px solid transparent;
161
- border-radius: var(--radius-sm);
162
- color: var(--body);
163
- font-size: 13px;
164
- font-weight: 600;
165
- text-decoration: none;
166
- transition:
167
- border-color var(--transition-fast),
168
- background-color var(--transition-fast),
169
- color var(--transition-fast);
170
- }
171
-
172
- .nav-link > i {
173
- font-size: 16px;
174
- font-weight: 400;
175
- }
176
- .nav-link:hover,
177
- .nav-link:focus-visible {
178
- border-color: var(--hairline-strong);
179
- background: var(--surface);
180
- color: var(--ink);
181
- outline: none;
182
- }
183
- .nav-link-active {
184
- border-color: var(--orange);
185
- background: var(--surface);
186
- color: var(--ink);
187
- }
188
-
189
- .header-meta {
190
- grid-area: status;
191
- display: inline-flex;
192
- justify-self: end;
193
- align-items: center;
194
- gap: 7px;
195
- color: var(--muted);
196
- font-size: 12px;
197
- font-variant-numeric: tabular-nums;
198
- }
199
-
200
- .header-meta > i {
201
- color: var(--green);
202
- font-size: 16px;
203
- }
204
-
205
- .breadcrumb {
206
- grid-area: crumb;
207
- display: flex;
208
- min-height: 16px;
209
- gap: 7px;
210
- color: var(--muted);
211
- font-size: 12px;
212
- }
213
-
214
- .breadcrumb[hidden] {
215
- display: none;
216
- }
217
-
218
- .breadcrumb a {
219
- color: var(--body);
220
- text-decoration: none;
221
- }
222
- .breadcrumb a:hover,
223
- .breadcrumb a:focus-visible {
224
- color: var(--orange);
225
- text-decoration: underline;
226
- outline: none;
227
- }
228
-
229
- .dashboard-main:focus {
230
- outline: none;
231
- }
232
- .view {
233
- min-width: 0;
234
- }
235
- .view[hidden] {
236
- display: none !important;
237
- }
238
- .view:not(.view-dashboard) {
239
- display: grid;
240
- gap: var(--space-4);
241
- }
242
-
243
- .view-heading {
244
- display: grid;
245
- gap: 4px;
246
- margin-bottom: var(--space-6);
247
- }
248
-
249
- .view-kicker {
250
- margin: 0;
251
- color: var(--orange);
252
- font-size: 11px;
253
- font-weight: 700;
254
- letter-spacing: 0.08em;
255
- }
256
-
257
- .view h2 {
258
- margin: 0;
259
- color: var(--ink);
260
- font-size: 28px;
261
- font-weight: 500;
262
- line-height: 1.16;
263
- letter-spacing: 0;
264
- }
265
-
266
- .view-heading > p:last-child {
267
- max-width: 66ch;
268
- margin: 0;
269
- color: var(--body);
270
- }
271
-
272
- .panel {
273
- min-width: 0;
274
- background: var(--surface);
275
- border: 1px solid var(--hairline);
276
- border-radius: var(--radius-lg);
277
- padding: var(--space-5);
278
- }
279
-
280
- .panel-primary {
281
- border-color: var(--hairline-strong);
282
- }
283
- .panel-meta {
284
- background: transparent;
285
- border-color: var(--hairline-strong);
286
- }
287
- .panel-table {
288
- overflow: hidden;
289
- padding: 0;
290
- }
291
- .panel-output {
292
- background: #fbfbf9;
293
- }
294
-
295
- .section-heading,
296
- .panel h3 {
297
- margin: 0 0 var(--space-4);
298
- color: var(--ink);
299
- font-size: 14px;
300
- font-weight: 700;
301
- }
302
-
303
- .empty,
304
- .risk-empty {
305
- margin: 0;
306
- color: var(--muted);
307
- }
308
- .empty-state {
309
- padding: var(--space-8);
310
- text-align: center;
311
- color: var(--body);
312
- }
313
-
314
- .view-dashboard {
315
- display: grid;
316
- gap: var(--space-4);
317
- }
318
-
319
- .repo-banner {
320
- display: flex;
321
- align-items: center;
322
- gap: var(--space-3);
323
- padding: 10px 14px;
324
- border: 1px solid var(--hairline-strong);
325
- border-radius: var(--radius-lg);
326
- background: var(--surface);
327
- }
328
- .repo-banner > i {
329
- color: var(--muted);
330
- font-size: 18px;
331
- }
332
- .repo-banner-text {
333
- display: grid;
334
- gap: 2px;
335
- min-width: 0;
336
- }
337
- .repo-banner-name {
338
- color: var(--ink);
339
- font-size: 14px;
340
- font-weight: 700;
341
- overflow-wrap: anywhere;
342
- }
343
- .repo-banner-path {
344
- color: var(--muted);
345
- font-size: 11px;
346
- overflow-wrap: anywhere;
347
- }
348
-
349
- .panel-kpi {
350
- padding: 0;
351
- background: transparent;
352
- border: 0;
353
- }
354
-
355
- .kpi-group {
356
- margin: 0;
357
- padding: 0;
358
- border: 0;
359
- display: grid;
360
- gap: var(--space-3);
361
- }
362
- .kpi-group + .kpi-group {
363
- margin-top: var(--space-3);
364
- }
365
- .kpi-group-legend {
366
- padding: 0;
367
- color: var(--muted);
368
- font-size: 11px;
369
- font-weight: 700;
370
- letter-spacing: 0.04em;
371
- text-transform: uppercase;
372
- }
373
-
374
- .kpi-grid {
375
- display: grid;
376
- grid-template-columns: repeat(6, minmax(0, 1fr));
377
- overflow: visible;
378
- border: 1px solid var(--hairline-strong);
379
- border-radius: var(--radius-lg);
380
- background: var(--surface);
381
- }
382
-
383
- .kpi-card {
384
- position: relative;
385
- min-width: 0;
386
- min-height: 84px;
387
- padding: 15px 18px 14px;
388
- border-left: 1px solid var(--hairline);
389
- }
390
-
391
- .kpi-card:first-child {
392
- border-left: 0;
393
- }
394
- .kpi-label {
395
- margin-bottom: 9px;
396
- color: var(--muted);
397
- font-size: 11px;
398
- font-weight: 650;
399
- }
400
- .kpi-value-row {
401
- display: flex;
402
- align-items: baseline;
403
- gap: 6px;
404
- }
405
- .kpi-value {
406
- color: var(--ink);
407
- font-size: 26px;
408
- font-weight: 500;
409
- line-height: 1;
410
- font-variant-numeric: tabular-nums;
411
- }
412
-
413
- .kpi-help {
414
- display: inline-flex;
415
- align-items: center;
416
- justify-content: center;
417
- width: 16px;
418
- height: 16px;
419
- padding: 0;
420
- border: 0;
421
- border-radius: 50%;
422
- background: transparent;
423
- color: var(--muted-soft);
424
- cursor: help;
425
- font-size: 13px;
426
- line-height: 1;
427
- }
428
- .kpi-help:hover,
429
- .kpi-help:focus-visible {
430
- color: var(--ink);
431
- background: var(--surface-muted);
432
- outline: none;
433
- }
434
- .kpi-help:focus-visible {
435
- box-shadow: 0 0 0 2px var(--hairline-strong);
436
- }
437
- .kpi-tip {
438
- position: absolute;
439
- left: 12px;
440
- right: 12px;
441
- top: calc(100% - 8px);
442
- z-index: 10;
443
- max-width: 280px;
444
- padding: 8px 10px;
445
- border: 1px solid var(--hairline-strong);
446
- border-radius: var(--radius-md);
447
- background: var(--surface-ink);
448
- color: var(--canvas);
449
- font-size: 11px;
450
- font-weight: 400;
451
- line-height: 1.5;
452
- box-shadow: var(--shadow-panel);
453
- opacity: 0;
454
- visibility: hidden;
455
- pointer-events: none;
456
- transition: opacity var(--transition-fast);
457
- }
458
- .kpi-help:hover + .kpi-tip,
459
- .kpi-help:focus-visible + .kpi-tip {
460
- opacity: 1;
461
- visibility: visible;
462
- }
463
-
464
- .dashboard-workspace,
465
- .dashboard-secondary {
466
- display: grid;
467
- gap: var(--space-4);
468
- align-items: stretch;
469
- }
470
-
471
- .dashboard-workspace {
472
- grid-template-columns: 1fr;
473
- }
474
- .dashboard-secondary {
475
- grid-template-columns: repeat(2, minmax(0, 1fr));
476
- }
477
-
478
- .panel-risk {
479
- display: block;
480
- background: var(--canvas-soft);
481
- }
482
-
483
- .panel-risk-attention {
484
- border-color: color-mix(in srgb, var(--red) 50%, var(--hairline));
485
- background: #fff8f9;
486
- }
487
- .panel-risk .section-heading {
488
- margin: 0 0 var(--space-3);
489
- }
490
- .risk-blocks {
491
- display: grid;
492
- gap: var(--space-4);
493
- }
494
- .risk-block {
495
- display: grid;
496
- grid-template-columns: minmax(120px, 0.25fr) minmax(0, 1fr);
497
- align-items: start;
498
- gap: var(--space-3);
499
- padding-top: var(--space-3);
500
- border-top: 1px solid var(--hairline);
501
- }
502
- .risk-block:first-child {
503
- padding-top: 0;
504
- border-top: 0;
505
- }
506
- .risk-block-label {
507
- color: var(--muted);
508
- font-size: 11px;
509
- font-weight: 700;
510
- letter-spacing: 0.04em;
511
- text-transform: uppercase;
512
- }
513
- .risk-block-dag .risk-block-label {
514
- color: var(--ink);
515
- }
516
- .risk-block-worker .risk-block-label {
517
- color: var(--ink);
518
- }
519
- .risk-total {
520
- margin: 0;
521
- color: var(--amber);
522
- font-size: 32px;
523
- font-weight: 500;
524
- line-height: 1;
525
- font-variant-numeric: tabular-nums;
526
- }
527
- .panel-risk-attention .risk-total {
528
- color: var(--red);
529
- }
530
- .risk-summary {
531
- margin: 0;
532
- color: var(--body);
533
- font-size: 12px;
534
- line-height: 1.6;
535
- }
536
- .panel-risk .risk-empty {
537
- margin: 0;
538
- }
539
-
540
- .projection-fault {
541
- display: flex;
542
- align-items: flex-start;
543
- gap: var(--space-3);
544
- padding: 14px 16px;
545
- border: 1px solid color-mix(in srgb, var(--red) 50%, var(--hairline));
546
- border-radius: var(--radius-lg);
547
- background: #fff8f9;
548
- }
549
- .projection-fault > i {
550
- color: var(--red);
551
- font-size: 20px;
552
- line-height: 1.4;
553
- }
554
- .projection-fault-body {
555
- display: grid;
556
- gap: 4px;
557
- min-width: 0;
558
- }
559
- .projection-fault-title {
560
- margin: 0;
561
- color: var(--ink);
562
- font-size: 14px;
563
- font-weight: 700;
564
- }
565
- .projection-fault-message {
566
- margin: 0;
567
- color: var(--body);
568
- font-size: 12px;
569
- overflow-wrap: anywhere;
570
- }
571
- .projection-fault-at {
572
- margin: 0;
573
- color: var(--muted);
574
- font-size: 11px;
575
- }
576
-
577
- .risk-link,
578
- .active-dag-link,
579
- .link,
580
- .inbox-link,
581
- .artifact-link,
582
- .step-link {
583
- color: var(--ink);
584
- font-size: 12px;
585
- font-weight: 700;
586
- text-decoration-color: var(--orange);
587
- text-decoration-thickness: 1px;
588
- text-underline-offset: 4px;
589
- }
590
-
591
- .risk-link {
592
- margin: 0;
593
- padding: 0;
594
- white-space: nowrap;
595
- }
596
- .risk-link:hover,
597
- .active-dag-link:hover,
598
- .link:hover,
599
- .inbox-link:hover,
600
- .artifact-link:hover,
601
- .step-link:hover {
602
- color: var(--orange-active);
603
- }
604
-
605
- .active-dag-list {
606
- display: grid;
607
- gap: 10px;
608
- }
609
- .active-dag-card {
610
- padding: 14px;
611
- border: 1px solid var(--hairline);
612
- border-radius: var(--radius-md);
613
- background: var(--canvas-soft);
614
- }
615
- .active-dag-card-running {
616
- border-left: 3px solid var(--orange);
617
- padding-left: 12px;
618
- }
619
- .active-dag-header {
620
- display: flex;
621
- align-items: start;
622
- justify-content: space-between;
623
- gap: var(--space-3);
624
- margin-bottom: 9px;
625
- }
626
- .active-dag-title {
627
- min-width: 0;
628
- color: var(--ink);
629
- font-size: 14px;
630
- font-weight: 700;
631
- overflow-wrap: anywhere;
632
- }
633
- .active-dag-meta {
634
- display: grid;
635
- gap: 4px;
636
- color: var(--body);
637
- font-size: 12px;
638
- }
639
- .active-dag-link {
640
- display: inline-block;
641
- margin-top: 10px;
642
- }
643
-
644
- .meta-grid {
645
- display: grid;
646
- grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
647
- gap: 15px 24px;
648
- margin: 0;
649
- }
650
-
651
- .meta-item {
652
- min-width: 0;
653
- }
654
- .meta-item dt {
655
- color: var(--muted);
656
- font-size: 11px;
657
- font-weight: 650;
658
- }
659
- .meta-item dd {
660
- min-height: 24px;
661
- margin: 4px 0 0;
662
- padding-top: 5px;
663
- border-top: 1px solid var(--hairline);
664
- color: var(--ink);
665
- overflow-wrap: anywhere;
666
- font-size: 12px;
667
- }
668
-
669
- table {
670
- width: 100%;
671
- border-collapse: collapse;
672
- font-size: 13px;
673
- }
674
- th,
675
- td {
676
- padding: 11px 14px;
677
- border-bottom: 1px solid var(--hairline);
678
- text-align: left;
679
- vertical-align: top;
680
- }
681
- th {
682
- position: sticky;
683
- top: 0;
684
- z-index: 2;
685
- background: var(--surface-muted);
686
- color: var(--body);
687
- font-size: 11px;
688
- font-weight: 700;
689
- }
690
- td {
691
- color: var(--body);
692
- }
693
- tbody tr:last-child td {
694
- border-bottom: 0;
695
- }
696
- tbody tr {
697
- transition: background-color var(--transition-fast);
698
- }
699
- tbody tr:hover {
700
- background: #fff8f4;
701
- }
702
- tr.clickable {
703
- cursor: pointer;
704
- }
705
- tr.clickable:focus-within {
706
- outline: 2px solid var(--orange);
707
- outline-offset: -2px;
708
- }
709
-
710
- .badge {
711
- display: inline-flex;
712
- align-items: center;
713
- min-height: 22px;
714
- padding: 2px 7px;
715
- border: 1px solid currentColor;
716
- border-radius: 999px;
717
- background: transparent;
718
- color: var(--muted);
719
- font-size: 11px;
720
- font-weight: 700;
721
- line-height: 1.2;
722
- white-space: nowrap;
723
- }
724
-
725
- .badge-succeeded,
726
- .badge-finished,
727
- .badge-completed,
728
- .badge-done,
729
- .liveness-active {
730
- color: var(--green);
731
- background: #f2faf5;
732
- }
733
- .badge-failed,
734
- .badge-error,
735
- .liveness-stale {
736
- color: var(--red);
737
- background: #fff5f7;
738
- }
739
- .badge-partial-failed {
740
- color: #9a3a4f;
741
- background: #fff7f8;
742
- }
743
- .badge-running,
744
- .badge-started {
745
- color: var(--orange-active);
746
- background: #fff5ed;
747
- }
748
- .badge-pending,
749
- .badge-queued,
750
- .badge-blocked,
751
- .badge-unknown {
752
- color: var(--body);
753
- background: var(--surface-muted);
754
- }
755
- .badge-skipped,
756
- .badge-reused,
757
- .liveness-quiet {
758
- color: var(--blue);
759
- background: #f2f6fb;
760
- }
761
- .liveness-timeout-risk {
762
- color: var(--amber);
763
- background: #fff8e7;
764
- }
765
-
766
- .dag-detail-workspace {
767
- display: block;
768
- }
769
-
770
- .dag-inspector {
771
- position: fixed;
772
- z-index: 40;
773
- top: 96px;
774
- right: 24px;
775
- bottom: 24px;
776
- display: grid;
777
- grid-template-rows: auto minmax(0, 1fr);
778
- width: min(var(--dag-inspector-width, 440px), calc(100vw - 48px));
779
- min-width: 0;
780
- padding: 0;
781
- overflow: hidden;
782
- border-color: var(--hairline-strong);
783
- box-shadow: 0 20px 48px rgba(38, 37, 30, 0.16);
784
- opacity: 0;
785
- pointer-events: none;
786
- transform: translateX(calc(100% + 24px));
787
- visibility: hidden;
788
- transition:
789
- transform var(--transition-base),
790
- opacity var(--transition-base),
791
- visibility 0s linear 240ms;
792
- }
793
- .dag-inspector.is-open {
794
- opacity: 1;
795
- pointer-events: auto;
796
- transform: translateX(0);
797
- visibility: visible;
798
- transition-delay: 0s, 0s, 0s;
799
- }
800
- .dag-inspector-resize-handle {
801
- position: absolute;
802
- z-index: 1;
803
- top: 0;
804
- bottom: 0;
805
- left: 0;
806
- width: 18px;
807
- cursor: col-resize;
808
- touch-action: none;
809
- outline: none;
810
- }
811
- .dag-inspector-resize-handle::before {
812
- content: "";
813
- position: absolute;
814
- top: 50%;
815
- left: 7px;
816
- width: 3px;
817
- height: 52px;
818
- transform: translateY(-50%);
819
- border-radius: 2px;
820
- background: var(--hairline-strong);
821
- opacity: 0;
822
- transition:
823
- opacity var(--transition-base),
824
- background var(--transition-base);
825
- }
826
- .dag-inspector-resize-handle:hover::before,
827
- .dag-inspector-resize-handle:focus-visible::before {
828
- background: var(--orange);
829
- opacity: 1;
830
- }
831
- .dag-inspector-resize-handle:focus-visible {
832
- outline: 2px solid var(--orange);
833
- outline-offset: -2px;
834
- }
835
- body.is-resizing-dag-inspector {
836
- cursor: col-resize;
837
- user-select: none;
838
- }
839
- body.is-resizing-dag-graph {
840
- cursor: grabbing;
841
- user-select: none;
842
- }
843
- .dag-inspector-header {
844
- display: grid;
845
- grid-template-columns: minmax(0, 1fr) auto;
846
- gap: var(--space-3);
847
- align-items: start;
848
- padding: var(--space-4) var(--space-4) var(--space-3);
849
- border-bottom: 1px solid var(--hairline);
850
- background: var(--canvas-soft);
851
- }
852
- .dag-inspector-title {
853
- display: grid;
854
- gap: 6px;
855
- min-width: 0;
856
- }
857
- .dag-inspector-title h3 {
858
- margin: 0;
859
- font-size: 14px;
860
- }
861
- .dag-inspector-node {
862
- min-width: 0;
863
- color: var(--body);
864
- font-size: 12px;
865
- font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
866
- overflow-wrap: anywhere;
867
- }
868
- .dag-inspector-controls {
869
- display: inline-flex;
870
- align-items: center;
871
- gap: 8px;
872
- }
873
- .dag-inspector-close {
874
- display: inline-grid;
875
- place-items: center;
876
- width: 32px;
877
- height: 32px;
878
- border: 1px solid var(--hairline-strong);
879
- border-radius: var(--radius-sm);
880
- background: var(--surface);
881
- color: var(--body);
882
- cursor: pointer;
883
- }
884
- .dag-inspector-close:hover,
885
- .dag-inspector-close:focus-visible {
886
- border-color: var(--orange);
887
- color: var(--orange-active);
888
- outline: none;
889
- }
890
- .dag-inspector-tabs {
891
- display: flex;
892
- grid-column: 1 / -1;
893
- gap: 4px;
894
- margin-top: 2px;
895
- }
896
- .dag-inspector-tab {
897
- min-height: 32px;
898
- padding: 0 10px;
899
- border: 1px solid transparent;
900
- border-radius: var(--radius-sm);
901
- background: transparent;
902
- color: var(--muted);
903
- font-size: 12px;
904
- font-weight: 700;
905
- cursor: pointer;
906
- }
907
- .dag-inspector-tab:hover,
908
- .dag-inspector-tab:focus-visible {
909
- color: var(--ink);
910
- outline: none;
911
- }
912
- .dag-inspector-tab[aria-selected="true"] {
913
- border-color: color-mix(in srgb, var(--orange) 55%, var(--hairline));
914
- background: #fff5ed;
915
- color: var(--orange-active);
916
- }
917
- .dag-inspector-content {
918
- min-height: 0;
919
- padding: var(--space-4);
920
- overflow: auto;
921
- overscroll-behavior: contain;
922
- }
923
- .panel-graph {
924
- min-height: 0;
925
- }
926
-
927
- .dag-graph-wrap {
928
- display: grid;
929
- gap: var(--space-3);
930
- }
931
- .dag-graph-toolbar {
932
- display: flex;
933
- align-items: center;
934
- justify-content: space-between;
935
- gap: var(--space-3);
936
- }
937
- .dag-graph-summary,
938
- .dag-graph-fallback {
939
- margin: 0;
940
- color: var(--muted);
941
- font-size: 12px;
942
- }
943
- .dag-graph-reset {
944
- min-height: 32px;
945
- padding: 0 10px;
946
- border: 1px solid var(--hairline-strong);
947
- border-radius: var(--radius-sm);
948
- background: var(--surface);
949
- color: var(--ink);
950
- font-size: 12px;
951
- font-weight: 650;
952
- cursor: pointer;
953
- }
954
- .dag-graph-reset:hover,
955
- .dag-graph-reset:focus-visible {
956
- border-color: var(--orange);
957
- color: var(--orange-active);
958
- outline: none;
959
- }
960
- .dag-graph-viewport {
961
- min-height: 320px;
962
- max-height: 560px;
963
- overflow: auto;
964
- border: 1px solid var(--hairline);
965
- border-radius: var(--radius-md);
966
- background: var(--canvas-soft);
967
- scroll-behavior: auto;
968
- }
969
- .dag-graph {
970
- display: block;
971
- }
972
- .dag-edge {
973
- fill: none;
974
- stroke: var(--hairline-strong);
975
- stroke-width: 2;
976
- transition:
977
- opacity var(--transition-fast),
978
- stroke var(--transition-fast);
979
- }
980
- #dag-arrow path {
981
- fill: var(--hairline-strong);
982
- }
983
- .dag-graph-node {
984
- cursor: pointer;
985
- transition: opacity var(--transition-fast);
986
- }
987
- .dag-graph-node rect {
988
- fill: var(--surface);
989
- stroke: var(--hairline-strong);
990
- stroke-width: 1.5;
991
- }
992
- .dag-graph-node:hover rect,
993
- .dag-graph-node:focus-visible rect {
994
- stroke: var(--orange);
995
- stroke-width: 2;
996
- }
997
- .dag-graph-node:focus {
998
- outline: none;
999
- }
1000
- .dag-graph-node.selected rect {
1001
- stroke: var(--orange);
1002
- stroke-width: 3;
1003
- }
1004
- .dag-graph-node.status-running rect,
1005
- .dag-graph-node.status-started rect {
1006
- stroke: var(--orange);
1007
- fill: #fff7f0;
1008
- }
1009
- .dag-graph-node.status-failed rect,
1010
- .dag-graph-node.status-error rect {
1011
- stroke: var(--red);
1012
- fill: #fff7f8;
1013
- }
1014
- .dag-graph-node.status-succeeded:hover rect,
1015
- .dag-graph-node.status-succeeded:focus-visible rect,
1016
- .dag-graph-node.status-finished:hover rect,
1017
- .dag-graph-node.status-finished:focus-visible rect,
1018
- .dag-graph-node.status-completed:hover rect,
1019
- .dag-graph-node.status-completed:focus-visible rect,
1020
- .dag-graph-node.status-done:hover rect,
1021
- .dag-graph-node.status-done:focus-visible rect {
1022
- stroke: var(--green);
1023
- fill: #f2faf5;
1024
- }
1025
- .dag-graph-node.selected.status-succeeded rect,
1026
- .dag-graph-node.selected.status-finished rect,
1027
- .dag-graph-node.selected.status-completed rect,
1028
- .dag-graph-node.selected.status-done rect {
1029
- stroke: var(--green);
1030
- fill: #f2faf5;
1031
- }
1032
- .dag-graph-node.status-skipped rect {
1033
- stroke-dasharray: 5 4;
1034
- }
1035
- .dag-node-label {
1036
- fill: var(--ink);
1037
- font-size: 13px;
1038
- font-weight: 700;
1039
- }
1040
- .dag-node-meta {
1041
- fill: var(--muted);
1042
- font-size: 11px;
1043
- }
1044
- .dag-node-status {
1045
- fill: var(--body);
1046
- font-size: 11px;
1047
- }
1048
- .dag-dimmed {
1049
- opacity: 0.28;
1050
- }
1051
- .dag-graph-node.status-running {
1052
- animation: graph-node-pulse 2s ease-in-out infinite;
1053
- }
1054
- @keyframes graph-node-pulse {
1055
- 50% {
1056
- opacity: 0.72;
1057
- }
1058
- }
1059
-
1060
- .dag-section-heading {
1061
- display: flex;
1062
- align-items: baseline;
1063
- justify-content: space-between;
1064
- gap: var(--space-3);
1065
- margin-bottom: var(--space-4);
1066
- }
1067
- .dag-section-heading h3 {
1068
- margin: 0;
1069
- }
1070
- .dag-section-meta {
1071
- color: var(--muted);
1072
- font-size: 12px;
1073
- }
1074
- #dag-nodes .dag-section-heading {
1075
- padding: var(--space-5) var(--space-5) 0;
1076
- }
1077
- #dag-nodes .dag-node-table {
1078
- border-top: 1px solid var(--hairline);
1079
- }
1080
- .dag-node-table {
1081
- table-layout: fixed;
1082
- }
1083
- .dag-node-table th:nth-child(1),
1084
- .dag-node-table td:nth-child(1) {
1085
- width: 19%;
1086
- }
1087
- .dag-node-table th:nth-child(2),
1088
- .dag-node-table td:nth-child(2) {
1089
- width: 7%;
1090
- }
1091
- .dag-node-table th:nth-child(3),
1092
- .dag-node-table td:nth-child(3) {
1093
- width: 12%;
1094
- }
1095
- .dag-node-table th:nth-child(4),
1096
- .dag-node-table td:nth-child(4) {
1097
- width: 16%;
1098
- }
1099
- .dag-node-table th:nth-child(5),
1100
- .dag-node-table td:nth-child(5) {
1101
- width: 12%;
1102
- }
1103
- .dag-node-table th:nth-child(6),
1104
- .dag-node-table td:nth-child(6) {
1105
- width: 9%;
1106
- }
1107
- .dag-node-table th:nth-child(7),
1108
- .dag-node-table td:nth-child(7) {
1109
- width: 25%;
1110
- }
1111
- .dag-node-table td:nth-child(1),
1112
- .dag-node-table td:nth-child(4),
1113
- .dag-node-table td:nth-child(7) {
1114
- overflow-wrap: anywhere;
1115
- }
1116
- .dag-active-node {
1117
- background: #fff8f3;
1118
- }
1119
- .dag-error-node {
1120
- background: #fff7f8;
1121
- }
1122
- .dag-node-selected {
1123
- box-shadow: inset 3px 0 0 var(--orange);
1124
- }
1125
-
1126
- .rank-lanes {
1127
- display: grid;
1128
- gap: var(--space-3);
1129
- }
1130
- .rank-lane {
1131
- display: grid;
1132
- grid-template-columns: 56px minmax(0, 1fr);
1133
- gap: var(--space-3);
1134
- align-items: center;
1135
- }
1136
- .rank-lane-label {
1137
- color: var(--muted);
1138
- font-size: 11px;
1139
- font-weight: 700;
1140
- }
1141
- .rank-lane-nodes {
1142
- display: flex;
1143
- flex-wrap: wrap;
1144
- gap: 8px;
1145
- }
1146
- .rank-node-chip {
1147
- display: inline-flex;
1148
- align-items: center;
1149
- gap: 7px;
1150
- min-height: 32px;
1151
- padding: 5px 8px;
1152
- border: 1px solid var(--hairline);
1153
- border-radius: var(--radius-sm);
1154
- background: var(--canvas-soft);
1155
- }
1156
- .rank-node-active {
1157
- border-color: var(--orange);
1158
- }
1159
- .rank-node-error {
1160
- border-color: var(--red);
1161
- }
1162
- .rank-node-id {
1163
- color: var(--ink);
1164
- font-size: 11px;
1165
- }
1166
- .rank-node-dur {
1167
- color: var(--muted);
1168
- font-size: 11px;
1169
- }
1170
-
1171
- .process-timeline-note {
1172
- margin: 0 0 var(--space-2);
1173
- color: var(--muted);
1174
- font-size: 11px;
1175
- }
1176
- .process-timeline {
1177
- display: grid;
1178
- gap: 0;
1179
- margin: 0;
1180
- padding: var(--space-2) 0;
1181
- list-style: none;
1182
- }
1183
- .process-timeline-item {
1184
- display: grid;
1185
- grid-template-columns: 20px minmax(0, 1fr);
1186
- align-items: stretch;
1187
- min-height: 34px;
1188
- }
1189
- .process-timeline-item.has-time {
1190
- grid-template-columns: 20px 92px minmax(0, 1fr);
1191
- }
1192
- .process-timeline-rail {
1193
- position: relative;
1194
- display: grid;
1195
- place-items: center;
1196
- min-height: 34px;
1197
- }
1198
- .process-timeline-rail::before {
1199
- position: absolute;
1200
- top: 0;
1201
- bottom: 0;
1202
- width: 1px;
1203
- background: var(--hairline-strong);
1204
- content: "";
1205
- }
1206
- .process-timeline-item.is-first .process-timeline-rail::before {
1207
- top: 50%;
1208
- }
1209
- .process-timeline-item.is-last .process-timeline-rail::before {
1210
- bottom: 50%;
1211
- }
1212
- .process-timeline-dot {
1213
- position: relative;
1214
- z-index: 1;
1215
- width: 8px;
1216
- height: 8px;
1217
- border: 2px solid var(--surface);
1218
- border-radius: 50%;
1219
- background: var(--muted-soft);
1220
- }
1221
- .process-timeline-lifecycle .process-timeline-dot {
1222
- background: var(--lavender);
1223
- }
1224
- .process-timeline-tool-start .process-timeline-dot {
1225
- background: var(--orange);
1226
- }
1227
- .process-timeline-tool-end .process-timeline-dot {
1228
- background: var(--green);
1229
- }
1230
- .process-timeline-assistant .process-timeline-dot {
1231
- background: var(--blue);
1232
- }
1233
- .process-timeline-protocol .process-timeline-dot {
1234
- background: var(--muted-soft);
1235
- }
1236
- .process-timeline-time {
1237
- padding: 9px 0;
1238
- color: var(--muted);
1239
- font-size: 10px;
1240
- font-variant-numeric: tabular-nums;
1241
- }
1242
- .process-timeline-label {
1243
- min-width: 0;
1244
- padding: 8px 0 8px var(--space-2);
1245
- color: var(--body);
1246
- font-size: 12px;
1247
- line-height: 1.5;
1248
- overflow-wrap: anywhere;
1249
- }
1250
- .process-timeline-protocol .process-timeline-label {
1251
- color: var(--muted);
1252
- font-size: 11px;
1253
- }
1254
-
1255
- .markdown-output {
1256
- display: grid;
1257
- gap: var(--space-3);
1258
- color: var(--body);
1259
- font-size: 13px;
1260
- line-height: 1.65;
1261
- }
1262
- .markdown-output > :first-child {
1263
- margin-top: 0;
1264
- }
1265
- .markdown-output > :last-child {
1266
- margin-bottom: 0;
1267
- }
1268
- .markdown-output h1,
1269
- .markdown-output h2,
1270
- .markdown-output h3,
1271
- .markdown-output h4 {
1272
- margin: var(--space-5) 0 var(--space-2);
1273
- color: var(--ink);
1274
- line-height: 1.3;
1275
- }
1276
- .markdown-output h1 {
1277
- font-size: 21px;
1278
- }
1279
- .markdown-output h2 {
1280
- font-size: 18px;
1281
- }
1282
- .markdown-output h3 {
1283
- font-size: 16px;
1284
- }
1285
- .markdown-output h4 {
1286
- font-size: 14px;
1287
- }
1288
- .markdown-output p,
1289
- .markdown-output blockquote,
1290
- .markdown-output ul,
1291
- .markdown-output ol {
1292
- margin: 0;
1293
- }
1294
- .markdown-output ul,
1295
- .markdown-output ol {
1296
- padding-left: 22px;
1297
- }
1298
- .markdown-output blockquote {
1299
- padding-left: 12px;
1300
- border-left: 3px solid var(--peach);
1301
- color: var(--body);
1302
- }
1303
- .markdown-output pre {
1304
- margin: 0;
1305
- padding: var(--space-3);
1306
- overflow: auto;
1307
- border: 1px solid var(--hairline);
1308
- border-radius: var(--radius-sm);
1309
- background: var(--surface-ink);
1310
- color: #f8f7f2;
1311
- font-size: 12px;
1312
- line-height: 1.65;
1313
- }
1314
- .markdown-output code {
1315
- padding: 1px 4px;
1316
- border-radius: 3px;
1317
- background: var(--surface-muted);
1318
- color: var(--ink);
1319
- font-size: 0.92em;
1320
- }
1321
- .markdown-output pre code {
1322
- padding: 0;
1323
- background: transparent;
1324
- color: inherit;
1325
- }
1326
- .markdown-output a {
1327
- color: var(--orange-active);
1328
- text-decoration-color: var(--orange);
1329
- text-underline-offset: 3px;
1330
- }
1331
- .markdown-output table {
1332
- font-size: 12px;
1333
- }
1334
- .markdown-output th,
1335
- .markdown-output td {
1336
- padding: 8px 9px;
1337
- }
1338
- .markdown-output th {
1339
- position: static;
1340
- }
1341
- .markdown-error {
1342
- display: grid;
1343
- gap: var(--space-2);
1344
- padding-top: var(--space-4);
1345
- border-top: 1px solid var(--hairline);
1346
- }
1347
- .markdown-error-title {
1348
- margin: 0;
1349
- color: var(--red);
1350
- font-size: 12px;
1351
- font-weight: 700;
1352
- }
1353
-
1354
- .spec-evidence-section { padding-bottom: var(--space-4); border-bottom: 1px solid var(--hairline); }
1355
- .spec-evidence-section + .spec-evidence-section { margin-top: var(--space-4); }
1356
- .spec-evidence-section h4 { margin: 0 0 var(--space-2); color: var(--ink); font-size: 12px; font-weight: 700; }
1357
- .spec-evidence-summary { margin: var(--space-2) 0 0; color: var(--body); font-size: 12px; line-height: 1.6; }
1358
- .spec-evidence-list { display: grid; gap: 6px; margin: var(--space-2) 0 0; padding: 0; list-style: none; }
1359
- .spec-evidence-list li { display: flex; align-items: flex-start; gap: 6px; color: var(--body); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
1360
- .spec-evidence-list li > i { flex-shrink: 0; margin-top: 2px; color: var(--muted); font-size: 13px; }
1361
- .spec-evidence-list code { font-size: 11px; }
1362
- .spec-evidence-time { margin-left: auto; color: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; white-space: nowrap; }
1363
- .spec-evidence-warning { display: flex; align-items: flex-start; gap: 8px; margin-top: var(--space-4); padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--amber) 50%, var(--hairline)); border-radius: var(--radius-sm); background: #fff8e7; color: var(--body); font-size: 12px; line-height: 1.6; }
1364
- .spec-evidence-warning > i { flex-shrink: 0; margin-top: 2px; color: var(--amber); }
1365
-
1366
- .run-layer-process {
1367
- display: grid;
1368
- gap: var(--space-4);
1369
- margin-top: var(--space-4);
1370
- }
1371
- .run-layer-diagnosis {
1372
- display: grid;
1373
- gap: var(--space-4);
1374
- margin-top: var(--space-4);
1375
- }
1376
- .run-detail-workspace {
1377
- display: grid;
1378
- grid-template-columns: minmax(220px, 0.5fr) minmax(0, 1.25fr);
1379
- gap: var(--space-4);
1380
- align-items: start;
1381
- }
1382
- .run-evidence {
1383
- display: grid;
1384
- gap: var(--space-4);
1385
- min-width: 0;
1386
- }
1387
- .artifact-preview-list {
1388
- gap: 12px;
1389
- }
1390
- .artifact-preview-head {
1391
- display: flex;
1392
- flex-wrap: wrap;
1393
- gap: 8px;
1394
- align-items: baseline;
1395
- margin-bottom: 6px;
1396
- }
1397
- .artifact-preview-label {
1398
- font-size: 12px;
1399
- color: var(--muted);
1400
- overflow-wrap: anywhere;
1401
- }
1402
- .artifact-preview-body {
1403
- max-height: 240px;
1404
- overflow: auto;
1405
- font-size: 12px;
1406
- }
1407
- .artifact-preview-error {
1408
- color: var(--red);
1409
- }
1410
- .batch-task-links,
1411
- .batch-task-evidence {
1412
- display: flex;
1413
- flex-wrap: wrap;
1414
- gap: 4px;
1415
- align-items: center;
1416
- }
1417
- .object-link {
1418
- color: var(--body);
1419
- text-decoration: underline;
1420
- text-underline-offset: 2px;
1421
- }
1422
- .panel-rail {
1423
- background: var(--canvas-soft);
1424
- }
1425
- .step-timeline {
1426
- display: grid;
1427
- gap: 0;
1428
- margin: 0;
1429
- padding: 0;
1430
- list-style: none;
1431
- }
1432
- .step-timeline li {
1433
- display: grid;
1434
- grid-template-columns: 18px minmax(0, 1fr) auto;
1435
- align-items: center;
1436
- gap: 8px;
1437
- min-height: 38px;
1438
- border-bottom: 1px solid var(--hairline);
1439
- }
1440
- .step-timeline li:last-child {
1441
- border-bottom: 0;
1442
- }
1443
- .step-marker {
1444
- display: inline-grid;
1445
- place-items: center;
1446
- width: 16px;
1447
- height: 16px;
1448
- border: 1px solid var(--hairline-strong);
1449
- border-radius: 50%;
1450
- color: var(--muted);
1451
- font-size: 10px;
1452
- }
1453
- .step-marker.succeeded {
1454
- border-color: var(--green);
1455
- color: var(--green);
1456
- }
1457
- .step-marker.running {
1458
- border-color: var(--orange);
1459
- color: var(--orange-active);
1460
- }
1461
- .step-marker.failed {
1462
- border-color: var(--red);
1463
- color: var(--red);
1464
- }
1465
- .step-name {
1466
- min-width: 0;
1467
- color: var(--body);
1468
- font-size: 12px;
1469
- overflow-wrap: anywhere;
1470
- }
1471
- .step-duration {
1472
- color: var(--muted);
1473
- font-size: 11px;
1474
- font-variant-numeric: tabular-nums;
1475
- }
1476
-
1477
- .output-block {
1478
- max-height: 480px;
1479
- margin: 0;
1480
- padding: var(--space-4);
1481
- overflow: auto;
1482
- border: 1px solid var(--hairline);
1483
- border-radius: var(--radius-sm);
1484
- background: var(--surface-ink);
1485
- color: #f8f7f2;
1486
- font-size: 12px;
1487
- line-height: 1.7;
1488
- white-space: pre-wrap;
1489
- overflow-wrap: anywhere;
1490
- }
1491
-
1492
- .artifact-list {
1493
- display: grid;
1494
- gap: 8px;
1495
- margin: 0;
1496
- padding: 0;
1497
- list-style: none;
1498
- }
1499
- .artifact-list li {
1500
- min-width: 0;
1501
- }
1502
- .artifact-list a {
1503
- color: var(--body);
1504
- font-size: 12px;
1505
- overflow-wrap: anywhere;
1506
- }
1507
- .artifact-links {
1508
- display: flex;
1509
- flex-wrap: wrap;
1510
- gap: 6px;
1511
- }
1512
- .muted {
1513
- color: var(--muted);
1514
- }
1515
-
1516
- .dag-run-timeline {
1517
- position: relative;
1518
- display: grid;
1519
- gap: 0;
1520
- }
1521
- .dag-run-timeline::before {
1522
- position: absolute;
1523
- top: 12px;
1524
- bottom: 12px;
1525
- left: 10px;
1526
- width: 1px;
1527
- background: var(--hairline-strong);
1528
- content: "";
1529
- }
1530
- .dag-run-timeline-item {
1531
- position: relative;
1532
- display: grid;
1533
- grid-template-columns: 24px minmax(0, 1fr) auto;
1534
- gap: var(--space-3);
1535
- align-items: start;
1536
- padding: 9px 0;
1537
- color: inherit;
1538
- text-decoration: none;
1539
- transition: background-color var(--transition-fast);
1540
- }
1541
- .dag-run-timeline-item:hover,
1542
- .dag-run-timeline-item:focus-visible {
1543
- margin-inline: -8px;
1544
- padding-inline: 8px;
1545
- background: #fff8f4;
1546
- outline: none;
1547
- }
1548
- .dag-run-timeline-rail {
1549
- position: relative;
1550
- display: grid;
1551
- place-items: center;
1552
- min-height: 24px;
1553
- }
1554
- .dag-run-timeline-dot {
1555
- position: relative;
1556
- z-index: 1;
1557
- width: 9px;
1558
- height: 9px;
1559
- border: 2px solid var(--surface);
1560
- border-radius: 50%;
1561
- background: var(--muted-soft);
1562
- }
1563
- .dag-run-timeline-dot.status-finished,
1564
- .dag-run-timeline-dot.status-succeeded,
1565
- .dag-run-timeline-dot.status-completed {
1566
- background: var(--green);
1567
- }
1568
- .dag-run-timeline-dot.status-failed,
1569
- .dag-run-timeline-dot.status-error,
1570
- .dag-run-timeline-dot.status-partial_failed {
1571
- background: var(--red);
1572
- }
1573
- .dag-run-timeline-dot.status-running,
1574
- .dag-run-timeline-dot.status-started {
1575
- background: var(--orange);
1576
- }
1577
- .dag-run-timeline-content {
1578
- display: grid;
1579
- gap: 3px;
1580
- min-width: 0;
1581
- }
1582
- .dag-run-timeline-title {
1583
- color: var(--ink);
1584
- font-size: 13px;
1585
- font-weight: 700;
1586
- overflow-wrap: anywhere;
1587
- }
1588
- .dag-run-timeline-meta {
1589
- color: var(--muted);
1590
- font-size: 11px;
1591
- overflow-wrap: anywhere;
1592
- }
1593
- .dag-run-timeline-status {
1594
- padding-top: 1px;
1595
- }
1596
-
1597
- #failures-list .row-failed td:first-child,
1598
- #failures-list .row-blocked td:first-child {
1599
- color: var(--red);
1600
- font-weight: 700;
1601
- }
1602
-
1603
- @media (max-width: 1320px) {
1604
- .kpi-grid {
1605
- grid-template-columns: repeat(3, minmax(0, 1fr));
1606
- }
1607
- .kpi-card:nth-child(4) {
1608
- border-left: 0;
1609
- }
1610
- .kpi-card:nth-child(n + 4) {
1611
- border-top: 1px solid var(--hairline);
1612
- }
1613
- .dashboard-workspace {
1614
- grid-template-columns: 1fr;
1615
- }
1616
- .run-detail-workspace {
1617
- grid-template-columns: minmax(200px, 0.45fr) minmax(0, 1fr);
1618
- }
1619
- .panel-artifacts {
1620
- grid-column: 1 / -1;
1621
- }
1622
- }
1623
-
1624
- @media (max-width: 1080px) {
1625
- #app {
1626
- width: min(100% - 32px, 1680px);
1627
- }
1628
- .site-header {
1629
- grid-template-columns: auto auto 1fr;
1630
- grid-template-areas: "brand nav status" "crumb crumb crumb";
1631
- row-gap: 8px;
1632
- }
1633
- .run-detail-workspace {
1634
- grid-template-columns: 1fr;
1635
- }
1636
- .panel-artifacts {
1637
- grid-column: auto;
1638
- }
1639
- }
1640
-
1641
- @media (max-width: 720px) {
1642
- #app {
1643
- width: min(100% - 24px, 1680px);
1644
- }
1645
- .site-header {
1646
- margin-bottom: var(--space-6);
1647
- }
1648
- .kpi-grid {
1649
- grid-template-columns: repeat(2, minmax(0, 1fr));
1650
- }
1651
- .kpi-card:nth-child(n) {
1652
- border-top: 1px solid var(--hairline);
1653
- border-left: 1px solid var(--hairline);
1654
- }
1655
- .kpi-card:nth-child(1),
1656
- .kpi-card:nth-child(2) {
1657
- border-top: 0;
1658
- }
1659
- .kpi-card:nth-child(odd) {
1660
- border-left: 0;
1661
- }
1662
- .dag-inspector {
1663
- top: 76px;
1664
- right: 12px;
1665
- bottom: 12px;
1666
- width: calc(100vw - 24px);
1667
- }
1668
- .dag-inspector-resize-handle {
1669
- display: none;
1670
- }
1671
- .dashboard-secondary {
1672
- grid-template-columns: 1fr;
1673
- }
1674
- .risk-block {
1675
- grid-template-columns: 1fr;
1676
- gap: var(--space-2);
1677
- }
1678
- .panel {
1679
- padding: var(--space-4);
1680
- }
1681
- .panel-table {
1682
- overflow-x: auto;
1683
- padding: 0;
1684
- }
1685
- table {
1686
- min-width: 680px;
1687
- }
1688
- .view h2 {
1689
- font-size: 24px;
1690
- }
1691
- }
1692
-
1693
- /* R3: object relation bar + recommended commands (copy-only) */
1694
- .object-relations-panel {
1695
- padding: var(--space-3) var(--space-4);
1696
- }
1697
-
1698
- .object-relation-bar {
1699
- display: flex;
1700
- flex-wrap: wrap;
1701
- align-items: center;
1702
- gap: var(--space-2);
1703
- font-size: 0.9rem;
1704
- }
1705
-
1706
- .object-relation-item {
1707
- display: inline-flex;
1708
- align-items: baseline;
1709
- gap: 0.25rem;
1710
- }
1711
-
1712
- .object-relation-label {
1713
- color: var(--muted, #6b6560);
1714
- font-weight: 600;
1715
- font-size: 0.75rem;
1716
- text-transform: uppercase;
1717
- letter-spacing: 0.04em;
1718
- }
1719
-
1720
- .object-relation-sep {
1721
- color: var(--muted, #6b6560);
1722
- opacity: 0.7;
1723
- user-select: none;
1724
- }
1725
-
1726
- .object-link {
1727
- color: var(--accent, #8a5a2b);
1728
- text-decoration: none;
1729
- word-break: break-all;
1730
- }
1731
-
1732
- .object-link:hover,
1733
- .object-link:focus-visible {
1734
- text-decoration: underline;
1735
- }
1736
-
1737
- .recommended-command {
1738
- border: 1px solid var(--border, #e2ddd4);
1739
- border-radius: 8px;
1740
- padding: var(--space-3);
1741
- margin: var(--space-2) 0;
1742
- background: #fbf9f4;
1743
- }
1744
-
1745
- .recommended-command-head {
1746
- display: flex;
1747
- flex-wrap: wrap;
1748
- gap: var(--space-2);
1749
- align-items: baseline;
1750
- margin-bottom: var(--space-2);
1751
- }
1752
-
1753
- .recommended-command-kind {
1754
- font-size: 0.75rem;
1755
- font-weight: 600;
1756
- color: var(--muted, #6b6560);
1757
- text-transform: uppercase;
1758
- }
1759
-
1760
- .recommended-command-label {
1761
- font-weight: 600;
1762
- }
1763
-
1764
- .recommended-command-body {
1765
- display: flex;
1766
- flex-wrap: wrap;
1767
- align-items: center;
1768
- gap: var(--space-2);
1769
- }
1770
-
1771
- .recommended-command-text {
1772
- flex: 1 1 12rem;
1773
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
1774
- font-size: 0.85rem;
1775
- word-break: break-all;
1776
- background: #f0ebe3;
1777
- padding: 0.35rem 0.5rem;
1778
- border-radius: 4px;
1779
- }
1780
-
1781
- button.copy-command {
1782
- appearance: none;
1783
- border: 1px solid var(--border, #d4cdc2);
1784
- background: #fff;
1785
- border-radius: 6px;
1786
- padding: 0.35rem 0.75rem;
1787
- cursor: pointer;
1788
- font-size: 0.85rem;
1789
- }
1790
-
1791
- button.copy-command:hover,
1792
- button.copy-command:focus-visible {
1793
- border-color: var(--accent, #8a5a2b);
1794
- }
1795
-
1796
- .executed-facts {
1797
- border-left: 3px solid #6b8f71;
1798
- }
1799
-
1800
- .advisory-note {
1801
- margin: 0 0 var(--space-2);
1802
- font-size: 0.85rem;
1803
- }
1804
-
1805
- .blocking-list {
1806
- margin: 0;
1807
- padding-left: 1.25rem;
1808
- }
1809
-
1810
- .blocking-message {
1811
- font-weight: 500;
1812
- }
1813
-
1814
- .blocking-meta {
1815
- font-size: 0.85rem;
1816
- color: var(--muted, #6b6560);
1817
- margin: 0.15rem 0 0.35rem;
1818
- }
1819
-
1820
-
1821
-
1822
- /* R5: unified view states + information hierarchy */
1823
- .view-state {
1824
- border-radius: var(--radius, 8px);
1825
- padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
1826
- margin: 0 0 var(--space-3, 0.75rem);
1827
- }
1828
- .view-state-loading {
1829
- border: 1px dashed var(--border, #e2dcd4);
1830
- background: var(--surface-muted, #f7f4ef);
1831
- color: var(--muted, #6b6560);
1832
- }
1833
- .view-state-empty {
1834
- border: 1px solid var(--border, #e2dcd4);
1835
- background: var(--surface, #fffdf9);
1836
- }
1837
- .view-state-degraded {
1838
- /* projection-fault styles also apply */
1839
- }
1840
- .view-state-error {
1841
- border: 1px solid var(--danger-border, #e8b4b4);
1842
- background: var(--danger-bg, #fdf2f2);
1843
- color: var(--danger-text, #8a2f2f);
1844
- }
1845
- .view-state-error p {
1846
- margin: 0;
1847
- }
1848
- .layer-primary {
1849
- /* main facts */
1850
- }
1851
- .layer-diagnostic {
1852
- opacity: 0.98;
1853
- }
1854
- .layer-raw {
1855
- font-size: 0.9rem;
1856
- color: var(--muted, #6b6560);
1857
- }
1858
- .pool-filters {
1859
- display: flex;
1860
- flex-wrap: wrap;
1861
- gap: 0.5rem 0.75rem;
1862
- align-items: center;
1863
- margin: 0 0 var(--space-3, 0.75rem);
1864
- }
1865
- .pool-filters label {
1866
- display: inline-flex;
1867
- align-items: center;
1868
- gap: 0.35rem;
1869
- font-size: 0.9rem;
1870
- }
1871
- .pool-filters select,
1872
- .pool-filters input[type="search"] {
1873
- font: inherit;
1874
- padding: 0.25rem 0.5rem;
1875
- border: 1px solid var(--border, #e2dcd4);
1876
- border-radius: 6px;
1877
- background: var(--surface, #fff);
1878
- min-height: 2rem;
1879
- }
1880
- .pool-filters select:focus-visible,
1881
- .pool-filters input[type="search"]:focus-visible {
1882
- outline: 2px solid var(--focus, #3d6bf3);
1883
- outline-offset: 2px;
1884
- }
1885
-
1886
- @media (max-width: 1024px) {
1887
- .pool-filters {
1888
- flex-direction: column;
1889
- align-items: stretch;
1890
- }
1891
- }
1892
-
1893
- @media (prefers-reduced-motion: reduce) {
1894
- *,
1895
- *::before,
1896
- *::after {
1897
- animation-duration: 0.01ms !important;
1898
- animation-iteration-count: 1 !important;
1899
- scroll-behavior: auto !important;
1900
- transition-duration: 0.01ms !important;
1901
- }
1902
- }
1
+ :root {
2
+ --canvas: #f7f7f4;
3
+ --canvas-soft: #fafaf7;
4
+ --surface: #ffffff;
5
+ --surface-muted: #f0efe9;
6
+ --surface-ink: #26251e;
7
+ --ink: #26251e;
8
+ --body: #5a5852;
9
+ --muted: #807d72;
10
+ --muted-soft: #a09c92;
11
+ --hairline: #e6e5e0;
12
+ --hairline-strong: #cfcdc4;
13
+ --orange: #f54e00;
14
+ --orange-active: #d04200;
15
+ --blue: #3f6ea4;
16
+ --green: #1f8a65;
17
+ --amber: #a66a00;
18
+ --red: #c72d53;
19
+ --lavender: #e4daf1;
20
+ --mint: #d8ead5;
21
+ --peach: #f1d8cb;
22
+ --gold: #d8b166;
23
+ --space-1: 4px;
24
+ --space-2: 8px;
25
+ --space-3: 12px;
26
+ --space-4: 16px;
27
+ --space-5: 20px;
28
+ --space-6: 24px;
29
+ --space-8: 32px;
30
+ --space-10: 40px;
31
+ --space-12: 48px;
32
+ --radius-sm: 4px;
33
+ --radius-md: 6px;
34
+ --radius-lg: 8px;
35
+ --transition-fast: 160ms ease;
36
+ --transition-base: 240ms ease;
37
+ }
38
+
39
+ * {
40
+ box-sizing: border-box;
41
+ }
42
+
43
+ html {
44
+ background: var(--canvas);
45
+ scroll-behavior: smooth;
46
+ }
47
+
48
+ body {
49
+ min-width: 320px;
50
+ margin: 0;
51
+ background: var(--canvas);
52
+ color: var(--ink);
53
+ font-family:
54
+ system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
55
+ font-size: 14px;
56
+ line-height: 1.5;
57
+ }
58
+
59
+ button,
60
+ input,
61
+ select,
62
+ textarea {
63
+ font: inherit;
64
+ }
65
+
66
+ a {
67
+ color: inherit;
68
+ }
69
+
70
+ code,
71
+ pre,
72
+ .output-block,
73
+ .rank-node-id,
74
+ .dag-node-label,
75
+ .dag-node-meta,
76
+ .dag-node-status,
77
+ td:first-child,
78
+ .meta-item dd,
79
+ .header-refresh,
80
+ .kpi-value,
81
+ .risk-total,
82
+ .process-timeline-time {
83
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
84
+ }
85
+
86
+ .skip-link {
87
+ position: fixed;
88
+ top: -64px;
89
+ left: var(--space-4);
90
+ z-index: 100;
91
+ padding: 9px 12px;
92
+ background: var(--orange);
93
+ color: #fff;
94
+ font-weight: 700;
95
+ text-decoration: none;
96
+ transition: top var(--transition-fast);
97
+ }
98
+
99
+ .skip-link:focus {
100
+ top: var(--space-3);
101
+ }
102
+
103
+ #app {
104
+ width: min(100% - 48px, 1680px);
105
+ margin: 0 auto;
106
+ padding-bottom: 56px;
107
+ }
108
+
109
+ .site-header {
110
+ position: sticky;
111
+ top: 0;
112
+ z-index: 30;
113
+ display: grid;
114
+ grid-template-columns: auto auto 1fr;
115
+ grid-template-areas: "brand nav status" "crumb crumb crumb";
116
+ column-gap: var(--space-6);
117
+ align-items: center;
118
+ min-height: 76px;
119
+ margin-bottom: var(--space-8);
120
+ padding: 14px 0 12px;
121
+ background: color-mix(in srgb, var(--canvas) 94%, transparent);
122
+ border-bottom: 1px solid var(--hairline);
123
+ backdrop-filter: blur(10px);
124
+ }
125
+
126
+ .logo {
127
+ grid-area: brand;
128
+ display: inline-flex;
129
+ align-items: center;
130
+ gap: 9px;
131
+ color: var(--ink);
132
+ font-size: 16px;
133
+ font-weight: 650;
134
+ letter-spacing: 0;
135
+ text-decoration: none;
136
+ }
137
+
138
+ .logo > i {
139
+ color: var(--orange);
140
+ font-size: 20px;
141
+ font-weight: 400;
142
+ }
143
+ .logo:hover {
144
+ color: var(--orange-active);
145
+ }
146
+
147
+ .top-nav {
148
+ grid-area: nav;
149
+ display: inline-flex;
150
+ align-items: center;
151
+ gap: 4px;
152
+ }
153
+
154
+ .nav-link {
155
+ display: inline-flex;
156
+ align-items: center;
157
+ gap: 7px;
158
+ min-height: 36px;
159
+ padding: 0 10px;
160
+ border: 1px solid transparent;
161
+ border-radius: var(--radius-sm);
162
+ color: var(--body);
163
+ font-size: 13px;
164
+ font-weight: 600;
165
+ text-decoration: none;
166
+ transition:
167
+ border-color var(--transition-fast),
168
+ background-color var(--transition-fast),
169
+ color var(--transition-fast);
170
+ }
171
+
172
+ .nav-link > i {
173
+ font-size: 16px;
174
+ font-weight: 400;
175
+ }
176
+ .nav-link:hover,
177
+ .nav-link:focus-visible {
178
+ border-color: var(--hairline-strong);
179
+ background: var(--surface);
180
+ color: var(--ink);
181
+ outline: none;
182
+ }
183
+ .nav-link-active {
184
+ border-color: var(--orange);
185
+ background: var(--surface);
186
+ color: var(--ink);
187
+ }
188
+
189
+ .header-meta {
190
+ grid-area: status;
191
+ display: inline-flex;
192
+ justify-self: end;
193
+ align-items: center;
194
+ gap: 7px;
195
+ color: var(--muted);
196
+ font-size: 12px;
197
+ font-variant-numeric: tabular-nums;
198
+ }
199
+
200
+ .header-meta > i {
201
+ color: var(--green);
202
+ font-size: 16px;
203
+ }
204
+
205
+ .breadcrumb {
206
+ grid-area: crumb;
207
+ display: flex;
208
+ min-height: 16px;
209
+ gap: 7px;
210
+ color: var(--muted);
211
+ font-size: 12px;
212
+ }
213
+
214
+ .breadcrumb[hidden] {
215
+ display: none;
216
+ }
217
+
218
+ .breadcrumb a {
219
+ color: var(--body);
220
+ text-decoration: none;
221
+ }
222
+ .breadcrumb a:hover,
223
+ .breadcrumb a:focus-visible {
224
+ color: var(--orange);
225
+ text-decoration: underline;
226
+ outline: none;
227
+ }
228
+
229
+ .dashboard-main:focus {
230
+ outline: none;
231
+ }
232
+ .view {
233
+ min-width: 0;
234
+ }
235
+ .view[hidden] {
236
+ display: none !important;
237
+ }
238
+ .view:not(.view-dashboard) {
239
+ display: grid;
240
+ gap: var(--space-4);
241
+ }
242
+
243
+ .view-heading {
244
+ display: grid;
245
+ gap: 4px;
246
+ margin-bottom: var(--space-6);
247
+ }
248
+
249
+ .view-kicker {
250
+ margin: 0;
251
+ color: var(--orange);
252
+ font-size: 11px;
253
+ font-weight: 700;
254
+ letter-spacing: 0.08em;
255
+ }
256
+
257
+ .view h2 {
258
+ margin: 0;
259
+ color: var(--ink);
260
+ font-size: 28px;
261
+ font-weight: 500;
262
+ line-height: 1.16;
263
+ letter-spacing: 0;
264
+ }
265
+
266
+ .view-heading > p:last-child {
267
+ max-width: 66ch;
268
+ margin: 0;
269
+ color: var(--body);
270
+ }
271
+
272
+ .panel {
273
+ min-width: 0;
274
+ background: var(--surface);
275
+ border: 1px solid var(--hairline);
276
+ border-radius: var(--radius-lg);
277
+ padding: var(--space-5);
278
+ }
279
+
280
+ .panel-primary {
281
+ border-color: var(--hairline-strong);
282
+ box-shadow: var(--shadow-panel);
283
+ }
284
+ .panel-features {
285
+ background: var(--canvas-soft);
286
+ border-color: var(--hairline);
287
+ }
288
+ .panel-meta {
289
+ background: transparent;
290
+ border-color: var(--hairline-strong);
291
+ }
292
+ .panel-table {
293
+ overflow: hidden;
294
+ padding: 0;
295
+ }
296
+ .panel-output {
297
+ background: #fbfbf9;
298
+ }
299
+
300
+ .section-heading,
301
+ .panel h3 {
302
+ margin: 0 0 var(--space-4);
303
+ color: var(--ink);
304
+ font-size: 14px;
305
+ font-weight: 700;
306
+ }
307
+
308
+ .empty,
309
+ .risk-empty {
310
+ margin: 0;
311
+ color: var(--muted);
312
+ }
313
+ .empty-state {
314
+ padding: var(--space-8);
315
+ text-align: center;
316
+ color: var(--body);
317
+ }
318
+
319
+ .view-dashboard {
320
+ --dashboard-cols: minmax(0, 1.65fr) minmax(280px, 0.85fr);
321
+ /* Secondary: timeline + batch table — more even, batch side slightly wider. */
322
+ --dashboard-secondary-cols: minmax(0, 1fr) minmax(0, 1.2fr);
323
+ --dashboard-gap: var(--space-4);
324
+ display: grid;
325
+ gap: var(--space-4);
326
+ }
327
+
328
+ .view-pool {
329
+ display: grid;
330
+ gap: var(--space-4);
331
+ }
332
+ .page-header,
333
+ .pool-page-header,
334
+ .dashboard-page-header {
335
+ display: grid;
336
+ grid-template-columns: minmax(0, 1fr) auto;
337
+ gap: var(--space-4) var(--space-6);
338
+ align-items: start;
339
+ padding-bottom: var(--space-4);
340
+ border-bottom: 1px solid var(--hairline);
341
+ }
342
+ .page-header-heading,
343
+ .view-dashboard .page-header-heading,
344
+ .view-pool .page-header-heading {
345
+ margin-bottom: 0;
346
+ }
347
+ .pool-toolbar {
348
+ display: grid;
349
+ justify-items: end;
350
+ gap: 8px;
351
+ padding-top: 2px;
352
+ }
353
+ .pool-toolbar-actions {
354
+ display: flex;
355
+ flex-wrap: wrap;
356
+ align-items: center;
357
+ justify-content: flex-end;
358
+ gap: 10px 12px;
359
+ }
360
+ .pool-toolbar .pool-updated-at {
361
+ margin: 0;
362
+ max-width: 28ch;
363
+ font-size: 11px;
364
+ line-height: 1.4;
365
+ text-align: right;
366
+ }
367
+ .pool-refresh-btn {
368
+ appearance: none;
369
+ border: 1px solid var(--hairline-strong);
370
+ border-radius: var(--radius-md);
371
+ background: var(--surface);
372
+ color: var(--ink);
373
+ font-size: 13px;
374
+ font-weight: 700;
375
+ padding: 8px 14px;
376
+ cursor: pointer;
377
+ }
378
+ .pool-refresh-btn:hover {
379
+ border-color: var(--orange);
380
+ color: var(--orange-active);
381
+ }
382
+ .pool-auto-refresh-label {
383
+ display: inline-flex;
384
+ align-items: center;
385
+ gap: 6px;
386
+ color: var(--body);
387
+ font-size: 13px;
388
+ cursor: pointer;
389
+ }
390
+ .pool-workspace {
391
+ display: grid;
392
+ grid-template-columns: repeat(2, minmax(0, 1fr));
393
+ gap: var(--space-4);
394
+ align-items: start;
395
+ }
396
+ .pool-ops-list {
397
+ display: grid;
398
+ gap: 10px;
399
+ }
400
+ .pool-ops-card {
401
+ padding: 12px 14px;
402
+ border: 1px solid var(--hairline);
403
+ border-radius: var(--radius-md);
404
+ background: var(--canvas-soft);
405
+ border-left: 3px solid var(--hairline-strong);
406
+ }
407
+ .pool-ops-card-attention {
408
+ border-left-color: var(--red);
409
+ border-color: color-mix(in srgb, var(--red) 35%, var(--hairline));
410
+ background: #fff8f9;
411
+ }
412
+ .pool-ops-card-ready {
413
+ border-left-color: var(--orange);
414
+ background: #fffaf5;
415
+ }
416
+ .pool-ops-card-title {
417
+ margin-bottom: 6px;
418
+ font-size: 14px;
419
+ font-weight: 700;
420
+ }
421
+ .pool-ops-card-meta {
422
+ display: flex;
423
+ flex-wrap: wrap;
424
+ align-items: center;
425
+ gap: 8px;
426
+ color: var(--muted);
427
+ font-size: 12px;
428
+ }
429
+ .pool-ops-card-detail {
430
+ margin: 8px 0 0;
431
+ color: var(--body);
432
+ font-size: 12px;
433
+ line-height: 1.5;
434
+ }
435
+ .pool-filters {
436
+ display: block;
437
+ }
438
+ .pool-filters-inner {
439
+ display: flex;
440
+ flex-wrap: wrap;
441
+ align-items: end;
442
+ gap: var(--space-3);
443
+ }
444
+ .pool-filters-inner label {
445
+ display: grid;
446
+ gap: 4px;
447
+ color: var(--muted);
448
+ font-size: 11px;
449
+ font-weight: 700;
450
+ }
451
+ .pool-filters-inner select,
452
+ .pool-filters-inner input[type="search"] {
453
+ min-width: 160px;
454
+ padding: 7px 10px;
455
+ border: 1px solid var(--hairline);
456
+ border-radius: var(--radius-md);
457
+ background: var(--surface);
458
+ color: var(--ink);
459
+ font-size: 13px;
460
+ }
461
+ .pool-table-wrap {
462
+ overflow-x: auto;
463
+ }
464
+ .pool-ref-links {
465
+ display: inline;
466
+ font-size: 12px;
467
+ overflow-wrap: anywhere;
468
+ }
469
+ .pool-events-details {
470
+ border: 1px solid var(--hairline);
471
+ border-radius: var(--radius-lg);
472
+ background: var(--surface);
473
+ padding: 0 var(--space-5) var(--space-4);
474
+ }
475
+ .pool-events-details > summary {
476
+ cursor: pointer;
477
+ padding: var(--space-4) 0;
478
+ color: var(--ink);
479
+ font-size: 14px;
480
+ font-weight: 700;
481
+ }
482
+ .pool-events-details > summary:hover {
483
+ color: var(--orange-active);
484
+ }
485
+ .pool-events-details .panel-timeline {
486
+ border: 0;
487
+ padding: 0;
488
+ box-shadow: none;
489
+ }
490
+ #pool-kpi.panel-kpi {
491
+ display: grid;
492
+ grid-template-columns: 1fr;
493
+ gap: var(--space-2);
494
+ }
495
+ #pool-kpi .section-heading {
496
+ margin: 0;
497
+ }
498
+ .pool-fault-active {
499
+ display: grid;
500
+ gap: var(--space-3);
501
+ }
502
+
503
+ .repo-banner {
504
+ display: flex;
505
+ align-items: flex-start;
506
+ gap: 10px;
507
+ padding: 6px 12px;
508
+ border: 1px solid var(--hairline);
509
+ border-radius: var(--radius-md);
510
+ background: transparent;
511
+ }
512
+ .repo-banner-inline {
513
+ justify-self: end;
514
+ align-items: center;
515
+ max-width: min(48ch, 100%);
516
+ padding: 4px 10px 4px 8px;
517
+ border: 1px solid var(--hairline);
518
+ border-radius: 999px;
519
+ background: var(--canvas-soft);
520
+ }
521
+ .repo-banner-icon {
522
+ display: inline-flex;
523
+ align-items: center;
524
+ justify-content: center;
525
+ flex: 0 0 auto;
526
+ width: 28px;
527
+ height: 28px;
528
+ border-radius: 8px;
529
+ background: var(--surface);
530
+ border: 1px solid var(--hairline);
531
+ color: var(--orange-active);
532
+ }
533
+ .repo-banner-icon > i {
534
+ font-size: 15px;
535
+ line-height: 1;
536
+ }
537
+ .repo-banner-inline .repo-banner-text {
538
+ display: grid;
539
+ justify-items: start;
540
+ gap: 1px;
541
+ min-width: 0;
542
+ }
543
+ .repo-banner-text {
544
+ display: flex;
545
+ flex-wrap: wrap;
546
+ align-items: baseline;
547
+ gap: 6px 10px;
548
+ min-width: 0;
549
+ }
550
+ .repo-banner-name {
551
+ color: var(--ink);
552
+ font-size: 13px;
553
+ font-weight: 700;
554
+ letter-spacing: 0.01em;
555
+ line-height: 1.25;
556
+ overflow: hidden;
557
+ text-overflow: ellipsis;
558
+ white-space: nowrap;
559
+ }
560
+ .repo-banner-path {
561
+ color: var(--muted);
562
+ font-size: 11px;
563
+ line-height: 1.35;
564
+ font-variant-numeric: tabular-nums;
565
+ letter-spacing: 0.01em;
566
+ overflow: hidden;
567
+ text-overflow: ellipsis;
568
+ white-space: nowrap;
569
+ max-width: 36ch;
570
+ }
571
+
572
+ .panel-kpi {
573
+ display: grid;
574
+ grid-template-columns: var(--dashboard-cols);
575
+ gap: var(--space-2) var(--dashboard-gap);
576
+ align-items: stretch;
577
+ padding: 0;
578
+ background: transparent;
579
+ border: 0;
580
+ }
581
+
582
+ .kpi-group {
583
+ margin: 0;
584
+ padding: 0;
585
+ border: 0;
586
+ min-width: 0;
587
+ display: grid;
588
+ grid-template-rows: auto 1fr;
589
+ gap: var(--space-2);
590
+ }
591
+ .kpi-group + .kpi-group {
592
+ margin-top: 0;
593
+ }
594
+ .kpi-group-legend {
595
+ padding: 0;
596
+ color: var(--muted);
597
+ font-size: 11px;
598
+ font-weight: 700;
599
+ letter-spacing: 0.04em;
600
+ text-transform: uppercase;
601
+ }
602
+
603
+ .kpi-grid {
604
+ display: grid;
605
+ grid-template-columns: repeat(5, minmax(0, 1fr));
606
+ overflow: visible;
607
+ border: 1px solid var(--hairline);
608
+ border-radius: var(--radius-md);
609
+ background: var(--surface);
610
+ height: 100%;
611
+ }
612
+
613
+ /* Must follow .kpi-grid so display:flex wins over display:grid. */
614
+ .kpi-grid.pool-health-grid {
615
+ display: flex;
616
+ flex-wrap: nowrap;
617
+ align-items: stretch;
618
+ overflow-x: auto;
619
+ height: auto;
620
+ grid-template-columns: none;
621
+ }
622
+ .kpi-grid.pool-health-grid .kpi-card {
623
+ flex: 1 1 0;
624
+ min-width: 96px;
625
+ display: flex;
626
+ flex-direction: row;
627
+ flex-wrap: nowrap;
628
+ align-items: baseline;
629
+ justify-content: flex-start;
630
+ gap: 8px;
631
+ padding: 8px 12px;
632
+ border-top: 0;
633
+ border-left: 1px solid var(--hairline);
634
+ }
635
+ .kpi-grid.pool-health-grid .kpi-card:first-child {
636
+ border-left: 0;
637
+ }
638
+ .kpi-grid.pool-health-grid .kpi-value {
639
+ font-size: 18px;
640
+ line-height: 1.1;
641
+ }
642
+ .kpi-grid.pool-health-grid .kpi-label {
643
+ margin: 0;
644
+ font-size: 11px;
645
+ font-weight: 650;
646
+ color: var(--muted);
647
+ white-space: nowrap;
648
+ }
649
+
650
+ .kpi-card {
651
+ position: relative;
652
+ min-width: 0;
653
+ min-height: 0;
654
+ padding: 10px 12px 9px;
655
+ border-left: 1px solid var(--hairline);
656
+ }
657
+
658
+ .kpi-card:first-child {
659
+ border-left: 0;
660
+ }
661
+ .kpi-label {
662
+ margin-bottom: 4px;
663
+ color: var(--muted);
664
+ font-size: 10px;
665
+ font-weight: 650;
666
+ }
667
+ .kpi-value-row {
668
+ display: flex;
669
+ align-items: flex-start;
670
+ gap: 6px;
671
+ }
672
+ .kpi-value {
673
+ color: var(--ink);
674
+ font-size: 22px;
675
+ font-weight: 500;
676
+ line-height: 1;
677
+ font-variant-numeric: tabular-nums;
678
+ }
679
+ .kpi-card.kpi-highlight .kpi-value {
680
+ color: var(--orange-active);
681
+ }
682
+ .kpi-card.kpi-muted .kpi-value {
683
+ color: var(--muted);
684
+ }
685
+ .kpi-card.kpi-risk .kpi-value {
686
+ color: var(--amber);
687
+ }
688
+ .kpi-card.kpi-danger .kpi-value {
689
+ color: var(--red);
690
+ }
691
+ .kpi-value-with-link {
692
+ display: flex;
693
+ flex-direction: column;
694
+ align-items: flex-start;
695
+ gap: 2px;
696
+ }
697
+ .kpi-value-with-link .kpi-value-num {
698
+ font-variant-numeric: tabular-nums;
699
+ }
700
+ .kpi-value-with-link .inbox-link {
701
+ font-size: 10px;
702
+ font-weight: 650;
703
+ line-height: 1.2;
704
+ text-underline-offset: 2px;
705
+ }
706
+
707
+ .kpi-help {
708
+ display: inline-flex;
709
+ align-items: center;
710
+ justify-content: center;
711
+ width: 16px;
712
+ height: 16px;
713
+ padding: 0;
714
+ border: 0;
715
+ border-radius: 50%;
716
+ background: transparent;
717
+ color: var(--muted-soft);
718
+ cursor: help;
719
+ font-size: 13px;
720
+ line-height: 1;
721
+ }
722
+ .kpi-help:hover,
723
+ .kpi-help:focus-visible {
724
+ color: var(--ink);
725
+ background: var(--surface-muted);
726
+ outline: none;
727
+ }
728
+ .kpi-help:focus-visible {
729
+ box-shadow: 0 0 0 2px var(--hairline-strong);
730
+ }
731
+ .kpi-tip {
732
+ position: absolute;
733
+ left: 12px;
734
+ right: 12px;
735
+ top: calc(100% - 8px);
736
+ z-index: 10;
737
+ max-width: 280px;
738
+ padding: 8px 10px;
739
+ border: 1px solid var(--hairline-strong);
740
+ border-radius: var(--radius-md);
741
+ background: var(--surface-ink);
742
+ color: var(--canvas);
743
+ font-size: 11px;
744
+ font-weight: 400;
745
+ line-height: 1.5;
746
+ box-shadow: var(--shadow-panel);
747
+ opacity: 0;
748
+ visibility: hidden;
749
+ pointer-events: none;
750
+ transition: opacity var(--transition-fast);
751
+ }
752
+ .kpi-help:hover + .kpi-tip,
753
+ .kpi-help:focus-visible + .kpi-tip {
754
+ opacity: 1;
755
+ visibility: visible;
756
+ }
757
+
758
+ .dashboard-workspace,
759
+ .dashboard-secondary {
760
+ display: grid;
761
+ gap: var(--dashboard-gap);
762
+ align-items: start;
763
+ }
764
+
765
+ .dashboard-workspace {
766
+ grid-template-columns: var(--dashboard-cols);
767
+ }
768
+ .dashboard-secondary {
769
+ grid-template-columns: var(--dashboard-secondary-cols);
770
+ }
771
+ #dashboard-batches {
772
+ min-width: 0;
773
+ overflow-x: auto;
774
+ }
775
+ #dashboard-batches table {
776
+ width: 100%;
777
+ min-width: 0;
778
+ }
779
+ #dashboard-batches th,
780
+ #dashboard-batches td {
781
+ white-space: nowrap;
782
+ }
783
+ #dashboard-batches td:last-child {
784
+ white-space: normal;
785
+ min-width: 12rem;
786
+ }
787
+
788
+ .panel-primary,
789
+ .panel-risk {
790
+ min-width: 0;
791
+ }
792
+
793
+ .panel-risk {
794
+ display: block;
795
+ background: var(--surface);
796
+ border-color: var(--hairline-strong);
797
+ box-shadow: var(--shadow-panel);
798
+ position: sticky;
799
+ top: 16px;
800
+ }
801
+
802
+ /* Attention state stays on inner cards; outer shell matches active DAG panel. */
803
+ .panel-risk-attention {
804
+ border-color: var(--hairline-strong);
805
+ background: var(--surface);
806
+ }
807
+ .panel-risk .section-heading {
808
+ margin: 0 0 var(--space-4);
809
+ }
810
+ .risk-blocks {
811
+ display: grid;
812
+ gap: 10px;
813
+ }
814
+ .risk-block,
815
+ .risk-block-dag,
816
+ .risk-block-worker {
817
+ display: grid;
818
+ grid-template-columns: minmax(0, 1fr) auto;
819
+ grid-template-areas:
820
+ "label total"
821
+ "summary total"
822
+ "link total";
823
+ align-items: start;
824
+ column-gap: var(--space-3);
825
+ row-gap: 4px;
826
+ padding: 14px;
827
+ padding-left: 12px;
828
+ border: 1px solid color-mix(in srgb, var(--red) 35%, var(--hairline));
829
+ border-left: 3px solid var(--red);
830
+ border-radius: var(--radius-md);
831
+ background: #fff8f9;
832
+ }
833
+ .risk-block-label {
834
+ grid-area: label;
835
+ color: var(--ink);
836
+ font-size: 11px;
837
+ font-weight: 700;
838
+ letter-spacing: 0.04em;
839
+ text-transform: uppercase;
840
+ }
841
+ .risk-total {
842
+ grid-area: total;
843
+ margin: 0;
844
+ color: var(--red);
845
+ font-size: 32px;
846
+ font-weight: 500;
847
+ line-height: 1;
848
+ font-variant-numeric: tabular-nums;
849
+ align-self: center;
850
+ text-align: right;
851
+ min-width: 1.5ch;
852
+ }
853
+ .risk-summary {
854
+ grid-area: summary;
855
+ margin: 0;
856
+ color: var(--body);
857
+ font-size: 12px;
858
+ line-height: 1.6;
859
+ }
860
+ .risk-block .risk-link {
861
+ grid-area: link;
862
+ justify-self: start;
863
+ margin-top: 6px;
864
+ }
865
+ .panel-risk .risk-empty {
866
+ margin: 0;
867
+ }
868
+
869
+ .projection-fault {
870
+ display: flex;
871
+ align-items: flex-start;
872
+ gap: var(--space-3);
873
+ padding: 14px 16px;
874
+ border: 1px solid color-mix(in srgb, var(--red) 50%, var(--hairline));
875
+ border-radius: var(--radius-lg);
876
+ background: #fff8f9;
877
+ }
878
+ .projection-fault > i {
879
+ color: var(--red);
880
+ font-size: 20px;
881
+ line-height: 1.4;
882
+ }
883
+ .projection-fault-body {
884
+ display: grid;
885
+ gap: 4px;
886
+ min-width: 0;
887
+ }
888
+ .projection-fault-title {
889
+ margin: 0;
890
+ color: var(--ink);
891
+ font-size: 14px;
892
+ font-weight: 700;
893
+ }
894
+ .projection-fault-message {
895
+ margin: 0;
896
+ color: var(--body);
897
+ font-size: 12px;
898
+ overflow-wrap: anywhere;
899
+ }
900
+ .projection-fault-at {
901
+ margin: 0;
902
+ color: var(--muted);
903
+ font-size: 11px;
904
+ }
905
+
906
+ .risk-link,
907
+ .active-dag-link,
908
+ .link,
909
+ .inbox-link,
910
+ .artifact-link,
911
+ .step-link {
912
+ color: var(--ink);
913
+ font-size: 12px;
914
+ font-weight: 700;
915
+ text-decoration-color: var(--orange);
916
+ text-decoration-thickness: 1px;
917
+ text-underline-offset: 4px;
918
+ }
919
+
920
+ .risk-link {
921
+ margin: 0;
922
+ padding: 0;
923
+ white-space: nowrap;
924
+ }
925
+ .risk-link:hover,
926
+ .active-dag-link:hover,
927
+ .link:hover,
928
+ .inbox-link:hover,
929
+ .artifact-link:hover,
930
+ .step-link:hover {
931
+ color: var(--orange-active);
932
+ }
933
+
934
+ .active-dag-list {
935
+ display: grid;
936
+ gap: 10px;
937
+ }
938
+ .active-dag-card {
939
+ padding: 14px;
940
+ border: 1px solid var(--hairline);
941
+ border-radius: var(--radius-md);
942
+ background: var(--canvas-soft);
943
+ border-left: 3px solid var(--hairline-strong);
944
+ padding-left: 12px;
945
+ }
946
+ .active-dag-card-running {
947
+ border-left-color: var(--orange);
948
+ background: #fffaf5;
949
+ }
950
+ .active-dag-card-attention {
951
+ border-left-color: var(--red);
952
+ border-color: color-mix(in srgb, var(--red) 35%, var(--hairline));
953
+ background: #fff8f9;
954
+ }
955
+ .active-dag-header {
956
+ display: flex;
957
+ align-items: start;
958
+ justify-content: space-between;
959
+ gap: var(--space-3);
960
+ margin-bottom: 9px;
961
+ }
962
+ .active-dag-title {
963
+ min-width: 0;
964
+ color: var(--ink);
965
+ font-size: 14px;
966
+ font-weight: 700;
967
+ overflow-wrap: anywhere;
968
+ }
969
+ .active-dag-meta {
970
+ display: grid;
971
+ gap: 4px;
972
+ color: var(--body);
973
+ font-size: 12px;
974
+ }
975
+ .active-dag-link {
976
+ display: inline-block;
977
+ margin-top: 10px;
978
+ }
979
+
980
+ .feature-decision-list {
981
+ display: grid;
982
+ gap: 8px;
983
+ }
984
+ .feature-decision-row {
985
+ display: grid;
986
+ grid-template-columns: minmax(120px, 0.9fr) minmax(88px, 0.55fr) minmax(0, 1.6fr) auto;
987
+ align-items: center;
988
+ gap: var(--space-3);
989
+ padding: 10px 12px;
990
+ border: 1px solid var(--hairline);
991
+ border-radius: var(--radius-md);
992
+ background: var(--surface);
993
+ cursor: pointer;
994
+ }
995
+ .feature-decision-row:hover {
996
+ border-color: var(--hairline-strong);
997
+ }
998
+ .feature-decision-id {
999
+ min-width: 0;
1000
+ font-size: 13px;
1001
+ font-weight: 700;
1002
+ overflow-wrap: anywhere;
1003
+ }
1004
+ .feature-decision-status {
1005
+ color: var(--body);
1006
+ font-size: 12px;
1007
+ }
1008
+ .feature-decision-next {
1009
+ min-width: 0;
1010
+ color: var(--muted);
1011
+ font-size: 12px;
1012
+ overflow: hidden;
1013
+ text-overflow: ellipsis;
1014
+ white-space: nowrap;
1015
+ }
1016
+ .feature-decision-open {
1017
+ color: var(--ink);
1018
+ font-size: 12px;
1019
+ font-weight: 700;
1020
+ white-space: nowrap;
1021
+ }
1022
+
1023
+ .meta-grid {
1024
+ display: grid;
1025
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
1026
+ gap: 15px 24px;
1027
+ margin: 0;
1028
+ }
1029
+
1030
+ .meta-item {
1031
+ min-width: 0;
1032
+ }
1033
+ .meta-item dt {
1034
+ color: var(--muted);
1035
+ font-size: 11px;
1036
+ font-weight: 650;
1037
+ }
1038
+ .meta-item dd {
1039
+ min-height: 24px;
1040
+ margin: 4px 0 0;
1041
+ padding-top: 5px;
1042
+ border-top: 1px solid var(--hairline);
1043
+ color: var(--ink);
1044
+ overflow-wrap: anywhere;
1045
+ font-size: 12px;
1046
+ }
1047
+
1048
+ table {
1049
+ width: 100%;
1050
+ border-collapse: collapse;
1051
+ font-size: 13px;
1052
+ }
1053
+ th,
1054
+ td {
1055
+ padding: 11px 14px;
1056
+ border-bottom: 1px solid var(--hairline);
1057
+ text-align: left;
1058
+ vertical-align: top;
1059
+ }
1060
+ th {
1061
+ position: sticky;
1062
+ top: 0;
1063
+ z-index: 2;
1064
+ background: var(--surface-muted);
1065
+ color: var(--body);
1066
+ font-size: 11px;
1067
+ font-weight: 700;
1068
+ }
1069
+ td {
1070
+ color: var(--body);
1071
+ }
1072
+ tbody tr:last-child td {
1073
+ border-bottom: 0;
1074
+ }
1075
+ tbody tr {
1076
+ transition: background-color var(--transition-fast);
1077
+ }
1078
+ tbody tr:hover {
1079
+ background: #fff8f4;
1080
+ }
1081
+ tr.clickable {
1082
+ cursor: pointer;
1083
+ }
1084
+ tr.clickable:focus-within {
1085
+ outline: 2px solid var(--orange);
1086
+ outline-offset: -2px;
1087
+ }
1088
+
1089
+ .badge {
1090
+ display: inline-flex;
1091
+ align-items: center;
1092
+ min-height: 22px;
1093
+ padding: 2px 7px;
1094
+ border: 1px solid currentColor;
1095
+ border-radius: 999px;
1096
+ background: transparent;
1097
+ color: var(--muted);
1098
+ font-size: 11px;
1099
+ font-weight: 700;
1100
+ line-height: 1.2;
1101
+ white-space: nowrap;
1102
+ }
1103
+
1104
+ .badge-succeeded,
1105
+ .badge-finished,
1106
+ .badge-completed,
1107
+ .badge-done,
1108
+ .liveness-active {
1109
+ color: var(--green);
1110
+ background: #f2faf5;
1111
+ }
1112
+ .badge-failed,
1113
+ .badge-error,
1114
+ .liveness-stale {
1115
+ color: var(--red);
1116
+ background: #fff5f7;
1117
+ }
1118
+ .badge-partial-failed {
1119
+ color: #9a3a4f;
1120
+ background: #fff7f8;
1121
+ }
1122
+ .badge-running,
1123
+ .badge-started {
1124
+ color: var(--orange-active);
1125
+ background: #fff5ed;
1126
+ }
1127
+ .badge-pending,
1128
+ .badge-queued,
1129
+ .badge-blocked,
1130
+ .badge-unknown {
1131
+ color: var(--body);
1132
+ background: var(--surface-muted);
1133
+ }
1134
+ .badge-skipped,
1135
+ .badge-reused,
1136
+ .liveness-quiet {
1137
+ color: var(--blue);
1138
+ background: #f2f6fb;
1139
+ }
1140
+ .liveness-timeout-risk {
1141
+ color: var(--amber);
1142
+ background: #fff8e7;
1143
+ }
1144
+
1145
+ .dag-detail-workspace {
1146
+ display: block;
1147
+ }
1148
+
1149
+ .dag-inspector {
1150
+ position: fixed;
1151
+ z-index: 40;
1152
+ /* Align with site-header top edge; same inset as right/bottom. */
1153
+ top: 24px;
1154
+ right: 24px;
1155
+ bottom: 24px;
1156
+ display: grid;
1157
+ grid-template-rows: auto minmax(0, 1fr);
1158
+ width: min(var(--dag-inspector-width, 50vw), calc(100vw - 48px));
1159
+ min-width: 0;
1160
+ padding: 0;
1161
+ overflow: hidden;
1162
+ border-color: var(--hairline-strong);
1163
+ box-shadow: 0 20px 48px rgba(38, 37, 30, 0.16);
1164
+ opacity: 0;
1165
+ pointer-events: none;
1166
+ transform: translateX(calc(100% + 24px));
1167
+ visibility: hidden;
1168
+ transition:
1169
+ transform var(--transition-base),
1170
+ opacity var(--transition-base),
1171
+ visibility 0s linear 240ms;
1172
+ }
1173
+ .dag-inspector.is-open {
1174
+ opacity: 1;
1175
+ pointer-events: auto;
1176
+ transform: translateX(0);
1177
+ visibility: visible;
1178
+ transition-delay: 0s, 0s, 0s;
1179
+ }
1180
+ .dag-inspector-resize-handle {
1181
+ position: absolute;
1182
+ z-index: 1;
1183
+ top: 0;
1184
+ bottom: 0;
1185
+ left: 0;
1186
+ width: 18px;
1187
+ cursor: col-resize;
1188
+ touch-action: none;
1189
+ outline: none;
1190
+ }
1191
+ .dag-inspector-resize-handle::before {
1192
+ content: "";
1193
+ position: absolute;
1194
+ top: 50%;
1195
+ left: 7px;
1196
+ width: 3px;
1197
+ height: 52px;
1198
+ transform: translateY(-50%);
1199
+ border-radius: 2px;
1200
+ background: var(--hairline-strong);
1201
+ opacity: 0;
1202
+ transition:
1203
+ opacity var(--transition-base),
1204
+ background var(--transition-base);
1205
+ }
1206
+ .dag-inspector-resize-handle:hover::before,
1207
+ .dag-inspector-resize-handle:focus-visible::before {
1208
+ background: var(--orange);
1209
+ opacity: 1;
1210
+ }
1211
+ .dag-inspector-resize-handle:focus-visible {
1212
+ outline: 2px solid var(--orange);
1213
+ outline-offset: -2px;
1214
+ }
1215
+ body.is-resizing-dag-inspector {
1216
+ cursor: col-resize;
1217
+ user-select: none;
1218
+ }
1219
+ body.is-resizing-dag-graph {
1220
+ cursor: grabbing;
1221
+ user-select: none;
1222
+ }
1223
+ .dag-inspector-header {
1224
+ display: grid;
1225
+ grid-template-columns: minmax(0, 1fr) auto;
1226
+ gap: var(--space-3);
1227
+ align-items: start;
1228
+ padding: var(--space-4) var(--space-4) var(--space-3);
1229
+ border-bottom: 1px solid var(--hairline);
1230
+ background: var(--canvas-soft);
1231
+ }
1232
+ .dag-inspector-title {
1233
+ display: grid;
1234
+ gap: 6px;
1235
+ min-width: 0;
1236
+ }
1237
+ .dag-inspector-title h3 {
1238
+ margin: 0;
1239
+ font-size: 14px;
1240
+ }
1241
+ .dag-inspector-node {
1242
+ min-width: 0;
1243
+ color: var(--body);
1244
+ font-size: 12px;
1245
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
1246
+ overflow-wrap: anywhere;
1247
+ }
1248
+ .dag-inspector-controls {
1249
+ display: inline-flex;
1250
+ align-items: center;
1251
+ gap: 8px;
1252
+ }
1253
+ .dag-inspector-close {
1254
+ display: inline-grid;
1255
+ place-items: center;
1256
+ width: 32px;
1257
+ height: 32px;
1258
+ border: 1px solid var(--hairline-strong);
1259
+ border-radius: var(--radius-sm);
1260
+ background: var(--surface);
1261
+ color: var(--body);
1262
+ cursor: pointer;
1263
+ }
1264
+ .dag-inspector-close:hover,
1265
+ .dag-inspector-close:focus-visible {
1266
+ border-color: var(--orange);
1267
+ color: var(--orange-active);
1268
+ outline: none;
1269
+ }
1270
+ .dag-inspector-tabs {
1271
+ display: flex;
1272
+ grid-column: 1 / -1;
1273
+ gap: 4px;
1274
+ margin-top: 2px;
1275
+ }
1276
+ .dag-inspector-tab {
1277
+ min-height: 32px;
1278
+ padding: 0 10px;
1279
+ border: 1px solid transparent;
1280
+ border-radius: var(--radius-sm);
1281
+ background: transparent;
1282
+ color: var(--muted);
1283
+ font-size: 12px;
1284
+ font-weight: 700;
1285
+ cursor: pointer;
1286
+ }
1287
+ .dag-inspector-tab:hover,
1288
+ .dag-inspector-tab:focus-visible {
1289
+ color: var(--ink);
1290
+ outline: none;
1291
+ }
1292
+ .dag-inspector-tab[aria-selected="true"] {
1293
+ border-color: color-mix(in srgb, var(--orange) 55%, var(--hairline));
1294
+ background: #fff5ed;
1295
+ color: var(--orange-active);
1296
+ }
1297
+ .dag-inspector-content {
1298
+ min-height: 0;
1299
+ padding: var(--space-4);
1300
+ overflow: auto;
1301
+ overscroll-behavior: contain;
1302
+ }
1303
+ .panel-graph {
1304
+ min-height: 0;
1305
+ }
1306
+
1307
+ .dag-graph-wrap {
1308
+ display: grid;
1309
+ gap: var(--space-3);
1310
+ }
1311
+ .dag-graph-toolbar {
1312
+ display: flex;
1313
+ align-items: center;
1314
+ justify-content: space-between;
1315
+ gap: var(--space-3);
1316
+ }
1317
+ .dag-graph-summary,
1318
+ .dag-graph-fallback {
1319
+ margin: 0;
1320
+ color: var(--muted);
1321
+ font-size: 12px;
1322
+ }
1323
+ .dag-graph-reset {
1324
+ min-height: 32px;
1325
+ padding: 0 10px;
1326
+ border: 1px solid var(--hairline-strong);
1327
+ border-radius: var(--radius-sm);
1328
+ background: var(--surface);
1329
+ color: var(--ink);
1330
+ font-size: 12px;
1331
+ font-weight: 650;
1332
+ cursor: pointer;
1333
+ }
1334
+ .dag-graph-reset:hover,
1335
+ .dag-graph-reset:focus-visible {
1336
+ border-color: var(--orange);
1337
+ color: var(--orange-active);
1338
+ outline: none;
1339
+ }
1340
+ .dag-graph-viewport {
1341
+ min-height: 320px;
1342
+ max-height: 560px;
1343
+ overflow: auto;
1344
+ border: 1px solid var(--hairline);
1345
+ border-radius: var(--radius-md);
1346
+ background: var(--canvas-soft);
1347
+ scroll-behavior: auto;
1348
+ }
1349
+ .dag-graph {
1350
+ display: block;
1351
+ }
1352
+ .dag-edge {
1353
+ fill: none;
1354
+ stroke: var(--hairline-strong);
1355
+ stroke-width: 2;
1356
+ transition:
1357
+ opacity var(--transition-fast),
1358
+ stroke var(--transition-fast);
1359
+ }
1360
+ #dag-arrow path {
1361
+ fill: var(--hairline-strong);
1362
+ }
1363
+ .dag-graph-node {
1364
+ cursor: pointer;
1365
+ transition: opacity var(--transition-fast);
1366
+ }
1367
+ .dag-graph-node rect {
1368
+ fill: var(--surface);
1369
+ stroke: var(--hairline-strong);
1370
+ stroke-width: 1.5;
1371
+ }
1372
+ .dag-graph-node:hover rect,
1373
+ .dag-graph-node:focus-visible rect {
1374
+ stroke: var(--orange);
1375
+ stroke-width: 2;
1376
+ }
1377
+ .dag-graph-node:focus {
1378
+ outline: none;
1379
+ }
1380
+ .dag-graph-node.selected rect {
1381
+ stroke: var(--orange);
1382
+ stroke-width: 3;
1383
+ }
1384
+ .dag-graph-node.status-running rect,
1385
+ .dag-graph-node.status-started rect {
1386
+ stroke: var(--orange);
1387
+ fill: #fff7f0;
1388
+ }
1389
+ .dag-graph-node.status-failed rect,
1390
+ .dag-graph-node.status-error rect {
1391
+ stroke: var(--red);
1392
+ fill: #fff7f8;
1393
+ }
1394
+ .dag-graph-node.status-succeeded:hover rect,
1395
+ .dag-graph-node.status-succeeded:focus-visible rect,
1396
+ .dag-graph-node.status-finished:hover rect,
1397
+ .dag-graph-node.status-finished:focus-visible rect,
1398
+ .dag-graph-node.status-completed:hover rect,
1399
+ .dag-graph-node.status-completed:focus-visible rect,
1400
+ .dag-graph-node.status-done:hover rect,
1401
+ .dag-graph-node.status-done:focus-visible rect {
1402
+ stroke: var(--green);
1403
+ fill: #f2faf5;
1404
+ }
1405
+ .dag-graph-node.selected.status-succeeded rect,
1406
+ .dag-graph-node.selected.status-finished rect,
1407
+ .dag-graph-node.selected.status-completed rect,
1408
+ .dag-graph-node.selected.status-done rect {
1409
+ stroke: var(--green);
1410
+ fill: #f2faf5;
1411
+ }
1412
+ .dag-graph-node.status-skipped rect {
1413
+ stroke-dasharray: 5 4;
1414
+ }
1415
+ .dag-node-label {
1416
+ fill: var(--ink);
1417
+ font-size: 13px;
1418
+ font-weight: 700;
1419
+ }
1420
+ .dag-node-meta {
1421
+ fill: var(--muted);
1422
+ font-size: 11px;
1423
+ }
1424
+ .dag-node-status {
1425
+ fill: var(--body);
1426
+ font-size: 11px;
1427
+ }
1428
+ .dag-dimmed {
1429
+ opacity: 0.28;
1430
+ }
1431
+ .dag-graph-node.status-running {
1432
+ animation: graph-node-pulse 2s ease-in-out infinite;
1433
+ }
1434
+ @keyframes graph-node-pulse {
1435
+ 50% {
1436
+ opacity: 0.72;
1437
+ }
1438
+ }
1439
+
1440
+ .dag-section-heading {
1441
+ display: flex;
1442
+ align-items: baseline;
1443
+ justify-content: space-between;
1444
+ gap: var(--space-3);
1445
+ margin-bottom: var(--space-4);
1446
+ }
1447
+ .dag-section-heading h3 {
1448
+ margin: 0;
1449
+ }
1450
+ .dag-section-meta {
1451
+ color: var(--muted);
1452
+ font-size: 12px;
1453
+ }
1454
+ #dag-nodes .dag-section-heading {
1455
+ padding: var(--space-5) var(--space-5) 0;
1456
+ }
1457
+ #dag-nodes .dag-node-table {
1458
+ border-top: 1px solid var(--hairline);
1459
+ }
1460
+ .dag-node-table {
1461
+ table-layout: fixed;
1462
+ }
1463
+ .dag-node-table th:nth-child(1),
1464
+ .dag-node-table td:nth-child(1) {
1465
+ width: 19%;
1466
+ }
1467
+ .dag-node-table th:nth-child(2),
1468
+ .dag-node-table td:nth-child(2) {
1469
+ width: 7%;
1470
+ }
1471
+ .dag-node-table th:nth-child(3),
1472
+ .dag-node-table td:nth-child(3) {
1473
+ width: 12%;
1474
+ }
1475
+ .dag-node-table th:nth-child(4),
1476
+ .dag-node-table td:nth-child(4) {
1477
+ width: 16%;
1478
+ }
1479
+ .dag-node-table th:nth-child(5),
1480
+ .dag-node-table td:nth-child(5) {
1481
+ width: 12%;
1482
+ }
1483
+ .dag-node-table th:nth-child(6),
1484
+ .dag-node-table td:nth-child(6) {
1485
+ width: 9%;
1486
+ }
1487
+ .dag-node-table th:nth-child(7),
1488
+ .dag-node-table td:nth-child(7) {
1489
+ width: 25%;
1490
+ }
1491
+ .dag-node-table td:nth-child(1),
1492
+ .dag-node-table td:nth-child(4),
1493
+ .dag-node-table td:nth-child(7) {
1494
+ overflow-wrap: anywhere;
1495
+ }
1496
+ .dag-active-node {
1497
+ background: #fff8f3;
1498
+ }
1499
+ .dag-error-node {
1500
+ background: #fff7f8;
1501
+ }
1502
+ .dag-node-selected {
1503
+ box-shadow: inset 3px 0 0 var(--orange);
1504
+ }
1505
+
1506
+ .rank-lanes {
1507
+ display: grid;
1508
+ gap: var(--space-3);
1509
+ }
1510
+ .rank-lane {
1511
+ display: grid;
1512
+ grid-template-columns: 56px minmax(0, 1fr);
1513
+ gap: var(--space-3);
1514
+ align-items: center;
1515
+ }
1516
+ .rank-lane-label {
1517
+ color: var(--muted);
1518
+ font-size: 11px;
1519
+ font-weight: 700;
1520
+ }
1521
+ .rank-lane-nodes {
1522
+ display: flex;
1523
+ flex-wrap: wrap;
1524
+ gap: 8px;
1525
+ }
1526
+ .rank-node-chip {
1527
+ display: inline-flex;
1528
+ align-items: center;
1529
+ gap: 7px;
1530
+ min-height: 32px;
1531
+ padding: 5px 8px;
1532
+ border: 1px solid var(--hairline);
1533
+ border-radius: var(--radius-sm);
1534
+ background: var(--canvas-soft);
1535
+ }
1536
+ .rank-node-active {
1537
+ border-color: var(--orange);
1538
+ }
1539
+ .rank-node-error {
1540
+ border-color: var(--red);
1541
+ }
1542
+ .rank-node-id {
1543
+ color: var(--ink);
1544
+ font-size: 11px;
1545
+ }
1546
+ .rank-node-dur {
1547
+ color: var(--muted);
1548
+ font-size: 11px;
1549
+ }
1550
+
1551
+ .process-timeline-note {
1552
+ margin: 0 0 var(--space-2);
1553
+ color: var(--muted);
1554
+ font-size: 11px;
1555
+ }
1556
+ .process-timeline {
1557
+ display: grid;
1558
+ gap: 0;
1559
+ margin: 0;
1560
+ padding: var(--space-2) 0;
1561
+ list-style: none;
1562
+ }
1563
+ .process-timeline-item {
1564
+ display: grid;
1565
+ grid-template-columns: 20px minmax(0, 1fr);
1566
+ align-items: stretch;
1567
+ min-height: 34px;
1568
+ }
1569
+ .process-timeline-item.has-time {
1570
+ grid-template-columns: 20px 92px minmax(0, 1fr);
1571
+ }
1572
+ .process-timeline-rail {
1573
+ position: relative;
1574
+ display: grid;
1575
+ place-items: center;
1576
+ min-height: 34px;
1577
+ }
1578
+ .process-timeline-rail::before {
1579
+ position: absolute;
1580
+ top: 0;
1581
+ bottom: 0;
1582
+ width: 1px;
1583
+ background: var(--hairline-strong);
1584
+ content: "";
1585
+ }
1586
+ .process-timeline-item.is-first .process-timeline-rail::before {
1587
+ top: 50%;
1588
+ }
1589
+ .process-timeline-item.is-last .process-timeline-rail::before {
1590
+ bottom: 50%;
1591
+ }
1592
+ .process-timeline-dot {
1593
+ position: relative;
1594
+ z-index: 1;
1595
+ width: 8px;
1596
+ height: 8px;
1597
+ border: 2px solid var(--surface);
1598
+ border-radius: 50%;
1599
+ background: var(--muted-soft);
1600
+ }
1601
+ .process-timeline-lifecycle .process-timeline-dot {
1602
+ background: var(--lavender);
1603
+ }
1604
+ .process-timeline-tool-start .process-timeline-dot {
1605
+ background: var(--orange);
1606
+ }
1607
+ .process-timeline-tool-end .process-timeline-dot {
1608
+ background: var(--green);
1609
+ }
1610
+ .process-timeline-assistant .process-timeline-dot {
1611
+ background: var(--blue);
1612
+ }
1613
+ .process-timeline-protocol .process-timeline-dot {
1614
+ background: var(--muted-soft);
1615
+ }
1616
+ .process-timeline-time {
1617
+ padding: 9px 0;
1618
+ color: var(--muted);
1619
+ font-size: 10px;
1620
+ font-variant-numeric: tabular-nums;
1621
+ }
1622
+ .process-timeline-label {
1623
+ min-width: 0;
1624
+ padding: 8px 0 8px var(--space-2);
1625
+ color: var(--body);
1626
+ font-size: 12px;
1627
+ line-height: 1.5;
1628
+ overflow-wrap: anywhere;
1629
+ }
1630
+ .process-timeline-protocol .process-timeline-label {
1631
+ color: var(--muted);
1632
+ font-size: 11px;
1633
+ }
1634
+
1635
+ .process-timeline-toolbar {
1636
+ display: flex;
1637
+ flex-wrap: wrap;
1638
+ gap: 8px;
1639
+ margin-bottom: var(--space-2);
1640
+ }
1641
+ .process-timeline-toggle {
1642
+ min-height: 28px;
1643
+ padding: 0 10px;
1644
+ border: 1px solid var(--hairline-strong);
1645
+ border-radius: var(--radius-sm);
1646
+ background: var(--surface);
1647
+ color: var(--body);
1648
+ font-size: 11px;
1649
+ font-weight: 600;
1650
+ cursor: pointer;
1651
+ }
1652
+ .process-timeline-toggle:hover,
1653
+ .process-timeline-toggle:focus-visible {
1654
+ border-color: var(--orange);
1655
+ color: var(--orange-active);
1656
+ outline: none;
1657
+ }
1658
+ .process-timeline-toggle[aria-pressed="true"] {
1659
+ border-color: color-mix(in srgb, var(--orange) 55%, var(--hairline));
1660
+ background: #fff5ed;
1661
+ color: var(--orange-active);
1662
+ }
1663
+ .process-timeline-body {
1664
+ min-width: 0;
1665
+ padding: 4px 0 8px var(--space-2);
1666
+ }
1667
+ .process-timeline-card {
1668
+ display: grid;
1669
+ gap: 6px;
1670
+ min-width: 0;
1671
+ }
1672
+ .process-timeline-details {
1673
+ min-width: 0;
1674
+ border: 1px solid var(--hairline);
1675
+ border-radius: var(--radius-sm);
1676
+ background: var(--surface);
1677
+ }
1678
+ .process-timeline-summary {
1679
+ display: flex;
1680
+ flex-wrap: wrap;
1681
+ align-items: center;
1682
+ justify-content: space-between;
1683
+ gap: 8px;
1684
+ padding: 8px 10px;
1685
+ cursor: pointer;
1686
+ list-style: none;
1687
+ color: var(--ink);
1688
+ font-size: 12px;
1689
+ font-weight: 650;
1690
+ }
1691
+ .process-timeline-summary::-webkit-details-marker {
1692
+ display: none;
1693
+ }
1694
+ .process-timeline-summary-title {
1695
+ min-width: 0;
1696
+ overflow-wrap: anywhere;
1697
+ }
1698
+ .process-timeline-summary-status {
1699
+ flex-shrink: 0;
1700
+ color: var(--muted);
1701
+ font-size: 11px;
1702
+ font-weight: 700;
1703
+ }
1704
+ .process-timeline-summary-status.status-succeeded {
1705
+ color: var(--green);
1706
+ }
1707
+ .process-timeline-summary-status.status-failed {
1708
+ color: var(--red);
1709
+ }
1710
+ .process-timeline-summary-status.status-pending {
1711
+ color: var(--orange);
1712
+ }
1713
+ .process-timeline-tool-card.is-error .process-timeline-details {
1714
+ border-color: color-mix(in srgb, var(--red) 45%, var(--hairline));
1715
+ background: color-mix(in srgb, var(--red) 6%, var(--surface));
1716
+ }
1717
+ .process-timeline-card-body {
1718
+ display: grid;
1719
+ gap: 6px;
1720
+ padding: 0 10px 10px;
1721
+ }
1722
+ .process-timeline-section-label {
1723
+ color: var(--muted);
1724
+ font-size: 11px;
1725
+ font-weight: 700;
1726
+ }
1727
+ .process-timeline-code,
1728
+ .process-timeline-thinking-body {
1729
+ margin: 0;
1730
+ padding: 8px 10px;
1731
+ overflow: auto;
1732
+ border-radius: var(--radius-sm);
1733
+ background: var(--canvas-soft);
1734
+ color: var(--body);
1735
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
1736
+ font-size: 11px;
1737
+ line-height: 1.45;
1738
+ white-space: pre-wrap;
1739
+ overflow-wrap: anywhere;
1740
+ }
1741
+ .process-timeline-more {
1742
+ margin-top: 2px;
1743
+ }
1744
+ .process-timeline-more > summary {
1745
+ cursor: pointer;
1746
+ color: var(--blue);
1747
+ font-size: 11px;
1748
+ font-weight: 650;
1749
+ }
1750
+ .process-timeline-thinking > summary {
1751
+ background: color-mix(in srgb, var(--lavender) 35%, var(--surface));
1752
+ }
1753
+ .process-timeline-turn-text {
1754
+ display: grid;
1755
+ gap: 6px;
1756
+ padding: 8px 10px;
1757
+ border: 1px solid var(--hairline);
1758
+ border-radius: var(--radius-sm);
1759
+ background: var(--surface);
1760
+ }
1761
+ .process-timeline-turn-text .markdown-output {
1762
+ font-size: 12px;
1763
+ }
1764
+ .process-timeline-tool-only-note {
1765
+ margin: 0;
1766
+ font-size: 12px;
1767
+ }
1768
+ .process-timeline-turn-tools {
1769
+ display: grid;
1770
+ gap: 4px;
1771
+ margin: 0;
1772
+ padding: 0 0 0 1.1em;
1773
+ color: var(--body);
1774
+ font-size: 12px;
1775
+ font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
1776
+ overflow-wrap: anywhere;
1777
+ }
1778
+ .process-timeline-turn-tools li {
1779
+ padding: 2px 0;
1780
+ }
1781
+ .process-timeline-agent-end-note {
1782
+ margin: 0;
1783
+ font-size: 11px;
1784
+ }
1785
+ .process-timeline-item.is-error .process-timeline-dot {
1786
+ background: var(--red);
1787
+ }
1788
+
1789
+ .markdown-output {
1790
+ display: grid;
1791
+ gap: var(--space-3);
1792
+ color: var(--body);
1793
+ font-size: 13px;
1794
+ line-height: 1.65;
1795
+ }
1796
+ .markdown-output > :first-child {
1797
+ margin-top: 0;
1798
+ }
1799
+ .markdown-output > :last-child {
1800
+ margin-bottom: 0;
1801
+ }
1802
+ .markdown-output h1,
1803
+ .markdown-output h2,
1804
+ .markdown-output h3,
1805
+ .markdown-output h4 {
1806
+ margin: var(--space-5) 0 var(--space-2);
1807
+ color: var(--ink);
1808
+ line-height: 1.3;
1809
+ }
1810
+ .markdown-output h1 {
1811
+ font-size: 21px;
1812
+ }
1813
+ .markdown-output h2 {
1814
+ font-size: 18px;
1815
+ }
1816
+ .markdown-output h3 {
1817
+ font-size: 16px;
1818
+ }
1819
+ .markdown-output h4 {
1820
+ font-size: 14px;
1821
+ }
1822
+ .markdown-output p,
1823
+ .markdown-output blockquote,
1824
+ .markdown-output ul,
1825
+ .markdown-output ol {
1826
+ margin: 0;
1827
+ overflow-wrap: anywhere;
1828
+ }
1829
+ .markdown-output p {
1830
+ white-space: normal;
1831
+ }
1832
+ .markdown-output ul,
1833
+ .markdown-output ol {
1834
+ padding-left: 22px;
1835
+ }
1836
+ .markdown-output blockquote {
1837
+ padding-left: 12px;
1838
+ border-left: 3px solid var(--peach);
1839
+ color: var(--body);
1840
+ }
1841
+ .markdown-output pre {
1842
+ margin: 0;
1843
+ padding: var(--space-3);
1844
+ overflow: auto;
1845
+ border: 1px solid var(--hairline);
1846
+ border-radius: var(--radius-sm);
1847
+ background: var(--surface-ink);
1848
+ color: #f8f7f2;
1849
+ font-size: 12px;
1850
+ line-height: 1.65;
1851
+ }
1852
+ .markdown-output code {
1853
+ padding: 1px 4px;
1854
+ border-radius: 3px;
1855
+ background: var(--surface-muted);
1856
+ color: var(--ink);
1857
+ font-size: 0.92em;
1858
+ }
1859
+ .markdown-output pre code {
1860
+ padding: 0;
1861
+ background: transparent;
1862
+ color: inherit;
1863
+ }
1864
+ .markdown-output a {
1865
+ color: var(--orange-active);
1866
+ text-decoration-color: var(--orange);
1867
+ text-underline-offset: 3px;
1868
+ }
1869
+ .markdown-output table {
1870
+ font-size: 12px;
1871
+ }
1872
+ .markdown-output th,
1873
+ .markdown-output td {
1874
+ padding: 8px 9px;
1875
+ }
1876
+ .markdown-output th {
1877
+ position: static;
1878
+ }
1879
+ .markdown-error {
1880
+ display: grid;
1881
+ gap: var(--space-2);
1882
+ padding-top: var(--space-4);
1883
+ border-top: 1px solid var(--hairline);
1884
+ }
1885
+ .markdown-error-title {
1886
+ margin: 0;
1887
+ color: var(--red);
1888
+ font-size: 12px;
1889
+ font-weight: 700;
1890
+ }
1891
+
1892
+ .spec-evidence-section { padding-bottom: var(--space-4); border-bottom: 1px solid var(--hairline); }
1893
+ .spec-evidence-section + .spec-evidence-section { margin-top: var(--space-4); }
1894
+ .spec-evidence-section h4 { margin: 0 0 var(--space-2); color: var(--ink); font-size: 12px; font-weight: 700; }
1895
+ .spec-evidence-summary { margin: var(--space-2) 0 0; color: var(--body); font-size: 12px; line-height: 1.6; }
1896
+ .spec-evidence-list { display: grid; gap: 6px; margin: var(--space-2) 0 0; padding: 0; list-style: none; }
1897
+ .spec-evidence-list li { display: flex; align-items: flex-start; gap: 6px; color: var(--body); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
1898
+ .spec-evidence-list li > i { flex-shrink: 0; margin-top: 2px; color: var(--muted); font-size: 13px; }
1899
+ .spec-evidence-list code { font-size: 11px; }
1900
+ .spec-evidence-time { margin-left: auto; color: var(--muted); font-size: 10px; font-variant-numeric: tabular-nums; white-space: nowrap; }
1901
+ .spec-evidence-warning { display: flex; align-items: flex-start; gap: 8px; margin-top: var(--space-4); padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--amber) 50%, var(--hairline)); border-radius: var(--radius-sm); background: #fff8e7; color: var(--body); font-size: 12px; line-height: 1.6; }
1902
+ .spec-evidence-warning > i { flex-shrink: 0; margin-top: 2px; color: var(--amber); }
1903
+
1904
+ .run-layer-process {
1905
+ display: grid;
1906
+ gap: var(--space-4);
1907
+ margin-top: var(--space-4);
1908
+ }
1909
+ .run-layer-diagnosis {
1910
+ display: grid;
1911
+ gap: var(--space-4);
1912
+ margin-top: var(--space-4);
1913
+ }
1914
+ .run-detail-workspace {
1915
+ display: grid;
1916
+ grid-template-columns: minmax(220px, 0.5fr) minmax(0, 1.25fr);
1917
+ gap: var(--space-4);
1918
+ align-items: start;
1919
+ }
1920
+ .run-evidence {
1921
+ display: grid;
1922
+ gap: var(--space-4);
1923
+ min-width: 0;
1924
+ }
1925
+ .artifact-preview-list {
1926
+ gap: 12px;
1927
+ }
1928
+ .artifact-preview-head {
1929
+ display: flex;
1930
+ flex-wrap: wrap;
1931
+ gap: 8px;
1932
+ align-items: baseline;
1933
+ margin-bottom: 6px;
1934
+ }
1935
+ .artifact-preview-label {
1936
+ font-size: 12px;
1937
+ color: var(--muted);
1938
+ overflow-wrap: anywhere;
1939
+ }
1940
+ .artifact-preview-body {
1941
+ max-height: 240px;
1942
+ overflow: auto;
1943
+ font-size: 12px;
1944
+ }
1945
+ .artifact-preview-error {
1946
+ color: var(--red);
1947
+ }
1948
+ .batch-task-links,
1949
+ .batch-task-evidence {
1950
+ display: flex;
1951
+ flex-wrap: wrap;
1952
+ gap: 4px;
1953
+ align-items: center;
1954
+ }
1955
+ .object-link {
1956
+ color: var(--body);
1957
+ text-decoration: underline;
1958
+ text-underline-offset: 2px;
1959
+ }
1960
+ .panel-rail {
1961
+ background: var(--canvas-soft);
1962
+ }
1963
+ .step-timeline {
1964
+ display: grid;
1965
+ gap: 0;
1966
+ margin: 0;
1967
+ padding: 0;
1968
+ list-style: none;
1969
+ }
1970
+ .step-timeline li {
1971
+ display: grid;
1972
+ grid-template-columns: 18px minmax(0, 1fr) auto;
1973
+ align-items: center;
1974
+ gap: 8px;
1975
+ min-height: 38px;
1976
+ border-bottom: 1px solid var(--hairline);
1977
+ }
1978
+ .step-timeline li:last-child {
1979
+ border-bottom: 0;
1980
+ }
1981
+ .step-marker {
1982
+ display: inline-grid;
1983
+ place-items: center;
1984
+ width: 16px;
1985
+ height: 16px;
1986
+ border: 1px solid var(--hairline-strong);
1987
+ border-radius: 50%;
1988
+ color: var(--muted);
1989
+ font-size: 10px;
1990
+ }
1991
+ .step-marker.succeeded {
1992
+ border-color: var(--green);
1993
+ color: var(--green);
1994
+ }
1995
+ .step-marker.running {
1996
+ border-color: var(--orange);
1997
+ color: var(--orange-active);
1998
+ }
1999
+ .step-marker.failed {
2000
+ border-color: var(--red);
2001
+ color: var(--red);
2002
+ }
2003
+ .step-name {
2004
+ min-width: 0;
2005
+ color: var(--body);
2006
+ font-size: 12px;
2007
+ overflow-wrap: anywhere;
2008
+ }
2009
+ .step-duration {
2010
+ color: var(--muted);
2011
+ font-size: 11px;
2012
+ font-variant-numeric: tabular-nums;
2013
+ }
2014
+
2015
+ .output-block {
2016
+ max-height: 480px;
2017
+ margin: 0;
2018
+ padding: var(--space-4);
2019
+ overflow: auto;
2020
+ border: 1px solid var(--hairline);
2021
+ border-radius: var(--radius-sm);
2022
+ background: var(--surface-ink);
2023
+ color: #f8f7f2;
2024
+ font-size: 12px;
2025
+ line-height: 1.7;
2026
+ white-space: pre-wrap;
2027
+ overflow-wrap: anywhere;
2028
+ }
2029
+
2030
+ .artifact-list {
2031
+ display: grid;
2032
+ gap: 8px;
2033
+ margin: 0;
2034
+ padding: 0;
2035
+ list-style: none;
2036
+ }
2037
+ .artifact-list li {
2038
+ min-width: 0;
2039
+ }
2040
+ .artifact-list a {
2041
+ color: var(--body);
2042
+ font-size: 12px;
2043
+ overflow-wrap: anywhere;
2044
+ }
2045
+ .artifact-links {
2046
+ display: flex;
2047
+ flex-wrap: wrap;
2048
+ gap: 6px;
2049
+ }
2050
+ .muted {
2051
+ color: var(--muted);
2052
+ }
2053
+
2054
+ .dag-run-timeline {
2055
+ position: relative;
2056
+ display: grid;
2057
+ gap: 0;
2058
+ }
2059
+ .dag-run-timeline::before {
2060
+ position: absolute;
2061
+ top: 12px;
2062
+ bottom: 12px;
2063
+ left: 10px;
2064
+ width: 1px;
2065
+ background: var(--hairline-strong);
2066
+ content: "";
2067
+ }
2068
+ .dag-run-timeline-item {
2069
+ position: relative;
2070
+ display: grid;
2071
+ grid-template-columns: 24px minmax(0, 1fr) auto;
2072
+ gap: var(--space-3);
2073
+ align-items: start;
2074
+ padding: 9px 0;
2075
+ color: inherit;
2076
+ text-decoration: none;
2077
+ transition: background-color var(--transition-fast);
2078
+ }
2079
+ .dag-run-timeline-item:hover,
2080
+ .dag-run-timeline-item:focus-visible {
2081
+ margin-inline: -8px;
2082
+ padding-inline: 8px;
2083
+ background: #fff8f4;
2084
+ outline: none;
2085
+ }
2086
+ .dag-run-timeline-rail {
2087
+ position: relative;
2088
+ display: grid;
2089
+ place-items: center;
2090
+ min-height: 24px;
2091
+ }
2092
+ .dag-run-timeline-dot {
2093
+ position: relative;
2094
+ z-index: 1;
2095
+ width: 9px;
2096
+ height: 9px;
2097
+ border: 2px solid var(--surface);
2098
+ border-radius: 50%;
2099
+ background: var(--muted-soft);
2100
+ }
2101
+ .dag-run-timeline-dot.status-finished,
2102
+ .dag-run-timeline-dot.status-succeeded,
2103
+ .dag-run-timeline-dot.status-completed {
2104
+ background: var(--green);
2105
+ }
2106
+ .dag-run-timeline-dot.status-failed,
2107
+ .dag-run-timeline-dot.status-error,
2108
+ .dag-run-timeline-dot.status-partial_failed {
2109
+ background: var(--red);
2110
+ }
2111
+ .dag-run-timeline-dot.status-running,
2112
+ .dag-run-timeline-dot.status-started {
2113
+ background: var(--orange);
2114
+ }
2115
+ .dag-run-timeline-content {
2116
+ display: grid;
2117
+ gap: 3px;
2118
+ min-width: 0;
2119
+ }
2120
+ .dag-run-timeline-title {
2121
+ color: var(--ink);
2122
+ font-size: 13px;
2123
+ font-weight: 700;
2124
+ overflow-wrap: anywhere;
2125
+ }
2126
+ .dag-run-timeline-meta {
2127
+ color: var(--muted);
2128
+ font-size: 11px;
2129
+ overflow-wrap: anywhere;
2130
+ }
2131
+ .dag-run-timeline-status {
2132
+ padding-top: 1px;
2133
+ }
2134
+
2135
+ #failures-list .row-failed td:first-child,
2136
+ #failures-list .row-blocked td:first-child {
2137
+ color: var(--red);
2138
+ font-weight: 700;
2139
+ }
2140
+
2141
+ @media (max-width: 1320px) {
2142
+ .view-dashboard {
2143
+ --dashboard-cols: 1fr;
2144
+ }
2145
+ .kpi-grid {
2146
+ grid-template-columns: repeat(3, minmax(0, 1fr));
2147
+ }
2148
+ .kpi-grid.pool-health-grid {
2149
+ display: flex;
2150
+ flex-wrap: nowrap;
2151
+ grid-template-columns: none;
2152
+ }
2153
+ .kpi-card:nth-child(4) {
2154
+ border-left: 0;
2155
+ }
2156
+ .kpi-card:nth-child(n + 4) {
2157
+ border-top: 1px solid var(--hairline);
2158
+ }
2159
+ .kpi-grid.pool-health-grid .kpi-card,
2160
+ .kpi-grid.pool-health-grid .kpi-card:nth-child(n),
2161
+ .kpi-grid.pool-health-grid .kpi-card:nth-child(n + 4) {
2162
+ border-top: 0;
2163
+ border-left: 1px solid var(--hairline);
2164
+ }
2165
+ .kpi-grid.pool-health-grid .kpi-card:first-child {
2166
+ border-left: 0;
2167
+ }
2168
+ .panel-risk {
2169
+ position: static;
2170
+ }
2171
+ .run-detail-workspace {
2172
+ grid-template-columns: minmax(200px, 0.45fr) minmax(0, 1fr);
2173
+ }
2174
+ .panel-artifacts {
2175
+ grid-column: 1 / -1;
2176
+ }
2177
+ }
2178
+
2179
+ @media (max-width: 1080px) {
2180
+ #app {
2181
+ width: min(100% - 32px, 1680px);
2182
+ }
2183
+ .site-header {
2184
+ grid-template-columns: auto auto 1fr;
2185
+ grid-template-areas: "brand nav status" "crumb crumb crumb";
2186
+ row-gap: 8px;
2187
+ }
2188
+ .run-detail-workspace {
2189
+ grid-template-columns: 1fr;
2190
+ }
2191
+ .panel-artifacts {
2192
+ grid-column: auto;
2193
+ }
2194
+ .pool-workspace {
2195
+ grid-template-columns: 1fr;
2196
+ }
2197
+ .page-header,
2198
+ .pool-page-header,
2199
+ .dashboard-page-header {
2200
+ grid-template-columns: 1fr;
2201
+ }
2202
+ .repo-banner-inline {
2203
+ justify-self: start;
2204
+ max-width: none;
2205
+ }
2206
+ .repo-banner-path {
2207
+ max-width: none;
2208
+ white-space: normal;
2209
+ }
2210
+ .pool-toolbar {
2211
+ justify-items: start;
2212
+ }
2213
+ .pool-toolbar-actions {
2214
+ justify-content: flex-start;
2215
+ }
2216
+ .pool-toolbar .pool-updated-at {
2217
+ text-align: left;
2218
+ max-width: none;
2219
+ }
2220
+ }
2221
+
2222
+ @media (max-width: 720px) {
2223
+ #app {
2224
+ width: min(100% - 24px, 1680px);
2225
+ }
2226
+ .site-header {
2227
+ margin-bottom: var(--space-6);
2228
+ }
2229
+ .kpi-grid {
2230
+ grid-template-columns: repeat(2, minmax(0, 1fr));
2231
+ }
2232
+ .kpi-grid.pool-health-grid {
2233
+ display: flex;
2234
+ flex-wrap: nowrap;
2235
+ grid-template-columns: none;
2236
+ }
2237
+ .kpi-card:nth-child(n) {
2238
+ border-top: 1px solid var(--hairline);
2239
+ border-left: 1px solid var(--hairline);
2240
+ }
2241
+ .kpi-card:nth-child(1),
2242
+ .kpi-card:nth-child(2) {
2243
+ border-top: 0;
2244
+ }
2245
+ .kpi-card:nth-child(odd) {
2246
+ border-left: 0;
2247
+ }
2248
+ .kpi-grid.pool-health-grid .kpi-card,
2249
+ .kpi-grid.pool-health-grid .kpi-card:nth-child(n),
2250
+ .kpi-grid.pool-health-grid .kpi-card:nth-child(odd) {
2251
+ border-top: 0;
2252
+ border-left: 1px solid var(--hairline);
2253
+ }
2254
+ .kpi-grid.pool-health-grid .kpi-card:first-child {
2255
+ border-left: 0;
2256
+ }
2257
+ .dag-inspector {
2258
+ top: 12px;
2259
+ right: 12px;
2260
+ bottom: 12px;
2261
+ width: calc(100vw - 24px);
2262
+ }
2263
+ .dag-inspector-resize-handle {
2264
+ display: none;
2265
+ }
2266
+ .dashboard-secondary {
2267
+ grid-template-columns: 1fr;
2268
+ }
2269
+ .feature-decision-row {
2270
+ grid-template-columns: 1fr;
2271
+ gap: 4px;
2272
+ }
2273
+ .feature-decision-next {
2274
+ white-space: normal;
2275
+ }
2276
+ .risk-block {
2277
+ grid-template-columns: minmax(0, 1fr) auto;
2278
+ column-gap: var(--space-2);
2279
+ }
2280
+ .panel {
2281
+ padding: var(--space-4);
2282
+ }
2283
+ .panel-table {
2284
+ overflow-x: auto;
2285
+ padding: 0;
2286
+ }
2287
+ table {
2288
+ min-width: 680px;
2289
+ }
2290
+ .view h2 {
2291
+ font-size: 24px;
2292
+ }
2293
+ }
2294
+
2295
+ /* R3: object relation bar + recommended commands (copy-only) */
2296
+ .object-relations-panel {
2297
+ padding: var(--space-3) var(--space-4);
2298
+ }
2299
+
2300
+ .object-relation-bar {
2301
+ display: flex;
2302
+ flex-wrap: wrap;
2303
+ align-items: center;
2304
+ gap: var(--space-2);
2305
+ font-size: 0.9rem;
2306
+ }
2307
+
2308
+ .object-relation-item {
2309
+ display: inline-flex;
2310
+ align-items: baseline;
2311
+ gap: 0.25rem;
2312
+ }
2313
+
2314
+ .object-relation-label {
2315
+ color: var(--muted, #6b6560);
2316
+ font-weight: 600;
2317
+ font-size: 0.75rem;
2318
+ text-transform: uppercase;
2319
+ letter-spacing: 0.04em;
2320
+ }
2321
+
2322
+ .object-relation-sep {
2323
+ color: var(--muted, #6b6560);
2324
+ opacity: 0.7;
2325
+ user-select: none;
2326
+ }
2327
+
2328
+ .object-link {
2329
+ color: var(--accent, #8a5a2b);
2330
+ text-decoration: none;
2331
+ word-break: break-all;
2332
+ }
2333
+
2334
+ .object-link:hover,
2335
+ .object-link:focus-visible {
2336
+ text-decoration: underline;
2337
+ }
2338
+
2339
+ .recommended-command {
2340
+ border: 1px solid var(--border, #e2ddd4);
2341
+ border-radius: 8px;
2342
+ padding: var(--space-3);
2343
+ margin: var(--space-2) 0;
2344
+ background: #fbf9f4;
2345
+ }
2346
+
2347
+ .recommended-command-head {
2348
+ display: flex;
2349
+ flex-wrap: wrap;
2350
+ gap: var(--space-2);
2351
+ align-items: baseline;
2352
+ margin-bottom: var(--space-2);
2353
+ }
2354
+
2355
+ .recommended-command-kind {
2356
+ font-size: 0.75rem;
2357
+ font-weight: 600;
2358
+ color: var(--muted, #6b6560);
2359
+ text-transform: uppercase;
2360
+ }
2361
+
2362
+ .recommended-command-label {
2363
+ font-weight: 600;
2364
+ }
2365
+
2366
+ .recommended-command-body {
2367
+ display: flex;
2368
+ flex-wrap: wrap;
2369
+ align-items: center;
2370
+ gap: var(--space-2);
2371
+ }
2372
+
2373
+ .recommended-command-text {
2374
+ flex: 1 1 12rem;
2375
+ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
2376
+ font-size: 0.85rem;
2377
+ word-break: break-all;
2378
+ background: #f0ebe3;
2379
+ padding: 0.35rem 0.5rem;
2380
+ border-radius: 4px;
2381
+ }
2382
+
2383
+ button.copy-command {
2384
+ appearance: none;
2385
+ border: 1px solid var(--border, #d4cdc2);
2386
+ background: #fff;
2387
+ border-radius: 6px;
2388
+ padding: 0.35rem 0.75rem;
2389
+ cursor: pointer;
2390
+ font-size: 0.85rem;
2391
+ }
2392
+
2393
+ button.copy-command:hover,
2394
+ button.copy-command:focus-visible {
2395
+ border-color: var(--accent, #8a5a2b);
2396
+ }
2397
+
2398
+ .executed-facts {
2399
+ border-left: 3px solid #6b8f71;
2400
+ }
2401
+
2402
+ .advisory-note {
2403
+ margin: 0 0 var(--space-2);
2404
+ font-size: 0.85rem;
2405
+ }
2406
+
2407
+ .blocking-list {
2408
+ margin: 0;
2409
+ padding-left: 1.25rem;
2410
+ }
2411
+
2412
+ .blocking-message {
2413
+ font-weight: 500;
2414
+ }
2415
+
2416
+ .blocking-meta {
2417
+ font-size: 0.85rem;
2418
+ color: var(--muted, #6b6560);
2419
+ margin: 0.15rem 0 0.35rem;
2420
+ }
2421
+
2422
+
2423
+
2424
+ /* R5: unified view states + information hierarchy */
2425
+ .view-state {
2426
+ border-radius: var(--radius, 8px);
2427
+ padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
2428
+ margin: 0 0 var(--space-3, 0.75rem);
2429
+ }
2430
+ .view-state-loading {
2431
+ border: 1px dashed var(--border, #e2dcd4);
2432
+ background: var(--surface-muted, #f7f4ef);
2433
+ color: var(--muted, #6b6560);
2434
+ }
2435
+ .view-state-empty {
2436
+ border: 1px solid var(--border, #e2dcd4);
2437
+ background: var(--surface, #fffdf9);
2438
+ }
2439
+ .view-state-degraded {
2440
+ /* projection-fault styles also apply */
2441
+ }
2442
+ .view-state-error {
2443
+ border: 1px solid var(--danger-border, #e8b4b4);
2444
+ background: var(--danger-bg, #fdf2f2);
2445
+ color: var(--danger-text, #8a2f2f);
2446
+ }
2447
+ .view-state-error p {
2448
+ margin: 0;
2449
+ }
2450
+ .layer-primary {
2451
+ /* main facts */
2452
+ }
2453
+ .layer-diagnostic {
2454
+ opacity: 0.98;
2455
+ }
2456
+ .layer-raw {
2457
+ font-size: 0.9rem;
2458
+ color: var(--muted, #6b6560);
2459
+ }
2460
+ .pool-filters {
2461
+ display: flex;
2462
+ flex-wrap: wrap;
2463
+ gap: 0.5rem 0.75rem;
2464
+ align-items: center;
2465
+ margin: 0 0 var(--space-3, 0.75rem);
2466
+ }
2467
+ .pool-filters label {
2468
+ display: inline-flex;
2469
+ align-items: center;
2470
+ gap: 0.35rem;
2471
+ font-size: 0.9rem;
2472
+ }
2473
+ .pool-filters select,
2474
+ .pool-filters input[type="search"] {
2475
+ font: inherit;
2476
+ padding: 0.25rem 0.5rem;
2477
+ border: 1px solid var(--border, #e2dcd4);
2478
+ border-radius: 6px;
2479
+ background: var(--surface, #fff);
2480
+ min-height: 2rem;
2481
+ }
2482
+ .pool-filters select:focus-visible,
2483
+ .pool-filters input[type="search"]:focus-visible {
2484
+ outline: 2px solid var(--focus, #3d6bf3);
2485
+ outline-offset: 2px;
2486
+ }
2487
+
2488
+ @media (max-width: 1024px) {
2489
+ .pool-filters {
2490
+ flex-direction: column;
2491
+ align-items: stretch;
2492
+ }
2493
+ }
2494
+
2495
+ @media (prefers-reduced-motion: reduce) {
2496
+ *,
2497
+ *::before,
2498
+ *::after {
2499
+ animation-duration: 0.01ms !important;
2500
+ animation-iteration-count: 1 !important;
2501
+ scroll-behavior: auto !important;
2502
+ transition-duration: 0.01ms !important;
2503
+ }
2504
+ }