anentrypoint-design 0.0.381 → 0.0.382

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/247420.css +228 -162
  2. package/dist/247420.js +24 -24
  3. package/package.json +1 -1
  4. package/src/components/content/avatar.js +31 -0
  5. package/src/components/content/charts.js +50 -0
  6. package/src/components/content/cli.js +46 -0
  7. package/src/components/content/feedback.js +77 -0
  8. package/src/components/content/fields.js +136 -0
  9. package/src/components/content/hero.js +146 -0
  10. package/src/components/content/lists.js +85 -0
  11. package/src/components/content/panel.js +79 -0
  12. package/src/components/content/row.js +115 -0
  13. package/src/components/content/table.js +97 -0
  14. package/src/components/content/views.js +81 -0
  15. package/src/components/content.js +29 -861
  16. package/src/components/editor-primitives/batch.js +60 -0
  17. package/src/components/editor-primitives/chrome.js +146 -0
  18. package/src/components/editor-primitives/collapse.js +46 -0
  19. package/src/components/editor-primitives/context-menu.js +127 -0
  20. package/src/components/editor-primitives/diagnostics.js +44 -0
  21. package/src/components/editor-primitives/focus-trap.js +26 -0
  22. package/src/components/editor-primitives/json-viewer.js +123 -0
  23. package/src/components/editor-primitives/layout.js +89 -0
  24. package/src/components/editor-primitives/modals.js +89 -0
  25. package/src/components/editor-primitives/pager.js +74 -0
  26. package/src/components/editor-primitives/property-grid.js +57 -0
  27. package/src/components/editor-primitives/shared.js +18 -0
  28. package/src/components/editor-primitives/split-panel.js +101 -0
  29. package/src/components/editor-primitives/toast.js +59 -0
  30. package/src/components/editor-primitives/tree.js +75 -0
  31. package/src/components/editor-primitives.js +35 -1048
  32. package/src/components/overlay-primitives/approval-prompt.js +38 -0
  33. package/src/components/overlay-primitives/auth-modal.js +89 -0
  34. package/src/components/overlay-primitives/command-palette.js +101 -0
  35. package/src/components/overlay-primitives/emoji-picker.js +103 -0
  36. package/src/components/overlay-primitives/floating.js +146 -0
  37. package/src/components/overlay-primitives/full-screen.js +45 -0
  38. package/src/components/overlay-primitives/menus.js +131 -0
  39. package/src/components/overlay-primitives/popover.js +51 -0
  40. package/src/components/overlay-primitives/roving-menu.js +73 -0
  41. package/src/components/overlay-primitives/settings-popover.js +85 -0
  42. package/src/components/overlay-primitives/tooltip.js +55 -0
  43. package/src/components/overlay-primitives.js +33 -855
  44. package/src/css/app-shell/chat-polish.css +39 -32
  45. package/src/css/app-shell/data-density.css +25 -21
  46. package/src/css/app-shell/files.css +37 -29
  47. package/src/css/app-shell/kits-appended.css +73 -50
  48. package/src/css/app-shell/responsive.css +47 -29
  49. package/src/kits/os/freddie-dashboard.css +2 -2
package/dist/247420.css CHANGED
@@ -1963,7 +1963,7 @@
1963
1963
  brand and let it scroll horizontally. The brand stays on the first row;
1964
1964
  nav wraps to a second row at 100% width (flex-wrap on .app-topbar). */
1965
1965
  .ds-247420 .app-topbar {
1966
- gap: var(--space-2); padding: 12px var(--space-3);
1966
+ gap: var(--space-2); padding: var(--space-2-75) var(--space-3);
1967
1967
  }
1968
1968
  /* When the topbar is folded into .app-chrome it is a flex:0 0 auto child, so
1969
1969
  it sizes to its nav's content and overflows the viewport instead of letting
@@ -1972,7 +1972,7 @@
1972
1972
  .ds-247420 .app-chrome > .app-topbar { max-width: 100%; min-width: 0; flex-basis: 100%; }
1973
1973
  .ds-247420 .app-topbar > nav {
1974
1974
  flex: 1 1 100%; margin-left: 0; order: 3; min-width: 0; max-width: 100%;
1975
- display: flex; gap: 2px; flex-wrap: nowrap;
1975
+ display: flex; gap: var(--space-hair); flex-wrap: nowrap;
1976
1976
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
1977
1977
  /* Fade the trailing edge so a clipped last item (e.g. "source ->" cut to
1978
1978
  "sour") reads as scrollable content, not a broken/truncated label. */
@@ -1981,7 +1981,7 @@
1981
1981
  }
1982
1982
  .ds-247420 .app-topbar nav::-webkit-scrollbar { display: none; }
1983
1983
  .ds-247420 .app-topbar nav a {
1984
- flex: 0 0 auto; padding: 10px 12px; min-height: 44px; white-space: nowrap;
1984
+ flex: 0 0 auto; padding: var(--space-2-5) var(--space-2-75); min-height: 44px; white-space: nowrap;
1985
1985
  }
1986
1986
  .ds-247420 .brand { font-size: var(--fs-tiny); font-weight: 600; }
1987
1987
 
@@ -2004,8 +2004,8 @@
2004
2004
 
2005
2005
  .ds-247420 .row {
2006
2006
  grid-template-columns: minmax(0, 1fr) auto !important;
2007
- gap: var(--space-2); padding: 12px 16px;
2008
- row-gap: 4px !important;
2007
+ gap: var(--space-2); padding: var(--space-2-75) var(--space-3);
2008
+ row-gap: var(--space-1) !important;
2009
2009
  }
2010
2010
  .ds-247420 .row .sub { grid-column: 1 / -1; order: 3; }
2011
2011
  .ds-247420 .row .title { font-size: var(--fs-sm); }
@@ -2016,7 +2016,10 @@
2016
2016
 
2017
2017
  /* Buttons */
2018
2018
  .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost {
2019
- padding: 11px 16px; font-size: var(--fs-tiny);
2019
+ /* 11px vertical is optical, not scale drift: --space-2-75 (12) would tip
2020
+ the intrinsic box past the 44px min-height floor below and make the
2021
+ floor dead, changing the mobile button rhythm. */
2022
+ padding: 11px var(--space-3); font-size: var(--fs-tiny);
2020
2023
  min-height: 44px; /* Touch target minimum */
2021
2024
  }
2022
2025
 
@@ -2024,13 +2027,13 @@
2024
2027
  .ds-247420 .ds-file-grid {
2025
2028
  display: flex;
2026
2029
  flex-direction: column;
2027
- gap: 3px;
2030
+ gap: var(--space-half);
2028
2031
  }
2029
2032
  .ds-247420 .ds-file-row {
2030
- gap: 8px; padding: 10px 12px;
2033
+ gap: var(--space-2); padding: var(--space-2-5) var(--space-2-75);
2031
2034
  font-size: var(--fs-xs);
2032
2035
  }
2033
- .ds-247420 .ds-file-open { gap: 10px; }
2036
+ .ds-247420 .ds-file-open { gap: var(--space-2-5); }
2034
2037
  /* At mobile row widths, a fixed-size meta column (date/size) plus the
2035
2038
  always-visible action buttons leave the flexible title only a few px —
2036
2039
  not enough for even one legible character before the two collide. Drop
@@ -2047,12 +2050,12 @@
2047
2050
  /* Chat */
2048
2051
  .ds-247420 .chat-stack { max-width: 100%; min-width: 0; }
2049
2052
  .ds-247420 .chat-bubble {
2050
- padding: 10px 12px; font-size: var(--fs-sm);
2053
+ padding: var(--space-2-5) var(--space-2-75); font-size: var(--fs-sm);
2051
2054
  }
2052
2055
  .ds-247420 .chat-avatar { width: 28px; height: 28px; font-size: 11px; }
2053
- .ds-247420 .chat-msg:hover { padding: 4px 0; margin: 0; background: transparent; }
2054
- .ds-247420 .chat-composer { padding: 8px; gap: 6px; }
2055
- .ds-247420 .chat-composer textarea { padding: 10px 12px; font-size: var(--fs-sm); }
2056
+ .ds-247420 .chat-msg:hover { padding: var(--space-1) 0; margin: 0; background: transparent; }
2057
+ .ds-247420 .chat-composer { padding: var(--space-2); gap: var(--space-1-75); }
2058
+ .ds-247420 .chat-composer textarea { padding: var(--space-2-5) var(--space-2-75); font-size: var(--fs-sm); }
2056
2059
 
2057
2060
  /* KPI Cards */
2058
2061
  .ds-247420 .kpi {
@@ -2068,9 +2071,10 @@
2068
2071
  .ds-247420 .empty { padding: var(--space-5); font-size: var(--fs-xs); }
2069
2072
 
2070
2073
  /* Form */
2071
- .ds-247420 .row-form { gap: 10px; padding: var(--space-3); }
2074
+ .ds-247420 .row-form { gap: var(--space-2-5); padding: var(--space-3); }
2072
2075
  .ds-247420 .row-form input,
2073
- .ds-247420 .row-form textarea { padding: 11px 12px; font-size: var(--fs-sm); }
2076
+
2077
+ .ds-247420 .row-form textarea { padding: 11px var(--space-2-75); font-size: var(--fs-sm); }
2074
2078
 
2075
2079
  /* Hero Section — keep fluid base font-size, just unconstrain width on mobile. */
2076
2080
  .ds-247420 .ds-hero { padding: var(--space-6) 0 var(--space-5); }
@@ -2080,14 +2084,14 @@
2080
2084
  /* Table Responsiveness */
2081
2085
  .ds-247420 table { font-size: var(--fs-xs); }
2082
2086
  .ds-247420 table th,
2083
- .ds-247420 table td { padding: 10px 12px; }
2087
+ .ds-247420 table td { padding: var(--space-2-5) var(--space-2-75); }
2084
2088
 
2085
2089
  /* CLI Block */
2086
2090
  .ds-247420 .cli {
2087
- flex-direction: column; align-items: flex-start; gap: 10px;
2088
- padding: 16px 12px; font-size: var(--fs-xs);
2091
+ flex-direction: column; align-items: flex-start; gap: var(--space-2-5);
2092
+ padding: var(--space-3) var(--space-2-75); font-size: var(--fs-xs);
2089
2093
  }
2090
- .ds-247420 .cli .copy { padding: 6px 12px; font-size: var(--fs-micro); }
2094
+ .ds-247420 .cli .copy { padding: var(--space-1-75) var(--space-2-75); font-size: var(--fs-micro); }
2091
2095
  }
