anentrypoint-design 0.0.379 → 0.0.381

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.
package/dist/247420.css CHANGED
@@ -147,6 +147,13 @@
147
147
  --ff-body: system-ui, sans-serif;
148
148
  --ff-mono: ui-monospace, Menlo, Consolas, monospace;
149
149
 
150
+ /* Sub-12px tiers exist ONLY for dense OS/data chrome — taskbar strips,
151
+ session chips, tool-call headers, file-row metadata, ID/stat columns.
152
+ Never use them for body copy or ordinary UI text: at these sizes the
153
+ system stack loses its readable x-height, so they are reserved for
154
+ glanceable, secondary, non-prose material. --fs-pico is the floor. */
155
+ --fs-pico: 10px;
156
+ --fs-nano: 11px;
150
157
  --fs-micro: 12px;
151
158
  --fs-tiny: 13px;
152
159
  --fs-xs: 14px;
@@ -247,8 +254,61 @@
247
254
  edges (panel spine, expo numbering). A literal length, not a color. */
248
255
  --ink-offset: 3px;
249
256
 
250
- --z-header: 100;
251
- --z-overlay: 1000;
257
+ /* ============================================================
258
+ Stacking scale — the ONE ordered set of layers anything may
259
+ paint into. Rungs are 100 apart so a future layer can be
260
+ inserted between two neighbours without renumbering the rest,
261
+ and so a component may locally offset (+1/+2) within its own
262
+ rung without colliding with the next one.
263
+
264
+ Order is the contract; the numbers are just how it is spelled.
265
+ Read top to bottom as "what paints over what":
266
+
267
+ --z-below -1 decorative texture UNDER its own content
268
+ (.ds-grain/.ds-halftone print layer)
269
+ --z-base 0 in-flow content; the default plane
270
+ --z-raised 100 a thing lifted above its siblings inside
271
+ one component (code-lang tab, timeline dot,
272
+ selection checkbox, resize handle)
273
+ --z-sticky 200 sticky-within-a-scroller chrome: section
274
+ labels, sticky table headers, save bars.
275
+ Above raised content it scrolls past.
276
+ --z-header 300 the app's own sticky chrome band
277
+ (.app-topbar/.app-chrome)
278
+ --z-drawer 400 off-canvas panels (sidebar/pane/session
279
+ drawers) and their scrim, which must cover
280
+ the header they slide over
281
+ --z-window 500 free-floating window-manager surfaces —
282
+ the OS kit's .wm-root canvas of draggable
283
+ windows. Above the shell, below all
284
+ transient popups.
285
+ --z-dock 600 persistent OS shell furniture that must
286
+ stay above windows: launcher dock, menubar,
287
+ taskbar, os-root
288
+ --z-dropdown 700 menus/popovers anchored to a trigger; they
289
+ must escape the dock that spawned them
290
+ --z-modal 800 blocking dialogs, lightboxes, command
291
+ palettes and their backdrops
292
+ --z-toast 900 transient notifications — above a modal,
293
+ because they report on what the modal did
294
+ --z-tooltip 1000 pointer-following hint; never blocked
295
+ --z-top 1100 last resort: boot/loading veils and
296
+ full-screen takeovers that outrank
297
+ everything, including a tooltip
298
+ ============================================================ */
299
+ --z-below: -1;
300
+ --z-base: 0;
301
+ --z-raised: 100;
302
+ --z-sticky: 200;
303
+ --z-header: 300;
304
+ --z-drawer: 400;
305
+ --z-window: 500;
306
+ --z-dock: 600;
307
+ --z-dropdown: 700;
308
+ --z-modal: 800;
309
+ --z-toast: 900;
310
+ --z-tooltip: 1000;
311
+ --z-top: 1100;
252
312
 
253
313
  --measure: 68ch;
254
314
  --measure-wide: 940px;
@@ -591,11 +651,10 @@
591
651
  scrim; heavier than --shadow-3 and theme-driven (was raw rgba(0,0,0,.4)). */
592
652
  --shadow-overlay: 0 12px 40px color-mix(in oklab, var(--fg) 28%, transparent),
593
653
  0 4px 12px color-mix(in oklab, var(--fg) 16%, transparent);
594
- --z-dropdown: 600;
595
- --z-popover: 700;
596
- --z-modal: 800;
597
- --z-toast: 900;
598
- --z-tooltip: 1000;
654
+ /* --z-popover is an alias, not a rung: popovers and dropdowns are the
655
+ same anchored-to-a-trigger layer and must never be able to drift
656
+ apart. The rungs themselves live with the stacking scale above. */
657
+ --z-popover: var(--z-dropdown);
599
658
  }
600
659
 
601
660
  /* app-shell.css */
@@ -624,7 +683,10 @@
624
683
  color: var(--accent-fg);
625
684
  padding: 8px 16px;
626
685
  text-decoration: none;
627
- z-index: 100;
686
+ /* Must outrank every layer of chrome once focused, or the first Tab press
687
+ lands on a control hidden behind the sticky header (was z-index:100,
688
+ which the header alone now matches). */
689
+ z-index: var(--z-top);
628
690
  border-radius: var(--r-pill);
629
691
  font-weight: 600;
630
692
  font-size: var(--fs-sm);
@@ -679,6 +741,13 @@
679
741
  .ds-247420 .t-mono { font-family: var(--ff-mono); }
680
742
  .ds-247420 .t-body { font-family: var(--ff-body); }
681
743
 
744
+ /* House small-label voice, in two sizes. Every declaration here is sourced
745
+ from a token, so a sheet that cannot join these selector lists (community.css
746
+ and gm-prose.css ship as separate <link>-able exports and must not depend on
747
+ app-shell.css being present) still composes the same voice by referencing the
748
+ same four tokens — --ff-mono / --fs-* / uppercase / --tr-label. That token
749
+ set, not this rule, is the single source of truth; a selector that restates a
750
+ literal instead of the token is the drift this pairing exists to prevent. */
682
751
  .ds-247420 .t-label { font-family: var(--ff-mono); font-size: var(--fs-tiny); text-transform: uppercase; letter-spacing: var(--tr-label); font-weight: 500; }
683
752
  .ds-247420 .t-micro { font-family: var(--ff-mono); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tr-label); color: var(--fg-3); }
684
753
  .ds-247420 .t-meta { font-family: var(--ff-body); font-size: var(--fs-sm); color: var(--fg-3); }
@@ -1348,7 +1417,12 @@
1348
1417
  }
1349
1418
  .ds-247420 .panel-body { padding: var(--space-2) var(--space-3) var(--space-3); }
1350
1419
  .ds-247420 .panel-body > * { margin: 0; }
1351
- .ds-247420 .panel-body > * + * { margin-top: var(--space-3); }
1420
+ /* Inner sibling rhythm scales with density like the outer panel rhythm, so a
1421
+ compact/spacious surface stays proportional instead of only its outer
1422
+ intervals moving while the panel interiors hold still. Kept strictly below
1423
+ the outer .ds-panel-gap interval at every density — that ordering is what
1424
+ makes proximity report grouping truthfully. */
1425
+ .ds-247420 .panel-body > * + * { margin-top: calc(var(--space-3) * var(--density)); }
1352
1426
  .ds-247420 .panel.panel-wide .panel-body { padding: 0; }
1353
1427
 
1354
1428
  /* ============================================================
@@ -1570,7 +1644,7 @@
1570
1644
  ============================================================ */
1571
1645
  .ds-247420 .ds-grain { position: relative; isolation: isolate; }
1572
1646
  .ds-247420 .ds-grain::after {
1573
- content: ''; position: absolute; inset: 0; z-index: -1;
1647
+ content: ''; position: absolute; inset: 0; z-index: var(--z-below);
1574
1648
  pointer-events: none;
1575
1649
  background-image: var(--grain);
1576
1650
  background-size: 160px 160px;
@@ -2454,7 +2528,7 @@
2454
2528
  }
2455
2529
  .ds-247420 .ds-file-cell-meta { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); text-align: left; }
2456
2530
  .ds-247420 .ds-file-cell-check {
2457
- position: absolute; top: 4px; left: 4px; z-index: 1;
2531
+ position: absolute; top: 4px; left: 4px; z-index: var(--z-raised);
2458
2532
  background: color-mix(in oklab, var(--bg) 78%, transparent);
2459
2533
  }
2460
2534
 
@@ -2600,7 +2674,7 @@
2600
2674
  .ds-247420 .ds-dropzone--wrap { position: relative; border: none; border-radius: 0; background: transparent; }
2601
2675
  .ds-247420 .ds-dropzone--wrap > .ds-dropzone-inner { display: none; }
2602
2676
  .ds-247420 .ds-dropzone--wrap.dragover > .ds-dropzone-inner {
2603
- display: flex; position: absolute; inset: 0; z-index: 5;
2677
+ display: flex; position: absolute; inset: 0; z-index: var(--z-raised);
2604
2678
  margin: 0; padding: var(--space-3);
2605
2679
  align-items: center; justify-content: center;
2606
2680
  background: color-mix(in srgb, var(--bg) 84%, transparent);
@@ -2692,7 +2766,7 @@
2692
2766
 
2693
2767
  /* -- Modals ------------------------------------------------- */
2694
2768
  .ds-247420 .ds-modal-backdrop {
2695
- position: fixed; inset: 0; z-index: var(--z-modal, 800);
2769
+ position: fixed; inset: 0; z-index: var(--z-modal);
2696
2770
  display: flex; align-items: center; justify-content: center;
2697
2771
  /* Notch/home-indicator safe: near-fullscreen modals must not slide under. */
2698
2772
  padding: max(var(--space-3), env(safe-area-inset-top))
@@ -3001,6 +3075,13 @@
3001
3075
  transition: color var(--dur-base) var(--ease), background var(--dur-base) var(--ease);
3002
3076
  }
3003
3077
  .ds-247420 .ds-segmented .ds-seg-btn:hover { color: var(--fg); }
3078
+ /* Touch floor — a segmented control is a primary mode switch but renders ~30px
3079
+ tall from its 4px padding, below the 44px minimum the rest of the system
3080
+ holds. Grows the hit area only; the pill's visual size is unchanged at
3081
+ fine-pointer sizes. */
3082
+ @media (pointer: coarse) {
3083
+ .ds-247420 .ds-segmented .ds-seg-btn { min-height: 44px; padding-inline: var(--space-3); }
3084
+ }
3004
3085
  .ds-247420 .ds-segmented .ds-seg-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
3005
3086
  .ds-247420 .ds-segmented .ds-seg-btn.is-on {
3006
3087
  background: var(--bg); color: var(--fg);
@@ -3146,7 +3227,12 @@
3146
3227
  .ds-247420 .chat-bubble.chat-md li { margin: var(--space-1) 0; }
3147
3228
  .ds-247420 .chat-bubble.chat-md blockquote {
3148
3229
  margin: var(--space-2) 0; padding: 4px 12px;
3149
- border-left: 3px solid color-mix(in oklab, currentColor 30%, transparent);
3230
+ /* DELIBERATE, but slimmed to the --bw-rule tier. This is a real markdown
3231
+ <blockquote> inside a chat bubble: the left rule is the standard
3232
+ typographic quotation mark, not a colored alert stripe (the tone is a
3233
+ currentColor mix that inherits the bubble's own ink — never an accent).
3234
+ A 3px off-scale literal read as the generic tell; 2px reads as type. */
3235
+ border-left: var(--bw-rule) solid color-mix(in oklab, currentColor 30%, transparent);
3150
3236
  color: color-mix(in oklab, currentColor 75%, transparent); font-style: italic;
3151
3237
  }
3152
3238
  .ds-247420 .chat-bubble.chat-md pre {
@@ -3722,7 +3808,12 @@
3722
3808
  min-height: 120px;
3723
3809
  display: flex; align-items: center; justify-content: center;
3724
3810
  text-align: center; color: var(--fg-3);
3725
- transition: all var(--dur-snap) var(--ease);
3811
+ /* Explicit list, never `all` — the only things `.drop-zone.active` changes
3812
+ are the dashed border tone, the tinted fill and the label colour. `all`
3813
+ also animated padding/min-height/border-width, so a drop target visibly
3814
+ resized mid-drag instead of snapping. */
3815
+ transition: background var(--dur-snap) var(--ease), border-color var(--dur-snap) var(--ease),
3816
+ color var(--dur-snap) var(--ease);
3726
3817
  }
3727
3818
  .ds-247420 .drop-zone.active {
3728
3819
  border-color: var(--accent);
@@ -3762,7 +3853,7 @@
3762
3853
  border-radius: var(--r-2);
3763
3854
  box-shadow: var(--shadow-overlay);
3764
3855
  min-width: 160px;
3765
- z-index: calc(var(--z-overlay, 1000) + 1);
3856
+ z-index: var(--z-dropdown);
3766
3857
  padding: 4px 0;
3767
3858
  }
3768
3859
 
@@ -4141,7 +4232,7 @@
4141
4232
  position: absolute; top: -40px; left: 0;
4142
4233
  background: var(--fg); color: var(--bg);
4143
4234
  padding: 8px 16px; border-radius: var(--r-1);
4144
- text-decoration: none; z-index: var(--z-overlay, 1000);
4235
+ text-decoration: none; z-index: var(--z-top);
4145
4236
  }
4146
4237
  .ds-247420 .skip-to-main:focus { top: 10px; }
4147
4238
 
@@ -4261,7 +4352,7 @@
4261
4352
  padding: var(--space-3) var(--space-4);
4262
4353
  max-width: 320px;
4263
4354
  box-shadow: var(--shadow-overlay);
4264
- z-index: calc(var(--z-overlay, 1000) + 10);
4355
+ z-index: var(--z-toast);
4265
4356
  }
4266
4357
 
4267
4358
  @keyframes toast-slide-in {
@@ -4435,8 +4526,9 @@
4435
4526
  width: 280px; max-width: 80%;
4436
4527
  transform: translateX(-100%);
4437
4528
  transition: transform var(--dur-base, 240ms) var(--ease, ease);
4438
- /* Above the sticky chrome (z-header): scrim > chrome > content budget. */
4439
- z-index: calc(var(--z-header, 100) + 2);
4529
+ /* Drawer rung, above the sticky chrome it slides over. +1 puts the panel
4530
+ itself over its own scrim (--z-drawer), which is the layer below it. */
4531
+ z-index: calc(var(--z-drawer) + 1);
4440
4532
  background: var(--bg);
4441
4533
  border-right: 1px solid color-mix(in oklab, var(--fg) 8%, transparent);
4442
4534
  overflow-y: auto;
@@ -4477,8 +4569,9 @@
4477
4569
  display: none;
4478
4570
  position: absolute; inset: 0;
4479
4571
  background: color-mix(in oklab, var(--bg) 60%, transparent);
4480
- /* Above the sticky chrome so nav behind an open drawer is not clickable. */
4481
- z-index: calc(var(--z-header, 100) + 1);
4572
+ /* Above the sticky chrome so nav behind an open drawer is not clickable.
4573
+ Base of the drawer rung — the panel itself sits one above this. */
4574
+ z-index: var(--z-drawer);
4482
4575
  }
4483
4576
  @container (max-width: 900px) {
4484
4577
  .ds-247420 .app-body.side-open .app-side-scrim { display: block; }
@@ -4490,9 +4583,10 @@
4490
4583
  .ds-247420 .app-side-toggle {
4491
4584
  display: none;
4492
4585
  position: absolute; top: calc((var(--app-topbar-h) - 44px) / 2); left: 10px;
4493
- /* Above the sticky topbar/chrome (z-header) and the drawer/scrim so the
4494
- translucent blurred chrome never paints over or intercepts the toggle. */
4495
- z-index: calc(var(--z-header, 100) + 3);
4586
+ /* Above the sticky topbar/chrome and the drawer/scrim so the translucent
4587
+ blurred chrome never paints over or intercepts the toggle. Top of the
4588
+ drawer rung: scrim < panel < toggle. */
4589
+ z-index: calc(var(--z-drawer) + 2);
4496
4590
  /* 44x44 minimum hit area (WCAG 2.5.5 / Apple HIG) - 36px is below the
4497
4591
  reliable-tap threshold on touch. */
4498
4592
  width: 44px; height: 44px;
@@ -4594,7 +4688,7 @@
4594
4688
  /* Column resize handles: a thin keyboard-accessible separator pinned to the
4595
4689
  right edge of each chrome track; drag (or ArrowLeft/Right) writes a clamped
4596
4690
  inline --ws-*-w. */
4597
- .ds-247420 .ws-resizer { grid-row: 1 / -1; align-self: stretch; justify-self: end; width: 8px; margin-right: -4px; z-index: 5; cursor: col-resize; background: transparent; border: none; padding: 0; touch-action: none; }
4691
+ .ds-247420 .ws-resizer { grid-row: 1 / -1; align-self: stretch; justify-self: end; width: 8px; margin-right: -4px; z-index: var(--z-raised); cursor: col-resize; background: transparent; border: none; padding: 0; touch-action: none; }
4598
4692
  .ds-247420 .ws-resizer::after { content: ""; display: block; width: 2px; height: 100%; margin: 0 auto; background: transparent; transition: background var(--dur-snap) var(--ease); }
4599
4693
  .ds-247420 .ws-resizer:hover::after, .ds-247420 .ws-resizer:focus-visible::after { background: var(--accent); }
4600
4694
  .ds-247420 .ws-resizer:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: -2px; }
@@ -4783,7 +4877,7 @@
4783
4877
  .ds-247420 .ws-pane {
4784
4878
  position: fixed; inset: 0 0 0 auto;
4785
4879
  width: min(340px, 85vw);
4786
- z-index: 42; transform: translateX(110%);
4880
+ z-index: calc(var(--z-drawer) + 1); transform: translateX(110%);
4787
4881
  transition: transform var(--dur-base) var(--ease);
4788
4882
  }
4789
4883
  .ds-247420 .ws-shell.ws-pane-open .ws-pane { transform: translateX(0); width: min(340px, 85vw); }
@@ -4792,7 +4886,7 @@
4792
4886
  .ds-247420 .ws-pane-drawer-toggle { display: inline-flex; }
4793
4887
  /* Scrim is always present from this stage down so it FADES with the drawer
4794
4888
  instead of hard-appearing; pointer-events gate keeps it inert while closed. */
4795
- .ds-247420 .ws-scrim { display: block; opacity: 0; pointer-events: none; position: fixed; inset: 0; z-index: 41; background: color-mix(in srgb, var(--fg) 38%, transparent); transition: opacity var(--dur-base) var(--ease); }
4889
+ .ds-247420 .ws-scrim { display: block; opacity: 0; pointer-events: none; position: fixed; inset: 0; z-index: var(--z-drawer); background: color-mix(in srgb, var(--fg) 38%, transparent); transition: opacity var(--dur-base) var(--ease); }
4796
4890
  .ds-247420 .ws-shell.ws-sessions-open .ws-scrim, .ds-247420 .ws-shell.ws-pane-open .ws-scrim { opacity: 1; pointer-events: auto; }
4797
4891
  }
4798
4892
 
@@ -4814,7 +4908,7 @@
4814
4908
  /* Immune to the desktop collapse var (--ws-sessions-w:0px persisted from
4815
4909
  a desktop session would open an invisible 0-width drawer). */
4816
4910
  width: min(max(var(--ws-sessions-w), 280px), 80vw);
4817
- z-index: 42; transform: translateX(-110%);
4911
+ z-index: calc(var(--z-drawer) + 1); transform: translateX(-110%);
4818
4912
  transition: transform var(--dur-base) var(--ease);
4819
4913
  border-right: var(--bw-hair) solid var(--bg-3);
4820
4914
  overscroll-behavior: contain;
@@ -4841,7 +4935,9 @@
4841
4935
  grid-template-columns: minmax(0, 1fr);
4842
4936
  grid-template-areas: "content";
4843
4937
  }
4844
- .ds-247420 .ws-rail { position: fixed; inset: 0 auto 0 0; width: var(--ws-rail-w-collapsed); z-index: 40; }
4938
+ /* Persistent chrome, not a drawer: it stays put while the session/pane
4939
+ drawers slide over it, so it sits on the header rung below them. */
4940
+ .ds-247420 .ws-rail { position: fixed; inset: 0 auto 0 0; width: var(--ws-rail-w-collapsed); z-index: var(--z-header); }
4845
4941
  .ds-247420 .ws-rail .ws-rail-brand,
4846
4942
  .ds-247420 .ws-rail .ws-rail-action-label,
4847
4943
  .ds-247420 .ws-rail .ws-rail-item-label,
@@ -5054,10 +5150,28 @@
5054
5150
  .ds-247420 .ds-sub-btn:hover { border-color: var(--accent); color: var(--accent-ink); }
5055
5151
  .ds-247420 .ds-sub-btn span { display: block; font-size: 18px; font-weight: 700; color: var(--accent-ink); }
5056
5152
 
