oficina-opencode 3.0.5 → 3.1.1

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 (145) hide show
  1. package/README.md +240 -208
  2. package/commands/oficina.md +7 -6
  3. package/dashboard/.dom-check.html +1257 -0
  4. package/dashboard/README-DASHBOARD.md +64 -0
  5. package/dashboard/assets/factory.css +1543 -0
  6. package/dashboard/assets/tokens.css +208 -0
  7. package/dashboard/build-kanban-data.mjs +279 -0
  8. package/dashboard/dashboard.css +753 -0
  9. package/dashboard/dashboard.html +121 -0
  10. package/dashboard/dashboard.js +610 -0
  11. package/dashboard/data/snapshot.json +883 -0
  12. package/dashboard/debate.html +134 -0
  13. package/dashboard/factory/build-snapshot.mjs +89 -0
  14. package/dashboard/factory/factory-app.js +1185 -0
  15. package/dashboard/factory/factory-core.js +541 -0
  16. package/dashboard/factory/snapshot.js +850 -0
  17. package/dashboard/factory.html +350 -0
  18. package/dashboard/kanban-data.json +671 -0
  19. package/dashboard/kanban-source.js +643 -0
  20. package/dashboard/kanban.check.mjs +454 -0
  21. package/dashboard/kanban.html +1257 -0
  22. package/dashboard/leadership.html +1008 -0
  23. package/dashboard/lib/debate-app.js +1149 -0
  24. package/dashboard/lib/debate-core.js +698 -0
  25. package/dashboard/lib/debate-data.js +163 -0
  26. package/dashboard/lib/debate-demo.js +110 -0
  27. package/dashboard/lib/debate.css +1155 -0
  28. package/dashboard/lib/leadership-model.js +946 -0
  29. package/dashboard/probe.mjs +35 -0
  30. package/dashboard/scripts/serve.mjs +122 -0
  31. package/dashboard/scripts/snapshot-data.mjs +93 -0
  32. package/dashboard/scripts/snapshot.mjs +28 -0
  33. package/dashboard/server.mjs +242 -0
  34. package/dashboard/shot.mjs +54 -0
  35. package/dashboard/shots/desktop-gates.png +0 -0
  36. package/dashboard/shots/desktop-light.png +0 -0
  37. package/dashboard/shots/desktop-real.png +0 -0
  38. package/dashboard/shots/mobile.png +0 -0
  39. package/dashboard/test/factory-core.test.mjs +244 -0
  40. package/dashboard/tests/debate-core.test.mjs +336 -0
  41. package/dashboard/tests/leadership-model.test.mjs +404 -0
  42. package/dist/cli.js +148 -26
  43. package/dist/cli.js.map +1 -1
  44. package/dist/core/bus.js +3 -3
  45. package/dist/core/bus.js.map +1 -1
  46. package/dist/core/catalog.d.ts +9 -1
  47. package/dist/core/catalog.d.ts.map +1 -1
  48. package/dist/core/catalog.js +77 -2
  49. package/dist/core/catalog.js.map +1 -1
  50. package/dist/core/dashboard.d.ts +33 -0
  51. package/dist/core/dashboard.d.ts.map +1 -0
  52. package/dist/core/dashboard.js +115 -0
  53. package/dist/core/dashboard.js.map +1 -0
  54. package/dist/core/dispatch.d.ts +1 -1
  55. package/dist/core/dispatch.d.ts.map +1 -1
  56. package/dist/core/dispatch.js +84 -12
  57. package/dist/core/dispatch.js.map +1 -1
  58. package/dist/core/docsync.d.ts +0 -9
  59. package/dist/core/docsync.d.ts.map +1 -1
  60. package/dist/core/docsync.js +12 -15
  61. package/dist/core/docsync.js.map +1 -1
  62. package/dist/core/environment.d.ts +28 -0
  63. package/dist/core/environment.d.ts.map +1 -0
  64. package/dist/core/environment.js +80 -0
  65. package/dist/core/environment.js.map +1 -0
  66. package/dist/core/factory.d.ts +16 -0
  67. package/dist/core/factory.d.ts.map +1 -1
  68. package/dist/core/factory.js +143 -0
  69. package/dist/core/factory.js.map +1 -1
  70. package/dist/core/fsx.d.ts +20 -2
  71. package/dist/core/fsx.d.ts.map +1 -1
  72. package/dist/core/fsx.js +10 -6
  73. package/dist/core/fsx.js.map +1 -1
  74. package/dist/core/gates.d.ts +23 -1
  75. package/dist/core/gates.d.ts.map +1 -1
  76. package/dist/core/gates.js +83 -8
  77. package/dist/core/gates.js.map +1 -1
  78. package/dist/core/leases.d.ts.map +1 -1
  79. package/dist/core/leases.js +4 -1
  80. package/dist/core/leases.js.map +1 -1
  81. package/dist/core/mesa.d.ts +1 -6
  82. package/dist/core/mesa.d.ts.map +1 -1
  83. package/dist/core/mesa.js +1 -6
  84. package/dist/core/mesa.js.map +1 -1
  85. package/dist/core/office.d.ts +3 -29
  86. package/dist/core/office.d.ts.map +1 -1
  87. package/dist/core/office.js +77 -90
  88. package/dist/core/office.js.map +1 -1
  89. package/dist/core/paths.d.ts.map +1 -1
  90. package/dist/core/paths.js +6 -1
  91. package/dist/core/paths.js.map +1 -1
  92. package/dist/core/retry.d.ts +2 -8
  93. package/dist/core/retry.d.ts.map +1 -1
  94. package/dist/core/retry.js +3 -34
  95. package/dist/core/retry.js.map +1 -1
  96. package/dist/core/roster.js +3 -3
  97. package/dist/core/roster.js.map +1 -1
  98. package/dist/core/sandbox.d.ts +38 -1
  99. package/dist/core/sandbox.d.ts.map +1 -1
  100. package/dist/core/sandbox.js +119 -15
  101. package/dist/core/sandbox.js.map +1 -1
  102. package/dist/core/state.d.ts +2 -2
  103. package/dist/core/state.d.ts.map +1 -1
  104. package/dist/core/state.js +5 -33
  105. package/dist/core/state.js.map +1 -1
  106. package/dist/core/stores.d.ts +3 -13
  107. package/dist/core/stores.d.ts.map +1 -1
  108. package/dist/core/stores.js +8 -32
  109. package/dist/core/stores.js.map +1 -1
  110. package/dist/core/systemPrompt.d.ts.map +1 -1
  111. package/dist/core/systemPrompt.js +4 -1
  112. package/dist/core/systemPrompt.js.map +1 -1
  113. package/dist/core/tripwire.d.ts +22 -8
  114. package/dist/core/tripwire.d.ts.map +1 -1
  115. package/dist/core/tripwire.js +71 -26
  116. package/dist/core/tripwire.js.map +1 -1
  117. package/dist/core/types.d.ts +6 -14
  118. package/dist/core/types.d.ts.map +1 -1
  119. package/dist/core/types.js +11 -3
  120. package/dist/core/types.js.map +1 -1
  121. package/dist/hooks/scopeGuard.d.ts +15 -1
  122. package/dist/hooks/scopeGuard.d.ts.map +1 -1
  123. package/dist/hooks/scopeGuard.js +88 -73
  124. package/dist/hooks/scopeGuard.js.map +1 -1
  125. package/dist/tools/index.d.ts +9 -1
  126. package/dist/tools/index.d.ts.map +1 -1
  127. package/dist/tools/index.js +29 -81
  128. package/dist/tools/index.js.bak +972 -0
  129. package/dist/tools/index.js.map +1 -1
  130. package/dist/v1.d.ts.map +1 -1
  131. package/dist/v1.js +30 -36
  132. package/dist/v1.js.map +1 -1
  133. package/dist/v2.d.ts +5 -0
  134. package/dist/v2.d.ts.map +1 -1
  135. package/dist/v2.js +79 -46
  136. package/dist/v2.js.bak +517 -0
  137. package/dist/v2.js.map +1 -1
  138. package/docs/GARANTIAS.md +2 -2
  139. package/docs/PRUEBA-E2E.md +4 -4
  140. package/docs/QUE-ES.md +4 -5
  141. package/docs/SEGURIDAD-REPO.md +83 -0
  142. package/docs/assets/banner.svg +42 -0
  143. package/docs/catalog-facts.json +3 -3
  144. package/docs/superpowers/specs/2026-10-29-factory-skill-creator-and-remove-budget.md +182 -0
  145. package/package.json +14 -6
