aimeat 3.3.0 → 3.3.2

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 (141) hide show
  1. package/README.md +1 -1
  2. package/dist/.env.example +10 -1
  3. package/dist/build-stamp.json +4 -4
  4. package/dist/locales/en.json +9263 -9225
  5. package/dist/locales/es.json +9255 -9217
  6. package/dist/locales/fi.json +9263 -9225
  7. package/dist/public/css/views/admin.css +935 -860
  8. package/dist/public/css/views/chat.css +393 -388
  9. package/dist/public/js/services/admin.js +12 -0
  10. package/dist/public/robots.node.txt +4 -0
  11. package/dist/public/views/admin/config-tab.js +333 -185
  12. package/dist/public/views/admin/usage-tab.js +373 -307
  13. package/dist/public/views/chat/parts.js +25 -6
  14. package/dist/public/views/profile/landing-page.cards.js +732 -700
  15. package/dist/public/views/profile/landing-page.js +6 -2
  16. package/dist/scripts/audit-mcp-schemas.js +22 -6
  17. package/dist/scripts/audit-mcp-schemas.js.map +1 -1
  18. package/dist/scripts/check-ai-disclosure.d.ts +1 -1
  19. package/dist/scripts/check-ai-disclosure.d.ts.map +1 -1
  20. package/dist/scripts/check-ai-disclosure.js +19 -3
  21. package/dist/scripts/check-ai-disclosure.js.map +1 -1
  22. package/dist/scripts/check-config-coverage.d.ts +2 -0
  23. package/dist/scripts/check-config-coverage.d.ts.map +1 -0
  24. package/dist/scripts/check-config-coverage.js +129 -0
  25. package/dist/scripts/check-config-coverage.js.map +1 -0
  26. package/dist/src/auth/ai-gate.d.ts +25 -0
  27. package/dist/src/auth/ai-gate.d.ts.map +1 -0
  28. package/dist/src/auth/ai-gate.js +21 -0
  29. package/dist/src/auth/ai-gate.js.map +1 -0
  30. package/dist/src/cli/connect/mcp/tools/apps.d.ts.map +1 -1
  31. package/dist/src/cli/connect/mcp/tools/apps.js +102 -20
  32. package/dist/src/cli/connect/mcp/tools/apps.js.map +1 -1
  33. package/dist/src/cli/connect/tool-call-defs-agent.d.ts.map +1 -1
  34. package/dist/src/cli/connect/tool-call-defs-agent.js +38 -9
  35. package/dist/src/cli/connect/tool-call-defs-agent.js.map +1 -1
  36. package/dist/src/cli/connect/tool-call-defs-apps.d.ts.map +1 -1
  37. package/dist/src/cli/connect/tool-call-defs-apps.js +199 -103
  38. package/dist/src/cli/connect/tool-call-defs-apps.js.map +1 -1
  39. package/dist/src/cli/connect/tool-call-defs-core.d.ts.map +1 -1
  40. package/dist/src/cli/connect/tool-call-defs-core.js +149 -26
  41. package/dist/src/cli/connect/tool-call-defs-core.js.map +1 -1
  42. package/dist/src/cli/connect/tool-call-defs-organism.d.ts.map +1 -1
  43. package/dist/src/cli/connect/tool-call-defs-organism.js +20 -3
  44. package/dist/src/cli/connect/tool-call-defs-organism.js.map +1 -1
  45. package/dist/src/cli/connect/tool-call-defs-packages.d.ts +23 -0
  46. package/dist/src/cli/connect/tool-call-defs-packages.d.ts.map +1 -0
  47. package/dist/src/cli/connect/tool-call-defs-packages.js +45 -0
  48. package/dist/src/cli/connect/tool-call-defs-packages.js.map +1 -0
  49. package/dist/src/cli/connect/tool-call-defs-workflows.d.ts +14 -0
  50. package/dist/src/cli/connect/tool-call-defs-workflows.d.ts.map +1 -0
  51. package/dist/src/cli/connect/tool-call-defs-workflows.js +75 -0
  52. package/dist/src/cli/connect/tool-call-defs-workflows.js.map +1 -0
  53. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  54. package/dist/src/cli/connect/tool-call.js +54 -1
  55. package/dist/src/cli/connect/tool-call.js.map +1 -1
  56. package/dist/src/config-types-ai.d.ts +13 -0
  57. package/dist/src/config-types-ai.d.ts.map +1 -1
  58. package/dist/src/config.d.ts.map +1 -1
  59. package/dist/src/config.js +2 -0
  60. package/dist/src/config.js.map +1 -1
  61. package/dist/src/generated/api-types.d.ts +196 -0
  62. package/dist/src/generated/api-types.d.ts.map +1 -1
  63. package/dist/src/mcp/annotations.d.ts.map +1 -1
  64. package/dist/src/mcp/annotations.js +8 -0
  65. package/dist/src/mcp/annotations.js.map +1 -1
  66. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.d.ts.map +1 -1
  67. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js +25 -8
  68. package/dist/src/mcp/catalog/definitions/organisms-workspaces-apps.js.map +1 -1
  69. package/dist/src/mcp/catalog/definitions/packages.d.ts +17 -0
  70. package/dist/src/mcp/catalog/definitions/packages.d.ts.map +1 -0
  71. package/dist/src/mcp/catalog/definitions/packages.js +46 -0
  72. package/dist/src/mcp/catalog/definitions/packages.js.map +1 -0
  73. package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
  74. package/dist/src/mcp/catalog/definitions.js +2 -0
  75. package/dist/src/mcp/catalog/definitions.js.map +1 -1
  76. package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
  77. package/dist/src/mcp/catalog/scopes.js +2 -0
  78. package/dist/src/mcp/catalog/scopes.js.map +1 -1
  79. package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
  80. package/dist/src/mcp/catalog/surfaces.js +2 -0
  81. package/dist/src/mcp/catalog/surfaces.js.map +1 -1
  82. package/dist/src/routes/admin-usage.d.ts.map +1 -1
  83. package/dist/src/routes/admin-usage.js +57 -0
  84. package/dist/src/routes/admin-usage.js.map +1 -1
  85. package/dist/src/routes/ai.d.ts.map +1 -1
  86. package/dist/src/routes/ai.js +4 -15
  87. package/dist/src/routes/ai.js.map +1 -1
  88. package/dist/src/routes/bootstrap.d.ts +2 -1
  89. package/dist/src/routes/bootstrap.d.ts.map +1 -1
  90. package/dist/src/routes/bootstrap.js +7 -18
  91. package/dist/src/routes/bootstrap.js.map +1 -1
  92. package/dist/src/routes/chat.d.ts +3 -0
  93. package/dist/src/routes/chat.d.ts.map +1 -1
  94. package/dist/src/routes/chat.js +20 -0
  95. package/dist/src/routes/chat.js.map +1 -1
  96. package/dist/src/routes/llm-proxy.d.ts +34 -0
  97. package/dist/src/routes/llm-proxy.d.ts.map +1 -0
  98. package/dist/src/routes/llm-proxy.js +258 -0
  99. package/dist/src/routes/llm-proxy.js.map +1 -0
  100. package/dist/src/routes/sitemaps.d.ts +22 -0
  101. package/dist/src/routes/sitemaps.d.ts.map +1 -0
  102. package/dist/src/routes/sitemaps.js +67 -0
  103. package/dist/src/routes/sitemaps.js.map +1 -0
  104. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  105. package/dist/src/server-bootstrap/routes-loader.js +2 -0
  106. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  107. package/dist/src/services/ai-completion.d.ts +76 -0
  108. package/dist/src/services/ai-completion.d.ts.map +1 -1
  109. package/dist/src/services/ai-completion.js +104 -68
  110. package/dist/src/services/ai-completion.js.map +1 -1
  111. package/dist/src/services/chat-session.d.ts +3 -0
  112. package/dist/src/services/chat-session.d.ts.map +1 -1
  113. package/dist/src/services/chat-session.js +4 -0
  114. package/dist/src/services/chat-session.js.map +1 -1
  115. package/dist/src/services/config-schema.d.ts +4 -0
  116. package/dist/src/services/config-schema.d.ts.map +1 -1
  117. package/dist/src/services/config-schema.js +33 -0
  118. package/dist/src/services/config-schema.js.map +1 -1
  119. package/dist/src/services/goose-acp.d.ts.map +1 -1
  120. package/dist/src/services/goose-acp.js +11 -0
  121. package/dist/src/services/goose-acp.js.map +1 -1
  122. package/dist/src/services/handbooks/appdev.d.ts +1 -1
  123. package/dist/src/services/handbooks/appdev.d.ts.map +1 -1
  124. package/dist/src/services/handbooks/appdev.js +7 -1
  125. package/dist/src/services/handbooks/appdev.js.map +1 -1
  126. package/dist/src/services/openrouter.d.ts +23 -0
  127. package/dist/src/services/openrouter.d.ts.map +1 -1
  128. package/dist/src/services/openrouter.js +32 -1
  129. package/dist/src/services/openrouter.js.map +1 -1
  130. package/dist/src/services/usage-summary.d.ts +15 -0
  131. package/dist/src/services/usage-summary.d.ts.map +1 -1
  132. package/dist/src/services/usage-summary.js +15 -0
  133. package/dist/src/services/usage-summary.js.map +1 -1
  134. package/dist/src/storage/providers/postgres-kysely/methods/wallet.d.ts.map +1 -1
  135. package/dist/src/storage/providers/postgres-kysely/methods/wallet.js +23 -4
  136. package/dist/src/storage/providers/postgres-kysely/methods/wallet.js.map +1 -1
  137. package/dist/src/storage/providers/sqlite/methods/work.d.ts +5 -0
  138. package/dist/src/storage/providers/sqlite/methods/work.d.ts.map +1 -1
  139. package/dist/src/storage/providers/sqlite/methods/work.js +34 -22
  140. package/dist/src/storage/providers/sqlite/methods/work.js.map +1 -1
  141. package/package.json +4 -1
