anentrypoint-design 0.0.146 → 0.0.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/247420.css CHANGED
@@ -9,6 +9,10 @@
9
9
  @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400;1,700&family=Space+Grotesk:wght@300;400;500;600;700&display=swap');
10
10
 
11
11
  .ds-247420 {
12
+ /* Tree view indentation tokens */
13
+ --tree-indent: 12px;
14
+ --tree-base-indent: 6px;
15
+
12
16
  /* Paper / Ink — cool stone scale; lets lore palette pop. */
13
17
  --paper: #F6F5F1;
14
18
  --paper-2: #ECEBE6;
@@ -138,6 +142,18 @@
138
142
  --z-overlay: 1000;
139
143
 
140
144
  --measure: 68ch;
145
+ --measure-wide: 940px;
146
+ --measure-narrow: 760px;
147
+
148
+ --sidebar-width: 220px;
149
+ --sidebar-width-collapsed: 64px;
150
+
151
+ --lh-tall: 1.4;
152
+
153
+ /* Control size scale — heights for status/topbar/crumb + controls. */
154
+ --size-sm: 32px;
155
+ --size-base: 42px;
156
+ --size-lg: 56px;
141
157
  }
142
158
 
143
159
  /* ============================================================
@@ -168,7 +184,7 @@
168
184
  .ds-247420 textarea:focus-visible,
169
185
  .ds-247420 select:focus-visible {
170
186
  outline: 2px solid var(--accent);
171
- outline-offset: 1px;
187
+ outline-offset: 2px;
172
188
  }
173
189
 
174
190
  /* Interactive element focus-visible */
@@ -200,6 +216,10 @@
200
216
  --danger: oklch(0.68 0.19 25);
201
217
  }
202
218
 
