trackops 1.0.0 → 1.1.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 (72) hide show
  1. package/README.md +341 -232
  2. package/bin/trackops.js +102 -70
  3. package/lib/config.js +260 -35
  4. package/lib/control.js +518 -475
  5. package/lib/env.js +227 -0
  6. package/lib/i18n.js +61 -53
  7. package/lib/init.js +146 -55
  8. package/lib/locale.js +63 -0
  9. package/lib/opera-bootstrap.js +523 -0
  10. package/lib/opera.js +319 -170
  11. package/lib/registry.js +27 -13
  12. package/lib/release.js +56 -0
  13. package/lib/resources.js +42 -0
  14. package/lib/server.js +912 -418
  15. package/lib/skills.js +148 -124
  16. package/lib/workspace.js +260 -0
  17. package/locales/en.json +331 -139
  18. package/locales/es.json +331 -139
  19. package/package.json +14 -3
  20. package/scripts/skills-marketplace-smoke.js +124 -0
  21. package/scripts/smoke-tests.js +445 -0
  22. package/scripts/sync-skill-version.js +21 -0
  23. package/scripts/validate-skill.js +88 -0
  24. package/skills/trackops/SKILL.md +64 -0
  25. package/skills/trackops/agents/openai.yaml +3 -0
  26. package/skills/trackops/references/activation.md +39 -0
  27. package/skills/trackops/references/troubleshooting.md +34 -0
  28. package/skills/trackops/references/workflow.md +20 -0
  29. package/skills/trackops/scripts/bootstrap-trackops.js +201 -0
  30. package/skills/trackops/skill.json +29 -0
  31. package/templates/etapa/agent.md +2 -2
  32. package/templates/etapa/references/etapa-cycle.md +1 -1
  33. package/templates/opera/agent.md +1 -1
  34. package/templates/opera/en/agent.md +26 -0
  35. package/templates/opera/en/genesis.md +79 -0
  36. package/templates/opera/en/references/autonomy-and-recovery.md +23 -0
  37. package/templates/opera/en/references/opera-cycle.md +62 -0
  38. package/templates/opera/en/registry.md +28 -0
  39. package/templates/opera/en/router.md +39 -0
  40. package/templates/opera/genesis.md +79 -94
  41. package/templates/skills/changelog-updater/locales/en/SKILL.md +11 -0
  42. package/templates/skills/commiter/locales/en/SKILL.md +11 -0
  43. package/templates/skills/project-starter-skill/SKILL.md +5 -3
  44. package/templates/skills/project-starter-skill/locales/en/SKILL.md +24 -0
  45. package/ui/css/base.css +266 -0
  46. package/ui/css/charts.css +327 -0
  47. package/ui/css/components.css +570 -0
  48. package/ui/css/panels.css +956 -0
  49. package/ui/css/tokens.css +227 -0
  50. package/ui/favicon.svg +5 -0
  51. package/ui/index.html +91 -351
  52. package/ui/js/api.js +220 -0
  53. package/ui/js/app.js +200 -0
  54. package/ui/js/console-logger.js +172 -0
  55. package/ui/js/i18n.js +14 -0
  56. package/ui/js/icons.js +104 -0
  57. package/ui/js/onboarding.js +439 -0
  58. package/ui/js/router.js +125 -0
  59. package/ui/js/state.js +130 -0
  60. package/ui/js/theme.js +100 -0
  61. package/ui/js/time-tracker.js +248 -0
  62. package/ui/js/utils.js +175 -0
  63. package/ui/js/views/board.js +255 -0
  64. package/ui/js/views/execution.js +256 -0
  65. package/ui/js/views/flash.js +47 -0
  66. package/ui/js/views/insights.js +340 -0
  67. package/ui/js/views/overview.js +365 -0
  68. package/ui/js/views/settings.js +381 -0
  69. package/ui/js/views/sidebar.js +131 -0
  70. package/ui/js/views/skills.js +163 -0
  71. package/ui/js/views/tasks.js +406 -0
  72. package/ui/js/views/topbar.js +239 -0