2092
2096
 
2093
2097
  /* --------------------------------------------------------------------
@@ -2096,8 +2100,8 @@
2096
2100
  @container (max-width: 760px) {
2097
2101
  .ds-247420 .app-body { grid-template-columns: 1fr !important; }
2098
2102
  .ds-247420 .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
2099
- .ds-247420 .app-topbar nav { font-size: var(--fs-xs); gap: 14px; }
2100
- .ds-247420 .row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: 4px !important; }
2103
+ .ds-247420 .app-topbar nav { font-size: var(--fs-xs); gap: var(--space-2-75); }
2104
+ .ds-247420 .row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: var(--space-1) !important; }
2101
2105
  .ds-247420 .row .sub { grid-column: 1 / -1; order: 3; }
2102
2106
  .ds-247420 .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
2103
2107
  .ds-247420 .ds-changelog-row .title { grid-column: 1 / -1; }
@@ -2109,7 +2113,7 @@
2109
2113
  @media (min-width: 481px) and (max-width: 1024px) {
2110
2114
  /* App Layout — side handled by 900px drawer block; restore for 901-1024 */
2111
2115
  .ds-247420 .app-side a {
2112
- padding: 12px 12px; gap: 8px;
2116
+ padding: var(--space-2-75) var(--space-2-75); gap: var(--space-2);
2113
2117
  grid-template-columns: 16px 1fr auto;
2114
2118
  font-size: var(--fs-xs);
2115
2119
  min-height: 44px;
@@ -2117,14 +2121,14 @@
2117
2121
 
2118
2122
  /* Topbar Navigation (flex container — no grid-template here) */
2119
2123
  .ds-247420 .app-topbar {
2120
- gap: var(--space-3); padding: 12px var(--space-4);
2124
+ gap: var(--space-3); padding: var(--space-2-75) var(--space-4);
2121
2125
  }
2122
2126
  .ds-247420 .app-topbar nav {
2123
- display: flex; gap: 8px; font-size: var(--fs-xs);
2127
+ display: flex; gap: var(--space-2); font-size: var(--fs-xs);
2124
2128
  flex-wrap: wrap;
2125
2129
  }
2126
2130
  .ds-247420 .app-topbar nav a {
2127
- padding: 12px 12px; font-size: var(--fs-xs);
2131
+ padding: var(--space-2-75) var(--space-2-75); font-size: var(--fs-xs);
2128
2132
  min-height: 44px;
2129
2133
  }
2130
2134
  .ds-247420 .brand { font-size: var(--fs-sm); }
@@ -2133,7 +2137,10 @@
2133
2137
  .ds-247420 .app-search {
2134
2138
  display: inline-flex;
2135
2139
  max-width: 280px; font-size: var(--fs-xs);
2136
- padding: 8px 14px;
2140
+ /* 14px inline is between --space-2-75 (12) and --space-3 (16) with no tier;
2141
+ it is the width that centers the search glyph against the 280px max-width
2142
+ field. Snapping either way reads as a mis-centered control. */
2143
+ padding: var(--space-2) 14px;
2137
2144
  }
2138
2145
 
2139
2146
  /* Main Content */
@@ -2145,12 +2152,17 @@
2145
2152
  /* File list — single column rows on tablet (cards only via data-columns) */
2146
2153
  .ds-247420 .ds-file-row {
2147
2154
  grid-template-columns: 24px minmax(0, 1fr) auto auto;
2148
- gap: 12px; padding: 12px 14px;
2155
+ /* 14px inline (no tier between 12 and 16) is the tablet row inset that
2156
+ keeps the 24px icon column optically flush with the panel edge. */
2157
+ gap: var(--space-2-75); padding: var(--space-2-75) 14px;
2149
2158
  }
2150
2159
 
2151
2160
  /* Chat Bubbles */
2152
2161
  .ds-247420 .chat-stack { max-width: min(75%, 420px); }
2153
2162
  .ds-247420 .chat-bubble {
2163
+ /* 11px/14px are the tuned tablet bubble insets; neither is on the scale
2164
+ (11 sits between --space-2-5 and --space-2-75, 14 between --space-2-75
2165
+ and --space-3) and snapping visibly re-pitches every bubble in a thread. */
2154
2166
  padding: 11px 14px; font-size: var(--fs-sm);
2155
2167
  }
2156
2168
  .ds-247420 .chat-avatar { width: 32px; height: 32px; font-size: 12px; }
@@ -2163,7 +2175,10 @@
2163
2175
 
2164
2176
  /* Buttons */
2165
2177
  .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost {
2166
- padding: 12px 18px; font-size: var(--fs-sm);
2178
+ /* 18px inline has no tier (--space-3 is 16, --space-3-5 is 20); it is the
2179
+ tablet CTA width tuned against the 12px vertical, so snapping changes
2180
+ the button aspect on the most visible control in the kit. */
2181
+ padding: var(--space-2-75) 18px; font-size: var(--fs-sm);
2167
2182
  }
2168
2183
 
2169
2184
  /* Panel - keep the head on the body's left axis at laptop widths too. */
@@ -2177,7 +2192,9 @@
2177
2192
  /* Row */
2178
2193
  .ds-247420 .row {
2179
2194
  grid-template-columns: minmax(90px, 12ch) minmax(0, 1fr) auto;
2180
- gap: var(--space-2); padding: 14px 16px;
2195
+ /* 14px block (no tier between 12 and 16) is the tablet row height tuned
2196
+ against the 12ch code column; snapping re-pitches the whole list. */
2197
+ gap: var(--space-2); padding: 14px var(--space-3);
2181
2198
  }
2182
2199
  }
2183
2200
 
@@ -2235,7 +2252,7 @@
2235
2252
  .ds-247420 .ds-file-grid {
2236
2253
  display: flex;
2237
2254
  flex-direction: column;
2238
- gap: 4px;
2255
+ gap: var(--space-1);
2239
2256
  }
2240
2257
  .ds-247420 .ds-file-grid:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); border-radius: var(--r-2); }
2241
2258
 
@@ -2246,7 +2263,7 @@
2246
2263
  /* The filter is now an inline item in the single .ds-file-controls toolbar row
2247
2264
  (the standalone right-aligned .ds-file-filter strip was removed). */
2248
2265
  .ds-247420 .ds-file-filter-input {
2249
- width: min(280px, 100%); padding: 6px 12px; font-size: var(--fs-sm);
2266
+ width: min(280px, 100%); padding: var(--space-1-75) var(--space-2-75); font-size: var(--fs-sm);
2250
2267
  background: var(--bg); color: var(--fg);
2251
2268
  border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
2252
2269
  }
@@ -2256,7 +2273,7 @@
2256
2273
  .ds-247420 .ds-file-sort { display: flex; gap: var(--space-2); padding: 0 var(--space-2) var(--space-1); }
2257
2274
  .ds-247420 .ds-file-sort-btn {
2258
2275
  font-size: var(--fs-tiny); font-family: var(--ff-mono); color: var(--fg-3);
2259
- background: none; border: none; cursor: pointer; padding: 2px 4px; border-radius: var(--r-1);
2276
+ background: none; border: none; cursor: pointer; padding: var(--space-hair) var(--space-1); border-radius: var(--r-1);
2260
2277
  }
2261
2278
  .ds-247420 .ds-file-sort-btn:hover { color: var(--fg-2); background: var(--bg-2); }
2262
2279
  .ds-247420 .ds-file-sort-btn.active { color: var(--accent-ink); }
@@ -2271,9 +2288,9 @@
2271
2288
  .ds-247420 .ds-file-grid { transition: opacity .15s var(--ease); }
2272
2289
  }
2273
2290
  /* EventList loading skeleton (shares the .ds-skel shimmer base above). */
2274
- .ds-247420 .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: 12px 16px; pointer-events: none; }
2291
+ .ds-247420 .ds-event-row-skeleton { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2-75) var(--space-3); pointer-events: none; }
2275
2292
  .ds-247420 .ds-skel-rank { height: 12px; width: 2.5ch; }
2276
- .ds-247420 .ds-event-state { padding: var(--space-2) 16px; }
2293
+ .ds-247420 .ds-event-state { padding: var(--space-2) var(--space-3); }
2277
2294
  .ds-247420 .ds-skel { display: inline-block; border-radius: var(--r-1); background: var(--bg-2); position: relative; overflow: hidden; }
