anentrypoint-design 0.0.381 → 0.0.383

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 (54) hide show
  1. package/dist/247420.css +406 -180
  2. package/dist/247420.js +26 -26
  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/files-modals.js +1 -1
  33. package/src/components/overlay-primitives/approval-prompt.js +38 -0
  34. package/src/components/overlay-primitives/auth-modal.js +89 -0
  35. package/src/components/overlay-primitives/command-palette.js +101 -0
  36. package/src/components/overlay-primitives/emoji-picker.js +103 -0
  37. package/src/components/overlay-primitives/floating.js +146 -0
  38. package/src/components/overlay-primitives/full-screen.js +45 -0
  39. package/src/components/overlay-primitives/menus.js +135 -0
  40. package/src/components/overlay-primitives/popover.js +51 -0
  41. package/src/components/overlay-primitives/roving-menu.js +73 -0
  42. package/src/components/overlay-primitives/settings-popover.js +85 -0
  43. package/src/components/overlay-primitives/tooltip.js +55 -0
  44. package/src/components/overlay-primitives.js +33 -855
  45. package/src/css/app-shell/base.css +54 -1
  46. package/src/css/app-shell/chat-polish.css +39 -32
  47. package/src/css/app-shell/data-density.css +25 -21
  48. package/src/css/app-shell/files.css +37 -29
  49. package/src/css/app-shell/kits-appended.css +92 -50
  50. package/src/css/app-shell/responsive.css +73 -35
  51. package/src/css/app-shell/responsive2-workspace.css +16 -4
  52. package/src/css/app-shell/states-interactions.css +21 -4
  53. package/src/css/app-shell/topbar.css +5 -1
  54. package/src/kits/os/freddie-dashboard.css +2 -2
@@ -30,9 +30,15 @@
30
30
  app scale (--fs-h1-app, 22-30px) is what these tokens exist for. Applied
31
31
  here rather than as a data-attribute on each kit shell so any surface using
32
32
  this root gets the app voice without a per-kit opt-in that kits forget. */
33
- .ds-app-surface > h1, .ds-app-surface > .t-h1 { font-size: var(--fs-h1-app); line-height: 1.15; }
34
- .ds-app-surface > h2, .ds-app-surface > .t-h2 { font-size: var(--fs-h2-app); }
35
- .ds-app-surface > h3, .ds-app-surface > .t-h3 { font-size: var(--fs-h3-app); }
33
+ /* Descendant, not direct-child: a kit that wraps its title in a head row (an
34
+ h1 beside a theme toggle, say) still gets the app voice. The direct-child
35
+ form silently missed exactly that shape and left those titles at the 64px
36
+ display ceiling -- the surface opted in but the rule did not reach the
37
+ heading. Nested .ds-section content is unaffected because nothing re-raises
38
+ the size below this point. */
39
+ .ds-app-surface h1, .ds-app-surface .t-h1 { font-size: var(--fs-h1-app); line-height: 1.15; }
40
+ .ds-app-surface h2, .ds-app-surface .t-h2 { font-size: var(--fs-h2-app); }
41
+ .ds-app-surface h3, .ds-app-surface .t-h3 { font-size: var(--fs-h3-app); }
36
42
  /* The lede is supporting chrome under an app title, not a marketing stand-first:
37
43
  it drops to body size and keeps a readable measure instead of --fs-xl. */
38
44
  .ds-app-surface > .lede, .ds-app-surface > .t-lede { font-size: var(--fs-body); max-width: 60ch; }
@@ -138,7 +144,7 @@
138
144
  margin: var(--space-3) auto;
139
145
  background: var(--bg-2);
140
146
  border-radius: var(--r-2);
141
- padding: clamp(16px, 5vw, 64px);
147
+ padding: clamp(var(--space-3), 5vw, var(--space-7));
142
148
  box-sizing: border-box;
143
149
  display: flex;
144
150
  overflow: hidden;
@@ -153,8 +159,10 @@
153
159
  }
154
160
  .ds-deck-slide { flex: 1; display: flex; min-width: 0; }
155
161
  .ds-deck-controls {
162
+ /* 14px sits between --space-2-75 (12) and --space-3 (16) with no tier; it is
163
+ the deck control spacing tuned against the mono glyph run. */
156
164
  display: flex; align-items: center; justify-content: center; gap: 14px;
157
- padding: 8px; font-family: var(--ff-mono); font-size: var(--fs-sm);
165
+ padding: var(--space-2); font-family: var(--ff-mono); font-size: var(--fs-sm);
158
166
  }
159
167
  .ds-deck-count { color: var(--fg-3); }
160
168
  @media (pointer: coarse) {
@@ -181,9 +189,9 @@
181
189
  full-bleed slide chrome, not panel chrome) and owns its own bottom gutter. */
182
190
  .ds-slide-eyebrow {
183
191
  color: var(--fg-3);
184
- margin-bottom: clamp(12px, 2.5cqw, 24px);
192
+ margin-bottom: clamp(var(--space-2-75), 2.5cqw, var(--space-4));
185
193
  }
186
- .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
194
+ .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; }
187
195
  .ds-slide-col--start { align-items: flex-start; }
