anentrypoint-design 0.0.478 → 0.0.481

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 (38) hide show
  1. package/chat.css +4 -4
  2. package/colors_and_type.css +33 -3
  3. package/community.css +22 -8
  4. package/dist/247420.css +195 -59
  5. package/dist/247420.js +24 -24
  6. package/package.json +1 -1
  7. package/src/community-app.js +4 -2
  8. package/src/components/community/navigation.js +2 -2
  9. package/src/components/community/presence.js +10 -4
  10. package/src/components/community/views.js +8 -2
  11. package/src/components/content/avatar.js +30 -0
  12. package/src/components/content.js +2 -2
  13. package/src/components/overlay-primitives/emoji-picker.js +15 -3
  14. package/src/components/shell/workspace-shell.js +1 -1
  15. package/src/components/theme-toggle.js +8 -3
  16. package/src/css/app-shell/base.css +18 -0
  17. package/src/css/app-shell/catalog-theme.css +14 -2
  18. package/src/css/app-shell/chat-polish.css +12 -0
  19. package/src/css/app-shell/collab.css +5 -0
  20. package/src/css/app-shell/data-density.css +4 -0
  21. package/src/css/app-shell/files.css +1 -1
  22. package/src/css/app-shell/hero-content.css +1 -1
  23. package/src/css/app-shell/loading-alerts.css +14 -12
  24. package/src/css/app-shell/otp-input.css +2 -2
  25. package/src/css/app-shell/plugins-config.css +3 -0
  26. package/src/css/app-shell/primitives.css +13 -4
  27. package/src/css/app-shell/responsive.css +13 -0
  28. package/src/css/app-shell/responsive2-workspace.css +4 -1
  29. package/src/css/app-shell/states-interactions.css +20 -4
  30. package/src/kits/os/app-panes.css +3 -2
  31. package/src/kits/os/icons.js +16 -0
  32. package/src/kits/os/shell-geometry.js +2 -2
  33. package/src/kits/os/shell.js +24 -3
  34. package/src/kits/os/theme.css +251 -78
  35. package/src/kits/os/wm.css +19 -6
  36. package/src/kits/spoint/host-join-lobby.css +3 -3
  37. package/src/web-components/freddie-chat.js +2 -2
  38. package/types/components.d.ts +4 -0
@@ -37,9 +37,58 @@
37
37
  --os-bar-h-mobile: 52px;
38
38
  --os-rail-w: 64px;
39
39
  --os-tap: 44px;
40
+ /* Unified menubar control height: every clickable control in the top bar
41
+ (home/apps buttons, workspace tabs, tray icon buttons) sits on this one
42
+ height so the bar reads as a single control language instead of a mix
43
+ of pill buttons, chips, and icon buttons each sized on their own. */
44
+ --os-control-h: 28px;
40
45
  --os-font: var(--ff-ui);
41
46
  --os-display: var(--ff-display);
42
47
  --os-mono: var(--ff-mono);