2278
2295
  .ds-247420 .ds-skel::after {
2279
2296
  content: ''; position: absolute; inset: 0;
@@ -2292,8 +2309,13 @@
2292
2309
  because FileRow wraps the row content in a real button for native keyboard
2293
2310
  semantics. */
2294
2311
  .ds-247420 .ds-file-row {
2295
- display: flex; align-items: center; gap: 10px;
2296
- padding: 11px 16px; background: var(--bg);
2312
+ display: flex; align-items: center; gap: var(--space-2-5);
2313
+ /* 11px vertical is an optical half-step between --space-2-5 (10) and
2314
+ --space-2-75 (12), deliberately off-scale: with the 26px .ds-file-icon
2315
+ and the hairline borders it lands the row at ~50px, comfortably over the
2316
+ 44px touch floor without the 52px a 12px pad would give. Snapping either
2317
+ way visibly re-pitches every row in a long listing. */
2318
+ padding: 11px var(--space-3); background: var(--bg);
2297
2319
  border: var(--bw-hair) solid transparent;
2298
2320
  border-radius: var(--r-2); color: var(--fg);
2299
2321
  cursor: pointer;
@@ -2302,7 +2324,7 @@
2302
2324
  transform var(--dur-snap) var(--ease);
2303
2325
  }
2304
2326
  .ds-247420 .ds-file-open {
2305
- display: flex; align-items: center; gap: 14px;
2327
+ display: flex; align-items: center; gap: var(--space-2-75);
2306
2328
  flex: 1 1 auto; min-width: 0;
2307
2329
  background: none; border: 0; padding: 0; margin: 0;
2308
2330
  color: inherit; font: inherit; text-align: left; cursor: pointer;
@@ -2365,7 +2387,7 @@
2365
2387
  hidden, which left mouse/trackpad users unable to find rename/move/delete
2366
2388
  without accidentally hovering a row), full opacity on hover/focus. */
2367
2389
  .ds-247420 .ds-file-actions {
2368
- display: inline-flex; gap: 2px; align-items: center;
2390
+ display: inline-flex; gap: var(--space-hair); align-items: center;
2369
2391
  opacity: 0.35; transition: opacity var(--dur-base) var(--ease);
2370
2392
  }
2371
2393
  .ds-247420 .ds-file-row:hover .ds-file-actions,
@@ -2410,7 +2432,7 @@
2410
2432
 
2411
2433
  .ds-247420 .ds-file-check {
2412
2434
  display: inline-flex; align-items: center; justify-content: center;
2413
- min-width: 28px; height: 28px; padding: 0 4px;
2435
+ min-width: 28px; height: 28px; padding: 0 var(--space-1);
2414
2436
  background: transparent; border: 0; border-radius: var(--r-1);
2415
2437
  color: var(--fg-3);
2416
2438
  cursor: pointer;
@@ -2442,7 +2464,7 @@
2442
2464
  quiet destructive outline - the app arm-confirms destructive bulk actions
2443
2465
  via ConfirmDialog, so the strip never needs a loud CTA. */
2444
2466
  .ds-247420 .ds-bulkbar .btn, .ds-247420 .ds-bulkbar .btn-primary {
2445
- padding: 5px 12px; min-height: 32px; border-radius: var(--r-1); font-weight: 500;
2467
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px; border-radius: var(--r-1); font-weight: 500;
2446
2468
  }
2447
2469
  .ds-247420 .ds-bulkbar .btn { background: transparent; border: var(--bw-hair) solid var(--rule); color: var(--fg-2); }
2448
2470
  .ds-247420 .ds-bulkbar .btn:hover { background: var(--bg-2); color: var(--fg); }
@@ -2454,7 +2476,7 @@
2454
2476
 
2455
2477
  /* Density picker — list / compact / thumbnails. */
2456
2478
  .ds-247420 .ds-density {
2457
- display: inline-flex; gap: 2px; padding: 2px;
2479
+ display: inline-flex; gap: var(--space-hair); padding: var(--space-hair);
2458
2480
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
2459
2481
  }
2460
2482
  .ds-247420 .ds-density-btn {
@@ -2469,8 +2491,8 @@
2469
2491
  .ds-247420 .ds-density-btn:focus-visible { outline: var(--focus-w) solid var(--focus-color); outline-offset: var(--focus-offset); }
2470
2492
 
2471
2493
  /* Compact density — tighter rows for long listings. */
2472
- .ds-247420 .ds-file-grid[data-density="compact"] { gap: 2px; }
2473
- .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row { padding: 5px 12px; gap: 10px; }
2494
+ .ds-247420 .ds-file-grid[data-density="compact"] { gap: var(--space-hair); }
2495
+ .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row { padding: var(--space-1-5) var(--space-2-75); gap: var(--space-2-5); }
2474
2496
  .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row .title { font-size: var(--fs-xs); }
2475
2497
  .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-row .ds-file-meta { font-size: var(--fs-micro); }
2476
2498
  .ds-247420 .ds-file-grid[data-density="compact"] .ds-file-icon { width: 20px; height: 20px; font-size: 13px; }
@@ -2492,11 +2514,14 @@
2492
2514
  .ds-247420 .ds-file-cell.is-locked { opacity: 0.6; }
2493
2515
  .ds-247420 .ds-file-row.is-locked { opacity: 0.6; }
2494
2516
  .ds-247420 .ds-file-row.is-restricted .title { color: var(--fg-2); }
2495
- /* A fourth, deliberately bordered/mono tag variant for file-permission tags
2517
+ /* 1px vertical pad is deliberately below --space-hair (2px): this mono tag
2518
+ sits inline in a file row and must not add height to it; --space-hair would
2519
+ double the vertical pad and push the tag past the row cap height.
2520
+ A fourth, deliberately bordered/mono tag variant for file-permission tags
2496
2521
  specifically (distinct from .ds-badge for numeric counts and .chip for
2497
2522
  status/label words) - is-noaccess reuses the shared --flame tone token
2498
2523
  so 'no access' reads the same red as chip.tone-error/miss elsewhere. */
2499
- .ds-247420 .ds-file-perm-tag { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); padding: 1px 6px; border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); white-space: nowrap; }
2524
+ .ds-247420 .ds-file-perm-tag { font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--fg-3); padding: 1px var(--space-1-75); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1); white-space: nowrap; }
2500
2525
  .ds-247420 .ds-file-perm-tag.is-noaccess { color: var(--flame); border-color: var(--flame); }
2501
2526
  .ds-247420 .ds-file-cell-open {
2502
2527
  display: flex; flex-direction: column; align-items: stretch; gap: var(--space-1);
@@ -2565,12 +2590,12 @@
2565
2590
 
2566
2591
  /* Breadcrumb path */
2567
2592
  .ds-247420 .ds-crumb-path {
2568
- display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
2593
+ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-hair);
2569
2594
  font-size: var(--fs-sm);
2570
2595
  }
2571
2596
  .ds-247420 .ds-crumb-seg {
2572
2597
  background: transparent; border: 0; cursor: pointer;
2573
- padding: 4px 8px; border-radius: var(--r-1);
2598
+ padding: var(--space-1) var(--space-2); border-radius: var(--r-1);
2574
2599
  color: var(--fg-3); font-family: inherit; font-size: var(--fs-sm);
2575
2600
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
2576
2601
  /* A single long unbroken segment (hash-named dir) must never force the
@@ -2618,7 +2643,7 @@
2618
2643
  /* Toolbar-scoped buttons: quiet, compact, rectangular - a toolbar is chrome,
2619
2644
  not a CTA row; the stadium pill stays for real page-level actions. */
2620
2645
  .ds-247420 .ds-file-toolbar .btn, .ds-247420 .ds-file-toolbar .btn-ghost {
2621
- padding: 5px 12px; min-height: 32px;
2646
+ padding: var(--space-1-5) var(--space-2-75); min-height: 32px;
2622
2647
  border-radius: var(--r-1);
2623
2648
  font-weight: 500;
2624
2649
  background: transparent;
@@ -2635,7 +2660,7 @@
2635
2660
 
2636
2661
  /* Error banner — dismissible toast row. */
2637
2662
  .ds-247420 .ds-error-banner {
2638
- padding: 10px 14px; border-radius: var(--r-2);
2663
+ padding: var(--space-2-5) var(--space-2-75); border-radius: var(--r-2);
2639
2664
  background: color-mix(in oklab, var(--warn) 14%, var(--bg));
2640
2665
  border: var(--bw-hair) solid color-mix(in oklab, var(--warn) 40%, transparent);
2641
2666
  color: var(--warn); font-size: var(--fs-sm); cursor: pointer;
@@ -2692,11 +2717,11 @@
2692
2717
  }
2693
2718
 
2694
2719
  /* Upload progress */
2695
- .ds-247420 .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
2720
+ .ds-247420 .ds-upload-progress { display: flex; flex-direction: column; gap: var(--space-1-75); }
2696
2721
  .ds-247420 .ds-upload-item {
2697
2722
  display: grid; grid-template-columns: minmax(0, 1fr) 120px 44px;
2698
2723
  gap: var(--space-2); align-items: center;
2699
- padding: 8px 12px; border-radius: var(--r-2);
2724
+ padding: var(--space-2) var(--space-2-75); border-radius: var(--r-2);
2700
2725
  background: var(--bg-2); font-size: var(--fs-xs);
2701
2726
  }
2702
2727
  .ds-247420 .ds-upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -2740,7 +2765,7 @@
2740
2765
  }
2741
2766
  .ds-247420 .ds-upload-actions { display: inline-flex; gap: var(--space-1); justify-content: flex-end; }
2742
2767
  .ds-247420 .ds-upload-act {
2743
- padding: 2px 10px; min-height: 24px; cursor: pointer;
2768
+ padding: var(--space-hair) var(--space-2-5); min-height: 24px; cursor: pointer;
2744
2769
  background: var(--bg); border: var(--bw-hair) solid var(--rule); border-radius: var(--r-1);
2745
2770
  color: var(--fg-2); font-family: var(--ff-body); font-size: var(--fs-micro);
2746
2771
  }
@@ -2810,7 +2835,7 @@
2810
2835
  border-top: var(--bw-hair) solid var(--rule);
2811
2836
  }
2812
2837
  .ds-247420 .ds-modal-input {
2813
- width: 100%; padding: 10px 12px;
2838
+ width: 100%; padding: var(--space-2-5) var(--space-2-75);
2814
2839
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule);
2815
2840
  border-radius: var(--r-2); color: var(--fg);
2816
2841
  font-family: inherit; font-size: var(--fs-sm);
@@ -2822,10 +2847,10 @@
2822
2847
  }
2823
2848
  /* PromptDialog's optional roots-chip row (destination-path prompts with more
2824
2849
  than one allowed root) - same chip idiom the cwd editor's roots row uses. */
2825
- .ds-247420 .ds-prompt-roots { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
2850
+ .ds-247420 .ds-prompt-roots { display: flex; align-items: center; gap: var(--space-1-75); flex-wrap: wrap; margin-top: var(--space-2); }
2826
2851
  .ds-247420 .ds-prompt-root-chip {
2827
2852
  background: var(--bg-2); border: var(--bw-hair) solid var(--rule); color: var(--fg-2);
2828
- border-radius: var(--r-pill); padding: 3px 10px; font: inherit; font-size: var(--fs-tiny);
2853
+ border-radius: var(--r-pill); padding: var(--space-half) var(--space-2-5); font: inherit; font-size: var(--fs-tiny);
2829
2854
  cursor: pointer;
2830
2855
  }
2831
2856
  .ds-247420 .ds-prompt-root-chip:hover { border-color: var(--accent); color: var(--fg); }
@@ -2834,7 +2859,7 @@
2834
2859
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
2835
2860
  the dialog, not behind the fixed overlay. */
2836
2861
  .ds-247420 .ds-modal-error {
2837
- margin: var(--space-2) 0 0; padding: 8px 10px;
2862
+ margin: var(--space-2) 0 0; padding: var(--space-2) var(--space-2-5);
2838
2863
  border: var(--bw-hair) solid var(--flame); border-radius: var(--r-2);
2839
2864
  background: color-mix(in oklab, var(--flame) 12%, var(--bg));
2840
2865
  color: var(--flame); font-size: var(--fs-xs);
@@ -2862,7 +2887,7 @@
2862
2887
  color: var(--fg-3); white-space: nowrap;
2863
2888
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
2864
2889
  }
2865
- .ds-247420 .ds-preview-actions { display: inline-flex; gap: 2px; margin-left: auto; }
2890
+ .ds-247420 .ds-preview-actions { display: inline-flex; gap: var(--space-hair); margin-left: auto; }
2866
2891
  .ds-247420 .ds-preview-body {
2867
2892
  flex: 1; min-height: 0; overflow: auto;
2868
2893
  padding: var(--space-3) var(--space-4);
@@ -2949,7 +2974,7 @@
2949
2974
  .ds-247420 .ds-file-stage { padding: var(--space-3) var(--space-2); }
2950
2975
  /* Preview head: let it wrap and drop the nowrap meta (duplicated in body)
2951
2976
  so the close button can never be pushed past the modal edge. */
2952
- .ds-247420 .ds-preview-head { flex-wrap: wrap; row-gap: 4px; }
2977
+ .ds-247420 .ds-preview-head { flex-wrap: wrap; row-gap: var(--space-1); }
2953
2978
  .ds-247420 .ds-preview-meta { display: none; }
2954
2979
  }
2955
2980
 
@@ -3109,7 +3134,7 @@
3109
3134
  flex: 1; min-height: 0; gap: var(--space-3);
3110
3135
  }