5057
- /* SessionRow — base .ds-session-row (layout, hover/focus/active states,
5058
- rail-tone indicators) is canonically defined in chat.css alongside the
5059
- rest of the chat session-list component; this file only carries the
5060
- dev/admin-row sub-parts (id/counts/devcnt/span) that decorate it. */
5153
+ /* SessionRow — the RICH treatment (hover/focus/active, rail tones, nesting,
5154
+ inline rename/delete) lives in chat.css with the rest of the chat session
5155
+ list. But SessionRow is part of this data-density family and is used by kits
5156
+ that never link chat.css (gm_inspector links only colors_and_type +
5157
+ app-shell + editor-primitives), where the component rendered with NO layout
5158
+ at all: gap resolved to `normal`, so id/counts/devcnt/phasewalk/span all
5159
+ butted together at 0px. The layout floor therefore belongs here, next to the
5160
+ sub-parts it positions, so the component is never shipped shapeless.
5161
+ chat.css still layers its interactive states on top; these declarations are
5162
+ identical to the ones there, so a kit loading both gets the same result. */
5163
+ .ds-247420 .ds-session-row {
5164
+ position: relative; display: flex; align-items: center; gap: var(--space-2);
5165
+ width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
5166
+ background: transparent; border: none; border-radius: var(--r-1);
5167
+ text-align: left; color: var(--fg);
5168
+ }
5169
+ /* Only an interactive row gets the pointer affordance (chat.css sets cursor
5170
+ unconditionally because every row there is clickable; here rows are often
5171
+ static readouts). */
5172
+ .ds-247420 .ds-session-row[role="button"], .ds-247420 a.ds-session-row { cursor: pointer; }
5173
+
5174
+ /* Sub-parts that decorate the row above. */
5061
5175
  .ds-247420 .ds-session-row-id {
5062
5176
  font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--accent-ink);
5063
5177
  flex: 0 1 160px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
@@ -5126,11 +5240,115 @@
5126
5240
  /* == appended: ui-kits == */
5127
5241
  /* ============================================================
5128
5242
  ui_kit responsive helpers (kits-grids sweep) */
5129
- .ds-247420 .ds-section-pad { padding: clamp(6px, 1.2vw, 16px); }
5130
- .ds-247420 .ds-panel-gap { margin: var(--space-2) 0; }
5131
- .ds-247420 .ds-panel-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin: var(--space-2) 0; }
5243
+ /* App-surface root. .ds-section carries a --space-8 (96px) editorial rhythm
5244
+ that is correct between landing-page sections and wrong as the ROOT wrapper
5245
+ of an Operate surface, where .app-main has already padded the region used
5246
+ there it just pushes the page heading a screen-inch down and adds dead space
5247
+ below the last panel. This is the app-mode counterpart: no outer margin, and
5248
+ it owns the heading -> lede -> first-panel cadence so each kit stops
5249
+ re-deriving it. Pair with .ds-section-pad for the shadow inset. */
5250
+ .ds-247420 .ds-app-surface { margin: 0; display: flow-root; }
5251
+ /* Operate surfaces run the compact heading ceiling. --fs-h1 tops out at 64px,
5252
+ a display size that makes the page TITLE outweigh the data it labels; the
5253
+ app scale (--fs-h1-app, 22-30px) is what these tokens exist for. Applied
5254
+ here rather than as a data-attribute on each kit shell so any surface using
5255
+ this root gets the app voice without a per-kit opt-in that kits forget. */
5256
+ .ds-247420 .ds-app-surface > h1, .ds-247420 .ds-app-surface > .t-h1 { font-size: var(--fs-h1-app); line-height: 1.15; }
5257
+ .ds-247420 .ds-app-surface > h2, .ds-247420 .ds-app-surface > .t-h2 { font-size: var(--fs-h2-app); }
5258
+ .ds-247420 .ds-app-surface > h3, .ds-247420 .ds-app-surface > .t-h3 { font-size: var(--fs-h3-app); }
5259
+ /* The lede is supporting chrome under an app title, not a marketing stand-first:
5260
+ it drops to body size and keeps a readable measure instead of --fs-xl. */
5261
+ .ds-247420 .ds-app-surface > .lede, .ds-247420 .ds-app-surface > .t-lede { font-size: var(--fs-body); max-width: 60ch; }
5262
+ .ds-247420 .ds-app-surface > h1,
5263
+ .ds-247420 .ds-app-surface > h2 { margin-bottom: var(--space-2); }
5264
+ /* The lede belongs to the heading above it, so it sits tight to that heading
5265
+ and separates generously from the content it introduces. */
5266
+ .ds-247420 .ds-app-surface > .lede,
5267
+ .ds-247420 .ds-app-surface > .t-lede { margin-bottom: calc(var(--space-6) * var(--density)); }
5268
+ /* No leading margin on the first block or trailing margin on the last — the
5269
+ shell owns the region's outer edges. */
5270
+ .ds-247420 .ds-app-surface > :first-child { margin-top: 0; }
5271
+ .ds-247420 .ds-app-surface > :last-child { margin-bottom: 0; }
5272
+
5273
+ /* Section padding is the shell's job (.app-main owns --pad-x). This only adds
5274
+ the small inset a kit root needs so panel shadows are not clipped by the
5275
+ scroll container, and it scales with density like every other app metric —
5276
+ the old clamp(6px,1.2vw,16px) sized against the VIEWPORT inside a
5277
+ container-query layout that measures everything else in cqi. */
5278
+ .ds-247420 .ds-section-pad { padding: calc(var(--space-1) * var(--density)); }
5279
+
5280
+ /* Separation between sibling panels. This is the OUTER rhythm: it must exceed
5281
+ .panel-body's 16px inner sibling gap, otherwise proximity says two unrelated
5282
+ panels belong together more tightly than two rows inside one panel. The old
5283
+ value was --space-2 (8px), which inverted exactly that relationship and made
5284
+ the class named "gap" the only rule in the system that removed separation. */
5285
+ .ds-247420 .ds-panel-gap { margin: calc(var(--space-5) * var(--density)) 0; }
5286
+ /* Density-scaled sibling rhythm for any run of stacked panels, so the cadence
5287
+ holds without each kit re-declaring a margin per panel. */
5288
+ .ds-247420 .ds-panel-gap + .ds-panel-gap { margin-top: calc(var(--space-5) * var(--density)); }
5289
+
5290
+ /* A panel inside a gap-owning parent (grid/flex row). .panel ships a 24px
5291
+ bottom margin for the stacked case; inside a row that margin fights the
5292
+ parent's gap and makes the last row of a wrapping grid sit on a different
5293
+ rhythm than the columns. The container owns separation, so the panel drops
5294
+ its own. Also stretches to the row's height so a short panel next to a tall
5295
+ one does not leave a ragged bottom edge. */
5296
+ /* Drops only the panel's own bottom margin — the row container owns separation.
5297
+ Height is deliberately NOT forced here: whether panels in a row should match
5298
+ heights depends on whether they are a SET (trio: equal peers, matching edge
5299
+ reads as one band) or a PAIR of different things (duo: a 4-bar chart beside a
5300
+ 5-row table, where forcing equality just relocates the dead space inside the
5301
+ shorter panel). Each container decides via align-items below. */
5302
+ .ds-247420 .ds-panel-flush { margin-bottom: 0; }
5303
+
5304
+ /* Paired panels. Container-relative (the shell is the CQ container), so the
5305
+ split collapses when the PANELS are cramped rather than when the viewport
5306
+ crosses an arbitrary width — with a sidebar open those are far apart.
5307
+ minmax(0,1fr) lets a scrolling table shrink instead of forcing overflow. */
5308
+ .ds-247420 .ds-panel-duo {
5309
+ display: grid;
5310
+ grid-template-columns: repeat(2, minmax(0, 1fr));
5311
+ gap: calc(var(--space-3) * var(--density));
5312
+ margin: calc(var(--space-5) * var(--density)) 0;
5313
+ /* A duo pairs two DIFFERENT things (a 4-bar chart beside a 5-row table).
5314
+ Stretching them to a common height does not create equality, it just moves
5315
+ the shorter panel's dead space inside its own body. Each takes its natural
5316
+ height and they align at the top, where the eye actually starts. */
5317
+ align-items: start;
5318
+ }
5319
+ @container (max-width: 900px) {
5320
+ .ds-247420 .ds-panel-duo { grid-template-columns: minmax(0, 1fr); }
5321
+ }
5322
+ /* Fallback for kit roots that are not themselves a container (older kit shells
5323
+ mount outside .app/.ds-stage); harmless where the CQ rule already applies. */
5324
+ @media (max-width: 760px) {
5325
+ .ds-247420 .ds-panel-duo { grid-template-columns: minmax(0, 1fr); }
5326
+ }
5327
+
5328
+ /* Three equal reference panels. Real grid tracks, NOT percentage flex-basis:
5329
+ three 33.33% bases plus two gaps exceed 100% and wrap the last panel onto
5330
+ its own row. Steps 3 -> 2 -> 1 on container width so the panels reflow when
5331
+ they are actually cramped rather than at a viewport number that ignores how
5332
+ much chrome the shell is holding. */
5333
+ .ds-247420 .ds-panel-trio {
5334
+ display: grid;
5335
+ grid-template-columns: repeat(3, minmax(0, 1fr));
5336
+ gap: calc(var(--space-3) * var(--density));
5337
+ margin: calc(var(--space-5) * var(--density)) 0;
5338
+ /* A trio IS a set of equal peers, so a shared bottom edge reads as one band
5339
+ rather than three ragged cards — the opposite call from .ds-panel-duo
5340
+ above, and the reason these are two classes and not one. */
5341
+ align-items: stretch;
5342
+ }
5343
+ .ds-247420 .ds-panel-trio > .panel { height: 100%; }
5344
+ @container (max-width: 1100px) {
5345
+ .ds-247420 .ds-panel-trio { grid-template-columns: repeat(2, minmax(0, 1fr)); }
5346
+ }
5347
+ @container (max-width: 720px) {
5348
+ .ds-247420 .ds-panel-trio { grid-template-columns: minmax(0, 1fr); }
5349
+ }
5132
5350
  @media (max-width: 760px) {
5133
- .ds-247420 .ds-panel-duo { grid-template-columns: 1fr; }
5351
+ .ds-247420 .ds-panel-trio { grid-template-columns: minmax(0, 1fr); }
5134
5352
  }
5135
5353
  /* wide dense rows/tables scroll inside their panel, never the page */
5136
5354
  .ds-247420 .ds-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
@@ -5165,9 +5383,28 @@
5165
5383
  @media (pointer: coarse) {
5166
5384
  .ds-247420 .ds-deck-controls .btn { min-height: 44px; min-width: 44px; }
5167
5385
  }
5386
+ /* Kit small-label voice — one local composition of the house `.t-label` recipe
5387
+ (base.css) for every eyebrow/label in the appended kit blocks below. These
5388
+ previously each restated the four declarations with drifted tracking
5389
+ (0.1em / 0.06em / --tr-label) and drifted size (11px / --fs-micro); they now
5390
+ share --fs-nano + --tr-label. Members declare only their real differences.
5391
+ --fs-nano because these are dense kit chrome, never body or UI text. */
5392
+ .ds-247420 .ds-slide-eyebrow,
5393
+ .ds-247420 .ds-field-eyebrow,
5394
+ .ds-247420 .ds-auth-field-label,
5395
+ .ds-247420 .ds-lightbox-tag {
5396
+ font-family: var(--ff-mono);
5397
+ font-size: var(--fs-nano);
5398
+ letter-spacing: var(--tr-label);
5399
+ text-transform: uppercase;
5400
+ color: var(--panel-text-3);
5401
+ }
5402
+
5403
+ /* Deliberate overrides: the deck slide eyebrow sits on the app --fg ramp (it is
5404
+ full-bleed slide chrome, not panel chrome) and owns its own bottom gutter. */
5168
5405
  .ds-247420 .ds-slide-eyebrow {
5169
- font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.1em;
5170
- text-transform: uppercase; color: var(--fg-3); margin-bottom: clamp(12px, 2.5cqw, 24px);
5406
+ color: var(--fg-3);
5407
+ margin-bottom: clamp(12px, 2.5cqw, 24px);
5171
5408
  }
5172
5409
  .ds-247420 .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
5173
5410
  .ds-247420 .ds-slide-col--start { align-items: flex-start; }
@@ -5204,10 +5441,24 @@
5204
5441
  .ds-247420 .ds-slide-split { grid-template-columns: 1fr; }
5205
5442
  }
5206
5443
  .ds-247420 .ds-slide-split-cell {
5207
- padding: 18px; background: var(--bg-2); border-radius: var(--r-2);
5444
+ padding: var(--space-3-5); background: var(--bg-2); border-radius: var(--r-2);
5208
5445
  color: var(--fg-2); font-size: var(--fs-lg); line-height: var(--lh-base); min-width: 0;
5209
5446
  }
5210
- .ds-247420 .ds-slide-split-cell--accent { border-left: 3px solid var(--slide-accent, var(--accent)); }
5447
+ /* DELIBERATE accent spine this modifier's only job is to mark the emphasized
5448
+ half of a split slide (see ui_kits/slide_deck/app.js), so the rule is the
5449
+ whole component, not decoration on a card. Routed through the house
5450
+ .panel-spine idiom (::before rail at --bw-chunk, squared leading corners)
5451
+ instead of an off-scale 3px border-left. */
5452
+ .ds-247420 .ds-slide-split-cell--accent {
5453
+ position: relative;
5454
+ padding-left: calc(var(--space-3-5) + var(--bw-chunk));
5455
+ border-radius: 0 var(--r-2) var(--r-2) 0;
5456
+ }
5457
+ .ds-247420 .ds-slide-split-cell--accent::before {
5458
+ content: ''; position: absolute; left: 0; top: 0; bottom: 0;
5459
+ width: var(--bw-chunk); background: var(--slide-accent, var(--accent));
5460
+ border-radius: var(--bw-chunk) 0 0 var(--bw-chunk);
5461
+ }
5211
5462
 
5212
5463
  /* --- error 404 --------------------------------------------- */
5213
5464
  .ds-247420 .ds-err-hero {
@@ -5253,7 +5504,7 @@
5253
5504
  display: flex; align-items: center; justify-content: center;
5254
5505
  padding: clamp(12px, 4vw, 32px);
5255
5506
  padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
5256
- z-index: 50;
5507
+ z-index: var(--z-modal);
5257
5508
  }
5258
5509
  .ds-247420 .ds-lightbox-card {
5259
5510
  background: var(--panel-0); border-radius: var(--r-2); padding: clamp(16px, 4vw, 28px);
@@ -5367,15 +5618,29 @@
5367
5618
 
5368
5619
  /* == appended: settings kit cleanup == */
5369
5620
  /* == appended: settings kit == */
5370
- .ds-247420 .ds-settings-main { padding: var(--space-2, 8px); }
5371
- .ds-247420 .ds-settings-body { padding: 14px 18px; }
5372
- .ds-247420 .ds-settings-body-stack { display: flex; flex-direction: column; gap: var(--space-2-5, 10px); }
5373
- .ds-247420 .ds-field-block { margin: var(--space-2-5, 10px) 0; }
5374
- .ds-247420 .ds-field-eyebrow {
5375
- font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em;
5376
- text-transform: uppercase; color: var(--panel-text-3);
5377
- }
5378
- .ds-247420 .ds-hint-sm { font-size: 12px; color: var(--panel-text-2); }
5621
+ /* .app-main already owns this region's padding; this only supplies the inset
5622
+ that keeps panel shadows off the scroll edge (see .ds-section-pad). */
5623
+ .ds-247420 .ds-settings-main { padding: calc(var(--space-1) * var(--density)); }
5624
+ /* .panel-body already pads the panel interior — this sat inside it and
5625
+ double-padded every field, on an off-scale 14/18 pair. The body is now a
5626
+ flow container that owns only the RHYTHM between fields, not a second inset. */
5627
+ .ds-247420 .ds-settings-body { padding: 0; }
5628
+ .ds-247420 .ds-settings-body-stack { display: flex; flex-direction: column; gap: calc(var(--space-2-5) * var(--density)); }
5629
+ /* Field rhythm: the label/control/hint cluster is tight internally, so fields
5630
+ need a clearly larger interval between them than within them, or the whole
5631
+ form reads as one undifferentiated column. Margin-collapse-free (flow root
5632
+ siblings) — first/last are zeroed so the panel body sets the outer edge. */
5633
+ .ds-247420 .ds-field-block { display: flex; flex-direction: column; gap: var(--space-1-75); margin: calc(var(--space-4) * var(--density)) 0 0; }
5634
+ .ds-247420 .ds-settings-body > .ds-field-block:first-child { margin-top: 0; }
5635
+ /* Field width is a hint about expected input length. A name or handle stretched
5636
+ across a 1000px desktop column tells the user to type a paragraph and leaves
5637
+ the eye no left-to-right anchor; capping the control (not the row) keeps the
5638
+ label/hint full-width for wrapping while the input reads as the right size.
5639
+ Textareas keep a wider cap since prose genuinely uses the room. */
5640
+ .ds-247420 .ds-field-block > .input { max-width: 44ch; width: 100%; }
5641
+ .ds-247420 .ds-field-block > textarea.input { max-width: 72ch; }
5642
+ /* .ds-field-eyebrow joins the kit small-label voice above with no overrides. */
5643
+ .ds-247420 .ds-hint-sm { font-size: var(--fs-xs); color: var(--panel-text-2); }
5379
5644
  .ds-247420 .ds-note-quiet { margin: 0; color: var(--panel-text-2); }
5380
5645
  .ds-247420 .ds-btn-row { display: flex; gap: var(--space-2, 8px); flex-wrap: wrap; }
5381
5646
  .ds-247420 .ds-btn-row-tight { gap: var(--space-1-75, 6px); }
@@ -5386,21 +5651,31 @@
5386
5651
  /* Raw --mascot text measures 3.11:1 on paper (fails 4.5:1); --mascot-deep is
5387
5652
  the text-safe tone, same accent/accent-ink split used everywhere else. */
5388
5653
  .ds-247420 .ds-btn-mascot { color: var(--mascot-deep); }
5654
+ /* Sticky commit bar. It floats OVER the form it commits, so it needs real
5655
+ elevation and a larger top margin than the form's own field rhythm —
5656
+ otherwise it reads as one more field rather than as the action for all of
5657
+ them. Spacing is density-scaled like the rest of the surface. */
5389
5658
  .ds-247420 .ds-savebar {
5390
- position: sticky; bottom: 8px; display: flex; align-items: center;
5391
- justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding: 10px;
5392
- background: var(--panel-2); border-radius: var(--r-1); margin: 8px 0;
5659
+ position: sticky; bottom: var(--space-2); z-index: var(--z-sticky);
5660
+ display: flex; align-items: center;
5661
+ justify-content: flex-end; gap: var(--space-2); flex-wrap: wrap;
5662
+ padding: calc(var(--space-2-75) * var(--density)) calc(var(--space-3) * var(--density));
5663
+ background: var(--panel-2); border-radius: var(--r-1);
5664
+ margin: calc(var(--space-5) * var(--density)) 0 var(--space-2);
5665
+ box-shadow: var(--shadow-2, var(--shadow-1));
5393
5666
  }
5394
5667
  .ds-247420 .ds-savebar-note { flex: 1 1 160px; min-width: 0; color: var(--panel-text-2); }
5395
- .ds-247420 .ds-settings-modal { min-width: min(320px, calc(100vw - 32px)); max-width: 480px; }
5396
- .ds-247420 .ds-modal-body-form { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
5397
- .ds-247420 .ds-modal-note { margin: 0 0 8px; color: var(--panel-text-2); font-size: 14px; }
5668
+ .ds-247420 .ds-settings-modal { min-width: min(320px, calc(100vw - var(--space-5))); max-width: 480px; }
5669
+ .ds-247420 .ds-modal-body-form { padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2-75); }
5670
+ .ds-247420 .ds-modal-note { margin: 0; color: var(--panel-text-2); font-size: var(--fs-xs); }
5398
5671
  .ds-247420 .ds-draft-preview {
5399
- background: var(--panel-1); padding: 12px; border-radius: var(--r-0);
5400
- font-size: 13px; color: var(--panel-text-2); max-height: 120px;
5672
+ background: var(--panel-1); padding: var(--space-2-75); border-radius: var(--r-0);
5673
+ font-size: var(--fs-micro); color: var(--panel-text-2); max-height: 120px;
5401
5674
  overflow-y: auto; font-family: var(--ff-mono); overflow-wrap: anywhere;
5402
5675
  }
5403
- .ds-247420 .ds-modal-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: space-between; flex-wrap: wrap; }
5676
+ /* Destructive-choice actions get a clearly larger interval than the body's own
5677
+ gap — the decision must not read as the next line of the explanation. */
5678
+ .ds-247420 .ds-modal-actions { display: flex; gap: var(--space-2); margin-top: var(--space-3); justify-content: space-between; flex-wrap: wrap; }
5404
5679
 
5405
5680
  /* == appended: signin kit cleanup == */
5406
5681
  /* -- signin kit (ui_kits/signin) -- */
