ltcai 4.0.0 → 4.0.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 (108) hide show
  1. package/README.md +37 -33
  2. package/docs/CHANGELOG.md +64 -0
  3. package/docs/REALTIME_COLLABORATION.md +3 -3
  4. package/docs/V3_FRONTEND.md +9 -8
  5. package/docs/V4_DIGITAL_BRAIN_RECOVERY.md +86 -43
  6. package/docs/kg-schema.md +6 -2
  7. package/docs/spec-vs-impl.md +10 -10
  8. package/kg_schema.py +2 -603
  9. package/knowledge_graph.py +37 -4958
  10. package/latticeai/__init__.py +1 -1
  11. package/latticeai/api/admin.py +15 -16
  12. package/latticeai/api/agents.py +13 -6
  13. package/latticeai/api/auth.py +19 -11
  14. package/latticeai/api/invitations.py +100 -0
  15. package/latticeai/api/knowledge_graph.py +4 -11
  16. package/latticeai/api/plugins.py +3 -6
  17. package/latticeai/api/realtime.py +4 -7
  18. package/latticeai/api/static_routes.py +9 -12
  19. package/latticeai/api/ui_redirects.py +26 -0
  20. package/latticeai/api/workflow_designer.py +39 -6
  21. package/latticeai/api/workspace.py +24 -10
  22. package/latticeai/app_factory.py +88 -17
  23. package/latticeai/brain/_kg_common.py +1123 -0
  24. package/latticeai/brain/discovery.py +1455 -0
  25. package/latticeai/brain/documents.py +218 -0
  26. package/latticeai/brain/ingest.py +644 -0
  27. package/latticeai/brain/projection.py +561 -0
  28. package/latticeai/brain/provenance.py +401 -0
  29. package/latticeai/brain/retrieval.py +1316 -0
  30. package/latticeai/brain/schema.py +640 -0
  31. package/latticeai/brain/store.py +216 -0
  32. package/latticeai/brain/write_master.py +225 -0
  33. package/latticeai/core/invitations.py +131 -0
  34. package/latticeai/core/marketplace.py +1 -1
  35. package/latticeai/core/multi_agent.py +1 -1
  36. package/latticeai/core/policy.py +54 -0
  37. package/latticeai/core/realtime.py +65 -44
  38. package/latticeai/core/sessions.py +31 -5
  39. package/latticeai/core/users.py +147 -0
  40. package/latticeai/core/workspace_os.py +420 -20
  41. package/latticeai/services/agent_runtime.py +242 -4
  42. package/latticeai/services/run_executor.py +328 -0
  43. package/latticeai/services/workspace_service.py +27 -19
  44. package/package.json +2 -14
  45. package/scripts/lint_v3.mjs +23 -0
  46. package/static/v3/asset-manifest.json +21 -14
  47. package/static/v3/js/{app.356e6452.js → app.c5c80c46.js} +1 -1
  48. package/static/v3/js/core/{api.7a308b89.js → api.ba0fbf14.js} +58 -1
  49. package/static/v3/js/core/api.js +57 -0
  50. package/static/v3/js/core/i18n.880e1fec.js +575 -0
  51. package/static/v3/js/core/i18n.js +575 -0
  52. package/static/v3/js/core/routes.37522821.js +101 -0
  53. package/static/v3/js/core/routes.js +71 -63
  54. package/static/v3/js/core/{shell.a1657f20.js → shell.e3f6bbfa.js} +67 -38
  55. package/static/v3/js/core/shell.js +65 -36
  56. package/static/v3/js/core/{store.204a08b2.js → store.7b2aa044.js} +10 -0
  57. package/static/v3/js/core/store.js +10 -0
  58. package/static/v3/js/views/account.eff40715.js +143 -0
  59. package/static/v3/js/views/account.js +143 -0
  60. package/static/v3/js/views/activity.0d271ef9.js +67 -0
  61. package/static/v3/js/views/activity.js +67 -0
  62. package/static/v3/js/views/{admin-users.03bac88c.js → admin-users.f7ac7b43.js} +4 -6
  63. package/static/v3/js/views/admin-users.js +4 -6
  64. package/static/v3/js/views/{agents.014d0b74.js → agents.17c5288d.js} +35 -12
  65. package/static/v3/js/views/agents.js +35 -12
  66. package/static/v3/js/views/{chat.e6dd7dd0.js → chat.e250e2cc.js} +23 -0
  67. package/static/v3/js/views/chat.js +23 -0
  68. package/static/v3/js/views/{knowledge-graph.5e40cbeb.js → knowledge-graph.4d09c537.js} +27 -7
  69. package/static/v3/js/views/knowledge-graph.js +27 -7
  70. package/static/v3/js/views/network.52a4f181.js +97 -0
  71. package/static/v3/js/views/network.js +97 -0
  72. package/static/v3/js/views/{planning.9ac3e313.js → planning.4876fd77.js} +26 -5
  73. package/static/v3/js/views/planning.js +26 -5
  74. package/static/v3/js/views/runs.b63b2afa.js +144 -0
  75. package/static/v3/js/views/runs.js +144 -0
  76. package/static/v3/js/views/{settings.8631fa5e.js → settings.b7140634.js} +7 -8
  77. package/static/v3/js/views/settings.js +7 -8
  78. package/static/v3/js/views/snapshots.6f5db095.js +135 -0
  79. package/static/v3/js/views/snapshots.js +135 -0
  80. package/static/v3/js/views/{workflows.26c57290.js → workflows.7752225a.js} +87 -2
  81. package/static/v3/js/views/workflows.js +87 -2
  82. package/static/v3/js/views/workspace-admin.c466029b.js +156 -0
  83. package/static/v3/js/views/workspace-admin.js +156 -0
  84. package/static/account.html +0 -113
  85. package/static/activity.html +0 -73
  86. package/static/admin.html +0 -486
  87. package/static/agents.html +0 -139
  88. package/static/chat.html +0 -841
  89. package/static/css/reference/account.css +0 -439
  90. package/static/css/reference/admin.css +0 -610
  91. package/static/css/reference/base.css +0 -1661
  92. package/static/css/reference/chat.css +0 -4623
  93. package/static/css/reference/graph.css +0 -1016
  94. package/static/css/responsive.css +0 -861
  95. package/static/graph.html +0 -122
  96. package/static/platform.css +0 -104
  97. package/static/plugins.html +0 -136
  98. package/static/scripts/account.js +0 -238
  99. package/static/scripts/admin.js +0 -1614
  100. package/static/scripts/chat.js +0 -5081
  101. package/static/scripts/graph.js +0 -1804
  102. package/static/scripts/platform.js +0 -64
  103. package/static/scripts/ux.js +0 -167
  104. package/static/scripts/workspace.js +0 -948
  105. package/static/v3/js/core/routes.7222343d.js +0 -93
  106. package/static/workflows.html +0 -146
  107. package/static/workspace.css +0 -1121
  108. package/static/workspace.html +0 -357