3111
3136
  .ds-247420 .chat-head {
3112
- display: flex; align-items: baseline; gap: 8px;
3137
+ display: flex; align-items: baseline; gap: var(--space-2);
3113
3138
  padding: var(--space-3) 0 var(--space-2);
3114
3139
  font-family: var(--ff-mono); font-size: var(--fs-xs);
3115
3140
  color: var(--fg-3); text-transform: lowercase; letter-spacing: 0.02em;
@@ -3147,10 +3172,10 @@
3147
3172
  .ds-247420 .chat-empty-title { font-size: var(--fs-sm); margin: 0 0 var(--space-1); }
3148
3173
  .ds-247420 .chat-empty-sub { font-size: var(--fs-tiny); margin: 0; opacity: .7; }
3149
3174
 
3150
- .ds-247420 .chat-msg { display: flex; gap: 12px; align-items: flex-start; padding: 6px 0; position: relative; min-width: 0; }
3175
+ .ds-247420 .chat-msg { display: flex; gap: var(--space-2-75); align-items: flex-start; padding: var(--space-1-75) 0; position: relative; min-width: 0; }
3151
3176
  .ds-247420 .chat-msg.you { flex-direction: row-reverse; }
3152
3177
  .ds-247420 .chat-msg.you .chat-stack { align-items: flex-end; }
3153
- .ds-247420 .chat-msg:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); padding: 6px 0; margin: 0; border-radius: var(--r-0); transition: background var(--dur-base) var(--ease); }
3178
+ .ds-247420 .chat-msg:hover { background: color-mix(in oklab, var(--fg) 4%, transparent); padding: var(--space-1-75) 0; margin: 0; border-radius: var(--r-0); transition: background var(--dur-base) var(--ease); }
3154
3179
 
3155
3180
  .ds-247420 .chat-avatar {
3156
3181
  width: 36px; height: 36px; flex-shrink: 0;
@@ -3172,13 +3197,16 @@
3172
3197
  }
3173
3198
 
3174
3199
  .ds-247420 .chat-stack {
3175
- display: flex; flex-direction: column; gap: 4px;
3200
+ display: flex; flex-direction: column; gap: var(--space-1);
3176
3201
  max-width: min(70%, 56ch); min-width: 0;
3177
3202
  flex: 0 1 auto; overflow: hidden;
3178
3203
  }
3179
3204
 