@@ -5412,7 +5687,7 @@
5412
5687
  .ds-247420 .ds-auth-sent-title { margin: 0; font-weight: 600; }
5413
5688
  .ds-247420 .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
5414
5689
  .ds-247420 .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
5415
- .ds-247420 .ds-auth-field-label { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
5690
+ /* .ds-auth-field-label joins the kit small-label voice above, no overrides. */
5416
5691
  .ds-247420 .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
5417
5692
  .ds-247420 .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
5418
5693
  .ds-247420 .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
@@ -5444,7 +5719,7 @@
5444
5719
  .ds-247420 .ds-gal-swatch-name { color: var(--panel-text); }
5445
5720
  .ds-247420 .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
5446
5721
  .ds-247420 .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
5447
- .ds-247420 .ds-lightbox-tag { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
5722
+ /* .ds-lightbox-tag joins the kit small-label voice above, no overrides. */
5448
5723
 
5449
5724
  /* --- error_404 kit --- */
5450
5725
  .ds-247420 .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
@@ -5460,10 +5735,18 @@
5460
5735
  .ds-247420 .ds-cli-warn .prompt, .ds-247420 .ds-cli-warn .cmd { color: var(--mascot-deep); }
5461
5736
  .ds-247420 .ds-cli-log .prompt { color: var(--fg-3); }
5462
5737
  .ds-247420 .ds-cli-log .cmd { color: var(--fg-2); font-family: var(--ff-mono); }
5463
- .ds-247420 .ds-term-body { padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; background: var(--bg-2); border-radius: var(--r-1); }
5738
+ .ds-247420 .ds-term-body { padding: var(--space-2-75) var(--space-3-5); display: flex; flex-direction: column; gap: var(--space-1); background: var(--bg-2); border-radius: var(--r-1); }
5464
5739
  .ds-247420 .ds-term-body--tall { min-height: 280px; }
5465
- .ds-247420 .ds-term-input-row { margin-top: 6px; }
5466
- .ds-247420 .ds-term-input { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; font-family: var(--ff-mono); font-size: 13px; color: var(--fg); }
5740
+ .ds-247420 .ds-term-input-row { margin-top: var(--space-1-75); }
5741
+ .ds-247420 .ds-term-input { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg); }
5742
+ /* The input itself is a prompt line, not a form control, so it is NOT floored
5743
+ to 44px (that would break the terminal's line rhythm). Instead the whole
5744
+ prompt ROW becomes the tap target, and the font goes to 16px so focusing it
5745
+ does not trigger iOS zoom — a sub-16px input is what causes that. */
5746
+ @media (pointer: coarse) {
5747
+ .ds-247420 .ds-term-input-row { min-height: 44px; align-items: center; }
5748
+ .ds-247420 .ds-term-input { font-size: max(16px, var(--fs-micro)); }
5749
+ }
5467
5750
  /* full-viewport render root (community-app) */
5468
5751
  .ds-247420 .ds-root-viewport { height: 100vh; height: 100dvh; }
5469
5752
 
@@ -5527,7 +5810,7 @@
5527
5810
  }
5528
5811
  .ds-247420 .ds-sheet-preview-table thead th {
5529
5812
  position: sticky; top: 0; background: var(--bg-2); color: var(--fg-3);
5530
- font-weight: 600; z-index: 1;
5813
+ font-weight: 600; z-index: var(--z-sticky);
5531
5814
  }
5532
5815
  .ds-247420 .ds-sheet-preview-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
5533
5816
  .ds-247420 .ds-sheet-preview-empty { padding: var(--space-3, 16px); color: var(--fg-3); }
@@ -5538,6 +5821,191 @@
5538
5821
  }
5539
5822
  .ds-247420 .ds-sheet-preview-error-action:hover { background: var(--bg-2); }
5540
5823
  .ds-247420 .ds-sheet-preview-error-action:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 2px; }
5824
+
5825
+ /* == appended: community kit message list == */
5826
+ /* ui_kits/community mounts CommunityShell (the .cm-* family) but renders its
5827
+ OWN message list in ds-* markup, and its index.html links app-shell.css
5828
+ WITHOUT community.css. So these live here, not in community.css: the .cm-*
5829
+ sheet never reaches this page, and .ds-community-* is ds-family markup by
5830
+ the lint-classes taxonomy anyway. Every rule below deliberately mirrors the
5831
+ .chat-msg / .chat-avatar / .chat-stack primitives in chat-polish.css so the
5832
+ community thread and the chat kit read as one message language. */
5833
+
5834
+ /* Page root — owns the full viewport column so CommunityShell's own 100dvh
5835
+ flex shell has a height to resolve against, with the topbar/status chrome
5836
+ stacked around it. */
5837
+ .ds-247420 .ds-community-page {
5838
+ display: flex;
5839
+ flex-direction: column;
5840
+ min-height: 100vh;
5841
+ min-height: 100dvh;
5842
+ min-width: 0;
5843
+ }
5844
+ /* Main column inside the shell — .cm-main's ds-family counterpart: header
5845
+ pinned, message list taking the remaining height and doing the scrolling. */
5846
+ .ds-247420 .ds-community-main {
5847
+ display: flex;
5848
+ flex-direction: column;
5849
+ flex: 1;
5850
+ min-width: 0;
5851
+ min-height: 0;
5852
+ }
5853
+
5854
+ /* Thread scroller. Same rhythm as .chat-thread (column + --space-3 gap +
5855
+ own overflow), so messages breathe on the same interval as the chat kit. */
5856
+ .ds-247420 .ds-community-messages {
5857
+ display: flex;
5858
+ flex-direction: column;
5859
+ gap: var(--space-3);
5860
+ flex: 1;
5861
+ min-height: 0;
5862
+ overflow-y: auto;
5863
+ padding: var(--space-3);
5864
+ scrollbar-width: thin;
5865
+ scrollbar-color: var(--bg-3) transparent;
5866
+ }
5867
+ .ds-247420 .ds-community-messages::-webkit-scrollbar { width: 8px; }
5868
+ .ds-247420 .ds-community-messages::-webkit-scrollbar-thumb { background: var(--bg-3); border-radius: var(--r-0); }
5869
+
5870
+ /* One message — avatar rail + body stack, matching .chat-msg's flex/gap and
5871
+ its quiet tonal hover (no border, per the zero-border aesthetic). */
5872
+ .ds-247420 .ds-community-msg {
5873
+ display: flex;
5874
+ align-items: flex-start;
5875
+ gap: var(--space-2-75);
5876
+ padding: var(--space-1-75) var(--space-2);
5877
+ margin: 0;
5878
+ border-radius: var(--r-1);
5879
+ min-width: 0;
5880
+ transition: background var(--dur-base) var(--ease);
5881
+ }
5882
+ .ds-247420 .ds-community-msg:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); }
5883
+
5884
+ /* Identity disc. The inline `background:` from app.js supplies the per-author
5885
+ tone; this owns the SHAPE — a circle, which is the whole reason the avatar
5886
+ was rendering as a coloured bar with no rule. Footprint + type match
5887
+ .chat-avatar exactly. */
5888
+ .ds-247420 .ds-community-avatar {
5889
+ flex: 0 0 36px;
5890
+ width: 36px;
5891
+ height: 36px;
5892
+ border-radius: 50%;
5893
+ display: inline-flex;
5894
+ align-items: center;
5895
+ justify-content: center;
5896
+ overflow: hidden;
5897
+ color: var(--ink);
5898
+ font-family: var(--ff-mono);
5899
+ font-size: var(--fs-micro);
5900
+ font-weight: 600;
5901
+ line-height: 1;
5902
+ user-select: none;
5903
+ }
5904
+
5905
+ /* Body stack — name + time on one baseline, text beneath. .chat-stack's
5906
+ column/gap idiom, without the bubble max-width (this is a flat list row,
5907
+ not a two-sided bubble thread). */
5908
+ .ds-247420 .ds-community-msg-body {
5909
+ display: flex;
5910
+ flex-wrap: wrap;
5911
+ align-items: baseline;
5912
+ gap: var(--space-1) var(--space-2);
5913
+ flex: 1;
5914
+ min-width: 0;
5915
+ }
5916
+ /* Author. The inline `color:` from app.js carries the per-author tone; weight
5917
+ and size are what make it read as the row's title. */
5918
+ .ds-247420 .ds-community-msg-name {
5919
+ font-weight: 600;
5920
+ font-size: var(--fs-sm);
5921
+ line-height: 1.3;
5922
+ }
5923
+ /* Timestamp — the quiet mono meta voice used by .cm-user-tag / row .meta. */
5924
+ .ds-247420 .ds-community-msg-time {
5925
+ font-family: var(--ff-mono);
5926
+ font-size: var(--fs-micro);
5927
+ color: var(--fg-3);
5928
+ line-height: 1.3;
5929
+ }
5930
+ /* Message body claims the full second line of the wrapping body row. */
5931
+ .ds-247420 .ds-community-msg-text {
5932
+ flex: 1 0 100%;
5933
+ margin: 0;
5934
+ min-width: 0;
5935
+ color: var(--fg-2);
5936
+ font-size: var(--fs-sm);
5937
+ line-height: var(--lh-base);
5938
+ overflow-wrap: anywhere;
5939
+ }
5940
+
5941
+ @media (prefers-reduced-motion: reduce) {
5942
+ .ds-247420 .ds-community-msg { transition: none; }
5943
+ }
5944
+
5945
+ /* == appended: cross-kit note / swatch / chat-page / caret == */
5946
+
5947
+ /* "about this kit" explanatory block — 8 kits render a run of <p> lines here
5948
+ (often carrying inline Chip()/<code>) inside a .panel body. This is
5949
+ SECONDARY copy annotating the demo above it, so it takes the quiet voice:
5950
+ one step down from body, on the --fg-2 ramp, with a comfortable reading
5951
+ line-height. It owns only the RHYTHM between its lines; the panel body still
5952
+ owns the inset, so this must not re-pad. */
5953
+ .ds-247420 .ds-pattern-notes {
5954
+ display: flex;
5955
+ flex-direction: column;
5956
+ gap: var(--space-2);
5957
+ color: var(--fg-2);
5958
+ font-size: var(--fs-sm);
5959
+ line-height: var(--lh-base);
5960
+ max-width: var(--measure);
5961
+ min-width: 0;
5962
+ }
5963
+ .ds-247420 .ds-pattern-notes p { margin: 0; overflow-wrap: anywhere; }
5964
+ /* Inline literals inside a note read as quoted machinery, not as body copy —
5965
+ same tonal chip treatment .chat-bubble code uses. */
5966
+ .ds-247420 .ds-pattern-notes code {
5967
+ font-family: var(--ff-mono);
5968
+ font-size: 0.92em;
5969
+ background: color-mix(in oklab, var(--fg) 8%, transparent);
5970
+ padding: 0 var(--space-1);
5971
+ border-radius: var(--r-hair);
5972
+ }
5973
+ .ds-247420 .ds-pattern-notes strong { color: var(--fg); font-weight: 600; }
5974
+
5975
+ /* Swatch cell wrapper (system_primer pairs it with .ds-swatch-col, which owns
5976
+ the column/gap). This adds only what the wrapper itself needs: a minimum-zero
5977
+ track so long token names ellipsize inside the grid instead of widening it. */
5978
+ .ds-247420 .ds-swatch { min-width: 0; }
5979
+ .ds-247420 .ds-swatch .ds-swatch-name { overflow-wrap: anywhere; }
5980
+
5981
+ /* Chat kit page root — the thread must own the leftover column height rather
5982
+ than growing the page, so the composer stays on screen. Pairs with
5983
+ .ds-chat-layout (flex column, flex:1) which is already defined above. */
5984
+ .ds-247420 .chat-kit-page {
5985
+ display: flex;
5986
+ flex-direction: column;
5987
+ flex: 1;
5988
+ min-height: 0;
5989
+ min-width: 0;
5990
+ }
5991
+
5992
+ /* Terminal caret — a solid block that sits on the last demo line. Sized in ch
5993
+ so it tracks the mono column it follows. The blink is motion, so it is
5994
+ declared ONLY inside prefers-reduced-motion: no-preference (the same
5995
+ opt-in shape .cm-ch-spinner / .cm-vs-label::before use); with reduced
5996
+ motion the caret is a steady block, still marking the cursor position. */
5997
+ .ds-247420 .cursor-blink {
5998
+ display: inline-block;
5999
+ width: 1ch;
6000
+ height: 1em;
6001
+ margin-left: var(--space-1);
6002
+ background: var(--accent);
6003
+ vertical-align: text-bottom;
6004
+ }
6005
+ @media (prefers-reduced-motion: no-preference) {
6006
+ .ds-247420 .cursor-blink { animation: ds-cursor-blink 1s step-end infinite; }
6007
+ @keyframes ds-cursor-blink { 50% { opacity: 0; } }
6008
+ }
5541
6009
  /* ============================================================
5542
6010
  Git status panel + diff view — changed-file list, unified diff.
5543
6011
  ============================================================ */
@@ -5655,7 +6123,7 @@
5655
6123
  ============================================================ */
5656
6124
 
5657
6125
  .ds-247420 .ds-plugins-overlay {
5658
- position: fixed; inset: 0; z-index: var(--z-modal, 1000);
6126
+ position: fixed; inset: 0; z-index: var(--z-modal);
5659
6127
  background: color-mix(in oklab, var(--ink) 35%, transparent);
5660
6128
  display: flex; align-items: center; justify-content: center;
5661
6129
  padding: var(--space-3);
@@ -5917,6 +6385,25 @@
5917
6385
  All tokens sourced from colors_and_type.css.
5918
6386
  ============================================================ */
5919
6387
 
6388
+ /* ============================================================
6389
+ Small-label voice — the local composition of the house `.t-micro`
6390
+ recipe (src/css/app-shell/base.css). This sheet is a standalone
6391
+ published export consumed via its own <link>, so it cannot join the
6392
+ `.t-micro` selector list; it composes by referencing the identical
6393
+ token set instead. Every selector below that needs the label voice
6394
+ JOINS this rule and declares only what it deliberately differs on —
6395
+ never a second copy of these four declarations.
6396
+ ============================================================ */
6397
+ .ds-247420 .cm-vs-label,
6398
+ .ds-247420 .vx-section-label,
6399
+ .ds-247420 .vx-chip-tag {
6400
+ font-family: var(--ff-mono);
6401
+ font-size: var(--fs-micro);
6402
+ text-transform: uppercase;
6403
+ letter-spacing: var(--tr-label);
6404
+ color: var(--fg-3);
6405
+ }
6406
+
5920
6407
  /* ============================================================
5921
6408
  Shell — top-level flex container for the community layout
5922
6409
  ============================================================ */
@@ -5955,8 +6442,8 @@
5955
6442
  display: flex;
5956
6443
  flex-direction: column;
5957
6444
  align-items: center;
5958
- gap: 8px;
5959
- padding: 12px 0;
6445
+ gap: var(--space-2);
6446
+ padding: var(--space-2-75) 0;
5960
6447
  background: color-mix(in oklab, var(--bg) 70%, var(--ink));
5961
6448
  overflow-y: auto;
5962
6449
  overflow-x: hidden;
@@ -6025,7 +6512,7 @@
6025
6512
  right: -2px;
6026
6513
  min-width: 18px;
6027
6514
  height: 18px;
6028
- padding: 0 5px;
6515
+ padding: 0 var(--space-1-5);
6029
6516
  background: var(--warn);
6030
6517
  color: var(--paper);
6031
6518
  font-family: var(--ff-mono);
@@ -6070,7 +6557,7 @@
6070
6557
  height: 2px;
6071
6558
  background: color-mix(in oklab, var(--fg) 12%, transparent);
6072
6559
  border-radius: var(--r-hair);
6073
- margin: 4px 0;
6560
+ margin: var(--space-1) 0;
6074
6561
  flex-shrink: 0;
6075
6562
  }
6076
6563
 
@@ -6091,8 +6578,8 @@
6091
6578
  display: flex;
6092
6579
  align-items: center;
6093
6580
  justify-content: space-between;
6094
- gap: 8px;
6095
- padding: 14px 16px;
6581
+ gap: var(--space-2);
6582
+ padding: var(--space-2-75) var(--space-3);
6096
6583
  background: var(--bg-2);
6097
6584
  box-shadow: 0 1px 0 color-mix(in oklab, var(--fg) 8%, transparent);
6098
6585
  font-weight: 600;
@@ -6119,10 +6606,10 @@
6119
6606
  min-height: 0;
6120
6607
  overflow-y: auto;
6121
6608
  overflow-x: hidden;
6122
- padding: 8px 0 16px;
6609
+ padding: var(--space-2) 0 var(--space-3);
6123
6610
  display: flex;
6124
6611
  flex-direction: column;
6125
- gap: 2px;
6612
+ gap: var(--space-hair);
6126
6613
  scrollbar-width: thin;
6127
6614
  scrollbar-color: color-mix(in oklab, var(--fg) 18%, transparent) transparent;
6128
6615
  }
@@ -6139,15 +6626,15 @@
6139
6626
  .ds-247420 .cm-channel-category {
6140
6627
  display: flex;
6141
6628
  flex-direction: column;
6142
- margin-top: 12px;
6629
+ margin-top: var(--space-2-75);
6143
6630
  }
6144
- .ds-247420 .cm-channel-category:first-child { margin-top: 4px; }
6631
+ .ds-247420 .cm-channel-category:first-child { margin-top: var(--space-1); }
6145
6632
 
6146
6633
  .ds-247420 .cm-category-header {
6147
6634
  display: flex;
6148
6635
  align-items: center;
6149
- gap: 4px;
6150
- padding: 4px 8px 4px 8px;
6636
+ gap: var(--space-1);
6637
+ padding: var(--space-1) var(--space-2);
6151
6638
  font-family: var(--ff-body);
6152
6639
  font-size: var(--fs-micro);
6153
6640
  font-weight: 600;
@@ -6181,6 +6668,10 @@
6181
6668
  text-overflow: ellipsis;
6182
6669
  white-space: nowrap;
6183
6670
  }