188
196
  .ds-slide-col--narrow { max-width: 38ch; }
189
197
  .ds-slide-col--quote { max-width: 42ch; }
@@ -197,15 +205,17 @@
197
205
  font-size: clamp(var(--fs-h3), 4.5cqw, var(--fs-h1));
198
206
  line-height: var(--lh-snug); color: var(--fg); font-weight: 500; min-width: 0;
199
207
  }
200
- .ds-slide-h1--lead { margin-bottom: 12px; }
208
+ .ds-slide-h1--lead { margin-bottom: var(--space-2-75); }
201
209
  .ds-slide-quote-body {
202
210
  font-size: clamp(var(--fs-lg), 3.5cqw, var(--fs-h2));
203
211
  line-height: var(--lh-snug); color: var(--fg); font-weight: 400; font-style: italic;
204
212
  }
205
213
  .ds-slide-cite { font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-3); }
206
214
  .ds-slide-bullet {
207
- display: flex; gap: clamp(8px, 2vw, 18px); align-items: baseline;
208
- border-bottom: 1px solid var(--rule); padding: 12px 0; flex-wrap: wrap;
215
+ /* 18px ceiling has no tier (--space-3 is 16, --space-3-5 is 20); it is the
216
+ bullet key/value split tuned against the clamp(56px,18%,100px) key column. */
217
+ display: flex; gap: clamp(var(--space-2), 2vw, 18px); align-items: baseline;
218
+ border-bottom: 1px solid var(--rule); padding: var(--space-2-75) 0; flex-wrap: wrap;
209
219
  }
210
220
  .ds-slide-bullet-key {
211
221
  flex: 0 1 clamp(56px, 18%, 100px); min-width: 0;
@@ -213,7 +223,7 @@
213
223
  color: var(--slide-accent, var(--accent-ink));
214
224
  }
215
225
  .ds-slide-bullet-val { color: var(--fg-2); font-size: var(--fs-lg); min-width: 0; }
216
- .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 3vw, 32px); margin-top: 12px; }
226
+ .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); }
217
227
  @media (max-width: 760px) {
218
228
  .ds-slide-split { grid-template-columns: 1fr; }
219
229
  }
@@ -239,7 +249,10 @@
239
249
 
240
250
  /* --- error 404 --------------------------------------------- */
241
251
  .ds-err-hero {
242
- padding: clamp(16px, 5vw, 36px) clamp(12px, 4vw, 22px);
252
+ /* 36px/22px clamp ceilings and the 14px gap are off-scale on purpose: this
253
+ hero is centred around a clamp(56px,20vw,120px) numeral and the insets are
254
+ tuned to it, not to the panel rhythm the --space-* scale encodes. */
255
+ padding: clamp(var(--space-3), 5vw, 36px) clamp(var(--space-2-75), 4vw, 22px);
243
256
  text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center;
244
257
  }
245
258
  .ds-err-numeral {
@@ -247,25 +260,25 @@
247
260
  line-height: 1; color: var(--panel-text-3); letter-spacing: -0.03em;
248
261
  }
249
262
  .ds-err-path {
250
- display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; max-width: 100%;
263
+ display: inline-flex; gap: var(--space-1-75); align-items: baseline; flex-wrap: wrap; max-width: 100%;
251
264
  font-family: var(--ff-mono); font-size: 13px; color: var(--panel-text-2);
252
- background: var(--panel-1); padding: 6px 12px; border-radius: var(--r-0);
265
+ background: var(--panel-1); padding: var(--space-1-75) var(--space-2-75); border-radius: var(--r-0);
253
266
  overflow-wrap: anywhere; word-break: break-all;
254
267
  }
255
268
 
256
269
  /* --- gallery ------------------------------------------------ */
257
270
  .ds-tile-grid {
258
- padding: clamp(8px, 2.5vw, 16px);
259
- display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 8px;
271
+ padding: clamp(var(--space-2), 2.5vw, var(--space-3));
272
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: var(--space-2);
260
273
  }