3180
3205
  .ds-247420 .chat-bubble {
3181
- padding: 10px 14px; background: var(--bg-2); color: var(--fg);
3206
+ /* 14px inline has no tier (--space-2-75 is 12, --space-3 is 16). It is the
3207
+ shared bubble/attachment inset used by .chat-file/.chat-pdf-head below;
3208
+ snapping only this one would visibly desync the bubble from its cards. */
3209
+ padding: var(--space-2-5) 14px; background: var(--bg-2); color: var(--fg);
3182
3210
  max-width: 100%;
3183
3211
  border-radius: var(--r-2); line-height: 1.55;
3184
3212
  word-wrap: break-word; overflow-wrap: anywhere;
@@ -3196,7 +3224,9 @@
3196
3224
  .ds-247420 .chat-bubble code {
3197
3225
  font-family: var(--ff-mono); font-size: 0.92em;
3198
3226
  background: color-mix(in oklab, var(--fg) 10%, transparent);
3199
- padding: 1px 6px; border-radius: var(--r-0);
3227
+ /* 1px block is deliberately under --space-hair (2px): inline <code> must not
3228
+ grow the line box of the prose it sits inside. */
3229
+ padding: 1px var(--space-1-75); border-radius: var(--r-0);
3200
3230
  }
3201
3231
  .ds-247420 .chat-msg.you .chat-bubble code { background: color-mix(in oklab, var(--fg) 10%, transparent); }
3202
3232
  .ds-247420 .chat-bubble a {
@@ -3223,10 +3253,11 @@
3223
3253
  .ds-247420 .chat-bubble.chat-md h3 { font-size: 1.04em; }
3224
3254
  .ds-247420 .chat-bubble.chat-md p { margin: var(--space-2) 0; }
3225
3255
  .ds-247420 .chat-bubble.chat-md ul,
3256
+
3226
3257
  .ds-247420 .chat-bubble.chat-md ol { margin: var(--space-2) 0; padding-left: 22px; }
3227
3258
  .ds-247420 .chat-bubble.chat-md li { margin: var(--space-1) 0; }
3228
3259
  .ds-247420 .chat-bubble.chat-md blockquote {
3229
- margin: var(--space-2) 0; padding: 4px 12px;
3260
+ margin: var(--space-2) 0; padding: var(--space-1) var(--space-2-75);
3230
3261
  /* DELIBERATE, but slimmed to the --bw-rule tier. This is a real markdown
3231
3262
  <blockquote> inside a chat bubble: the left rule is the standard
3232
3263
  typographic quotation mark, not a colored alert stripe (the tone is a
@@ -3238,7 +3269,7 @@
3238
3269
  .ds-247420 .chat-bubble.chat-md pre {
3239
3270
  background: var(--bg);
3240
3271
  border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
3241
- padding: 12px 16px; border-radius: var(--r-1); overflow-x: auto;
3272
+ padding: var(--space-2-75) var(--space-3); border-radius: var(--r-1); overflow-x: auto;
3242
3273
  font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
3243
3274
  color: var(--fg); margin: var(--space-2) 0;
3244
3275
  }
@@ -3252,11 +3283,11 @@
3252
3283
  }
3253
3284
  /* Markdown tables + horizontal rules: agents routinely emit them, but they were
3254
3285
  unstyled (bare unspaced cells, vanished rules). */
3255
- .ds-247420 .chat-bubble.chat-md table { border-collapse: collapse; width: auto; max-width: 100%; margin: 8px 0; font-size: .95em; display: block; overflow-x: auto; }
3286
+ .ds-247420 .chat-bubble.chat-md table { border-collapse: collapse; width: auto; max-width: 100%; margin: var(--space-2) 0; font-size: .95em; display: block; overflow-x: auto; }
3256
3287
  .ds-247420 .chat-bubble.chat-md th,
3257
- .ds-247420 .chat-bubble.chat-md td { border: var(--bw-hair) solid var(--rule); padding: 4px 10px; text-align: left; }
3288
+ .ds-247420 .chat-bubble.chat-md td { border: var(--bw-hair) solid var(--rule); padding: var(--space-1) var(--space-2-5); text-align: left; }
3258
3289
  .ds-247420 .chat-bubble.chat-md th { background: color-mix(in oklab, var(--fg) 5%, transparent); font-weight: 600; }
3259
- .ds-247420 .chat-bubble.chat-md hr { border: 0; border-top: var(--bw-hair) solid var(--rule); margin: 12px 0; }
3290
+ .ds-247420 .chat-bubble.chat-md hr { border: 0; border-top: var(--bw-hair) solid var(--rule); margin: var(--space-2-75) 0; }
3260
3291
 
3261
3292
  /* Mermaid diagram blocks — rendered SVG swapped in over the fenced source by
3262
3293
  src/mermaid.js's renderMermaidBlocksUnder(); the source .pre stays in the
@@ -3264,7 +3295,7 @@
3264
3295
  .ds-247420 .ds-mermaid-block {
3265
3296
  position: relative; margin: var(--space-2) 0;
3266
3297
  border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
3267
- border-radius: var(--r-1); background: var(--bg); padding: 12px 16px;
3298
+ border-radius: var(--r-1); background: var(--bg); padding: var(--space-2-75) var(--space-3);
3268
3299
  }
3269
3300
  .ds-247420 .ds-mermaid-diagram { overflow-x: auto; display: flex; justify-content: center; }
3270
3301
  .ds-247420 .ds-mermaid-diagram svg { max-width: 100%; height: auto; }
@@ -3273,7 +3304,7 @@
3273
3304
  font: inherit; font-size: var(--fs-xs); line-height: 1;
3274
3305
  background: color-mix(in oklab, var(--fg) 8%, transparent);
3275
3306
  color: var(--fg); border: none; border-radius: var(--r-1);
3276
- padding: 4px 8px; cursor: pointer;
3307
+ padding: var(--space-1) var(--space-2); cursor: pointer;
3277
3308
  }
3278
3309
  .ds-247420 .ds-mermaid-toggle:hover { background: color-mix(in oklab, var(--fg) 14%, transparent); }
3279
3310
 
@@ -3306,8 +3337,8 @@
3306
3337
  min-width: 0;
3307
3338
  }
3308
3339
  .ds-247420 .chat-code-head {
3309
- display: flex; align-items: center; gap: 10px;
3310
- padding: 8px 12px;
3340
+ display: flex; align-items: center; gap: var(--space-2-5);
3341
+ padding: var(--space-2) var(--space-2-75);
3311
3342
  background: color-mix(in oklab, var(--fg) 6%, var(--bg-2));
3312
3343
  border-bottom: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
3313
3344
  font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3);
@@ -3317,7 +3348,7 @@
3317
3348
  .ds-247420 .chat-code-head .name { color: var(--fg-2); font-weight: 500; }
3318
3349
  .ds-247420 .chat-code-head .spread { flex: 1; }
3319
3350
  .ds-247420 .chat-bubble.chat-code pre {
3320
- margin: 0; padding: 12px 16px; background: transparent;
3351
+ margin: 0; padding: var(--space-2-75) var(--space-3); background: transparent;
3321
3352
  font-family: var(--ff-mono); font-size: var(--fs-xs); line-height: 1.55;
3322
3353
  overflow-x: auto; color: var(--fg); border-radius: 0;
3323
3354
  }
@@ -3349,12 +3380,12 @@
3349
3380
  }
3350
3381
  .ds-247420 .chat-image img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; }
3351
3382
  .ds-247420 .chat-image .cap,
3352
- .ds-247420 .chat-image .caption { display: block; padding: 8px 12px; font-size: var(--fs-xs); color: var(--fg-3); font-family: var(--ff-mono); }
3383
+ .ds-247420 .chat-image .caption { display: block; padding: var(--space-2) var(--space-2-75); font-size: var(--fs-xs); color: var(--fg-3); font-family: var(--ff-mono); }
3353
3384
 
3354
3385
  .ds-247420 .chat-msg.you .chat-file,
3355
3386
  .ds-247420 .chat-msg .chat-file,
3356
3387
  .ds-247420 .chat-file {
3357
- display: flex; align-items: center; gap: 12px; padding: 12px 14px;
3388
+ display: flex; align-items: center; gap: var(--space-2-75); padding: var(--space-2-75) 14px;
3358
3389
  background: var(--bg-2); border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
3359
3390
  border-radius: var(--r-1); text-decoration: none; color: var(--fg);
3360
3391
  max-width: min(100%, 360px);
@@ -3367,12 +3398,12 @@
3367
3398
  background: var(--bg-3);
3368
3399
  color: var(--fg-2); border-radius: var(--r-0); flex-shrink: 0; font-family: var(--ff-mono);
3369
3400
  }
3370
- .ds-247420 .chat-file > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
3401
+ .ds-247420 .chat-file > div { display: flex; flex-direction: column; gap: var(--space-hair); min-width: 0; }
3371
3402
  .ds-247420 .chat-file .name {
3372
3403
  font-weight: 600; font-size: var(--fs-sm);
3373
3404
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
3374
3405
  }
3375
- .ds-247420 .chat-file .meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
3406
+ .ds-247420 .chat-file .meta { display: flex; flex-direction: column; gap: var(--space-hair); min-width: 0; flex: 1; }
3376
3407
  .ds-247420 .chat-file .size { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); }
3377
3408
  .ds-247420 .chat-file .go { font-family: var(--ff-mono); font-size: 16px; color: var(--fg-3); flex-shrink: 0; }
3378
3409
  .ds-247420 .chat-file:hover .go { color: var(--accent-ink); }
@@ -3388,7 +3419,7 @@
3388
3419
  }
3389
3420
  .ds-247420 .chat-msg:hover .chat-pdf { border-color: var(--rule); }
3390
3421
  .ds-247420 .chat-pdf-head {
3391
- display: flex; align-items: center; gap: 10px; padding: 10px 14px;
3422
+ display: flex; align-items: center; gap: var(--space-2-5); padding: var(--space-2-5) 14px;
3392
3423
  background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
3393
3424
  border-bottom: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
3394
3425
  }
@@ -3403,7 +3434,7 @@
3403
3434
  .ds-247420 .chat-msg.you .chat-link,
3404
3435
  .ds-247420 .chat-msg .chat-link,
3405
3436
  .ds-247420 .chat-link {
3406
- display: grid; grid-template-columns: 80px 1fr; gap: 12px; padding: 10px;
3437
+ display: grid; grid-template-columns: 80px 1fr; gap: var(--space-2-75); padding: var(--space-2-5);
3407
3438
  background: var(--bg-2);
3408
3439
  border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
3409
3440
  border-radius: var(--r-1); text-decoration: none; color: var(--fg);
@@ -3417,28 +3448,28 @@
3417
3448
  .ds-247420 .chat-link:not(:has(.thumb)):not(:has(img)) { grid-template-columns: 1fr; }
3418
3449
  .ds-247420 .chat-link .thumb,
3419
3450
  .ds-247420 .chat-link img.thumb { width: 80px; height: 80px; border-radius: var(--r-0); object-fit: cover; background: var(--bg-3) center/cover no-repeat; }
3420
- .ds-247420 .chat-link .meta { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
3451
+ .ds-247420 .chat-link .meta { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
3421
3452
  .ds-247420 .chat-link .host { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); text-transform: lowercase; }
3422
3453
  .ds-247420 .chat-link .title { font-weight: 600; font-size: var(--fs-sm); line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
3423
3454
  .ds-247420 .chat-link .desc { font-size: var(--fs-xs); color: var(--fg-2); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
3424
3455
 
3425
3456
  .ds-247420 .chat-meta {
3426
- display: flex; align-items: center; gap: 6px;
3457
+ display: flex; align-items: center; gap: var(--space-1-75);
3427
3458
  font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3);
3428
- padding: 0 6px; letter-spacing: 0.02em;
3459
+ padding: 0 var(--space-1-75); letter-spacing: 0.02em;
3429
3460
  }
3430
3461
  .ds-247420 .chat-meta .who { font-weight: 600; color: var(--fg-2); }
3431
3462
  .ds-247420 .chat-meta .who::after { content: ' ·'; color: var(--fg-3); font-weight: 400; }
3432
3463
  .ds-247420 .chat-meta .t { color: var(--fg-3); }
3433
- .ds-247420 .chat-meta .tick { color: var(--fg-3); margin-left: 2px; letter-spacing: -2px; font-family: var(--ff-mono); }
3464
+ .ds-247420 .chat-meta .tick { color: var(--fg-3); margin-left: var(--space-hair); letter-spacing: -2px; font-family: var(--ff-mono); }
3434
3465
  .ds-247420 .chat-meta .tick.read { color: var(--accent-ink); }
3435
3466
 
3436
3467
  .ds-247420 .chat-reactions {
3437
- display: flex; gap: 4px; flex-wrap: wrap; margin-top: 2px;
3468
+ display: flex; gap: var(--space-1); flex-wrap: wrap; margin-top: var(--space-hair);
3438
3469
  }
3439
3470
  .ds-247420 .chat-reactions .rxn {
3440
- display: inline-flex; align-items: center; gap: 4px;
3441
- padding: 2px 8px; background: var(--bg-2);
3471
+ display: inline-flex; align-items: center; gap: var(--space-1);
3472
+ padding: var(--space-hair) var(--space-2); background: var(--bg-2);
3442
3473
  border: 1px solid color-mix(in oklab, var(--fg) 10%, transparent);
3443
3474
  border-radius: var(--r-pill); font-size: var(--fs-xs);
3444
3475
  cursor: pointer; user-select: none;
@@ -3455,7 +3486,7 @@
3455
3486
  .ds-247420 .chat-reactions .rxn .n { font-family: var(--ff-mono); font-weight: 600; font-size: 11px; color: var(--fg-2); }
3456
3487
  .ds-247420 .chat-reactions .rxn.you .n { color: var(--accent-ink); }
3457
3488
 
3458
- .ds-247420 .chat-typing { display: inline-flex; gap: 4px; align-items: center; }
3489
+ .ds-247420 .chat-typing { display: inline-flex; gap: var(--space-1); align-items: center; }
3459
3490
  .ds-247420 .chat-typing span {
3460
3491
  width: 6px; height: 6px; border-radius: 50%; background: var(--fg-3);
3461
3492
  }
@@ -3523,7 +3554,7 @@
3523
3554
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--flame) 22%, transparent);
3524
3555
  }
3525
3556
  .ds-247420 .chat-composer textarea {
3526
- flex: 1; min-width: 0; padding: 8px 4px;
3557
+ flex: 1; min-width: 0; padding: var(--space-2) var(--space-1);
3527
3558
  background: none; color: var(--fg);
3528
3559
  border: none; border-radius: 0;
3529
3560
  font-family: inherit; font-size: var(--fs-sm);
@@ -3577,7 +3608,7 @@
3577
3608
  .ds-247420 .composer-btn { transition: none; }
3578
3609
  }
3579
3610
 
3580
- .ds-247420 .aicat-portrait { display: inline-flex; align-items: center; gap: 10px; padding: 4px 0; }
3611
+ .ds-247420 .aicat-portrait { display: inline-flex; align-items: center; gap: var(--space-2-5); padding: var(--space-1) 0; }
3581
3612
  .ds-247420 .aicat-face {
3582
3613
  width: 32px; height: 32px; font-size: 24px;
3583
3614
  display: inline-flex; align-items: center; justify-content: center;
@@ -5061,7 +5092,7 @@
5061
5092
  }
5062
5093
 
5063
5094
  /* PhaseWalk */
5064
- .ds-247420 .ds-phasewalk { display: inline-flex; gap: 2px; vertical-align: middle; }
5095
+ .ds-247420 .ds-phasewalk { display: inline-flex; gap: var(--space-hair); vertical-align: middle; }
5065
5096
  .ds-247420 .ds-phasewalk-seg {
5066
5097
  width: 18px; height: 10px; border-radius: var(--r-hair);
5067
5098
  background: var(--bg-3); position: relative;
@@ -5070,6 +5101,10 @@
5070
5101
  .ds-247420 .ds-phasewalk-seg.is-gap { background: var(--warn); }
5071
5102
  /* Standalone PhaseWalk reserves headroom for the labels instead of letting
5072
5103
  them escape upward and overlap the element above. */
5104
+ /* 15px is load-bearing, not off-scale drift: it must equal the absolute
5105
+ `top: -15px` the label below is lifted by, so the label clears the segments
5106
+ without a gap. Snapping the pad to --space-3 (16px) alone would desync the
5107
+ pair. */
5073
5108
  .ds-247420 .ds-phasewalk { padding-top: 15px; }
5074
5109
  .ds-247420 .ds-phasewalk-lbl {
5075
5110
  position: absolute; top: -15px; left: 0;
@@ -5082,25 +5117,25 @@
5082
5117
 
5083
5118
  /* TreeNode */
5084
5119
  .ds-247420 .ds-tree-node {
5085
- padding: 5px 10px; border-left: var(--bw-rule) solid var(--bg-3);
5086
- margin: 2px 0 2px 16px; font-size: var(--fs-tiny);
5120
+ padding: var(--space-1-5) var(--space-2-5); border-left: var(--bw-rule) solid var(--bg-3);
5121
+ margin: var(--space-hair) 0 var(--space-hair) var(--space-3); font-size: var(--fs-tiny);
5087
5122
  min-width: 0; overflow-wrap: anywhere;
5088
5123
  }
5089
5124
  @media (max-width: 400px) {
5090
- .ds-247420 .ds-tree-node { margin-left: 8px; padding-left: 8px; }
5125
+ .ds-247420 .ds-tree-node { margin-left: var(--space-2); padding-left: var(--space-2); }
5091
5126
  }
5092
5127
  .ds-247420 .ds-tree-node.is-phase { border-color: var(--accent); background: var(--bg-3); font-weight: 600; }
5093
5128
  .ds-247420 .ds-tree-node.is-deviation { border-color: var(--warn); background: var(--danger-surface); color: var(--warn); }
5094
5129
  .ds-247420 .ds-tree-node.is-mutable-resolve { border-color: var(--success); }
5095
5130
  .ds-247420 .ds-tree-node.is-prd-add { border-color: var(--amber); }
5096
- .ds-247420 .ds-tree-node-ts { margin-right: 8px; color: var(--fg-3); }
5097
- .ds-247420 .ds-tree-node-pills { margin-left: 6px; }
5098
- .ds-247420 .ds-tree-node-reason { margin-top: 2px; color: var(--fg-2); }
5099
- .ds-247420 .ds-tree-node-deviation { margin-top: 2px; }
5100
- .ds-247420 .ds-tree-node-residuals { margin-top: 2px; color: var(--fg-3); }
5131
+ .ds-247420 .ds-tree-node-ts { margin-right: var(--space-2); color: var(--fg-3); }
5132
+ .ds-247420 .ds-tree-node-pills { margin-left: var(--space-1-75); }
5133
+ .ds-247420 .ds-tree-node-reason { margin-top: var(--space-hair); color: var(--fg-2); }
5134
+ .ds-247420 .ds-tree-node-deviation { margin-top: var(--space-hair); }
5135
+ .ds-247420 .ds-tree-node-residuals { margin-top: var(--space-hair); color: var(--fg-3); }
5101
5136
 
5102
5137
  /* BarRow */
5103
- .ds-247420 .ds-bar-row { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: var(--fs-tiny); }
5138
+ .ds-247420 .ds-bar-row { display: flex; align-items: center; gap: var(--space-2); margin: var(--space-half) 0; font-size: var(--fs-tiny); }
5104
5139
  .ds-247420 .ds-bar-row-label { width: 100px; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
5105
5140
  .ds-247420 .ds-bar-bg { flex: 1; min-width: 60px; background: var(--bg-3); border-radius: var(--r-hair); height: 6px; overflow: hidden; }
5106
5141
  .ds-247420 .ds-bar-fill { background: var(--fg-3); height: 100%; border-radius: var(--r-hair); }
@@ -5119,11 +5154,11 @@
5119
5154
  .ds-247420 .ds-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-1); }
5120
5155
  }
5121
5156
  .ds-247420 .ds-stats-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
5122
- .ds-247420 .ds-stat { min-width: 0; background: var(--bg-3); border-radius: var(--r-0); padding: 10px 12px; }
5157
+ .ds-247420 .ds-stat { min-width: 0; background: var(--bg-3); border-radius: var(--r-0); padding: var(--space-2-5) var(--space-2-75); }
5123
5158
  .ds-247420 .ds-stat-val { font-size: clamp(18px, 5cqi, 22px); font-weight: 700; color: var(--accent-ink); overflow-wrap: anywhere; }
5124
5159
  .ds-247420 .ds-stat-val.rate-big { font-size: clamp(24px, 7cqi, 32px); color: var(--success); }
5125
5160
  .ds-247420 .ds-stat-val.err-rate { font-size: clamp(24px, 7cqi, 32px); color: var(--warn); }
5126
- .ds-247420 .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: 2px; }
5161
+ .ds-247420 .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: var(--space-hair); }
5127
5162
 
5128
5163
  /* RateCell — tone-colored numeric table cell (success-rate / percentile-latency
5129
5164
  columns), ported from docstudio's endpointsView() success-rate coloring.
@@ -5140,10 +5175,10 @@
5140
5175
  .ds-247420 .ds-inline-row { display: flex; align-items: center; gap: var(--space-2, 8px); }
5141
5176
 
5142
5177
  /* SubGrid */
5143
- .ds-247420 .ds-sub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 6px; margin-top: 8px; }
5178
+ .ds-247420 .ds-sub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: var(--space-1-75); margin-top: var(--space-2); }
5144
5179
  .ds-247420 .ds-sub-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