6671
+ /* Deliberately NOT the small-label voice: this is the `+` affordance sitting
6672
+ inside .cm-category-header, which IS uppercase + tracked. The zeroed
6673
+ letter-spacing and text-transform are resets of that inherited voice, not a
6674
+ copy of it — a bare glyph must not be tracked apart or case-folded. */
6184
6675
  .ds-247420 .cm-cat-extra {
6185
6676
  font-family: var(--ff-mono);
6186
6677
  font-size: var(--fs-micro);
@@ -6195,7 +6686,7 @@
6195
6686
  justify-content: center;
6196
6687
  width: 28px;
6197
6688
  height: 28px;
6198
- padding: 4px;
6689
+ padding: var(--space-1);
6199
6690
  border: 0;
6200
6691
  background: transparent;
6201
6692
  color: var(--fg-3);
@@ -6217,8 +6708,11 @@
6217
6708
  .ds-247420 .cm-cat-channels {
6218
6709
  display: flex;
6219
6710
  flex-direction: column;
6711
+ /* gap:1px is OFF-SCALE ON PURPOSE — channel rows are meant to read as one
6712
+ near-continuous stack with only a hairline seam between them. --space-hair
6713
+ (2px) doubles the seam and breaks the rows into visibly separate pills. */
6220
6714
  gap: 1px;
6221
- padding: 2px 0;
6715
+ padding: var(--space-hair) 0;
6222
6716
  }
6223
6717
 
6224
6718
  /* ============================================================
@@ -6226,15 +6720,15 @@
6226
6720
  ============================================================ */
6227
6721
  .ds-247420 .cm-channel-item-wrap {
6228
6722
  position: relative;
6229
- padding: 0 8px;
6723
+ padding: 0 var(--space-2);
6230
6724
  }
6231
6725
 
6232
6726
  .ds-247420 .cm-channel-item {
6233
6727
  position: relative;
6234
6728
  display: flex;
6235
6729
  align-items: center;
6236
- gap: 8px;
6237
- padding: 6px 8px;
6730
+ gap: var(--space-2);
6731
+ padding: var(--space-1-75) var(--space-2);
6238
6732
  border-radius: var(--r-1);
6239
6733
  color: var(--fg-3);
6240
6734
  cursor: pointer;
@@ -6350,7 +6844,7 @@
6350
6844
  flex-shrink: 0;
6351
6845
  min-width: 16px;
6352
6846
  height: 16px;
6353
- padding: 0 5px;
6847
+ padding: 0 var(--space-1-5);
6354
6848
  background: var(--warn);
6355
6849
  color: var(--paper);
6356
6850
  font-family: var(--ff-mono);
@@ -6366,7 +6860,7 @@
6366
6860
  .ds-247420 .cm-ch-actions {
6367
6861
  display: inline-flex;
6368
6862
  align-items: center;
6369
- gap: 2px;
6863
+ gap: var(--space-hair);
6370
6864
  opacity: 0;
6371
6865
  transition: opacity var(--dur-snap) var(--ease);
6372
6866
  flex-shrink: 0;
@@ -6376,7 +6870,7 @@
6376
6870
  .ds-247420 .cm-ch-action-btn {
6377
6871
  width: 28px;
6378
6872
  height: 28px;
6379
- padding: 4px;
6873
+ padding: var(--space-1);
6380
6874
  display: inline-flex;
6381
6875
  align-items: center;
6382
6876
  justify-content: center;
@@ -6401,15 +6895,16 @@
6401
6895
  .ds-247420 .cm-ch-voice-users {
6402
6896
  display: flex;
6403
6897
  flex-direction: column;
6898
+ /* gap:1px — same hairline-seam rationale as .cm-cat-channels above. */
6404
6899
  gap: 1px;
6405
- padding: 2px 8px 4px 32px;
6900
+ padding: var(--space-hair) var(--space-2) var(--space-1) var(--space-5);
6406
6901
  }
6407
6902
 
6408
6903
  .ds-247420 .cm-ch-voice-user {
6409
6904
  display: flex;
6410
6905
  align-items: center;
6411
- gap: 8px;
6412
- padding: 3px 6px;
6906
+ gap: var(--space-2);
6907
+ padding: var(--space-half) var(--space-1-75);
6413
6908
  border-radius: var(--r-1);
6414
6909
  color: var(--fg-2);
6415
6910
  font-size: var(--fs-xs);
@@ -6463,8 +6958,8 @@
6463
6958
  .ds-247420 .cm-voice-strip {
6464
6959
  display: none;
6465
6960
  flex-direction: column;
6466
- gap: 8px;
6467
- padding: 10px 12px;
6961
+ gap: var(--space-2);
6962
+ padding: var(--space-2-5) var(--space-2-75);
6468
6963
  background: color-mix(in oklab, var(--green) 18%, var(--bg-2));
6469
6964
  color: var(--fg);
6470
6965
  box-shadow: 0 -1px 0 color-mix(in oklab, var(--fg) 10%, transparent);
@@ -6472,16 +6967,15 @@
6472
6967
  }
6473
6968
  .ds-247420 .cm-voice-strip.open { display: flex; }
6474
6969
 
6970
+ /* Joins the small-label voice above. Deliberate overrides: --green (this is a
6971
+ live-recording indicator, not neutral chrome) and weight 700 (it sits next to
6972
+ a pulsing dot and must read as the loudest thing in the strip). */
6475
6973
  .ds-247420 .cm-vs-label {
6476
- font-family: var(--ff-mono);
6477
- font-size: var(--fs-micro);
6478
- text-transform: uppercase;
6479
- letter-spacing: var(--tr-caps);
6480
6974
  color: var(--green);
6481
6975
  font-weight: 700;
6482
6976
  display: inline-flex;
6483
6977
  align-items: center;
6484
- gap: 6px;
6978
+ gap: var(--space-1-75);
6485
6979
  }
6486
6980
  .ds-247420 .cm-vs-label::before {
6487
6981
  content: '';
@@ -6515,7 +7009,7 @@
6515
7009
  color: var(--fg-2);
6516
7010
  display: flex;
6517
7011
  align-items: center;
6518
- gap: 6px;
7012
+ gap: var(--space-1-75);
6519
7013
  flex-wrap: wrap;
6520
7014
  }
6521
7015
 
@@ -6523,9 +7017,9 @@
6523
7017
  display: inline-flex;
6524
7018
  align-items: center;
6525
7019
  justify-content: center;
6526
- gap: 6px;
7020
+ gap: var(--space-1-75);
6527
7021
  height: 28px;
6528
- padding: 0 10px;
7022
+ padding: 0 var(--space-2-5);
6529
7023
  background: color-mix(in oklab, var(--fg) 10%, transparent);
6530
7024
  color: var(--fg);
6531
7025
  border: 0;
@@ -6553,8 +7047,8 @@
6553
7047
  .ds-247420 .cm-user-panel {
6554
7048
  display: flex;
6555
7049
  align-items: center;
6556
- gap: 8px;
6557
- padding: 8px 8px;
7050
+ gap: var(--space-2);
7051
+ padding: var(--space-2);
6558
7052
  background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
6559
7053
  flex-shrink: 0;
6560
7054
  }
@@ -6607,6 +7101,8 @@
6607
7101
  text-overflow: ellipsis;
6608
7102
  white-space: nowrap;
6609
7103
  }
7104
+ /* Deliberately NOT the small-label voice: a user's handle/tag is content, not
7105
+ chrome, so it stays sentence-case and untracked. Mono + micro + --fg-3 only. */
6610
7106
  .ds-247420 .cm-user-tag {
6611
7107
  font-family: var(--ff-mono);
6612
7108
  font-size: var(--fs-micro);
@@ -6619,7 +7115,7 @@
6619
7115
  .ds-247420 .cm-user-controls {
6620
7116
  display: inline-flex;
6621
7117
  align-items: center;
6622
- gap: 2px;
7118
+ gap: var(--space-hair);
6623
7119
  }
6624
7120
 
6625
7121
  .ds-247420 .cm-user-btn {
@@ -6654,8 +7150,8 @@
6654
7150
  .ds-247420 .cm-chat-header {
6655
7151
  display: flex;
6656
7152
  align-items: center;
6657
- gap: 10px;
6658
- padding: 12px 16px;
7153
+ gap: var(--space-2-5);
7154
+ padding: var(--space-2-75) var(--space-3);
6659
7155
  background: var(--bg);
6660
7156
  box-shadow: 0 1px 0 color-mix(in oklab, var(--fg) 8%, transparent);
6661
7157
  flex-shrink: 0;
@@ -6685,8 +7181,8 @@
6685
7181
  .ds-247420 .cm-chat-header-topic {
6686
7182
  flex: 1;
6687
7183
  min-width: 0;
6688
- padding-left: 12px;
6689
- margin-left: 4px;
7184
+ padding-left: var(--space-2-75);
7185
+ margin-left: var(--space-1);
6690
7186
  border-left: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
6691
7187
  color: var(--fg-3);
6692
7188
  font-size: var(--fs-xs);
@@ -6698,7 +7194,7 @@
6698
7194
  .ds-247420 .cm-chat-header-toolbar {
6699
7195
  display: inline-flex;
6700
7196
  align-items: center;
6701
- gap: 4px;
7197
+ gap: var(--space-1);
6702
7198
  flex-shrink: 0;
6703
7199
  }
6704
7200
 
@@ -6714,7 +7210,7 @@
6714
7210
  overflow-y: auto;
6715
7211
  overflow-x: hidden;
6716
7212
  background: var(--bg-2);
6717
- padding: 16px 0;
7213
+ padding: var(--space-3) 0;
6718
7214
  scrollbar-width: thin;
6719
7215
  scrollbar-color: color-mix(in oklab, var(--fg) 18%, transparent) transparent;
6720
7216
  transition: width var(--dur-base) var(--ease), flex-basis var(--dur-base) var(--ease);
@@ -6736,7 +7232,7 @@
6736
7232
  }
6737
7233
 
6738
7234
  .ds-247420 .cm-member-category {
6739
- padding: 12px 16px 6px;
7235
+ padding: var(--space-2-75) var(--space-3) var(--space-1-75);
6740
7236
  font-family: var(--ff-body);
6741
7237
  font-size: var(--fs-micro);
6742
7238
  font-weight: 600;
@@ -6748,9 +7244,9 @@
6748
7244
  .ds-247420 .cm-member-item {
6749
7245
  display: flex;
6750
7246
  align-items: center;
6751
- gap: 10px;
6752
- padding: 6px 12px;
6753
- margin: 0 8px;
7247
+ gap: var(--space-2-5);
7248
+ padding: var(--space-1-75) var(--space-2-75);
7249
+ margin: 0 var(--space-2);
6754
7250
  border-radius: var(--r-1);
6755
7251
  color: var(--fg-2);
6756
7252
  cursor: pointer;
@@ -6815,8 +7311,8 @@
6815
7311
  display: inline-flex;
6816
7312
  flex-direction: column;
6817
7313
  align-items: center;
6818
- gap: 6px;
6819
- padding: 10px;
7314
+ gap: var(--space-1-75);
7315
+ padding: var(--space-2-5);
6820
7316
  border-radius: var(--r-2);
6821
7317
  background: var(--bg-2);
6822
7318
  transition: box-shadow var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease);
@@ -6866,7 +7362,7 @@
6866
7362
  @media (max-width: 900px) {
6867
7363
  .ds-247420 .cm-channel-sidebar {
6868
7364
  position: absolute;
6869
- z-index: 20;
7365
+ z-index: calc(var(--z-drawer) + 1);
6870
7366
  top: 0;
6871
7367
  left: 72px;
6872
7368
  bottom: 0;
@@ -6879,7 +7375,7 @@
6879
7375
  .ds-247420 .cm-member-list.open {
6880
7376
  display: flex;
6881
7377
  position: absolute;
6882
- z-index: 20;
7378
+ z-index: calc(var(--z-drawer) + 1);
6883
7379
  top: 0;
6884
7380
  right: 0;
6885
7381
  bottom: 0;
@@ -6899,7 +7395,7 @@
6899
7395
  content: '';
6900
7396
  position: absolute;
6901
7397
  inset: 0;
6902
- z-index: 15;
7398
+ z-index: var(--z-drawer);
6903
7399
  background: color-mix(in oklab, var(--ink) 40%, transparent);
6904
7400
  pointer-events: none;
6905
7401
  }
@@ -6915,7 +7411,7 @@
6915
7411
  .ds-247420 .cm-server-back {
6916
7412
  width: 44px;
6917
7413
  height: 44px;
6918
- padding: 4px;
7414
+ padding: var(--space-1);
6919
7415
  }
6920
7416
  .ds-247420 .cm-channel-sidebar,
6921
7417
  .ds-247420 .cm-channel-sidebar.open {
@@ -7061,7 +7557,12 @@
7061
7557
  gap: var(--space-2);
7062
7558
  padding: var(--space-1) var(--space-2);
7063
7559
  background: var(--bg-2);
7064
- border-left: 3px solid var(--accent);
7560
+ /* Hairline, not a 3px accent bar. This is a transient status strip pinned
7561
+ above the composer (role=status, "Replying to <author>"), not a card or a
7562
+ callout — the tinted fill already carries the attachment. A chunky left
7563
+ bar here was the generic accent-stripe tell; the real accent still lands
7564
+ on .cm-rb-author. */
7565
+ border-left: var(--bw-hair) solid var(--rule-strong);
7065
7566
  font-size: 0.85rem;
7066
7567
  }
7067
7568
  .ds-247420 .cm-rb-label { flex: none; color: var(--fg-2); }
@@ -7109,7 +7610,7 @@
7109
7610
  color: inherit;
7110
7611
  font: inherit;
7111
7612
  font-weight: 600;
7112
- padding: 2px var(--space-2);
7613
+ padding: var(--space-hair) var(--space-2);
7113
7614
  border-radius: var(--r-1);
7114
7615
  cursor: pointer;
7115
7616
  }
@@ -7192,6 +7693,14 @@
7192
7693
  the glow's -4px bleed without overflowing the viewport edge. */
7193
7694
  .ds-247420 .vx-ptt-glow { inset: -4px 0; }
7194
7695
  }
7696
+ @media (max-height: 420px) {
7697
+ /* Phone-in-landscape: topbar + chat-head + user-identity bar alone can
7698
+ consume most of a ~320px-tall viewport, leaving no room for the fixed
7699
+ 120px .vx-ptt plus the voice grid above it -- shrink the PTT button so
7700
+ both remain visible instead of the label clipping off-screen. */
7701
+ .ds-247420 .vx-ptt { min-width: 88px; min-height: 64px; padding: var(--space-2); }
7702
+ .ds-247420 .vx-ptt-icon { font-size: var(--fs-lg); }
7703
+ }
7195
7704
  .ds-247420 .vx-ptt-recording, .ds-247420 .vx-ptt-live {
7196
7705
  background: var(--accent);
7197
7706
  color: var(--accent-fg);
@@ -7331,13 +7840,7 @@
7331
7840
  border-top: var(--bw-hair) solid var(--rule);
7332
7841
  }
7333
7842
  .ds-247420 .vx-section { display: flex; flex-direction: column; gap: var(--space-2); }
7334
- .ds-247420 .vx-section-label {
7335
- font-family: var(--ff-mono);
7336
- font-size: var(--fs-micro);
7337
- letter-spacing: var(--tr-label);
7338
- text-transform: uppercase;
7339
- color: var(--fg-3);
7340
- }
7843
+ /* Joins the small-label voice above with no overrides — it IS the plain voice. */
7341
7844
  .ds-247420 .vx-segmented { display: flex; gap: var(--space-1); }
7342
7845
  .ds-247420 .vx-seg {
7343
7846
  flex: 1;
@@ -7386,7 +7889,7 @@
7386
7889
  display: flex; gap: var(--space-2);
7387
7890
  overflow-x: auto;
7388
7891
  flex: 1;
7389
- padding-bottom: 2px;
7892
+ padding-bottom: var(--space-hair);
7390
7893
  }
7391
7894
  .ds-247420 .vx-chip {
7392
7895
  display: inline-flex; align-items: center; gap: var(--space-1);
@@ -7405,9 +7908,11 @@
7405
7908
  .ds-247420 .vx-chip-dot { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--fg-3); flex-shrink: 0; }
7406
7909
  .ds-247420 .vx-chip-name { font-weight: 600; }
7407
7910
  .ds-247420 .vx-chip-dur { font-family: var(--ff-mono); color: var(--fg-3); }
7911
+ /* Joins the small-label voice above. Deliberate overrides: --green + weight 700
7912
+ because this is the "LIVE" badge on a session chip, same signal role as
7913
+ .cm-vs-label. */
7408
7914
  .ds-247420 .vx-chip-tag {
7409
- font-family: var(--ff-mono); font-size: var(--fs-micro);
7410
- color: var(--green); font-weight: 700; letter-spacing: var(--tr-caps);
7915
+ color: var(--green); font-weight: 700;
7411
7916
  }
7412
7917
 
7413
7918
  /* VoiceControls — vx-vc-* */
@@ -7442,7 +7947,7 @@
7442
7947
  @media (max-width: 900px) {
7443
7948
  .ds-247420 .cm-thread-panel {
7444
7949
  position: absolute;
7445
- z-index: 20;
7950
+ z-index: calc(var(--z-drawer) + 1);
7446
7951
  top: 0; right: 0; bottom: 0;
7447
7952
  height: auto;
7448
7953
  width: min(320px, 90vw);
@@ -7463,7 +7968,7 @@
7463
7968
  .ds-247420 .cm-tp-list { flex: 1; min-height: 0; overflow-y: auto; }
7464
7969
  .ds-247420 .cm-tp-item {
7465
7970
  position: relative; /* anchors .cm-tp-dot to the row, not the panel */
7466
- display: flex; flex-direction: column; gap: 2px;
7971
+ display: flex; flex-direction: column; gap: var(--space-hair);
7467
7972
  width: 100%; text-align: left; cursor: pointer;
7468
7973
  padding: var(--space-2); border: none; background: transparent;
7469
7974
  border-bottom: var(--bw-hair) solid var(--rule);
@@ -7488,7 +7993,7 @@
7488
7993
  list surface in the kit uses one shimmer language, never a bare spinner. */
7489
7994
  .ds-247420 .cm-channel-item-skeleton, .ds-247420 .cm-member-item-skeleton {
7490
7995
  display: flex; align-items: center; gap: var(--space-2);
7491
- padding: var(--space-2); margin: 2px var(--space-1);
7996
+ padding: var(--space-2); margin: var(--space-hair) var(--space-1);
7492
7997
  }
7493
7998
  .ds-247420 .cm-channel-item-skeleton .ds-skel-icon, .ds-247420 .cm-member-item-skeleton .ds-skel-icon {
7494
7999
  width: 20px; height: 20px; border-radius: var(--r-round, 50%); flex: none; background: var(--bg-3);
@@ -7497,7 +8002,7 @@
7497
8002
  height: 12px; width: 60%; border-radius: var(--r-1); background: var(--bg-3);
7498
8003
  }
7499
8004
  .ds-247420 .cm-list-item-skeleton {
7500
- display: flex; flex-direction: column; gap: 6px;
8005
+ display: flex; flex-direction: column; gap: var(--space-1-75);
7501
8006
  padding: var(--space-2) var(--space-3); border-bottom: var(--bw-hair) solid var(--rule);
7502
8007
  }
7503
8008
  .ds-247420 .cm-list-item-skeleton .ds-skel-title { height: 12px; width: 55%; border-radius: var(--r-1); background: var(--bg-3); }
@@ -7529,8 +8034,10 @@
7529
8034
  .ds-247420 .cm-forum-item-replies { font-size: var(--fs-0, 12px); color: var(--fg-2, var(--fg)); opacity: .8; white-space: nowrap; }
7530
8035
  .ds-247420 .cm-forum-item-snippet { font-size: var(--fs-0, 12px); color: var(--fg-2, var(--fg)); opacity: .85; }
7531
8036
  .ds-247420 .cm-forum-item-meta { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; font-size: var(--fs-micro, 11px); color: var(--fg-2, var(--fg)); opacity: .7; }
7532
- .ds-247420 .cm-forum-item-tags { display: inline-flex; gap: 4px; }
7533
- .ds-247420 .cm-forum-tag { padding: 1px 6px; border-radius: var(--r-1); background: var(--bg-3); border: var(--bw-hair) solid var(--rule); }
8037
+ .ds-247420 .cm-forum-item-tags { display: inline-flex; gap: var(--space-1); }
8038
+ /* 1px vertical is OFF-SCALE ON PURPOSE the tag is an inline chip inside the
8039
+ forum meta row; --space-hair (2px) tips it past the row height. */
8040
+ .ds-247420 .cm-forum-tag { padding: 1px var(--space-1-75); border-radius: var(--r-1); background: var(--bg-3); border: var(--bw-hair) solid var(--rule); }
7534
8041
 
7535
8042
  /* PageView — cm-page / cm-page-* */
7536
8043
  .ds-247420 .cm-page { display: flex; flex-direction: column; height: 100%; min-height: 0; overflow-y: auto; background: var(--bg-1, var(--bg-2)); color: var(--fg); }
@@ -7557,6 +8064,9 @@
7557
8064
  .ds-247420 .fd-chat-thread { flex: 1 1 auto; min-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-2, 10px); padding: var(--space-2, 10px); }
7558
8065
  .ds-247420 .fd-page-error { white-space: pre-wrap; overflow-wrap: anywhere; }
7559
8066
  /* Visually-hidden polite live region — announces async busy/done to SR users. */
8067
+ /* margin:-1px is OFF-SCALE ON PURPOSE — the canonical visually-hidden idiom;
8068
+ the negative margin cancels the 1px box so the live region contributes zero
8069
+ layout. A --space-* rung would reintroduce a measurable gap. */
7560
8070
  .ds-247420 .fd-sr-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
7561
8071
  /* page-level responsive: tighten padding on narrow viewports */
7562
8072
  @media (max-width: 640px) {
@@ -7596,8 +8106,12 @@
7596
8106
  .ds-247420 .agentchat-controls .ds-select { min-width: 130px; max-width: 240px; }
7597
8107
  /* One shared control metric for the most-seen chrome row (mirrors the
7598
8108
  .ds-dash-toolbar precedent): selects, buttons, export acts all 32px / r-1. */
7599
- .ds-247420 .agentchat-controls .ds-select { min-height: 32px; padding: 4px 28px 4px 10px; font-size: var(--fs-sm); border-radius: var(--r-1); }
7600
- .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500; }
8109
+ /* The 28px right pad is OFF-SCALE ON PURPOSE: it is not rhythm but clearance
8110
+ for the native select's dropdown arrow, which the UA draws at a fixed inset.
8111
+ Snapping to --space-5 (32px) or --space-4 (24px) either wastes a column of
8112
+ text width or lets long option labels run under the arrow. */
8113
+ .ds-247420 .agentchat-controls .ds-select { min-height: 32px; padding: var(--space-1) 28px var(--space-1) var(--space-2-5); font-size: var(--fs-sm); border-radius: var(--r-1); }
8114
+ .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500; }
7601
8115
  @media (pointer: coarse) {
7602
8116
  .ds-247420 .agentchat-controls .ds-select, .ds-247420 .agentchat-controls .btn, .ds-247420 .agentchat-controls .btn-primary { min-height: 44px; }
7603
8117
  }
@@ -7617,6 +8131,12 @@
7617
8131
  .ds-247420 .agentchat-controls [role="combobox"] { flex-basis: 100%; }
7618
8132
  }
7619
8133
 
8134
+ /* The .4em/.5em gaps on this status line, .agentchat-head below, and the
8135
+ narrow-viewport .agentchat-controls override are em-based ON PURPOSE, not
8136
+ un-migrated literals: each is the gap between a label and its own inline
8137
+ text/disc, so it must track that element's font-size (these rows are scaled
8138
+ by font-size alone at narrow widths). A --space-* px rung would hold the gap
8139
+ fixed while the type around it shrank. */
7620
8140
  .ds-247420 .agentchat-status {
7621
8141
  display: inline-flex;
7622
8142
  align-items: center;
@@ -7667,7 +8187,7 @@
7667
8187
  border: 1px solid var(--rule);
7668
8188
  color: inherit;
7669
8189
  border-radius: var(--r-1);
7670
- padding: 2px 8px;
8190
+ padding: var(--space-hair) var(--space-2);
7671
8191
  cursor: pointer;
7672
8192
  font: inherit;
7673
8193
  }
@@ -7680,7 +8200,7 @@
7680
8200
  border: var(--bw-hair) solid var(--rule);
7681
8201
  color: var(--fg);
7682
8202
  border-radius: var(--r-1);
7683
- padding: 4px 8px;
8203
+ padding: var(--space-1) var(--space-2);
7684
8204
  font: inherit;
7685
8205
  }
7686
8206
  .ds-247420 .agentchat-cwd-input:focus-visible { outline: none; box-shadow: var(--focus-ring-inset); }
@@ -7693,12 +8213,12 @@
7693
8213
  .ds-247420 .agentchat-cwd-editing { flex-direction: column; align-items: stretch; }
7694
8214
  .ds-247420 .agentchat-cwd-row { display: flex; align-items: center; gap: var(--space-2, 8px); flex-wrap: wrap; }
7695
8215
  .ds-247420 .agentchat-cwd-roots, .ds-247420 .agentchat-cwd-recent {
7696
- display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
8216
+ display: flex; align-items: center; gap: var(--space-1-75); flex-wrap: wrap;
7697
8217
  }
7698
8218
  .ds-247420 .agentchat-cwd-recent-label { font-size: var(--fs-tiny); color: var(--fg-3); }
7699
8219
  .ds-247420 .agentchat-cwd-chip {
7700
8220
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
7701
- border-radius: var(--r-pill); padding: 3px 10px; font: inherit; font-size: var(--fs-tiny);
8221
+ border-radius: var(--r-pill); padding: var(--space-half) var(--space-2-5); font: inherit; font-size: var(--fs-tiny);
7702
8222
  cursor: pointer;
7703
8223
  }
7704
8224
  .ds-247420 .agentchat-cwd-chip:hover { border-color: var(--accent); color: var(--fg); }
@@ -7706,17 +8226,17 @@
7706
8226
  .ds-247420 .agentchat-cwd-browse {
7707
8227
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
7708
8228
  padding: var(--space-2, 8px); background: var(--bg-2);
7709
- display: flex; flex-direction: column; gap: 6px;
8229
+ display: flex; flex-direction: column; gap: var(--space-1-75);
7710
8230
  max-height: 220px;
7711
8231
  }
7712
8232
  .ds-247420 .agentchat-cwd-browse-list { overflow-y: auto; display: flex; flex-direction: column; max-height: 160px; }
7713
8233
  .ds-247420 .agentchat-cwd-browse-item {
7714
8234
  background: none; border: none; color: var(--fg-2); text-align: left;
7715
- padding: 6px 8px; border-radius: var(--r-1); font: inherit; font-size: var(--fs-tiny);
8235
+ padding: var(--space-1-75) var(--space-2); border-radius: var(--r-1); font: inherit; font-size: var(--fs-tiny);
7716
8236
  cursor: pointer;
7717
8237
  }
7718
8238
  .ds-247420 .agentchat-cwd-browse-item:hover, .ds-247420 .agentchat-cwd-browse-item:focus-visible { background: var(--bg-3, var(--bg)); color: var(--fg); }
7719
- .ds-247420 .agentchat-cwd-browse-loading, .ds-247420 .agentchat-cwd-browse-empty { padding: 6px 8px; font-size: var(--fs-tiny); color: var(--fg-3); }
8239
+ .ds-247420 .agentchat-cwd-browse-loading, .ds-247420 .agentchat-cwd-browse-empty { padding: var(--space-1-75) var(--space-2); font-size: var(--fs-tiny); color: var(--fg-3); }
7720
8240
 
7721
8241
  /* head + thread */
7722
8242
  .ds-247420 .agentchat-head {
@@ -7737,14 +8257,14 @@
7737
8257
  .ds-247420 .agentchat-side-panel { display: flex; flex-direction: column; height: 100%; min-height: 0; border-left: var(--bw-hair) solid var(--bg-3); }
7738
8258
  .ds-247420 .agentchat-side-panel-head {
7739
8259
  display: flex; align-items: center; justify-content: space-between;
7740
- padding: var(--space-2, 8px) var(--space-3, 12px); border-bottom: var(--bw-hair) solid var(--bg-3);
8260
+ padding: var(--space-2, 8px) var(--space-3, 16px); border-bottom: var(--bw-hair) solid var(--bg-3);
7741
8261
  flex: 0 0 auto;
7742
8262
  }
7743
8263
  .ds-247420 .agentchat-side-panel-title { font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-2); text-transform: uppercase; letter-spacing: var(--tr-label); }
7744
8264
  .ds-247420 .agentchat-side-panel-close {
7745
8265
  display: inline-flex; align-items: center; justify-content: center;
7746
8266
  background: none; border: none; color: var(--fg-3); cursor: pointer;
7747
- padding: 4px; border-radius: var(--r-1);
8267
+ padding: var(--space-1); border-radius: var(--r-1);
7748
8268
  }
7749
8269
  .ds-247420 .agentchat-side-panel-close:hover { background: var(--bg-2); color: var(--fg); }
7750
8270
  .ds-247420 .agentchat-side-panel-close:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
@@ -7768,8 +8288,11 @@
7768
8288
 
7769
8289
  /* Jump-to-latest: hidden until the thread scroll listener adds .show. */
7770
8290
  .ds-247420 .agentchat-jump {
7771
- position: absolute; right: 16px; bottom: 12px; z-index: 3;
8291
+ position: absolute; right: 16px; bottom: 12px; z-index: var(--z-raised);
7772
8292
  display: none; align-items: center; gap: .35em;
8293
+ /* em, not --space-*: this pill must scale with its own --fs-tiny text so the
8294
+ capsule stays proportional when a host overrides the chat font size. A px
8295
+ rung would fix the padding while the label grew/shrank inside it. */
7773
8296
  padding: .4em .8em; font: inherit; font-size: var(--fs-tiny); cursor: pointer;
7774
8297
  border-radius: var(--r-pill); border: var(--bw-hair) solid var(--rule);
7775
8298
  background: var(--bg-2); color: var(--fg-2, var(--fg));
@@ -7781,6 +8304,9 @@
7781
8304
 
7782
8305
  /* Streaming caret: a thin blinking bar at the live edge of an assistant turn. */
7783
8306
  .ds-247420 .chat-stream-caret {
8307
+ /* margin-left:1px is OFF-SCALE ON PURPOSE — a hairline optical nudge that
8308
+ separates the caret bar from the last glyph without reading as a space
8309
+ character. --space-hair (2px) is already wide enough to look like one. */
7784
8310
  display: inline-block; width: 2px; height: 1.05em; margin-left: 1px;
7785
8311
  vertical-align: text-bottom; background: var(--accent, var(--fg));
7786
8312
  animation: chat-caret-blink 1s step-end infinite;
@@ -7789,11 +8315,11 @@
7789
8315
  @media (prefers-reduced-motion: reduce) { .ds-247420 .chat-stream-caret { animation: none; opacity: .8; } }
7790
8316
 
7791
8317
  /* Per-message hover-revealed action row (copy / retry / edit). */
7792
- .ds-247420 .chat-msg-actions { display: flex; gap: 2px; margin-top: 3px; opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
8318
+ .ds-247420 .chat-msg-actions { display: flex; gap: var(--space-hair); margin-top: var(--space-half); opacity: 0; transition: opacity var(--dur-snap, .12s) var(--ease, ease); }
7793
8319
  .ds-247420 .chat-msg:hover .chat-msg-actions, .ds-247420 .chat-msg:focus-within .chat-msg-actions { opacity: 1; }
7794
8320
  .ds-247420 .chat-msg-action {
7795
- display: inline-flex; align-items: center; justify-content: center; gap: 4px;
7796
- min-width: 26px; height: 26px; padding: 0 6px; cursor: pointer;
8321
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
8322
+ min-width: 26px; height: 26px; padding: 0 var(--space-1-75); cursor: pointer;
7797
8323
  border: none; border-radius: var(--r-1, 4px); background: none; color: var(--fg-3);
7798
8324
  font-family: var(--ff-body); font-size: var(--fs-tiny);
7799
8325
  }
@@ -7802,7 +8328,12 @@
7802
8328
  .ds-247420 .chat-msg-action:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; opacity: 1; }
7803
8329
  .ds-247420 .chat-msg-action.is-copied { color: var(--accent-ink); opacity: 1; }
7804
8330
 
7805
- /* Empty state: a fresh thread is an invitation, not a void. */
8331
+ /* Empty state: a fresh thread is an invitation, not a void.
8332
+ The em-based gap/padding through this block and the suggestion chips below
8333
+ are OFF the --space-* px scale ON PURPOSE: the empty state is typeset copy
8334
+ whose rhythm must track its own font-size (hosts scale this panel down on
8335
+ narrow viewports via font-size alone). Fixed px rungs here would decouple
8336
+ the chip padding from the label and break the capsule proportions. */
7806
8337
  .ds-247420 .agentchat-empty {
7807
8338
  margin: auto;
7808
8339
  display: flex;
@@ -7866,7 +8397,7 @@
7866
8397
  font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-2, var(--fg));
7867
8398
  }
7868
8399
  .ds-247420 .agentchat-install-copy {
7869
- flex: 0 0 auto; cursor: pointer; padding: 2px 8px; min-height: 24px;
8400
+ flex: 0 0 auto; cursor: pointer; padding: var(--space-hair) var(--space-2); min-height: 24px;
7870
8401
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
7871
8402
  background: none; color: var(--fg-3);
7872
8403
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -7877,7 +8408,7 @@
7877
8408
 
7878
8409
  /* Host-supplied transcript export actions riding the controls row. */
7879
8410
  .ds-247420 .agentchat-export-act {
7880
- cursor: pointer; padding: 4px 10px; min-height: 32px;
8411
+ cursor: pointer; padding: var(--space-1) var(--space-2-5); min-height: 32px;
7881
8412
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
7882
8413
  background: none; color: var(--fg-3);
7883
8414
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -7885,7 +8416,10 @@
7885
8416
  .ds-247420 .agentchat-export-act:hover { background: var(--bg-2); color: var(--fg); }
7886
8417
  .ds-247420 .agentchat-export-act:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; }
7887
8418
 
7888
- /* "working" tail: a long silent tool call shouldn't read as frozen. */
8419
+ /* "working" tail: a long silent tool call shouldn't read as frozen.
8420
+ em gap/padding here and on .chat-thinking below is deliberate — both tails
8421
+ are inline status text sized off --fs-tiny, and their inset must shrink with
8422
+ the type, not sit on a fixed px rung. */
7889
8423
  .ds-247420 .agentchat-working {
7890
8424
  display: flex;
7891
8425
  align-items: center;
@@ -7897,7 +8431,7 @@
7897
8431
  .ds-247420 .agentchat-working-text { color: var(--fg-3); }
7898
8432
  /* Self-contained dots (chat-thinking-dots lives in a kit sheet not bundled
7899
8433
  into this DS distribution, so the agentchat tail draws its own). */
7900
- .ds-247420 .agentchat-working .chat-thinking-dots { display: inline-flex; gap: 3px; }
8434
+ .ds-247420 .agentchat-working .chat-thinking-dots { display: inline-flex; gap: var(--space-half); }
7901
8435
  .ds-247420 .agentchat-working .chat-thinking-dots span {
7902
8436
  width: 5px; height: 5px; border-radius: 50%;
7903
8437
  background: var(--fg); opacity: .4;
@@ -7918,7 +8452,7 @@
7918
8452
  no muted tone. Reuse the agentchat-dot-bounce keyframe. */
7919
8453
  .ds-247420 .chat-thinking { display: flex; align-items: center; gap: .5em; color: var(--fg-3); font-size: var(--fs-tiny); background: none; padding: .3em .2em; }
7920
8454
  .ds-247420 .chat-thinking-text { color: var(--fg-3); }
7921
- .ds-247420 .chat-thinking-dots { display: inline-flex; gap: 3px; }
8455
+ .ds-247420 .chat-thinking-dots { display: inline-flex; gap: var(--space-half); }
7922
8456
  .ds-247420 .chat-thinking-dots span {
7923
8457
  width: 5px; height: 5px; border-radius: 50%;
7924
8458
  background: var(--fg); opacity: .4;
@@ -8018,7 +8552,7 @@
8018
8552
  .ds-247420 .ds-session-new:hover { background: var(--bg-2); color: var(--fg); }
8019
8553
  /* Rail filter uses the shared .ds-search-input primitive (provides bg/border/
8020
8554
  radius/focus-ring); only the rail layout + touch floor live here. */
8021
- .ds-247420 .ds-session-head .ds-search-input { order: 1; flex: 1 1 auto; min-width: 0; min-height: 36px; padding: 0 10px; }
8555
+ .ds-247420 .ds-session-head .ds-search-input { order: 1; flex: 1 1 auto; min-width: 0; min-height: 36px; padding: 0 var(--space-2-5); }
8022
8556
  .ds-247420 .ds-session-new:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
8023
8557
  /* Touch floor (must FOLLOW the base rules - same specificity, order decides). */
8024
8558
  @media (pointer: coarse) {
@@ -8027,7 +8561,7 @@
8027
8561
  }
8028
8562
  .ds-247420 .ds-session-list, .ds-247420 .ds-session-groups { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-2); }
8029
8563
  .ds-247420 .ds-session-loadmore {
8030
- width: 100%; margin-top: var(--space-1); padding: 8px 12px;
8564
+ width: 100%; margin-top: var(--space-1); padding: var(--space-2) var(--space-2-75);
8031
8565
  font-size: var(--fs-sm); font-family: inherit; color: var(--fg-3);
8032
8566
  background: none; border: var(--bw-hair) dashed var(--rule); border-radius: var(--r-1);
8033
8567
  cursor: pointer; text-align: center;
@@ -8038,11 +8572,11 @@
8038
8572
  /* Grouped rows (Today/Yesterday/...) lay out like the flat list; the section
8039
8573
  label sticks to the top of the scroll area for Claude-Desktop-style headers. */
8040
8574
  .ds-247420 .ds-session-group { display: flex; flex-direction: column; }
8041
- .ds-247420 .ds-session-group-rows { display: flex; flex-direction: column; gap: 2px; }
8042
- .ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: 1; background: var(--bg-1, var(--bg)); font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-label); padding: var(--space-2) var(--space-2) var(--space-1); }
8575
+ .ds-247420 .ds-session-group-rows { display: flex; flex-direction: column; gap: var(--space-hair); }
8576
+ .ds-247420 .ds-session-group-label { position: sticky; top: 0; z-index: var(--z-sticky); background: var(--bg-1, var(--bg)); font-size: var(--fs-tiny); font-weight: 600; color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-label); padding: var(--space-2) var(--space-2) var(--space-1); }
8043
8577
  .ds-247420 .ds-session-row {
8044
8578
  position: relative; display: flex; align-items: center; gap: var(--space-2);
8045
- width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
8579
+ width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: var(--space-hair);
8046
8580
  background: transparent; border: none; border-radius: var(--r-1);
8047
8581
  cursor: pointer; text-align: left; color: var(--fg);
8048
8582
  }
@@ -8057,7 +8591,7 @@
8057
8591
  .ds-247420 .ds-session-row.rail-green::before { background: var(--accent-ink); }
8058
8592
  .ds-247420 .ds-session-row.rail-purple::before { background: var(--purple-2); }
8059
8593
  .ds-247420 .ds-session-row.rail-flame::before { background: var(--flame); }
8060
- .ds-247420 .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
8594
+ .ds-247420 .ds-session-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-hair); }
8061
8595
  .ds-247420 .ds-session-title { font-size: var(--fs-sm); color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
8062
8596
  .ds-247420 .ds-session-sub { font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
8063
8597
  .ds-247420 .ds-session-meta { display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; }
@@ -8127,7 +8661,7 @@
8127
8661
  it only goes loud while ARMED (the one-shot press-again confirm). */
8128
8662
  .ds-247420 .ds-dash-header .btn, .ds-247420 .ds-dash-header .btn-primary {
8129
8663
  margin-left: 0;
8130
- padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
8664
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500;
8131
8665
  }
8132
8666
  .ds-247420 .ds-dash-header .btn-primary.danger {
8133
8667
  background: transparent; color: var(--warn);
@@ -8148,7 +8682,7 @@
8148
8682
  .ds-247420 .ds-dash-status.is-error { color: var(--flame); }
8149
8683
  .ds-247420 .ds-dash-agent { font-size: var(--fs-body); font-weight: 600; color: var(--fg); }
8150
8684
  .ds-247420 .ds-dash-model { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); margin-left: auto; }
8151
- .ds-247420 .ds-dash-meta { display: flex; flex-direction: column; gap: 2px; }
8685
+ .ds-247420 .ds-dash-meta { display: flex; flex-direction: column; gap: var(--space-hair); }
8152
8686
  .ds-247420 .ds-dash-cwd { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
8153
8687
  .ds-247420 .ds-dash-stat { font-family: var(--ff-mono); font-size: var(--fs-tiny); color: var(--fg-2); }
8154
8688
  .ds-247420 .ds-dash-stat-cost { color: var(--fg); font-weight: 600; }
@@ -8179,7 +8713,7 @@
8179
8713
  letter-spacing: var(--tr-caps); text-transform: uppercase;
8180
8714
  padding: 0 0 var(--space-2);
8181
8715
  }
8182
- .ds-247420 .ds-context-group .row + .row { margin-top: 2px; }
8716
+ .ds-247420 .ds-context-group .row + .row { margin-top: var(--space-hair); }
8183
8717
 
8184
8718
  /* ============================================================================
8185
8719
  Cohesion sweep (gui-cohesion.js): one-product polish across surfaces.
@@ -8193,7 +8727,7 @@
8193
8727
  .ds-247420 .chat-code-copy {
8194
8728
  position: absolute; top: 6px; right: 6px;
8195
8729
  display: inline-flex; align-items: center; justify-content: center;
8196
- min-width: 48px; min-height: 24px; padding: 2px 8px;
8730
+ min-width: 48px; min-height: 24px; padding: var(--space-hair) var(--space-2);
8197
8731
  border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1, 4px);
8198
8732
  background: var(--bg-2); color: var(--fg-2); cursor: pointer;
8199
8733
  font-family: var(--ff-body); font-size: var(--fs-tiny);
@@ -8236,7 +8770,7 @@
8236
8770
 
8237
8771
  /* --- A5: composer context line (agent / model / cwd at point of typing). --- */
8238
8772
  .ds-247420 .chat-composer-context {
8239
- display: block; width: 100%; text-align: left; padding: 4px var(--space-3) 0;
8773
+ display: block; width: 100%; text-align: left; padding: var(--space-1) var(--space-3) 0;
8240
8774
  background: none; border: none; cursor: default; color: var(--fg-3);
8241
8775
  font-family: var(--ff-mono); font-size: var(--fs-tiny);
8242
8776
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
@@ -8278,11 +8812,11 @@
8278
8812
  height, never a stacked full-width form column. */
8279
8813
  .ds-247420 .ds-dash-toolbar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
8280
8814
  .ds-247420 .ds-dash-toolbar .ds-search-input {
8281
- width: 200px; min-height: 32px; padding: 5px 10px;
8815
+ width: 200px; min-height: 32px; padding: var(--space-1-5) var(--space-2-5);
8282
8816
  font-size: var(--fs-sm); border-radius: var(--r-1);
8283
8817
  }
8284
8818
  .ds-247420 .ds-dash-toolbar .ds-select, .ds-247420 .ds-dash-toolbar select {
8285
- min-height: 32px; padding: 4px 10px; font-size: var(--fs-sm);
8819
+ min-height: 32px; padding: var(--space-1) var(--space-2-5); font-size: var(--fs-sm);
8286
8820
  width: auto; border-radius: var(--r-1);
8287
8821
  }
8288
8822
  .ds-247420 .ds-dash-stream { font-size: var(--fs-tiny); color: var(--fg-3); }
@@ -8291,7 +8825,7 @@
8291
8825
  .ds-247420 .ds-dash-stream.is-connecting { color: var(--amber); }
8292
8826
  .ds-247420 .ds-dash-header .spread { flex: 1; }
8293
8827
  .ds-247420 .ds-dash-errors-toggle {
8294
- padding: 4px 10px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
8828
+ padding: var(--space-1) var(--space-2-5); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
8295
8829
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2);
8296
8830
  cursor: pointer; font-family: var(--ff-body); font-size: var(--fs-tiny);
8297
8831
  }
@@ -8334,14 +8868,14 @@
8334
8868
  .ds-247420 .ds-preview-code-wrap { display: flex; flex-direction: column; min-height: 0; }
8335
8869
  .ds-247420 .ds-preview-code-head { flex: 0 0 auto; }
8336
8870
  /* --- E2: prev/next stepper in preview head. --- */
8337
- .ds-247420 .ds-preview-step { display: inline-flex; gap: 2px; }
8338
- .ds-247420 .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 6px; font-family: var(--ff-body); font-size: var(--fs-tiny); }
8871
+ .ds-247420 .ds-preview-step { display: inline-flex; gap: var(--space-hair); }
8872
+ .ds-247420 .ds-preview-step .ds-file-act { min-width: 40px; padding: 0 var(--space-1-75); font-family: var(--ff-body); font-size: var(--fs-tiny); }
8339
8873
 
8340
8874
  /* --- D1: file grid "show more" row. --- */
8341
8875
  .ds-247420 .ds-file-more { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); justify-content: center; }
8342
8876
  .ds-247420 .ds-file-more-count { font-size: var(--fs-tiny); color: var(--fg-3); }
8343
8877
  .ds-247420 .ds-file-more-btn {
8344
- padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
8878
+ padding: var(--space-1) var(--space-2-75); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
8345
8879
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
8346
8880
  font-family: var(--ff-body); font-size: var(--fs-tiny);
8347
8881
  }
@@ -8350,9 +8884,9 @@
8350
8884
  .ds-247420 .ds-file-row.is-locked { opacity: .6; }
8351
8885
 
8352
8886
  /* --- D4: roots picker segmented control. --- */
8353
- .ds-247420 .ds-roots-picker { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-2); border-radius: var(--r-1); }
8887
+ .ds-247420 .ds-roots-picker { display: inline-flex; gap: var(--space-hair); padding: var(--space-hair); background: var(--bg-2); border-radius: var(--r-1); }
8354
8888
  .ds-247420 .ds-roots-tab {
8355
- padding: 4px 10px; min-height: 32px; border: none; border-radius: var(--r-1);
8889
+ padding: var(--space-1) var(--space-2-5); min-height: 32px; border: none; border-radius: var(--r-1);
8356
8890
  background: none; color: var(--fg-3); cursor: pointer;
8357
8891
  font-family: var(--ff-body); font-size: var(--fs-tiny);
8358
8892
  }
@@ -8386,7 +8920,7 @@
8386
8920
  .ds-247420 .ds-session-meta-label { color: var(--fg-3); }
8387
8921
  .ds-247420 .ds-session-meta-value { font-family: var(--ff-mono); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
8388
8922
  .ds-247420 .ds-session-meta-copy, .ds-247420 .ds-session-meta-action {
8389
- padding: 2px 8px; min-height: 24px; cursor: pointer;
8923
+ padding: var(--space-hair) var(--space-2); min-height: 24px; cursor: pointer;
8390
8924
  background: var(--bg-2); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-1);
8391
8925
  color: var(--fg-3); font-family: var(--ff-body); font-size: var(--fs-micro);
8392
8926
  }
@@ -8405,7 +8939,7 @@
8405
8939
  can discover Enter-vs-Shift+Enter without having to focus it first;
8406
8940
  hidden under 420px to save rows. */
8407
8941
  .ds-247420 .chat-composer-hint {
8408
- display: block; width: 100%; order: 5; padding: 2px var(--space-1) 0;
8942
+ display: block; width: 100%; order: 5; padding: var(--space-hair) var(--space-1) 0;
8409
8943
  font-size: var(--fs-micro); color: var(--fg-3);
8410
8944
  }
8411
8945
  @media (max-width: 420px) {
@@ -8414,13 +8948,13 @@
8414
8948
 
8415
8949
  /* Transient composer note (paste/drop not supported), aria-live polite. */
8416
8950
  .ds-247420 .chat-composer-note {
8417
- padding: 4px var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
8951
+ padding: var(--space-1) var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
8418
8952
  }
8419
8953
 
8420
8954
  /* Streaming elapsed-time counter: ticks m:ss while a turn is in flight.
8421
8955
  Tabular-nums so the digits don't jitter the layout every second. */
8422
8956
  .ds-247420 .chat-composer-elapsed {
8423
- order: 5; padding: 2px var(--space-1) 0;
8957
+ order: 5; padding: var(--space-hair) var(--space-1) 0;
8424
8958
  font-size: var(--fs-micro); color: var(--fg-3);
8425
8959
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum';
8426
8960
  }
@@ -8430,7 +8964,7 @@
8430
8964
  new chrome. */
8431
8965
  .ds-247420 .chat-composer-detected-badge {
8432
8966
  display: flex; align-items: center; gap: var(--space-2, 8px);
8433
- padding: 4px var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
8967
+ padding: var(--space-1) var(--space-3); font-size: var(--fs-tiny); color: var(--fg-2);
8434
8968
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
8435
8969
  border-radius: var(--r-1); width: 100%; order: -1;
8436
8970
  }
@@ -8438,7 +8972,7 @@
8438
8972
  .ds-247420 .chat-composer-detected-dismiss {
8439
8973
  flex: 0 0 auto; background: none; border: none; cursor: pointer;
8440
8974
  color: var(--fg-3); font: inherit; font-size: var(--fs-tiny);
8441
- padding: 2px 6px; border-radius: var(--r-1);
8975
+ padding: var(--space-hair) var(--space-1-75); border-radius: var(--r-1);
8442
8976
  }
8443
8977
  .ds-247420 .chat-composer-detected-dismiss:hover { color: var(--fg); }
8444
8978
  .ds-247420 .chat-composer-detected-dismiss:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
@@ -8491,7 +9025,7 @@
8491
9025
  /* Out-of-band turn notices: neutral tone (NOT error red) — a stopped or
8492
9026
  incomplete turn must not read as a finished answer. */
8493
9027
  .ds-247420 .chat-msg-notice {
8494
- margin-top: var(--space-1); padding: 6px 10px;
9028
+ margin-top: var(--space-1); padding: var(--space-1-75) var(--space-2-5);
8495
9029
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-2);
8496
9030
  background: var(--bg-2); color: var(--fg-2); font-size: var(--fs-tiny);
8497
9031
  }
@@ -8506,14 +9040,14 @@
8506
9040
  .ds-247420 .chat-msg-retry-btn {
8507
9041
  border: var(--bw-hair) solid var(--danger); border-radius: var(--r-1);
8508
9042
  background: transparent; color: var(--danger-ink, var(--danger));
8509
- font: inherit; font-size: var(--fs-tiny); padding: 2px 10px; cursor: pointer;
9043
+ font: inherit; font-size: var(--fs-tiny); padding: var(--space-hair) var(--space-2-5); cursor: pointer;
8510
9044
  }
8511
9045
  .ds-247420 .chat-msg-retry-btn:hover { background: var(--danger); color: var(--bg); }
8512
9046
  .ds-247420 .chat-msg-retry-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
8513
9047
 
8514
9048
  /* Tail-window streaming head ('streaming · N KB so far'). */
8515
9049
  .ds-247420 .chat-stream-head {
8516
- padding: 2px 0 6px; font-family: var(--ff-mono);
9050
+ padding: var(--space-hair) 0 var(--space-1-75); font-family: var(--ff-mono);
8517
9051
  font-size: var(--fs-micro); color: var(--fg-3);
8518
9052
  }
8519
9053
 
@@ -8524,7 +9058,7 @@
8524
9058
  }
8525
9059
  .ds-247420 .agentchat-earlier-count { font-size: var(--fs-tiny); color: var(--fg-3); }
8526
9060
  .ds-247420 .agentchat-earlier-btn {
8527
- padding: 4px 12px; min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
9061
+ padding: var(--space-1) var(--space-2-75); min-height: 32px; border: var(--bw-hair) solid var(--bg-3);
8528
9062
  border-radius: var(--r-1); background: var(--bg-2); color: var(--fg-2); cursor: pointer;
8529
9063
  font-family: var(--ff-body); font-size: var(--fs-tiny);
8530
9064
  }
@@ -8550,7 +9084,10 @@
8550
9084
 
8551
9085
  /* External (observed, not owned) session card: no stop control exists. */
8552
9086
  .ds-247420 .ds-dash-external {
8553
- padding: 1px 6px; border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-pill);
9087
+ /* 1px vertical is OFF-SCALE ON PURPOSE — a --fs-micro uppercase pill whose
9088
+ height must stay inside the card's meta row. --space-hair (2px) tips it
9089
+ past the row and pushes the card taller. Horizontal snaps normally. */
9090
+ padding: 1px var(--space-1-75); border: var(--bw-hair) solid var(--bg-3); border-radius: var(--r-pill);
8554
9091
  font-size: var(--fs-micro); color: var(--fg-3); text-transform: uppercase; letter-spacing: var(--tr-caps);
8555
9092
  }
8556
9093
  .ds-247420 .ds-dash-card.is-external { border-style: dashed; }
@@ -8589,11 +9126,18 @@
8589
9126
  .ds-247420 .chat-msg-flat .chat-role { margin-bottom: var(--space-2); }
8590
9127
  .ds-247420 .chat-msg-flat .chat-md { line-height: var(--lh-long); }
8591
9128
  .ds-247420 .chat-msg-flat .chat-md p { margin: var(--space-2) 0; }
9129
+ /* The `+ 2px` is an OFF-SCALE optical correction, not a rhythm step: the tinted
9130
+ assistant row needs marginally more inset than the untinted .you row so the
9131
+ fill does not appear to crowd the text. Expressing it as a --space-* rung
9132
+ would make it a visible step rather than the sub-perceptual nudge intended. */
8592
9133
  .ds-247420 .chat-msg-flat.them { padding-block: calc(var(--space-3) * var(--density, 1) + 2px); }
8593
9134
  /* Inline backtick code (renderInline tags <code class=chat-tick>) - was a dead
8594
9135
  class relying on the generic .chat-bubble code rule, so notices / non-bubble
8595
9136
  surfaces got unstyled monospace. Self-style it regardless of container. */
8596
- .ds-247420 .chat-tick { font-family: var(--ff-mono); font-size: .92em; background: color-mix(in oklab, var(--fg) 10%, transparent); padding: 1px 6px; border-radius: var(--r-1); }
9137
+ /* 1px vertical is OFF-SCALE ON PURPOSE inline code sits INSIDE a line of running
9138
+ prose; any larger vertical pad makes the tinted box overlap the lines above and
9139
+ below. Horizontal is on the scale. */
9140
+ .ds-247420 .chat-tick { font-family: var(--ff-mono); font-size: .92em; background: color-mix(in oklab, var(--fg) 10%, transparent); padding: 1px var(--space-1-75); border-radius: var(--r-1); }
8597
9141
  /* Structured tool/code output earns more width than running prose (claude.ai/code
8598
9142
  lets diffs/tables break out wider than the reading measure). A flat turn that
8599
9143
  contains a tool card or code block widens itself AND its stack past --measure;
@@ -8645,7 +9189,7 @@
8645
9189
  margin-left: auto; flex: 0 0 auto;
8646
9190
  font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: var(--tr-caps);
8647
9191
  color: var(--fg-3);
8648
- padding: 2px var(--space-2); border-radius: var(--r-pill);
9192
+ padding: var(--space-hair) var(--space-2); border-radius: var(--r-pill);
8649
9193
  background: color-mix(in oklab, var(--fg) 6%, transparent);
8650
9194
  }
8651
9195
  .ds-247420 .chat-msg .chat-tool.tool-running .chat-tool-status { color: var(--accent-ink); background: color-mix(in oklab, var(--accent) 12%, transparent); }
@@ -8673,8 +9217,8 @@
8673
9217
  structured CodeNode). injectCodeCopy reads the language- class. */
8674
9218
  .ds-247420 .chat-code-block { position: relative; }
8675
9219
  .ds-247420 .chat-code-lang {
8676
- position: absolute; top: 0; left: 0; z-index: 2;
8677
- padding: 2px var(--space-2); border-bottom-right-radius: var(--r-1);
9220
+ position: absolute; top: 0; left: 0; z-index: var(--z-raised);
9221
+ padding: var(--space-hair) var(--space-2); border-bottom-right-radius: var(--r-1);
8678
9222
  font-family: var(--ff-mono); font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tr-caps);
8679
9223
  color: var(--fg-3); background: color-mix(in oklab, var(--fg) 6%, transparent);
8680
9224
  pointer-events: none;
@@ -8734,7 +9278,7 @@
8734
9278
  .ds-247420 .ds-dash-clear:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: 1px; border-radius: var(--r-1); }
8735
9279
 
8736
9280
  /* Conversation-rail loading skeleton (cold ccsniff walk). */
8737
- .ds-247420 .ds-session-row-skeleton { display: flex; flex-direction: column; gap: 6px; padding: var(--space-2) var(--space-3); }
9281
+ .ds-247420 .ds-session-row-skeleton { display: flex; flex-direction: column; gap: var(--space-1-75); padding: var(--space-2) var(--space-3); }
8738
9282
  .ds-247420 .ds-session-row-skeleton .ds-skel { background: var(--bg-3); border-radius: var(--r-1); }
8739
9283
  .ds-247420 .ds-session-row-skeleton .ds-skel-title { height: 12px; width: 70%; }
8740
9284
  .ds-247420 .ds-session-row-skeleton .ds-skel-meta { height: 9px; width: 45%; }
@@ -8785,7 +9329,7 @@
8785
9329
  Hover/focus/active-state rules on the originals still apply.
8786
9330
  ---------------------------------------------------------------------------- */
8787
9331
  .ds-247420 .row-act, .ds-247420 .ds-dash-errors-toggle, .ds-247420 .agentchat-export-act, .ds-247420 .ds-file-more-btn {
8788
- min-height: 32px; padding: 5px 12px; border-radius: var(--r-1);
9332
+ min-height: 32px; padding: var(--space-1-5) var(--space-2-75); border-radius: var(--r-1);
8789
9333
  font-family: var(--ff-body); font-size: var(--fs-tiny); font-weight: 500;
8790
9334
  background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
8791
9335
  cursor: pointer;
@@ -8794,7 +9338,7 @@
8794
9338
  background: var(--bg-2); color: var(--fg);
8795
9339
  }
8796
9340
  .ds-247420 .agentchat-install-copy, .ds-247420 .ds-upload-act, .ds-247420 .ds-session-meta-copy {
8797
- min-height: 24px; padding: 2px 8px; border-radius: var(--r-1);
9341
+ min-height: 24px; padding: var(--space-hair) var(--space-2); border-radius: var(--r-1);
8798
9342
  font-family: var(--ff-body); font-size: var(--fs-tiny);
8799
9343
  background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-3);
8800
9344
  cursor: pointer;
@@ -8848,7 +9392,10 @@
8848
9392
  border-top: var(--bw-hair) solid var(--rule);
8849
9393
  border-bottom: var(--bw-hair) solid var(--rule);
8850
9394
  pointer-events: none;
8851
- z-index: 1;
9395
+ /* Minimap internal order: centerline < viewport < dot < tooltip. All four
9396
+ live inside the one raised widget, so they share its rung and differ
9397
+ only by a local offset. */
9398
+ z-index: calc(var(--z-raised) + 1);
8852
9399
  }
8853
9400
  .ds-247420 .chat-minimap-centerline {
8854
9401
  position: absolute;
@@ -8858,7 +9405,7 @@
8858
9405
  width: 1px;
8859
9406
  background: var(--rule);
8860
9407
  transform: translateX(-50%);
8861
- z-index: 0;
9408
+ z-index: var(--z-raised);
8862
9409
  }
8863
9410
  .ds-247420 .chat-minimap-dot {
8864
9411
  position: absolute;
@@ -8868,7 +9415,7 @@
8868
9415
  border-radius: var(--r-pill, 999px);
8869
9416
  transform: translate(-50%, -50%) scale(1);
8870
9417
  transition: transform 0.1s;
8871
- z-index: 2;
9418
+ z-index: calc(var(--z-raised) + 2);
8872
9419
  }
8873
9420
  .ds-247420 .chat-minimap-dot.is-user {
8874
9421
  background: color-mix(in oklab, var(--accent) 18%, transparent);
@@ -8890,7 +9437,10 @@
8890
9437
  border-left: 2px solid var(--fg-3);
8891
9438
  border-radius: var(--r-1);
8892
9439
  padding: calc(var(--space-1) / 2) var(--space-2);
8893
- z-index: 100;
9440
+ /* Top of the minimap's internal order. Deliberately NOT --z-tooltip: it is
9441
+ clipped to the minimap rail rather than floating over the app, so it must
9442
+ not outrank real overlays that may cover the rail. */
9443
+ z-index: calc(var(--z-raised) + 3);
8894
9444
  pointer-events: none;
8895
9445
  opacity: 0.45;
8896
9446
  font-size: var(--fs-tiny);
@@ -8928,8 +9478,8 @@
8928
9478
  }
8929
9479
  .ds-247420 .ds-ep-panel-head {
8930
9480
  flex-shrink: 0;
8931
- display: flex; align-items: center; justify-content: space-between; gap: 8px;
8932
- padding: 6px 10px;
9481
+ display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
9482
+ padding: var(--space-1-75) var(--space-2-5);
8933
9483
  border-bottom: 1px solid var(--rule);
8934
9484
  font-size: var(--fs-micro, 11px); font-weight: 600;
8935
9485
  text-transform: uppercase; letter-spacing: 0.1em;
@@ -8943,7 +9493,7 @@
8943
9493
  }
8944
9494
  .ds-247420 .ds-ep-panel-body {
8945
9495
  flex: 1; min-height: 0; overflow: auto;
8946
- padding: 6px 8px;
9496
+ padding: var(--space-1-75) var(--space-2);
8947
9497
  }
8948
9498
  .ds-247420 .ds-ep-panel-body.flush { padding: 0; }
8949
9499
  /* A sub-section divider inside a docked panel (e.g. app-prop mount). Only
@@ -8959,36 +9509,36 @@
8959
9509
  /* Dense status strip for editor chrome — thin, flush, bordered top. */
8960
9510
  .ds-247420 .ds-ep-statusbar {
8961
9511
  flex-shrink: 0;
8962
- display: flex; align-items: center; justify-content: space-between; gap: 8px;
9512
+ display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
8963
9513
  min-height: 0; height: 26px;
8964
- padding: 0 10px;
9514
+ padding: 0 var(--space-2-5);
8965
9515
  border-top: 1px solid var(--rule);
8966
9516
  background: var(--panel-1);
8967
9517
  color: var(--panel-text-2);
8968
9518
  font: var(--fs-micro, 11px)/1 var(--ff-mono, monospace);
8969
9519
  }
8970
- .ds-247420 .ds-ep-statusbar-left, .ds-247420 .ds-ep-statusbar-right { display: flex; align-items: center; gap: 8px; min-width: 0; }
9520
+ .ds-247420 .ds-ep-statusbar-left, .ds-247420 .ds-ep-statusbar-right { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
8971
9521
  .ds-247420 .ds-ep-statusbar-left { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
8972
9522
  /* Buttons inside the dense strip shrink to fit the 26px band. */
8973
9523
  .ds-247420 .ds-ep-statusbar button {
8974
- min-height: 0; height: 20px; padding: 0 8px;
9524
+ min-height: 0; height: 20px; padding: 0 var(--space-2);
8975
9525
  border-radius: var(--r-1, 4px);
8976
9526
  font: var(--fs-micro, 11px)/1 var(--ff-mono, monospace);
8977
9527
  }
8978
9528
 
8979
9529
  /* Toolbar */
8980
9530
  .ds-247420 .ds-ep-toolbar {
8981
- display: flex; align-items: center; gap: 6px;
8982
- padding: 8px 10px;
9531
+ display: flex; align-items: center; gap: var(--space-1-75);
9532
+ padding: var(--space-2) var(--space-2-5);
8983
9533
  background: var(--panel-1);
8984
9534
  color: var(--panel-text);
8985
9535
  border-bottom: 1px solid var(--rule);
8986
9536
  font: var(--fs-tiny, 12px)/var(--lh-base, 1.55) var(--ff-mono, monospace);
8987
9537
  }
8988
- .ds-247420 .ds-ep-toolbar.dense { padding: 2px 4px; gap: 2px; }
9538
+ .ds-247420 .ds-ep-toolbar.dense { padding: var(--space-hair) var(--space-1); gap: var(--space-hair); }
8989
9539
  .ds-247420 .ds-ep-toolbar-leading,
8990
9540
  .ds-247420 .ds-ep-toolbar-center,
8991
- .ds-247420 .ds-ep-toolbar-trailing { display: flex; align-items: center; gap: 4px; }
9541
+ .ds-247420 .ds-ep-toolbar-trailing { display: flex; align-items: center; gap: var(--space-1); }
8992
9542
  .ds-247420 .ds-ep-toolbar-trailing { margin-left: auto; }
8993
9543
  .ds-247420 .ds-ep-toolbar-center { flex: 1; min-width: 0; }
8994
9544
 
@@ -9058,7 +9608,7 @@
9058
9608
  flex: 1; min-width: 0; appearance: none; background: transparent; border: 0;
9059
9609
  border-bottom: 2px solid transparent;
9060
9610
  color: var(--panel-text-3);
9061
- padding: 8px 10px;
9611
+ padding: var(--space-2) var(--space-2-5);
9062
9612
  font: inherit; cursor: pointer;
9063
9613
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
9064
9614
  transition: color var(--dur-snap, 80ms) var(--ease, ease), border-color var(--dur-snap, 80ms) var(--ease, ease);
@@ -9097,8 +9647,8 @@
9097
9647
  color: var(--panel-text);
9098
9648
  }
9099
9649
  .ds-247420 .ds-ep-eventrow {
9100
- display: flex; align-items: baseline; gap: 8px;
9101
- padding: 3px 8px;
9650
+ display: flex; align-items: baseline; gap: var(--space-2);
9651
+ padding: var(--space-half) var(--space-2);
9102
9652
  border-bottom: 1px solid color-mix(in oklab, var(--rule) 50%, transparent);
9103
9653
  }
9104
9654
  .ds-247420 .ds-ep-eventrow:hover { background: color-mix(in oklab, var(--accent) 6%, transparent); }
@@ -9115,8 +9665,8 @@
9115
9665
  .ds-247420 .ds-ep-tree-item { display: flex; flex-direction: column; }
9116
9666
  .ds-247420 .ds-ep-tree-item:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
9117
9667
  .ds-247420 .ds-ep-tree-row {
9118
- display: flex; align-items: center; gap: 6px;
9119
- padding: 4px 8px 4px 0;
9668
+ display: flex; align-items: center; gap: var(--space-1-75);
9669
+ padding: var(--space-1) var(--space-2) var(--space-1) 0;
9120
9670
  border-radius: var(--r-1, 10px);
9121
9671
  cursor: pointer;
9122
9672
  color: var(--panel-text-2);
@@ -9139,25 +9689,25 @@
9139
9689
  .ds-247420 .ds-ep-tree-glyph { flex-shrink: 0; color: var(--panel-text-3); }
9140
9690
  .ds-247420 .ds-ep-tree-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
9141
9691
  .ds-247420 .ds-ep-tree-tag {
9142
- flex-shrink: 0; padding-left: 6px;
9692
+ flex-shrink: 0; padding-left: var(--space-1-75);
9143
9693
  font-size: 0.85em; color: var(--panel-text-3);
9144
9694
  }
9145
9695
  .ds-247420 .ds-ep-tree-children { display: flex; flex-direction: column; }
9146
9696
 
9147
9697
  /* PropertyGrid / PropertyField */
9148
9698
  .ds-247420 .ds-ep-propgrid {
9149
- display: flex; flex-direction: column; gap: 6px;
9150
- padding: 8px;
9699
+ display: flex; flex-direction: column; gap: var(--space-1-75);
9700
+ padding: var(--space-2);
9151
9701
  color: var(--panel-text);
9152
9702
  font: var(--fs-tiny, 12px)/var(--lh-base, 1.55) var(--ff-mono, monospace);
9153
9703
  }
9154
9704
  .ds-247420 .ds-ep-propfield {
9155
9705
  display: grid;
9156
9706
  grid-template-columns: minmax(80px, 120px) 1fr;
9157
- gap: 4px 10px;
9707
+ gap: var(--space-1) var(--space-2-5);
9158
9708
  align-items: center;
9159
9709
  }
9160
- .ds-247420 .ds-ep-propfield.inline { display: flex; gap: 8px; }
9710
+ .ds-247420 .ds-ep-propfield.inline { display: flex; gap: var(--space-2); }
9161
9711
  .ds-247420 .ds-ep-propfield-label {
9162
9712
  color: var(--panel-text-3);
9163
9713
  font-size: 0.85em;
@@ -9166,7 +9716,7 @@
9166
9716
  }
9167
9717
  .ds-247420 .ds-ep-propfield-value {
9168
9718
  color: var(--panel-text);
9169
- display: flex; align-items: center; gap: 4px; min-width: 0;
9719
+ display: flex; align-items: center; gap: var(--space-1); min-width: 0;
9170
9720
  }
9171
9721
  .ds-247420 .ds-ep-propfield-value input,
9172
9722
  .ds-247420 .ds-ep-propfield-value select,
@@ -9176,7 +9726,7 @@
9176
9726
  color: var(--panel-text);
9177
9727
  border: 1px solid var(--rule);
9178
9728
  border-radius: var(--r-1, 10px);
9179
- padding: 4px 8px;
9729
+ padding: var(--space-1) var(--space-2);
9180
9730
  font: inherit;
9181
9731
  min-width: 0; width: 100%;
9182
9732
  }
@@ -9194,7 +9744,7 @@
9194
9744
  }
9195
9745
  /* x/y/z packed on one row, each field equal width, no horizontal overflow. */
9196
9746
  .ds-247420 .ds-ep-vec3 {
9197
- display: flex; gap: 4px; width: 100%; min-width: 0;
9747
+ display: flex; gap: var(--space-1); width: 100%; min-width: 0;
9198
9748
  }
9199
9749
  .ds-247420 .ds-ep-vec3 > * { flex: 1 1 0; min-width: 0; }
9200
9750
  /* Each axis cell (axis letter + scrub input) must show its full 3-decimal value
@@ -9202,7 +9752,7 @@
9202
9752
  fill the rest with tight padding and centered text so 0.000 / -0.0 / 1.000 are
9203
9753
  always legible even in the narrow 3-up layout. */
9204
9754
  .ds-247420 .ds-ep-vec3 > * {
9205
- display: flex; align-items: center; gap: 2px;
9755
+ display: flex; align-items: center; gap: var(--space-hair);
9206
9756
  }
9207
9757
  .ds-247420 .ds-ep-vec3 .ds-ep-propfield-hint {
9208
9758
  flex: 0 0 auto; width: 9px; text-align: center;
@@ -9210,12 +9760,12 @@
9210
9760
  }
9211
9761
  .ds-247420 .ds-ep-vec3 .ds-input-bare {
9212
9762
  flex: 1 1 auto; min-width: 0; width: auto;
9213
- padding: 2px 4px; text-align: center; text-overflow: clip;
9763
+ padding: var(--space-hair) var(--space-1); text-align: center; text-overflow: clip;
9214
9764
  }
9215
9765
  /* Dense numeric inputs in the inspector — compact, tight radius, mono. */
9216
9766
  .ds-247420 .ds-ep-propfield-value input,
9217
9767
  .ds-247420 .ds-ep-propfield-value .ds-input-bare {
9218
- padding: 2px 6px;
9768
+ padding: var(--space-hair) var(--space-1-75);
9219
9769
  border-radius: var(--r-1, 4px);
9220
9770
  font: var(--fs-tiny, 12px)/1.3 var(--ff-mono, monospace);
9221
9771
  }
@@ -9225,7 +9775,7 @@
9225
9775
  color: var(--panel-text);
9226
9776
  border: 1px solid var(--rule);
9227
9777
  border-radius: var(--r-1, 4px);
9228
- padding: 2px 6px;
9778
+ padding: var(--space-hair) var(--space-1-75);
9229
9779
  font: var(--fs-tiny, 12px)/1.3 var(--ff-mono, monospace);
9230
9780
  min-width: 0;
9231
9781
  }
@@ -9234,7 +9784,7 @@
9234
9784
  control below) — used for wide segmented controls that would clip in the
