anentrypoint-design 0.0.380 → 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 (68) hide show
  1. package/app-shell.css +16 -0
  2. package/chat.css +102 -62
  3. package/colors_and_type.css +66 -7
  4. package/community.css +104 -70
  5. package/dist/247420.css +1123 -465
  6. package/dist/247420.js +32 -29
  7. package/package.json +1 -1
  8. package/src/components/content/avatar.js +31 -0
  9. package/src/components/content/charts.js +50 -0
  10. package/src/components/content/cli.js +46 -0
  11. package/src/components/content/feedback.js +77 -0
  12. package/src/components/content/fields.js +136 -0
  13. package/src/components/content/hero.js +146 -0
  14. package/src/components/content/lists.js +85 -0
  15. package/src/components/content/panel.js +79 -0
  16. package/src/components/content/row.js +115 -0
  17. package/src/components/content/table.js +97 -0
  18. package/src/components/content/views.js +81 -0
  19. package/src/components/content.js +29 -852
  20. package/src/components/editor-primitives/batch.js +60 -0
  21. package/src/components/editor-primitives/chrome.js +146 -0
  22. package/src/components/editor-primitives/collapse.js +46 -0
  23. package/src/components/editor-primitives/context-menu.js +127 -0
  24. package/src/components/editor-primitives/diagnostics.js +44 -0
  25. package/src/components/editor-primitives/focus-trap.js +26 -0
  26. package/src/components/editor-primitives/json-viewer.js +123 -0
  27. package/src/components/editor-primitives/layout.js +89 -0
  28. package/src/components/editor-primitives/modals.js +89 -0
  29. package/src/components/editor-primitives/pager.js +74 -0
  30. package/src/components/editor-primitives/property-grid.js +57 -0
  31. package/src/components/editor-primitives/shared.js +18 -0
  32. package/src/components/editor-primitives/split-panel.js +101 -0
  33. package/src/components/editor-primitives/toast.js +59 -0
  34. package/src/components/editor-primitives/tree.js +75 -0
  35. package/src/components/editor-primitives.js +35 -1048
  36. package/src/components/freddie/helpers.js +7 -0
  37. package/src/components/freddie.js +21 -21
  38. package/src/components/overlay-primitives/approval-prompt.js +38 -0
  39. package/src/components/overlay-primitives/auth-modal.js +89 -0
  40. package/src/components/overlay-primitives/command-palette.js +101 -0
  41. package/src/components/overlay-primitives/emoji-picker.js +103 -0
  42. package/src/components/overlay-primitives/floating.js +146 -0
  43. package/src/components/overlay-primitives/full-screen.js +45 -0
  44. package/src/components/overlay-primitives/menus.js +131 -0
  45. package/src/components/overlay-primitives/popover.js +51 -0
  46. package/src/components/overlay-primitives/roving-menu.js +73 -0
  47. package/src/components/overlay-primitives/settings-popover.js +85 -0
  48. package/src/components/overlay-primitives/tooltip.js +55 -0
  49. package/src/components/overlay-primitives.js +33 -855
  50. package/src/css/app-shell/base.css +11 -1
  51. package/src/css/app-shell/catalog-theme.css +7 -0
  52. package/src/css/app-shell/chat-polish.css +45 -33
  53. package/src/css/app-shell/data-density.css +46 -24
  54. package/src/css/app-shell/files.css +40 -32
  55. package/src/css/app-shell/hero-content.css +1 -1
  56. package/src/css/app-shell/kits-appended.css +456 -79
  57. package/src/css/app-shell/panel-row.css +6 -1
  58. package/src/css/app-shell/plugins-config.css +1 -1
  59. package/src/css/app-shell/responsive.css +47 -29
  60. package/src/css/app-shell/responsive2-workspace.css +17 -12
  61. package/src/css/app-shell/states-interactions.css +9 -4
  62. package/src/kits/os/freddie-dashboard.css +2 -2
  63. package/src/kits/os/launcher.css +1 -1
  64. package/src/kits/os/theme.css +359 -283
  65. package/src/kits/os/wm.css +2 -2
  66. package/src/kits/slides/deck-stage-style.js +5 -2
  67. package/src/kits/spoint/host-join-lobby.css +1 -1
  68. package/src/kits/spoint/loading-screen.css +1 -1