5145
5180
  .ds-247420 .ds-sub-btn {
5146
- padding: 6px 10px; background: var(--bg-3); border: var(--bw-hair) solid var(--bg-3);
5181
+ padding: var(--space-1-75) var(--space-2-5); background: var(--bg-3); border: var(--bw-hair) solid var(--bg-3);
5147
5182
  border-radius: var(--r-0); font-size: var(--fs-tiny); cursor: pointer; color: var(--fg);
5148
5183
  text-align: left; font-family: var(--ff-body);
5149
5184
  }
@@ -5162,7 +5197,7 @@
5162
5197
  identical to the ones there, so a kit loading both gets the same result. */
5163
5198
  .ds-247420 .ds-session-row {
5164
5199
  position: relative; display: flex; align-items: center; gap: var(--space-2);
5165
- width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: 2px;
5200
+ width: 100%; padding: var(--space-2); min-height: 52px; margin-bottom: var(--space-hair);
5166
5201
  background: transparent; border: none; border-radius: var(--r-1);
5167
5202
  text-align: left; color: var(--fg);
5168
5203
  }
@@ -5190,7 +5225,7 @@
5190
5225
  /* DevRow */
5191
5226
  .ds-247420 .ds-dev-row {
5192
5227
  background: var(--danger-surface); border-left: var(--bw-chunk) solid var(--warn);
5193
- padding: 8px 12px; margin: 4px 0; border-radius: var(--r-hair); font-size: var(--fs-tiny);
5228
+ padding: var(--space-2) var(--space-2-75); margin: var(--space-1) 0; border-radius: var(--r-hair); font-size: var(--fs-tiny);
5194
5229
  }
5195
5230
  .ds-247420 .ds-dev-row strong { color: var(--warn); }
5196
5231
 
@@ -5207,17 +5242,17 @@
5207
5242
  /* Embedded in a WM window the viewport calc is meaningless — fill the container. */
5208
5243
  .ds-247420 .fd-root .ds-live-log { height: 100%; max-height: none; min-height: 0; flex: 1 1 auto; }
5209
5244
  .ds-247420 .ds-live-log-empty { height: auto; min-height: 0; padding: var(--space-3); color: var(--fg-3); }
5210
- .ds-247420 .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
5245
+ .ds-247420 .ds-live-log-entry { padding: var(--space-hair) var(--space-2); border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
5211
5246
  .ds-247420 .ds-live-log-entry:hover { background: var(--bg-3); }
5212
- .ds-247420 .ds-live-log-ts { margin-right: 6px; color: var(--fg-3); }
5213
- .ds-247420 .ds-live-log-subtag { margin-right: 6px; padding: 0 5px; border-radius: var(--r-hair); font-size: var(--fs-micro); }
5214
- .ds-247420 .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); word-break: break-word; }
5247
+ .ds-247420 .ds-live-log-ts { margin-right: var(--space-1-75); color: var(--fg-3); }
5248
+ .ds-247420 .ds-live-log-subtag { margin-right: var(--space-1-75); padding: 0 var(--space-1-5); border-radius: var(--r-hair); font-size: var(--fs-micro); }
5249
+ .ds-247420 .ds-live-log-preview { margin-left: var(--space-1-75); color: var(--fg-3); word-break: break-word; }
5215
5250
 
5216
5251
  /* Touch floors for the dense controls (not covered by the mobile width blocks). */
5217
5252
  @media (pointer: coarse) {
5218
5253
  .ds-247420 .ds-sub-btn { min-height: 44px; }
5219
5254
  .ds-247420 .ds-session-row { min-height: 44px; }
5220
- .ds-247420 .ds-live-log-entry { padding-block: 6px; }
5255
+ .ds-247420 .ds-live-log-entry { padding-block: var(--space-1-75); }
5221
5256
  }
5222
5257
 
5223
5258
 
@@ -5253,9 +5288,15 @@
5253
5288
  app scale (--fs-h1-app, 22-30px) is what these tokens exist for. Applied
5254
5289
  here rather than as a data-attribute on each kit shell so any surface using
5255
5290
  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); }
5291
+ /* Descendant, not direct-child: a kit that wraps its title in a head row (an
5292
+ h1 beside a theme toggle, say) still gets the app voice. The direct-child
5293
+ form silently missed exactly that shape and left those titles at the 64px
5294
+ display ceiling -- the surface opted in but the rule did not reach the
5295
+ heading. Nested .ds-section content is unaffected because nothing re-raises
5296
+ the size below this point. */
5297
+ .ds-247420 .ds-app-surface h1, .ds-247420 .ds-app-surface .t-h1 { font-size: var(--fs-h1-app); line-height: 1.15; }
5298
+ .ds-247420 .ds-app-surface h2, .ds-247420 .ds-app-surface .t-h2 { font-size: var(--fs-h2-app); }
5299
+ .ds-247420 .ds-app-surface h3, .ds-247420 .ds-app-surface .t-h3 { font-size: var(--fs-h3-app); }
5259
5300
  /* The lede is supporting chrome under an app title, not a marketing stand-first:
5260
5301
  it drops to body size and keeps a readable measure instead of --fs-xl. */
5261
5302
  .ds-247420 .ds-app-surface > .lede, .ds-247420 .ds-app-surface > .t-lede { font-size: var(--fs-body); max-width: 60ch; }
@@ -5361,7 +5402,7 @@
5361
5402
  margin: var(--space-3) auto;
5362
5403
  background: var(--bg-2);
5363
5404
  border-radius: var(--r-2);
5364
- padding: clamp(16px, 5vw, 64px);
5405
+ padding: clamp(var(--space-3), 5vw, var(--space-7));
5365
5406
  box-sizing: border-box;
5366
5407
  display: flex;
5367
5408
  overflow: hidden;
@@ -5376,8 +5417,10 @@
5376
5417
  }
5377
5418
  .ds-247420 .ds-deck-slide { flex: 1; display: flex; min-width: 0; }