48
+
49
+ /* ---- Unified spacing scale (--space-1..6) ----
50
+ colors_and_type.css already defines --space-1 (4px) through --space-6
51
+ (48px), plus finer hair/half/fractional rungs (--space-hair/half/0/1-5/
52
+ 1-75/2-5/2-75/3-5), all loaded before this sheet for every .ds-247420
53
+ consumer. That IS the unified spacing scale this contract asks for — no
54
+ redeclaration here (a self-referencing `--space-1: var(--space-1)` would
55
+ be circular and resolve to invalid at computed-value time). New call
56
+ sites and the migrations below consolidate onto --space-1..6 directly. */
57
+
58
+ /* ---- Unified type scale (title / body / meta) ----
59
+ Maps onto the canonical --fs-* rail (colors_and_type.css) rather than
60
+ inventing new pixel values: title = display-weight heading size already
61
+ used by .os-drawer-title/.chat-empty-title (--fs-xl); body = the base
62
+ readable size already used by .chat-bubble/.app-pane (--fs-xs); meta =
63
+ the small secondary/timestamp size already used by .chat-meta/.os-clock
64
+ (--fs-nano). */
65
+ --font-size-title: var(--fs-xl);
66
+ --font-size-body: var(--fs-xs);
67
+ --font-size-meta: var(--fs-nano);
68
+
69
+ /* ---- Unified corner-radius scale (sm / md / lg / pill) ----
70
+ Aliases of the canonical --r-* rail (colors_and_type.css: --r-0 4px,
71
+ --r-1 8px, --r-2 10px, --r-3 14px, --r-pill 999px) under the names this
72
+ token contract specifies, so windows/buttons/badges can standardize on
73
+ one vocabulary instead of picking --r-0 vs --r-1 vs --r-2 ad hoc. */
74
+ --radius-sm: var(--r-1);
75
+ --radius-md: var(--r-2);
76
+ --radius-lg: var(--r-3);
77
+ --radius-pill: var(--r-pill, 999px);
78
+
79
+ /* ---- Unified color / accent system ----
80
+ --accent-primary is the brand lead (#247420 in the thebird preset via
81
+ --os-accent, which already resolves through --accent-ink); kept as its
82
+ own token (rather than a bare alias) so non-.ds-247420 consumers of this
83
+ kit get the literal brand green called for by this contract even before
84
+ any brand-scoped override applies. --color-success/warning/danger alias
85
+ the existing canonical severity primitives (--green-2/--sun/--warn) so
86
+ severity language is consistent with what --success/--warn already mean
87
+ everywhere else in colors_and_type.css — not a second competing set. */
88
+ --accent-primary: #247420;
89
+ --color-success: var(--success, var(--green-2, #3A9A34));
90
+ --color-warning: var(--sun, #F5C344);
91
+ --color-danger: var(--warn, #C41C0C);
43
92
  }
44
93
 
45
94
  html, body {
@@ -50,6 +99,20 @@ html, body {
50
99
  text-rendering: optimizeLegibility;
51
100
  }
52
101
 
102
+ /* ---- Global focus-visible ring ----
103
+ Baseline accent-colored outline for every keyboard-focusable element
104
+ (inputs/textareas/buttons/links/contenteditable, including the terminal's
105
+ and chat composer's text entry) so focus is never invisible. Component-
106
+ level :focus-visible rules elsewhere in this sheet (chat composer textarea,
107
+ composer-btn, chat-empty-suggestion, fsb-row, ...) already set a matching
108
+ var(--os-accent) ring with layout-specific offset/inset and win by source
109
+ order + specificity; this is the catch-all every other focusable surface
110
+ falls back to. */
111
+ .ds-247420 :focus-visible {
112
+ outline: 2px solid var(--os-accent);
113
+ outline-offset: 2px;
114
+ }
115
+
53
116
  .os-menubar, .os-taskbar {
54
117
  background: color-mix(in oklab, var(--os-bg-2) 88%, transparent);
55
118
  backdrop-filter: blur(10px);
@@ -89,25 +152,35 @@ html, body {
89
152
  gap: var(--space-2);
90
153
  text-transform: lowercase;
91
154
  }
155
+ /* Wordmark lockup: the mark echoes favicon.svg (rounded-square tile, accent
156
+ fill, monogram) instead of a bare accent dot, so the brand reads as an
157
+ actual logo mark next to the "thebird" text rather than plain type with a
158
+ decorative dot. Inlined as a data-URI (same technique renderFaviconTags
159
+ already uses for the <link rel="icon"> glyph case) since theme.css ships
160
+ standalone via unpkg with no guaranteed relative path to favicon.svg. */
92
161
  .os-brand::before {
93
162
  content: '';
94
163
  display: inline-block;
95
- width: 8px; height: 8px;
96
- border-radius: 50%;
97
- background: var(--os-accent);
164
+ width: 16px; height: 16px;
165
+ border-radius: var(--r-1, 4px);
166
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%23247420'/%3E%3Ctext x='16' y='22' font-family='ui-monospace,monospace' font-size='14' font-weight='700' fill='%23EFE9DD' text-anchor='middle'%3E24%3C/text%3E%3C/svg%3E");
167
+ background-size: contain;
168
+ background-repeat: no-repeat;
169
+ flex: 0 0 auto;
98
170
  }
99
171
 
100
172
  .os-btn {
101
173
  background: transparent;
102
174
  color: var(--os-fg-2);
103
- border: none;
104
- padding: 7px 14px;
175
+ border: 1px solid transparent;
176
+ height: var(--os-control-h);
177
+ padding: 0 14px;
105
178
  cursor: pointer;
106
179
  font: inherit;
107
180
  font-family: var(--os-font);
108
181
  font-size: var(--fs-tiny);
109
- border-radius: var(--r-pill, 999px);
110
- transition: background 80ms ease, color 80ms ease;
182
+ border-radius: var(--radius-pill, var(--r-pill, 999px));
183
+ transition: background 80ms ease, color 80ms ease, border-color 80ms ease;
111
184
  display: inline-flex;
112
185
  align-items: center;
113
186
  gap: var(--space-1-75);
@@ -124,9 +197,16 @@ html, body {
124
197
  position: absolute;
125
198
  background: var(--os-bg-1);
126
199
  border: none;
127
- border-radius: var(--r-3, 18px);
200
+ border-radius: var(--radius-lg, var(--r-3, 18px));
128
201
  padding: var(--space-2, 8px);
129
202
  min-width: 220px;
203
+ /* Uncapped, the menu grows to its widest label and — at the common
204
+ * tablet-range window widths (~810-1150px) where content columns are
205
+ * already narrow — reads as covering most of the open content instead
206
+ * of a dropdown. Cap to a comfortable reading width but never past
207
+ * the viewport (same "must not extend past the viewport" contract the
208
+ * height clamp below already applies). */
209
+ max-width: min(320px, calc(100vw - var(--space-4, 16px)));
130
210
  top: calc(var(--os-bar-h) + var(--space-1, 4px));
131
211
  left: var(--space-2, 8px);
132
212
  z-index: var(--z-dropdown);
@@ -139,12 +219,40 @@ html, body {
139
219
  max-height: calc(100dvh - var(--os-bar-h) - env(safe-area-inset-top, 0px) - 16px);
140
220
  overflow-y: auto;
141
221
  overscroll-behavior: contain;
222
+ /* Scroll-shadow affordance: dual-background trick -- the fade gradients
223
+ * are pinned to the scrollport (background-attachment: local) so they
224
+ * only appear once there is actually more content to reveal in that
225
+ * direction, cueing that the menu is scrollable rather than just
226
+ * clipped at the viewport edge. */
227
+ background-image:
228
+ linear-gradient(var(--os-bg-1), var(--os-bg-1)),
229
+ linear-gradient(var(--os-bg-1), var(--os-bg-1)),
230
+ linear-gradient(to bottom, color-mix(in oklab, var(--os-bg-1) 100%, transparent), transparent),
231
+ linear-gradient(to top, color-mix(in oklab, var(--os-bg-1) 100%, transparent), transparent);
232
+ background-position: top, bottom, top, bottom;
233
+ background-repeat: no-repeat;
234
+ background-size: 100% var(--space-2, 8px), 100% var(--space-2, 8px), 100% var(--space-4, 16px), 100% var(--space-4, 16px);
235
+ background-attachment: local, local, scroll, scroll;
142
236
  }
143
237
  .os-menu.open { display: flex; }
238
+ /* Dimming scrim behind the open apps menu — same var(--scrim) fixed-inset
239
+ * pattern as .tb-sess-overlay, but as a pseudo-element (not a sibling DOM
240
+ * node) since buildAppsMenu() in shell-chrome.js emits only the menu itself.
241
+ * pointer-events:none so existing click-outside-to-close handling (thebird
242
+ * JS) keeps working unmodified; the scrim sits one layer below the menu's
243
+ * own z-index but still above .wm-root's windows. */
244
+ .os-menu.open::before {
245
+ content: '';
246
+ position: fixed;
247
+ inset: 0;
248
+ z-index: var(--z-below);
249
+ background: var(--scrim);
250
+ pointer-events: none;
251
+ }
144
252
  .os-menu .os-btn {
145
253
  width: 100%;
146
254
  text-align: left;
147
- border-radius: var(--os-radius-sm);
255
+ border-radius: var(--radius-sm, var(--os-radius-sm));
148
256
  padding: var(--space-2) var(--space-2-5);
149
257
  color: var(--os-fg);
150
258
  justify-content: flex-start;
@@ -166,16 +274,19 @@ html, body {
166
274
  .os-clock {
167
275
  color: var(--os-fg-2);
168
276
  font-variant-numeric: tabular-nums;
169
- font-family: var(--os-mono);
277
+ font-family: var(--os-font);
170
278
  padding: 0 var(--space-2-5);
171
279
  font-size: var(--fs-micro);
172
280
  }
173
281
 
174
282
  .os-task {
283
+ display: inline-flex;
284
+ align-items: center;
285
+ gap: var(--space-1-5, 6px);
175
286
  border: none;
176
287
  background: var(--os-bg-1);
177
288
  color: var(--os-fg-2);
178
- border-radius: var(--r-pill, 999px);
289
+ border-radius: var(--radius-pill, var(--r-pill, 999px));
179
290
  padding: var(--space-1-75) 14px;
180
291
  font-size: var(--fs-micro);
181
292
  font-family: var(--os-font);
@@ -186,20 +297,23 @@ html, body {
186
297
  white-space: nowrap;
187
298
  overflow: hidden;
188
299
  text-overflow: ellipsis;
189
- /* No text-transform here: .os-task carries the app/window's own dynamic
190
- * title (shell.js refreshTaskbar -> t.textContent = w.title), and a
191
- * user- or app-supplied string (filename, acronym, URL) must render
192
- * as-authored rather than get silently lowercased by brand-voice CSS. */
300
+ /* No text-transform here: .os-task-label carries the app/window's own
301
+ * dynamic title (shell.js refreshTaskbar), and a user- or app-supplied
302
+ * string (filename, acronym, URL) must render as-authored rather than
303
+ * get silently lowercased by brand-voice CSS. */
193
304
  }
194
305
  .os-task { min-height: 28px; }
195
306
  .os-task:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
307
+ .os-task .ic { flex: none; display: inline-flex; width: 14px; height: 14px; }
308
+ .os-task .ic svg { width: 100%; height: 100%; fill: none; stroke: currentColor; }
309
+ .os-task-label { overflow: hidden; text-overflow: ellipsis; }
196
310
  /* Empty taskbar reads as an intentional strip, not a stray blurred bar. */
197
311
  .os-task-empty { font-size: var(--fs-nano); color: var(--os-fg-3); padding: 0 var(--space-2-5); font-family: var(--os-font); }
198
312
  .os-task.focused {
199
- background: var(--panel-select, var(--os-accent-soft));
313
+ background: var(--panel-select, color-mix(in oklab, var(--os-accent) 30%, var(--os-bg-1)));
200
314
  color: var(--os-fg);
201
- font-weight: 600;
202
- box-shadow: inset 4px 0 0 var(--os-accent);
315
+ font-weight: 700;
316
+ box-shadow: inset 4px 0 0 var(--os-accent), inset 0 0 0 1px color-mix(in oklab, var(--os-accent) 40%, transparent);
203
317
  }
204
318
 
205
319
  /* Window-chrome overrides of wm.css.
@@ -212,14 +326,14 @@ html, body {
212
326
  * job by force. Do not un-scope these; the scope IS the override mechanism. */
213
327
  .ds-247420 .wm-win {
214
328
  background: var(--os-bg-1);
215
- border: none;
216
- border-radius: var(--r-3);
217
- box-shadow: none;
329
+ border: 1px solid color-mix(in oklab, var(--os-fg) 14%, transparent);
330
+ border-radius: var(--radius-lg, var(--r-3));
331
+ box-shadow: var(--shadow-2);
218
332
  overflow: hidden;
219
333
  }
220
334
  .ds-247420 .wm-win.wm-focused {
221
- border: none;
222
- box-shadow: inset var(--space-1) 0 0 var(--os-accent);
335
+ border-color: color-mix(in oklab, var(--os-fg) 28%, transparent);
336
+ box-shadow: inset var(--space-1) 0 0 var(--os-accent), var(--shadow-3);
223
337
  }
224
338
 
225
339
  .ds-247420 .wm-bar {
@@ -227,6 +341,14 @@ html, body {
227
341
  border: none;
228
342
  padding: var(--space-2) var(--space-2-75);
229
343
  gap: var(--space-2-5);
344
+ transition: background 120ms ease;
345
+ }
346
+ /* Focused vs. unfocused titlebar differentiation: stacked windows otherwise
347
+ * share one flat gray bar and blur together. The focused window's bar picks
348
+ * up the accent-tinted panel shade and full-strength title text; unfocused
349
+ * bars stay on the plain background with dimmed title opacity. */
350
+ .ds-247420 .wm-win.wm-focused .wm-bar {
351
+ background: color-mix(in oklab, var(--os-accent) 10%, var(--os-bg-2));
230
352
  }
231
353
  .ds-247420 .wm-title {
232
354
  font: var(--fs-tiny) var(--os-font);
@@ -234,15 +356,21 @@ html, body {
234
356
  letter-spacing: 0.005em;
235
357
  text-align: center;
236
358
  font-weight: 600;
359
+ opacity: 0.65;
360
+ transition: opacity 120ms ease;
237
361
  /* No text-transform here: the titlebar renders the window's own dynamic
238
362
  * title (renderWindow({title}) / setTitle(t) in wm.js) — a user- or
239
363
  * app-supplied filename/acronym/URL must not be silently lowercased. */
240
364
  }
241
- .ds-247420 .wm-btns { gap: var(--space-1-75); order: -1; }
365
+ .ds-247420 .wm-win.wm-focused .wm-title {
366
+ color: var(--os-fg);
367
+ opacity: 1;
368
+ }
369
+ .ds-247420 .wm-btns { display: flex; align-items: center; gap: var(--space-1-75); order: -1; }
242
370
  .ds-247420 .wm-btn {
243
- width: 22px;
244
- height: 22px;
245
- border-radius: var(--r-1);
371
+ width: 26px;
372
+ height: 26px;
373
+ border-radius: var(--radius-sm, var(--r-1));
246
374
  border: none;
247
375
  background: var(--os-bg-3);
248
376
  color: var(--os-fg-2);
@@ -256,11 +384,20 @@ html, body {
256
384
  transition: background 100ms ease, color 100ms ease;
257
385
  }
258
386
  .ds-247420 .wm-btn:hover { background: var(--panel-hover, var(--os-bg-2)); color: var(--os-fg); }
259
- .ds-247420 .wm-btn svg { width: 12px; height: 12px; display: block; fill: none; stroke: currentColor; }
387
+ .ds-247420 .wm-btn svg { width: 13px; height: 13px; display: block; fill: none; stroke: currentColor; }
388
+ /* Hover-only color differentiation on the close button (independent of the
389
+ * armed/confirm state below) so it reads as the destructive action at a
390
+ * glance, matching the base wm.css rule. */
391
+ .ds-247420 .wm-btn[title='close']:hover,
392
+ .ds-247420 .wm-btn[aria-label='close']:hover {
393
+ background: var(--color-danger);
394
+ color: var(--paper);
395
+ }
260
396
  /* Armed (first-click) confirm state for the window close button's
261
397
  * second-click-to-confirm idiom — an unrecoverable close gets a visible cue
262
398
  * before it commits, matching the launcher dock's instance-close treatment. */
263
- .ds-247420 .wm-btn.confirm { background: var(--os-red); color: var(--paper); }
399
+ .ds-247420 .wm-btn.confirm { background: var(--color-danger); color: var(--paper); }
400
+ .ds-247420 .wm-btn.confirm:hover { background: color-mix(in oklab, var(--color-danger) 85%, black); }
264
401
 
265
402
  .ds-247420 .wm-resize {
266
403
  background: transparent;
@@ -338,7 +475,7 @@ html, body {
338
475
  box-sizing: border-box;
339
476
  background: var(--os-bg-2);
340
477
  }
341
- .os-drawer-title { color: var(--os-fg); font-family: var(--os-display); font-size: var(--fs-xl); font-weight: 700; letter-spacing: -0.01em; text-transform: lowercase; }
478
+ .os-drawer-title { color: var(--os-fg); font-family: var(--os-display); font-size: var(--font-size-title, var(--fs-xl)); font-weight: 700; letter-spacing: -0.01em; text-transform: lowercase; }
342
479
  .os-drawer-close {
343
480
  width: 44px; height: 44px;
344
481
  border: none; background: transparent;
@@ -374,7 +511,7 @@ html, body {
374
511
  cursor: pointer;
375
512
  transition: background 80ms ease;
376
513
  outline: none;
377
- border-radius: var(--r-3, 18px);
514
+ border-radius: var(--radius-lg, var(--r-3, 18px));
378
515
  text-transform: lowercase;
379
516
  }
380
517
  .os-drawer-tile:hover { background: var(--panel-hover, var(--os-bg-2)); }
@@ -387,7 +524,7 @@ html, body {
387
524
  .os-tray { display: flex; align-items: center; gap: var(--space-1-75); }
388
525
  .os-instances { display: flex; gap: var(--space-1); margin-left: var(--space-2); flex: 0 1 40vw; max-width: 40vw; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; padding: 0 var(--space-1); -webkit-mask-image: linear-gradient(to right, transparent, black 12px, black calc(100% - 12px), transparent); mask-image: linear-gradient(to right, transparent, black 12px, black calc(100% - 12px), transparent); }
389
526
  .os-instances::-webkit-scrollbar { height: 4px; }
390
- .os-instances .os-btn { flex: 0 0 auto; min-width: 36px; padding: var(--space-hair) var(--space-2); font-family: var(--os-mono); font-size: var(--fs-nano); }
527
+ .os-instances .os-btn { flex: 0 0 auto; min-width: 36px; height: var(--os-control-h); padding: 0 var(--space-2); font-family: var(--os-mono); font-size: var(--fs-nano); }
391
528
  .os-instances .os-btn.active { background: var(--panel-select, var(--os-accent-soft)); color: var(--os-fg); border-color: var(--panel-accent, var(--os-accent)); box-shadow: inset 0 0 0 1px var(--panel-accent, var(--os-accent)); }
392
529
  .os-menubar [data-role="home"] { display: none; }
393
530
  .os-root { position: fixed; inset: 0; display: flex; flex-direction: column; pointer-events: none; z-index: calc(var(--z-dock) + 2); }
@@ -416,12 +553,13 @@ html, body {
416
553
  .app-pane.mono .head { color: var(--os-accent); margin-bottom: var(--space-2); padding-bottom: var(--space-2); font-weight: 600; letter-spacing: 0.02em; border-bottom: 1px solid var(--os-bg-3); }
417
554
  /* Visible fetch-error surface for polling app panes (files/monitor): a swallowed
418
555
  * rejection must not leave the pane silently frozen with no user-facing signal. */
419
- .app-pane.mono .row-error { color: var(--danger, #c0392b); padding: var(--space-2); }
420
- .app-pane.mono[data-component="monitor-app"].is-error { color: var(--danger, #c0392b); }
556
+ .app-pane.mono .row-error { color: var(--color-danger); padding: var(--space-2); }
557
+ .app-pane.mono[data-component="monitor-app"].is-error { color: var(--color-danger); }
421
558
  /* Placeholder body shown immediately for a window spawned by an async app
422
559
  * factory, swapped for the real content on resolve — see openApp() in
423
560
  * shell.js. Prevents a slow factory from reading as a dead click. */
424
- .os-app-loading { display: flex; align-items: center; justify-content: center; color: var(--os-fg-3); font-style: italic; }
561
+ .os-app-loading { display: flex; align-items: center; justify-content: center; gap: var(--space-2, 8px); color: var(--os-fg-3); }
562
+ .os-app-loading-label { font-style: italic; }
425
563
  .app-pane.mono pre { background: var(--os-bg-2); padding: var(--space-2-5) var(--space-2-75); margin: var(--space-2) 0 0 0; max-height: 220px; overflow: auto; white-space: pre-wrap; font: var(--fs-nano) var(--os-mono); border-radius: var(--r-1, 6px); color: var(--os-fg); border: none; }
426
564
  .app-shell-pane { margin: 0; padding: var(--space-2); font: var(--fs-micro) var(--os-mono); color: var(--os-fg); background: var(--os-bg-0); height: 100%; overflow: auto; white-space: pre-wrap; box-sizing: border-box; }
427
565
  .app-canvas { width: 100%; height: 100%; background: var(--os-bg-0); display: block; cursor: default; }
@@ -446,7 +584,13 @@ html, body {
446
584
  .os-menubar { padding-left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
447
585
  .os-taskbar { padding-left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
448
586
  .os-menubar .os-instances { display: flex; }
449
- .os-menu { left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px)); }
587
+ .os-menu {
588
+ left: calc(var(--os-rail-w) + env(safe-area-inset-left, 0px) + var(--space-2, 8px));
589
+ /* The base rule's max-width doesn't know about the rail's left offset;
590
+ * re-derive it here so the menu still can't overflow the viewport's
591
+ * right edge on tablet-band windows (~810-1150px is the tightest). */
592
+ max-width: min(320px, calc(100vw - var(--os-rail-w) - env(safe-area-inset-left, 0px) - var(--space-4, 16px)));
593
+ }
450
594
  }
451
595
 
452
596
  @media (max-width: 767px) {
@@ -480,7 +624,7 @@ html, body {
480
624
  scroll-snap-align: start;
481
625
  font-size: var(--fs-tiny);
482
626
  }
483
- .os-task.focused { background: var(--panel-select, var(--os-accent-soft)); box-shadow: inset var(--space-1) 0 0 var(--os-accent); }
627
+ .os-task.focused { background: var(--panel-select, color-mix(in oklab, var(--os-accent) 30%, var(--os-bg-1))); font-weight: 700; box-shadow: inset var(--space-1) 0 0 var(--os-accent), inset 0 0 0 1px color-mix(in oklab, var(--os-accent) 40%, transparent); }
484
628
  .os-side-rail { display: none; }
485
629
  .os-menu { left: var(--space-2); right: var(--space-2); min-width: 0; top: calc(var(--os-bar-h) + env(safe-area-inset-top, 0) + var(--space-1)); }
486
630
  .ds-247420 .wm-root {
@@ -722,8 +866,8 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
722
866
 
723
867
  .ds-247420 .tb-sess-chip {
724
868
  display: inline-flex; align-items: center; gap: var(--space-1-75);
725
- height: 22px; padding: 0 var(--space-1-75) 0 var(--space-2);
726
- border-radius: var(--r-pill, 999px);
869
+ height: var(--os-control-h); padding: 0 var(--space-1-75) 0 var(--space-2);
870
+ border-radius: var(--radius-pill, var(--r-pill, 999px));
727
871
  background: color-mix(in oklab, var(--fg) 6%, transparent);
728
872
  color: var(--fg);
729
873
  font-family: var(--ff-ui); font-size: var(--fs-nano); font-weight: 500;
@@ -744,7 +888,7 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
744
888
  .ds-247420 .tb-sess-badge {
745
889
  display: inline-flex; align-items: center; justify-content: center;
746
890
  min-width: 16px; height: 14px; padding: 0 var(--space-1);
747
- border-radius: var(--r-0);
891
+ border-radius: var(--radius-sm, var(--r-0));
748
892
  background: color-mix(in oklab, var(--fg) 14%, transparent);
749
893
  font-size: var(--fs-pico); font-weight: 600; line-height: 1;
750
894
  }
@@ -757,14 +901,14 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
757
901
  opacity: 0.55; transition: opacity 120ms ease, background 120ms ease;
758
902
  }
759
903
  .ds-247420 .tb-sess-chip:hover .tb-sess-x { opacity: 1; }
760
- .ds-247420 .tb-sess-x:hover { background: color-mix(in oklab, var(--danger) 30%, transparent); color: var(--on-color); }
904
+ .ds-247420 .tb-sess-x:hover { background: color-mix(in oklab, var(--color-danger) 30%, transparent); color: var(--on-color); }
761
905
 
762
906
  .ds-247420 .tb-sess-add {
763
907
  display: inline-flex; align-items: center; gap: var(--space-1);
764
- height: 22px; padding: 0 var(--space-2-5);
908
+ height: var(--os-control-h); padding: 0 var(--space-2-5);
765
909
  border: 1px dashed color-mix(in oklab, var(--fg) 30%, transparent);
766
910
  background: transparent;
767
- border-radius: var(--r-pill, 999px);
911
+ border-radius: var(--radius-pill, var(--r-pill, 999px));
768
912
  font-family: var(--ff-ui); font-size: var(--fs-nano); font-weight: 500;
769
913
  color: var(--fg);
770
914
  cursor: pointer;
@@ -788,7 +932,7 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
788
932
  .tb-sess-modal {
789
933
  background: var(--bg);
790
934
  color: var(--fg);
791
- border-radius: var(--r-1);
935
+ border-radius: var(--radius-sm, var(--r-1));
792
936
  box-shadow: var(--shadow-overlay);
793
937
  min-width: 320px; max-width: 480px;
794
938
  border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
@@ -804,7 +948,7 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
804
948
  width: 100%; box-sizing: border-box;
805
949
  height: 32px; padding: 0 var(--space-2-5);
806
950
  border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent);
807
- border-radius: var(--r-0);
951
+ border-radius: var(--radius-sm, var(--r-0));
808
952
  background: color-mix(in oklab, var(--fg) 6%, var(--bg));
809
953
  color: inherit;
810
954
  font-family: inherit; font-size: var(--fs-tiny);
@@ -815,16 +959,16 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
815
959
  .tb-sess-modal-foot { display: flex; justify-content: flex-end; gap: var(--space-2); padding: var(--space-2-75) var(--space-3); border-top: 1px solid color-mix(in oklab, var(--fg) 8%, transparent); }
816
960
  .tb-sess-modal-btn {
817
961
  height: 28px; padding: 0 14px;
818
- border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent);
962
+ border-radius: var(--radius-sm, var(--r-0)); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent);
819
963
  background: transparent; color: inherit;
820
964
  font-family: inherit; font-size: var(--fs-micro); font-weight: 500; cursor: pointer;
821
965
  transition: background 120ms ease, border-color 120ms ease;
822
966
  }
823
967
  .tb-sess-modal-btn:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
824
- .tb-sess-modal-btn.primary { background: var(--os-accent); color: var(--on-color); border-color: var(--os-accent); }
825
- .tb-sess-modal-btn.primary:hover { background: color-mix(in oklab, var(--os-accent) 80%, var(--ink)); }
826
- .tb-sess-modal-btn.danger { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
827
- .tb-sess-modal-btn.danger:hover { background: color-mix(in oklab, var(--danger) 80%, var(--ink)); }
968
+ .tb-sess-modal-btn.primary { background: var(--accent-primary, var(--os-accent)); color: var(--on-color); border-color: var(--accent-primary, var(--os-accent)); }
969
+ .tb-sess-modal-btn.primary:hover { background: color-mix(in oklab, var(--accent-primary, var(--os-accent)) 80%, var(--ink)); }
970
+ .tb-sess-modal-btn.danger { background: var(--color-danger); color: var(--on-color); border-color: var(--color-danger); }
971
+ .tb-sess-modal-btn.danger:hover { background: color-mix(in oklab, var(--color-danger) 80%, var(--ink)); }
828
972
 
829
973
  .tb-sess-empty {
830
974
  position: fixed; inset: 0; z-index: var(--z-window);
@@ -837,7 +981,7 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
837
981
  background: var(--bg);
838
982
  color: var(--fg);
839
983
  border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent);
840
- border-radius: var(--r-2);
984
+ border-radius: var(--radius-md, var(--r-2));
841
985
  box-shadow: var(--shadow-3);
842
986
  padding: var(--space-5) 40px; text-align: center;
843
987
  font-family: var(--ff-ui);
@@ -847,8 +991,8 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
847
991
  .tb-sess-empty-sub { font-size: var(--fs-tiny); opacity: 0.7; margin-bottom: var(--space-3-5); }
848
992
  .tb-sess-empty-cta {
849
993
  height: 40px; padding: 0 var(--space-4);
850
- background: var(--os-accent); color: var(--on-color);
851
- border: 0; border-radius: var(--r-pill, 999px);
994
+ background: var(--accent-primary, var(--os-accent)); color: var(--on-color);
995
+ border: 0; border-radius: var(--radius-pill, var(--r-pill, 999px));
852
996
  font-family: inherit; font-size: var(--fs-xs); font-weight: 600;
853
997
  cursor: pointer;
854
998
  transition: transform 120ms ease, box-shadow 120ms ease;
@@ -861,25 +1005,25 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
861
1005
  .ds-247420 .tb-sessions-title { font-weight: 600; font-size: var(--fs-xs); }
862
1006
  .ds-247420 .tb-sessions-count { font-size: var(--fs-micro); opacity: 0.6; margin-left: var(--space-1); }
863
1007
  .ds-247420 .tb-sessions-spacer { flex: 1; }
864
- .ds-247420 .tb-sessions-btn { height: 28px; padding: 0 var(--space-2-75); border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent); background: transparent; color: inherit; font-size: var(--fs-micro); font-weight: 500; cursor: pointer; font-family: inherit; }
1008
+ .ds-247420 .tb-sessions-btn { height: 28px; padding: 0 var(--space-2-75); border-radius: var(--radius-sm, var(--r-0)); border: 1px solid color-mix(in oklab, var(--fg) 20%, transparent); background: transparent; color: inherit; font-size: var(--fs-micro); font-weight: 500; cursor: pointer; font-family: inherit; }
865
1009
  .ds-247420 .tb-sessions-btn:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
866
- .ds-247420 .tb-sessions-btn.primary { background: var(--os-accent); color: var(--on-color); border-color: var(--os-accent); }
867
- .ds-247420 .tb-sessions-btn.danger { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
1010
+ .ds-247420 .tb-sessions-btn.primary { background: var(--accent-primary, var(--os-accent)); color: var(--on-color); border-color: var(--accent-primary, var(--os-accent)); }
1011
+ .ds-247420 .tb-sessions-btn.danger { background: var(--color-danger); color: var(--on-color); border-color: var(--color-danger); }
868
1012
  .ds-247420 .tb-sessions-btn:disabled { opacity: 0.4; cursor: not-allowed; }
869
1013
  .ds-247420 .tb-sessions-grid { flex: 1; overflow: auto; padding: 14px; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-2-75); align-content: start; }
870
- .ds-247420 .tb-sessions-card { padding: var(--space-2-75); border-radius: var(--r-1, 10px); border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent); background: color-mix(in oklab, var(--fg) 3%, transparent); display: flex; flex-direction: column; gap: var(--space-2); transition: border-color 120ms ease, transform 120ms ease; }
1014
+ .ds-247420 .tb-sessions-card { padding: var(--space-2-75); border-radius: var(--radius-sm, var(--r-1, 10px)); border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent); background: color-mix(in oklab, var(--fg) 3%, transparent); display: flex; flex-direction: column; gap: var(--space-2); transition: border-color 120ms ease, transform 120ms ease; }
871
1015
  .ds-247420 .tb-sessions-card:hover { border-color: var(--os-accent); }
872
1016
  .ds-247420 .tb-sessions-card.active { border-color: var(--os-accent); box-shadow: 0 0 0 2px color-mix(in oklab, var(--os-accent) 30%, transparent); }
873
1017
  .ds-247420 .tb-sessions-card-head { display: flex; align-items: center; gap: var(--space-2); }
874
1018
  .ds-247420 .tb-sessions-card-check { width: 14px; height: 14px; cursor: pointer; flex: 0 0 14px; }
875
- .ds-247420 .tb-sessions-card-name { font-weight: 600; font-size: var(--fs-tiny); flex: 1; outline: none; padding: var(--space-hair) var(--space-1); border-radius: var(--r-0); }
1019
+ .ds-247420 .tb-sessions-card-name { font-weight: 600; font-size: var(--fs-tiny); flex: 1; outline: none; padding: var(--space-hair) var(--space-1); border-radius: var(--radius-sm, var(--r-0)); }
876
1020
  .ds-247420 .tb-sessions-card-name[contenteditable="true"] { background: color-mix(in oklab, var(--fg) 8%, transparent); }
877
1021
  .ds-247420 .tb-sessions-card-id { font-family: var(--os-mono, monospace); font-size: var(--fs-pico); opacity: 0.5; }
878
1022
  .ds-247420 .tb-sessions-card-stats { font-size: var(--fs-nano); opacity: 0.7; display: flex; gap: var(--space-2-75); }
879
1023
  .ds-247420 .tb-sessions-card-actions { display: flex; gap: var(--space-1-75); margin-top: var(--space-1); }
880
- .ds-247420 .tb-sessions-card-actions button { flex: 1; height: 24px; font-size: var(--fs-nano); padding: 0 var(--space-2); border-radius: var(--r-0); border: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); background: transparent; color: inherit; cursor: pointer; font-family: inherit; }
1024
+ .ds-247420 .tb-sessions-card-actions button { flex: 1; height: 24px; font-size: var(--fs-nano); padding: 0 var(--space-2); border-radius: var(--radius-sm, var(--r-0)); border: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); background: transparent; color: inherit; cursor: pointer; font-family: inherit; }
881
1025
  .ds-247420 .tb-sessions-card-actions button:hover { background: color-mix(in oklab, var(--fg) 6%, transparent); }
882
- .ds-247420 .tb-sessions-card-actions button.danger:hover { background: var(--danger); color: var(--on-color); border-color: var(--danger); }
1026
+ .ds-247420 .tb-sessions-card-actions button.danger:hover { background: var(--color-danger); color: var(--on-color); border-color: var(--color-danger); }
883
1027
  .ds-247420 .tb-sessions-empty-mid { padding: 40px; text-align: center; opacity: 0.6; font-size: var(--fs-tiny); }
884
1028
 
885
1029
  /* ---- prefers-contrast: more — strengthen borders + focus so the translucent
@@ -924,9 +1068,9 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
924
1068
  .ds-247420 .freddie-chat-wrap { position: absolute; inset: 0; display: flex; flex-direction: column; min-height: 0; }
925
1069
  .ds-247420 .freddie-chat-wrap > freddie-chat { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
926
1070
  .ds-247420 .cc-strip { flex: 0 0 auto; font-size: var(--fs-micro); border-bottom: 1px solid color-mix(in oklab, var(--fg) 16%, transparent); }
927
- .ds-247420 .cc-toggle { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: .4em; padding: .35em .7em; color: var(--fg, inherit); opacity: .75; }
928
- .ds-247420 .cc-toggle:hover { opacity: 1; }
929
- .ds-247420 .cc-toggle.cc-open { opacity: 1; font-weight: 600; }
1071
+ .ds-247420 .cc-toggle { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: .4em; padding: .35em .7em; color: var(--fg, inherit); opacity: .75; border: 1px solid transparent; border-radius: var(--r-1, 8px); }
1072
+ .ds-247420 .cc-toggle:hover { opacity: 1; background: var(--panel-hover, var(--os-bg-2)); border-color: color-mix(in oklab, var(--fg) 18%, transparent); color: var(--os-fg, inherit); }
1073
+ .ds-247420 .cc-toggle.cc-open { opacity: 1; font-weight: 600; background: var(--panel-hover, var(--os-bg-2)); border-color: color-mix(in oklab, var(--fg) 18%, transparent); }
930
1074
  .ds-247420 .cc-body { padding: .5em .7em .7em; display: flex; flex-direction: column; gap: .5em; max-height: 42vh; max-height: 42dvh; overflow: auto; }
931
1075
  .ds-247420 .cc-body[hidden] { display: none; }
932
1076
  .ds-247420 .cc-row { display: flex; gap: .6em; flex-wrap: wrap; }
@@ -1029,13 +1173,13 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1029
1173
  /* Tool-call card — collapsible details with status icon + name + label. */
1030
1174
  .ds-247420 .chat-tool { display: block; background: var(--panel-1, color-mix(in oklab, var(--fg) 4%, transparent)); border: 1px solid color-mix(in oklab, var(--fg) 14%, transparent); border-radius: var(--r-0); padding: 0; max-width: min(640px, 92%); overflow: hidden; font-size: var(--fs-micro); }
1031
1175
  .ds-247420 .chat-tool[open] { background: var(--panel-1, color-mix(in oklab, var(--fg) 6%, transparent)); }
1032
- .ds-247420 .chat-tool.tool-error { border-color: color-mix(in oklab, var(--danger, #c0392b) 60%, transparent); }
1033
- .ds-247420 .chat-tool.tool-done { border-color: color-mix(in oklab, var(--os-accent, #247420) 35%, transparent); }
1176
+ .ds-247420 .chat-tool.tool-error { border-color: color-mix(in oklab, var(--color-danger) 60%, transparent); }
1177
+ .ds-247420 .chat-tool.tool-done { border-color: color-mix(in oklab, var(--color-success) 35%, transparent); }
1034
1178
  .ds-247420 .chat-tool-head { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1-75) var(--space-2-5); cursor: pointer; list-style: none; user-select: none; }
1035
1179
  .ds-247420 .chat-tool-head::-webkit-details-marker { display: none; }
1036
1180
  .ds-247420 .chat-tool-icon { display: inline-flex; width: 14px; height: 14px; align-items: center; justify-content: center; font-family: var(--os-mono, monospace); font-size: var(--fs-micro); opacity: 0.7; }
1037
- .ds-247420 .chat-tool.tool-error .chat-tool-icon { color: var(--danger, #c0392b); opacity: 1; }
1038
- .ds-247420 .chat-tool.tool-done .chat-tool-icon { color: var(--os-accent, #247420); opacity: 1; }
1181
+ .ds-247420 .chat-tool.tool-error .chat-tool-icon { color: var(--color-danger); opacity: 1; }
1182
+ .ds-247420 .chat-tool.tool-done .chat-tool-icon { color: var(--color-success); opacity: 1; }
1039
1183
  .ds-247420 .chat-tool.tool-running .chat-tool-icon { animation: chat-spin 1.4s linear infinite; }
1040
1184
  @keyframes chat-spin { to { transform: rotate(360deg); } }
1041
1185
  .ds-247420 .chat-tool-name { font-family: var(--os-mono, monospace); font-weight: 600; font-size: var(--fs-micro); }
@@ -1045,7 +1189,7 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1045
1189
  .ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-half); }
1046
1190
  .ds-247420 .chat-tool-section-label { font-size: var(--fs-pico); opacity: 0.5; text-transform: lowercase; letter-spacing: 0.05em; }
1047
1191
  .ds-247420 .chat-tool-pre { margin: 0; padding: var(--space-1-75) var(--space-2); background: color-mix(in oklab, var(--fg) 4%, transparent); border-radius: var(--r-0); max-height: 200px; overflow: auto; font: var(--fs-nano)/1.45 var(--os-mono, ui-monospace, monospace); white-space: pre-wrap; word-break: break-word; }
1048
- .ds-247420 .chat-tool-pre.is-error { color: var(--danger, #c0392b); }
1192
+ .ds-247420 .chat-tool-pre.is-error { color: var(--color-danger); }
1049
1193
 
1050
1194
  /* Thinking indicator — typing dots + label, transient (assistant-side). */
1051
1195
  .ds-247420 .chat-thinking { display: inline-flex; align-items: center; gap: var(--space-2); background: transparent; border: 0; padding: var(--space-1) var(--space-2); opacity: 0.7; font-size: var(--fs-micro); }
@@ -1066,8 +1210,8 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1066
1210
  .ds-247420 .chat-empty-suggestion:focus-visible { outline: 2px solid var(--os-accent, #247420); outline-offset: 2px; }
1067
1211
 
1068
1212
  /* Cancel-while-generating button replaces send. */
1069
- .ds-247420 .chat-composer .send.cancel { background: var(--danger); color: var(--on-color); }
1070
- .ds-247420 .chat-composer .send.cancel:hover { background: color-mix(in oklab, var(--danger, #c0392b) 80%, black); }
1213
+ .ds-247420 .chat-composer .send.cancel { background: var(--color-danger); color: var(--on-color); }
1214
+ .ds-247420 .chat-composer .send.cancel:hover { background: color-mix(in oklab, var(--color-danger) 80%, black); }
1071
1215
 
1072
1216
  /* ============================================================================
1073
1217
  * Jank pass 2 (2026-05-30) — outer-layer scroll containment + iframe gesture
@@ -1095,10 +1239,34 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1095
1239
 
1096
1240
  /* Subtle backdrop blur behind modal overlays — depth cue without compounding
1097
1241
  * paint cost since the blur layer is GPU-composited. Respect reduced-motion
1098
- * by falling back to plain dim. */
1099
- .ds-247420 .tb-sess-overlay { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
1242
+ * by falling back to plain dim. Shared with the overlay-primitives backdrops
1243
+ * below (.ov-cmd-backdrop / .ov-lightbox-backdrop / .ov-auth-backdrop) so
1244
+ * every full-viewport modal in the kit reads as one consistent "on top of
1245
+ * dimmed content" language instead of some floating over undimmed chrome. */
1246
+ .ds-247420 .tb-sess-overlay,
1247
+ .ds-247420 .ov-cmd-backdrop,
1248
+ .ds-247420 .ov-lightbox-backdrop,
1249
+ .ds-247420 .ov-auth-backdrop { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
1100
1250
  @media (prefers-reduced-motion: reduce) {
1101
- .ds-247420 .tb-sess-overlay { backdrop-filter: none; -webkit-backdrop-filter: none; }
1251
+ .ds-247420 .tb-sess-overlay,
1252
+ .ds-247420 .ov-cmd-backdrop,
1253
+ .ds-247420 .ov-lightbox-backdrop,
1254
+ .ds-247420 .ov-auth-backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; }
1255
+ }
1256
+
1257
+ /* Shared full-viewport dimming scrim for the overlay-primitives components
1258
+ * (CommandPalette, VideoLightbox, AuthModal) — these three ship a *-backdrop
1259
+ * root element (command-palette.js / full-screen.js / auth-modal.js) but had
1260
+ * zero CSS anywhere in the kit, so they rendered undimmed, competing with
1261
+ * whatever page content sat behind them instead of reading as on-top. Same
1262
+ * position:fixed/inset:0/var(--z-modal)/var(--scrim) shape as .tb-sess-overlay
1263
+ * above — one scrim implementation, not three near-duplicates. */
1264
+ .ov-cmd-backdrop,
1265
+ .ov-lightbox-backdrop,
1266
+ .ov-auth-backdrop {
1267
+ position: fixed; inset: 0; z-index: var(--z-modal);
1268
+ background: var(--scrim);
1269
+ display: flex; align-items: center; justify-content: center;
1102
1270
  }
1103
1271
 
1104
1272
  /* -----------------------------------------------------------------------
@@ -1271,12 +1439,17 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1271
1439
  }
1272
1440
 
1273
1441
  .ds-247420 .chat-bubble {
1274
- background: var(--panel-1, color-mix(in oklab, var(--fg) 5%, transparent));
1442
+ /* --panel-1 aliases the same --bg-2 the window body already sits on
1443
+ (.wm-body uses --os-bg-1 = --bg-2), so an incoming bubble on --panel-1
1444
+ read as near-invisible against its own window. --panel-2 (--bg-3) is
1445
+ the next real step up the existing panel scale — visible separation,
1446
+ no new token. */
1447
+ background: var(--panel-2, color-mix(in oklab, var(--fg) 10%, transparent));
1275
1448
  color: var(--fg);
1276
1449
  border: 1px solid color-mix(in oklab, var(--fg) 8%, transparent);
1277
- border-radius: var(--r-1);
1450
+ border-radius: var(--radius-sm, var(--r-1));
1278
1451
  padding: var(--space-2) var(--space-2-75);
1279
- font-size: var(--fs-xs);
1452
+ font-size: var(--font-size-body, var(--fs-xs));
1280
1453
  line-height: 1.5;
1281
1454
  max-width: min(720px, 86%);
1282
1455
  overflow-wrap: anywhere;
@@ -1317,8 +1490,8 @@ html.ds-247420 { touch-action: pan-x pan-y; overscroll-behavior: none; -webkit-t
1317
1490
  }
1318
1491
 
1319
1492
  .ds-247420 .chat-meta {
1320
- font-size: var(--fs-nano);
1321
- opacity: 0.55;
1493
+ font-size: var(--font-size-meta, var(--fs-nano));
1494
+ color: var(--fg-3);
1322
1495
  display: inline-flex;
1323
1496
  align-items: center;
1324
1497
  gap: var(--space-1-75);