package/community.css CHANGED
@@ -4,6 +4,25 @@
4
4
  All tokens sourced from colors_and_type.css.
5
5
  ============================================================ */
6
6
 
7
+ /* ============================================================
8
+ Small-label voice — the local composition of the house `.t-micro`
9
+ recipe (src/css/app-shell/base.css). This sheet is a standalone
10
+ published export consumed via its own <link>, so it cannot join the
11
+ `.t-micro` selector list; it composes by referencing the identical
12
+ token set instead. Every selector below that needs the label voice
13
+ JOINS this rule and declares only what it deliberately differs on —
14
+ never a second copy of these four declarations.
15
+ ============================================================ */
16
+ .cm-vs-label,
17
+ .vx-section-label,
18
+ .vx-chip-tag {
19
+ font-family: var(--ff-mono);
20
+ font-size: var(--fs-micro);
21
+ text-transform: uppercase;
22
+ letter-spacing: var(--tr-label);
23
+ color: var(--fg-3);
24
+ }
25
+
7
26
  /* ============================================================
8
27
  Shell — top-level flex container for the community layout
9
28
  ============================================================ */
@@ -42,8 +61,8 @@
42
61
  display: flex;
43
62
  flex-direction: column;
44
63
  align-items: center;
45
- gap: 8px;
46
- padding: 12px 0;
64
+ gap: var(--space-2);
65
+ padding: var(--space-2-75) 0;
47
66
  background: color-mix(in oklab, var(--bg) 70%, var(--ink));
48
67
  overflow-y: auto;
49
68
  overflow-x: hidden;
@@ -112,7 +131,7 @@
112
131
  right: -2px;
113
132
  min-width: 18px;
114
133
  height: 18px;
115
- padding: 0 5px;
134
+ padding: 0 var(--space-1-5);
116
135
  background: var(--warn);
117
136
  color: var(--paper);
118
137
  font-family: var(--ff-mono);
@@ -157,7 +176,7 @@
157
176
  height: 2px;
158
177
  background: color-mix(in oklab, var(--fg) 12%, transparent);
159
178
  border-radius: var(--r-hair);
160
- margin: 4px 0;
179
+ margin: var(--space-1) 0;
161
180
  flex-shrink: 0;
162
181
  }
163
182
 
@@ -178,8 +197,8 @@
178
197
  display: flex;
179
198
  align-items: center;
180
199
  justify-content: space-between;
181
- gap: 8px;
182
- padding: 14px 16px;
200
+ gap: var(--space-2);
201
+ padding: var(--space-2-75) var(--space-3);
183
202
  background: var(--bg-2);
184
203
  box-shadow: 0 1px 0 color-mix(in oklab, var(--fg) 8%, transparent);
185
204
  font-weight: 600;
@@ -206,10 +225,10 @@
206
225
  min-height: 0;
207
226
  overflow-y: auto;
208
227
  overflow-x: hidden;
209
- padding: 8px 0 16px;
228
+ padding: var(--space-2) 0 var(--space-3);
210
229
  display: flex;
211
230
  flex-direction: column;
212
- gap: 2px;
231
+ gap: var(--space-hair);
213
232
  scrollbar-width: thin;
214
233
  scrollbar-color: color-mix(in oklab, var(--fg) 18%, transparent) transparent;
215
234
  }
@@ -226,15 +245,15 @@
226
245
  .cm-channel-category {
227
246
  display: flex;
228
247
  flex-direction: column;
229
- margin-top: 12px;
248
+ margin-top: var(--space-2-75);
230
249
  }
231
- .cm-channel-category:first-child { margin-top: 4px; }
250
+ .cm-channel-category:first-child { margin-top: var(--space-1); }
232
251
 