5378
5419
  .ds-247420 .ds-deck-controls {
5420
+ /* 14px sits between --space-2-75 (12) and --space-3 (16) with no tier; it is
5421
+ the deck control spacing tuned against the mono glyph run. */
5379
5422
  display: flex; align-items: center; justify-content: center; gap: 14px;
5380
- padding: 8px; font-family: var(--ff-mono); font-size: var(--fs-sm);
5423
+ padding: var(--space-2); font-family: var(--ff-mono); font-size: var(--fs-sm);
5381
5424
  }
5382
5425
  .ds-247420 .ds-deck-count { color: var(--fg-3); }
5383
5426
  @media (pointer: coarse) {
@@ -5404,9 +5447,9 @@
5404
5447
  full-bleed slide chrome, not panel chrome) and owns its own bottom gutter. */
5405
5448
  .ds-247420 .ds-slide-eyebrow {
5406
5449
  color: var(--fg-3);
5407
- margin-bottom: clamp(12px, 2.5cqw, 24px);
5450
+ margin-bottom: clamp(var(--space-2-75), 2.5cqw, var(--space-4));
5408
5451
  }
5409
- .ds-247420 .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
5452
+ .ds-247420 .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(var(--space-2-75), 2.5cqw, var(--space-4)); min-width: 0; }
5410
5453
  .ds-247420 .ds-slide-col--start { align-items: flex-start; }
5411
5454
  .ds-247420 .ds-slide-col--narrow { max-width: 38ch; }
5412
5455
  .ds-247420 .ds-slide-col--quote { max-width: 42ch; }
@@ -5420,15 +5463,17 @@
5420
5463
  font-size: clamp(var(--fs-h3), 4.5cqw, var(--fs-h1));
5421
5464
  line-height: var(--lh-snug); color: var(--fg); font-weight: 500; min-width: 0;
5422
5465
  }
5423
- .ds-247420 .ds-slide-h1--lead { margin-bottom: 12px; }
5466
+ .ds-247420 .ds-slide-h1--lead { margin-bottom: var(--space-2-75); }
5424
5467
  .ds-247420 .ds-slide-quote-body {
5425
5468
  font-size: clamp(var(--fs-lg), 3.5cqw, var(--fs-h2));
5426
5469
  line-height: var(--lh-snug); color: var(--fg); font-weight: 400; font-style: italic;
5427
5470
  }
5428
5471
  .ds-247420 .ds-slide-cite { font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-3); }
5429
5472
  .ds-247420 .ds-slide-bullet {
5430
- display: flex; gap: clamp(8px, 2vw, 18px); align-items: baseline;
5431
- border-bottom: 1px solid var(--rule); padding: 12px 0; flex-wrap: wrap;
5473
+ /* 18px ceiling has no tier (--space-3 is 16, --space-3-5 is 20); it is the
5474
+ bullet key/value split tuned against the clamp(56px,18%,100px) key column. */
5475
+ display: flex; gap: clamp(var(--space-2), 2vw, 18px); align-items: baseline;
5476
+ border-bottom: 1px solid var(--rule); padding: var(--space-2-75) 0; flex-wrap: wrap;
5432
5477
  }
5433
5478
  .ds-247420 .ds-slide-bullet-key {
5434
5479
  flex: 0 1 clamp(56px, 18%, 100px); min-width: 0;
@@ -5436,7 +5481,7 @@
5436
5481
  color: var(--slide-accent, var(--accent-ink));
5437
5482
  }
5438
5483
  .ds-247420 .ds-slide-bullet-val { color: var(--fg-2); font-size: var(--fs-lg); min-width: 0; }
5439
- .ds-247420 .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 3vw, 32px); margin-top: 12px; }
5484
+ .ds-247420 .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(var(--space-2-75), 3vw, var(--space-5)); margin-top: var(--space-2-75); }
5440
5485
  @media (max-width: 760px) {
5441
5486
  .ds-247420 .ds-slide-split { grid-template-columns: 1fr; }
5442
5487
  }
@@ -5462,7 +5507,10 @@
5462
5507
 
5463
5508
  /* --- error 404 --------------------------------------------- */
5464
5509
  .ds-247420 .ds-err-hero {
5465
- padding: clamp(16px, 5vw, 36px) clamp(12px, 4vw, 22px);
5510
+ /* 36px/22px clamp ceilings and the 14px gap are off-scale on purpose: this
5511
+ hero is centred around a clamp(56px,20vw,120px) numeral and the insets are
5512
+ tuned to it, not to the panel rhythm the --space-* scale encodes. */
5513
+ padding: clamp(var(--space-3), 5vw, 36px) clamp(var(--space-2-75), 4vw, 22px);
5466
5514
  text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center;
5467
5515
  }
5468
5516
  .ds-247420 .ds-err-numeral {
@@ -5470,25 +5518,25 @@
5470
5518
  line-height: 1; color: var(--panel-text-3); letter-spacing: -0.03em;
5471
5519
  }
5472
5520
  .ds-247420 .ds-err-path {
5473
- display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; max-width: 100%;
5521
+ display: inline-flex; gap: var(--space-1-75); align-items: baseline; flex-wrap: wrap; max-width: 100%;
5474
5522
  font-family: var(--ff-mono); font-size: 13px; color: var(--panel-text-2);
5475
- background: var(--panel-1); padding: 6px 12px; border-radius: var(--r-0);
5523
+ background: var(--panel-1); padding: var(--space-1-75) var(--space-2-75); border-radius: var(--r-0);
5476
5524
  overflow-wrap: anywhere; word-break: break-all;
5477
5525
  }
5478
5526
 
5479
5527
  /* --- gallery ------------------------------------------------ */
5480
5528
  .ds-247420 .ds-tile-grid {
5481
- padding: clamp(8px, 2.5vw, 16px);
5482
- display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 8px;
5529
+ padding: clamp(var(--space-2), 2.5vw, var(--space-3));
5530
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: var(--space-2);
5483
5531
  }
5484
5532
  .ds-247420 .ds-tile-grid--tight { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
5485
5533
  .ds-247420 .ds-swatch-grid {
5486
- padding: clamp(8px, 2.5vw, 16px);
5487
- display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: 12px;
5534
+ padding: clamp(var(--space-2), 2.5vw, var(--space-3));
5535
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: var(--space-2-75);
5488
5536
  }
5489
5537
  .ds-247420 .ds-gallery-tile {
5490
- cursor: pointer; display: flex; flex-direction: column; gap: 6px;
5491
- padding: 12px; border-radius: var(--r-1); min-height: clamp(120px, 18vw, 160px);
5538
+ cursor: pointer; display: flex; flex-direction: column; gap: var(--space-1-75);
5539
+ padding: var(--space-2-75); border-radius: var(--r-1); min-height: clamp(120px, 18vw, 160px);
5492
5540
  border: 0; text-align: left; font: inherit; color: inherit;
5493
5541
  background: var(--tile-tone, var(--panel-1));
5494
5542
  transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
@@ -5502,20 +5550,23 @@
5502
5550
  .ds-247420 .ds-lightbox {
5503
5551
  position: fixed; inset: 0; background: var(--scrim);
5504
5552
  display: flex; align-items: center; justify-content: center;
5505
- padding: clamp(12px, 4vw, 32px);
5506
- padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
5553
+ padding: clamp(var(--space-2-75), 4vw, var(--space-5));
5554
+ padding-bottom: max(clamp(var(--space-2-75), 4vw, var(--space-5)), env(safe-area-inset-bottom));
5507
5555
  z-index: var(--z-modal);
5508
5556
  }
5509
5557
  .ds-247420 .ds-lightbox-card {
5510
- background: var(--panel-0); border-radius: var(--r-2); padding: clamp(16px, 4vw, 28px);
5558
+ /* 28px ceiling has no tier (--space-4 is 24, --space-5 is 32); it is the
5559
+ lightbox card inset tuned against the min(520px,100%) card width. */
5560
+ background: var(--panel-0); border-radius: var(--r-2); padding: clamp(var(--space-3), 4vw, 28px);
5511
5561
  width: min(520px, 100%); min-width: 0;
5512
5562
  max-height: calc(100vh - 24px);
5513
5563
  max-height: calc(100dvh - 24px);
5514
5564
  overflow: auto;
5515
- display: flex; flex-direction: column; gap: 14px;
5565
+ display: flex; flex-direction: column; gap: 14px; /* off-scale, matches the card inset above */
5516
5566
  }
5517
5567
  .ds-247420 .ds-lightbox-preview {
5518
- padding: clamp(16px, 6vw, 36px); border-radius: var(--r-1); text-align: center;
5568
+ /* 36px ceiling has no tier (--space-5 is 32, --space-6 is 48). */
5569
+ padding: clamp(var(--space-3), 6vw, 36px); border-radius: var(--r-1); text-align: center;
5519
5570
  font-family: var(--ff-mono); white-space: pre-line; font-size: clamp(16px, 5vw, 24px);
5520
5571
  background: var(--tile-tone, var(--panel-1));
5521
5572
  }
@@ -5525,25 +5576,31 @@
5525
5576
  @media (max-width: 480px) {
5526
5577
  .ds-247420 .ds-topbar-search { flex-basis: 100%; }
5527
5578
  }
5528
- .ds-247420 .ds-empty-state { padding: clamp(16px, 5vw, 24px); text-align: center; color: var(--panel-text-3); }
5579
+ .ds-247420 .ds-empty-state { padding: clamp(var(--space-3), 5vw, var(--space-4)); text-align: center; color: var(--panel-text-3); }
5529
5580
  .ds-247420 .ds-empty-state-glyph { font-size: clamp(24px, 6vw, 32px); }
5530
- .ds-247420 .ds-empty-state-msg { margin: 6px 0; }
5581
+ .ds-247420 .ds-empty-state-msg { margin: var(--space-1-75) 0; }
5531
5582
  .ds-247420 .ds-empty-state-hint { margin: 0; font-size: var(--fs-sm); }
5532
5583
 
5533
5584
  /* --- system primer ------------------------------------------ */
5585
+ /* The three primer panels below share one fluid inset,
5586
+ clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px), and a 14/18px gap. None of
5587
+ 10/14/18 is a --space-* tier (the scale jumps 8 -> 10 -> 12 -> 16 -> 20) and
5588
+ the three values are tuned as a set against the 64px label columns, so the
5589
+ panels stay optically identical to each other. Snapping any one of them
5590
+ desyncs the family; they are deliberate literals, not un-migrated drift. */
5534
5591
  .ds-247420 .ds-swatch-grid-sm {
5535
5592
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
5536
- gap: 12px; padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
5593
+ gap: var(--space-2-75); padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
5537
5594
  }
5538
5595
  .ds-247420 .ds-swatch-grid-lg { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
5539
- .ds-247420 .ds-swatch-col { display: flex; flex-direction: column; gap: 6px; }
5596
+ .ds-247420 .ds-swatch-col { display: flex; flex-direction: column; gap: var(--space-1-75); }
5540
5597
  .ds-247420 .ds-swatch-chip { height: 48px; border-radius: var(--r-1); border: 1px solid var(--rule); background: var(--swatch, var(--panel-1)); }
5541
5598
  .ds-247420 .ds-swatch-chip--big { height: 64px; }
5542
5599
  .ds-247420 .ds-swatch-name { font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
5543
5600
  .ds-247420 .ds-type-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 14px; }
5544
5601
  .ds-247420 .ds-type-row {
5545
5602
  display: flex; align-items: baseline; gap: 14px;
5546
- border-bottom: 1px solid var(--rule); padding-bottom: 8px; flex-wrap: wrap;
5603
+ border-bottom: 1px solid var(--rule); padding-bottom: var(--space-2); flex-wrap: wrap;
5547
5604
  }
5548
5605
  .ds-247420 .ds-type-row-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
5549
5606
  .ds-247420 .ds-type-sample {
@@ -5551,7 +5608,7 @@
5551
5608
  font-size: var(--sample-size, var(--fs-body));
5552
5609
  }
5553
5610
  .ds-247420 .ds-prim-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 18px; }
5554
- .ds-247420 .ds-prim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
5611
+ .ds-247420 .ds-prim-row { display: flex; gap: var(--space-2-5); flex-wrap: wrap; align-items: center; }
5555
5612
  .ds-247420 .ds-prim-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
5556
5613
 
5557
5614
  /* == appended: content-site == */
@@ -5607,7 +5664,7 @@
5607
5664
  matching the "color reserved for meaning, not decoration" pattern seen in
5608
5665
  docstudio's admin table. */
5609
5666
  .ds-247420 .ds-table-sort-btn {
5610
- display: inline-flex; align-items: center; gap: 4px;
5667
+ display: inline-flex; align-items: center; gap: var(--space-1);
5611
5668
  background: none; border: none; padding: 0; margin: 0;
5612
5669
  font: inherit; font-weight: inherit; color: inherit; cursor: pointer;
5613
5670
  }
@@ -5680,55 +5737,56 @@
5680
5737
  /* == appended: signin kit cleanup == */
5681
5738
  /* -- signin kit (ui_kits/signin) -- */
5682
5739
  .ds-247420 .ds-auth-wrap { padding: var(--space-2, 8px); display: flex; flex-direction: column; align-items: center; }
5683
- .ds-247420 .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 8px; margin: clamp(12px, 4vw, 24px) 0; min-width: 0; }
5684
- .ds-247420 .ds-auth-form { padding: clamp(12px, 3vw, 18px); display: flex; flex-direction: column; gap: 10px; }
5740
+ .ds-247420 .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: var(--space-2); margin: clamp(var(--space-2-75), 4vw, var(--space-4)) 0; min-width: 0; }
5741
+ /* 18px ceiling: no tier between --space-3 (16) and --space-3-5 (20). */
5742
+ .ds-247420 .ds-auth-form { padding: clamp(var(--space-2-75), 3vw, 18px); display: flex; flex-direction: column; gap: var(--space-2-5); }
5685
5743
  .ds-247420 .ds-auth-sent { align-items: center; text-align: center; }