219
+ /* NOTE: the [data-theme="auto"] block below intentionally duplicates the
220
+ [data-theme="ink"/"dark"] block above. They are NOT literally identical —
221
+ the explicit-dark block also overrides --danger for contrast — so they are
222
+ kept separate rather than consolidated to avoid a behavior change. */
203
223
  @media (prefers-color-scheme: dark) {
204
224
  .ds-247420[data-theme="auto"] {
205
225
  --bg: var(--ink);
@@ -311,6 +331,7 @@
311
331
  ============================================================ */
312
332
  .ds-247420 * { box-sizing: border-box; }
313
333
  .ds-247420, .ds-247420 body { margin: 0; padding: 0; }
334
+ .ds-247420 button, .ds-247420 input, .ds-247420 select, .ds-247420 textarea { font: inherit; }
314
335
 
315
336
  /* ============================================================
316
337
  Accessibility — Skip Link
@@ -330,7 +351,7 @@
330
351
  }
331
352
  .ds-247420 .skip-link:focus {
332
353
  top: 10px;
333
- outline: 2px solid var(--fg-3);
354
+ outline: 2px solid var(--accent);
334
355
  outline-offset: 2px;
335
356
  }
336
357
  .ds-247420 body {
@@ -373,7 +394,7 @@
373
394
 
374
395
  .ds-247420 .lede, .ds-247420 .t-lede {
375
396
  font-family: var(--ff-body); font-size: var(--fs-xl);
376
- line-height: 1.4; max-width: 38ch; font-weight: 400; color: var(--fg-2);
397
+ line-height: var(--lh-tall); max-width: 38ch; font-weight: 400; color: var(--fg-2);
377
398
  margin: 0;
378
399
  }
379
400
 
@@ -429,8 +450,8 @@
429
450
 
430
451
  .ds-247420 pre {
431
452
  font-family: var(--ff-mono);
432
- background: var(--ink);
433
- color: var(--paper);
453
+ background: var(--panel-bg, #15151a);
454
+ color: var(--panel-text, inherit);
434
455
  padding: var(--space-5);
435
456
  overflow-x: auto;
436
457
  line-height: 1.55;
@@ -459,10 +480,19 @@
459
480
  padding-right: env(safe-area-inset-right);
460
481
  }
461
482
 
483
+ /* When the app shell is embedded inside a windowed surface (e.g. the freddie
484
+ dashboard mounted in a WM window via .fd-root) it is NOT a full-page app:
485
+ `min-height:100vh` and the absence of an explicit width make it collapse to
486
+ 0 width at desktop, where the responsive single-column @media rules don't
487
+ apply. Inside .fd-root it must fill its container instead. (At <=767px the
488
+ grid already linearizes, which is why the bug only showed at desktop width.) */
489
+ .ds-247420 .fd-root .app { width: 100%; height: 100%; min-height: 0; flex: 1 1 auto; }
490
+ .ds-247420 .fd-root .app-body { min-width: 0; }
491
+
462
492
  .ds-247420 {
463
- --app-status-h: 42px;
464
- --app-topbar-h: 56px;
465
- --app-crumb-h: 32px;
493
+ --app-status-h: var(--size-base);
494
+ --app-topbar-h: var(--size-lg);
495
+ --app-crumb-h: var(--size-sm);
466
496
  }
467
497
 
468
498
  .ds-247420 .app-topbar {
@@ -531,8 +561,11 @@
531
561
  .ds-247420 .app-crumb .crumb-right { margin-left: auto; color: var(--fg-3); }
532
562
 
533
563
  .ds-247420 .app-side-shell { background: var(--bg); }
534
- .ds-247420 .app-body { display: grid; grid-template-columns: 220px minmax(0, 1fr); flex: 1; min-height: 0; }
564
+ .ds-247420 .app-body { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); align-items: stretch; align-content: stretch; flex: 1; min-height: 0; }
535
565
  .ds-247420 .app-body.no-side { grid-template-columns: minmax(0, 1fr); }
566
+ /* When there is no sidebar, the empty side-shell must not occupy a grid row,
567
+ otherwise main wraps to a second (collapsed) row. Remove it from layout. */
568
+ .ds-247420 .app-body.no-side .app-side-shell { display: none; }
536
569
 
537
570
  .ds-247420 .app-side {
538
571
  display: flex; flex-direction: column; gap: var(--space-4);
@@ -572,23 +605,34 @@
572
605
  .ds-247420 .app-main {
573
606
  padding: var(--space-5) var(--pad-x) 0;
574
607
  min-width: 0;
608
+ /* Full-height flex column so a single flex:1 child (e.g. .chat) fills the
609
+ region between crumb and status instead of floating at content height. */
610
+ display: flex; flex-direction: column;
611
+ min-height: 0;
612
+ align-self: stretch;
613
+ height: 100%;
575
614
  }
576
- .ds-247420 .app-main.narrow { max-width: 760px; margin: 0 auto; }
615
+ .ds-247420 .app-main > * { min-height: 0; }
616
+ .ds-247420 .app-main.narrow { max-width: var(--measure-narrow); margin: 0 auto; }
577
617
 
578
618
  @media (min-width: 1400px) {
579
619
  .ds-247420 .app { max-width: 1400px; margin-left: auto; margin-right: auto; }
580
620
  .ds-247420 .app-main .chat,
581
621
  .ds-247420 .app-main > .chat-area,
582
622
  .ds-247420 .app-main > .main-content { max-width: none; margin: 0; width: 100%; }
583
- .ds-247420 .app-status { max-width: 1400px; margin-left: auto; margin-right: auto; left: 0; right: 0; }
623
+ /* Status bar inherits the .app max-width cap above and stretches edge-to-edge
624
+ within it; no separate width constraint (which previously narrowed it). */
625
+ .ds-247420 .app-status { width: 100%; }
584
626
  }
585
627
 
586
628
  .ds-247420 .app-status {
587
629
  display: flex; align-items: center; gap: var(--space-3);
630
+ width: 100%;
588
631
  min-height: var(--app-status-h);
589
632
  padding: 10px var(--pad-x);
590
633
  font-family: var(--ff-mono); font-size: var(--fs-xs);
591
634
  color: var(--fg-3);
635
+ border-top: 1px solid var(--rule);
592
636
  }
593
637
  .ds-247420 .app-status .item { color: inherit; }
594
638
  .ds-247420 .app-status .item:first-of-type { color: var(--accent); }
@@ -620,6 +664,54 @@
620
664
  outline-offset: 2px;
621
665
  }
622
666
 
667
+ /* ============================================================
668
+ IconButton — square icon-only button
669
+ ============================================================ */
670
+ .ds-247420 .ds-icon-btn {
671
+ display: inline-flex; align-items: center; justify-content: center;
672
+ padding: 0; border: none; cursor: pointer;
673
+ border-radius: var(--r-1, 6px);
674
+ background: transparent; color: var(--fg);
675
+ width: 32px; height: 32px;
676
+ }
677
+ .ds-247420 .ds-icon-btn-xs { width: 22px; height: 22px; }
678
+ .ds-247420 .ds-icon-btn-sm { width: 26px; height: 26px; }
679
+ .ds-247420 .ds-icon-btn-base { width: 32px; height: 32px; }
680
+ .ds-247420 .ds-icon-btn-lg { width: 40px; height: 40px; }
681
+ .ds-247420 .ds-icon-btn-xl { width: 48px; height: 48px; }
682
+ .ds-247420 .ds-icon-btn-ghost { background: transparent; }
683
+ .ds-247420 .ds-icon-btn-ghost:hover { background: var(--bg-2); }
684
+ .ds-247420 .ds-icon-btn-primary { background: var(--accent); color: var(--accent-fg); }
685
+ .ds-247420 .ds-icon-btn-primary:hover { background: var(--fg); color: var(--bg); }
686
+ .ds-247420 .ds-icon-btn-danger { background: var(--flame); color: var(--paper); }
687
+ .ds-247420 .ds-icon-btn-danger:hover { filter: brightness(1.1); }
688
+ .ds-247420 .ds-icon-btn:active { transform: translateY(1px); }
689
+ .ds-247420 .ds-icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
690
+ .ds-247420 .ds-icon-btn:disabled, .ds-247420 .ds-icon-btn.is-disabled {
691
+ opacity: 0.5; cursor: not-allowed; pointer-events: none;
692
+ }
693
+
694
+ /* ============================================================
695
+ Badge — small inline count/status pill
696
+ ============================================================ */
697
+ .ds-247420 .ds-badge {
698
+ display: inline-flex; align-items: center; justify-content: center;
699
+ min-width: 18px; height: 18px; padding: 0 6px;
700
+ font-size: 11px; font-weight: 600; line-height: 1;
701
+ border-radius: 999px;
702
+ background: var(--bg-3); color: var(--fg-2);
703
+ }
704
+ .ds-247420 .ds-badge.tone-green { background: var(--green-tint); color: var(--green-deep); }
705
+ .ds-247420 .ds-badge.tone-purple { background: var(--purple-tint); color: var(--purple-deep); }
706
+ .ds-247420 .ds-badge.tone-mascot { background: var(--mascot-tint); color: var(--ink); }
707
+ .ds-247420 .ds-badge.tone-sun { background: var(--sun); color: var(--ink); }
708
+ .ds-247420 .ds-badge.tone-flame { background: var(--flame); color: var(--paper); }
709
+ .ds-247420 .ds-badge.tone-live { background: var(--green-tint); color: var(--green-deep); }
710
+ .ds-247420 .ds-badge.tone-wip { background: var(--bg-3); color: var(--fg-2); }
711
+ .ds-247420 .ds-badge.tone-error { background: var(--flame); color: var(--paper); }
712
+ .ds-247420 .ds-badge.tone-success { background: var(--green-tint); color: var(--green-deep); }
713
+ .ds-247420 .ds-badge.tone-neutral { background: var(--bg-3); color: var(--fg-2); }
714
+
623
715
  .ds-247420 .chip {
624
716
  display: inline-flex; align-items: center; gap: 6px;
625
717
  padding: 3px 10px;
@@ -636,6 +728,12 @@
636
728
  .ds-247420 .chip.tone-flame { background: var(--flame); color: var(--paper); }
637
729
  .ds-247420 .chip.tone-live { background: var(--green-tint); color: var(--green-deep); }
638
730
  .ds-247420 .chip.tone-wip { background: var(--bg-3); color: var(--fg-2); }
731
+ .ds-247420 .chip.tone-error { background: var(--flame); color: var(--paper); }
732
+ .ds-247420 .chip.tone-success { background: var(--green-tint); color: var(--green-deep); }
733
+ .ds-247420 .chip.tone-disabled { background: var(--bg-3); color: var(--fg-3); }
734
+ .ds-247420 .chip.tone-ok { background: var(--green-tint); color: var(--green-deep); }
735
+ .ds-247420 .chip.tone-miss { background: var(--flame); color: var(--paper); }
736
+ .ds-247420 .chip.tone-neutral { background: var(--bg-3); color: var(--fg-2); }
639
737
 
640
738
  .ds-247420 .glyph {
641
739
  display: inline-flex; align-items: center; justify-content: center;
@@ -696,6 +794,9 @@
696
794
  .ds-247420 .row:hover::before { background: var(--rule-strong); }
697
795
  .ds-247420 .row.active { background: color-mix(in oklab, var(--accent) 10%, var(--bg-2)); }
698
796
  .ds-247420 .row.active::before { background: var(--accent); }
797
+ .ds-247420 .row.row-state-disabled { opacity: 0.5; pointer-events: none; }
798
+ .ds-247420 .row.row-state-error { background: color-mix(in oklab, var(--flame) 10%, var(--bg-2)); }
799
+ .ds-247420 .row.row-state-error::before { background: var(--flame); }
699
800
  .ds-247420 .row-grid { /* explicit grid-template-columns set inline */ }
700
801
 
701
802
  .ds-247420 .row .code { font-family: var(--ff-mono); font-size: var(--fs-xs); color: var(--fg-3); }
@@ -711,7 +812,7 @@
711
812
  .ds-247420 .ds-hero {
712
813
  padding: var(--space-9) 0 var(--space-8);
713
814
  display: grid; gap: var(--space-5);
714
- max-width: 940px;
815
+ max-width: var(--measure-wide);
715
816
  }
716
817
  .ds-247420 .ds-hero-title {
717
818
  font-family: var(--ff-body); font-weight: 600;
@@ -725,6 +826,8 @@
725
826
  color: var(--fg-2);
726
827
  }
727
828
  .ds-247420 .ds-hero-accent { color: var(--accent); font-weight: 500; }
829
+ .ds-247420 .ds-hero-actions { display: flex; gap: var(--space-2, 10px); flex-wrap: wrap; margin-top: var(--space-2, 8px); }
830
+ .ds-247420 .ds-chat-title { margin: 0; font-size: inherit; }
728
831
 
729
832
  /* ============================================================
730
833
  Section grouping
@@ -890,6 +993,21 @@
890
993
  .ds-247420 .row-form input:focus,
891
994
  .ds-247420 .row-form textarea:focus { box-shadow: inset 0 0 0 2px var(--accent); }
892
995
 
996
+ /* Field char counter (TextField maxLength) */
997
+ .ds-247420 .ds-field-count {
998
+ font-size: var(--fs-tiny, 12px);
999
+ color: var(--fg-3, var(--fg-2));
1000
+ text-align: right;
1001
+ }
1002
+
1003
+ /* Multi-column form layout (Form columns prop) */
1004
+ .ds-247420 .row-form[data-columns="2"] { grid-template-columns: repeat(2, 1fr); }
1005
+ .ds-247420 .row-form[data-columns="3"] { grid-template-columns: repeat(3, 1fr); }
1006
+ @media (max-width: 600px) {
1007
+ .ds-247420 .row-form[data-columns="2"],
1008
+ .ds-247420 .row-form[data-columns="3"] { grid-template-columns: 1fr; }
1009
+ }
1010
+
893
1011
  /* ============================================================
894
1012
  Responsive Design — Mobile (480px), Tablet (1024px), Desktop (1440px+)
895
1013
  ============================================================ */
@@ -970,7 +1088,6 @@
970
1088
  /* Chat */
971
1089
  .ds-247420 .chat-stack { max-width: 100%; min-width: 0; }
972
1090
  .ds-247420 .chat-bubble {
973
- max-width: clamp(200px, 85vw, 320px);
974
1091
  padding: 10px 12px; font-size: var(--fs-sm);
975
1092
  }
976
1093
  .ds-247420 .chat-avatar { width: 28px; height: 28px; font-size: 11px; }
@@ -1080,7 +1197,6 @@
1080
1197
  /* Chat Bubbles */
1081
1198
  .ds-247420 .chat-stack { max-width: min(75%, 420px); }
1082
1199
  .ds-247420 .chat-bubble {
1083
- max-width: clamp(220px, 75vw, 420px);
1084
1200
  padding: 11px 14px; font-size: var(--fs-sm);
1085
1201
  }
1086
1202
  .ds-247420 .chat-avatar { width: 32px; height: 32px; font-size: 12px; }
@@ -1111,15 +1227,29 @@
1111
1227
  }
1112
1228
  }
1113
1229
 
1230
+ /* ────────────────────────────────────────────────────────────────────
1231
+ Mid Breakpoint (768px and below) — collapse sidebar + simplify row grid
1232
+ ────────────────────────────────────────────────────────────────────── */
1233
+ @media (max-width: 768px) {
1234
+ /* Sidebar stacks above main rather than sitting beside it */
1235
+ .ds-247420 .app-body { grid-template-columns: 1fr; }
1236
+ .ds-247420 .app-side { width: 100%; max-width: none; }
1237
+
1238
+ /* Row drops the leading code column; title + meta share the line */
1239
+ .ds-247420 .row {
1240
+ grid-template-columns: minmax(0, 1fr) auto;
1241
+ gap: var(--space-2);
1242
+ }
1243
+ .ds-247420 .row .code { display: none; }
1244
+ .ds-247420 .row .sub { grid-column: 1 / -1; }
1245
+ }
1246
+
1114
1247
  /* ────────────────────────────────────────────────────────────────────
1115
1248
  Desktop Breakpoint Enhancements (1025px and up)
1116
1249
  ────────────────────────────────────────────────────────────────────── */
1117
1250
  @media (min-width: 1025px) {
1118
1251
  /* Chat Bubbles */
1119
1252
  .ds-247420 .chat-stack { max-width: min(70%, 480px); }
1120
- .ds-247420 .chat-bubble {
1121
- max-width: clamp(240px, 70vw, 480px);
1122
- }
1123
1253
 
1124
1254
  /* KPI Cards */
1125
1255
  .ds-247420 .kpi {
@@ -1398,7 +1528,7 @@
1398
1528
  border-radius: var(--r-2); color: var(--fg);
1399
1529
  font-family: inherit; font-size: var(--fs-sm);
1400
1530
  }
1401
- .ds-247420 .ds-modal-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
1531
+ .ds-247420 .ds-modal-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
1402
1532
  .ds-247420 .btn-primary.danger {
1403
1533
  background: var(--warn);
1404
1534
  border-color: var(--warn);
@@ -1487,7 +1617,7 @@
1487
1617
  border-radius: var(--r-pill); color: var(--fg);
1488
1618
  font-family: inherit; font-size: var(--fs-xs);
1489
1619
  }
1490
- .ds-247420 .ds-filter-input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
1620
+ .ds-247420 .ds-filter-input:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
1491
1621
 
1492
1622
  /* Loading skeleton — placeholder rows while a directory loads. */
1493
1623
  .ds-247420 .ds-file-grid-loading { display: flex; flex-direction: column; gap: 4px; }
@@ -1676,7 +1806,7 @@
1676
1806
  border-radius: 14px; line-height: 1.55;
1677
1807
  word-wrap: break-word; overflow-wrap: anywhere;
1678
1808
  font-size: var(--fs-sm);
1679
- max-width: 100%;
1809
+ max-width: clamp(220px, min(75vw, 28em), 480px);
1680
1810
  min-width: 0;
1681
1811
  transition: transform 0.12s ease, box-shadow 0.12s ease;
1682
1812
  }
@@ -1950,6 +2080,8 @@
1950
2080
  font-family: inherit; font-size: var(--fs-sm);
1951
2081
  line-height: 1.4; resize: none;
1952
2082
  min-height: 44px; max-height: 200px;
2083
+ box-sizing: border-box; overflow-y: auto;
2084
+ scrollbar-width: thin;
1953
2085
  }
1954
2086
  .ds-247420 .chat-composer textarea::placeholder { color: var(--fg-3); }
1955
2087
  .ds-247420 .chat-composer textarea:focus {
@@ -2497,6 +2629,12 @@
2497
2629
  .ds-247420 .ds-spinner-sm { height: 12px; gap: 2px; }
2498
2630
  .ds-247420 .ds-spinner-sm span { width: 2px; height: 2px; }
2499
2631
 
2632
+ .ds-247420 .ds-spinner-xs { height: 8px; gap: 1px; }
2633
+ .ds-247420 .ds-spinner-xs span { width: 1.5px; height: 1.5px; }
2634
+
2635
+ .ds-247420 .ds-spinner-xl { height: 32px; gap: 8px; }
2636
+ .ds-247420 .ds-spinner-xl span { width: 8px; height: 8px; }
2637
+
2500
2638
  @keyframes ds-bounce {
2501
2639
  0%, 80%, 100% { transform: translateY(0); }
2502
2640
  40% { transform: translateY(-8px); }
@@ -2622,7 +2760,7 @@
2622
2760
  .ds-247420 .app-main { padding-left: var(--space-3); padding-right: var(--space-3); }
2623
2761
  }
2624
2762
 
2625
- /* Drawer scrim */
2763
+ /* Drawer scrim — lives inside .app-body, shown when drawer open ≤900px */
2626
2764
  .ds-247420 .app-side-scrim {
2627
2765
  display: none;
2628
2766
  position: fixed; inset: 0;
@@ -2630,8 +2768,34 @@
2630
2768
  z-index: 49;
2631
2769
  }
2632
2770
  @media (max-width: 900px) {
2633
- .ds-247420 .app-body.side-open ~ .app-side-scrim,
2634
- .ds-247420 .app-side-shell.open ~ .app-side-scrim { display: block; }
2771
+ .ds-247420 .app-body.side-open .app-side-scrim { display: block; }
2772
+ }
2773
+
2774
+ /* Mobile nav toggle (hamburger) — hidden on desktop, shown ≤900px */
2775
+ .ds-247420 .app-side-toggle {
2776
+ display: none;
2777
+ position: fixed; top: calc((var(--app-topbar-h) - 32px) / 2); left: 10px;
2778
+ z-index: 51;
2779
+ width: 36px; height: 36px;
2780
+ align-items: center; justify-content: center;
2781
+ font-size: 18px; line-height: 1;
2782
+ background: var(--bg-2); color: var(--fg);
2783
+ border: 1px solid var(--rule, color-mix(in oklab, var(--fg) 12%, transparent));
2784
+ border-radius: var(--r-1, 6px);
2785
+ cursor: pointer;
2786
+ }
2787
+ .ds-247420 .app-side-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2788
+ @media (max-width: 900px) {
2789
+ .ds-247420 .app-side-toggle { display: inline-flex; }
2790
+ .ds-247420 .app-topbar .brand { margin-left: 44px; }
2791
+ }
2792
+
2793
+ /* Desktop: independent scroll for side rail and main, so a short viewport
2794
+ keeps the bottom nav items reachable and main scrolls on its own. */
2795
+ @media (min-width: 901px) {
2796
+ .ds-247420 .app-body { min-height: 0; max-height: calc(100vh - var(--app-topbar-h) - var(--app-crumb-h, 0px) - var(--app-status-h, 0px)); }
2797
+ .ds-247420 .app-side-shell { overflow-y: auto; max-height: 100%; }
2798
+ .ds-247420 .app-main { overflow-y: auto; max-height: 100%; }
2635
2799
  }
2636
2800
 
2637
2801
  /* Mobile (≤480) status bar compact; hide tail item */
@@ -3171,7 +3335,7 @@
3171
3335
  width: 20px;
3172
3336
  height: 20px;
3173
3337
  border-radius: 50%;
3174
- background: var(--bg-3);
3338
+ background: var(--avatar-bg, var(--bg-3));
3175
3339
  color: var(--fg-2);
3176
3340
  display: inline-flex;
3177
3341
  align-items: center;
@@ -3304,7 +3468,7 @@
3304
3468
  width: 32px;
3305
3469
  height: 32px;
3306
3470
  border-radius: 50%;
3307
- background: var(--bg-3);
3471
+ background: var(--avatar-bg, var(--bg-3));
3308
3472
  color: var(--fg-2);
3309
3473
  display: inline-flex;
3310
3474
  align-items: center;
@@ -3508,7 +3672,7 @@
3508
3672
  width: 28px;
3509
3673
  height: 28px;
3510
3674
  border-radius: 50%;
3511
- background: var(--bg-3);
3675
+ background: var(--avatar-bg, var(--bg-3));
3512
3676
  color: var(--fg-2);
3513
3677
  display: inline-flex;
3514
3678
  align-items: center;
@@ -3569,7 +3733,7 @@
3569
3733
  width: 56px;
3570
3734
  height: 56px;
3571
3735
  border-radius: 50%;
3572
- background: var(--bg-3);
3736
+ background: var(--avatar-bg, var(--bg-3));
3573
3737
  color: var(--fg-2);
3574
3738
  display: inline-flex;
3575
3739
  align-items: center;
@@ -4161,6 +4325,27 @@
4161
4325
  .ds-247420 .cm-page-body { padding: var(--space-3); line-height: 1.6; }
4162
4326
  .ds-247420 .cm-page-empty { color: var(--fg-2, var(--fg)); opacity: .7; }
4163
4327
 
4328
+ /* ============================================================
4329
+ freddie pages — layout for FREDDIE_PAGES renderers.
4330
+ Scoped under .ds-247420 by the build prefixer. Tokens only.
4331
+ ============================================================ */
4332
+ .ds-247420 .fd-page-root { display: block; height: 100%; }
4333
+ .ds-247420 .fd-page-inner { display: flex; flex-direction: column; gap: var(--space-3, 16px); padding: var(--space-3, 16px); max-width: 1100px; }
4334
+ .ds-247420 .fd-page-inner > * { min-width: 0; }
4335
+ .ds-247420 .fd-loading { display: flex; align-items: center; gap: var(--space-2, 10px); padding: var(--space-4, 24px); color: var(--fg-2, var(--fg)); }
4336
+ .ds-247420 .fd-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2, 10px); padding: var(--space-5, 32px) var(--space-3, 16px); color: var(--fg-2, var(--fg)); text-align: center; }
4337
+ .ds-247420 .fd-empty-glyph { font-size: 28px; opacity: .55; line-height: 1; }
4338
+ .ds-247420 .fd-pre { margin: 0; padding: var(--space-2, 10px); background: var(--bg-3, var(--panel-bg-2)); border: var(--bw-hair, 1px) solid var(--rule, var(--panel-accent)); border-radius: var(--r-1, 6px); overflow: auto; max-height: 460px; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; font-family: var(--font-mono, ui-monospace, monospace); font-size: 12px; line-height: 1.5; }
4339
+ .ds-247420 .fd-skill-body { max-height: 320px; }
4340
+ .ds-247420 .fd-row-actions { display: inline-flex; gap: var(--space-1, 6px); align-items: center; }
4341
+ .ds-247420 .fd-chat { display: flex; flex-direction: column; gap: var(--space-2, 10px); height: 100%; min-height: 0; }
4342
+ .ds-247420 .fd-chat-thread { flex: 1 1 auto; min-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-2, 10px); padding: var(--space-2, 10px); }
4343
+ .ds-247420 .fd-page-error { white-space: pre-wrap; overflow-wrap: anywhere; }
4344
+ /* page-level responsive: tighten padding on narrow viewports */
4345
+ @media (max-width: 640px) {
4346
+ .ds-247420 .fd-page-inner { padding: var(--space-2, 10px); gap: var(--space-2, 10px); }
4347
+ }
4348
+
4164
4349
  /* chat.css */