261
274
  .ds-tile-grid--tight { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
262
275
  .ds-swatch-grid {
263
- padding: clamp(8px, 2.5vw, 16px);
264
- display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: 12px;
276
+ padding: clamp(var(--space-2), 2.5vw, var(--space-3));
277
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: var(--space-2-75);
265
278
  }
266
279
  .ds-gallery-tile {
267
- cursor: pointer; display: flex; flex-direction: column; gap: 6px;
268
- padding: 12px; border-radius: var(--r-1); min-height: clamp(120px, 18vw, 160px);
280
+ cursor: pointer; display: flex; flex-direction: column; gap: var(--space-1-75);
281
+ padding: var(--space-2-75); border-radius: var(--r-1); min-height: clamp(120px, 18vw, 160px);
269
282
  border: 0; text-align: left; font: inherit; color: inherit;
270
283
  background: var(--tile-tone, var(--panel-1));
271
284
  transition: transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
@@ -279,20 +292,23 @@
279
292
  .ds-lightbox {
280
293
  position: fixed; inset: 0; background: var(--scrim);
281
294
  display: flex; align-items: center; justify-content: center;
282
- padding: clamp(12px, 4vw, 32px);
283
- padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
295
+ padding: clamp(var(--space-2-75), 4vw, var(--space-5));
296
+ padding-bottom: max(clamp(var(--space-2-75), 4vw, var(--space-5)), env(safe-area-inset-bottom));
284
297
  z-index: var(--z-modal);
285
298
  }
286
299
  .ds-lightbox-card {
287
- background: var(--panel-0); border-radius: var(--r-2); padding: clamp(16px, 4vw, 28px);
300
+ /* 28px ceiling has no tier (--space-4 is 24, --space-5 is 32); it is the
301
+ lightbox card inset tuned against the min(520px,100%) card width. */
302
+ background: var(--panel-0); border-radius: var(--r-2); padding: clamp(var(--space-3), 4vw, 28px);
288
303
  width: min(520px, 100%); min-width: 0;
289
304
  max-height: calc(100vh - 24px);
290
305
  max-height: calc(100dvh - 24px);
291
306
  overflow: auto;
292
- display: flex; flex-direction: column; gap: 14px;
307
+ display: flex; flex-direction: column; gap: 14px; /* off-scale, matches the card inset above */
293
308
  }
294
309
  .ds-lightbox-preview {
295
- padding: clamp(16px, 6vw, 36px); border-radius: var(--r-1); text-align: center;
310
+ /* 36px ceiling has no tier (--space-5 is 32, --space-6 is 48). */
311
+ padding: clamp(var(--space-3), 6vw, 36px); border-radius: var(--r-1); text-align: center;
296
312
  font-family: var(--ff-mono); white-space: pre-line; font-size: clamp(16px, 5vw, 24px);
297
313
  background: var(--tile-tone, var(--panel-1));
298
314
  }
@@ -302,25 +318,31 @@
302
318
  @media (max-width: 480px) {
303
319
  .ds-topbar-search { flex-basis: 100%; }
304
320
  }
305
- .ds-empty-state { padding: clamp(16px, 5vw, 24px); text-align: center; color: var(--panel-text-3); }
321
+ .ds-empty-state { padding: clamp(var(--space-3), 5vw, var(--space-4)); text-align: center; color: var(--panel-text-3); }
306
322
  .ds-empty-state-glyph { font-size: clamp(24px, 6vw, 32px); }
307
- .ds-empty-state-msg { margin: 6px 0; }
323
+ .ds-empty-state-msg { margin: var(--space-1-75) 0; }
308
324
  .ds-empty-state-hint { margin: 0; font-size: var(--fs-sm); }
309
325
 
310
326
  /* --- system primer ------------------------------------------ */
327
+ /* The three primer panels below share one fluid inset,
328
+ clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px), and a 14/18px gap. None of
329
+ 10/14/18 is a --space-* tier (the scale jumps 8 -> 10 -> 12 -> 16 -> 20) and
330
+ the three values are tuned as a set against the 64px label columns, so the
331
+ panels stay optically identical to each other. Snapping any one of them
332
+ desyncs the family; they are deliberate literals, not un-migrated drift. */
311
333
  .ds-swatch-grid-sm {
312
334
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
313
- gap: 12px; padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
335
+ gap: var(--space-2-75); padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
314
336
  }
315
337
  .ds-swatch-grid-lg { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
316
- .ds-swatch-col { display: flex; flex-direction: column; gap: 6px; }
338
+ .ds-swatch-col { display: flex; flex-direction: column; gap: var(--space-1-75); }
317
339
  .ds-swatch-chip { height: 48px; border-radius: var(--r-1); border: 1px solid var(--rule); background: var(--swatch, var(--panel-1)); }
318
340
  .ds-swatch-chip--big { height: 64px; }
319
341
  .ds-swatch-name { font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
320
342
  .ds-type-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 14px; }
321
343
  .ds-type-row {
322
344
  display: flex; align-items: baseline; gap: 14px;
323
- border-bottom: 1px solid var(--rule); padding-bottom: 8px; flex-wrap: wrap;
345
+ border-bottom: 1px solid var(--rule); padding-bottom: var(--space-2); flex-wrap: wrap;
324
346
  }
325
347
  .ds-type-row-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
326
348
  .ds-type-sample {
@@ -328,7 +350,7 @@
328
350
  font-size: var(--sample-size, var(--fs-body));
329
351
  }
330
352
  .ds-prim-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 18px; }
331
- .ds-prim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
353
+ .ds-prim-row { display: flex; gap: var(--space-2-5); flex-wrap: wrap; align-items: center; }
332
354
  .ds-prim-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
333
355
 
334
356
  /* == appended: content-site == */
@@ -384,7 +406,7 @@
384
406
  matching the "color reserved for meaning, not decoration" pattern seen in
385
407
  docstudio's admin table. */
386
408
  .ds-table-sort-btn {
387
- display: inline-flex; align-items: center; gap: 4px;
409
+ display: inline-flex; align-items: center; gap: var(--space-1);
388
410
  background: none; border: none; padding: 0; margin: 0;
389
411
  font: inherit; font-weight: inherit; color: inherit; cursor: pointer;
390
412
  }
@@ -457,55 +479,56 @@
457
479
  /* == appended: signin kit cleanup == */
458
480
  /* -- signin kit (ui_kits/signin) -- */
459
481
  .ds-auth-wrap { padding: var(--space-2, 8px); display: flex; flex-direction: column; align-items: center; }
460
- .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 8px; margin: clamp(12px, 4vw, 24px) 0; min-width: 0; }
461
- .ds-auth-form { padding: clamp(12px, 3vw, 18px); display: flex; flex-direction: column; gap: 10px; }
482
+ .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; }
483
+ /* 18px ceiling: no tier between --space-3 (16) and --space-3-5 (20). */
484
+ .ds-auth-form { padding: clamp(var(--space-2-75), 3vw, 18px); display: flex; flex-direction: column; gap: var(--space-2-5); }
462
485
  .ds-auth-sent { align-items: center; text-align: center; }