9235
9785
  narrow value column. */
9236
9786
  .ds-247420 .ds-ep-propfield.block {
9237
- display: flex; flex-direction: column; align-items: stretch; gap: 4px;
9787
+ display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
9238
9788
  }
9239
9789
  .ds-247420 .ds-ep-propfield.block > .ds-ep-propfield-value { width: 100%; }
9240
9790
  .ds-247420 .ds-ep-propfield.block .ds-ep-btngrp { width: 100%; }
@@ -9283,8 +9833,8 @@
9283
9833
  Compact buttons, square-ish, bordered top — not big floating pills. */
9284
9834
  .ds-247420 .ds-ep-actionbar {
9285
9835
  flex-shrink: 0;
9286
- display: flex; align-items: center; gap: 6px;
9287
- padding: 6px 8px;
9836
+ display: flex; align-items: center; gap: var(--space-1-75);
9837
+ padding: var(--space-1-75) var(--space-2);
9288
9838
  border-top: 1px solid var(--rule);
9289
9839
  background: var(--panel-1);
9290
9840
  }
@@ -9302,7 +9852,7 @@
9302
9852
  IconButtonGroup which manages its own sizing. */
9303
9853
  .ds-247420 .ds-ep-tree-row button:not(.ds-ep-btngrp-btn),