5686
5744
  .ds-247420 .ds-auth-sent-glyph { font-size: 32px; color: var(--panel-accent); }
5687
5745
  .ds-247420 .ds-auth-sent-title { margin: 0; font-weight: 600; }
5688
5746
  .ds-247420 .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
5689
- .ds-247420 .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
5747
+ .ds-247420 .ds-auth-field { display: flex; flex-direction: column; gap: var(--space-1); }
5690
5748
  /* .ds-auth-field-label joins the kit small-label voice above, no overrides. */
5691
- .ds-247420 .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
5692
- .ds-247420 .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
5749
+ .ds-247420 .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; }
5750
+ .ds-247420 .ds-auth-remember { display: flex; align-items: center; gap: var(--space-1-75); cursor: pointer; }
5693
5751
  .ds-247420 .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
5694
5752
  .ds-247420 .ds-auth-forgot { font-size: 13px; }
5695
- .ds-247420 .ds-auth-error { padding: 8px 10px; background: var(--panel-1); border-radius: var(--r-0); color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
5696
- .ds-247420 .ds-auth-providers { display: flex; gap: 8px; flex-wrap: wrap; }
5697
- .ds-247420 .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; }
5753
+ .ds-247420 .ds-auth-error { padding: var(--space-2) var(--space-2-5); background: var(--panel-1); border-radius: var(--r-0); color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
5754
+ .ds-247420 .ds-auth-providers { display: flex; gap: var(--space-2); flex-wrap: wrap; }
5755
+ .ds-247420 .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-2-5); }
5698
5756
  .ds-247420 .ds-auth-provider-btn--loading { opacity: 0.7; pointer-events: none; }
5699
5757
  .ds-247420 .ds-auth-provider-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); display: inline-flex; }
5700
- .ds-247420 .ds-auth-modes { display: flex; justify-content: center; gap: 14px; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
5758
+ .ds-247420 .ds-auth-modes { display: flex; justify-content: center; gap: 14px; /* off-scale, matches the auth form inset */ margin-top: var(--space-2); font-size: 13px; flex-wrap: wrap; }
5701
5759
  .ds-247420 .ds-auth-mode-link { color: var(--panel-text-3); text-decoration: none; }
5702
5760
  .ds-247420 .ds-auth-mode-link--active { color: var(--panel-text); text-decoration: underline; }
5703
- .ds-247420 .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: 6px 0; }
5761
+ .ds-247420 .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: var(--space-1-75) 0; }
5704
5762
 
5705
5763
  /* == appended: gallery-misc kit cleanup == */
5706
5764
  /* --- shared helpers (converted from inline styles) --- */
5707
5765
  .ds-247420 .ds-m0 { margin: 0; }
5708
5766
  .ds-247420 .ds-text-2 { color: var(--panel-text-2); }
5709
5767
  .ds-247420 .ds-text-3 { color: var(--panel-text-3); }
5710
- .ds-247420 .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(8px, 2vw, 16px); flex-wrap: wrap; }
5768
+ .ds-247420 .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(var(--space-2), 2vw, var(--space-3)); flex-wrap: wrap; }
5711
5769
 
5712
5770
  /* --- gallery kit --- */
5713
5771
  .ds-247420 .ds-tile-cap { flex: 1; display: flex; align-items: center; justify-content: center; font-family: var(--ff-mono); white-space: pre-line; color: var(--panel-text-2); font-size: 18px; min-width: 0; text-align: center; }
5714
- .ds-247420 .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; flex-wrap: wrap; min-width: 0; }
5772
+ .ds-247420 .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: var(--space-1-75); font-size: 12px; flex-wrap: wrap; min-width: 0; }
5715
5773
  .ds-247420 .ds-tile-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); }
5716
5774
  .ds-247420 .ds-tile-label { color: var(--panel-text); overflow-wrap: anywhere; }
5717
5775
  .ds-247420 .ds-gal-swatch { height: 64px; border-radius: var(--r-0); background: var(--swatch, var(--panel-1)); }
5718
- .ds-247420 .ds-gal-swatch-meta { display: flex; justify-content: space-between; gap: 6px; flex-wrap: wrap; font-family: var(--ff-mono); font-size: 11px; min-width: 0; }
5776
+ .ds-247420 .ds-gal-swatch-meta { display: flex; justify-content: space-between; gap: var(--space-1-75); flex-wrap: wrap; font-family: var(--ff-mono); font-size: 11px; min-width: 0; }
5719
5777
  .ds-247420 .ds-gal-swatch-name { color: var(--panel-text); }
5720
5778
  .ds-247420 .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
5721
- .ds-247420 .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
5779
+ .ds-247420 .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
5722
5780
  /* .ds-lightbox-tag joins the kit small-label voice above, no overrides. */
5723
5781
 
5724
5782
  /* --- error_404 kit --- */
5725
- .ds-247420 .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
5726
- .ds-247420 .ds-err-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
5783
+ .ds-247420 .ds-err-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: center; margin-top: var(--space-1-75); }
5784
+ .ds-247420 .ds-err-chips { display: flex; gap: var(--space-1-75); flex-wrap: wrap; justify-content: center; margin-top: var(--space-1); }
5727
5785
 
5728
5786
  /* == appended: terminal-capp kit cleanup == */
5729
5787
  /* --- terminal kit ------------------------------------------ */
5730
- .ds-247420 .ds-section-pad-sm { padding: 8px; }
5731
- .ds-247420 .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
5788
+ .ds-247420 .ds-section-pad-sm { padding: var(--space-2); }
5789
+ .ds-247420 .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
5732
5790
  .ds-247420 .ds-cli-cmt .cmd { color: var(--fg-3); }
5733
5791
  .ds-247420 .ds-cli-out .cmd { color: var(--fg-2); }
5734
5792
  .ds-247420 .ds-cli-ok .prompt, .ds-247420 .ds-cli-ok .cmd { color: var(--accent-ink); }
@@ -11641,7 +11699,15 @@
11641
11699
 
11642
11700
  /* Event-list row hover + search-result flash. */
11643
11701
  .ds-247420 .ds-event-list .row[role="button"]:hover { background: color-mix(in srgb, var(--fg) 5%, transparent); }
11644
- .ds-247420 .ds-event-list .row.event-flash { animation: agentgui-event-flash 2s ease-out; }
11702
+ /* Opt-in like every other animation in the kit: the flash is declared only
11703
+ under no-preference, so a reduced-motion user gets the row without a 2s
11704
+ pulsing highlight. It animates background rather than transform, so the
11705
+ vestibular risk is low, but a repeating attention pull is still exactly the
11706
+ kind of thing the preference exists to suppress. The row is located by the
11707
+ scroll-into-view that accompanies it, so nothing is lost when it is absent. */
11708
+ @media (prefers-reduced-motion: no-preference) {
11709
+ .ds-247420 .ds-event-list .row.event-flash { animation: agentgui-event-flash 2s ease-out; }
11710
+ }
11645
11711
 
11646
11712
 
11647
11713
  /* Generic interactive focus ring for app-emitted controls. */