463
486
  .ds-auth-sent-glyph { font-size: 32px; color: var(--panel-accent); }
464
487
  .ds-auth-sent-title { margin: 0; font-weight: 600; }
465
488
  .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
466
- .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
489
+ .ds-auth-field { display: flex; flex-direction: column; gap: var(--space-1); }
467
490
  /* .ds-auth-field-label joins the kit small-label voice above, no overrides. */
468
- .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
469
- .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
491
+ .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; }
492
+ .ds-auth-remember { display: flex; align-items: center; gap: var(--space-1-75); cursor: pointer; }
470
493
  .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
471
494
  .ds-auth-forgot { font-size: 13px; }
472
- .ds-auth-error { padding: 8px 10px; background: var(--panel-1); border-radius: var(--r-0); color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
473
- .ds-auth-providers { display: flex; gap: 8px; flex-wrap: wrap; }
474
- .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; }
495
+ .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; }
496
+ .ds-auth-providers { display: flex; gap: var(--space-2); flex-wrap: wrap; }
497
+ .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); }
475
498
  .ds-auth-provider-btn--loading { opacity: 0.7; pointer-events: none; }
476
499
  .ds-auth-provider-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); display: inline-flex; }
477
- .ds-auth-modes { display: flex; justify-content: center; gap: 14px; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
500
+ .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; }
478
501
  .ds-auth-mode-link { color: var(--panel-text-3); text-decoration: none; }
479
502
  .ds-auth-mode-link--active { color: var(--panel-text); text-decoration: underline; }
480
- .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: 6px 0; }
503
+ .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: var(--space-1-75) 0; }
481
504
 
482
505
  /* == appended: gallery-misc kit cleanup == */
483
506
  /* --- shared helpers (converted from inline styles) --- */
484
507
  .ds-m0 { margin: 0; }
485
508
  .ds-text-2 { color: var(--panel-text-2); }
486
509
  .ds-text-3 { color: var(--panel-text-3); }
487
- .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(8px, 2vw, 16px); flex-wrap: wrap; }
510
+ .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(var(--space-2), 2vw, var(--space-3)); flex-wrap: wrap; }
488
511
 
489
512
  /* --- gallery kit --- */
490
513
  .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; }
491
- .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; flex-wrap: wrap; min-width: 0; }
514
+ .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; }
492
515
  .ds-tile-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); }
493
516
  .ds-tile-label { color: var(--panel-text); overflow-wrap: anywhere; }
494
517
  .ds-gal-swatch { height: 64px; border-radius: var(--r-0); background: var(--swatch, var(--panel-1)); }
495
- .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; }
518
+ .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; }
496
519
  .ds-gal-swatch-name { color: var(--panel-text); }
497
520
  .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
498
- .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
521
+ .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
499
522
  /* .ds-lightbox-tag joins the kit small-label voice above, no overrides. */
500
523
 
501
524
  /* --- error_404 kit --- */
502
- .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
503
- .ds-err-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
525
+ .ds-err-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: center; margin-top: var(--space-1-75); }
526
+ .ds-err-chips { display: flex; gap: var(--space-1-75); flex-wrap: wrap; justify-content: center; margin-top: var(--space-1); }
504
527
 
505
528
  /* == appended: terminal-capp kit cleanup == */
506
529
  /* --- terminal kit ------------------------------------------ */
507
- .ds-section-pad-sm { padding: 8px; }
508
- .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
530
+ .ds-section-pad-sm { padding: var(--space-2); }
531
+ .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
509
532
  .ds-cli-cmt .cmd { color: var(--fg-3); }
510
533
  .ds-cli-out .cmd { color: var(--fg-2); }
511
534
  .ds-cli-ok .prompt, .ds-cli-ok .cmd { color: var(--accent-ink); }
@@ -783,3 +806,22 @@
783
806
  .cursor-blink { animation: ds-cursor-blink 1s step-end infinite; }
784
807
  @keyframes ds-cursor-blink { 50% { opacity: 0; } }
785
808
  }