9304
9854
  .ds-247420 .ds-ep-toolbar button:not(.ds-ep-btngrp-btn) {
9305
- min-height: 24px; height: 24px; padding: 0 8px;
9855
+ min-height: 24px; height: 24px; padding: 0 var(--space-2);
9306
9856
  border-radius: var(--r-1, 4px);
9307
9857
  font: var(--fs-tiny, 12px)/1 var(--ff-mono, monospace);
9308
9858
  }
@@ -9338,7 +9888,7 @@
9338
9888
  border: 1px solid var(--rule);
9339
9889
  color: var(--panel-text, var(--fg));
9340
9890
  min-width: 1.75em;
9341
- padding: var(--space-half, 3px) var(--space-1, 5px);
9891
+ padding: var(--space-half, 3px) var(--space-1, 4px);
9342
9892
  border-radius: var(--r-1, 4px);
9343
9893
  font: inherit;
9344
9894
  text-align: center;
@@ -9350,6 +9900,15 @@
9350
9900
  border-color: var(--accent);
9351
9901
  }
9352
9902
  .ds-247420 .ds-ep-pager-ellipsis { padding: 0 var(--space-hair, 2px); opacity: 0.6; }
9903
+ /* Touch floor. Pager controls render ~21px tall, so on a coarse pointer they
9904
+ were the smallest interactive targets in the kit — every other control family
9905
+ here (.ds-sub-btn, .ds-session-row, .ds-file-act, .btn) already floors at
9906
+ 44px, and paging is a repeated, mis-tap-prone action. The visible mark stays
9907
+ compact; only the hit area grows. */
9908
+ @media (pointer: coarse) {
9909
+ .ds-247420 .ds-ep-pager-btn, .ds-247420 .ds-ep-pager-num { min-height: 44px; min-width: 44px; }
9910
+ .ds-247420 .ds-ep-pager { gap: var(--space-2); }
9911
+ }
9353
9912
  .ds-247420 .ds-ep-pager-total { white-space: nowrap; margin-left: auto; }