233
252
  .cm-category-header {
234
253
  display: flex;
235
254
  align-items: center;
236
- gap: 4px;
237
- padding: 4px 8px 4px 8px;
255
+ gap: var(--space-1);
256
+ padding: var(--space-1) var(--space-2);
238
257
  font-family: var(--ff-body);
239
258
  font-size: var(--fs-micro);
240
259
  font-weight: 600;
@@ -268,6 +287,10 @@
268
287
  text-overflow: ellipsis;
269
288
  white-space: nowrap;
270
289
  }
290
+ /* Deliberately NOT the small-label voice: this is the `+` affordance sitting
291
+ inside .cm-category-header, which IS uppercase + tracked. The zeroed
292
+ letter-spacing and text-transform are resets of that inherited voice, not a
293
+ copy of it — a bare glyph must not be tracked apart or case-folded. */
271
294
  .cm-cat-extra {
272
295
  font-family: var(--ff-mono);
273
296
  font-size: var(--fs-micro);
@@ -282,7 +305,7 @@
282
305
  justify-content: center;
283
306
  width: 28px;
284
307
  height: 28px;
285
- padding: 4px;
308
+ padding: var(--space-1);
286
309
  border: 0;
287
310
  background: transparent;
288
311
  color: var(--fg-3);
@@ -304,8 +327,11 @@
304
327
  .cm-cat-channels {
305
328
  display: flex;
306
329
  flex-direction: column;
330
+ /* gap:1px is OFF-SCALE ON PURPOSE — channel rows are meant to read as one
331
+ near-continuous stack with only a hairline seam between them. --space-hair
332
+ (2px) doubles the seam and breaks the rows into visibly separate pills. */
307
333
  gap: 1px;
308
- padding: 2px 0;
334
+ padding: var(--space-hair) 0;
309
335
  }
310
336
 
311
337
  /* ============================================================
@@ -313,15 +339,15 @@
313
339
  ============================================================ */
314
340
  .cm-channel-item-wrap {
315
341
  position: relative;
316
- padding: 0 8px;
342
+ padding: 0 var(--space-2);
317
343
  }
318
344
 
319
345
  .cm-channel-item {
320
346
  position: relative;
321
347
  display: flex;
322
348
  align-items: center;
323
- gap: 8px;
324
- padding: 6px 8px;
349
+ gap: var(--space-2);
350
+ padding: var(--space-1-75) var(--space-2);
325
351
  border-radius: var(--r-1);
326
352
  color: var(--fg-3);
327
353
  cursor: pointer;
@@ -437,7 +463,7 @@
437
463
  flex-shrink: 0;
438
464
  min-width: 16px;
439
465
  height: 16px;
440
- padding: 0 5px;
466
+ padding: 0 var(--space-1-5);
441
467
  background: var(--warn);
442
468
  color: var(--paper);
443
469
  font-family: var(--ff-mono);
@@ -453,7 +479,7 @@
453
479
  .cm-ch-actions {
454
480
  display: inline-flex;
455
481
  align-items: center;
456
- gap: 2px;
482
+ gap: var(--space-hair);
457
483
  opacity: 0;
458
484
  transition: opacity var(--dur-snap) var(--ease);
459
485
  flex-shrink: 0;
@@ -463,7 +489,7 @@
463
489
  .cm-ch-action-btn {
464
490
  width: 28px;
465
491
  height: 28px;
466
- padding: 4px;
492
+ padding: var(--space-1);
467
493
  display: inline-flex;
468
494
  align-items: center;
469
495
  justify-content: center;
@@ -488,15 +514,16 @@
488
514
  .cm-ch-voice-users {
489
515
  display: flex;
490
516
  flex-direction: column;
517
+ /* gap:1px — same hairline-seam rationale as .cm-cat-channels above. */
491
518
  gap: 1px;
492
- padding: 2px 8px 4px 32px;
519
+ padding: var(--space-hair) var(--space-2) var(--space-1) var(--space-5);
493
520
  }
494
521
 
495
522
  .cm-ch-voice-user {
496
523
  display: flex;
497
524
  align-items: center;
498
- gap: 8px;
499
- padding: 3px 6px;
525
+ gap: var(--space-2);
526
+ padding: var(--space-half) var(--space-1-75);
500
527
  border-radius: var(--r-1);
501
528
  color: var(--fg-2);
502
529
  font-size: var(--fs-xs);
@@ -550,8 +577,8 @@
550
577
  .cm-voice-strip {
551
578
  display: none;
552
579
  flex-direction: column;
553
- gap: 8px;
554
- padding: 10px 12px;
580
+ gap: var(--space-2);
581
+ padding: var(--space-2-5) var(--space-2-75);
555
582
  background: color-mix(in oklab, var(--green) 18%, var(--bg-2));
556
583
  color: var(--fg);
557
584
  box-shadow: 0 -1px 0 color-mix(in oklab, var(--fg) 10%, transparent);
@@ -559,16 +586,15 @@
559
586
  }
560
587
  .cm-voice-strip.open { display: flex; }
561
588
 
589
+ /* Joins the small-label voice above. Deliberate overrides: --green (this is a
590
+ live-recording indicator, not neutral chrome) and weight 700 (it sits next to
591
+ a pulsing dot and must read as the loudest thing in the strip). */
562
592
  .cm-vs-label {
563
- font-family: var(--ff-mono);
564
- font-size: var(--fs-micro);
565
- text-transform: uppercase;
566
- letter-spacing: var(--tr-caps);
567
593
  color: var(--green);
568
594
  font-weight: 700;
569
595
  display: inline-flex;
570
596
  align-items: center;
571
- gap: 6px;
597
+ gap: var(--space-1-75);
572
598
  }
573
599
  .cm-vs-label::before {
574
600
  content: '';
@@ -602,7 +628,7 @@
602
628
  color: var(--fg-2);
603
629
  display: flex;
604
630
  align-items: center;
605
- gap: 6px;
631
+ gap: var(--space-1-75);
606
632
  flex-wrap: wrap;
607
633
  }
608
634
 
@@ -610,9 +636,9 @@
610
636
  display: inline-flex;
611
637
  align-items: center;
612
638
  justify-content: center;
613
- gap: 6px;
639
+ gap: var(--space-1-75);
614
640
  height: 28px;
615
- padding: 0 10px;
641
+ padding: 0 var(--space-2-5);
616
642
  background: color-mix(in oklab, var(--fg) 10%, transparent);
617
643
  color: var(--fg);
618
644
  border: 0;
@@ -640,8 +666,8 @@
640
666
  .cm-user-panel {
641
667
  display: flex;
642
668
  align-items: center;
643
- gap: 8px;
644
- padding: 8px 8px;
669
+ gap: var(--space-2);
670
+ padding: var(--space-2);
645
671
  background: color-mix(in oklab, var(--fg) 5%, var(--bg-2));
646
672
  flex-shrink: 0;
647
673
  }
@@ -694,6 +720,8 @@
694
720
  text-overflow: ellipsis;
695
721
  white-space: nowrap;
696
722
  }
723
+ /* Deliberately NOT the small-label voice: a user's handle/tag is content, not
724
+ chrome, so it stays sentence-case and untracked. Mono + micro + --fg-3 only. */
697
725
  .cm-user-tag {
698
726
  font-family: var(--ff-mono);
699
727
  font-size: var(--fs-micro);
@@ -706,7 +734,7 @@
706
734
  .cm-user-controls {
707
735
  display: inline-flex;
708
736
  align-items: center;
709
- gap: 2px;
737
+ gap: var(--space-hair);
710
738
  }
711
739
 
712
740
  .cm-user-btn {
@@ -741,8 +769,8 @@
741
769
  .cm-chat-header {
742
770
  display: flex;
743
771
  align-items: center;
744
- gap: 10px;
745
- padding: 12px 16px;
772
+ gap: var(--space-2-5);
773
+ padding: var(--space-2-75) var(--space-3);
746
774
  background: var(--bg);
747
775
  box-shadow: 0 1px 0 color-mix(in oklab, var(--fg) 8%, transparent);
748
776
  flex-shrink: 0;
@@ -772,8 +800,8 @@
772
800
  .cm-chat-header-topic {
773
801
  flex: 1;
774
802
  min-width: 0;
775
- padding-left: 12px;
776
- margin-left: 4px;
803
+ padding-left: var(--space-2-75);
804
+ margin-left: var(--space-1);
777
805
  border-left: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
778
806
  color: var(--fg-3);
779
807
  font-size: var(--fs-xs);
@@ -785,7 +813,7 @@
785
813
  .cm-chat-header-toolbar {
786
814
  display: inline-flex;
787
815
  align-items: center;
788
- gap: 4px;
816
+ gap: var(--space-1);
789
817
  flex-shrink: 0;
790
818
  }
791
819
 
@@ -801,7 +829,7 @@
801
829
  overflow-y: auto;
802
830
  overflow-x: hidden;
803
831
  background: var(--bg-2);
804
- padding: 16px 0;
832
+ padding: var(--space-3) 0;
805
833
  scrollbar-width: thin;
806
834
  scrollbar-color: color-mix(in oklab, var(--fg) 18%, transparent) transparent;
807
835
  transition: width var(--dur-base) var(--ease), flex-basis var(--dur-base) var(--ease);
@@ -823,7 +851,7 @@
823
851
  }
824
852
 
825
853
  .cm-member-category {
826
- padding: 12px 16px 6px;
854
+ padding: var(--space-2-75) var(--space-3) var(--space-1-75);
827
855
  font-family: var(--ff-body);
828
856
  font-size: var(--fs-micro);
829
857
  font-weight: 600;
@@ -835,9 +863,9 @@
835
863
  .cm-member-item {
836
864
  display: flex;
837
865
  align-items: center;
838
- gap: 10px;
839
- padding: 6px 12px;
840
- margin: 0 8px;
866
+ gap: var(--space-2-5);
867
+ padding: var(--space-1-75) var(--space-2-75);
868
+ margin: 0 var(--space-2);
841
869
  border-radius: var(--r-1);
842
870
  color: var(--fg-2);
843
871
  cursor: pointer;
@@ -902,8 +930,8 @@
902
930
  display: inline-flex;
903
931
  flex-direction: column;
904
932
  align-items: center;
905
- gap: 6px;
906
- padding: 10px;
933
+ gap: var(--space-1-75);
934
+ padding: var(--space-2-5);
907
935
  border-radius: var(--r-2);
908
936
  background: var(--bg-2);
909
937
  transition: box-shadow var(--dur-snap) var(--ease), background var(--dur-snap) var(--ease);
@@ -953,7 +981,7 @@
953
981
  @media (max-width: 900px) {
954
982
  .cm-channel-sidebar {
955
983
  position: absolute;
956
- z-index: 20;
984
+ z-index: calc(var(--z-drawer) + 1);
957
985
  top: 0;
958
986
  left: 72px;
959
987
  bottom: 0;
@@ -966,7 +994,7 @@
966
994
  .cm-member-list.open {
967
995
  display: flex;
968
996
  position: absolute;
969
- z-index: 20;
997
+ z-index: calc(var(--z-drawer) + 1);
970
998
  top: 0;
971
999
  right: 0;
972
1000
  bottom: 0;
@@ -986,7 +1014,7 @@
986
1014
  content: '';
987
1015
  position: absolute;
988
1016
  inset: 0;
989
- z-index: 15;
1017
+ z-index: var(--z-drawer);
990
1018
  background: color-mix(in oklab, var(--ink) 40%, transparent);
991
1019
  pointer-events: none;
992
1020
  }
@@ -1002,7 +1030,7 @@
1002
1030
  .cm-server-back {
1003
1031
  width: 44px;
1004
1032
  height: 44px;
1005
- padding: 4px;
1033
+ padding: var(--space-1);
1006
1034
  }
1007
1035
  .cm-channel-sidebar,
1008
1036
  .cm-channel-sidebar.open {
@@ -1148,7 +1176,12 @@
1148
1176
  gap: var(--space-2);
1149
1177
  padding: var(--space-1) var(--space-2);
1150
1178
  background: var(--bg-2);
1151
- border-left: 3px solid var(--accent);
1179
+ /* Hairline, not a 3px accent bar. This is a transient status strip pinned
1180
+ above the composer (role=status, "Replying to <author>"), not a card or a
1181
+ callout — the tinted fill already carries the attachment. A chunky left
1182
+ bar here was the generic accent-stripe tell; the real accent still lands
1183
+ on .cm-rb-author. */
1184
+ border-left: var(--bw-hair) solid var(--rule-strong);
1152
1185
  font-size: 0.85rem;
1153
1186
  }
1154
1187
  .cm-rb-label { flex: none; color: var(--fg-2); }
@@ -1196,7 +1229,7 @@
1196
1229
  color: inherit;
1197
1230
  font: inherit;
1198
1231
  font-weight: 600;
1199
- padding: 2px var(--space-2);
1232
+ padding: var(--space-hair) var(--space-2);
1200
1233
  border-radius: var(--r-1);
1201
1234
  cursor: pointer;
1202
1235
  }
@@ -1426,13 +1459,7 @@
1426
1459
  border-top: var(--bw-hair) solid var(--rule);
1427
1460
  }
1428
1461
  .vx-section { display: flex; flex-direction: column; gap: var(--space-2); }
1429
- .vx-section-label {
1430
- font-family: var(--ff-mono);
1431
- font-size: var(--fs-micro);
1432
- letter-spacing: var(--tr-label);
1433
- text-transform: uppercase;
1434
- color: var(--fg-3);
1435
- }
1462
+ /* Joins the small-label voice above with no overrides — it IS the plain voice. */
1436
1463
  .vx-segmented { display: flex; gap: var(--space-1); }
1437
1464
  .vx-seg {
1438
1465
  flex: 1;
@@ -1481,7 +1508,7 @@
1481
1508
  display: flex; gap: var(--space-2);
1482
1509
  overflow-x: auto;
1483
1510
  flex: 1;
1484
- padding-bottom: 2px;
1511
+ padding-bottom: var(--space-hair);
1485
1512
  }
1486
1513
  .vx-chip {
1487
1514
  display: inline-flex; align-items: center; gap: var(--space-1);
@@ -1500,9 +1527,11 @@
1500
1527
  .vx-chip-dot { width: 8px; height: 8px; border-radius: var(--r-pill); background: var(--fg-3); flex-shrink: 0; }
1501
1528
  .vx-chip-name { font-weight: 600; }
1502
1529
  .vx-chip-dur { font-family: var(--ff-mono); color: var(--fg-3); }
1530
+ /* Joins the small-label voice above. Deliberate overrides: --green + weight 700
1531
+ because this is the "LIVE" badge on a session chip, same signal role as
1532
+ .cm-vs-label. */
1503
1533
  .vx-chip-tag {
1504
- font-family: var(--ff-mono); font-size: var(--fs-micro);
1505
- color: var(--green); font-weight: 700; letter-spacing: var(--tr-caps);
1534
+ color: var(--green); font-weight: 700;
1506
1535
  }
1507
1536
 
1508
1537
  /* VoiceControls — vx-vc-* */
@@ -1537,7 +1566,7 @@
1537
1566
  @media (max-width: 900px) {
1538
1567
  .cm-thread-panel {
1539
1568
  position: absolute;
1540
- z-index: 20;
1569
+ z-index: calc(var(--z-drawer) + 1);
1541
1570
  top: 0; right: 0; bottom: 0;
1542
1571
  height: auto;
1543
1572
  width: min(320px, 90vw);
@@ -1558,7 +1587,7 @@
1558
1587
  .cm-tp-list { flex: 1; min-height: 0; overflow-y: auto; }
1559
1588
  .cm-tp-item {
1560
1589
  position: relative; /* anchors .cm-tp-dot to the row, not the panel */
1561
- display: flex; flex-direction: column; gap: 2px;
1590
+ display: flex; flex-direction: column; gap: var(--space-hair);
1562
1591
  width: 100%; text-align: left; cursor: pointer;
1563
1592
  padding: var(--space-2); border: none; background: transparent;
1564
1593
  border-bottom: var(--bw-hair) solid var(--rule);
@@ -1583,7 +1612,7 @@
1583
1612
  list surface in the kit uses one shimmer language, never a bare spinner. */
1584
1613
  .cm-channel-item-skeleton, .cm-member-item-skeleton {
1585
1614
  display: flex; align-items: center; gap: var(--space-2);
1586
- padding: var(--space-2); margin: 2px var(--space-1);
1615
+ padding: var(--space-2); margin: var(--space-hair) var(--space-1);
1587
1616
  }
1588
1617
  .cm-channel-item-skeleton .ds-skel-icon, .cm-member-item-skeleton .ds-skel-icon {
1589
1618
  width: 20px; height: 20px; border-radius: var(--r-round, 50%); flex: none; background: var(--bg-3);
@@ -1592,7 +1621,7 @@
1592
1621
  height: 12px; width: 60%; border-radius: var(--r-1); background: var(--bg-3);
1593
1622
  }
1594
1623
  .cm-list-item-skeleton {
1595
- display: flex; flex-direction: column; gap: 6px;
1624
+ display: flex; flex-direction: column; gap: var(--space-1-75);
1596
1625
  padding: var(--space-2) var(--space-3); border-bottom: var(--bw-hair) solid var(--rule);
1597
1626
  }
1598
1627
  .cm-list-item-skeleton .ds-skel-title { height: 12px; width: 55%; border-radius: var(--r-1); background: var(--bg-3); }
@@ -1626,8 +1655,10 @@
1626
1655
  .cm-forum-item-replies { font-size: var(--fs-0, 12px); color: var(--fg-2, var(--fg)); opacity: .8; white-space: nowrap; }
1627
1656
  .cm-forum-item-snippet { font-size: var(--fs-0, 12px); color: var(--fg-2, var(--fg)); opacity: .85; }
1628
1657
  .cm-forum-item-meta { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; font-size: var(--fs-micro, 11px); color: var(--fg-2, var(--fg)); opacity: .7; }
1629
- .cm-forum-item-tags { display: inline-flex; gap: 4px; }
1630
- .cm-forum-tag { padding: 1px 6px; border-radius: var(--r-1); background: var(--bg-3); border: var(--bw-hair) solid var(--rule); }
1658
+ .cm-forum-item-tags { display: inline-flex; gap: var(--space-1); }
1659
+ /* 1px vertical is OFF-SCALE ON PURPOSE the tag is an inline chip inside the
1660
+ forum meta row; --space-hair (2px) tips it past the row height. */
1661
+ .cm-forum-tag { padding: 1px var(--space-1-75); border-radius: var(--r-1); background: var(--bg-3); border: var(--bw-hair) solid var(--rule); }
1631
1662
 
1632
1663
  /* PageView — cm-page / cm-page-* */
1633
1664
  .cm-page { display: flex; flex-direction: column; height: 100%; min-height: 0; overflow-y: auto; background: var(--bg-1, var(--bg-2)); color: var(--fg); }
@@ -1654,6 +1685,9 @@
1654
1685
  .fd-chat-thread { flex: 1 1 auto; min-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-2, 10px); padding: var(--space-2, 10px); }
1655
1686
  .fd-page-error { white-space: pre-wrap; overflow-wrap: anywhere; }
1656
1687
  /* Visually-hidden polite live region — announces async busy/done to SR users. */
1688
+ /* margin:-1px is OFF-SCALE ON PURPOSE — the canonical visually-hidden idiom;
1689
+ the negative margin cancels the 1px box so the live region contributes zero
1690
+ layout. A --space-* rung would reintroduce a measurable gap. */
1657
1691
  .fd-sr-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1658
1692
  /* page-level responsive: tighten padding on narrow viewports */
1659
1693
  @media (max-width: 640px) {