@@ -0,0 +1,753 @@
1
+ /* Hallmark: sala-de-operaciones / console-dark / stamp line 1 (floor #15) */
2
+ /* floor: tokens-only colors, no transition:all, no width/height animation,
3
+ focus-visible always, reduced-motion respected. WarWARN: side stripes on
4
+ .msg are a deliberate control-room severity convention (state legibility),
5
+ not decoration. */
6
+ :root {
7
+ /* ---- Color: dark (default) ---- */
8
+ --bg: #0a0c10;
9
+ --bg-vignette: #05060a;
10
+ --surface: #12151c;
11
+ --surface-2: #181c26;
12
+ --surface-3: #20252f;
13
+ --border: #232833;
14
+ --border-strong: #343b49;
15
+ --text: #e8eaf0;
16
+ --text-2: #9aa2b1;
17
+ --text-3: #5c6675;
18
+ --accent: #f59e0b; /* ambar / el color de la oficina activa */
19
+ --accent-dim: #6b4a12;
20
+ --ok: #34d399;
21
+ --ok-dim: #0e3b2b;
22
+ --warn: #fbbf24;
23
+ --err: #f87171;
24
+ --err-dim: #3d1a1a;
25
+ --info: #60a5fa;
26
+ --info-dim: #16273f;
27
+ --peer: #c084fc; /* violeta / flujo entre pares */
28
+
29
+ /* ---- Strong variants (contraste AA sobre fondos dim) ---- */
30
+ --accent-strong: #fcd34d;
31
+ --ok-strong: #6ee7b7;
32
+ --err-strong: #fca5a5;
33
+ --info-strong: #93c5fd;
34
+ --peer-glow: rgba(192, 132, 252, 0.35);
35
+ --shadow-lift: 0 4px 16px rgba(0, 0, 0, 0.5);
36
+ --topbar-h: 46px;
37
+
38
+ /* ---- Color: semantic tokens ---- */
39
+ --card-todo: #9aa2b1;
40
+ --card-progress: #f59e0b;
41
+ --card-review: #60a5fa;
42
+ --card-done: #34d399;
43
+ --card-rework: #fbbf24;
44
+ --card-blocked: #f87171;
45
+ --card-escalated: #f472b6;
46
+
47
+ /* ---- Glow ---- */
48
+ --glow-accent: rgba(245, 158, 11, 0.35);
49
+ --glow-ok: rgba(52, 211, 153, 0.30);
50
+ --glow-err: rgba(248, 113, 113, 0.35);
51
+ --glow-info: rgba(96, 165, 250, 0.30);
52
+
53
+ /* ---- Typography ---- */
54
+ --font-display: "Archivo", "Segoe UI", system-ui, sans-serif;
55
+ --font-mono: "JetBrains Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
56
+
57
+ /* ---- Spacing scale ---- */
58
+ --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
59
+ --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;
60
+
61
+ /* ---- Radius ---- */
62
+ --r-sm: 4px; --r-md: 6px; --r-lg: 10px;
63
+
64
+ /* ---- Motion (Emil: solo transform/opacity) ---- */
65
+ --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
66
+ --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
67
+ --t-fast: 120ms;
68
+ --t-ui: 180ms;
69
+ --t-slow: 320ms;
70
+
71
+ --ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent);
72
+ }
73
+
74
+ [data-theme="light"] {
75
+ --bg: #f4f1ea;
76
+ --bg-vignette: #eceae2;
77
+ --surface: #fdfcf8;
78
+ --surface-2: #f2efe7;
79
+ --surface-3: #e6e2d7;
80
+ --border: #d8d3c6;
81
+ --border-strong: #b8b2a2;
82
+ --text: #1a1d23;
83
+ --text-2: #4c525e;
84
+ --text-3: #8a8f9b;
85
+ --accent: #92400e;
86
+ --accent-dim: #fbe8d3;
87
+ --ok: #047857;
88
+ --ok-dim: #d5f1e5;
89
+ --warn: #b45309;
90
+ --err: #b91c1c;
91
+ --err-dim: #fee2e2;
92
+ --info: #1d4ed8;
93
+ --info-dim: #dbeafe;
94
+ --peer: #7e22ce;
95
+ --accent-strong: #7c2d12;
96
+ --ok-strong: #065f46;
97
+ --err-strong: #7f1d1d;
98
+ --info-strong: #1e40af;
99
+ --peer-glow: rgba(126, 34, 206, 0.25);
100
+ --shadow-lift: 0 4px 16px rgba(26, 29, 35, 0.18);
101
+ --glow-accent: rgba(146, 64, 14, 0.25);
102
+ --glow-ok: rgba(4, 120, 87, 0.20);
103
+ --glow-err: rgba(185, 28, 28, 0.25);
104
+ --glow-info: rgba(29, 78, 216, 0.20);
105
+ }
106
+
107
+ /* ---- Skip link (accesibilidad) ---- */
108
+ .skip-link {
109
+ position: absolute;
110
+ left: var(--sp-3);
111
+ top: -40px;
112
+ z-index: 100;
113
+ padding: var(--sp-2) var(--sp-3);
114
+ background: var(--accent);
115
+ color: var(--bg);
116
+ border-radius: var(--r-sm);
117
+ font-size: 12px;
118
+ text-decoration: none;
119
+ transition: top var(--t-fast) var(--ease-out);
120
+ }
121
+ .skip-link:focus { top: var(--sp-2); }
122
+ .skip-link:focus-visible { outline: 2px solid var(--bg); outline-offset: 2px; }
123
+
124
+ /* ---- Reset ---- */
125
+ *,
126
+ *::before,
127
+ *::after { box-sizing: border-box; }
128
+
129
+ html, body { overflow-x: clip; }
130
+
131
+ body {
132
+ margin: 0;
133
+ background: var(--bg);
134
+ color: var(--text);
135
+ font-family: var(--font-mono);
136
+ font-size: 13px;
137
+ line-height: 1.55;
138
+ -webkit-font-smoothing: antialiased;
139
+ touch-action: manipulation;
140
+ }
141
+
142
+ h1, h2, h3 { font-family: var(--font-display); margin: 0; text-wrap: balance; }
143
+
144
+ /* ---- Focus ---- */
145
+ :focus { outline: none; }
146
+ :focus-visible {
147
+ outline: 2px solid var(--accent);
148
+ outline-offset: 2px;
149
+ border-radius: var(--r-sm);
150
+ }
151
+
152
+ ::selection { background: var(--accent-dim); color: var(--text); }
153
+
154
+ /* ---- Scrollbars ---- */
155
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
156
+ ::-webkit-scrollbar-track { background: transparent; }
157
+ ::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
158
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-3); }
159
+
160
+ /* ============================================================
161
+ Layout: header + grid de paneles
162
+ ============================================================ */
163
+
164
+ .app {
165
+ display: flex;
166
+ flex-direction: column;
167
+ min-height: 100dvh;
168
+ }
169
+ /* Los hijos de .app son flex items: sin min-width:0, el ancho intrinseco del
170
+ kanban (7 columnas de 240px) expande TODO el layout y recorta la vista. */
171
+ .app > * { min-width: 0; }
172
+
173
+ /* ---- Header ---- */
174
+ .topbar {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: var(--sp-4);
178
+ padding: var(--sp-3) var(--sp-5);
179
+ border-bottom: 1px solid var(--border);
180
+ background: var(--surface);
181
+ position: sticky;
182
+ top: 0;
183
+ z-index: 20;
184
+ }
185
+
186
+ .brand { display: flex; align-items: baseline; gap: var(--sp-3); }
187
+ .brand h1 {
188
+ font-size: 16px;
189
+ font-weight: 800;
190
+ letter-spacing: -0.02em;
191
+ color: var(--text);
192
+ }
193
+ .brand .run-id {
194
+ color: var(--text-3);
195
+ font-size: 11px;
196
+ }
197
+
198
+ .topbar .spacer { flex: 1; }
199
+
200
+ .conn {
201
+ display: inline-flex;
202
+ align-items: center;
203
+ gap: var(--sp-2);
204
+ font-size: 11px;
205
+ color: var(--text-2);
206
+ }
207
+ .conn .dot {
208
+ width: 8px; height: 8px;
209
+ border-radius: 50%;
210
+ background: var(--ok);
211
+ box-shadow: 0 0 6px var(--glow-ok);
212
+ }
213
+ .conn[data-state="poll"] .dot { background: var(--accent); box-shadow: 0 0 6px var(--glow-accent); }
214
+ .conn[data-state="demo"] .dot { background: var(--peer); box-shadow: 0 0 6px var(--peer-glow); }
215
+ .conn[data-state="offline"] .dot { background: var(--err); box-shadow: 0 0 6px var(--glow-err); }
216
+
217
+ .btn {
218
+ font-family: var(--font-mono);
219
+ font-size: 12px;
220
+ padding: 8px 16px;
221
+ background: transparent;
222
+ border: 1px solid var(--border);
223
+ border-radius: var(--r-md);
224
+ color: var(--text-2);
225
+ cursor: pointer;
226
+ transition: background var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
227
+ }
228
+ .btn:hover { background: var(--surface-3); color: var(--text); }
229
+ .btn:active { transform: scale(0.97); }
230
+ .btn:disabled { opacity: 0.45; cursor: not-allowed; }
231
+ .btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
232
+
233
+ /* ---- Barra de metricas ---- */
234
+ .metrics {
235
+ display: grid;
236
+ grid-template-columns: repeat(6, 1fr);
237
+ gap: 1px;
238
+ background: var(--border);
239
+ border-bottom: 1px solid var(--border);
240
+ }
241
+ .metric {
242
+ background: var(--surface);
243
+ padding: var(--sp-3) var(--sp-4);
244
+ display: flex;
245
+ flex-direction: column;
246
+ gap: 2px;
247
+ }
248
+ .metric b {
249
+ font-size: 20px;
250
+ font-weight: 800;
251
+ font-family: var(--font-display);
252
+ font-variant-numeric: tabular-nums;
253
+ letter-spacing: -0.02em;
254
+ }
255
+ .metric span {
256
+ font-size: 10px;
257
+ color: var(--text-3);
258
+ text-transform: none;
259
+ }
260
+ .metric[data-hot="true"] b { color: var(--accent); }
261
+
262
+ /* ---- Main grid ---- */
263
+ .main {
264
+ display: grid;
265
+ grid-template-columns: 380px 1fr 360px;
266
+ gap: 1px;
267
+ background: var(--border);
268
+ min-height: 0;
269
+ }
270
+
271
+ .panel {
272
+ background: var(--bg);
273
+ display: flex;
274
+ flex-direction: column;
275
+ min-height: 0;
276
+ min-width: 0;
277
+ }
278
+
279
+ .panel > header {
280
+ display: flex;
281
+ align-items: center;
282
+ gap: var(--sp-2);
283
+ padding: var(--sp-3) var(--sp-4);
284
+ border-bottom: 1px solid var(--border);
285
+ background: var(--surface);
286
+ position: sticky;
287
+ top: var(--topbar-h);
288
+ z-index: 10;
289
+ }
290
+ .panel > header h2 {
291
+ font-size: 12px;
292
+ font-weight: 700;
293
+ color: var(--text-2);
294
+ }
295
+ .panel > header .count {
296
+ margin-left: auto;
297
+ font-size: 11px;
298
+ color: var(--text-3);
299
+ font-variant-numeric: tabular-nums;
300
+ }
301
+ .panel-body {
302
+ flex: 1;
303
+ overflow-y: auto;
304
+ padding: var(--sp-4);
305
+ min-height: 0;
306
+ overscroll-behavior: contain;
307
+ }
308
+
309
+ /* ============================================================
310
+ Mesa visual (SVG)
311
+ ============================================================ */
312
+ .mesa-wrap {
313
+ position: relative;
314
+ }
315
+ #mesa-svg {
316
+ display: block;
317
+ width: 100%;
318
+ height: auto;
319
+ }
320
+
321
+ .agent-node { cursor: default; }
322
+ .agent-node circle.seat {
323
+ fill: var(--surface-2);
324
+ stroke: var(--border-strong);
325
+ stroke-width: 1.5;
326
+ transition: stroke var(--t-ui) var(--ease-out);
327
+ }
328
+ .agent-node[data-state="working"] circle.seat {
329
+ stroke: var(--accent);
330
+ box-shadow: 0 0 8px var(--glow-accent);
331
+ }
332
+ .agent-node[data-state="idle_available"] circle.seat { stroke: var(--ok); }
333
+ .agent-node[data-state="stale"] circle.seat { stroke: var(--err); }
334
+ .agent-node text {
335
+ fill: var(--text-2);
336
+ font-family: var(--font-mono);
337
+ font-size: 10px;
338
+ }
339
+ .agent-node text.name {
340
+ fill: var(--text);
341
+ font-weight: 700;
342
+ }
343
+ .pulse {
344
+ transform-origin: center;
345
+ transform-box: fill-box;
346
+ animation: pulse 2.4s var(--ease-in-out) infinite;
347
+ }
348
+ @keyframes pulse {
349
+ 0%, 100% { opacity: 0.55; transform: scale(1); }
350
+ 50% { opacity: 0.1; transform: scale(1.18); }
351
+ }
352
+
353
+ .mesa-legend {
354
+ display: flex;
355
+ flex-wrap: wrap;
356
+ gap: var(--sp-3);
357
+ padding: var(--sp-3) var(--sp-4);
358
+ font-size: 10px;
359
+ color: var(--text-3);
360
+ }
361
+ .mesa-legend i {
362
+ display: inline-block;
363
+ width: 8px; height: 8px;
364
+ border-radius: 50%;
365
+ margin-right: 4px;
366
+ vertical-align: middle;
367
+ }
368
+
369
+ /* ============================================================
370
+ Bus de mensajes
371
+ ============================================================ */
372
+ .bus-stream {
373
+ display: flex;
374
+ flex-direction: column;
375
+ gap: var(--sp-2);
376
+ }
377
+
378
+ .msg {
379
+ border: 1px solid var(--border);
380
+ border-left: 3px solid var(--text-3);
381
+ border-radius: var(--r-md);
382
+ background: var(--surface);
383
+ padding: var(--sp-2) var(--sp-3);
384
+ transition: border-color var(--t-ui) var(--ease-out), transform var(--t-ui) var(--ease-out);
385
+ animation: msg-in var(--t-slow) var(--ease-out) backwards;
386
+ content-visibility: auto;
387
+ contain-intrinsic-size: auto 64px;
388
+ }
389
+ @keyframes msg-in {
390
+ from { opacity: 0; transform: translateY(8px); }
391
+ to { opacity: 1; transform: none; }
392
+ }
393
+ .msg:hover { border-left-width: 3px; transform: translateY(-1px); }
394
+
395
+ .msg .head {
396
+ display: flex;
397
+ align-items: baseline;
398
+ gap: var(--sp-2);
399
+ font-size: 11px;
400
+ }
401
+ .msg .kind {
402
+ font-weight: 700;
403
+ font-size: 10px;
404
+ padding: 4px 8px;
405
+ border-radius: 3px;
406
+ letter-spacing: 0.02em;
407
+ }
408
+ .msg .kind[data-kind^="HELP"] { background: var(--info-dim); color: var(--info-strong); }
409
+ .msg .kind[data-kind="STATUS"] { background: var(--ok-dim); color: var(--ok-strong); }
410
+ .msg .kind[data-kind^="SPAWN"] { background: var(--accent-dim); color: var(--accent-strong); }
411
+ .msg .kind[data-kind^="CLAIM"],
412
+ .msg .kind[data-kind="RELEASE"] { background: var(--err-dim); color: var(--err-strong); }
413
+ .msg .kind[data-kind="NOTICE"],
414
+ .msg .kind[data-kind="ANSWER"],
415
+ .msg .kind[data-kind="QUESTION"] { background: var(--surface-3); color: var(--text-2); }
416
+
417
+ .msg .route { color: var(--text-2); }
418
+ .msg .route .arrow { color: var(--accent); }
419
+ .msg .time { margin-left: auto; color: var(--text-3); font-size: 10px; font-variant-numeric: tabular-nums; }
420
+
421
+ .msg .subject {
422
+ margin-top: 2px;
423
+ font-size: 12px;
424
+ color: var(--text);
425
+ font-weight: 600;
426
+ }
427
+ .msg .body {
428
+ margin-top: 4px;
429
+ font-size: 11px;
430
+ color: var(--text-2);
431
+ display: -webkit-box;
432
+ -webkit-line-clamp: 3;
433
+ -webkit-box-orient: vertical;
434
+ overflow: hidden;
435
+ }
436
+ .msg.expanded .body { -webkit-line-clamp: unset; }
437
+ .msg .prio {
438
+ font-size: 9px;
439
+ padding: 4px 8px;
440
+ border-radius: 3px;
441
+ border: 1px solid var(--border-strong);
442
+ color: var(--text-3);
443
+ }
444
+ .msg .prio[data-prio="critical"] { border-color: var(--err); color: var(--err); }
445
+ .msg .prio[data-prio="high"] { border-color: var(--accent); color: var(--accent); }
446
+ .msg[data-priority="critical"] { border-left-color: var(--err); }
447
+ .msg[data-priority="high"] { border-left-color: var(--accent); }
448
+ .msg[data-priority="normal"] { border-left-color: var(--border-strong); }
449
+ .msg[data-priority="low"] { border-left-color: var(--text-3); }
450
+
451
+ .msg.threaded {
452
+ margin-left: var(--sp-5);
453
+ position: relative;
454
+ }
455
+ .msg.threaded::before {
456
+ content: "";
457
+ position: absolute;
458
+ left: -18px;
459
+ top: -2px;
460
+ bottom: 50%;
461
+ width: 12px;
462
+ border-left: 1px solid var(--border-strong);
463
+ border-bottom: 1px solid var(--border-strong);
464
+ border-bottom-left-radius: 6px;
465
+ }
466
+
467
+ /* ---- Jefe: decisiones ---- */
468
+ .chief-feed { display: flex; flex-direction: column; gap: var(--sp-2); }
469
+ .chief-item {
470
+ display: grid;
471
+ grid-template-columns: 76px 1fr;
472
+ gap: var(--sp-3);
473
+ padding: var(--sp-3);
474
+ border: 1px solid var(--border);
475
+ border-radius: var(--r-md);
476
+ background: var(--surface);
477
+ }
478
+ .chief-item .who {
479
+ font-family: var(--font-display);
480
+ font-weight: 700;
481
+ font-size: 11px;
482
+ color: var(--text-2);
483
+ }
484
+ .chief-item[data-who="Commander"] .who { color: var(--accent); }
485
+ .chief-item[data-who="Integrator"] .who { color: var(--info); }
486
+ .chief-item[data-who="Architect"] .who { color: var(--peer); }
487
+ .chief-item .what { font-size: 11px; color: var(--text-2); }
488
+ .chief-item .what b { color: var(--text); font-weight: 600; }
489
+
490
+ /* ============================================================
491
+ Kanban
492
+ ============================================================ */
493
+ .board-section { padding: var(--sp-4); }
494
+ .board-title { padding: var(--sp-4) var(--sp-4) 0; }
495
+
496
+ .board {
497
+ display: grid;
498
+ grid-auto-flow: column;
499
+ grid-auto-columns: 240px;
500
+ gap: var(--sp-3);
501
+ overflow-x: auto;
502
+ padding-bottom: var(--sp-3);
503
+ scroll-snap-type: x proximity;
504
+ overscroll-behavior-x: contain;
505
+ }
506
+
507
+ .col { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; scroll-snap-align: start; }
508
+ .col > header {
509
+ display: flex;
510
+ align-items: center;
511
+ gap: var(--sp-2);
512
+ padding: var(--sp-2) var(--sp-3);
513
+ border-radius: var(--r-md);
514
+ background: var(--surface);
515
+ border: 1px solid var(--border);
516
+ font-size: 11px;
517
+ color: var(--text-2);
518
+ }
519
+ .col > header .n {
520
+ margin-left: auto;
521
+ font-size: 10px;
522
+ color: var(--text-3);
523
+ font-variant-numeric: tabular-nums;
524
+ }
525
+ .col > header i {
526
+ width: 8px; height: 8px;
527
+ border-radius: 2px;
528
+ }
529
+ .col[data-state="todo"] > header i { background: var(--card-todo); }
530
+ .col[data-state="in_progress"] > header i { background: var(--card-progress); }
531
+ .col[data-state="review"] > header i { background: var(--card-review); }
532
+ .col[data-state="done"] > header i { background: var(--card-done); }
533
+ .col[data-state="rework"] > header i { background: var(--card-rework); }
534
+ .col[data-state="blocked"] > header i { background: var(--card-blocked); }
535
+ .col[data-state="escalated"] > header i { background: var(--card-escalated); }
536
+
537
+ .card {
538
+ border: 1px solid var(--border);
539
+ border-top: 2px solid var(--text-3);
540
+ border-radius: var(--r-md);
541
+ background: var(--surface-2);
542
+ padding: var(--sp-3);
543
+ display: flex;
544
+ flex-direction: column;
545
+ gap: var(--sp-2);
546
+ transition: border-top-color var(--t-ui) var(--ease-out), transform var(--t-ui) var(--ease-out);
547
+ content-visibility: auto;
548
+ contain-intrinsic-size: auto 110px;
549
+ touch-action: manipulation;
550
+ }
551
+ .card:hover { transform: translateY(-2px); }
552
+ .card[data-state="todo"] { border-top-color: var(--card-todo); }
553
+ .card[data-state="in_progress"] { border-top-color: var(--card-progress); }
554
+ .card[data-state="review"] { border-top-color: var(--card-review); }
555
+ .card[data-state="done"] { border-top-color: var(--card-done); }
556
+ .card[data-state="rework"] { border-top-color: var(--card-rework); }
557
+ .card[data-state="blocked"] { border-top-color: var(--card-blocked); }
558
+ .card[data-state="escalated"] { border-top-color: var(--card-escalated); }
559
+
560
+ .card .cid {
561
+ font-size: 10px;
562
+ color: var(--text-3);
563
+ display: flex;
564
+ gap: var(--sp-2);
565
+ align-items: baseline;
566
+ }
567
+ .card .cid .rejected { color: var(--err); font-weight: 700; }
568
+ .card .title {
569
+ font-family: var(--font-display);
570
+ font-weight: 600;
571
+ font-size: 12px;
572
+ line-height: 1.4;
573
+ color: var(--text);
574
+ }
575
+ .card .people {
576
+ display: flex;
577
+ gap: var(--sp-2);
578
+ font-size: 10px;
579
+ color: var(--text-2);
580
+ }
581
+ .card .people .none { color: var(--text-3); font-style: italic; }
582
+ .card .ac { display: flex; flex-direction: column; gap: 2px; }
583
+ .card .ac label {
584
+ display: flex;
585
+ gap: 8px;
586
+ align-items: baseline;
587
+ font-size: 10px;
588
+ color: var(--text-2);
589
+ cursor: default;
590
+ }
591
+ .card .ac input { accent-color: var(--ok); }
592
+ .card .ac input:disabled {
593
+ accent-color: var(--text-3);
594
+ filter: grayscale(1);
595
+ cursor: not-allowed;
596
+ }
597
+ .card.gate-flash {
598
+ animation: gate-flash 600ms var(--ease-out) 3;
599
+ }
600
+ @keyframes gate-flash {
601
+ 0%, 100% { opacity: 1; }
602
+ 50% { opacity: 0.55; }
603
+ }
604
+
605
+ /* ============================================================
606
+ Gates
607
+ ============================================================ */
608
+ .gates-panel { display: flex; flex-direction: column; gap: var(--sp-2); }
609
+ .gate-row {
610
+ display: grid;
611
+ grid-template-columns: 14px 1fr auto;
612
+ align-items: center;
613
+ gap: var(--sp-2);
614
+ padding: var(--sp-2) var(--sp-3);
615
+ border-radius: var(--r-md);
616
+ border: 1px solid var(--border);
617
+ background: var(--surface);
618
+ font-size: 11px;
619
+ }
620
+ .gate-row .icon { display: inline-flex; justify-content: center; }
621
+ .gate-row[data-status="run"] .icon .spin {
622
+ width: 10px; height: 10px;
623
+ border: 2px solid var(--border-strong);
624
+ border-top-color: var(--accent);
625
+ border-radius: 50%;
626
+ animation: spin 800ms linear infinite;
627
+ }
628
+ @keyframes spin { to { transform: rotate(360deg); } }
629
+ .gate-row[data-status="pass"] { border-color: var(--ok-dim); }
630
+ .gate-row[data-status="pass"] .icon { color: var(--ok); }
631
+ .gate-row[data-status="fail"] { border-color: var(--err-dim); }
632
+ .gate-row[data-status="fail"] .icon { color: var(--err); }
633
+ .gate-row .name { color: var(--text-2); }
634
+ .gate-row .status { font-size: 10px; color: var(--text-3); }
635
+ .gate-row[data-status="pass"] .status { color: var(--ok); }
636
+ .gate-row[data-status="fail"] .status { color: var(--err); }
637
+
638
+ .gates-links {
639
+ display: flex;
640
+ gap: var(--sp-3);
641
+ padding-top: var(--sp-2);
642
+ }
643
+ .gates-links a {
644
+ font-size: 10px;
645
+ color: var(--info);
646
+ text-decoration: none;
647
+ border-bottom: 1px dashed var(--info);
648
+ }
649
+ .gates-links a:hover { color: var(--text); border-bottom-color: var(--text); }
650
+
651
+ /* ============================================================
652
+ Factory toast
653
+ ============================================================ */
654
+ .toasts {
655
+ position: fixed;
656
+ bottom: var(--sp-5);
657
+ right: var(--sp-5);
658
+ display: flex;
659
+ flex-direction: column;
660
+ gap: var(--sp-2);
661
+ z-index: 50;
662
+ }
663
+ .toast {
664
+ display: flex;
665
+ align-items: center;
666
+ gap: var(--sp-3);
667
+ padding: var(--sp-3) var(--sp-4);
668
+ background: var(--surface-2);
669
+ border: 1px solid var(--border-strong);
670
+ border-radius: var(--r-md);
671
+ box-shadow: var(--shadow-lift);
672
+ font-size: 12px;
673
+ transform-origin: bottom right;
674
+ animation: toast-in var(--t-slow) var(--ease-out) backwards;
675
+ }
676
+ @keyframes toast-in {
677
+ from { opacity: 0; transform: scale(0.95) translateY(8px); }
678
+ to { opacity: 1; transform: none; }
679
+ }
680
+ .toast.leaving { opacity: 0; transform: scale(0.95) translateY(8px); }
681
+ .toast .icon { color: var(--accent); }
682
+ .toast[data-kind="spawn"] .icon { color: var(--peer); }
683
+ .toast[data-kind="gate"] .icon { color: var(--ok); }
684
+ .toast[data-kind="gate-fail"] .icon { color: var(--err); }
685
+
686
+ /* ============================================================
687
+ Replay
688
+ ============================================================ */
689
+ .replay {
690
+ display: flex;
691
+ align-items: center;
692
+ gap: var(--sp-3);
693
+ padding: var(--sp-2) var(--sp-5);
694
+ border-top: 1px solid var(--border);
695
+ background: var(--surface);
696
+ }
697
+ .replay input[type="range"] {
698
+ flex: 1;
699
+ accent-color: var(--accent);
700
+ }
701
+ .replay .clock {
702
+ font-size: 11px;
703
+ color: var(--text-2);
704
+ min-width: 130px;
705
+ font-variant-numeric: tabular-nums;
706
+ }
707
+ .replay[hidden] { display: none; }
708
+
709
+ /* ---- Demo banner ---- */
710
+ .demo-banner {
711
+ padding: var(--sp-2) var(--sp-5);
712
+ background: var(--accent-dim);
713
+ color: var(--accent-strong);
714
+ font-size: 11px;
715
+ border-bottom: 1px solid var(--border);
716
+ }
717
+ .demo-banner[hidden] { display: none; }
718
+
719
+ /* ---- Empty states (ai-slop: honestos) ---- */
720
+ .empty {
721
+ padding: var(--sp-6) var(--sp-4);
722
+ text-align: center;
723
+ color: var(--text-3);
724
+ font-size: 12px;
725
+ }
726
+ .empty code { color: var(--text-2); }
727
+
728
+ /* ============================================================
729
+ Responsive
730
+ ============================================================ */
731
+ @media (max-width: 1280px) {
732
+ .main { grid-template-columns: 320px 1fr; }
733
+ .main .panel-right { grid-column: 1 / -1; }
734
+ }
735
+ @media (max-width: 860px) {
736
+ .main { grid-template-columns: 1fr; }
737
+ .metrics { grid-template-columns: repeat(3, 1fr); }
738
+ .topbar { flex-wrap: wrap; }
739
+ .panel { border-bottom: 1px solid var(--border); }
740
+ }
741
+
742
+ /* ============================================================
743
+ Reduced motion
744
+ ============================================================ */
745
+ @media (prefers-reduced-motion: reduce) {
746
+ *,
747
+ *::before,
748
+ *::after {
749
+ animation-duration: 0.01ms !important;
750
+ animation-iteration-count: 1 !important;
751
+ transition-duration: 0.01ms !important;
752
+ }
753
+ }