9354
9913
 
9355
9914
  /* Grid / GridItem — 24-column responsive layout. GridItem's flex-basis is
@@ -9430,7 +9989,7 @@
9430
9989
  /* Collapsible tree mode — native details/summary, indent guides on children. */
9431
9990
  .ds-247420 .ds-ep-json-tree { white-space: normal; }
9432
9991
  .ds-247420 .ds-ep-json-kids {
9433
- padding-left: var(--space-3-5, 14px);
9992
+ padding-left: var(--space-3-5, 20px);
9434
9993
  margin-left: var(--space-1, 4px);
9435
9994
  border-left: 1px solid var(--rule);
9436
9995
  }
@@ -9442,7 +10001,7 @@
9442
10001
  .ds-247420 .ds-ep-json-sum::-webkit-details-marker { display: none; }
9443
10002
  .ds-247420 .ds-ep-json-sum::before {
9444
10003
  content: '+';
9445
- display: inline-block; width: var(--space-3, 12px);
10004
+ display: inline-block; width: var(--space-3, 16px);
9446
10005
  color: var(--panel-text-3, var(--fg-3));
9447
10006
  }
9448
10007
  .ds-247420 .ds-ep-json-node[open] > .ds-ep-json-sum::before { content: '-'; }
@@ -9456,11 +10015,11 @@
9456
10015
  font-size: var(--fs-micro, 11px);
9457
10016
  color: var(--panel-text-3, var(--fg-3));
9458
10017
  }
9459
- .ds-247420 .ds-ep-json-leaf { padding-left: var(--space-3, 12px); word-break: break-all; }
10018
+ .ds-247420 .ds-ep-json-leaf { padding-left: var(--space-3, 16px); word-break: break-all; }
9460
10019
  /* Copy affordance (copyable:true) — floats over the viewer's top-right. */
9461
10020
  .ds-247420 .ds-ep-json-wrap { position: relative; }
9462
10021
  .ds-247420 .ds-ep-json-copy {
9463
- position: absolute; top: var(--space-1-75, 6px); right: var(--space-1-75, 6px); z-index: 1;
10022
+ position: absolute; top: var(--space-1-75, 6px); right: var(--space-1-75, 6px); z-index: var(--z-raised);
9464
10023
  appearance: none; cursor: pointer;
9465
10024
  background: var(--panel-1, var(--bg-1));
9466
10025
  border: 1px solid var(--rule);
@@ -9518,12 +10077,12 @@
9518
10077
  overflow: hidden;
9519
10078
  background: var(--panel-2);
9520
10079
  }