@@ -1,1121 +0,0 @@
1
- :root {
2
- /* Map the local palette onto the shared design tokens so this page
3
- inverts cleanly under :root[data-lt-theme="dark"]. Light defaults
4
- stay visually close to the original hand-tuned values. */
5
- --bg: var(--lt-bg, #f6f7f9);
6
- --surface: var(--lt-surface, #ffffff);
7
- --surface-2: var(--lt-surface-2, #f0f4f8);
8
- --input: var(--lt-input, var(--surface));
9
- --ink: var(--lt-ink, #101828);
10
- --muted: var(--lt-muted, #667085);
11
- --line: var(--lt-line, #d9e0e8);
12
- --blue: var(--lt-accent, #2563eb);
13
- --green: #12805c;
14
- --amber: #b45309;
15
- --pink: #be185d;
16
- --red: #c2410c;
17
- --radius: 8px;
18
- --shadow: var(--lt-shadow-md, 0 12px 34px rgba(16, 24, 40, 0.08));
19
- /* Rail keeps its dark-navy identity in light mode; dark mode remaps it
20
- to a shared surface token below so it inverts coherently. */
21
- --rail-bg: #111827;
22
- --rail-ink: #e5e7eb;
23
- --rail-ink-soft: #b8c0cc;
24
- --rail-ink-strong: #fff;
25
- --rail-hover: rgba(255, 255, 255, 0.08);
26
- --rail-line: rgba(255, 255, 255, 0.12);
27
- font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
28
- }
29
-
30
- /* Dark theme: remap the rail to the shared surface tokens so it inverts
31
- instead of staying permanently navy. */
32
- :root[data-lt-theme="dark"] {
33
- --rail-bg: var(--lt-surface-2);
34
- --rail-ink: var(--lt-ink);
35
- --rail-ink-soft: var(--lt-ink-soft);
36
- --rail-ink-strong: var(--lt-ink);
37
- --rail-hover: rgba(255, 255, 255, 0.06);
38
- --rail-line: var(--lt-line);
39
- }
40
-
41
- * { box-sizing: border-box; }
42
-
43
- html { scroll-behavior: smooth; }
44
-
45
- body {
46
- margin: 0;
47
- background: var(--bg);
48
- color: var(--ink);
49
- min-width: 320px;
50
- }
51
-
52
- button, input, select, textarea {
53
- font: inherit;
54
- }
55
-
56
- button {
57
- border: 0;
58
- cursor: pointer;
59
- }
60
-
61
- .workspace-shell {
62
- display: grid;
63
- grid-template-columns: 248px minmax(0, 1fr);
64
- min-height: 100vh;
65
- min-height: 100dvh;
66
- }
67
-
68
- .workspace-rail {
69
- position: sticky;
70
- top: 0;
71
- height: 100vh;
72
- height: 100dvh;
73
- background: var(--rail-bg);
74
- color: var(--rail-ink);
75
- padding: 18px 14px;
76
- display: flex;
77
- flex-direction: column;
78
- gap: 18px;
79
- }
80
-
81
- .rail-brand {
82
- display: flex;
83
- align-items: center;
84
- gap: 10px;
85
- color: var(--rail-ink-strong);
86
- text-decoration: none;
87
- font-weight: 800;
88
- padding: 8px;
89
- }
90
-
91
- .rail-brand img {
92
- width: 32px;
93
- height: 32px;
94
- border-radius: 8px;
95
- }
96
-
97
- .workspace-rail nav,
98
- .rail-links {
99
- display: grid;
100
- gap: 4px;
101
- }
102
-
103
- .workspace-rail a {
104
- color: var(--rail-ink-soft);
105
- text-decoration: none;
106
- }
107
-
108
- .workspace-rail nav a,
109
- .rail-links a {
110
- display: flex;
111
- align-items: center;
112
- gap: 10px;
113
- padding: 10px 12px;
114
- border-radius: 8px;
115
- font-size: 14px;
116
- }
117
-
118
- .workspace-rail nav a.active,
119
- .workspace-rail nav a:hover,
120
- .rail-links a:hover {
121
- background: var(--rail-hover);
122
- color: var(--rail-ink-strong);
123
- }
124
-
125
- .rail-links {
126
- border-top: 1px solid var(--rail-line);
127
- padding-top: 12px;
128
- margin-top: auto;
129
- }
130
-
131
- main {
132
- padding: 24px;
133
- display: grid;
134
- gap: 18px;
135
- }
136
-
137
- .workspace-topbar {
138
- display: flex;
139
- align-items: center;
140
- justify-content: space-between;
141
- gap: 16px;
142
- padding: 6px 0 2px;
143
- }
144
-
145
- .eyebrow {
146
- color: var(--blue);
147
- font-size: 11px;
148
- font-weight: 800;
149
- text-transform: uppercase;
150
- letter-spacing: .08em;
151
- }
152
-
153
- h1, h2 {
154
- margin: 0;
155
- letter-spacing: 0;
156
- }
157
-
158
- h1 {
159
- font-size: 30px;
160
- line-height: 1.15;
161
- }
162
-
163
- h2 {
164
- font-size: 17px;
165
- line-height: 1.25;
166
- }
167
-
168
- .top-actions,
169
- .section-head,
170
- .inline-form,
171
- .item-actions {
172
- display: flex;
173
- align-items: center;
174
- gap: 10px;
175
- }
176
-
177
- .section-head {
178
- justify-content: space-between;
179
- margin-bottom: 14px;
180
- }
181
-
182
- .primary-action,
183
- .secondary-action,
184
- .icon-action,
185
- .small-action {
186
- border-radius: 8px;
187
- min-height: 36px;
188
- display: inline-flex;
189
- align-items: center;
190
- justify-content: center;
191
- gap: 8px;
192
- white-space: nowrap;
193
- }
194
-
195
- .primary-action {
196
- background: var(--blue);
197
- color: white;
198
- padding: 0 14px;
199
- font-weight: 700;
200
- }
201
-
202
- .secondary-action {
203
- background: var(--accent-soft, #e6efff);
204
- color: var(--blue);
205
- padding: 0 12px;
206
- font-weight: 700;
207
- }
208
-
209
- .icon-action {
210
- width: 38px;
211
- background: var(--surface);
212
- color: var(--ink);
213
- border: 1px solid var(--line);
214
- }
215
-
216
- .small-action {
217
- min-height: 30px;
218
- padding: 0 10px;
219
- color: var(--ink);
220
- background: var(--surface-2);
221
- border: 1px solid var(--line);
222
- font-size: 12px;
223
- font-weight: 700;
224
- }
225
-
226
- .danger-action {
227
- color: #fff;
228
- background: var(--red);
229
- border-color: var(--red);
230
- }
231
-
232
- .metric-grid {
233
- display: grid;
234
- grid-template-columns: repeat(4, minmax(0, 1fr));
235
- gap: 12px;
236
- }
237
-
238
- .metric-card,
239
- .workspace-panel,
240
- .workspace-band {
241
- background: var(--surface);
242
- border: 1px solid var(--line);
243
- border-radius: 8px;
244
- box-shadow: var(--shadow);
245
- }
246
-
247
- .metric-card {
248
- padding: 16px;
249
- display: grid;
250
- gap: 8px;
251
- }
252
-
253
- .metric-card span {
254
- color: var(--muted);
255
- font-size: 12px;
256
- font-weight: 700;
257
- }
258
-
259
- .metric-card strong {
260
- font-size: 28px;
261
- line-height: 1;
262
- }
263
-
264
- .metric-card i {
265
- color: var(--green);
266
- font-size: 22px;
267
- }
268
-
269
- .workspace-band,
270
- .workspace-panel {
271
- padding: 18px;
272
- }
273
-
274
- .workspace-grid {
275
- display: grid;
276
- gap: 18px;
277
- }
278
-
279
- .two-col {
280
- grid-template-columns: repeat(2, minmax(0, 1fr));
281
- }
282
-
283
- .step-grid {
284
- display: grid;
285
- grid-template-columns: repeat(3, minmax(0, 1fr));
286
- gap: 10px;
287
- }
288
-
289
- .step-chip {
290
- display: flex;
291
- align-items: center;
292
- justify-content: space-between;
293
- gap: 10px;
294
- min-height: 44px;
295
- padding: 10px 12px;
296
- background: var(--surface-2);
297
- border: 1px solid var(--line);
298
- border-radius: 8px;
299
- }
300
-
301
- .status-pill {
302
- padding: 3px 8px;
303
- border-radius: 999px;
304
- font-size: 11px;
305
- font-weight: 800;
306
- background: #eef2ff;
307
- color: var(--blue);
308
- }
309
-
310
- .status-complete { background: #dcfce7; color: var(--green); }
311
- .status-failed { background: #ffedd5; color: var(--red); }
312
- .status-running { background: #fef3c7; color: var(--amber); }
313
-
314
- .list-stack {
315
- display: grid;
316
- gap: 10px;
317
- }
318
-
319
- .list-item {
320
- border: 1px solid var(--line);
321
- background: var(--surface-2);
322
- border-radius: 8px;
323
- padding: 12px;
324
- display: grid;
325
- gap: 8px;
326
- }
327
-
328
- .list-title {
329
- display: flex;
330
- justify-content: space-between;
331
- align-items: center;
332
- gap: 10px;
333
- font-weight: 800;
334
- }
335
-
336
- .list-title span {
337
- min-width: 0;
338
- overflow: hidden;
339
- text-overflow: ellipsis;
340
- white-space: nowrap;
341
- }
342
-
343
- .meta-line,
344
- .mini-row {
345
- color: var(--muted);
346
- font-size: 12px;
347
- }
348
-
349
- .tag-row {
350
- display: flex;
351
- flex-wrap: wrap;
352
- gap: 6px;
353
- }
354
-
355
- .tag {
356
- font-size: 11px;
357
- font-weight: 800;
358
- color: var(--ink);
359
- background: var(--surface-2);
360
- border: 1px solid var(--line);
361
- border-radius: 999px;
362
- padding: 3px 8px;
363
- }
364
-
365
- .inline-form {
366
- margin-bottom: 12px;
367
- }
368
-
369
- .inline-form.split {
370
- align-items: stretch;
371
- }
372
-
373
- input, select, textarea {
374
- width: 100%;
375
- border: 1px solid var(--line);
376
- border-radius: 8px;
377
- color: var(--ink);
378
- background: var(--input);
379
- min-height: 38px;
380
- padding: 9px 10px;
381
- }
382
-
383
- textarea {
384
- resize: vertical;
385
- min-height: 96px;
386
- }
387
-
388
- .memory-form {
389
- display: grid;
390
- grid-template-columns: 180px minmax(0, 1fr);
391
- gap: 10px;
392
- margin-bottom: 12px;
393
- }
394
-
395
- .memory-form textarea {
396
- grid-column: 1 / -1;
397
- }
398
-
399
- .memory-form button {
400
- grid-column: 1 / -1;
401
- }
402
-
403
- .code-box,
404
- .state-box {
405
- min-height: 120px;
406
- background: #111827;
407
- color: #e5e7eb;
408
- border-radius: 8px;
409
- border: 1px solid #253043;
410
- padding: 12px;
411
- overflow: auto;
412
- font-family: "SF Mono", Menlo, Consolas, monospace;
413
- font-size: 12px;
414
- line-height: 1.45;
415
- }
416
-
417
- .timeline-list {
418
- display: grid;
419
- gap: 0;
420
- border-left: 2px solid var(--line);
421
- margin-left: 7px;
422
- }
423
-
424
- .timeline-item {
425
- position: relative;
426
- padding: 0 0 14px 16px;
427
- }
428
-
429
- .timeline-item::before {
430
- content: "";
431
- position: absolute;
432
- left: -6px;
433
- top: 3px;
434
- width: 10px;
435
- height: 10px;
436
- border-radius: 50%;
437
- background: var(--pink);
438
- }
439
-
440
- .toggle-row {
441
- display: inline-flex;
442
- align-items: center;
443
- gap: 8px;
444
- }
445
-
446
- .toggle-row input {
447
- position: absolute;
448
- opacity: 0;
449
- pointer-events: none;
450
- /* 절대배치 + width:auto 인 체크박스는 컨테이닝 블록(뷰포트) 폭만큼 늘어나
451
- * 가로 오버플로우를 만든다. 1px 박스로 가둬 레이아웃에 영향 없게 한다. */
452
- width: 1px;
453
- height: 1px;
454
- margin: 0;
455
- }
456
-
457
- .toggle-row span {
458
- width: 42px;
459
- height: 24px;
460
- background: #cbd5e1;
461
- border-radius: 999px;
462
- position: relative;
463
- }
464
-
465
- .toggle-row span::after {
466
- content: "";
467
- position: absolute;
468
- width: 18px;
469
- height: 18px;
470
- top: 3px;
471
- left: 3px;
472
- border-radius: 50%;
473
- background: var(--surface);
474
- transition: transform 160ms ease;
475
- }
476
-
477
- .toggle-row input:checked + span {
478
- background: var(--green);
479
- }
480
-
481
- .toggle-row input:checked + span::after {
482
- transform: translateX(18px);
483
- }
484
-
485
- .toast {
486
- position: fixed;
487
- right: 18px;
488
- bottom: 18px;
489
- min-width: 220px;
490
- max-width: 360px;
491
- color: #fff;
492
- background: #111827;
493
- border-radius: 8px;
494
- padding: 12px 14px;
495
- opacity: 0;
496
- transform: translateY(8px);
497
- pointer-events: none;
498
- transition: opacity 160ms ease, transform 160ms ease;
499
- box-shadow: var(--shadow);
500
- }
501
-
502
- .toast.show {
503
- opacity: 1;
504
- transform: translateY(0);
505
- }
506
-
507
- @media (max-width: 1100px) {
508
- .metric-grid,
509
- .two-col {
510
- grid-template-columns: repeat(2, minmax(0, 1fr));
511
- }
512
- .step-grid {
513
- grid-template-columns: repeat(2, minmax(0, 1fr));
514
- }
515
- }
516
-
517
- @media (max-width: 760px) {
518
- .workspace-shell {
519
- grid-template-columns: 1fr;
520
- }
521
- .workspace-rail {
522
- position: relative;
523
- height: auto;
524
- }
525
- .workspace-rail nav,
526
- .rail-links {
527
- grid-template-columns: repeat(2, minmax(0, 1fr));
528
- }
529
- main {
530
- padding: 16px;
531
- }
532
- .workspace-topbar,
533
- .section-head {
534
- align-items: flex-start;
535
- flex-direction: column;
536
- }
537
- .metric-grid,
538
- .two-col,
539
- .step-grid {
540
- grid-template-columns: 1fr;
541
- }
542
- .memory-form {
543
- grid-template-columns: 1fr;
544
- }
545
- }
546
-
547
- /* Workspace switcher + organization management (v1.1.0) */
548
- .workspace-switcher {
549
- display: inline-flex;
550
- align-items: center;
551
- gap: 8px;
552
- padding: 6px 10px;
553
- border-radius: 10px;
554
- background: var(--rail-hover);
555
- border: 1px solid var(--rail-line);
556
- }
557
- .workspace-switcher select {
558
- background: transparent;
559
- border: none;
560
- color: inherit;
561
- font: inherit;
562
- font-weight: 600;
563
- max-width: 220px;
564
- }
565
- .workspace-role-pill {
566
- font-size: 11px;
567
- text-transform: uppercase;
568
- letter-spacing: 0.04em;
569
- opacity: 0.75;
570
- }
571
- #member-panel {
572
- margin-top: 16px;
573
- }
574
- #org-create-form {
575
- margin-bottom: 12px;
576
- }
577
-
578
- /* ── Product Experience Deepening (v1.6.0) ──────────────────────────────── */
579
-
580
- /* Workspace summary */
581
- .summary-card {
582
- display: flex;
583
- flex-wrap: wrap;
584
- justify-content: space-between;
585
- gap: 16px;
586
- align-items: center;
587
- }
588
- .summary-main { display: flex; align-items: center; gap: 14px; }
589
- .summary-icon {
590
- width: 48px; height: 48px; border-radius: 12px;
591
- display: grid; place-items: center;
592
- background: #eef2ff; color: var(--blue); font-size: 24px;
593
- }
594
- .summary-name { font-weight: 800; font-size: 18px; color: var(--ink); }
595
- .summary-stats { display: flex; flex-wrap: wrap; gap: 18px; }
596
- .summary-stat { display: grid; text-align: center; }
597
- .summary-stat strong { font-size: 20px; color: var(--ink); }
598
- .summary-stat span { font-size: 11px; color: var(--muted); font-weight: 700; }
599
- .quickswitch-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
600
- .switch-chip {
601
- display: inline-flex; align-items: center; gap: 6px;
602
- border: 1px solid var(--line); background: var(--surface-2); color: var(--ink);
603
- border-radius: 999px; padding: 6px 12px; font-weight: 700; font-size: 13px; cursor: pointer;
604
- }
605
- .switch-chip.active { border-color: var(--blue); background: var(--accent-soft, #eef2ff); color: var(--blue); }
606
-
607
- /* Entity explorer */
608
- .entity-card { text-align: left; cursor: pointer; width: 100%; font: inherit; }
609
- .entity-card.selected { border-color: var(--blue); box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15); }
610
- .importance-bar { height: 4px; border-radius: 999px; background: #edf2f7; overflow: hidden; }
611
- .importance-bar span { display: block; height: 100%; background: linear-gradient(90deg, #2563eb, #7c3aed); }
612
- .rel-row { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 2px 0; }
613
- .rel-dir { color: var(--muted); font-weight: 800; width: 16px; }
614
- .rel-node { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
615
- .activity-item .list-title span { font-weight: 700; }
616
-
617
- /* Skill marketplace tabs */
618
- .tab-bar { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
619
- .tab {
620
- border: 1px solid var(--line); background: var(--surface-2); color: var(--muted);
621
- border-radius: 999px; padding: 6px 14px; font-weight: 700; font-size: 13px; cursor: pointer;
622
- }
623
- .tab.active { border-color: var(--blue); background: var(--accent-soft, #eef2ff); color: var(--blue); }
624
- .tab-count {
625
- display: inline-block; min-width: 16px; padding: 0 5px; margin-left: 4px;
626
- border-radius: 999px; background: var(--red); color: #fff; font-size: 11px;
627
- }
628
- .tab-count:empty { display: none; }
629
-
630
- /* Enterprise capability grid */
631
- .capability-grid {
632
- display: grid; gap: 10px;
633
- grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr));
634
- margin-top: 12px;
635
- }
636
- .capability-card {
637
- display: flex; align-items: center; gap: 10px;
638
- border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; background: var(--surface-2);
639
- }
640
- .capability-card i { font-size: 18px; }
641
- .capability-card.off i { color: var(--muted); }
642
- .capability-card.on i { color: var(--green); }
643
- .capability-card .cap-name { flex: 1; font-weight: 700; font-size: 13px; color: var(--ink); }
644
-
645
- /* Workspace health dashboard + skill install lifecycle (v1.7.0) */
646
- .health-grid {
647
- display: grid;
648
- grid-template-columns: repeat(4, minmax(0, 1fr));
649
- gap: 12px;
650
- }
651
- .health-card {
652
- min-width: 0;
653
- border: 1px solid var(--line);
654
- border-radius: 8px;
655
- background: var(--surface-2);
656
- padding: 14px;
657
- display: grid;
658
- gap: 7px;
659
- }
660
- .health-card i {
661
- color: var(--blue);
662
- font-size: 20px;
663
- }
664
- .health-card span {
665
- color: var(--muted);
666
- font-size: 11px;
667
- font-weight: 800;
668
- text-transform: uppercase;
669
- }
670
- .health-card strong {
671
- color: var(--ink);
672
- font-size: 22px;
673
- line-height: 1.1;
674
- overflow-wrap: anywhere;
675
- }
676
- .health-card em {
677
- color: var(--muted);
678
- font-size: 12px;
679
- font-style: normal;
680
- }
681
- .skill-progress {
682
- display: grid;
683
- gap: 6px;
684
- }
685
- .skill-progress-head {
686
- display: flex;
687
- align-items: center;
688
- justify-content: space-between;
689
- color: var(--muted);
690
- font-size: 11px;
691
- font-weight: 800;
692
- }
693
- .skill-progress-track {
694
- height: 7px;
695
- border-radius: 999px;
696
- background: var(--surface-3, var(--surface-2));
697
- overflow: hidden;
698
- }
699
- .skill-progress-track span {
700
- display: block;
701
- height: 100%;
702
- border-radius: inherit;
703
- background: linear-gradient(90deg, var(--blue), var(--green));
704
- }
705
-
706
- @media (max-width: 1100px) {
707
- .health-grid {
708
- grid-template-columns: repeat(2, minmax(0, 1fr));
709
- }
710
- }
711
-
712
- @media (max-width: 760px) {
713
- .health-grid {
714
- grid-template-columns: 1fr;
715
- }
716
- }
717
-
718
- /* v2.2.1 — 태블릿(761~1024) 레일 슬림화로 본문 공간 확보 */
719
- @media (min-width: 761px) and (max-width: 1024px) {
720
- .workspace-shell { grid-template-columns: 196px minmax(0, 1fr); }
721
- .workspace-rail { padding: 14px 10px; }
722
- }
723
-
724
- /* v2.2.1 — 터치 영역 44px 보장 */
725
- @media (hover: none), (max-width: 760px) {
726
- .icon-action { min-width: 44px; min-height: 44px; }
727
- .small-action { min-height: 44px; }
728
- .workspace-rail a { min-height: 44px; display: flex; align-items: center; }
729
- }
730
-
731
- :root[data-lt-theme="dark"] main {
732
- background:
733
- linear-gradient(180deg, var(--bg) 0%, var(--bg-soft) 100%);
734
- }
735
-
736
- :root[data-lt-theme="dark"] .workspace-band,
737
- :root[data-lt-theme="dark"] .workspace-panel,
738
- :root[data-lt-theme="dark"] .metric-card {
739
- background: rgba(22, 22, 58, 0.92);
740
- border-color: rgba(160, 170, 230, 0.22);
741
- box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
742
- }
743
-
744
- :root[data-lt-theme="dark"] input,
745
- :root[data-lt-theme="dark"] select,
746
- :root[data-lt-theme="dark"] textarea,
747
- :root[data-lt-theme="dark"] .list-item,
748
- :root[data-lt-theme="dark"] .health-card,
749
- :root[data-lt-theme="dark"] .capability-card,
750
- :root[data-lt-theme="dark"] .switch-chip,
751
- :root[data-lt-theme="dark"] .tab,
752
- :root[data-lt-theme="dark"] .tag {
753
- background: rgba(255, 255, 255, 0.06);
754
- border-color: rgba(160, 170, 230, 0.22);
755
- color: var(--ink);
756
- }
757
-
758
- :root[data-lt-theme="dark"] input::placeholder,
759
- :root[data-lt-theme="dark"] textarea::placeholder {
760
- color: rgba(226, 232, 255, 0.48);
761
- }
762
-
763
- :root[data-lt-theme="dark"] .status-pill,
764
- :root[data-lt-theme="dark"] .workspace-role-pill {
765
- background: rgba(255, 255, 255, 0.10);
766
- color: var(--blue);
767
- }
768
-
769
- :root[data-lt-theme="dark"] .status-complete {
770
- background: rgba(52, 211, 153, 0.16);
771
- color: #86efac;
772
- }
773
-
774
- :root[data-lt-theme="dark"] .status-running {
775
- background: rgba(251, 191, 36, 0.16);
776
- color: #fbbf24;
777
- }
778
-
779
- :root[data-lt-theme="dark"] .status-failed {
780
- background: rgba(244, 113, 113, 0.16);
781
- color: #fca5a5;
782
- }
783
-
784
- /* ── Product shell redesign (frontend-only) ─────────────────────────────── */
785
- .workspace-page {
786
- background: var(--bg);
787
- color: var(--ink);
788
- }
789
-
790
- .workspace-page::before {
791
- content: "";
792
- position: fixed;
793
- inset: 0;
794
- pointer-events: none;
795
- background:
796
- linear-gradient(90deg, rgba(12, 92, 115, 0.035) 1px, transparent 1px),
797
- linear-gradient(180deg, rgba(12, 92, 115, 0.035) 1px, transparent 1px);
798
- background-size: 36px 36px;
799
- mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.4), transparent 72%);
800
- }
801
-
802
- .workspace-shell {
803
- grid-template-columns: minmax(240px, 284px) minmax(0, 1fr);
804
- background: var(--app-bg);
805
- }
806
-
807
- .workspace-rail {
808
- background: var(--rail-bg);
809
- color: var(--rail-ink);
810
- border-right: 1px solid var(--rail-line);
811
- box-shadow: none;
812
- overflow-y: auto;
813
- scrollbar-gutter: stable;
814
- }
815
-
816
- .rail-brand {
817
- min-height: 48px;
818
- border-radius: 8px;
819
- background: rgba(255, 255, 255, 0.06);
820
- border: 1px solid var(--rail-line);
821
- }
822
-
823
- .rail-brand span {
824
- line-height: 1;
825
- }
826
-
827
- .rail-brand small {
828
- margin-left: auto;
829
- color: var(--rail-ink-soft);
830
- font-size: 10px;
831
- font-weight: 800;
832
- text-transform: uppercase;
833
- letter-spacing: 0.08em;
834
- }
835
-
836
- .rail-section-label {
837
- color: var(--rail-ink-soft);
838
- display: block;
839
- font-size: 10px;
840
- font-weight: 900;
841
- letter-spacing: 0.1em;
842
- padding: 8px 12px 4px;
843
- text-transform: uppercase;
844
- }
845
-
846
- .workspace-rail nav a,
847
- .rail-links a {
848
- border: 1px solid transparent;
849
- min-height: 42px;
850
- }
851
-
852
- .workspace-rail nav a.active,
853
- .workspace-rail nav a:hover,
854
- .rail-links a:hover {
855
- background: var(--rail-hover);
856
- border-color: var(--rail-line);
857
- }
858
-
859
- .workspace-shell:not([data-admin-available="true"]) .admin-navigation {
860
- display: none;
861
- }
862
-
863
- main {
864
- gap: 16px;
865
- padding: 20px clamp(16px, 2vw, 28px) 36px;
866
- }
867
-
868
- .workspace-topbar {
869
- position: sticky;
870
- top: 0;
871
- z-index: 4;
872
- margin: -20px calc(clamp(16px, 2vw, 28px) * -1) 0;
873
- padding: 16px clamp(16px, 2vw, 28px);
874
- background: color-mix(in srgb, var(--surface-elevated) 94%, transparent);
875
- border-bottom: 1px solid var(--line);
876
- backdrop-filter: none; /* glass removed v3.5.0 */
877
- }
878
-
879
- .topbar-subtitle {
880
- color: var(--muted);
881
- font-size: 13px;
882
- line-height: 1.45;
883
- margin: 6px 0 0;
884
- max-width: 760px;
885
- }
886
-
887
- .top-actions {
888
- flex-wrap: wrap;
889
- justify-content: flex-end;
890
- min-width: min(100%, 560px);
891
- }
892
-
893
- .global-mode-switcher {
894
- display: inline-grid;
895
- grid-auto-flow: column;
896
- grid-auto-columns: minmax(76px, 1fr);
897
- gap: 2px;
898
- padding: 3px;
899
- border: 1px solid var(--line);
900
- border-radius: 8px;
901
- background: var(--surface-2);
902
- }
903
-
904
- .global-mode-switcher button {
905
- min-height: 34px;
906
- border-radius: 6px;
907
- background: transparent;
908
- color: var(--muted);
909
- font-size: 12px;
910
- font-weight: 800;
911
- padding: 0 10px;
912
- }
913
-
914
- .global-mode-switcher button.active {
915
- background: var(--accent);
916
- color: #fff;
917
- }
918
-
919
- .global-mode-switcher button:disabled {
920
- cursor: not-allowed;
921
- opacity: 0.45;
922
- }
923
-
924
- .chrome-select {
925
- width: auto;
926
- min-width: 108px;
927
- min-height: 38px;
928
- color: var(--ink);
929
- background: var(--surface);
930
- }
931
-
932
- .workspace-switcher {
933
- background: var(--surface);
934
- border-color: var(--line);
935
- color: var(--ink);
936
- }
937
-
938
- .workspace-switcher select {
939
- color: var(--ink);
940
- max-width: min(220px, 36vw);
941
- }
942
-
943
- .workspace-role-pill {
944
- color: var(--muted);
945
- opacity: 1;
946
- }
947
-
948
- .metric-grid {
949
- grid-template-columns: repeat(4, minmax(150px, 1fr));
950
- }
951
-
952
- .metric-card,
953
- .workspace-panel,
954
- .workspace-band {
955
- background: var(--surface);
956
- border-color: var(--line);
957
- border-radius: 8px;
958
- box-shadow: none;
959
- }
960
-
961
- .metric-card {
962
- border-left: 3px solid var(--accent);
963
- }
964
-
965
- .metric-card i,
966
- .health-card i {
967
- color: var(--accent-2);
968
- }
969
-
970
- .workspace-band,
971
- .workspace-panel {
972
- padding: 18px;
973
- }
974
-
975
- .section-head {
976
- border-bottom: 1px solid var(--line);
977
- margin: -2px 0 14px;
978
- padding-bottom: 12px;
979
- }
980
-
981
- .eyebrow {
982
- color: var(--accent);
983
- }
984
-
985
- .primary-action {
986
- background: var(--accent);
987
- }
988
-
989
- .secondary-action,
990
- .tab.active,
991
- .switch-chip.active {
992
- background: var(--accent-soft);
993
- color: var(--accent);
994
- border-color: color-mix(in srgb, var(--accent) 34%, var(--line));
995
- }
996
-
997
- .icon-action,
998
- .small-action,
999
- .step-chip,
1000
- .tab,
1001
- .switch-chip,
1002
- .list-item,
1003
- .health-card,
1004
- .capability-card {
1005
- background: var(--surface-2);
1006
- border-color: var(--line);
1007
- }
1008
-
1009
- .list-item,
1010
- .health-card,
1011
- .capability-card {
1012
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45);
1013
- }
1014
-
1015
- :root[data-lt-theme="dark"] .list-item,
1016
- :root[data-lt-theme="dark"] .health-card,
1017
- :root[data-lt-theme="dark"] .capability-card {
1018
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
1019
- }
1020
-
1021
- .status-pill {
1022
- background: var(--accent-soft);
1023
- color: var(--accent);
1024
- }
1025
-
1026
- .status-complete {
1027
- background: color-mix(in srgb, var(--success) 16%, transparent);
1028
- color: var(--success);
1029
- }
1030
-
1031
- .status-running {
1032
- background: color-mix(in srgb, var(--warning) 18%, transparent);
1033
- color: var(--warning);
1034
- }
1035
-
1036
- .status-failed {
1037
- background: color-mix(in srgb, var(--danger) 16%, transparent);
1038
- color: var(--danger);
1039
- }
1040
-
1041
- .importance-bar {
1042
- background: var(--surface-3);
1043
- }
1044
-
1045
- .importance-bar span,
1046
- .skill-progress-track span {
1047
- background: linear-gradient(90deg, var(--accent), var(--accent-2));
1048
- }
1049
-
1050
- .code-box,
1051
- .state-box,
1052
- .toast {
1053
- background: #101820;
1054
- border-color: rgba(148, 163, 184, 0.22);
1055
- }
1056
-
1057
- @media (min-width: 1600px) {
1058
- main {
1059
- max-width: 1680px;
1060
- width: 100%;
1061
- }
1062
-
1063
- .metric-grid,
1064
- .health-grid {
1065
- grid-template-columns: repeat(4, minmax(180px, 1fr));
1066
- }
1067
- }
1068
-
1069
- @media (max-width: 1180px) {
1070
- .workspace-topbar {
1071
- align-items: flex-start;
1072
- flex-direction: column;
1073
- }
1074
-
1075
- .top-actions {
1076
- justify-content: flex-start;
1077
- width: 100%;
1078
- }
1079
- }
1080
-
1081
- @media (max-width: 860px) {
1082
- .workspace-shell {
1083
- grid-template-columns: 1fr;
1084
- }
1085
-
1086
- .workspace-rail {
1087
- position: relative;
1088
- height: auto;
1089
- max-height: none;
1090
- }
1091
-
1092
- .workspace-rail nav,
1093
- .rail-links {
1094
- grid-template-columns: repeat(2, minmax(0, 1fr));
1095
- }
1096
-
1097
- .rail-section-label,
1098
- .rail-brand {
1099
- grid-column: 1 / -1;
1100
- }
1101
-
1102
- .workspace-topbar {
1103
- position: static;
1104
- margin-top: 0;
1105
- }
1106
-
1107
- .global-mode-switcher {
1108
- grid-auto-columns: minmax(88px, 1fr);
1109
- width: 100%;
1110
- }
1111
-
1112
- .workspace-switcher,
1113
- .chrome-select,
1114
- .primary-action {
1115
- width: 100%;
1116
- }
1117
-
1118
- .workspace-switcher select {
1119
- max-width: none;
1120
- }
1121
- }