809
+
810
+ /* == appended: panel width modifier == */
811
+ /* .panel.panel-inline-wide — a width-capped inline note panel. Companion to
812
+ the .panel-inline / .panel-wide modifiers in panel-row.css: those two change
813
+ the panel's SURFACE (tonal fill / chrome-stripped), this one changes only
814
+ its MEASURE, so it composes with either. Introduced when ui_kits/docs's
815
+ `[!] note` panel traded `style="max-width:640px"` for a class (the inline-
816
+ style sweep) but never got a rule written, leaving that panel to run the
817
+ full column width. 640px is the note measure, deliberately narrower than
818
+ --measure-narrow (760px): the aside is meant to read as a set-aside block
819
+ against the surrounding prose, not to match its column. It is a literal
820
+ rather than a new token because it has exactly one consumer — promote it to
821
+ --measure-note the moment a second surface wants the same cap.
822
+ `margin-right: auto` (not `margin: 0 auto`) keeps the panel left-aligned to
823
+ the prose it interrupts and preserves .panel's own --space-4 stack margin. */
824
+ .panel.panel-inline-wide {
825
+ max-width: 640px;
826
+ margin-right: auto;
827
+ }
@@ -14,7 +14,7 @@
14
14
  brand and let it scroll horizontally. The brand stays on the first row;
15
15
  nav wraps to a second row at 100% width (flex-wrap on .app-topbar). */
16
16
  .app-topbar {
17
- gap: var(--space-2); padding: 12px var(--space-3);
17
+ gap: var(--space-2); padding: var(--space-2-75) var(--space-3);
18
18
  }
19
19
  /* When the topbar is folded into .app-chrome it is a flex:0 0 auto child, so
20
20
  it sizes to its nav's content and overflows the viewport instead of letting
@@ -23,7 +23,7 @@
23
23
  .app-chrome > .app-topbar { max-width: 100%; min-width: 0; flex-basis: 100%; }
24
24
  .app-topbar > nav {
25
25
  flex: 1 1 100%; margin-left: 0; order: 3; min-width: 0; max-width: 100%;
26
- display: flex; gap: 2px; flex-wrap: nowrap;
26
+ display: flex; gap: var(--space-hair); flex-wrap: nowrap;
27
27
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
28
28
  /* Fade the trailing edge so a clipped last item (e.g. "source ->" cut to
29
29
  "sour") reads as scrollable content, not a broken/truncated label. */
@@ -32,7 +32,7 @@
32
32
  }
33
33
  .app-topbar nav::-webkit-scrollbar { display: none; }
34
34
  .app-topbar nav a {
35
- flex: 0 0 auto; padding: 10px 12px; min-height: 44px; white-space: nowrap;
35
+ flex: 0 0 auto; padding: var(--space-2-5) var(--space-2-75); min-height: 44px; white-space: nowrap;
36
36
  }
37
37
  .brand { font-size: var(--fs-tiny); font-weight: 600; }
38
38
 
@@ -53,21 +53,36 @@
53
53
  .panel-body { padding: var(--space-2); overflow-x: auto; -webkit-overflow-scrolling: touch; }
54
54
  .panel-body > table { min-width: 100%; }
55
55
 