4165
4350
  /* chat.css — chat-specific styles. Currently empty; all chat styles live in
4166
4351
  app-shell.css under the .chat-* prefix. Reserved for future split. */
@@ -4180,7 +4365,7 @@
4180
4365
  border-bottom: 1px solid var(--rule);
4181
4366
  font: var(--fs-tiny, 12px)/var(--lh-base, 1.4) var(--ff-mono, monospace);
4182
4367
  }
4183
- .ds-247420 .ds-ep-toolbar.dense { padding: 4px 6px; gap: 4px; }
4368
+ .ds-247420 .ds-ep-toolbar.dense { padding: 2px 4px; gap: 2px; }
4184
4369
  .ds-247420 .ds-ep-toolbar-leading,
4185
4370
  .ds-247420 .ds-ep-toolbar-center,
4186
4371
  .ds-247420 .ds-ep-toolbar-trailing { display: flex; align-items: center; gap: 4px; }
@@ -4190,7 +4375,8 @@
4190
4375
  /* Tabs */
4191
4376
  .ds-247420 .ds-ep-tabs { display: flex; flex-direction: column; min-height: 0; height: 100%; }
4192
4377
  .ds-247420 .ds-ep-tabs-head {
4193
- display: flex; flex-shrink: 0;
4378
+ display: flex; flex-shrink: 0; flex-wrap: nowrap;
4379
+ overflow-x: auto; scroll-behavior: smooth;
4194
4380
  background: var(--panel-1);
4195
4381
  border-bottom: 1px solid var(--rule);
4196
4382
  }