@@ -0,0 +1,956 @@
1
+ /* ═══════════════════════════════════════════════════════
2
+ PANELS — Sidebar, Topbar, Modals, Flash, Kanban
3
+ ═══════════════════════════════════════════════════════ */
4
+
5
+ /* ───────────────────────────────────
6
+ SIDEBAR
7
+ ─────────────────────────────────── */
8
+ .sidebar {
9
+ display: flex;
10
+ flex-direction: column;
11
+ height: 100%;
12
+ background: var(--surface-1);
13
+ border-right: 1px solid var(--border);
14
+ padding: var(--space-5) 0;
15
+ gap: 0;
16
+ }
17
+
18
+ /* Logo */
19
+ .sidebar-logo {
20
+ display: flex;
21
+ align-items: center;
22
+ gap: var(--space-3);
23
+ padding: 0 var(--space-5) var(--space-5);
24
+ border-bottom: 1px solid var(--border);
25
+ margin-bottom: var(--space-4);
26
+ text-decoration: none;
27
+ color: var(--text-primary);
28
+ }
29
+ .sidebar-logo:hover { color: var(--text-primary); }
30
+
31
+ .sidebar-logo-icon {
32
+ width: 36px;
33
+ height: 36px;
34
+ background: linear-gradient(135deg, var(--accent), #4F46E5);
35
+ border-radius: var(--radius-md);
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ flex-shrink: 0;
40
+ box-shadow: var(--shadow-accent);
41
+ }
42
+ .sidebar-logo-name {
43
+ font-family: var(--font-heading);
44
+ font-weight: 800;
45
+ font-size: var(--text-lg);
46
+ letter-spacing: -0.03em;
47
+ color: var(--text-primary);
48
+ }
49
+
50
+ /* Secciones */
51
+ .sidebar-section {
52
+ padding: 0 var(--space-3);
53
+ flex: 1;
54
+ overflow-y: auto;
55
+ }
56
+ .sidebar-section + .sidebar-section {
57
+ border-top: 1px solid var(--border);
58
+ padding-top: var(--space-4);
59
+ margin-top: var(--space-4);
60
+ }
61
+
62
+ .sidebar-section-label {
63
+ font-size: var(--text-xs);
64
+ font-weight: 700;
65
+ letter-spacing: 0.12em;
66
+ text-transform: uppercase;
67
+ color: var(--text-muted);
68
+ padding: 0 var(--space-3) var(--space-2);
69
+ }
70
+
71
+ /* Nav items */
72
+ .sidebar-nav { display: flex; flex-direction: column; gap: var(--space-1); }
73
+
74
+ .nav-item {
75
+ display: flex;
76
+ align-items: center;
77
+ gap: var(--space-3);
78
+ padding: 0.55rem var(--space-3);
79
+ border-radius: var(--radius-md);
80
+ font-size: var(--text-sm);
81
+ font-weight: 500;
82
+ color: var(--text-secondary);
83
+ cursor: pointer;
84
+ border: 1px solid transparent;
85
+ text-decoration: none;
86
+ transition:
87
+ background var(--duration-fast) var(--ease-out),
88
+ color var(--duration-fast) var(--ease-out),
89
+ border-color var(--duration-fast) var(--ease-out);
90
+ position: relative;
91
+ user-select: none;
92
+ min-height: 40px;
93
+ }
94
+ .nav-item:hover {
95
+ background: var(--surface-3);
96
+ color: var(--text-primary);
97
+ }
98
+ .nav-item.is-active {
99
+ background: var(--accent-light);
100
+ color: var(--text-accent);
101
+ border-color: var(--border-accent);
102
+ font-weight: 700;
103
+ }
104
+ .nav-item-icon {
105
+ flex-shrink: 0;
106
+ width: 18px;
107
+ height: 18px;
108
+ opacity: 0.7;
109
+ }
110
+ .nav-item.is-active .nav-item-icon { opacity: 1; }
111
+
112
+ .nav-item-label { flex: 1; min-width: 0; }
113
+ .nav-item-badge {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ min-width: 20px;
118
+ height: 20px;
119
+ padding: 0 5px;
120
+ font-size: 0.65rem;
121
+ font-weight: 800;
122
+ border-radius: var(--radius-full);
123
+ background: var(--accent);
124
+ color: white;
125
+ }
126
+ .nav-item-badge.danger { background: var(--danger); }
127
+
128
+ /* Sidebar footer */
129
+ .sidebar-footer {
130
+ padding: var(--space-4) var(--space-3) 0;
131
+ border-top: 1px solid var(--border);
132
+ margin-top: auto;
133
+ flex-shrink: 0;
134
+ display: flex;
135
+ flex-direction: column;
136
+ gap: var(--space-1);
137
+ }
138
+
139
+ /* ───────────────────────────────────
140
+ TOPBAR
141
+ ─────────────────────────────────── */
142
+ .topbar {
143
+ height: var(--topbar-height);
144
+ background: rgba(10, 15, 30, 0.85);
145
+ backdrop-filter: blur(20px);
146
+ -webkit-backdrop-filter: blur(20px);
147
+ border-bottom: 1px solid var(--border);
148
+ display: flex;
149
+ align-items: center;
150
+ padding: 0 var(--content-pad);
151
+ gap: var(--space-4);
152
+ }
153
+
154
+ .topbar-search {
155
+ flex: 1;
156
+ max-width: 380px;
157
+ }
158
+
159
+ .topbar-right {
160
+ display: flex;
161
+ align-items: center;
162
+ gap: var(--space-3);
163
+ margin-left: auto;
164
+ }
165
+
166
+ .topbar-project-selector {
167
+ display: flex;
168
+ align-items: center;
169
+ gap: var(--space-2);
170
+ }
171
+
172
+ .project-select-wrapper {
173
+ position: relative;
174
+ }
175
+ .project-select-wrapper select {
176
+ min-width: 220px;
177
+ background-color: var(--surface-2);
178
+ font-size: var(--text-sm);
179
+ height: 36px;
180
+ padding: 0 2.5rem 0 0.85rem;
181
+ }
182
+ .locale-select-wrapper select {
183
+ min-width: 110px;
184
+ }
185
+
186
+ .repo-badge {
187
+ display: flex;
188
+ align-items: center;
189
+ gap: var(--space-2);
190
+ padding: 0.3rem 0.75rem;
191
+ border-radius: var(--radius-full);
192
+ font-size: var(--text-xs);
193
+ font-weight: 600;
194
+ border: 1px solid transparent;
195
+ white-space: nowrap;
196
+ }
197
+ .repo-badge.clean {
198
+ background: var(--success-light);
199
+ border-color: rgba(16,185,129,0.2);
200
+ color: var(--success);
201
+ }
202
+ .repo-badge.dirty {
203
+ background: var(--warning-light);
204
+ border-color: rgba(245,158,11,0.2);
205
+ color: var(--warning);
206
+ }
207
+ .repo-badge-dot {
208
+ width: 6px;
209
+ height: 6px;
210
+ border-radius: 50%;
211
+ flex-shrink: 0;
212
+ }
213
+ .clean .repo-badge-dot { background: var(--success); animation: pulse 2s infinite; }
214
+ .dirty .repo-badge-dot { background: var(--warning); }
215
+
216
+ /* Hamburger (mobile) */
217
+ .topbar-hamburger {
218
+ display: none;
219
+ flex-direction: column;
220
+ gap: 5px;
221
+ padding: var(--space-2);
222
+ border-radius: var(--radius-sm);
223
+ cursor: pointer;
224
+ border: 1px solid var(--border);
225
+ background: var(--surface-2);
226
+ }
227
+ .topbar-hamburger span {
228
+ display: block;
229
+ width: 18px;
230
+ height: 2px;
231
+ background: var(--text-primary);
232
+ border-radius: 2px;
233
+ transition: transform var(--duration-base) var(--ease-out), opacity var(--duration-base);
234
+ }
235
+
236
+ @media (max-width: 1024px) {
237
+ .topbar-hamburger { display: flex; }
238
+ }
239
+
240
+ /* ───────────────────────────────────
241
+ TIME TRACKER WIDGET (en topbar)
242
+ ─────────────────────────────────── */
243
+ .topbar-timer {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: var(--space-2);
247
+ padding: 0.3rem 0.85rem;
248
+ background: var(--surface-2);
249
+ border: 1px solid var(--border);
250
+ border-radius: var(--radius-full);
251
+ font-family: var(--font-mono);
252
+ font-size: var(--text-sm);
253
+ font-weight: 700;
254
+ color: var(--text-primary);
255
+ letter-spacing: 0.04em;
256
+ }
257
+ .topbar-timer.is-running {
258
+ border-color: var(--border-accent);
259
+ background: var(--accent-light);
260
+ color: var(--text-accent);
261
+ }
262
+ .topbar-timer-dot {
263
+ width: 6px;
264
+ height: 6px;
265
+ border-radius: 50%;
266
+ background: var(--text-muted);
267
+ flex-shrink: 0;
268
+ }
269
+ .topbar-timer.is-running .topbar-timer-dot {
270
+ background: var(--accent);
271
+ animation: pulse 1s infinite;
272
+ }
273
+
274
+ /* ───────────────────────────────────
275
+ PANEL SECTION (contenedores de vistas)
276
+ ─────────────────────────────────── */
277
+ .panel {
278
+ background: var(--surface-2);
279
+ border: 1px solid var(--border);
280
+ border-radius: var(--radius-xl);
281
+ overflow: hidden;
282
+ }
283
+
284
+ .panel-header {
285
+ display: flex;
286
+ align-items: center;
287
+ justify-content: space-between;
288
+ padding: var(--space-5) var(--space-5) var(--space-4);
289
+ border-bottom: 1px solid var(--border);
290
+ gap: var(--space-4);
291
+ }
292
+ .panel-header-left { display: flex; flex-direction: column; gap: var(--space-1); }
293
+ .panel-header-right { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
294
+ .panel-title { font-size: var(--text-md); font-weight: 700; margin: 0; }
295
+ .panel-subtitle { font-size: var(--text-xs); color: var(--text-muted); }
296
+
297
+ .panel-body { padding: var(--space-5); }
298
+ .panel-footer {
299
+ padding: var(--space-4) var(--space-5);
300
+ border-top: 1px solid var(--border);
301
+ background: var(--surface-4);
302
+ }
303
+
304
+ /* ───────────────────────────────────
305
+ KANBAN BOARD
306
+ ─────────────────────────────────── */
307
+ .board-grid {
308
+ display: grid;
309
+ grid-auto-flow: column;
310
+ grid-auto-columns: minmax(260px, 1fr);
311
+ gap: var(--space-3);
312
+ overflow-x: auto;
313
+ padding-bottom: var(--space-4);
314
+ min-height: 500px;
315
+ align-items: start;
316
+ }
317
+
318
+ .board-column {
319
+ background: var(--surface-1);
320
+ border: 1px solid var(--border);
321
+ border-radius: var(--radius-lg);
322
+ padding: var(--space-3);
323
+ min-height: 400px;
324
+ transition: border-color var(--duration-fast), background var(--duration-fast);
325
+ }
326
+ .board-column.is-drop-target {
327
+ border-color: var(--border-accent);
328
+ background: rgba(99,102,241,0.04);
329
+ }
330
+
331
+ .board-column-header {
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: space-between;
335
+ margin-bottom: var(--space-3);
336
+ padding: 0 var(--space-1);
337
+ }
338
+ .board-column-title {
339
+ font-size: var(--text-sm);
340
+ font-weight: 700;
341
+ margin: 0;
342
+ display: flex;
343
+ align-items: center;
344
+ gap: var(--space-2);
345
+ }
346
+ .board-column-dot {
347
+ width: 8px; height: 8px;
348
+ border-radius: 50%;
349
+ flex-shrink: 0;
350
+ }
351
+ .col-pending .board-column-dot { background: var(--warning); }
352
+ .col-in_progress .board-column-dot { background: var(--info); }
353
+ .col-in_review .board-column-dot { background: var(--accent); }
354
+ .col-blocked .board-column-dot { background: var(--danger); }
355
+ .col-completed .board-column-dot { background: var(--success); }
356
+ .col-cancelled .board-column-dot { background: var(--text-muted); }
357
+
358
+ .board-column-count {
359
+ min-width: 24px;
360
+ height: 24px;
361
+ border-radius: var(--radius-full);
362
+ background: var(--surface-3);
363
+ font-size: var(--text-xs);
364
+ font-weight: 700;
365
+ display: flex;
366
+ align-items: center;
367
+ justify-content: center;
368
+ padding: 0 var(--space-2);
369
+ }
370
+
371
+ .board-column-body { display: flex; flex-direction: column; gap: var(--space-2); }
372
+
373
+ /* ───────────────────────────────────
374
+ TERMINAL SURFACE
375
+ ─────────────────────────────────── */
376
+ .terminal-surface {
377
+ background: #060a14;
378
+ border: 1px solid rgba(255,255,255,0.05);
379
+ border-radius: var(--radius-lg);
380
+ overflow: hidden;
381
+ }
382
+ .terminal-header {
383
+ display: flex;
384
+ align-items: center;
385
+ justify-content: space-between;
386
+ padding: var(--space-2) var(--space-4);
387
+ background: rgba(255,255,255,0.03);
388
+ border-bottom: 1px solid rgba(255,255,255,0.04);
389
+ gap: var(--space-3);
390
+ }
391
+ .terminal-dots { display: flex; gap: var(--space-2); align-items: center; }
392
+ .terminal-dots span {
393
+ width: 10px; height: 10px;
394
+ border-radius: 50%;
395
+ }
396
+ .terminal-dots span:nth-child(1) { background: #EF4444; }
397
+ .terminal-dots span:nth-child(2) { background: #F59E0B; }
398
+ .terminal-dots span:nth-child(3) { background: #10B981; }
399
+ .terminal-title {
400
+ font-family: var(--font-mono);
401
+ font-size: var(--text-xs);
402
+ color: var(--text-muted);
403
+ flex: 1;
404
+ text-align: center;
405
+ }
406
+ .terminal-output {
407
+ margin: 0;
408
+ padding: var(--space-5);
409
+ font-family: var(--font-mono);
410
+ font-size: var(--text-xs);
411
+ line-height: 1.7;
412
+ color: #94D4BC;
413
+ min-height: 280px;
414
+ max-height: 460px;
415
+ overflow-y: auto;
416
+ white-space: pre-wrap;
417
+ word-break: break-all;
418
+ }
419
+
420
+ /* ───────────────────────────────────
421
+ FLASH / TOAST
422
+ ─────────────────────────────────── */
423
+ #flash-container {
424
+ position: fixed;
425
+ right: var(--space-6);
426
+ bottom: var(--space-6);
427
+ z-index: var(--z-toast);
428
+ display: flex;
429
+ flex-direction: column;
430
+ gap: var(--space-2);
431
+ pointer-events: none;
432
+ max-width: 380px;
433
+ width: 100%;
434
+ }
435
+
436
+ .flash {
437
+ padding: var(--space-4) var(--space-5);
438
+ border-radius: var(--radius-lg);
439
+ background: var(--surface-2);
440
+ border: 1px solid var(--border-strong);
441
+ box-shadow: var(--shadow-lg);
442
+ color: var(--text-primary);
443
+ font-size: var(--text-sm);
444
+ font-weight: 500;
445
+ display: flex;
446
+ align-items: center;
447
+ gap: var(--space-3);
448
+ pointer-events: all;
449
+ animation: slideInRight var(--duration-slow) var(--ease-out) both;
450
+ backdrop-filter: blur(20px);
451
+ }
452
+ .flash.flash-success { border-color: rgba(16,185,129,0.3); }
453
+ .flash.flash-error { background: rgba(239,68,68,0.15); border-color: rgba(239,68,68,0.3); }
454
+ .flash.flash-warning { border-color: rgba(245,158,11,0.3); }
455
+ .flash.flash-exit { animation: slideInRight var(--duration-base) var(--ease-in) reverse; }
456
+
457
+ /* ───────────────────────────────────
458
+ MODAL
459
+ ─────────────────────────────────── */
460
+ .modal-overlay {
461
+ position: fixed;
462
+ inset: 0;
463
+ background: rgba(0,0,0,0.7);
464
+ backdrop-filter: blur(8px);
465
+ z-index: var(--z-modal);
466
+ display: flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ padding: var(--space-6);
470
+ animation: fadeIn var(--duration-base) var(--ease-out);
471
+ }
472
+ .modal-overlay.is-hidden { display: none; }
473
+
474
+ .modal {
475
+ background: var(--surface-2);
476
+ border: 1px solid var(--border-strong);
477
+ border-radius: var(--radius-xl);
478
+ width: 100%;
479
+ max-width: 540px;
480
+ max-height: 90dvh;
481
+ overflow-y: auto;
482
+ box-shadow: var(--shadow-xl);
483
+ animation: fadeInUp var(--duration-slow) var(--ease-out);
484
+ }
485
+ .modal-header {
486
+ display: flex;
487
+ align-items: center;
488
+ justify-content: space-between;
489
+ padding: var(--space-5) var(--space-6);
490
+ border-bottom: 1px solid var(--border);
491
+ }
492
+ .modal-title { font-size: var(--text-md); font-weight: 700; margin: 0; }
493
+ .modal-body { padding: var(--space-6); }
494
+ .modal-footer {
495
+ padding: var(--space-4) var(--space-6);
496
+ border-top: 1px solid var(--border);
497
+ display: flex;
498
+ justify-content: flex-end;
499
+ gap: var(--space-3);
500
+ }
501
+ .modal-close {
502
+ width: 32px; height: 32px;
503
+ border-radius: var(--radius-sm);
504
+ display: flex; align-items: center; justify-content: center;
505
+ color: var(--text-muted);
506
+ background: var(--surface-3);
507
+ border: 1px solid var(--border);
508
+ cursor: pointer;
509
+ transition: background var(--duration-fast);
510
+ }
511
+ .modal-close:hover { background: var(--surface-4); color: var(--text-primary); }
512
+
513
+ /* ───────────────────────────────────
514
+ CONSOLE LOGS PANEL
515
+ ─────────────────────────────────── */
516
+ .console-panel {
517
+ position: fixed;
518
+ bottom: 0;
519
+ left: var(--sidebar-width);
520
+ right: 0;
521
+ z-index: var(--z-panel);
522
+ background: #060a14;
523
+ border-top: 1px solid var(--border);
524
+ transition: transform var(--duration-slow) var(--ease-out);
525
+ transform: translateY(100%);
526
+ }
527
+ .console-panel.is-open {
528
+ transform: translateY(0);
529
+ }
530
+ .console-panel-header {
531
+ display: flex;
532
+ align-items: center;
533
+ justify-content: space-between;
534
+ padding: var(--space-2) var(--space-4);
535
+ border-bottom: 1px solid rgba(255,255,255,0.04);
536
+ background: rgba(255,255,255,0.02);
537
+ }
538
+ .console-panel-title {
539
+ font-family: var(--font-mono);
540
+ font-size: var(--text-xs);
541
+ color: var(--text-muted);
542
+ display: flex;
543
+ align-items: center;
544
+ gap: var(--space-2);
545
+ }
546
+ .console-panel-actions {
547
+ display: flex;
548
+ gap: var(--space-2);
549
+ }
550
+ .console-logs {
551
+ overflow-y: auto;
552
+ max-height: 220px;
553
+ padding: var(--space-2) 0;
554
+ }
555
+ .console-log-entry {
556
+ display: grid;
557
+ grid-template-columns: auto auto 1fr;
558
+ gap: var(--space-3);
559
+ align-items: start;
560
+ padding: var(--space-1) var(--space-4);
561
+ font-family: var(--font-mono);
562
+ font-size: var(--text-xs);
563
+ line-height: 1.6;
564
+ border-bottom: 1px solid rgba(255,255,255,0.02);
565
+ }
566
+ .console-log-entry:hover { background: rgba(255,255,255,0.02); }
567
+ .console-log-time { color: var(--text-muted); white-space: nowrap; }
568
+ .log-level { font-weight: 700; white-space: nowrap; }
569
+ .log-error { color: var(--danger); }
570
+ .log-warn { color: var(--warning); }
571
+ .log-info { color: var(--info); }
572
+ .log-debug { color: var(--text-muted); }
573
+ .console-log-msg { color: var(--text-secondary); word-break: break-all; }
574
+
575
+ /* ───────────────────────────────────
576
+ ONBOARDING SPOTLIGHT (Tour)
577
+ ─────────────────────────────────── */
578
+ .onboarding-spotlight {
579
+ /* Los estilos inline de position, inset, box-shadow se inyectan por JS */
580
+ background: transparent;
581
+ z-index: var(--z-onboard);
582
+ pointer-events: none;
583
+ }
584
+ .onboarding-spotlight.is-hidden { display: none; }
585
+
586
+ .onboarding-ring {
587
+ box-sizing: border-box;
588
+ }
589
+
590
+ @keyframes ob-ring-pulse {
591
+ 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(99,102,241,0.7); opacity: 1; }
592
+ 70% { transform: scale(1); box-shadow: 0 0 0 10px rgba(99,102,241,0); opacity: 0; }
593
+ 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(99,102,241,0); opacity: 0; }
594
+ }
595
+
596
+ .onboarding-tooltip {
597
+ /* Los estilos inline de position y transform se inyectan por JS */
598
+ background: var(--surface-2);
599
+ border: 1px solid var(--border-accent);
600
+ border-radius: var(--radius-xl);
601
+ padding: var(--space-6);
602
+ box-shadow: var(--shadow-xl);
603
+ opacity: 0;
604
+ transition: opacity var(--duration-base) var(--ease-out);
605
+ pointer-events: all;
606
+ color: var(--text-primary);
607
+ }
608
+ .onboarding-tooltip.is-hidden { display: none; pointer-events: none; }
609
+ .ob-enter {
610
+ animation: ob-enter-anim var(--duration-base) var(--ease-out) forwards;
611
+ }
612
+ @keyframes ob-enter-anim {
613
+ from { opacity: 0; transform: translateY(8px) scale(0.98); }
614
+ to { opacity: 1; transform: translateY(0) scale(1); }
615
+ }
616
+
617
+ /* ── Flechas (Bocadillo) ── */
618
+ .onboarding-tooltip::after {
619
+ content: '';
620
+ position: absolute;
621
+ width: 0;
622
+ height: 0;
623
+ border-style: solid;
624
+ }
625
+ /* Flecha apuntando hacia arriba (cuando el tooltip está bottom) */
626
+ .onboarding-tooltip[data-pos="bottom"]::after {
627
+ top: -10px;
628
+ left: 50%;
629
+ margin-left: -10px;
630
+ border-width: 0 10px 10px 10px;
631
+ border-color: transparent transparent var(--surface-2) transparent;
632
+ }
633
+ /* Flecha apuntando hacia abajo (cuando el tooltip está top) */
634
+ .onboarding-tooltip[data-pos="top"]::after {
635
+ bottom: -10px;
636
+ left: 50%;
637
+ margin-left: -10px;
638
+ border-width: 10px 10px 0 10px;
639
+ border-color: var(--surface-2) transparent transparent transparent;
640
+ }
641
+ /* Flecha apuntando hacia la izquierda (cuando el tooltip está right) */
642
+ .onboarding-tooltip[data-pos="right"]::after {
643
+ left: -10px;
644
+ top: 50%;
645
+ margin-top: -10px;
646
+ border-width: 10px 10px 10px 0;
647
+ border-color: transparent var(--surface-2) transparent transparent;
648
+ }
649
+ /* Flecha apuntando hacia la derecha (cuando el tooltip está left) */
650
+ .onboarding-tooltip[data-pos="left"]::after {
651
+ right: -10px;
652
+ top: 50%;
653
+ margin-top: -10px;
654
+ border-width: 10px 0 10px 10px;
655
+ border-color: transparent transparent transparent var(--surface-2);
656
+ }
657
+
658
+ .ob-step-label {
659
+ font-size: var(--text-xs);
660
+ font-weight: 700;
661
+ color: var(--accent);
662
+ letter-spacing: 0.08em;
663
+ text-transform: uppercase;
664
+ margin-bottom: var(--space-3);
665
+ }
666
+ .ob-title {
667
+ font-size: var(--text-lg);
668
+ font-weight: 800;
669
+ margin-bottom: var(--space-2);
670
+ }
671
+ .ob-desc {
672
+ font-size: var(--text-sm);
673
+ color: var(--text-secondary);
674
+ line-height: 1.6;
675
+ margin-bottom: var(--space-5);
676
+ }
677
+ .ob-nav {
678
+ display: flex;
679
+ align-items: center;
680
+ justify-content: space-between;
681
+ flex-wrap: wrap;
682
+ gap: var(--space-4);
683
+ }
684
+ .ob-dots {
685
+ display: flex;
686
+ gap: var(--space-2);
687
+ flex-wrap: wrap;
688
+ }
689
+ .ob-dot {
690
+ width: 6px; height: 6px;
691
+ border-radius: 50%;
692
+ background: var(--border-strong);
693
+ transition: background var(--duration-base);
694
+ }
695
+ .ob-dot.is-active {
696
+ background: var(--accent);
697
+ width: 18px;
698
+ border-radius: var(--radius-full);
699
+ }
700
+ .ob-actions {
701
+ display: flex;
702
+ gap: var(--space-2);
703
+ flex-wrap: wrap;
704
+ }
705
+
706
+
707
+ /* ───────────────────────────────────
708
+ TIME TRACKER (widget grande)
709
+ ─────────────────────────────────── */
710
+ .time-tracker-card {
711
+ background: linear-gradient(135deg, var(--navy-90) 0%, var(--surface-1) 100%);
712
+ border: 1px solid var(--border-accent);
713
+ border-radius: var(--radius-xl);
714
+ padding: var(--space-5);
715
+ position: relative;
716
+ overflow: hidden;
717
+ }
718
+ .time-tracker-card::before {
719
+ content: '';
720
+ position: absolute;
721
+ bottom: -40px; right: -40px;
722
+ width: 160px; height: 160px;
723
+ background: radial-gradient(circle, var(--accent-light) 0%, transparent 70%);
724
+ border-radius: 50%;
725
+ }
726
+
727
+ .timer-display {
728
+ font-family: var(--font-mono);
729
+ font-size: 2.8rem;
730
+ font-weight: 700;
731
+ letter-spacing: 0.04em;
732
+ color: var(--text-primary);
733
+ line-height: 1;
734
+ margin: var(--space-4) 0;
735
+ text-align: center;
736
+ }
737
+ .timer-display.is-running { color: var(--accent-hover); }
738
+
739
+ .timer-task-name {
740
+ font-size: var(--text-xs);
741
+ font-weight: 600;
742
+ color: var(--text-secondary);
743
+ text-align: center;
744
+ margin-bottom: var(--space-4);
745
+ overflow: hidden;
746
+ text-overflow: ellipsis;
747
+ white-space: nowrap;
748
+ }
749
+
750
+ .timer-controls {
751
+ display: flex;
752
+ align-items: center;
753
+ justify-content: center;
754
+ gap: var(--space-3);
755
+ }
756
+ .timer-btn {
757
+ width: 44px; height: 44px;
758
+ border-radius: 50%;
759
+ display: flex; align-items: center; justify-content: center;
760
+ border: 2px solid transparent;
761
+ cursor: pointer;
762
+ transition:
763
+ background var(--duration-base) var(--ease-out),
764
+ transform var(--duration-fast) var(--ease-out),
765
+ border-color var(--duration-base);
766
+ }
767
+ .timer-btn:active { transform: scale(0.9); }
768
+ .timer-btn-play {
769
+ background: var(--accent);
770
+ color: white;
771
+ box-shadow: var(--shadow-accent);
772
+ width: 54px; height: 54px;
773
+ }
774
+ .timer-btn-play:hover { background: var(--accent-hover); transform: scale(1.05); }
775
+ .timer-btn-pause {
776
+ background: var(--warning-light);
777
+ border-color: rgba(245,158,11,0.2);
778
+ color: var(--warning);
779
+ }
780
+ .timer-btn-stop {
781
+ background: var(--danger-light);
782
+ border-color: rgba(239,68,68,0.2);
783
+ color: var(--danger);
784
+ }
785
+
786
+ .timer-total {
787
+ text-align: center;
788
+ font-size: var(--text-xs);
789
+ color: var(--text-muted);
790
+ margin-top: var(--space-3);
791
+ }
792
+
793
+ /* ───────────────────────────────────
794
+ PROGRESS DONUT (SVG)
795
+ ─────────────────────────────────── */
796
+ .donut-wrapper {
797
+ display: flex;
798
+ flex-direction: column;
799
+ align-items: center;
800
+ gap: var(--space-3);
801
+ position: relative;
802
+ }
803
+ .donut-label {
804
+ position: absolute;
805
+ top: 50%;
806
+ left: 50%;
807
+ transform: translate(-50%, -50%);
808
+ text-align: center;
809
+ }
810
+ .donut-percent {
811
+ font-family: var(--font-heading);
812
+ font-size: var(--text-2xl);
813
+ font-weight: 800;
814
+ color: var(--text-primary);
815
+ display: block;
816
+ line-height: 1;
817
+ }
818
+ .donut-sub {
819
+ font-size: var(--text-xs);
820
+ color: var(--text-muted);
821
+ }
822
+ .donut-legend {
823
+ display: flex;
824
+ gap: var(--space-5);
825
+ flex-wrap: wrap;
826
+ justify-content: center;
827
+ }
828
+ .donut-legend-item {
829
+ display: flex;
830
+ align-items: center;
831
+ gap: var(--space-2);
832
+ font-size: var(--text-xs);
833
+ color: var(--text-secondary);
834
+ }
835
+ .donut-legend-dot {
836
+ width: 8px; height: 8px;
837
+ border-radius: 50%;
838
+ flex-shrink: 0;
839
+ }
840
+
841
+ /* ───────────────────────────────────
842
+ SESSION PILLS (consola)
843
+ ─────────────────────────────────── */
844
+ .session-pill {
845
+ display: flex;
846
+ align-items: center;
847
+ justify-content: space-between;
848
+ gap: var(--space-3);
849
+ padding: var(--space-2) var(--space-4);
850
+ background: var(--surface-3);
851
+ border: 1px solid var(--border);
852
+ border-radius: var(--radius-md);
853
+ font-size: var(--text-xs);
854
+ font-family: var(--font-mono);
855
+ cursor: pointer;
856
+ transition: border-color var(--duration-fast), background var(--duration-fast);
857
+ }
858
+ .session-pill:hover { border-color: var(--border-strong); }
859
+ .session-pill.is-selected {
860
+ border-color: var(--border-accent);
861
+ background: var(--accent-light);
862
+ }
863
+ .session-pill-cmd {
864
+ flex: 1;
865
+ min-width: 0;
866
+ overflow: hidden;
867
+ text-overflow: ellipsis;
868
+ white-space: nowrap;
869
+ color: var(--text-secondary);
870
+ }
871
+ .session-pill-status { flex-shrink: 0; }
872
+
873
+ /* ───────────────────────────────────
874
+ ACTIVITY TIMELINE
875
+ ─────────────────────────────────── */
876
+ .activity-item {
877
+ display: grid;
878
+ grid-template-columns: 36px 1fr;
879
+ gap: var(--space-3);
880
+ padding: var(--space-3) 0;
881
+ border-bottom: 1px solid var(--border);
882
+ align-items: start;
883
+ }
884
+ .activity-item:last-child { border-bottom: none; }
885
+ .activity-icon {
886
+ width: 36px; height: 36px;
887
+ border-radius: var(--radius-md);
888
+ display: flex; align-items: center; justify-content: center;
889
+ background: var(--surface-3);
890
+ border: 1px solid var(--border);
891
+ flex-shrink: 0;
892
+ }
893
+ .activity-content { min-width: 0; }
894
+ .activity-action { font-size: var(--text-sm); font-weight: 600; color: var(--text-primary); }
895
+ .activity-task { font-size: var(--text-xs); color: var(--text-secondary); margin-top: var(--space-1); }
896
+ .activity-time { font-size: var(--text-xs); color: var(--text-muted); font-family: var(--font-mono); }
897
+
898
+ /* ───────────────────────────────────
899
+ DECISION / FINDING ITEMS
900
+ ─────────────────────────────────── */
901
+ .finding-item {
902
+ padding: var(--space-4);
903
+ border-radius: var(--radius-md);
904
+ background: var(--surface-3);
905
+ border: 1px solid var(--border);
906
+ border-left: 3px solid var(--warning);
907
+ }
908
+ .finding-item.severity-critical { border-left-color: var(--danger); }
909
+ .finding-item.severity-low { border-left-color: var(--info); }
910
+
911
+ .decision-item {
912
+ padding: var(--space-4);
913
+ border-radius: var(--radius-md);
914
+ background: var(--surface-3);
915
+ border: 1px solid var(--border);
916
+ }
917
+
918
+ /* ───────────────────────────────────
919
+ PROJECT ROW (portfolio)
920
+ ─────────────────────────────────── */
921
+ .project-row {
922
+ display: flex;
923
+ align-items: center;
924
+ justify-content: space-between;
925
+ gap: var(--space-4);
926
+ padding: var(--space-3) var(--space-4);
927
+ border-radius: var(--radius-md);
928
+ background: var(--surface-3);
929
+ border: 1px solid var(--border);
930
+ transition: border-color var(--duration-fast), background var(--duration-fast);
931
+ }
932
+ .project-row:hover { border-color: var(--border-strong); }
933
+ .project-row.is-active {
934
+ border-color: var(--border-accent);
935
+ background: var(--accent-light);
936
+ }
937
+ .project-row-info { min-width: 0; flex: 1; }
938
+ .project-name { font-size: var(--text-sm); font-weight: 700; color: var(--text-primary); }
939
+ .project-path {
940
+ font-size: var(--text-xs);
941
+ font-family: var(--font-mono);
942
+ color: var(--text-muted);
943
+ overflow: hidden;
944
+ text-overflow: ellipsis;
945
+ white-space: nowrap;
946
+ }
947
+ .project-row-actions { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
948
+
949
+ /* ───────────────────────────────────
950
+ COMMAND PRESET STRIP
951
+ ─────────────────────────────────── */
952
+ .preset-strip {
953
+ display: flex;
954
+ gap: var(--space-2);
955
+ flex-wrap: wrap;
956
+ }