56
- .row {
57
- grid-template-columns: minmax(0, 1fr) auto !important;
58
- gap: var(--space-2); padding: 12px 16px;
59
- row-gap: 4px !important;
56
+ /* Scoped to the `.app` shell so this wins on SPECIFICITY (0,2,0) rather than
57
+ on an !important flag. Three rules would otherwise beat a bare `.row`
58
+ (0,1,0) here: `.row.row-nocode` (0,2,0, panel-row.css) out-specifies it,
59
+ and the `@media(481-1024)` + `@media(max-width:768px)` `.row` rules later
60
+ in THIS file win on source order (a media query adds no specificity).
61
+ `.app` is safe to require: `.app-body`/`.row` only ever render inside it
62
+ (single call site, shell.js AppShell). */
63
+ .app .row {
64
+ grid-template-columns: minmax(0, 1fr) auto;
65
+ gap: var(--space-2); padding: var(--space-2-75) var(--space-3);
66
+ row-gap: var(--space-1);
60
67
  }
61
68
  .row .sub { grid-column: 1 / -1; order: 3; }
62
69
  .row .title { font-size: var(--fs-sm); }
63
70
  /* Changelog carries 3 children: give date+ver line one, message wraps below
64
- (the generic 2-col .row override staggers it into an implicit row). */
65
- .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
71
+ (the generic 2-col .row override staggers it into an implicit row).
72
+ Needs (0,3,0) to clear BOTH the `.app .row` rule directly above and
73
+ `.ds-changelog-row`'s own !important base in hero-content.css — an
74
+ !important base can only be beaten by another !important, so this one
75
+ stays until that upstream flag is removed (hero-content.css is outside
76
+ this change's scope). */
77
+ .app .row.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
66
78
  .ds-changelog-row .title { grid-column: 1 / -1; }
67
79
 
68
80
  /* Buttons */
69
81
  .btn, .btn-primary, .btn-ghost {
70
- padding: 11px 16px; font-size: var(--fs-tiny);
82
+ /* 11px vertical is optical, not scale drift: --space-2-75 (12) would tip
83
+ the intrinsic box past the 44px min-height floor below and make the
84
+ floor dead, changing the mobile button rhythm. */
85
+ padding: 11px var(--space-3); font-size: var(--fs-tiny);
71
86
  min-height: 44px; /* Touch target minimum */
72
87
  }
73
88
 
@@ -75,13 +90,13 @@
75
90
  .ds-file-grid {
76
91
  display: flex;
77
92
  flex-direction: column;
78
- gap: 3px;
93
+ gap: var(--space-half);
79
94
  }
80
95
  .ds-file-row {
81
- gap: 8px; padding: 10px 12px;
96
+ gap: var(--space-2); padding: var(--space-2-5) var(--space-2-75);
82
97
  font-size: var(--fs-xs);
83
98
  }
84
- .ds-file-open { gap: 10px; }
99
+ .ds-file-open { gap: var(--space-2-5); }
85
100
  /* At mobile row widths, a fixed-size meta column (date/size) plus the
86
101
  always-visible action buttons leave the flexible title only a few px —
87
102
  not enough for even one legible character before the two collide. Drop
@@ -98,12 +113,12 @@
98
113
  /* Chat */
99
114
  .chat-stack { max-width: 100%; min-width: 0; }
100
115
  .chat-bubble {
101
- padding: 10px 12px; font-size: var(--fs-sm);
116
+ padding: var(--space-2-5) var(--space-2-75); font-size: var(--fs-sm);
102
117
  }
103
118
  .chat-avatar { width: 28px; height: 28px; font-size: 11px; }
104
- .chat-msg:hover { padding: 4px 0; margin: 0; background: transparent; }
105
- .chat-composer { padding: 8px; gap: 6px; }
106
- .chat-composer textarea { padding: 10px 12px; font-size: var(--fs-sm); }
119
+ .chat-msg:hover { padding: var(--space-1) 0; margin: 0; background: transparent; }
120
+ .chat-composer { padding: var(--space-2); gap: var(--space-1-75); }
121
+ .chat-composer textarea { padding: var(--space-2-5) var(--space-2-75); font-size: var(--fs-sm); }
107
122
 
108
123
  /* KPI Cards */
109
124
  .kpi {
@@ -119,9 +134,11 @@
119
134
  .empty { padding: var(--space-5); font-size: var(--fs-xs); }
120
135
 
121
136
  /* Form */
122
- .row-form { gap: 10px; padding: var(--space-3); }
137
+ .row-form { gap: var(--space-2-5); padding: var(--space-3); }
123
138
  .row-form input,
124
- .row-form textarea { padding: 11px 12px; font-size: var(--fs-sm); }
139
+ /* 11px block is the tuned inset that lines the textarea baseline up with the
140
+ sibling input; --space-2-75 (12) would offset the two by 1px each side. */
141
+ .row-form textarea { padding: 11px var(--space-2-75); font-size: var(--fs-sm); }
125
142
 
126
143
  /* Hero Section — keep fluid base font-size, just unconstrain width on mobile. */
127
144
  .ds-hero { padding: var(--space-6) 0 var(--space-5); }
@@ -131,26 +148,34 @@
131
148
  /* Table Responsiveness */
132
149
  table { font-size: var(--fs-xs); }
133
150
  table th,
134
- table td { padding: 10px 12px; }
151
+ table td { padding: var(--space-2-5) var(--space-2-75); }
135
152
 
136
153
  /* CLI Block */
137
154
  .cli {
138
- flex-direction: column; align-items: flex-start; gap: 10px;
139
- padding: 16px 12px; font-size: var(--fs-xs);
155
+ flex-direction: column; align-items: flex-start; gap: var(--space-2-5);
156
+ padding: var(--space-3) var(--space-2-75); font-size: var(--fs-xs);
140
157
  }
141
- .cli .copy { padding: 6px 12px; font-size: var(--fs-micro); }
158
+ .cli .copy { padding: var(--space-1-75) var(--space-2-75); font-size: var(--fs-micro); }
142
159
  }
143
160
 
144
161
  /* --------------------------------------------------------------------
145
162
  Container Query Responsive (720px and below)
146
163
  ---------------------------------------------------------------------- */
147
164
  @container (max-width: 760px) {
148
- .app-body { grid-template-columns: 1fr !important; }
165
+ /* `.app`-scoped for specificity, not an !important flag: the bare `.app-body`
166
+ (0,1,0) was out-specified by `.app-body.no-side` (0,2,0) in topbar.css, so
167
+ a sidebar-less shell kept its base template. `.app .app-body` is (0,2,0)
168
+ and lands later in source, beating both topbar.css rules on merit. */
169
+ .app .app-body { grid-template-columns: 1fr; }
149
170
  .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
150
- .app-topbar nav { font-size: var(--fs-xs); gap: 14px; }
151
- .row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: 4px !important; }
171
+ .app-topbar nav { font-size: var(--fs-xs); gap: var(--space-2-75); }
172
+ /* Same (0,2,0) lift as the 480px block above — clears `.row.row-nocode` and
173
+ the later `@media` `.row` rules in this file without a flag. */
174
+ .app .row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-1); }
152
175
  .row .sub { grid-column: 1 / -1; order: 3; }