9521
- .ds-247420 .ds-ep-btngrp.dense .ds-ep-btngrp-btn { padding: 2px 6px; min-width: 22px; }
10080
+ .ds-247420 .ds-ep-btngrp.dense .ds-ep-btngrp-btn { padding: var(--space-hair) var(--space-1-75); min-width: 22px; }
9522
10081
  .ds-247420 .ds-ep-btngrp-btn {
9523
10082
  appearance: none; border: 0;
9524
10083
  background: transparent;
9525
10084
  color: var(--panel-text-2);
9526
- padding: 4px 10px;
10085
+ padding: var(--space-1) var(--space-2-5);
9527
10086
  font: inherit; cursor: pointer;
9528
10087
  border-right: 1px solid var(--rule);
9529
10088
  transition: background var(--dur-snap, 80ms) var(--ease, ease), color var(--dur-snap, 80ms) var(--ease, ease);
@@ -9577,7 +10136,7 @@
9577
10136
  ContextMenu
9578
10137
  --------------------------------------------------------------- */
9579
10138
  .ds-247420 .ds-ep-ctxmenu-backdrop {
9580
- position: fixed; inset: 0; z-index: 9000;
10139
+ position: fixed; inset: 0; z-index: var(--z-dropdown);
9581
10140
  }
9582
10141
  .ds-247420 .ds-ep-ctxmenu {
9583
10142
  position: absolute;
@@ -9592,13 +10151,13 @@
9592
10151
  border: 1px solid var(--rule);
9593
10152
  border-radius: var(--r-2, 8px);
9594
10153
  box-shadow: var(--shadow-2);
9595
- padding: 4px;
10154
+ padding: var(--space-1);
9596
10155
  display: flex; flex-direction: column;
9597
10156
  outline: none;
9598
10157
  }
9599
10158
  .ds-247420 .ds-ep-ctxmenu-item {
9600
- display: flex; align-items: center; gap: 8px;
9601
- padding: 8px 10px;
10159
+ display: flex; align-items: center; gap: var(--space-2);
10160
+ padding: var(--space-2) var(--space-2-5);
9602
10161
  background: transparent; border: 0;
9603
10162
  color: inherit; font: inherit; text-align: left;
9604
10163
  border-radius: var(--r-1, 4px);
@@ -9611,13 +10170,13 @@
9611
10170
  .ds-247420 .ds-ep-ctxmenu-item.danger { color: var(--danger); }
9612
10171
  .ds-247420 .ds-ep-ctxmenu-item.disabled { opacity: 0.45; cursor: not-allowed; }
9613
10172
  .ds-247420 .ds-ep-ctxmenu-icon { width: 16px; display: inline-flex; justify-content: center; }
9614
- .ds-247420 .ds-ep-ctxmenu-sep { height: 1px; background: var(--rule); margin: 4px 6px; }
10173
+ .ds-247420 .ds-ep-ctxmenu-sep { height: 1px; background: var(--rule); margin: var(--space-1) var(--space-1-75); }
9615
10174
 
9616
10175
  /* ---------------------------------------------------------------
9617
10176
  Drawer
9618
10177
  --------------------------------------------------------------- */
9619
10178
  .ds-247420 .ds-ep-drawer-backdrop {
9620
- position: fixed; inset: 0; z-index: 8500;
10179
+ position: fixed; inset: 0; z-index: var(--z-drawer);
9621
10180
  background: var(--scrim);
9622
10181
  }
9623
10182
  .ds-247420 .ds-ep-drawer {
@@ -9627,11 +10186,11 @@
9627
10186
  box-shadow: var(--shadow-overlay);
9628
10187
  outline: none;
9629
10188
  transition: transform 180ms ease;
9630
- padding: 12px;
9631
- padding-top: max(12px, env(safe-area-inset-top));
9632
- padding-bottom: max(12px, env(safe-area-inset-bottom));
9633
- padding-left: max(12px, env(safe-area-inset-left));
9634
- padding-right: max(12px, env(safe-area-inset-right));
10189
+ padding: var(--space-2-75);
10190
+ padding-top: max(var(--space-2-75), env(safe-area-inset-top));
10191
+ padding-bottom: max(var(--space-2-75), env(safe-area-inset-bottom));
10192
+ padding-left: max(var(--space-2-75), env(safe-area-inset-left));
10193
+ padding-right: max(var(--space-2-75), env(safe-area-inset-right));
9635
10194
  }
9636
10195
  .ds-247420 .ds-ep-drawer.side-left { left: 0; top: 0; bottom: 0; width: 86vw; max-width: 320px; }
9637
10196
  .ds-247420 .ds-ep-drawer.side-right { right: 0; top: 0; bottom: 0; width: 86vw; max-width: 320px; }
@@ -9644,10 +10203,10 @@
9644
10203
  Dialog
9645
10204
  --------------------------------------------------------------- */
9646
10205
  .ds-247420 .ds-ep-dialog-backdrop {
9647
- position: fixed; inset: 0; z-index: 9500;
10206
+ position: fixed; inset: 0; z-index: var(--z-modal);
9648
10207
  background: var(--scrim-strong);
9649
10208
  display: flex; align-items: center; justify-content: center;
9650
- padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
10209
+ padding: max(var(--space-3), env(safe-area-inset-top)) max(var(--space-3), env(safe-area-inset-right)) max(var(--space-3), env(safe-area-inset-bottom)) max(var(--space-3), env(safe-area-inset-left));
9651
10210
  }
9652
10211
  .ds-247420 .ds-ep-dialog {
9653
10212
  background: var(--panel-1, var(--panel-bg));
@@ -9697,8 +10256,8 @@
9697
10256
  position: fixed;
9698
10257
  top: max(16px, env(safe-area-inset-top));
9699
10258
  right: max(16px, env(safe-area-inset-right));
9700
- z-index: 9800;
9701
- display: flex; flex-direction: column; gap: 8px;
10259
+ z-index: var(--z-toast);
10260
+ display: flex; flex-direction: column; gap: var(--space-2);
9702
10261
  pointer-events: none;
9703
10262
  }
9704
10263
  .ds-247420 .ds-ep-toast {
@@ -9706,7 +10265,13 @@
9706
10265
  background: var(--panel-1, var(--panel-bg));
9707
10266
  color: var(--panel-text, var(--fg-text));
9708
10267
  border: 1px solid var(--rule);
9709
- border-left: 3px solid var(--accent);
10268
+ /* DELIBERATE accent spine (same intent as .panel-spine, expressed as a
10269
+ border because a toast has no free ::before — the host stacks them and
10270
+ .has-action reflows the box). Load-bearing, not decoration: this edge is
10271
+ the ONLY channel carrying toast severity — .kind-success/.kind-warn/
10272
+ .kind-error below recolour border-left-color and nothing else. Do not
10273
+ demote to a hairline; that would erase the status signal. */
10274
+ border-left: var(--bw-chunk) solid var(--accent);
9710
10275
  border-radius: var(--r-1, 6px);
9711
10276
  padding: var(--space-2) var(--space-2-75);
9712
10277
  box-shadow: var(--shadow-3);
@@ -9765,8 +10330,8 @@
9765
10330
  .ds-247420 .ds-ep-tree-row,
9766
10331
  .ds-247420 .ds-ep-pager-btn {
9767
10332
  min-height: 44px;
9768
- padding-top: 10px;
9769
- padding-bottom: 10px;
10333
+ padding-top: var(--space-2-5);
10334
+ padding-bottom: var(--space-2-5);
9770
10335
  }
9771
10336
  .ds-247420 .ds-ep-resize.axis-h { width: 14px; }
9772
10337
  .ds-247420 .ds-ep-resize.axis-v { height: 14px; }
@@ -9911,6 +10476,10 @@
9911
10476
 
9912
10477
  .ds-247420 .sr-only {
9913
10478
  position: absolute; width: 1px; height: 1px;
10479
+ /* margin:-1px is OFF-SCALE ON PURPOSE — it is not rhythm, it is the
10480
+ canonical visually-hidden idiom: the negative margin cancels the 1px
10481
+ box so the clipped element contributes zero layout. Snapping it to a
10482
+ --space-* rung would reintroduce a measurable gap. */
9914
10483
  padding: 0; margin: -1px; overflow: hidden;
9915
10484
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
9916
10485
  }
@@ -9925,7 +10494,7 @@
9925
10494
  .ds-247420 .ds-tooltip {
9926
10495
  position: fixed;
9927
10496
  left: 0; top: 0;
9928
- z-index: 9700;
10497
+ z-index: var(--z-tooltip);
9929
10498
  background: var(--panel-1, var(--panel-bg));
9930
10499
  color: var(--panel-text, var(--fg-text));
9931
10500
  border: 1px solid var(--rule);
@@ -9948,7 +10517,7 @@
9948
10517
  .ds-247420 .ds-popover {
9949
10518
  position: fixed;
9950
10519
  left: 0; top: 0;
9951
- z-index: 9600;
10520
+ z-index: var(--z-dropdown);
9952
10521
  background: var(--panel-1, var(--panel-bg));
9953
10522
  color: var(--panel-text, var(--fg-text));
9954
10523
  border: 1px solid var(--rule);
@@ -9970,10 +10539,10 @@
9970
10539
  /* ---------------------------------------------------------------
9971
10540
  Dropdown
9972
10541
  --------------------------------------------------------------- */
9973
- .ds-247420 .ds-dropdown-menu { padding: 4px; }
10542
+ .ds-247420 .ds-dropdown-menu { padding: var(--space-1); }
9974
10543
  .ds-247420 .ds-dropdown-list { display: flex; flex-direction: column; }
9975
10544
  .ds-247420 .ds-dropdown-item {
9976
- display: flex; align-items: center; gap: 8px;
10545
+ display: flex; align-items: center; gap: var(--space-2);
9977
10546
  /* Dense desktop row (was an unconditional 44px touch target — a menu of
9978
10547
  these was very tall on desktop). ~30px here; the 44px tap target is
9979
10548
  restored under @media(pointer:coarse) below, matching the .ds-check-row
@@ -10005,7 +10574,7 @@
10005
10574
  .ds-247420 .ds-dropdown-item.is-danger { color: var(--danger); }
10006
10575
  .ds-247420 .ds-dropdown-glyph { width: 16px; display: inline-flex; justify-content: center; flex-shrink: 0; }
10007
10576
  .ds-247420 .ds-dropdown-label { flex: 1; min-width: 0; }
10008
- .ds-247420 .ds-dropdown-separator { height: 1px; background: var(--rule); margin: 4px 6px; }
10577
+ .ds-247420 .ds-dropdown-separator { height: 1px; background: var(--rule); margin: var(--space-1) var(--space-1-75); }
10009
10578
  .ds-247420 .ds-dropdown-trigger {
10010
10579
  appearance: none;
10011
10580
  background: var(--panel-2, transparent);
@@ -10145,7 +10714,7 @@
10145
10714
  border-radius: var(--r-1, 10px);
10146
10715
  background: var(--panel-2, var(--panel-1)); color: var(--panel-text);
10147
10716
  }
10148
- .ds-247420 .ds-kbd-group { margin: var(--space-3, 12px) 0; }
10717
+ .ds-247420 .ds-kbd-group { margin: var(--space-3, 16px) 0; }
10149
10718
  .ds-247420 .ds-kbd-group h3 { font-size: 0.9em; opacity: 0.7; margin: 0 0 var(--space-1, 4px); text-transform: capitalize; }
10150
10719
  /* One shortcut per row: the key chip on the left, its description on the right,
10151
10720
  so the dialog reads as "G Translate gizmo" rather than a wall of bare keys. */
@@ -10159,7 +10728,7 @@
10159
10728
  --------------------------------------------------------------- */
10160
10729
  .ds-247420 .ov-cmd-backdrop {
10161
10730
  position: fixed; inset: 0;
10162
- z-index: var(--z-overlay, 1000);
10731
+ z-index: var(--z-modal);
10163
10732
  background: color-mix(in oklab, var(--fg) 32%, transparent);
10164
10733
  display: flex; align-items: flex-start; justify-content: center;
10165
10734
  padding: 12vh var(--space-3, 16px) var(--space-3, 16px);
@@ -10214,7 +10783,8 @@
10214
10783
  --------------------------------------------------------------- */
10215
10784
  .ds-247420 .ov-emoji-root {
10216
10785
  position: fixed; left: 0; top: 0;
10217
- z-index: var(--z-overlay, 1000);
10786
+ /* Anchored to a trigger, not a blocking surface — dropdown rung. */
10787
+ z-index: var(--z-dropdown);
10218
10788
  width: 280px;
10219
10789
  display: flex; flex-direction: column;
10220
10790
  background: var(--bg-2); color: var(--fg);
@@ -10252,7 +10822,7 @@
10252
10822
  --------------------------------------------------------------- */
10253
10823
  .ds-247420 .ov-boot {
10254
10824
  position: fixed; inset: 0;
10255
- z-index: calc(var(--z-overlay, 1000) + 100);
10825
+ z-index: var(--z-top);
10256
10826
  background: var(--bg);
10257
10827
  display: flex; align-items: center; justify-content: center;
10258
10828
  color: var(--fg);
@@ -10295,7 +10865,8 @@
10295
10865
  --------------------------------------------------------------- */
10296
10866
  .ds-247420 .ov-set-root {
10297
10867
  position: fixed; left: 0; top: 0;
10298
- z-index: var(--z-overlay, 1000);
10868
+ /* Anchored to a trigger, not a blocking surface — dropdown rung. */
10869
+ z-index: var(--z-dropdown);
10299
10870
  width: 300px; max-height: 70vh;
10300
10871
  display: flex; flex-direction: column;
10301
10872
  background: var(--bg-2); color: var(--fg);
@@ -10344,7 +10915,7 @@
10344
10915
 
10345
10916
  /* AuthModal — ov-auth-* */
10346
10917
  .ds-247420 .ov-auth-backdrop {
10347
- position: fixed; inset: 0; z-index: var(--z-overlay, 1000);
10918
+ position: fixed; inset: 0; z-index: var(--z-modal);
10348
10919
  display: flex; align-items: center; justify-content: center;
10349
10920
  background: var(--scrim-strong);
10350
10921
  }
@@ -10373,7 +10944,7 @@
10373
10944
 
10374
10945
  /* VideoLightbox — ov-lightbox-* */
10375
10946
  .ds-247420 .ov-lightbox-backdrop {
10376
- position: fixed; inset: 0; z-index: var(--z-overlay-top, 1100);
10947
+ position: fixed; inset: 0; z-index: var(--z-modal);
10377
10948
  display: flex; align-items: center; justify-content: center;
10378
10949
  background: var(--scrim-media);
10379
10950
  }
@@ -10427,7 +10998,7 @@
10427
10998
  border: 1px solid var(--rule); border-radius: var(--r-1, 4px);
10428
10999
  background: var(--panel-2); cursor: pointer; flex-shrink: 0;
10429
11000
  }
10430
- .ds-247420 .ds-input-color::-webkit-color-swatch-wrapper { padding: 2px; }
11001
+ .ds-247420 .ds-input-color::-webkit-color-swatch-wrapper { padding: var(--space-hair); }
10431
11002
  .ds-247420 .ds-input-color::-webkit-color-swatch { border: none; border-radius: var(--r-hair); }
10432
11003
  .ds-247420 .ds-input-color:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
10433
11004
  .ds-247420 .ds-input-check {
@@ -10490,8 +11061,8 @@
10490
11061
  /* Collapsed: shrink to just the header strip, freeing the viewport. */
10491
11062
  .ds-247420 .ds-ep-dock.collapsed { bottom: auto; height: auto; }
10492
11063
  .ds-247420 .ds-ep-dock-head {
10493
- display: flex; align-items: center; gap: 6px;
10494
- flex: 0 0 auto; padding: 4px 6px 4px 10px;
11064
+ display: flex; align-items: center; gap: var(--space-1-75);
11065
+ flex: 0 0 auto; padding: var(--space-1) var(--space-1-75) var(--space-1) var(--space-2-5);
10495
11066
  border-bottom: 1px solid var(--rule);
10496
11067
  background: color-mix(in oklab, var(--panel-1) 60%, transparent);
10497
11068
  }
@@ -10522,7 +11093,7 @@
10522
11093
  border-radius: var(--r-1, 4px);
10523
11094
  background: var(--panel-2, var(--bg-2));
10524
11095
  }
10525
- .ds-247420 .ds-ep-collapse + .ds-ep-collapse { margin-top: var(--space-1, 5px); }
11096
+ .ds-247420 .ds-ep-collapse + .ds-ep-collapse { margin-top: var(--space-1, 4px); }
10526
11097
  .ds-247420 .ds-ep-collapse-head {
10527
11098
  appearance: none; cursor: pointer; width: 100%;
10528
11099
  display: flex; align-items: center; gap: var(--space-1-5, 5px);
@@ -10589,7 +11160,7 @@
10589
11160
  .ds-247420 .ov-perm-action {
10590
11161
  flex: 1; appearance: none; border: 1px solid var(--rule); background: transparent;
10591
11162
  color: var(--fg-2); font: inherit; font-size: var(--fs-tiny, 12px);
10592
- padding: 4px 8px; border-radius: var(--r-1, 10px); cursor: pointer;
11163
+ padding: var(--space-1) var(--space-2); border-radius: var(--r-1, 10px); cursor: pointer;
10593
11164
  }
10594
11165
  .ds-247420 .ov-perm-action:hover { background: var(--panel-2, var(--rule)); }
10595
11166
 
@@ -10820,7 +11391,7 @@
10820
11391
  @media (max-width: 900px) {
10821
11392
  .ds-247420.ds-247420 .ca-rail {
10822
11393
  position: absolute;
10823
- z-index: 20;
11394
+ z-index: calc(var(--z-drawer) + 1);
10824
11395
  top: 0; left: 0; bottom: 0;
10825
11396
  width: 240px; min-width: 240px;
10826
11397
  transform: translateX(-110%);
@@ -10835,7 +11406,7 @@
10835
11406
  content: '';
10836
11407
  position: absolute;
10837
11408
  inset: 0;
10838
- z-index: 15;
11409
+ z-index: var(--z-drawer);
10839
11410
  background: color-mix(in oklab, var(--ink, #000) 40%, transparent);
10840
11411
  pointer-events: none;
10841
11412
  }
@@ -11159,6 +11730,11 @@
11159
11730
  .ds-247420 #ds-article-host.has-toc {
11160
11731
  display: flex;
11161
11732
  align-items: flex-start;
11733
+ /* 44px is OFF-SCALE ON PURPOSE — it is not a rhythm step but one term of the
11734
+ three-term width equation on the next line (256px rail + 44px gutter +
11735
+ measure). It sits between --space-6 (48) and --space-5 (32); snapping it
11736
+ would silently change the host's computed max-width unless the calc were
11737
+ re-derived, so the literal and the calc stay coupled and explicit. */
11162
11738
  column-gap: 44px;
11163
11739
  gap: 44px;
11164
11740
  max-width: calc(256px + 44px + var(--measure-narrow));
@@ -11182,7 +11758,7 @@
11182
11758
  overscroll-behavior: contain;
11183
11759
  margin: 0;
11184
11760
  max-width: 100%;
11185
- padding: 18px 18px 18px 20px;
11761
+ padding: var(--space-3-5);
11186
11762
  background: var(--panel-1);
11187
11763
  border-radius: var(--r-1);
11188
11764
  box-shadow: var(--panel-shadow);
@@ -11201,15 +11777,28 @@
11201
11777
  background: var(--panel-text-3);
11202
11778
  background-clip: padding-box;
11203
11779
  }
11204
- .ds-247420 #ds-article-host .toc .toc-title {
11780
+ /* Small-label voice — the local composition of the house `.t-label` recipe
11781
+ (src/css/app-shell/base.css). This sheet is a standalone published export
11782
+ with its own <link>, so it cannot join the `.t-label` selector list; it
11783
+ composes by referencing the identical token set. Both members are gm-
11784
+ generated markup (injected into #ds-article-host), so the class list is not
11785
+ reachable from src/ — the rule, not the markup, does the composing.
11786
+ Deliberate override for both: --panel-text-2, because prose surfaces use the
11787
+ panel text ramp rather than the app --fg ramp. Sized at --fs-nano: these
11788
+ labels ride above dense article chrome, not UI text. */
11789
+ .ds-247420 #ds-article-host .toc .toc-title,
11790
+ .ds-247420 .ds-prose .gm-callout .who {
11205
11791
  font-family: var(--ff-mono);
11206
- font-size: 11px;
11792
+ font-size: var(--fs-nano);
11207
11793
  text-transform: uppercase;
11208
- letter-spacing: .09em;
11794
+ letter-spacing: var(--tr-label);
11209
11795
  color: var(--panel-text-2);
11210
- margin: 0 0 14px 0;
11211
11796
  }
11212
- .ds-247420 #ds-article-host .toc ol { margin: 0; padding-left: 18px; }
11797
+
11798
+ .ds-247420 #ds-article-host .toc .toc-title {
11799
+ margin: 0 0 var(--space-3) 0;
11800
+ }
11801
+ .ds-247420 #ds-article-host .toc ol { margin: 0; padding-left: var(--space-3-5); }
11213
11802
  .ds-247420 #ds-article-host .toc li { font-size: 13px; line-height: 1.85; color: var(--panel-text); }
11214
11803
  .ds-247420 #ds-article-host .toc li::marker { color: var(--panel-text-3); font-variant-numeric: tabular-nums; }
11215
11804
  .ds-247420 #ds-article-host .toc a { color: var(--panel-text-2); text-decoration: none; transition: color .12s ease; }
@@ -11222,7 +11811,7 @@
11222
11811
  position: static;
11223
11812
  max-height: none;
11224
11813
  overflow: visible;
11225
- margin: 0 0 28px 0;
11814
+ margin: 0 0 var(--space-5) 0;
11226
11815
  }
11227
11816
  }
11228
11817
 
@@ -11238,8 +11827,8 @@
11238
11827
  display: block;
11239
11828
  background: var(--panel-1);
11240
11829
  border-radius: var(--r-0);
11241
- padding: 16px 20px;
11242
- margin: 16px 0 28px 0;
11830
+ padding: var(--space-3) var(--space-3-5);
11831
+ margin: var(--space-3) 0 var(--space-5) 0;
11243
11832
  font-family: var(--ff-mono);
11244
11833
  font-size: 12.5px;
11245
11834
  line-height: 1.6;
@@ -11254,14 +11843,14 @@
11254
11843
  white-space: pre-wrap;
11255
11844
  word-break: break-word;
11256
11845
  min-height: 1.4em;
11257
- padding: 3px 0;
11846
+ padding: var(--space-half) 0;
11258
11847
  line-height: 1.6;
11259
11848
  }
11260
11849
  .ds-247420 .ds-cli-block .ds-cli-comment:empty::before { content: '\00a0'; }
11261
11850
  .ds-247420 .ds-cli-block .ds-cli-row {
11262
11851
  display: flex;
11263
- gap: 10px;
11264
- padding: 3px 0;
11852
+ gap: var(--space-2-5);
11853
+ padding: var(--space-half) 0;
11265
11854
  white-space: pre-wrap;
11266
11855
  word-break: break-word;
11267
11856
  }
@@ -11277,14 +11866,14 @@
11277
11866
  word-break: break-word;
11278
11867
  }
11279
11868
 
11280
- .ds-247420 .panel .row { align-items: flex-start; padding: 16px 20px; gap: 16px; }
11869
+ .ds-247420 .panel .row { align-items: flex-start; padding: var(--space-3) var(--space-3-5); gap: var(--space-3); }
11281
11870
  .ds-247420 .panel .row + .row { box-shadow: inset 0 1px 0 var(--rule); }
11282
- .ds-247420 .panel .row .code { padding-top: 2px; min-width: 28px; }
11283
- .ds-247420 .panel .row .meta { padding-top: 2px; opacity: 0.4; }
11871
+ .ds-247420 .panel .row .code { padding-top: var(--space-hair); min-width: 28px; }
11872
+ .ds-247420 .panel .row .meta { padding-top: var(--space-hair); opacity: 0.4; }
11284
11873
  .ds-247420 .panel .row .title { display: block; line-height: 1.4; }
11285
11874
  .ds-247420 .panel .row .title .sub {
11286
11875
  display: block;
11287
- margin-top: 6px;
11876
+ margin-top: var(--space-1-75);
11288
11877
  font-weight: 400;
11289
11878
  color: var(--panel-text-2);
11290
11879
  font-size: 13px;
@@ -11294,9 +11883,9 @@
11294
11883
  .ds-247420 .ds-prose .card {
11295
11884
  display: flex;
11296
11885
  flex-direction: column;
11297
- gap: 8px;
11298
- padding: 14px 18px;
11299
- margin: 8px 0;
11886
+ gap: var(--space-2);
11887
+ padding: var(--space-2-75) var(--space-3-5);
11888
+ margin: var(--space-2) 0;
11300
11889
  background: var(--panel-1);
11301
11890
  border-radius: var(--r-0);
11302
11891
  font-size: 13px;
@@ -11304,35 +11893,46 @@
11304
11893
  text-decoration: none;
11305
11894
  }
11306
11895
  .ds-247420 .ds-prose .card:hover { background: var(--panel-hover); }
11307
- .ds-247420 .ds-prose .card .card-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
11896
+ .ds-247420 .ds-prose .card .card-top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2-75); }
11308
11897
  .ds-247420 .ds-prose .card .repo-name { font-weight: 600; color: var(--panel-text); }
11309
11898
  .ds-247420 .ds-prose .card .stars { color: var(--panel-text-3); font-family: var(--ff-mono); font-size: 12px; flex: 0 0 auto; }
11310
11899
  .ds-247420 .ds-prose .card .desc { color: var(--panel-text-2); font-size: 12px; line-height: 1.5; margin: 0; }
11311
- .ds-247420 .ds-prose .tags { display: flex; gap: 6px; flex-wrap: wrap; }
11900
+ .ds-247420 .ds-prose .tags { display: flex; gap: var(--space-1-75); flex-wrap: wrap; }
11312
11901
  .ds-247420 .ds-prose .tag {
11313
11902
  background: var(--panel-2);
11314
11903
  color: var(--panel-text-2);
11315
11904
  border: 1px solid var(--panel-3);
11316
11905
  font-size: 0.7rem;
11906
+ /* rem, not --space-*: the chip's inset is deliberately tied to the root type
11907
+ scale alongside its own 0.7rem size, so the capsule keeps its proportions
11908
+ when a doc site scales root font-size. A px rung would decouple them. */
11317
11909
  padding: 0.15rem 0.5rem;
11318
11910
  border-radius: var(--r-hair);
11319
11911
  font-family: var(--ff-mono);
11320
11912
  }
11913
+ /* Attributed callout — an editorial pull-quote (it carries a .who byline), so
11914
+ the left accent is DELIBERATE, not the generic alert stripe. Expressed via
11915
+ the house .panel-spine idiom (absolute ::before rail at --bw-chunk, squared
11916
+ leading corners) instead of a raw 3px border-left, so it stays on the border
11917
+ scale and matches the spine primitive in panel-row.css. */
11321
11918
  .ds-247420 .ds-prose .gm-callout {
11322
- margin: 18px 0;
11323
- padding: 14px 18px;
11919
+ position: relative;
11920
+ margin: var(--space-3-5) 0;
11921
+ padding: var(--space-2-75) var(--space-3-5);
11922
+ padding-left: calc(var(--space-3-5) + var(--bw-chunk));
11324
11923
  background: var(--panel-1);
11325
- border-left: 3px solid var(--panel-accent);
11924
+ border-radius: 0 var(--r-1) var(--r-1) 0;
11326
11925
  color: var(--panel-text);
11327
11926
  }
11927
+ .ds-247420 .ds-prose .gm-callout::before {
11928
+ content: ''; position: absolute; left: 0; top: 0; bottom: 0;
11929
+ width: var(--bw-chunk); background: var(--panel-accent);
11930
+ border-radius: var(--bw-chunk) 0 0 var(--bw-chunk);
11931
+ }
11932
+ /* Joins the small-label voice above; only its own box properties here. */
11328
11933
  .ds-247420 .ds-prose .gm-callout .who {
11329
11934
  display: block;
11330
- font-family: var(--ff-mono);
11331
- font-size: 11px;
11332
- text-transform: uppercase;
11333
- letter-spacing: .08em;
11334
- color: var(--panel-text-2);
11335
- margin-bottom: 4px;
11935
+ margin-bottom: var(--space-1);
11336
11936
  }
11337
11937
 
11338
11938
  /* marketing.css */
@@ -11374,7 +11974,7 @@
11374
11974
  .ds-247420 .sp-loading {
11375
11975
  position: fixed;
11376
11976
  inset: 0;
11377
- z-index: 10000;
11977
+ z-index: var(--z-top);
11378
11978
  display: flex;
11379
11979
  align-items: center;
11380
11980
  justify-content: center;
@@ -11505,7 +12105,7 @@
11505
12105
  .ds-247420 .sp-lobby {
11506
12106
  position: fixed;
11507
12107
  inset: 0;
11508
- z-index: 9500;
12108
+ z-index: var(--z-modal);
11509
12109
  display: flex;
11510
12110
  align-items: center;
11511
12111
  justify-content: center;