@@ -4217,6 +4403,7 @@
4217
4403
  overflow: auto;
4218
4404
  }
4219
4405
  .ds-247420 .ds-ep-tree-item { display: flex; flex-direction: column; }
4406
+ .ds-247420 .ds-ep-tree-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
4220
4407
  .ds-247420 .ds-ep-tree-row {
4221
4408
  display: flex; align-items: center; gap: 6px;
4222
4409
  padding: 4px 8px 4px 0;
@@ -4256,7 +4443,7 @@
4256
4443
  }
4257
4444
  .ds-247420 .ds-ep-propfield {
4258
4445
  display: grid;
4259
- grid-template-columns: 120px 1fr;
4446
+ grid-template-columns: minmax(80px, 120px) 1fr;
4260
4447
  gap: 4px 10px;
4261
4448
  align-items: center;
4262
4449
  }
@@ -4319,6 +4506,14 @@
4319
4506
  }
4320
4507
  .ds-247420 .ds-ep-dock-center > * { pointer-events: auto; }
4321
4508
 
4509
+ /* Mobile — stack dock regions vertically instead of the 3x3 grid */
4510
+ @media (max-width: 600px) {
4511
+ .ds-247420 .ds-ep-dock {
4512
+ display: flex;
4513
+ flex-direction: column;
4514
+ }
4515
+ }
4516
+
4322
4517
  /* IconButtonGroup */
4323
4518
  .ds-247420 .ds-ep-btngrp {
4324
4519
  display: inline-flex;
@@ -4378,6 +4573,8 @@
4378
4573
  .ds-247420 .ds-ep-split.horiz { flex-direction: row; }
4379
4574
  .ds-247420 .ds-ep-split.vert { flex-direction: column; }
4380
4575
  .ds-247420 .ds-ep-split-pane { overflow: auto; }
4576
+ .ds-247420 .ds-ep-split.horiz > .ds-ep-split-pane:not(.grow) { width: var(--split-size); }
4577
+ .ds-247420 .ds-ep-split.vert > .ds-ep-split-pane:not(.grow) { height: var(--split-size); }
4381
4578
  .ds-247420 .ds-ep-split-pane.grow { flex: 1 1 0; }
4382
4579
 
4383
4580
  /* ---------------------------------------------------------------