153
- .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
176
+ /* (0,3,0) + !important: still required to beat `.ds-changelog-row`'s
177
+ !important base in hero-content.css (see the 480px block). */
178
+ .app .row.ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
154
179
  .ds-changelog-row .title { grid-column: 1 / -1; }
155
180
  }
156
181
 
@@ -160,7 +185,7 @@
160
185
  @media (min-width: 481px) and (max-width: 1024px) {
161
186
  /* App Layout — side handled by 900px drawer block; restore for 901-1024 */
162
187
  .app-side a {
163
- padding: 12px 12px; gap: 8px;
188
+ padding: var(--space-2-75) var(--space-2-75); gap: var(--space-2);
164
189
  grid-template-columns: 16px 1fr auto;
165
190
  font-size: var(--fs-xs);
166
191
  min-height: 44px;
@@ -168,14 +193,14 @@
168
193
 
169
194
  /* Topbar Navigation (flex container — no grid-template here) */
170
195
  .app-topbar {
171
- gap: var(--space-3); padding: 12px var(--space-4);
196
+ gap: var(--space-3); padding: var(--space-2-75) var(--space-4);
172
197
  }
173
198
  .app-topbar nav {
174
- display: flex; gap: 8px; font-size: var(--fs-xs);
199
+ display: flex; gap: var(--space-2); font-size: var(--fs-xs);
175
200
  flex-wrap: wrap;
176
201
  }
177
202
  .app-topbar nav a {
178
- padding: 12px 12px; font-size: var(--fs-xs);
203
+ padding: var(--space-2-75) var(--space-2-75); font-size: var(--fs-xs);
179
204
  min-height: 44px;
180
205
  }
181
206
  .brand { font-size: var(--fs-sm); }
@@ -184,7 +209,10 @@
184
209
  .app-search {
185
210
  display: inline-flex;
186
211
  max-width: 280px; font-size: var(--fs-xs);
187
- padding: 8px 14px;
212
+ /* 14px inline is between --space-2-75 (12) and --space-3 (16) with no tier;
213
+ it is the width that centers the search glyph against the 280px max-width
214
+ field. Snapping either way reads as a mis-centered control. */
215
+ padding: var(--space-2) 14px;
188
216
  }
189
217
 
190
218
  /* Main Content */
@@ -196,12 +224,17 @@
196
224
  /* File list — single column rows on tablet (cards only via data-columns) */
197
225
  .ds-file-row {
198
226
  grid-template-columns: 24px minmax(0, 1fr) auto auto;
199
- gap: 12px; padding: 12px 14px;
227
+ /* 14px inline (no tier between 12 and 16) is the tablet row inset that
228
+ keeps the 24px icon column optically flush with the panel edge. */
229
+ gap: var(--space-2-75); padding: var(--space-2-75) 14px;
200
230
  }
201
231
 
202
232
  /* Chat Bubbles */
203
233
  .chat-stack { max-width: min(75%, 420px); }
204
234
  .chat-bubble {
235
+ /* 11px/14px are the tuned tablet bubble insets; neither is on the scale
236
+ (11 sits between --space-2-5 and --space-2-75, 14 between --space-2-75
237
+ and --space-3) and snapping visibly re-pitches every bubble in a thread. */
205
238
  padding: 11px 14px; font-size: var(--fs-sm);
206
239
  }
207
240
  .chat-avatar { width: 32px; height: 32px; font-size: 12px; }
@@ -214,7 +247,10 @@
214
247
 
215
248
  /* Buttons */
216
249
  .btn, .btn-primary, .btn-ghost {
217
- padding: 12px 18px; font-size: var(--fs-sm);
250
+ /* 18px inline has no tier (--space-3 is 16, --space-3-5 is 20); it is the
251
+ tablet CTA width tuned against the 12px vertical, so snapping changes
252
+ the button aspect on the most visible control in the kit. */
253
+ padding: var(--space-2-75) 18px; font-size: var(--fs-sm);
218
254
  }
219
255
 
220
256
  /* Panel - keep the head on the body's left axis at laptop widths too. */
@@ -228,7 +264,9 @@
228
264
  /* Row */
229
265
  .row {
230
266
  grid-template-columns: minmax(90px, 12ch) minmax(0, 1fr) auto;
231
- gap: var(--space-2); padding: 14px 16px;
267
+ /* 14px block (no tier between 12 and 16) is the tablet row height tuned
268
+ against the 12ch code column; snapping re-pitches the whole list. */
269
+ gap: var(--space-2); padding: 14px var(--space-3);
232
270
  }
233
271
  }
234
272
 
@@ -10,8 +10,16 @@
10
10
  even on a wide desktop. Drawer/scrim/toggle are absolute (anchored to .app), so
11
11
  they overlay the window, not the page. */
12
12
  @container (max-width: 900px) {
13
- .app-body,
14
- .app-body.no-side { grid-template-columns: 1fr !important; }
13
+ /* `.app`-scoped for specificity instead of an !important flag. The bare
14
+ `.app-body` half of this list is (0,1,0) and was out-specified by
15
+ `.app-body.no-side` (0,2,0) in topbar.css; scoping lifts both halves to
16
+ (0,2,0)/(0,3,0), which also lands later in source than topbar.css, so the
17
+ drawer collapse wins on merit. `.app` is guaranteed: `.app-body` is
18
+ emitted only as a direct child of `.app` (single call site, shell.js
19
+ AppShell), and this @container query already requires `.app` as its
20
+ container ancestor. */
21
+ .app .app-body,
22
+ .app .app-body.no-side { grid-template-columns: 1fr; }
15
23
  .app-side-shell {
16
24
  position: absolute;
17
25
  /* Full-height overlay drawer: the merged .app-chrome wraps and its real
@@ -36,9 +44,13 @@
36
44
  .app-side-shell.open,
37
45
  .app-side.open,
38
46
  .app-body.side-open .app-side-shell { transform: translateX(0); }
47
+ /* No flags needed: the ONLY other rule that touches these properties is the
48
+ `.app-side` base in topbar.css, which already sets `flex-direction: column`
49
+ and never sets `flex-wrap` (nowrap is the initial value anyway). This rule
50
+ is equal-specificity and later in source, so it wins unaided. */
39
51
  .app-side {
40
- flex-direction: column !important;
41
- flex-wrap: nowrap !important;
52
+ flex-direction: column;
53
+ flex-wrap: nowrap;
42
54
  gap: var(--space-2);
43
55
  padding: var(--space-3);
44
56
  font-size: var(--fs-sm);
@@ -56,11 +56,16 @@ button:disabled, [disabled] {
56
56
  animation: spinner-rotate 0.8s linear infinite;
57
57
  }
58
58
 
59
- /* Error state */
59
+ /* Error state.
60
+ No !important: the only rule in the kit that also resets a matching element's
61
+ border-color is the bare-control base below (`textarea:where(:not(.input))`
62
+ et al, which use the `border: 0` shorthand). Those selectors are (0,0,1) —
63
+ the :where() guard adds nothing — so every selector in this list out-specifies
64
+ them on merit, and specificity beats the later source position. */
60
65
  .error, [data-state="error"],
61
66
  .row.error, input.error,
62
67
  textarea.error {
63
- border-color: var(--warn) !important;
68
+ border-color: var(--warn);
64
69
  background-color: color-mix(in oklab, var(--warn) 6%, var(--bg));
65
70
  }
66
71
  .error::placeholder { color: color-mix(in oklab, var(--warn) 60%, var(--fg-3)); }
@@ -576,7 +581,17 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
576
581
  .skip-to-main:focus { top: 10px; }
577
582
 
578
583
  /* Reduced motion preferences — scoped to the DS surface so it doesn't reach
579
- into and neutralize the host document's own motion. */
584
+ into and neutralize the host document's own motion.
585
+ The !important flags here are LOAD-BEARING and must not be "cleaned up":
586
+ `.ds-247420 *` / `.app *` is only (0,1,0) — the universal selector adds
587
+ nothing — yet it has to defeat every animation/transition declaration in the
588
+ kit, many of which are strictly more specific. Concrete rules it would
589
+ otherwise lose to: `.ds-dropzone.dragover` (0,2,0, files.css),
590
+ `.ds-upload-bar.indeterminate .ds-upload-fill` (0,3,0, files.css),
591
+ `.list-item.drag-after::after` (0,2,1, this file). Raising this selector to
592
+ out-specify an open-ended set of future component rules is not possible, so
593
+ the flag is the only correct mechanism — this is a WCAG 2.3.3 guarantee,
594
+ not a stylistic preference. */
580
595
  @media (prefers-reduced-motion: reduce) {
581
596
  .ds-247420 *, .app * {
582
597
  animation-duration: 0.01ms !important;
@@ -584,7 +599,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
584
599
  transition-duration: 0.01ms !important;
585
600
  }
586
601
  /* Kill the residual paint frame of looping skeleton/shimmer placeholders and
587
- give reduced-motion users a steady placeholder fill instead. */
602
+ give reduced-motion users a steady placeholder fill instead.
603
+ Also load-bearing: `.skeleton` is (0,1,0) and must override
604
+ `.ds-session-row-skeleton .ds-skel` (0,2,0), which sets its own shimmer. */
588
605
  .skeleton, .ds-skeleton, .ds-session-row-skeleton .ds-skel {
589
606
  animation: none !important;
590
607
  background: var(--bg-2) !important;
@@ -201,7 +201,11 @@ body.canvas-host { background: transparent !important; }
201
201
  border-radius: var(--r-pill);
202
202
  }
203
203
  /* The lime active pill is the sidebar's one accent moment; its own count
204
- chip rides the ink-on-accent pair instead of a second competing hue. */
204
+ chip rides the ink-on-accent pair instead of a second competing hue.
205
+ The bare --accent here is deliberate and is NOT the usual accent-as-text
206
+ defect: the chip's own background is --accent-fg (ink), so this is the
207
+ INVERTED pair -- lime on ink, which is the high-contrast direction. Only
208
+ accent-coloured text on a normal background needs --accent-ink. */
205
209
  .app-side a.active .count {
206
210
  background: color-mix(in oklab, var(--accent-fg) 82%, transparent);
207
211
  color: var(--accent);