@@ -1,860 +1,935 @@
1
- /* ── Admin Dashboard SPA Styles ──
2
- * @file admin.css
3
- * @description Admin dashboard (operator tooling) styles, .adm-* scoped. Keeps
4
- * its distinct indigo accent and a permanently-dark sidebar, but all content
5
- * surfaces map to global theme.css tokens so they flip with dark/light mode.
6
- * @version-history
7
- * v1.11.0 — 2026-08-15 — Organism ownership tab: .adm-oo-row / .adm-oo-card. The panel first
8
- * shipped with the profile's .detail-card/.form-row classes, which admin.css does not define, so
9
- * label and value rendered with no gap ("Ownershappyadmin") and the button dropped under the
10
- * input. Caught by driving the browser, not by any gate.
11
- * v1.10.0 — 2026-07-21 — App-shell scroll model (theme.css v1.24.0): .adm-sidebar height 100vh →
12
- * calc(100dvh − nav-height) so the sticky sidebar fills the .page-content scroll region instead of
13
- * overflowing the frame by the header's height.
14
- * v1.9.0 — 2026-07-16 — Drop the dead .adm-nav-item .icon rule (nav is label-only now).
15
- * v1.8.0 — 2026-06-25 — Applications tab: .adm-apps-rowactions (Hide/Restore + Delete row).
16
- * v1.7.0 — 2026-06-24 — Applications moderation tab: .adm-apps-* (filters row,
17
- * hidden-only toggle, dimmed hidden rows, modal actions).
18
- * v1.6.0 — 2026-06-12 — Subdomains tab: .adm-subdomain-form create-form grid
19
- * + .adm-subdomain-modal-actions (right-aligned type-to-confirm buttons).
20
- * v1.5.0 — 2026-06-02 — Component unification (#13 tables): strip the dead
21
- * `, #E5E7EB` hardcoded fallback from `.adm-breakdown-table th` border
22
- * (.adm always maps --glass-border → --border, so the fallback was dead
23
- * light-frozen code). No visual change. The .adm table look is unchanged
24
- * (scoped .adm table still wins over the new generic .data-table).
25
- * v1.1.0 — 2026-06-02 — Tokenize all surfaces/text/borders/badges for dark mode (Phase 2).
26
- * v1.2.0 — 2026-06-02 — Component unification (#3): remove .adm-modal-overlay
27
- * duplicate; msm-tab now uses canonical theme.css .modal-overlay.
28
- * v1.3.0 — 2026-06-02 — Component unification (#16): add tokenized
29
- * .tag--status-* classes (replace agent-tasks-tab inline hex status colors).
30
- * v1.4.0 — 2026-06-02 — Component unification (#21 key/value rows): strip the
31
- * dead `, #6366F1` hardcoded hex fallbacks from every `var(--accent, #6366F1)`
32
- * (10 sites incl. .adm-hval) — .adm always defines --accent (indigo light /
33
- * #818CF8 dark), so the fallback was light-mode-frozen dead code. No visual
34
- * change; removes hardcoded hex per Rule 7.3. .adm-erow/.adm-hrow markup left
35
- * in place (mono/bordered look differs from canonical .kv-row).
36
- */
37
-
38
- /* Admin-scoped variables: indigo accent identity + surfaces mapped to global
39
- (flipping) tokens. Text tiers inherit the global tokens so they flip too. */
40
- .adm {
41
- --accent: #6366F1;
42
- --accent-light: rgba(99, 102, 241, 0.12);
43
- --glass-border: var(--border);
44
- --glass-bg: var(--bg-card);
45
- --bg-deep: var(--bg);
46
- --sidebar-bg: #1E293B; /* dark slate — sidebar stays dark in both themes (by design) */
47
- --sidebar-text: #CBD5E1;
48
- --sidebar-border: rgba(255, 255, 255, 0.08);
49
- }
50
- /* Brighten the indigo accent for contrast on dark surfaces */
51
- [data-theme="dark"] .adm { --accent: #818CF8; }
52
-
53
- /* Layout */
54
- .adm { display: flex; min-height: 100vh; position: relative; z-index: 1; background: var(--bg-deep); color: var(--text); }
55
-
56
- /* Sidebar — stays dark per mockup (its colors are intentionally fixed) */
57
- .adm-sidebar {
58
- width: 220px;
59
- background: var(--sidebar-bg);
60
- border-right: none;
61
- padding: 16px 0;
62
- flex-shrink: 0;
63
- /* App-shell: sticks to the top of the .page-content scroll region; height caps
64
- at that region (viewport minus the fixed header) so the sidebar's own nav
65
- scrolls instead of overflowing past the frame by the header's height. */
66
- position: sticky;
67
- top: 0;
68
- height: calc(100dvh - var(--nav-height, 56px));
69
- box-sizing: border-box; /* fold the 16px vertical padding into the height so it fits the scroll region */
70
- overflow-y: auto;
71
- display: flex;
72
- flex-direction: column;
73
- }
74
- .adm-sidebar .node-id {
75
- padding: 0 18px;
76
- padding-top: 4px;
77
- color: #475569;
78
- font-size: .69rem;
79
- font-family: var(--font-mono);
80
- margin-bottom: 16px;
81
- word-break: break-all;
82
- }
83
- .adm-nav-group {
84
- font-size: .625rem;
85
- text-transform: uppercase;
86
- letter-spacing: 1px;
87
- color: #475569;
88
- padding: 0 18px;
89
- margin-top: 16px;
90
- margin-bottom: 4px;
91
- font-weight: 700;
92
- }
93
- .adm-nav-item {
94
- display: flex;
95
- align-items: center;
96
- gap: 10px;
97
- padding: 7px 18px;
98
- color: var(--sidebar-text, #CBD5E1);
99
- font-size: .84rem;
100
- cursor: pointer;
101
- border: none;
102
- background: none;
103
- width: 100%;
104
- text-align: left;
105
- font-family: inherit;
106
- font-weight: 400;
107
- transition: all .1s;
108
- border-left: 3px solid transparent;
109
- }
110
- .adm-nav-item:hover { background: rgba(255,255,255,0.04); color: #F1F5F9; }
111
- .adm-nav-item.active {
112
- color: #FFFFFF;
113
- background: rgba(99,102,241,0.18);
114
- border-left-color: var(--accent);
115
- font-weight: 500;
116
- }
117
- .adm-nav-item .label { flex: 1; }
118
- .adm-nav-item .cnt {
119
- background: rgba(255,255,255,0.08);
120
- color: #94A3B8;
121
- font-size: .69rem;
122
- padding: 1px 7px;
123
- border-radius: 9999px;
124
- font-weight: 600;
125
- }
126
- .adm-sep { height: 1px; background: rgba(255,255,255,0.08); margin: 8px 16px; }
127
-
128
- /* Main area */
129
- .adm-main { flex: 1; padding: 24px 32px; overflow-y: auto; background: var(--bg-deep); }
130
- .adm-topbar {
131
- display: flex;
132
- justify-content: space-between;
133
- align-items: center;
134
- margin-bottom: 20px;
135
- flex-wrap: wrap;
136
- gap: 10px;
137
- }
138
- .adm-topbar-right { display: flex; align-items: center; gap: 12px; }
139
- .adm-page-title {
140
- font-size: 1.375rem;
141
- font-weight: 800;
142
- color: var(--text);
143
- display: flex;
144
- align-items: center;
145
- gap: 10px;
146
- }
147
-
148
- /* Cards */
149
- .adm-grid { display: grid; gap: 16px; margin-bottom: 20px; }
150
- .adm-grid-4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
151
- .adm-grid-3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
152
- .adm-grid-2 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
153
- .adm-card {
154
- background: var(--glass-bg, #FFFFFF);
155
- border: 1px solid var(--glass-border, #E5E7EB);
156
- border-radius: 14px;
157
- padding: 20px 24px;
158
- box-shadow: var(--shadow-sm);
159
- }
160
- .adm-card h2 {
161
- font-size: .66rem;
162
- text-transform: uppercase;
163
- letter-spacing: .5px;
164
- color: var(--text-muted);
165
- margin-bottom: 6px;
166
- font-weight: 700;
167
- }
168
- .adm-subhead {
169
- font-size: .62rem;
170
- text-transform: uppercase;
171
- letter-spacing: .5px;
172
- color: var(--text-muted);
173
- font-weight: 700;
174
- margin: 10px 0 4px;
175
- padding-top: 8px;
176
- border-top: 1px solid var(--border);
177
- }
178
- .adm-stat { font-size: 1.625rem; font-weight: 800; line-height: 1.1; color: var(--text); }
179
- .adm-stat.indigo { color: var(--accent); }
180
- .adm-stat.mint,
181
- .adm-stat.green { color: var(--mint); }
182
- .adm-stat.cyan { color: var(--teal); }
183
- .adm-stat.amber { color: var(--warn); }
184
- .adm-stat.purple { color: var(--purple); }
185
- .adm-stat.blue { color: var(--blue); }
186
- .adm-stat.orange { color: var(--orange); }
187
- .adm-stat.red { color: var(--danger); }
188
- .adm-stat-label { color: var(--text-muted); font-size: .69rem; margin-top: 2px; }
189
-
190
- /* Storage/Database tab — per-table growth deltas + the counts table. */
191
- .adm-delta-up { color: var(--success); }
192
- .adm-delta-down { color: var(--danger); }
193
- .adm-delta-zero { color: var(--text-muted); }
194
- .adm-db-table { width: 100%; border-collapse: collapse; font-size: .82rem; }
195
- .adm-db-table th, .adm-db-table td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); }
196
- .adm-db-table th { color: var(--text-muted); font-weight: 600; }
197
- .adm-db-table td.num, .adm-db-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
198
- .adm-db-bar { height: 6px; border-radius: 3px; background: var(--blue); min-width: 2px; }
199
- .adm-db-bar-track { background: var(--bg-dim); border-radius: 3px; width: 100%; }
200
-
201
- /* Badges */
202
- .adm-badge {
203
- display: inline-block;
204
- padding: 2px 8px;
205
- border-radius: 20px;
206
- font-size: .7rem;
207
- font-weight: 600;
208
- text-transform: uppercase;
209
- }
210
- /* Badge semantic colors */
211
- .adm-badge--success { background: var(--success-bg); color: var(--success-fg); }
212
- .adm-badge--warning { background: var(--warn-bg); color: var(--warn-fg); }
213
- .adm-badge--danger { background: var(--danger-bg); color: var(--danger-fg); }
214
- .adm-badge--info { background: var(--info-bg); color: var(--info-fg); }
215
- .adm-badge--accent { background: var(--purple-bg); color: var(--purple-fg); }
216
- .adm-badge--muted { background: var(--bg-surface); color: var(--text-dim); }
217
- /* Single-dash aliases — the <Badge> component emits adm-badge-${type}, so these
218
- semantic tones need the single-dash form too (were undefined → badges rendered
219
- with no background in cortex/capabilities/federation tabs). neutral = muted. */
220
- .adm-badge-success { background: var(--success-bg); color: var(--success-fg); }
221
- .adm-badge-warning { background: var(--warn-bg); color: var(--warn-fg); }
222
- .adm-badge-muted,
223
- .adm-badge-neutral { background: var(--bg-surface); color: var(--text-dim); }
224
-
225
- /* Badge name aliases → semantic colors */
226
- .adm-badge-healthy,
227
- .adm-badge-public,
228
- .adm-badge-delivered,
229
- .adm-badge-settled,
230
- .adm-badge-owner { background: var(--success-bg); color: var(--success-fg); }
231
-
232
- .adm-badge-watch,
233
- .adm-badge-pending { background: var(--warn-bg); color: var(--warn-fg); }
234
-
235
- .adm-badge-danger,
236
- .adm-badge-critical,
237
- .adm-badge-cancelled,
238
- .adm-badge-expired,
239
- .adm-badge-disputed,
240
- .adm-badge-error { background: var(--danger-bg); color: var(--danger-fg); }
241
-
242
- .adm-badge-info,
243
- .adm-badge-accepted,
244
- .adm-badge-in_progress,
245
- .adm-badge-operator,
246
- .adm-badge-syncing { background: var(--info-bg); color: var(--info-fg); }
247
-
248
- .adm-badge-private,
249
- .adm-badge-agent { background: var(--purple-bg); color: var(--purple-fg); }
250
-
251
- .adm-badge-idle,
252
- .adm-badge-general { background: var(--bg-surface); color: var(--text-dim); }
253
-
254
- /* Error / success toast */
255
- .adm-toast {
256
- padding: 10px 16px;
257
- border-radius: 8px;
258
- font-size: .85rem;
259
- margin-bottom: 12px;
260
- display: flex;
261
- align-items: center;
262
- gap: 8px;
263
- animation: adm-toast-in .2s ease;
264
- }
265
- .adm-toast-error { background: var(--danger-bg); color: var(--danger-fg); border: 1px solid var(--danger-border); }
266
- .adm-toast-success { background: var(--success-bg); color: var(--success-fg); border: 1px solid var(--success-border); }
267
- .adm-toast-dismiss {
268
- margin-left: auto;
269
- cursor: pointer;
270
- opacity: .6;
271
- background: none;
272
- border: none;
273
- color: inherit;
274
- font-size: 1rem;
275
- }
276
- .adm-toast-dismiss:hover { opacity: 1; }
277
- @keyframes adm-toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
278
-
279
- /* Economy rows */
280
- .adm-erow { display: flex; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid var(--border-subtle); }
281
- .adm-erow:last-child { border-bottom: none; }
282
- .adm-elabel { color: var(--text-dim); font-size: .84rem; }
283
- .adm-eval { font-family: var(--font-mono); font-size: .81rem; font-weight: 600; color: var(--text); }
284
-
285
- /* Health rows */
286
- .adm-hrow { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border-subtle); }
287
- .adm-hrow:last-child { border-bottom: none; }
288
- .adm-hmetric { font-size: .84rem; color: var(--text-dim); }
289
- .adm-hval { font-family: var(--font-mono); font-size: .84rem; color: var(--accent); }
290
-
291
- /* Tables */
292
- .adm table { width: 100%; border-collapse: collapse; font-size: .81rem; }
293
- .adm th { text-align: left; color: var(--text-muted); font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; font-size: .69rem; text-transform: uppercase; letter-spacing: .3px; }
294
- .adm td { padding: 8px 10px; border-bottom: 1px solid var(--border-subtle); color: var(--text-dim); }
295
- .adm tr:hover td { background: var(--bg-surface); }
296
-
297
- /* Misc */
298
- .adm .mono { font-family: var(--font-mono); font-size: .78rem; }
299
- .adm .scrollable { max-height: 600px; overflow-y: auto; }
300
- .adm .empty { color: var(--text-muted); text-align: center; padding: 24px; font-size: .85rem; }
301
- .adm .error-box { background: var(--danger-bg); border: 1px solid var(--danger-border); border-radius: 8px; padding: 16px; color: var(--danger-fg); margin: 20px 0; }
302
- .adm .tag { display: inline-block; background: var(--bg-surface); color: var(--text-dim); padding: 1px 6px; border-radius: 4px; font-size: .7rem; margin: 1px; }
303
- /* Status-colored task tags — tokenized (were inline hex colors). Color only;
304
- base .adm .tag has no border so border-color stays inert as before. */
305
- .adm .tag--status-active { color: var(--accent); }
306
- .adm .tag--status-done { color: var(--success); }
307
- .adm .tag--status-failed { color: var(--danger); }
308
- .adm .tag--status-stalled { color: var(--warn); }
309
- .adm .tag--status-queued { color: var(--purple); }
310
- .adm .tag--status-draft { color: var(--text-dim); }
311
-
312
- /* Buttons */
313
- .adm-btn {
314
- background: var(--accent);
315
- color: #fff;
316
- border: none;
317
- padding: 8px 18px;
318
- border-radius: 10px;
319
- cursor: pointer;
320
- font-size: .81rem;
321
- font-weight: 600;
322
- font-family: inherit;
323
- transition: all .15s;
324
- }
325
- .adm-btn:hover { filter: brightness(0.92); }
326
- .adm-btn:disabled { opacity: .5; cursor: not-allowed; }
327
- .adm-btn-sm {
328
- background: none;
329
- border: 1px solid var(--border);
330
- color: var(--accent);
331
- padding: 3px 10px;
332
- border-radius: 6px;
333
- cursor: pointer;
334
- font-size: .75rem;
335
- font-family: inherit;
336
- }
337
- .adm-btn-sm:hover { background: var(--bg-surface); }
338
- .adm-btn-action {
339
- background: none;
340
- border: 1px solid var(--border);
341
- color: var(--accent);
342
- padding: 4px 12px;
343
- border-radius: 6px;
344
- cursor: pointer;
345
- font-size: .78rem;
346
- font-family: inherit;
347
- }
348
- .adm-btn-action:hover { background: var(--bg-surface); }
349
-
350
- /* Sub-panels */
351
- .adm-sub-panel {
352
- background: var(--bg-surface);
353
- border: 1px solid var(--border);
354
- border-radius: 8px;
355
- padding: 12px;
356
- margin-top: 8px;
357
- font-size: .8rem;
358
- }
359
-
360
- /* Inputs */
361
- .adm input[type="text"],
362
- .adm input[type="number"],
363
- .adm input[type="email"],
364
- .adm input[type="password"],
365
- .adm textarea,
366
- .adm select {
367
- padding: 8px 10px;
368
- border-radius: 6px;
369
- border: 1.5px solid var(--border);
370
- background: var(--bg-input);
371
- color: var(--text);
372
- font-size: .85rem;
373
- font-family: inherit;
374
- }
375
- .adm input:focus,
376
- .adm textarea:focus,
377
- .adm select:focus {
378
- border-color: var(--accent);
379
- box-shadow: 0 0 0 3px rgba(99,102,241,0.15);
380
- outline: none;
381
- }
382
-
383
- /* Login overlay */
384
- .adm-login {
385
- max-width: 420px;
386
- margin: 60px auto;
387
- text-align: center;
388
- }
389
- .adm-login h2 {
390
- font-size: 1.2rem;
391
- color: var(--text);
392
- text-transform: none;
393
- letter-spacing: 0;
394
- margin-bottom: 4px;
395
- }
396
- .adm-login p { color: var(--text-dim); font-size: .85rem; margin-bottom: 16px; }
397
- .adm-login input { width: 100%; margin-bottom: 8px; }
398
- .adm-login-err {
399
- margin-top: 10px;
400
- padding: 8px;
401
- border-radius: 6px;
402
- background: var(--danger-bg);
403
- border: 1px solid var(--danger-border);
404
- color: var(--danger-fg);
405
- font-size: .85rem;
406
- }
407
-
408
- /* Config editor */
409
- .adm-config-changes {
410
- margin-bottom: 16px;
411
- padding: 12px;
412
- background: var(--warn-bg);
413
- border: 1px solid var(--warn-border);
414
- border-radius: 8px;
415
- }
416
- .adm-config-array-edit {
417
- width: 360px;
418
- max-width: 100%;
419
- min-height: 4.5rem;
420
- font-family: 'JetBrains Mono', monospace;
421
- font-size: 0.8rem;
422
- padding: 6px 8px;
423
- border: 1px solid var(--border, #E5E7EB);
424
- border-radius: 6px;
425
- resize: vertical;
426
- box-sizing: border-box;
427
- }
428
- .adm-config-readonly { opacity: 0.85; pointer-events: none; }
429
- .adm-config-readonly input,
430
- .adm-config-readonly select { background: var(--bg-surface); cursor: not-allowed; }
431
- .adm-config-readonly-banner {
432
- margin-bottom: 16px;
433
- padding: 12px 16px;
434
- background: var(--info-bg);
435
- border: 1px solid var(--info-border);
436
- border-radius: 8px;
437
- color: var(--info-fg);
438
- font-size: .85rem;
439
- }
440
- .adm-config-result-ok {
441
- padding: 8px 12px;
442
- border-radius: 6px;
443
- background: var(--success-bg);
444
- color: var(--success-fg);
445
- border: 1px solid var(--success-border);
446
- }
447
-
448
- /* Expandable help sections */
449
- .adm-help {
450
- margin-bottom: 12px;
451
- border: 1px solid var(--border);
452
- border-radius: 8px;
453
- background: var(--bg-surface);
454
- }
455
- .adm-help-summary {
456
- cursor: pointer;
457
- padding: 10px 14px;
458
- color: var(--accent);
459
- font-size: .85rem;
460
- font-weight: 600;
461
- user-select: none;
462
- }
463
- .adm-help-summary:hover { color: var(--text); }
464
- .adm-help-body {
465
- padding: 0 14px 12px;
466
- color: var(--text-dim);
467
- font-size: .82rem;
468
- line-height: 1.6;
469
- }
470
- .adm-help-body p { margin: 0 0 8px; }
471
- .adm-help-body ul { margin: 4px 0 8px; padding-left: 20px; }
472
- .adm-help-body li { margin-bottom: 4px; }
473
- .adm-help-body code {
474
- background: var(--code-bg);
475
- padding: 1px 5px;
476
- border-radius: 3px;
477
- font-size: .78rem;
478
- color: var(--accent);
479
- }
480
- .adm-help-body strong { color: var(--text); }
481
-
482
- /* Card grid for card-based layouts */
483
- .adm-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
484
-
485
- /* Responsive */
486
- @media (max-width: 768px) {
487
- .adm-sidebar { display: none; }
488
- .adm-main { padding: 12px; }
489
- }
490
-
491
- /* ── System Prompts ── */
492
- .adm-prompt-editor { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
493
- .adm-prompt-textarea {
494
- width: 100%; min-height: 300px; max-height: 600px;
495
- font-family: var(--font-mono); font-size: 13px; line-height: 1.5;
496
- background: var(--bg-input); border: 1.5px solid var(--border);
497
- color: var(--text); padding: 12px; border-radius: 8px;
498
- resize: vertical; box-sizing: border-box; tab-size: 2;
499
- }
500
- .adm-prompt-textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(99,102,241,0.15); }
501
- .adm-prompt-vars { font-size: .8rem; color: var(--text-dim); padding: 8px 12px; background: var(--bg-surface); border-radius: 6px; margin: 4px 0; }
502
- .adm-prompt-vars code { color: var(--accent); }
503
- .adm-prompt-version-row {
504
- display: flex; align-items: center; gap: 8px; padding: 6px 0;
505
- border-bottom: 1px solid var(--border-subtle); font-size: .85rem;
506
- }
507
- .adm-prompt-version-row:last-child { border-bottom: none; }
508
- .adm-prompt-used-tag {
509
- display: inline-block; font-size: .7rem; padding: 2px 6px;
510
- background: var(--bg-surface); border: 1px solid var(--border);
511
- border-radius: 4px; color: var(--text-dim); margin: 1px;
512
- }
513
- .adm-prompt-group-header {
514
- cursor: pointer; padding: 8px 0; font-weight: 600; color: var(--text);
515
- display: flex; align-items: center; gap: 6px;
516
- border-bottom: 1px solid var(--border-subtle);
517
- }
518
-
519
- /* ── Form Controls ── */
520
- .adm-input {
521
- background: var(--bg-input);
522
- border: 1.5px solid var(--border);
523
- color: var(--text);
524
- padding: 8px 12px;
525
- border-radius: 6px;
526
- font-size: .85rem;
527
- font-family: inherit;
528
- }
529
- .adm-input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(99,102,241,0.15); }
530
- .adm-input-full { width: 100%; }
531
-
532
- .adm-textarea {
533
- background: var(--bg-input);
534
- border: 1.5px solid var(--border);
535
- color: var(--text);
536
- padding: 10px;
537
- border-radius: 6px;
538
- font-family: var(--font-mono);
539
- font-size: .8rem;
540
- resize: vertical;
541
- line-height: 1.5;
542
- tab-size: 2;
543
- }
544
-
545
- /* ── Flex Utilities ── */
546
- .adm-flex { display: flex; gap: 8px; }
547
- .adm-flex-col { display: flex; flex-direction: column; gap: 8px; }
548
- .adm-flex-between { display: flex; justify-content: space-between; align-items: center; }
549
- .adm-flex-center { display: flex; align-items: center; gap: 8px; }
550
- .adm-flex-wrap { display: flex; flex-wrap: wrap; gap: 8px; }
551
-
552
- /* ── Text Utilities ── */
553
- .adm-text-xs { font-size: .7rem; }
554
- .adm-text-sm { font-size: .8rem; }
555
- .adm-text-base { font-size: .85rem; }
556
- .adm-text-dim { color: var(--text-dim); }
557
- .adm-text-bright { color: var(--text); }
558
- .adm-text-accent { color: var(--accent); }
559
- .adm-text-error { color: var(--danger-fg); }
560
- .adm-text-success { color: var(--success-fg); }
561
- .adm-text-mono { font-family: var(--font-mono); font-size: .8rem; }
562
-
563
- /* ── Spacing Utilities ── */
564
- .adm-gap-xs { gap: 4px; }
565
- .adm-gap-sm { gap: 8px; }
566
- .adm-gap-md { gap: 12px; }
567
- .adm-gap-lg { gap: 16px; }
568
-
569
- .adm-mb-xs { margin-bottom: 4px; }
570
- .adm-mb-sm { margin-bottom: 8px; }
571
- .adm-mb-md { margin-bottom: 12px; }
572
- .adm-mb-lg { margin-bottom: 16px; }
573
-
574
- .adm-mt-sm { margin-top: 8px; }
575
- .adm-mt-md { margin-top: 12px; }
576
- .adm-mt-lg { margin-top: 16px; }
577
-
578
- /* ── Modal ── canonical overlay/box live in theme.css (.modal-overlay / .modal).
579
- msm-tab uses .modal-overlay directly; no admin-specific override needed. */
580
-
581
- /* ── Memory Tab ──
582
- (the bespoke .adm-mem-stat summary cards were removed — memory/agent-tasks/
583
- sharing-groups now use the canonical <StatsGrid>/.adm-stat pattern.) */
584
- .adm-mem-filters {
585
- display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; align-items: center;
586
- }
587
- .adm-mem-filters .adm-input {
588
- padding: 6px 10px; border: 1px solid var(--glass-border); border-radius: 6px;
589
- font-size: .85rem; background: var(--glass-bg); color: inherit; min-width: 160px;
590
- }
591
- .adm-mem-value-label { font-size: .8rem; color: var(--text-dim); margin-bottom: 4px; }
592
- .adm-mem-value {
593
- background: var(--bg-surface); border: 1px solid var(--glass-border); border-radius: 6px;
594
- padding: 10px; font-size: .8rem; max-height: 300px; overflow: auto;
595
- white-space: pre-wrap; word-break: break-all; font-family: 'JetBrains Mono', monospace;
596
- }
597
- .adm-mem-pagination {
598
- display: flex; align-items: center; justify-content: center; gap: 12px;
599
- padding: 12px 0; border-top: 1px solid var(--glass-border); margin-top: 8px;
600
- }
601
- .adm-mem-page-info { font-size: .85rem; color: var(--text-dim); }
602
- /* Semantic button modifiers — combine with .adm-btn-sm / .adm-btn-action
603
- (which supply padding/radius). Theme-aware via tokens, never hardcoded hex.
604
- These replace the ad-hoc inline style="color:#ef4444…" overrides that were
605
- scattered across the tabs. */
606
- .adm-btn-danger {
607
- color: var(--danger-fg); border-color: var(--danger-border);
608
- }
609
- .adm-btn-danger:hover { background: var(--danger-bg); }
610
- .adm-btn-success {
611
- color: var(--success-fg); border-color: var(--success-border);
612
- }
613
- .adm-btn-success:hover { background: var(--success-bg); }
614
- /* Solid danger — combine with .adm-btn (which supplies layout); the bg override
615
- below wins on source order. For destructive primary actions (e.g. delete). */
616
- .adm-btn-danger-solid {
617
- background: var(--danger); color: #fff; border-color: transparent;
618
- }
619
- .adm-btn-danger-solid:hover { background: var(--danger); filter: brightness(0.92); }
620
- /* Info / ghost button modifiers (combine with .adm-btn-sm like -danger/-success). */
621
- .adm-btn-info { color: var(--info-fg); border-color: var(--info-border); }
622
- .adm-btn-info:hover { background: var(--info-bg); }
623
- .adm-btn-ghost { color: var(--text-dim); border-color: var(--border); }
624
- .adm-btn-ghost:hover { background: var(--bg-surface); }
625
-
626
- /* Previously-undefined classes used by cortex/database/skills/feedback tabs
627
- (they rendered unstyled). Defined to the admin design language — no markup
628
- change needed. */
629
- .adm-section-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
630
- .adm-meta-row { display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; color: var(--text-dim); font-size: 0.85rem; margin: 0.5rem 0; }
631
- .adm-actions-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
632
- .adm-row { padding: 0.35rem 0; border-bottom: 1px solid var(--border-subtle); }
633
- .adm-row:last-child { border-bottom: none; }
634
- .adm-table-wrap { overflow-x: auto; }
635
- .adm-link { background: none; border: none; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-align: left; }
636
- .adm-link:hover { text-decoration: underline; }
637
- .adm-desc, .adm-help-text { color: var(--text-dim); font-size: 0.85rem; }
638
- .adm-muted { color: var(--text-dim); }
639
-
640
- /* Subtabs row */
641
- .adm-subtabs { display: flex; gap: 8px; margin: 16px 0; flex-wrap: wrap; }
642
-
643
- /* Subdomains tab — create-form row: subdomain | kind | target (grows) | button */
644
- .adm-subdomain-form {
645
- display: grid;
646
- grid-template-columns: minmax(120px, 200px) minmax(100px, 140px) 1fr auto;
647
- gap: 8px;
648
- align-items: center;
649
- }
650
- .adm-subdomain-form .adm-text-error { grid-column: 1 / -1; }
651
- .adm-subdomain-modal-actions { justify-content: flex-end; }
652
-
653
- /* Applications (moderation) tab */
654
- .adm-apps-filters { gap: 12px; align-items: center; }
655
- .adm-apps-toggle { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
656
- .adm-apps-row-hidden { opacity: 0.6; }
657
- .adm-apps-modal-actions { justify-content: flex-end; }
658
- .adm-apps-rowactions { gap: 6px; flex-wrap: wrap; }
659
-
660
- /* Active subtab button */
661
- .adm-btn-active,
662
- .adm-btn-active:hover { background: var(--accent); color: #fff; }
663
-
664
- /* Packages tab seed card */
665
- .adm-pkg-seed-card { margin-bottom: 16px; text-align: center; padding: 24px; }
666
- .adm-pkg-seed-text { margin-bottom: 12px; }
667
- .adm-pkg-seed-msg { margin-top: 8px; font-size: .85rem; color: var(--mint); }
668
-
669
- /* Template moderation */
670
- .adm-mod-section { margin-bottom: 16px; }
671
- .adm-mod-review { margin-top: 8px; }
672
- .adm-mod-review-title { font-size: 1rem; font-weight: 700; margin-bottom: 8px; color: var(--text-bright, #1A1A2E); }
673
- .adm-mod-desc { font-size: .85rem; color: var(--text-dim, #6B7280); margin-bottom: 8px; }
674
- .adm-mod-meta-grid { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 8px; font-size: .84rem; }
675
- .adm-mod-meta-item { color: var(--text-dim, #6B7280); }
676
- .adm-mod-meta-item strong { color: var(--text-bright, #1A1A2E); }
677
- .adm-mod-tags { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 8px; }
678
- .adm-mod-pre { font-size: .78rem; white-space: pre-wrap; word-break: break-all; max-height: 300px; overflow: auto; font-family: var(--font-mono); background: var(--bg-deep, #F8FAFC); border: 1px solid var(--glass-border, #E5E7EB); border-radius: 6px; padding: 10px; }
679
- .adm-mod-components { margin-bottom: 12px; }
680
- .adm-mod-components h5 { font-size: .84rem; margin-bottom: 6px; }
681
- .adm-mod-actions { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; }
682
- .adm-mod-action-group { flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 6px; }
683
- .adm-mod-action-label { font-size: .78rem; font-weight: 600; color: var(--text-dim, #6B7280); }
684
- .adm-mod-input { padding: 6px 10px; border: 1px solid var(--glass-border, #E5E7EB); border-radius: 6px; font-size: .85rem; background: var(--glass-bg, #fff); color: inherit; }
685
- .adm-mod-suspend-panel { margin-top: 8px; }
686
- .adm-mod-suspend-row { display: flex; gap: 8px; align-items: center; }
687
- .adm-mod-suspend-row .adm-mod-input { flex: 1; }
688
-
689
- /* Badge aliases for moderation statuses */
690
- .adm-badge-approved { background: var(--success-bg); color: var(--success-fg); }
691
- .adm-badge-rejected { background: var(--danger-bg); color: var(--danger-fg); }
692
- .adm-badge-suspended { background: var(--warn-bg); color: var(--warn-fg); }
693
- .adm-badge-published { background: var(--success-bg); color: var(--success-fg); }
694
- .adm-badge-active { background: var(--success-bg); color: var(--success-fg); }
695
- .adm-badge-installed { background: var(--success-bg); color: var(--success-fg); }
696
-
697
- /* ── Board Members ── */
698
- .adm-board-detail { border-top: 1px solid var(--card-border, var(--glass-border)); padding-top: 8px; }
699
- .adm-board-post { margin-bottom: 6px; padding: 6px; background: var(--bg-card, var(--glass-bg)); border-radius: 6px; }
700
- .adm-board-members { border-top: 1px solid var(--card-border, var(--glass-border)); padding-top: 8px; }
701
- .adm-member-tag {
702
- display: inline-flex; align-items: center; gap: 4px;
703
- background: var(--glass-bg); border: 1px solid var(--glass-border);
704
- border-radius: 4px; padding: 2px 8px; font-size: .8rem;
705
- }
706
- .adm-member-tag code { font-size: .78rem; }
707
- .adm-member-remove {
708
- background: none; border: none; color: var(--text-dim); cursor: pointer;
709
- font-size: 1rem; line-height: 1; padding: 0 2px;
710
- }
711
- .adm-member-remove:hover { color: var(--danger, #E8564A); }
712
- .adm-member-add { display: flex; gap: 8px; align-items: center; }
713
- .adm-member-add .adm-input { flex: 1; font-size: .85rem; }
714
- .adm-font-mono { font-family: 'JetBrains Mono', monospace; }
715
-
716
- /* ── Stats Time Range Selector ── */
717
- .adm-time-range {
718
- display: flex;
719
- flex-wrap: wrap;
720
- align-items: center;
721
- gap: 8px;
722
- margin-bottom: 20px;
723
- padding: 12px 16px;
724
- background: var(--glass-bg, #FFFFFF);
725
- border: 1px solid var(--glass-border, #E5E7EB);
726
- border-radius: 8px;
727
- }
728
- .adm-time-range-label {
729
- font-size: 0.8rem;
730
- color: var(--text-dim);
731
- margin-right: 4px;
732
- }
733
- .adm-time-btn {
734
- padding: 4px 12px;
735
- font-size: 0.75rem;
736
- border: 1px solid var(--glass-border, #E5E7EB);
737
- border-radius: 6px;
738
- background: transparent;
739
- color: var(--text);
740
- cursor: pointer;
741
- font-family: inherit;
742
- transition: all 0.15s;
743
- }
744
- .adm-time-btn:hover { border-color: var(--accent); color: var(--accent); }
745
- .adm-time-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
746
- .adm-time-custom {
747
- display: flex;
748
- align-items: center;
749
- gap: 6px;
750
- margin-left: auto;
751
- }
752
- .adm-time-custom input[type="date"] {
753
- padding: 3px 8px;
754
- font-size: 0.75rem;
755
- border: 1px solid var(--glass-border, #E5E7EB);
756
- border-radius: 4px;
757
- background: var(--bg-input);
758
- color: var(--text);
759
- font-family: inherit;
760
- }
761
-
762
- /* ── Stats Breakdown Table ── */
763
- .adm-breakdown-table {
764
- width: 100%;
765
- border-collapse: collapse;
766
- font-size: 0.78rem;
767
- margin-top: 8px;
768
- }
769
- .adm-breakdown-table th {
770
- text-align: left;
771
- padding: 6px 10px;
772
- color: var(--text-dim);
773
- border-bottom: 1px solid var(--border);
774
- font-weight: 500;
775
- }
776
- .adm-breakdown-table td {
777
- padding: 5px 10px;
778
- border-bottom: 1px solid var(--border-subtle);
779
- }
780
- .adm-breakdown-table td.num {
781
- text-align: right;
782
- font-variant-numeric: tabular-nums;
783
- }
784
-
785
- /* ── Stats Section Header Colors ── */
786
- .adm-section-purple { color: var(--purple); }
787
- .adm-section-cyan { color: var(--teal); }
788
- .adm-section-violet { color: var(--purple); }
789
- .adm-section-amber { color: var(--warn); }
790
- .adm-section-red { color: var(--danger); }
791
-
792
- /* ── Breakdown Table ── */
793
- .adm-breakdown-table th.num { text-align: right; }
794
-
795
- /* ── Stats Inline Breakdown ── */
796
- .adm-date-separator { color: var(--text-dim); }
797
- .adm-mailbox-inline { padding: 10px 16px; }
798
- .adm-blocked-reasons { margin-bottom: 6px; color: var(--text-dim); }
799
- .adm-channels-summary { color: var(--text-dim); }
800
-
801
- .adm-badge-live {
802
- display: inline-block;
803
- font-size: 0.6rem;
804
- padding: 1px 6px;
805
- border-radius: 4px;
806
- background: var(--accent);
807
- color: #fff;
808
- vertical-align: middle;
809
- margin-left: 6px;
810
- }
811
-
812
- /* Security tab — incident list */
813
- .adm-sec-title { font-size: 1.05rem; font-weight: 700; margin: 0 0 0.3rem; }
814
- .adm-sec-desc { color: var(--muted); font-size: 0.85rem; margin: 0 0 0.75rem; }
815
- .adm-sec-empty { color: var(--muted); padding: 0.75rem 0; }
816
- .adm-sec-list { display: flex; flex-direction: column; gap: 0.5rem; }
817
- .adm-sec-row { display: flex; gap: 0.75rem; justify-content: space-between; align-items: flex-start; border: 1px solid var(--border); border-radius: 8px; padding: 0.6rem 0.75rem; background: var(--card); }
818
- .adm-sec-row.open { border-color: var(--danger); border-left-width: 3px; }
819
- .adm-sec-main { min-width: 0; flex: 1; }
820
- .adm-sec-line1 { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
821
- .adm-sec-type { font-weight: 600; color: var(--text); }
822
- .adm-sec-code { font-size: 0.78rem; background: var(--bg-dim); padding: 0.05rem 0.35rem; border-radius: 4px; }
823
- .adm-sec-when { font-size: 0.74rem; color: var(--muted); margin-left: auto; }
824
- .adm-sec-line2 { font-size: 0.82rem; color: var(--text); margin: 0.25rem 0; word-break: break-word; }
825
- .adm-sec-line3 { font-size: 0.76rem; color: var(--muted); }
826
- .adm-sec-actions { display: flex; gap: 0.35rem; flex-shrink: 0; flex-wrap: wrap; }
827
-
828
- /* ── Skills admin tab (adm-skills) — node registry Phase 2b ── */
829
- .adm-skills-row { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); padding: 0.55rem 0.75rem; margin-bottom: 0.5rem; }
830
- .adm-skills-row-main { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
831
- .adm-skills-version { font-size: 0.74rem; color: var(--muted); }
832
- .adm-skills-actions { margin-left: auto; display: flex; gap: 0.3rem; }
833
- .adm-skills-desc { font-size: 0.82rem; color: var(--muted); margin-top: 0.25rem; }
834
- .adm-skills-body { background: var(--bg-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.6rem; font-size: 0.78rem; max-height: 24rem; overflow: auto; white-space: pre-wrap; margin-top: 0.5rem; }
835
- .adm-skills-editor { margin: 0.5rem 0 0.75rem; }
836
- .adm-skills-editor-actions { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }
837
- .adm-skills-editor-md { width: 100%; min-height: 24rem; font-family: var(--mono); font-size: 0.82rem; resize: vertical; }
838
- .adm-skills-detail { margin-top: 0.5rem; }
839
- .adm-skills-frontmatter { background: var(--bg-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.5rem 0.6rem; font-size: 0.74rem; color: var(--muted); white-space: pre-wrap; margin-bottom: 0.5rem; }
840
- .adm-skills-body-md { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.75rem 1rem; font-size: 0.86rem; max-height: 32rem; overflow: auto; }
841
-
842
- /* ── Feedback tab (Node Feedback Channel operator inbox) ── */
843
- .adm-fb-filters { display: flex; gap: 0.5rem; margin: 0.75rem 0; flex-wrap: wrap; }
844
- .adm-fb-row { cursor: pointer; }
845
- .adm-fb-row:hover td { background: var(--bg-dim); }
846
- .adm-fb-thread-head { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.75rem; flex-wrap: wrap; }
847
- .adm-fb-status { margin-left: auto; }
848
- .adm-fb-msg { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); padding: 0.6rem 0.8rem; margin-top: 0.5rem; white-space: pre-wrap; font-size: 0.88rem; }
849
- .adm-fb-msg-operator { background: var(--bg-dim); margin-left: 2rem; }
850
- .adm-fb-msg-sender { margin-right: 2rem; }
851
- .adm-fb-context { font-size: 0.76rem; color: var(--muted); margin-top: 0.4rem; }
852
- .adm-fb-replybox { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }
853
- .adm-fb-replybox textarea { width: 100%; resize: vertical; }
854
-
855
- /* ── Organism ownership tab (operator break-glass) ── */
856
- /* The lookup and add-owner rows: one input that takes the width, one button beside it. Without
857
- this the button dropped under a full-width input and the pair stopped reading as one action. */
858
- .adm-oo-row { display: flex; gap: 0.5rem; align-items: center; margin: 0.75rem 0; flex-wrap: wrap; }
859
- .adm-oo-row .input-field { flex: 1 1 20rem; }
860
- .adm-oo-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.4rem 0.9rem; margin: 0.75rem 0; }
1
+ /* ── Admin Dashboard SPA Styles ──
2
+ * @file admin.css
3
+ * @description Admin dashboard (operator tooling) styles, .adm-* scoped. Keeps
4
+ * its distinct indigo accent and a permanently-dark sidebar, but all content
5
+ * surfaces map to global theme.css tokens so they flip with dark/light mode.
6
+ * @version-history
7
+ * v1.11.0 — 2026-08-15 — Organism ownership tab: .adm-oo-row / .adm-oo-card. The panel first
8
+ * shipped with the profile's .detail-card/.form-row classes, which admin.css does not define, so
9
+ * label and value rendered with no gap ("Ownershappyadmin") and the button dropped under the
10
+ * input. Caught by driving the browser, not by any gate.
11
+ * v1.10.0 — 2026-07-21 — App-shell scroll model (theme.css v1.24.0): .adm-sidebar height 100vh →
12
+ * calc(100dvh − nav-height) so the sticky sidebar fills the .page-content scroll region instead of
13
+ * overflowing the frame by the header's height.
14
+ * v1.9.0 — 2026-07-16 — Drop the dead .adm-nav-item .icon rule (nav is label-only now).
15
+ * v1.8.0 — 2026-06-25 — Applications tab: .adm-apps-rowactions (Hide/Restore + Delete row).
16
+ * v1.7.0 — 2026-06-24 — Applications moderation tab: .adm-apps-* (filters row,
17
+ * hidden-only toggle, dimmed hidden rows, modal actions).
18
+ * v1.6.0 — 2026-06-12 — Subdomains tab: .adm-subdomain-form create-form grid
19
+ * + .adm-subdomain-modal-actions (right-aligned type-to-confirm buttons).
20
+ * v1.5.0 — 2026-06-02 — Component unification (#13 tables): strip the dead
21
+ * `, #E5E7EB` hardcoded fallback from `.adm-breakdown-table th` border
22
+ * (.adm always maps --glass-border → --border, so the fallback was dead
23
+ * light-frozen code). No visual change. The .adm table look is unchanged
24
+ * (scoped .adm table still wins over the new generic .data-table).
25
+ * v1.1.0 — 2026-06-02 — Tokenize all surfaces/text/borders/badges for dark mode (Phase 2).
26
+ * v1.2.0 — 2026-06-02 — Component unification (#3): remove .adm-modal-overlay
27
+ * duplicate; msm-tab now uses canonical theme.css .modal-overlay.
28
+ * v1.3.0 — 2026-06-02 — Component unification (#16): add tokenized
29
+ * .tag--status-* classes (replace agent-tasks-tab inline hex status colors).
30
+ * v1.4.0 — 2026-06-02 — Component unification (#21 key/value rows): strip the
31
+ * dead `, #6366F1` hardcoded hex fallbacks from every `var(--accent, #6366F1)`
32
+ * (10 sites incl. .adm-hval) — .adm always defines --accent (indigo light /
33
+ * #818CF8 dark), so the fallback was light-mode-frozen dead code. No visual
34
+ * change; removes hardcoded hex per Rule 7.3. .adm-erow/.adm-hrow markup left
35
+ * in place (mono/bordered look differs from canonical .kv-row).
36
+ */
37
+
38
+ /* Admin-scoped variables: indigo accent identity + surfaces mapped to global
39
+ (flipping) tokens. Text tiers inherit the global tokens so they flip too. */
40
+ .adm {
41
+ --accent: #6366F1;
42
+ --accent-light: rgba(99, 102, 241, 0.12);
43
+ --glass-border: var(--border);
44
+ --glass-bg: var(--bg-card);
45
+ --bg-deep: var(--bg);
46
+ --sidebar-bg: #1E293B; /* dark slate — sidebar stays dark in both themes (by design) */
47
+ --sidebar-text: #CBD5E1;
48
+ --sidebar-border: rgba(255, 255, 255, 0.08);
49
+ }
50
+ /* Brighten the indigo accent for contrast on dark surfaces */
51
+ [data-theme="dark"] .adm { --accent: #818CF8; }
52
+
53
+ /* Layout */
54
+ .adm { display: flex; min-height: 100vh; position: relative; z-index: 1; background: var(--bg-deep); color: var(--text); }
55
+
56
+ /* Sidebar — stays dark per mockup (its colors are intentionally fixed) */
57
+ .adm-sidebar {
58
+ width: 220px;
59
+ background: var(--sidebar-bg);
60
+ border-right: none;
61
+ padding: 16px 0;
62
+ flex-shrink: 0;
63
+ /* App-shell: sticks to the top of the .page-content scroll region; height caps
64
+ at that region (viewport minus the fixed header) so the sidebar's own nav
65
+ scrolls instead of overflowing past the frame by the header's height. */
66
+ position: sticky;
67
+ top: 0;
68
+ height: calc(100dvh - var(--nav-height, 56px));
69
+ box-sizing: border-box; /* fold the 16px vertical padding into the height so it fits the scroll region */
70
+ overflow-y: auto;
71
+ display: flex;
72
+ flex-direction: column;
73
+ }
74
+ .adm-sidebar .node-id {
75
+ padding: 0 18px;
76
+ padding-top: 4px;
77
+ color: #475569;
78
+ font-size: .69rem;
79
+ font-family: var(--font-mono);
80
+ margin-bottom: 16px;
81
+ word-break: break-all;
82
+ }
83
+ .adm-nav-group {
84
+ font-size: .625rem;
85
+ text-transform: uppercase;
86
+ letter-spacing: 1px;
87
+ color: #475569;
88
+ padding: 0 18px;
89
+ margin-top: 16px;
90
+ margin-bottom: 4px;
91
+ font-weight: 700;
92
+ }
93
+ .adm-nav-item {
94
+ display: flex;
95
+ align-items: center;
96
+ gap: 10px;
97
+ padding: 7px 18px;
98
+ color: var(--sidebar-text, #CBD5E1);
99
+ font-size: .84rem;
100
+ cursor: pointer;
101
+ border: none;
102
+ background: none;
103
+ width: 100%;
104
+ text-align: left;
105
+ font-family: inherit;
106
+ font-weight: 400;
107
+ transition: all .1s;
108
+ border-left: 3px solid transparent;
109
+ }
110
+ .adm-nav-item:hover { background: rgba(255,255,255,0.04); color: #F1F5F9; }
111
+ .adm-nav-item.active {
112
+ color: #FFFFFF;
113
+ background: rgba(99,102,241,0.18);
114
+ border-left-color: var(--accent);
115
+ font-weight: 500;
116
+ }
117
+ .adm-nav-item .label { flex: 1; }
118
+ .adm-nav-item .cnt {
119
+ background: rgba(255,255,255,0.08);
120
+ color: #94A3B8;
121
+ font-size: .69rem;
122
+ padding: 1px 7px;
123
+ border-radius: 9999px;
124
+ font-weight: 600;
125
+ }
126
+ .adm-sep { height: 1px; background: rgba(255,255,255,0.08); margin: 8px 16px; }
127
+
128
+ /* Main area */
129
+ .adm-main { flex: 1; padding: 24px 32px; overflow-y: auto; background: var(--bg-deep); }
130
+ .adm-topbar {
131
+ display: flex;
132
+ justify-content: space-between;
133
+ align-items: center;
134
+ margin-bottom: 20px;
135
+ flex-wrap: wrap;
136
+ gap: 10px;
137
+ }
138
+ .adm-topbar-right { display: flex; align-items: center; gap: 12px; }
139
+ .adm-page-title {
140
+ font-size: 1.375rem;
141
+ font-weight: 800;
142
+ color: var(--text);
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 10px;
146
+ }
147
+
148
+ /* Cards */
149
+ .adm-grid { display: grid; gap: 16px; margin-bottom: 20px; }
150
+ .adm-grid-4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
151
+ .adm-grid-3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
152
+ .adm-grid-2 { grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); }
153
+ .adm-card {
154
+ background: var(--glass-bg, #FFFFFF);
155
+ border: 1px solid var(--glass-border, #E5E7EB);
156
+ border-radius: 14px;
157
+ padding: 20px 24px;
158
+ box-shadow: var(--shadow-sm);
159
+ }
160
+ .adm-card h2 {
161
+ font-size: .66rem;
162
+ text-transform: uppercase;
163
+ letter-spacing: .5px;
164
+ color: var(--text-muted);
165
+ margin-bottom: 6px;
166
+ font-weight: 700;
167
+ }
168
+ .adm-subhead {
169
+ font-size: .62rem;
170
+ text-transform: uppercase;
171
+ letter-spacing: .5px;
172
+ color: var(--text-muted);
173
+ font-weight: 700;
174
+ margin: 10px 0 4px;
175
+ padding-top: 8px;
176
+ border-top: 1px solid var(--border);
177
+ }
178
+ .adm-stat { font-size: 1.625rem; font-weight: 800; line-height: 1.1; color: var(--text); }
179
+ .adm-stat.indigo { color: var(--accent); }
180
+ .adm-stat.mint,
181
+ .adm-stat.green { color: var(--mint); }
182
+ .adm-stat.cyan { color: var(--teal); }
183
+ .adm-stat.amber { color: var(--warn); }
184
+ .adm-stat.purple { color: var(--purple); }
185
+ .adm-stat.blue { color: var(--blue); }
186
+ .adm-stat.orange { color: var(--orange); }
187
+ .adm-stat.red { color: var(--danger); }
188
+ .adm-stat-label { color: var(--text-muted); font-size: .69rem; margin-top: 2px; }
189
+
190
+ /* Storage/Database tab — per-table growth deltas + the counts table. */
191
+ .adm-delta-up { color: var(--success); }
192
+ .adm-delta-down { color: var(--danger); }
193
+ .adm-delta-zero { color: var(--text-muted); }
194
+ .adm-db-table { width: 100%; border-collapse: collapse; font-size: .82rem; }
195
+ .adm-db-table th, .adm-db-table td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--border); }
196
+ .adm-db-table th { color: var(--text-muted); font-weight: 600; }
197
+ .adm-db-table td.num, .adm-db-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
198
+ .adm-db-bar { height: 6px; border-radius: 3px; background: var(--blue); min-width: 2px; }
199
+ .adm-db-bar-track { background: var(--bg-dim); border-radius: 3px; width: 100%; }
200
+
201
+ /* Badges */
202
+ .adm-badge {
203
+ display: inline-block;
204
+ padding: 2px 8px;
205
+ border-radius: 20px;
206
+ font-size: .7rem;
207
+ font-weight: 600;
208
+ text-transform: uppercase;
209
+ }
210
+ /* Badge semantic colors */
211
+ .adm-badge--success { background: var(--success-bg); color: var(--success-fg); }
212
+ .adm-badge--warning { background: var(--warn-bg); color: var(--warn-fg); }
213
+ .adm-badge--danger { background: var(--danger-bg); color: var(--danger-fg); }
214
+ .adm-badge--info { background: var(--info-bg); color: var(--info-fg); }
215
+ .adm-badge--accent { background: var(--purple-bg); color: var(--purple-fg); }
216
+ .adm-badge--muted { background: var(--bg-surface); color: var(--text-dim); }
217
+ /* Single-dash aliases — the <Badge> component emits adm-badge-${type}, so these
218
+ semantic tones need the single-dash form too (were undefined → badges rendered
219
+ with no background in cortex/capabilities/federation tabs). neutral = muted. */
220
+ .adm-badge-success { background: var(--success-bg); color: var(--success-fg); }
221
+ .adm-badge-warning { background: var(--warn-bg); color: var(--warn-fg); }
222
+ .adm-badge-muted,
223
+ .adm-badge-neutral { background: var(--bg-surface); color: var(--text-dim); }
224
+
225
+ /* Badge name aliases → semantic colors */
226
+ .adm-badge-healthy,
227
+ .adm-badge-public,
228
+ .adm-badge-delivered,
229
+ .adm-badge-settled,
230
+ .adm-badge-owner { background: var(--success-bg); color: var(--success-fg); }
231
+
232
+ .adm-badge-watch,
233
+ .adm-badge-pending { background: var(--warn-bg); color: var(--warn-fg); }
234
+
235
+ .adm-badge-danger,
236
+ .adm-badge-critical,
237
+ .adm-badge-cancelled,
238
+ .adm-badge-expired,
239
+ .adm-badge-disputed,
240
+ .adm-badge-error { background: var(--danger-bg); color: var(--danger-fg); }
241
+
242
+ .adm-badge-info,
243
+ .adm-badge-accepted,
244
+ .adm-badge-in_progress,
245
+ .adm-badge-operator,
246
+ .adm-badge-syncing { background: var(--info-bg); color: var(--info-fg); }
247
+
248
+ .adm-badge-private,
249
+ .adm-badge-agent { background: var(--purple-bg); color: var(--purple-fg); }
250
+
251
+ .adm-badge-idle,
252
+ .adm-badge-general { background: var(--bg-surface); color: var(--text-dim); }
253
+
254
+ /* Error / success toast */
255
+ .adm-toast {
256
+ padding: 10px 16px;
257
+ border-radius: 8px;
258
+ font-size: .85rem;
259
+ margin-bottom: 12px;
260
+ display: flex;
261
+ align-items: center;
262
+ gap: 8px;
263
+ animation: adm-toast-in .2s ease;
264
+ }
265
+ .adm-toast-error { background: var(--danger-bg); color: var(--danger-fg); border: 1px solid var(--danger-border); }
266
+ .adm-toast-success { background: var(--success-bg); color: var(--success-fg); border: 1px solid var(--success-border); }
267
+ .adm-toast-dismiss {
268
+ margin-left: auto;
269
+ cursor: pointer;
270
+ opacity: .6;
271
+ background: none;
272
+ border: none;
273
+ color: inherit;
274
+ font-size: 1rem;
275
+ }
276
+ .adm-toast-dismiss:hover { opacity: 1; }
277
+ @keyframes adm-toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } }
278
+
279
+ /* Economy rows */
280
+ .adm-erow { display: flex; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid var(--border-subtle); }
281
+ .adm-erow:last-child { border-bottom: none; }
282
+ .adm-elabel { color: var(--text-dim); font-size: .84rem; }
283
+ .adm-eval { font-family: var(--font-mono); font-size: .81rem; font-weight: 600; color: var(--text); }
284
+
285
+ /* Health rows */
286
+ .adm-hrow { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border-subtle); }
287
+ .adm-hrow:last-child { border-bottom: none; }
288
+ .adm-hmetric { font-size: .84rem; color: var(--text-dim); }
289
+ .adm-hval { font-family: var(--font-mono); font-size: .84rem; color: var(--accent); }
290
+
291
+ /* Tables */
292
+ .adm table { width: 100%; border-collapse: collapse; font-size: .81rem; }
293
+ .adm th { text-align: left; color: var(--text-muted); font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--border); white-space: nowrap; font-size: .69rem; text-transform: uppercase; letter-spacing: .3px; }
294
+ .adm td { padding: 8px 10px; border-bottom: 1px solid var(--border-subtle); color: var(--text-dim); }
295
+ .adm tr:hover td { background: var(--bg-surface); }
296
+
297
+ /* Misc */
298
+ .adm .mono { font-family: var(--font-mono); font-size: .78rem; }
299
+ .adm .scrollable { max-height: 600px; overflow-y: auto; }
300
+ .adm .empty { color: var(--text-muted); text-align: center; padding: 24px; font-size: .85rem; }
301
+ .adm .error-box { background: var(--danger-bg); border: 1px solid var(--danger-border); border-radius: 8px; padding: 16px; color: var(--danger-fg); margin: 20px 0; }
302
+ .adm .tag { display: inline-block; background: var(--bg-surface); color: var(--text-dim); padding: 1px 6px; border-radius: 4px; font-size: .7rem; margin: 1px; }
303
+ /* Status-colored task tags — tokenized (were inline hex colors). Color only;
304
+ base .adm .tag has no border so border-color stays inert as before. */
305
+ .adm .tag--status-active { color: var(--accent); }
306
+ .adm .tag--status-done { color: var(--success); }
307
+ .adm .tag--status-failed { color: var(--danger); }
308
+ .adm .tag--status-stalled { color: var(--warn); }
309
+ .adm .tag--status-queued { color: var(--purple); }
310
+ .adm .tag--status-draft { color: var(--text-dim); }
311
+
312
+ /* Buttons */
313
+ .adm-btn {
314
+ background: var(--accent);
315
+ color: #fff;
316
+ border: none;
317
+ padding: 8px 18px;
318
+ border-radius: 10px;
319
+ cursor: pointer;
320
+ font-size: .81rem;
321
+ font-weight: 600;
322
+ font-family: inherit;
323
+ transition: all .15s;
324
+ }
325
+ .adm-btn:hover { filter: brightness(0.92); }
326
+ .adm-btn:disabled { opacity: .5; cursor: not-allowed; }
327
+ .adm-btn-sm {
328
+ background: none;
329
+ border: 1px solid var(--border);
330
+ color: var(--accent);
331
+ padding: 3px 10px;
332
+ border-radius: 6px;
333
+ cursor: pointer;
334
+ font-size: .75rem;
335
+ font-family: inherit;
336
+ }
337
+ .adm-btn-sm:hover { background: var(--bg-surface); }
338
+ .adm-btn-action {
339
+ background: none;
340
+ border: 1px solid var(--border);
341
+ color: var(--accent);
342
+ padding: 4px 12px;
343
+ border-radius: 6px;
344
+ cursor: pointer;
345
+ font-size: .78rem;
346
+ font-family: inherit;
347
+ }
348
+ .adm-btn-action:hover { background: var(--bg-surface); }
349
+
350
+ /* Sub-panels */
351
+ .adm-sub-panel {
352
+ background: var(--bg-surface);
353
+ border: 1px solid var(--border);
354
+ border-radius: 8px;
355
+ padding: 12px;
356
+ margin-top: 8px;
357
+ font-size: .8rem;
358
+ }
359
+
360
+ /* Inputs */
361
+ .adm input[type="text"],
362
+ .adm input[type="number"],
363
+ .adm input[type="email"],
364
+ .adm input[type="password"],
365
+ .adm textarea,
366
+ .adm select {
367
+ padding: 8px 10px;
368
+ border-radius: 6px;
369
+ border: 1.5px solid var(--border);
370
+ background: var(--bg-input);
371
+ color: var(--text);
372
+ font-size: .85rem;
373
+ font-family: inherit;
374
+ }
375
+ .adm input:focus,
376
+ .adm textarea:focus,
377
+ .adm select:focus {
378
+ border-color: var(--accent);
379
+ box-shadow: 0 0 0 3px rgba(99,102,241,0.15);
380
+ outline: none;
381
+ }
382
+
383
+ /* Login overlay */
384
+ .adm-login {
385
+ max-width: 420px;
386
+ margin: 60px auto;
387
+ text-align: center;
388
+ }
389
+ .adm-login h2 {
390
+ font-size: 1.2rem;
391
+ color: var(--text);
392
+ text-transform: none;
393
+ letter-spacing: 0;
394
+ margin-bottom: 4px;
395
+ }
396
+ .adm-login p { color: var(--text-dim); font-size: .85rem; margin-bottom: 16px; }
397
+ .adm-login input { width: 100%; margin-bottom: 8px; }
398
+ .adm-login-err {
399
+ margin-top: 10px;
400
+ padding: 8px;
401
+ border-radius: 6px;
402
+ background: var(--danger-bg);
403
+ border: 1px solid var(--danger-border);
404
+ color: var(--danger-fg);
405
+ font-size: .85rem;
406
+ }
407
+
408
+ /* Config editor */
409
+ .adm-config-changes {
410
+ margin-bottom: 16px;
411
+ padding: 12px;
412
+ background: var(--warn-bg);
413
+ border: 1px solid var(--warn-border);
414
+ border-radius: 8px;
415
+ }
416
+ /* The pending bar follows the viewport, because the thing it reports — work that is not saved yet —
417
+ happens wherever you are on a page that is many screens long.
418
+ FIXED rather than sticky, and that was measured: the admin content sits inside `.adm-main`, which
419
+ has `overflow: auto` and is as tall as its content, so it is the nearest scrollport while the
420
+ actual scrolling happens in `.page-content` above it. A sticky bar therefore sticks to the top of
421
+ a box that itself scrolls away — measured at top: -1274px after one screen of scrolling, which is
422
+ the exact failure this bar exists to prevent. */
423
+ .adm-cfg-pending {
424
+ position: fixed;
425
+ left: 0;
426
+ right: 0;
427
+ bottom: 0;
428
+ z-index: 30;
429
+ margin-bottom: 0;
430
+ border-radius: 8px 8px 0 0;
431
+ box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.18);
432
+ }
433
+ .adm-cfg-pending-head {
434
+ display: flex;
435
+ align-items: center;
436
+ gap: 10px;
437
+ flex-wrap: wrap;
438
+ }
439
+ .adm-cfg-pending-hint { font-size: .8rem; opacity: .85; }
440
+ .adm-cfg-pending-actions { margin-left: auto; }
441
+ .adm-cfg-pending-list {
442
+ margin: 8px 0 0;
443
+ padding-left: 18px;
444
+ font-size: .8rem;
445
+ max-height: 30vh;
446
+ overflow-y: auto;
447
+ }
448
+ .adm-cfg-pending-list li { margin: 2px 0; display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; }
449
+ .adm-cfg-pending-was { text-decoration: line-through; opacity: .7; margin: 0 4px; }
450
+
451
+ /* An edited row stays findable after you have scrolled past it. */
452
+ .adm-cfg-row-edited { background: var(--warn-bg); border-radius: 6px; }
453
+ .adm-cfg-edited-dot { color: var(--warn-fg, #eab308); font-size: .8rem; }
454
+
455
+ /* Contents block */
456
+ .adm-cfg-toc-summary { cursor: pointer; font-weight: 600; font-size: .95rem; padding: 8px 0; }
457
+ .adm-cfg-toc-body {
458
+ display: grid;
459
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
460
+ gap: 12px;
461
+ padding: 8px 0;
462
+ }
463
+ .adm-cfg-toc-domain-name {
464
+ font-size: .7rem;
465
+ text-transform: uppercase;
466
+ letter-spacing: .04em;
467
+ color: var(--text-muted);
468
+ margin-bottom: 4px;
469
+ }
470
+ .adm-cfg-toc-links { display: flex; flex-wrap: wrap; gap: 4px; }
471
+ .adm-cfg-toc-link {
472
+ background: var(--bg-surface);
473
+ border: 1px solid var(--border);
474
+ border-radius: 6px;
475
+ padding: 3px 8px;
476
+ font-size: .78rem;
477
+ cursor: pointer;
478
+ color: inherit;
479
+ }
480
+ .adm-cfg-toc-link:hover { border-color: var(--accent-border); }
481
+ .adm-cfg-toc-count { color: var(--text-muted); font-size: .7rem; }
482
+
483
+ .adm-cfg-domain-head {
484
+ margin: 20px 0 8px;
485
+ font-size: .8rem;
486
+ text-transform: uppercase;
487
+ letter-spacing: .04em;
488
+ color: var(--text-muted);
489
+ }
490
+
491
+ .adm-config-array-edit {
492
+ width: 360px;
493
+ max-width: 100%;
494
+ min-height: 4.5rem;
495
+ font-family: 'JetBrains Mono', monospace;
496
+ font-size: 0.8rem;
497
+ padding: 6px 8px;
498
+ border: 1px solid var(--border, #E5E7EB);
499
+ border-radius: 6px;
500
+ resize: vertical;
501
+ box-sizing: border-box;
502
+ }
503
+ .adm-config-readonly { opacity: 0.85; pointer-events: none; }
504
+ .adm-config-readonly input,
505
+ .adm-config-readonly select { background: var(--bg-surface); cursor: not-allowed; }
506
+ .adm-config-readonly-banner {
507
+ margin-bottom: 16px;
508
+ padding: 12px 16px;
509
+ background: var(--info-bg);
510
+ border: 1px solid var(--info-border);
511
+ border-radius: 8px;
512
+ color: var(--info-fg);
513
+ font-size: .85rem;
514
+ }
515
+ .adm-config-result-ok {
516
+ padding: 8px 12px;
517
+ border-radius: 6px;
518
+ background: var(--success-bg);
519
+ color: var(--success-fg);
520
+ border: 1px solid var(--success-border);
521
+ }
522
+
523
+ /* Expandable help sections */
524
+ .adm-help {
525
+ margin-bottom: 12px;
526
+ border: 1px solid var(--border);
527
+ border-radius: 8px;
528
+ background: var(--bg-surface);
529
+ }
530
+ .adm-help-summary {
531
+ cursor: pointer;
532
+ padding: 10px 14px;
533
+ color: var(--accent);
534
+ font-size: .85rem;
535
+ font-weight: 600;
536
+ user-select: none;
537
+ }
538
+ .adm-help-summary:hover { color: var(--text); }
539
+ .adm-help-body {
540
+ padding: 0 14px 12px;
541
+ color: var(--text-dim);
542
+ font-size: .82rem;
543
+ line-height: 1.6;
544
+ }
545
+ .adm-help-body p { margin: 0 0 8px; }
546
+ .adm-help-body ul { margin: 4px 0 8px; padding-left: 20px; }
547
+ .adm-help-body li { margin-bottom: 4px; }
548
+ .adm-help-body code {
549
+ background: var(--code-bg);
550
+ padding: 1px 5px;
551
+ border-radius: 3px;
552
+ font-size: .78rem;
553
+ color: var(--accent);
554
+ }
555
+ .adm-help-body strong { color: var(--text); }
556
+
557
+ /* Card grid for card-based layouts */
558
+ .adm-card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
559
+
560
+ /* Responsive */
561
+ @media (max-width: 768px) {
562
+ .adm-sidebar { display: none; }
563
+ .adm-main { padding: 12px; }
564
+ }
565
+
566
+ /* ── System Prompts ── */
567
+ .adm-prompt-editor { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
568
+ .adm-prompt-textarea {
569
+ width: 100%; min-height: 300px; max-height: 600px;
570
+ font-family: var(--font-mono); font-size: 13px; line-height: 1.5;
571
+ background: var(--bg-input); border: 1.5px solid var(--border);
572
+ color: var(--text); padding: 12px; border-radius: 8px;
573
+ resize: vertical; box-sizing: border-box; tab-size: 2;
574
+ }
575
+ .adm-prompt-textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(99,102,241,0.15); }
576
+ .adm-prompt-vars { font-size: .8rem; color: var(--text-dim); padding: 8px 12px; background: var(--bg-surface); border-radius: 6px; margin: 4px 0; }
577
+ .adm-prompt-vars code { color: var(--accent); }
578
+ .adm-prompt-version-row {
579
+ display: flex; align-items: center; gap: 8px; padding: 6px 0;
580
+ border-bottom: 1px solid var(--border-subtle); font-size: .85rem;
581
+ }
582
+ .adm-prompt-version-row:last-child { border-bottom: none; }
583
+ .adm-prompt-used-tag {
584
+ display: inline-block; font-size: .7rem; padding: 2px 6px;
585
+ background: var(--bg-surface); border: 1px solid var(--border);
586
+ border-radius: 4px; color: var(--text-dim); margin: 1px;
587
+ }
588
+ .adm-prompt-group-header {
589
+ cursor: pointer; padding: 8px 0; font-weight: 600; color: var(--text);
590
+ display: flex; align-items: center; gap: 6px;
591
+ border-bottom: 1px solid var(--border-subtle);
592
+ }
593
+
594
+ /* ── Form Controls ── */
595
+ .adm-input {
596
+ background: var(--bg-input);
597
+ border: 1.5px solid var(--border);
598
+ color: var(--text);
599
+ padding: 8px 12px;
600
+ border-radius: 6px;
601
+ font-size: .85rem;
602
+ font-family: inherit;
603
+ }
604
+ .adm-input:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px rgba(99,102,241,0.15); }
605
+ .adm-input-full { width: 100%; }
606
+
607
+ .adm-textarea {
608
+ background: var(--bg-input);
609
+ border: 1.5px solid var(--border);
610
+ color: var(--text);
611
+ padding: 10px;
612
+ border-radius: 6px;
613
+ font-family: var(--font-mono);
614
+ font-size: .8rem;
615
+ resize: vertical;
616
+ line-height: 1.5;
617
+ tab-size: 2;
618
+ }
619
+
620
+ /* ── Flex Utilities ── */
621
+ .adm-flex { display: flex; gap: 8px; }
622
+ .adm-flex-col { display: flex; flex-direction: column; gap: 8px; }
623
+ .adm-flex-between { display: flex; justify-content: space-between; align-items: center; }
624
+ .adm-flex-center { display: flex; align-items: center; gap: 8px; }
625
+ .adm-flex-wrap { display: flex; flex-wrap: wrap; gap: 8px; }
626
+
627
+ /* ── Text Utilities ── */
628
+ .adm-text-xs { font-size: .7rem; }
629
+ .adm-text-sm { font-size: .8rem; }
630
+ .adm-text-base { font-size: .85rem; }
631
+ .adm-text-dim { color: var(--text-dim); }
632
+ .adm-text-bright { color: var(--text); }
633
+ .adm-text-accent { color: var(--accent); }
634
+ .adm-text-error { color: var(--danger-fg); }
635
+ .adm-text-success { color: var(--success-fg); }
636
+ .adm-text-mono { font-family: var(--font-mono); font-size: .8rem; }
637
+
638
+ /* ── Spacing Utilities ── */
639
+ .adm-gap-xs { gap: 4px; }
640
+ .adm-gap-sm { gap: 8px; }
641
+ .adm-gap-md { gap: 12px; }
642
+ .adm-gap-lg { gap: 16px; }
643
+
644
+ .adm-mb-xs { margin-bottom: 4px; }
645
+ .adm-mb-sm { margin-bottom: 8px; }
646
+ .adm-mb-md { margin-bottom: 12px; }
647
+ .adm-mb-lg { margin-bottom: 16px; }
648
+
649
+ .adm-mt-sm { margin-top: 8px; }
650
+ .adm-mt-md { margin-top: 12px; }
651
+ .adm-mt-lg { margin-top: 16px; }
652
+
653
+ /* ── Modal ── canonical overlay/box live in theme.css (.modal-overlay / .modal).
654
+ msm-tab uses .modal-overlay directly; no admin-specific override needed. */
655
+
656
+ /* ── Memory Tab ──
657
+ (the bespoke .adm-mem-stat summary cards were removed — memory/agent-tasks/
658
+ sharing-groups now use the canonical <StatsGrid>/.adm-stat pattern.) */
659
+ .adm-mem-filters {
660
+ display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; align-items: center;
661
+ }
662
+ .adm-mem-filters .adm-input {
663
+ padding: 6px 10px; border: 1px solid var(--glass-border); border-radius: 6px;
664
+ font-size: .85rem; background: var(--glass-bg); color: inherit; min-width: 160px;
665
+ }
666
+ .adm-mem-value-label { font-size: .8rem; color: var(--text-dim); margin-bottom: 4px; }
667
+ .adm-mem-value {
668
+ background: var(--bg-surface); border: 1px solid var(--glass-border); border-radius: 6px;
669
+ padding: 10px; font-size: .8rem; max-height: 300px; overflow: auto;
670
+ white-space: pre-wrap; word-break: break-all; font-family: 'JetBrains Mono', monospace;
671
+ }
672
+ .adm-mem-pagination {
673
+ display: flex; align-items: center; justify-content: center; gap: 12px;
674
+ padding: 12px 0; border-top: 1px solid var(--glass-border); margin-top: 8px;
675
+ }
676
+ .adm-mem-page-info { font-size: .85rem; color: var(--text-dim); }
677
+ /* Semantic button modifiers combine with .adm-btn-sm / .adm-btn-action
678
+ (which supply padding/radius). Theme-aware via tokens, never hardcoded hex.
679
+ These replace the ad-hoc inline style="color:#ef4444…" overrides that were
680
+ scattered across the tabs. */
681
+ .adm-btn-danger {
682
+ color: var(--danger-fg); border-color: var(--danger-border);
683
+ }
684
+ .adm-btn-danger:hover { background: var(--danger-bg); }
685
+ .adm-btn-success {
686
+ color: var(--success-fg); border-color: var(--success-border);
687
+ }
688
+ .adm-btn-success:hover { background: var(--success-bg); }
689
+ /* Solid danger combine with .adm-btn (which supplies layout); the bg override
690
+ below wins on source order. For destructive primary actions (e.g. delete). */
691
+ .adm-btn-danger-solid {
692
+ background: var(--danger); color: #fff; border-color: transparent;
693
+ }
694
+ .adm-btn-danger-solid:hover { background: var(--danger); filter: brightness(0.92); }
695
+ /* Info / ghost button modifiers (combine with .adm-btn-sm like -danger/-success). */
696
+ .adm-btn-info { color: var(--info-fg); border-color: var(--info-border); }
697
+ .adm-btn-info:hover { background: var(--info-bg); }
698
+ .adm-btn-ghost { color: var(--text-dim); border-color: var(--border); }
699
+ .adm-btn-ghost:hover { background: var(--bg-surface); }
700
+
701
+ /* Previously-undefined classes used by cortex/database/skills/feedback tabs
702
+ (they rendered unstyled). Defined to the admin design language — no markup
703
+ change needed. */
704
+ .adm-section-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
705
+ .adm-meta-row { display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; color: var(--text-dim); font-size: 0.85rem; margin: 0.5rem 0; }
706
+ .adm-actions-row { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
707
+ .adm-row { padding: 0.35rem 0; border-bottom: 1px solid var(--border-subtle); }
708
+ .adm-row:last-child { border-bottom: none; }
709
+ .adm-table-wrap { overflow-x: auto; }
710
+ .adm-link { background: none; border: none; padding: 0; color: var(--accent); cursor: pointer; font: inherit; text-align: left; }
711
+ .adm-link:hover { text-decoration: underline; }
712
+ .adm-desc, .adm-help-text { color: var(--text-dim); font-size: 0.85rem; }
713
+ .adm-muted { color: var(--text-dim); }
714
+
715
+ /* Subtabs row */
716
+ .adm-subtabs { display: flex; gap: 8px; margin: 16px 0; flex-wrap: wrap; }
717
+
718
+ /* Subdomains tab — create-form row: subdomain | kind | target (grows) | button */
719
+ .adm-subdomain-form {
720
+ display: grid;
721
+ grid-template-columns: minmax(120px, 200px) minmax(100px, 140px) 1fr auto;
722
+ gap: 8px;
723
+ align-items: center;
724
+ }
725
+ .adm-subdomain-form .adm-text-error { grid-column: 1 / -1; }
726
+ .adm-subdomain-modal-actions { justify-content: flex-end; }
727
+
728
+ /* Applications (moderation) tab */
729
+ .adm-apps-filters { gap: 12px; align-items: center; }
730
+ .adm-apps-toggle { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
731
+ .adm-apps-row-hidden { opacity: 0.6; }
732
+ .adm-apps-modal-actions { justify-content: flex-end; }
733
+ .adm-apps-rowactions { gap: 6px; flex-wrap: wrap; }
734
+
735
+ /* Active subtab button */
736
+ .adm-btn-active,
737
+ .adm-btn-active:hover { background: var(--accent); color: #fff; }
738
+
739
+ /* Packages tab seed card */
740
+ .adm-pkg-seed-card { margin-bottom: 16px; text-align: center; padding: 24px; }
741
+ .adm-pkg-seed-text { margin-bottom: 12px; }
742
+ .adm-pkg-seed-msg { margin-top: 8px; font-size: .85rem; color: var(--mint); }
743
+
744
+ /* Template moderation */
745
+ .adm-mod-section { margin-bottom: 16px; }
746
+ .adm-mod-review { margin-top: 8px; }
747
+ .adm-mod-review-title { font-size: 1rem; font-weight: 700; margin-bottom: 8px; color: var(--text-bright, #1A1A2E); }
748
+ .adm-mod-desc { font-size: .85rem; color: var(--text-dim, #6B7280); margin-bottom: 8px; }
749
+ .adm-mod-meta-grid { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 8px; font-size: .84rem; }
750
+ .adm-mod-meta-item { color: var(--text-dim, #6B7280); }
751
+ .adm-mod-meta-item strong { color: var(--text-bright, #1A1A2E); }
752
+ .adm-mod-tags { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 8px; }
753
+ .adm-mod-pre { font-size: .78rem; white-space: pre-wrap; word-break: break-all; max-height: 300px; overflow: auto; font-family: var(--font-mono); background: var(--bg-deep, #F8FAFC); border: 1px solid var(--glass-border, #E5E7EB); border-radius: 6px; padding: 10px; }
754
+ .adm-mod-components { margin-bottom: 12px; }
755
+ .adm-mod-components h5 { font-size: .84rem; margin-bottom: 6px; }
756
+ .adm-mod-actions { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 12px; }
757
+ .adm-mod-action-group { flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 6px; }
758
+ .adm-mod-action-label { font-size: .78rem; font-weight: 600; color: var(--text-dim, #6B7280); }
759
+ .adm-mod-input { padding: 6px 10px; border: 1px solid var(--glass-border, #E5E7EB); border-radius: 6px; font-size: .85rem; background: var(--glass-bg, #fff); color: inherit; }
760
+ .adm-mod-suspend-panel { margin-top: 8px; }
761
+ .adm-mod-suspend-row { display: flex; gap: 8px; align-items: center; }
762
+ .adm-mod-suspend-row .adm-mod-input { flex: 1; }
763
+
764
+ /* Badge aliases for moderation statuses */
765
+ .adm-badge-approved { background: var(--success-bg); color: var(--success-fg); }
766
+ .adm-badge-rejected { background: var(--danger-bg); color: var(--danger-fg); }
767
+ .adm-badge-suspended { background: var(--warn-bg); color: var(--warn-fg); }
768
+ .adm-badge-published { background: var(--success-bg); color: var(--success-fg); }
769
+ .adm-badge-active { background: var(--success-bg); color: var(--success-fg); }
770
+ .adm-badge-installed { background: var(--success-bg); color: var(--success-fg); }
771
+
772
+ /* ── Board Members ── */
773
+ .adm-board-detail { border-top: 1px solid var(--card-border, var(--glass-border)); padding-top: 8px; }
774
+ .adm-board-post { margin-bottom: 6px; padding: 6px; background: var(--bg-card, var(--glass-bg)); border-radius: 6px; }
775
+ .adm-board-members { border-top: 1px solid var(--card-border, var(--glass-border)); padding-top: 8px; }
776
+ .adm-member-tag {
777
+ display: inline-flex; align-items: center; gap: 4px;
778
+ background: var(--glass-bg); border: 1px solid var(--glass-border);
779
+ border-radius: 4px; padding: 2px 8px; font-size: .8rem;
780
+ }
781
+ .adm-member-tag code { font-size: .78rem; }
782
+ .adm-member-remove {
783
+ background: none; border: none; color: var(--text-dim); cursor: pointer;
784
+ font-size: 1rem; line-height: 1; padding: 0 2px;
785
+ }
786
+ .adm-member-remove:hover { color: var(--danger, #E8564A); }
787
+ .adm-member-add { display: flex; gap: 8px; align-items: center; }
788
+ .adm-member-add .adm-input { flex: 1; font-size: .85rem; }
789
+ .adm-font-mono { font-family: 'JetBrains Mono', monospace; }
790
+
791
+ /* ── Stats Time Range Selector ── */
792
+ .adm-time-range {
793
+ display: flex;
794
+ flex-wrap: wrap;
795
+ align-items: center;
796
+ gap: 8px;
797
+ margin-bottom: 20px;
798
+ padding: 12px 16px;
799
+ background: var(--glass-bg, #FFFFFF);
800
+ border: 1px solid var(--glass-border, #E5E7EB);
801
+ border-radius: 8px;
802
+ }
803
+ .adm-time-range-label {
804
+ font-size: 0.8rem;
805
+ color: var(--text-dim);
806
+ margin-right: 4px;
807
+ }
808
+ .adm-time-btn {
809
+ padding: 4px 12px;
810
+ font-size: 0.75rem;
811
+ border: 1px solid var(--glass-border, #E5E7EB);
812
+ border-radius: 6px;
813
+ background: transparent;
814
+ color: var(--text);
815
+ cursor: pointer;
816
+ font-family: inherit;
817
+ transition: all 0.15s;
818
+ }
819
+ .adm-time-btn:hover { border-color: var(--accent); color: var(--accent); }
820
+ .adm-time-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
821
+ .adm-time-custom {
822
+ display: flex;
823
+ align-items: center;
824
+ gap: 6px;
825
+ margin-left: auto;
826
+ }
827
+ .adm-time-custom input[type="date"] {
828
+ padding: 3px 8px;
829
+ font-size: 0.75rem;
830
+ border: 1px solid var(--glass-border, #E5E7EB);
831
+ border-radius: 4px;
832
+ background: var(--bg-input);
833
+ color: var(--text);
834
+ font-family: inherit;
835
+ }
836
+
837
+ /* ── Stats Breakdown Table ── */
838
+ .adm-breakdown-table {
839
+ width: 100%;
840
+ border-collapse: collapse;
841
+ font-size: 0.78rem;
842
+ margin-top: 8px;
843
+ }
844
+ .adm-breakdown-table th {
845
+ text-align: left;
846
+ padding: 6px 10px;
847
+ color: var(--text-dim);
848
+ border-bottom: 1px solid var(--border);
849
+ font-weight: 500;
850
+ }
851
+ .adm-breakdown-table td {
852
+ padding: 5px 10px;
853
+ border-bottom: 1px solid var(--border-subtle);
854
+ }
855
+ .adm-breakdown-table td.num {
856
+ text-align: right;
857
+ font-variant-numeric: tabular-nums;
858
+ }
859
+
860
+ /* ── Stats Section Header Colors ── */
861
+ .adm-section-purple { color: var(--purple); }
862
+ .adm-section-cyan { color: var(--teal); }
863
+ .adm-section-violet { color: var(--purple); }
864
+ .adm-section-amber { color: var(--warn); }
865
+ .adm-section-red { color: var(--danger); }
866
+
867
+ /* ── Breakdown Table ── */
868
+ .adm-breakdown-table th.num { text-align: right; }
869
+
870
+ /* ── Stats Inline Breakdown ── */
871
+ .adm-date-separator { color: var(--text-dim); }
872
+ .adm-mailbox-inline { padding: 10px 16px; }
873
+ .adm-blocked-reasons { margin-bottom: 6px; color: var(--text-dim); }
874
+ .adm-channels-summary { color: var(--text-dim); }
875
+
876
+ .adm-badge-live {
877
+ display: inline-block;
878
+ font-size: 0.6rem;
879
+ padding: 1px 6px;
880
+ border-radius: 4px;
881
+ background: var(--accent);
882
+ color: #fff;
883
+ vertical-align: middle;
884
+ margin-left: 6px;
885
+ }
886
+
887
+ /* Security tab — incident list */
888
+ .adm-sec-title { font-size: 1.05rem; font-weight: 700; margin: 0 0 0.3rem; }
889
+ .adm-sec-desc { color: var(--muted); font-size: 0.85rem; margin: 0 0 0.75rem; }
890
+ .adm-sec-empty { color: var(--muted); padding: 0.75rem 0; }
891
+ .adm-sec-list { display: flex; flex-direction: column; gap: 0.5rem; }
892
+ .adm-sec-row { display: flex; gap: 0.75rem; justify-content: space-between; align-items: flex-start; border: 1px solid var(--border); border-radius: 8px; padding: 0.6rem 0.75rem; background: var(--card); }
893
+ .adm-sec-row.open { border-color: var(--danger); border-left-width: 3px; }
894
+ .adm-sec-main { min-width: 0; flex: 1; }
895
+ .adm-sec-line1 { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
896
+ .adm-sec-type { font-weight: 600; color: var(--text); }
897
+ .adm-sec-code { font-size: 0.78rem; background: var(--bg-dim); padding: 0.05rem 0.35rem; border-radius: 4px; }
898
+ .adm-sec-when { font-size: 0.74rem; color: var(--muted); margin-left: auto; }
899
+ .adm-sec-line2 { font-size: 0.82rem; color: var(--text); margin: 0.25rem 0; word-break: break-word; }
900
+ .adm-sec-line3 { font-size: 0.76rem; color: var(--muted); }
901
+ .adm-sec-actions { display: flex; gap: 0.35rem; flex-shrink: 0; flex-wrap: wrap; }
902
+
903
+ /* ── Skills admin tab (adm-skills) — node registry Phase 2b ── */
904
+ .adm-skills-row { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); padding: 0.55rem 0.75rem; margin-bottom: 0.5rem; }
905
+ .adm-skills-row-main { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
906
+ .adm-skills-version { font-size: 0.74rem; color: var(--muted); }
907
+ .adm-skills-actions { margin-left: auto; display: flex; gap: 0.3rem; }
908
+ .adm-skills-desc { font-size: 0.82rem; color: var(--muted); margin-top: 0.25rem; }
909
+ .adm-skills-body { background: var(--bg-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.6rem; font-size: 0.78rem; max-height: 24rem; overflow: auto; white-space: pre-wrap; margin-top: 0.5rem; }
910
+ .adm-skills-editor { margin: 0.5rem 0 0.75rem; }
911
+ .adm-skills-editor-actions { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }
912
+ .adm-skills-editor-md { width: 100%; min-height: 24rem; font-family: var(--mono); font-size: 0.82rem; resize: vertical; }
913
+ .adm-skills-detail { margin-top: 0.5rem; }
914
+ .adm-skills-frontmatter { background: var(--bg-dim); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.5rem 0.6rem; font-size: 0.74rem; color: var(--muted); white-space: pre-wrap; margin-bottom: 0.5rem; }
915
+ .adm-skills-body-md { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.75rem 1rem; font-size: 0.86rem; max-height: 32rem; overflow: auto; }
916
+
917
+ /* ── Feedback tab (Node Feedback Channel operator inbox) ── */
918
+ .adm-fb-filters { display: flex; gap: 0.5rem; margin: 0.75rem 0; flex-wrap: wrap; }
919
+ .adm-fb-row { cursor: pointer; }
920
+ .adm-fb-row:hover td { background: var(--bg-dim); }
921
+ .adm-fb-thread-head { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.75rem; flex-wrap: wrap; }
922
+ .adm-fb-status { margin-left: auto; }
923
+ .adm-fb-msg { border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); padding: 0.6rem 0.8rem; margin-top: 0.5rem; white-space: pre-wrap; font-size: 0.88rem; }
924
+ .adm-fb-msg-operator { background: var(--bg-dim); margin-left: 2rem; }
925
+ .adm-fb-msg-sender { margin-right: 2rem; }
926
+ .adm-fb-context { font-size: 0.76rem; color: var(--muted); margin-top: 0.4rem; }
927
+ .adm-fb-replybox { margin-top: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }
928
+ .adm-fb-replybox textarea { width: 100%; resize: vertical; }
929
+
930
+ /* ── Organism ownership tab (operator break-glass) ── */
931
+ /* The lookup and add-owner rows: one input that takes the width, one button beside it. Without
932
+ this the button dropped under a full-width input and the pair stopped reading as one action. */
933
+ .adm-oo-row { display: flex; gap: 0.5rem; align-items: center; margin: 0.75rem 0; flex-wrap: wrap; }
934
+ .adm-oo-row .input-field { flex: 1 1 20rem; }
935
+ .adm-oo-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 0.4rem 0.9rem; margin: 0.75rem 0; }