anentrypoint-design 0.0.236 → 0.0.238

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/app-shell.css CHANGED
@@ -382,6 +382,8 @@ body.canvas-host { background: transparent !important; }
382
382
  /* Status bar inherits the .app max-width cap above and stretches edge-to-edge
383
383
  within it; no separate width constraint (which previously narrowed it). */
384
384
  .app-status { width: 100%; }
385
+ /* Cap row text measure inside the wide capped main (ultrawide readability). */
386
+ .row .title, .row .sub { max-width: var(--measure-wide); }
385
387
  }
386
388
 
387
389
  .app-status {
@@ -685,14 +687,16 @@ a.row { text-decoration: none; }
685
687
  padding: var(--space-9) 0 var(--space-8);
686
688
  display: grid; gap: var(--space-5) var(--space-6);
687
689
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
688
- grid-template-areas: 'title title' 'body actions';
690
+ grid-template-areas: 'title title' 'body actions' 'badge badge';
689
691
  align-items: end;
690
692
  max-width: var(--measure-wide);
691
693
  }
692
694
  .ds-hero-head { grid-area: title; display: grid; gap: var(--space-3); }
693
695
  .ds-hero-body { grid-area: body; }
694
696
  .ds-hero-actions { grid-area: actions; }
695
- .ds-hero-badge { grid-area: actions; }
697
+ /* Badge gets its own row — sharing 'actions' overlapped it onto the CTAs
698
+ whenever a caller passes both actions and badge. */
699
+ .ds-hero-badge { grid-area: badge; }
696
700
  .ds-hero-title {
697
701
  font-family: var(--ff-display); font-weight: 700;
698
702
  font-size: clamp(40px, 9cqi, 116px);
@@ -707,10 +711,13 @@ a.row { text-decoration: none; }
707
711
  /* The lead phrase in the title — printed in the electric lead, not glowing. */
708
712
  .ds-hero-accent { color: var(--accent-ink); font-weight: 700; }
709
713
  .ds-hero-actions { display: flex; gap: var(--space-2, 10px); flex-wrap: wrap; align-self: end; }
710
- @media (max-width: 900px) {
714
+ /* Container-queried (the whole shell is; a 500px pane on a wide viewport
715
+ would keep the two-column grid under a width @media). Left-aligned stack —
716
+ no centering — preserving the asymmetric intent. */
717
+ @container (max-width: 900px) {
711
718
  .ds-hero {
712
719
  grid-template-columns: minmax(0, 1fr);
713
- grid-template-areas: 'title' 'body' 'actions';
720
+ grid-template-areas: 'title' 'body' 'actions' 'badge';
714
721
  align-items: start;
715
722
  padding: var(--space-7) 0 var(--space-6);
716
723
  }
@@ -778,13 +785,21 @@ a.row { text-decoration: none; }
778
785
  }
779
786
  .ds-marquee-item { display: inline-flex; align-items: center; gap: var(--space-5); }
780
787
  .ds-marquee-sep { color: var(--accent-ink); }
781
- .ds-marquee:hover .ds-marquee-track { animation-play-state: paused; }
788
+ .ds-marquee:hover .ds-marquee-track,
789
+ .ds-marquee:focus-within .ds-marquee-track,
790
+ .ds-marquee:active .ds-marquee-track { animation-play-state: paused; }
782
791
  @keyframes ds-marquee-run {
783
792
  from { transform: translateX(0); }
784
793
  to { transform: translateX(-50%); }
785
794
  }
795
+ /* Touch has no hover-pause; slow the ticker so it burns less attention. */
796
+ @media (hover: none), (pointer: coarse) {
797
+ .ds-marquee-track { animation-duration: 40s; }
798
+ }
786
799
  @media (prefers-reduced-motion: reduce) {
787
- .ds-marquee-track { animation: none; }
800
+ /* Static: wrap to a readable strip instead of a frozen half-offscreen run. */
801
+ .ds-marquee-track { animation: none; flex-wrap: wrap; white-space: normal; }
802
+ .ds-marquee-run-b { display: none; }
788
803
  }
789
804
 
790
805
  /* ============================================================
@@ -792,6 +807,7 @@ a.row { text-decoration: none; }
792
807
  ============================================================ */
793
808
  .cli {
794
809
  display: flex; align-items: center; gap: 14px;
810
+ overflow-x: auto;
795
811
  padding: 20px 24px;
796
812
  background: var(--ink); color: var(--paper);
797
813
  border-radius: var(--r-3);
@@ -845,6 +861,15 @@ table.kv td:first-child {
845
861
  }
846
862
  table.kv td:last-child {
847
863
  font-weight: 600;
864
+ overflow-wrap: anywhere; min-width: 0;
865
+ }
866
+ /* Tiny screens: stack the key over the value instead of squeezing a 14ch
867
+ label column beside long unbroken values (URLs, hashes). */
868
+ @media (max-width: 400px) {
869
+ table.kv td { display: block; width: auto; padding: 4px 0; }
870
+ table.kv td:first-child { padding-top: 8px; }
871
+ table.kv tr + tr td { border-top: 0; }
872
+ table.kv tr + tr td:first-child { border-top: 1px solid var(--rule); }
848
873
  }
849
874
 
850
875
  /* ============================================================
@@ -1040,6 +1065,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1040
1065
  }
1041
1066
  .row .sub { grid-column: 1 / -1; order: 3; }
1042
1067
  .row .title { font-size: var(--fs-sm); }
1068
+ /* Changelog carries 3 children: give date+ver line one, message wraps below
1069
+ (the generic 2-col .row override staggers it into an implicit row). */
1070
+ .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
1071
+ .ds-changelog-row .title { grid-column: 1 / -1; }
1043
1072
 
1044
1073
  /* Buttons */
1045
1074
  .btn, .btn-primary, .btn-ghost {
@@ -1083,7 +1112,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1083
1112
  gap: var(--space-2);
1084
1113
  }
1085
1114
  .kpi-card { padding: var(--space-3); }
1086
- .kpi-card .num { font-size: clamp(22px, 5vw, 32px); }
1115
+ /* Container-relative like the base rule (5vw sized against the viewport and
1116
+ jumped across the breakpoint). */
1117
+ .kpi-card .num { font-size: clamp(22px, 8cqi, 32px); }
1087
1118
 
1088
1119
  /* Empty State */
1089
1120
  .empty { padding: var(--space-5); font-size: var(--fs-xs); }
@@ -1117,10 +1148,11 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1117
1148
  @container (max-width: 760px) {
1118
1149
  .app-body { grid-template-columns: 1fr !important; }
1119
1150
  .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
1120
- .app-topbar { grid-template-columns: 1fr auto; }
1121
1151
  .app-topbar nav { font-size: var(--fs-xs); gap: 14px; }
1122
1152
  .row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: 4px !important; }
1123
1153
  .row .sub { grid-column: 1 / -1; order: 3; }
1154
+ .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
1155
+ .ds-changelog-row .title { grid-column: 1 / -1; }
1124
1156
  }
1125
1157
 
1126
1158
  /* --------------------------------------------------------------------
@@ -1135,9 +1167,8 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1135
1167
  min-height: 44px;
1136
1168
  }
1137
1169
 
1138
- /* Topbar Navigation */
1170
+ /* Topbar Navigation (flex container — no grid-template here) */
1139
1171
  .app-topbar {
1140
- grid-template-columns: auto 1fr auto;
1141
1172
  gap: var(--space-3); padding: 12px var(--space-4);
1142
1173
  }
1143
1174
  .app-topbar nav {
@@ -1216,6 +1247,8 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1216
1247
  gap: var(--space-2);
1217
1248
  }
1218
1249
  .row .code { display: none; }
1250
+ /* Changelog's date lives in span.code — hiding it is data loss, not reflow. */
1251
+ .ds-changelog-row .code { display: inline; font-size: var(--fs-micro); }
1219
1252
  .row .sub { grid-column: 1 / -1; }
1220
1253
  }
1221
1254
 
@@ -1566,6 +1599,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1566
1599
  padding: 4px 8px; border-radius: var(--r-1);
1567
1600
  color: var(--fg-3); font-family: inherit; font-size: var(--fs-sm);
1568
1601
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
1602
+ /* A single long unbroken segment (hash-named dir) must never force the
1603
+ whole path past the viewport. */
1604
+ max-width: min(40vw, 220px);
1605
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1569
1606
  }
1570
1607
  .ds-crumb-seg:hover { background: var(--bg-2); color: var(--fg); }
1571
1608
  .ds-crumb-seg.leaf { color: var(--fg); font-weight: 600; }
@@ -1662,6 +1699,14 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1662
1699
  border-radius: var(--r-3);
1663
1700
  }
1664
1701
  .ds-dropzone--wrap.dragover { animation: none; }
1702
+ /* Touch devices can never fire dragover — keep the pick-files affordance
1703
+ visible as a compact static row so upload stays reachable in wrap mode. */
1704
+ @media (hover: none) and (pointer: coarse) {
1705
+ .ds-dropzone--wrap > .ds-dropzone-inner {
1706
+ display: flex; position: static; padding: var(--space-2);
1707
+ outline: none; background: transparent;
1708
+ }
1709
+ }
1665
1710
 
1666
1711
  /* Upload progress */
1667
1712
  .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
@@ -1690,7 +1735,12 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1690
1735
  .ds-upload-item.error .ds-upload-fill { background: var(--warn); }
1691
1736
  .ds-upload-item.error .ds-upload-pct { color: var(--warn); }
1692
1737
  /* Per-row upload recovery actions (replace / dismiss) — error rows are not dead ends. */
1693
- .ds-upload-item { grid-template-columns: minmax(0, 1fr) 120px 44px auto; }
1738
+ .ds-upload-item { grid-template-columns: minmax(0, 1fr) minmax(60px, 120px) 44px auto; }
1739
+ @media (max-width: 480px) {
1740
+ .ds-upload-item { grid-template-columns: minmax(0, 1fr) 44px; }
1741
+ .ds-upload-bar { grid-column: 1 / -1; order: 3; }
1742
+ .ds-upload-actions { grid-column: 1 / -1; justify-content: flex-end; }
1743
+ }
1694
1744
  .ds-upload-actions { display: inline-flex; gap: var(--space-1); justify-content: flex-end; }
1695
1745
  .ds-upload-act {
1696
1746
  padding: 2px 10px; min-height: 24px; cursor: pointer;
@@ -1701,6 +1751,11 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1701
1751
  .ds-upload-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
1702
1752
  @media (hover: none), (pointer: coarse) {
1703
1753
  .ds-upload-act { min-height: 44px; min-width: 44px; }
1754
+ /* 44px floor for file controls on ANY touch device, not only narrow ones
1755
+ (the width-based mobile block misses wide touch tablets). */
1756
+ .ds-file-act, .ds-file-sort-btn, .ds-crumb-seg, .ds-file-filter-input { min-height: 44px; }
1757
+ .ds-file-act { min-width: 44px; }
1758
+ .ds-file-check, .ds-file-selectall, .ds-density-btn { min-height: 44px; min-width: 44px; }
1704
1759
  }
1705
1760
 
1706
1761
  /* Empty state */
@@ -1716,7 +1771,11 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1716
1771
  .ds-modal-backdrop {
1717
1772
  position: fixed; inset: 0; z-index: var(--z-modal, 800);
1718
1773
  display: flex; align-items: center; justify-content: center;
1719
- padding: var(--space-3);
1774
+ /* Notch/home-indicator safe: near-fullscreen modals must not slide under. */
1775
+ padding: max(var(--space-3), env(safe-area-inset-top))
1776
+ max(var(--space-3), env(safe-area-inset-right))
1777
+ max(var(--space-3), env(safe-area-inset-bottom))
1778
+ max(var(--space-3), env(safe-area-inset-left));
1720
1779
  background: color-mix(in oklab, var(--ink) 55%, transparent);
1721
1780
  backdrop-filter: blur(3px);
1722
1781
  }
@@ -1726,7 +1785,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1726
1785
  @keyframes ds-modal-fade { from { opacity: 0; } to { opacity: 1; } }
1727
1786
  .ds-modal {
1728
1787
  display: flex; flex-direction: column;
1729
- width: 100%; max-width: 460px; max-height: calc(100vh - 2 * var(--space-4));
1788
+ width: 100%; max-width: 460px;
1789
+ max-height: calc(100vh - 2 * var(--space-4));
1790
+ max-height: calc(100dvh - 2 * var(--space-4));
1730
1791
  background: var(--bg); color: var(--fg);
1731
1792
  border: var(--bw-hair) solid var(--rule);
1732
1793
  border-radius: var(--r-3); box-shadow: var(--shadow-3);
@@ -1759,6 +1820,10 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1759
1820
  font-family: inherit; font-size: var(--fs-sm);
1760
1821
  }
1761
1822
  .ds-modal-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
1823
+ /* iOS auto-zooms inputs under 16px on focus, breaking the modal layout. */
1824
+ @media (hover: none), (pointer: coarse) {
1825
+ .ds-modal-input { font-size: 16px; min-height: 44px; }
1826
+ }
1762
1827
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
1763
1828
  the dialog, not behind the fixed overlay. */
1764
1829
  .ds-modal-error {
@@ -1782,10 +1847,12 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1782
1847
  .ds-preview-name {
1783
1848
  font-weight: 600; font-size: var(--fs-body);
1784
1849
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
1850
+ flex: 1 1 auto;
1785
1851
  }
1786
1852
  .ds-preview-meta {
1787
1853
  font-family: var(--ff-mono); font-size: var(--fs-xs);
1788
1854
  color: var(--fg-3); white-space: nowrap;
1855
+ flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
1789
1856
  }
1790
1857
  .ds-preview-actions { display: inline-flex; gap: 2px; margin-left: auto; }
1791
1858
  .ds-preview-body {
@@ -1794,7 +1861,9 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1794
1861
  display: flex; flex-direction: column;
1795
1862
  }
1796
1863
  .ds-preview-media {
1797
- max-width: 100%; max-height: 70vh; margin: 0 auto;
1864
+ max-width: 100%;
1865
+ max-height: 70vh; max-height: 70dvh;
1866
+ margin: 0 auto;
1798
1867
  border-radius: var(--r-2); object-fit: contain;
1799
1868
  }
1800
1869
  .ds-preview-audio { width: 100%; }
@@ -1840,10 +1909,22 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
1840
1909
 
1841
1910
  /* Mobile — modals go near-fullscreen, preview media shrinks. */
1842
1911
  @media (max-width: 560px) {
1843
- .ds-modal { max-width: 100%; max-height: calc(100vh - 2 * var(--space-3)); }
1844
- .ds-modal-preview { width: 100%; height: calc(100vh - 2 * var(--space-3)); max-height: none; }
1845
- .ds-preview-media { max-height: 50vh; }
1912
+ .ds-modal {
1913
+ max-width: 100%;
1914
+ max-height: calc(100vh - 2 * var(--space-3));
1915
+ max-height: calc(100dvh - 2 * var(--space-3));
1916
+ }
1917
+ .ds-modal-preview {
1918
+ width: 100%; max-height: none;
1919
+ height: calc(100vh - 2 * var(--space-3));
1920
+ height: calc(100dvh - 2 * var(--space-3));
1921
+ }
1922
+ .ds-preview-media { max-height: 50vh; max-height: 50dvh; }
1846
1923
  .ds-file-stage { padding: var(--space-3) var(--space-2); }
1924
+ /* Preview head: let it wrap and drop the nowrap meta (duplicated in body)
1925
+ so the close button can never be pushed past the modal edge. */
1926
+ .ds-preview-head { flex-wrap: wrap; row-gap: 4px; }
1927
+ .ds-preview-meta { display: none; }
1847
1928
  }
1848
1929
 
1849
1930
  /* -- File browser UX affordances ---------------------------- */
@@ -2460,10 +2541,21 @@ table tr.clickable:focus-visible td { background: var(--bg-2); }
2460
2541
  .chat-composer textarea { padding: 10px 12px; }
2461
2542
  }
2462
2543
 
2463
- /* --- landscape orientation: reduce vertical space for composer --- */
2544
+ /* --- landscape orientation: reduce vertical space for chrome + composer --- */
2464
2545
  @media (max-height: 500px) and (orientation: landscape) {
2465
- .chat-composer { padding: 6px 0; }
2466
- .chat-composer textarea { min-height: 44px; max-height: 120px; }
2546
+ /* Keep horizontal padding: 0 put the textarea/focus ring flush on the edge. */
2547
+ .chat-composer { padding: 6px var(--space-2); }
2548
+ .chat-composer textarea { min-height: 36px; max-height: 96px; }
2549
+ .chat-composer .chat-composer-hint,
2550
+ .chat-composer .chat-composer-context { display: none; }
2551
+ /* Compact the shell chrome: ~114px of topbar+crumb+status is a third of a
2552
+ 360px-tall landscape fold. */
2553
+ :root { --app-topbar-h: 40px; --app-crumb-h: 24px; }
2554
+ .app-chrome { padding: 4px var(--pad-x); }
2555
+ .app-status { display: none; }
2556
+ .ws-crumb { min-height: 32px; }
2557
+ .ds-hero { padding: var(--space-4) 0 var(--space-3); }
2558
+ .ds-hero-title { font-size: clamp(28px, 6cqi, 56px); }
2467
2559
  }
2468
2560
 
2469
2561
  /* ============================================================
@@ -2896,6 +2988,16 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
2896
2988
  }
2897
2989
  }
2898
2990
 
2991
+ /* Touch floor also for coarse-pointer devices that report hover (hybrid
2992
+ laptops/tablets with mice) — the block above requires hover:none too. */
2993
+ @media (pointer: coarse) {
2994
+ .ds-icon-btn, .ds-icon-btn-xs, .ds-icon-btn-sm, .ds-icon-btn-base {
2995
+ min-width: 44px; min-height: 44px;
2996
+ }
2997
+ .btn, .btn-primary, .btn-ghost,
2998
+ .app-topbar nav a, .app-side a { min-height: 44px; }
2999
+ }
3000
+
2899
3001
  /* ------------------------------------------------------------
2900
3002
  Theme Transition Smoothness
2901
3003
  -------------------------------------------------------------- */
@@ -3127,16 +3229,24 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3127
3229
  .app-body.no-side { grid-template-columns: 1fr !important; }
3128
3230
  .app-side-shell {
3129
3231
  position: absolute;
3130
- left: 0; top: var(--app-topbar-h);
3131
- height: calc(100% - var(--app-topbar-h) - var(--app-status-h));
3232
+ /* Full-height overlay drawer: the merged .app-chrome wraps and its real
3233
+ height drifts from --app-topbar-h, so anchoring below it misplaces the
3234
+ drawer. Overlay the chrome instead (z above --z-header), like ws drawers. */
3235
+ left: 0; top: 0;
3236
+ height: 100%;
3132
3237
  width: 280px; max-width: 80%;
3133
3238
  transform: translateX(-100%);
3134
3239
  transition: transform var(--dur-base, 240ms) var(--ease, ease);
3135
- z-index: 50;
3240
+ /* Above the sticky chrome (z-header): scrim > chrome > content budget. */
3241
+ z-index: calc(var(--z-header, 100) + 2);
3136
3242
  background: var(--bg);
3137
3243
  border-right: 1px solid color-mix(in oklab, var(--fg) 8%, transparent);
3138
3244
  overflow-y: auto;
3245
+ overscroll-behavior: contain;
3139
3246
  }
3247
+ /* Lock the content scroller while the drawer is open so touch pans don't
3248
+ scroll the page behind the scrim. */
3249
+ .app-body.side-open .app-main { overflow: hidden; }
3140
3250
  .app-side-shell.open,
3141
3251
  .app-side.open,
3142
3252
  .app-body.side-open .app-side-shell { transform: translateX(0); }
@@ -3169,7 +3279,8 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3169
3279
  display: none;
3170
3280
  position: absolute; inset: 0;
3171
3281
  background: color-mix(in oklab, var(--bg) 60%, transparent);
3172
- z-index: 49;
3282
+ /* Above the sticky chrome so nav behind an open drawer is not clickable. */
3283
+ z-index: calc(var(--z-header, 100) + 1);
3173
3284
  }
3174
3285
  @container (max-width: 900px) {
3175
3286
  .app-body.side-open .app-side-scrim { display: block; }
@@ -3181,7 +3292,9 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3181
3292
  .app-side-toggle {
3182
3293
  display: none;
3183
3294
  position: absolute; top: calc((var(--app-topbar-h) - 44px) / 2); left: 10px;
3184
- z-index: 51;
3295
+ /* Above the sticky topbar/chrome (z-header) and the drawer/scrim so the
3296
+ translucent blurred chrome never paints over or intercepts the toggle. */
3297
+ z-index: calc(var(--z-header, 100) + 3);
3185
3298
  /* 44x44 minimum hit area (WCAG 2.5.5 / Apple HIG) - 36px is below the
3186
3299
  reliable-tap threshold on touch. */
3187
3300
  width: 44px; height: 44px;
@@ -3233,6 +3346,8 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3233
3346
  .app-topbar nav,
3234
3347
  .app-topbar > :last-child { display: none; }
3235
3348
  .brand { font-size: var(--fs-tiny); }
3349
+ /* Slightly narrower drawer on tiny phones; max-width:80% remains the guard. */
3350
+ .app-side-shell { width: 260px; }
3236
3351
  }
3237
3352
 
3238
3353
  /* ----------------------------------------------------------------------------
@@ -3306,6 +3421,11 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3306
3421
  @media (prefers-reduced-motion: no-preference) {
3307
3422
  .ws-shell { transition: grid-template-columns var(--dur-base) var(--ease); }
3308
3423
  }
3424
+ /* Ultrawide: cap the shell so the 1fr content track doesn't stretch to
3425
+ unreadable measures while the fixed side columns pin to their clamps. */
3426
+ @media (min-width: 1920px) {
3427
+ .ws-shell { max-width: 1920px; margin-inline: auto; }
3428
+ }
3309
3429
 
3310
3430
  /* Rail (left nav) */
3311
3431
  .ws-rail {
@@ -3341,7 +3461,7 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3341
3461
  }
3342
3462
  .ws-rail-action:hover { filter: brightness(1.08); }
3343
3463
  .ws-rail-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3344
- .ws-rail-nav { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; flex: 1; min-height: 0; overflow-y: auto; }
3464
+ .ws-rail-nav { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
3345
3465
  .ws-rail-item {
3346
3466
  display: flex; align-items: center; gap: var(--space-2);
3347
3467
  width: 100%; padding: var(--space-2); min-height: 44px;
@@ -3404,6 +3524,7 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3404
3524
  min-height: 0; display: flex; flex-direction: column;
3405
3525
  background: var(--bg-2); border-left: var(--bw-hair) solid var(--bg-3);
3406
3526
  overflow: hidden; transition: width var(--dur-base) var(--ease);
3527
+ overscroll-behavior: contain;
3407
3528
  }
3408
3529
  .ws-pane-collapsed .ws-pane { width: 0; border-left: none; }
3409
3530
  .ws-pane-collapsed .ws-pane > * { display: none; }
@@ -3488,12 +3609,19 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3488
3609
  }
3489
3610
  .ws-sessions {
3490
3611
  position: fixed; inset: 0 auto 0 0;
3491
- width: min(var(--ws-sessions-w), 80vw);
3612
+ /* Immune to the desktop collapse var (--ws-sessions-w:0px persisted from
3613
+ a desktop session would open an invisible 0-width drawer). */
3614
+ width: min(max(var(--ws-sessions-w), 280px), 80vw);
3492
3615
  z-index: 42; transform: translateX(-110%);
3493
3616
  transition: transform var(--dur-base) var(--ease);
3494
3617
  border-right: var(--bw-hair) solid var(--bg-3);
3618
+ overscroll-behavior: contain;
3495
3619
  }
3496
3620
  .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
3621
+ /* Drawer mode ignores the desktop collapsed state: children stay rendered
3622
+ and the border returns, so a persisted collapse can't blank the drawer. */
3623
+ .ws-shell.ws-sessions-collapsed .ws-sessions > * { display: revert; }
3624
+ .ws-shell.ws-sessions-collapsed .ws-sessions { border-right: var(--bw-hair) solid var(--bg-3); }
3497
3625
  .ws-sessions-drawer-toggle { display: inline-flex; }
3498
3626
  }
3499
3627
 
@@ -3603,6 +3731,22 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3603
3731
  .ws-crumb,
3604
3732
  .app-status { display: none; }
3605
3733
  .ws-main { overflow: visible; height: auto; }
3734
+ /* AppShell: unpin the viewport-height frame so content flows across pages,
3735
+ and drop all chrome (it prints as page furniture otherwise). */
3736
+ .app { height: auto; min-height: 0; overflow: visible; display: block; }
3737
+ .app-body { display: block; }
3738
+ .app-main { overflow: visible; height: auto; display: block; max-width: 100%; }
3739
+ .app-topbar, .app-chrome, .app-crumb, .app-side-shell, .app-side-scrim,
3740
+ .app-side-toggle, .btn-fab, .skip-link, .ds-marquee { display: none; }
3741
+ /* Modals/preview: print the content, not a blurred overlay clipped to one page. */
3742
+ .ds-modal-backdrop { position: static; background: none; backdrop-filter: none; padding: 0; }
3743
+ .ds-modal, .ds-modal-preview { max-width: 100%; max-height: none; box-shadow: none; }
3744
+ .ds-modal-body, .ds-preview-body, .ds-preview-code, .ds-preview-text { overflow: visible; }
3745
+ .ds-modal-actions, .ds-preview-actions { display: none; }
3746
+ /* Data-density: fixed-height log clips; bg-only tiles lose their boundary. */
3747
+ .ds-live-log { height: auto; max-height: none; overflow: visible; }
3748
+ .ds-stat, .kpi-card { border: 1px solid var(--rule); }
3749
+ .ds-session-row { break-inside: avoid; }
3606
3750
  }
3607
3751
 
3608
3752
  /* ============================================================
@@ -3627,15 +3771,26 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3627
3771
  }
3628
3772
  .ds-phasewalk-seg.is-reached { background: var(--success); }
3629
3773
  .ds-phasewalk-seg.is-gap { background: var(--warn); }
3774
+ /* Standalone PhaseWalk reserves headroom for the labels instead of letting
3775
+ them escape upward and overlap the element above. */
3776
+ .ds-phasewalk { padding-top: 15px; }
3630
3777
  .ds-phasewalk-lbl {
3631
3778
  position: absolute; top: -15px; left: 0;
3632
3779
  font-size: var(--fs-micro); color: var(--fg-3); white-space: nowrap;
3633
3780
  }
3781
+ /* Inline in a single-line SessionRow the labels would overlap the row above —
3782
+ segments already carry title tooltips. */
3783
+ .ds-session-row .ds-phasewalk { padding-top: 0; }
3784
+ .ds-session-row .ds-phasewalk-lbl { display: none; }
3634
3785
 
3635
3786
  /* TreeNode */
3636
3787
  .ds-tree-node {
3637
3788
  padding: 5px 10px; border-left: var(--bw-rule) solid var(--bg-3);
3638
3789
  margin: 2px 0 2px 16px; font-size: var(--fs-tiny);
3790
+ min-width: 0; overflow-wrap: anywhere;
3791
+ }
3792
+ @media (max-width: 400px) {
3793
+ .ds-tree-node { margin-left: 8px; padding-left: 8px; }
3639
3794
  }
3640
3795
  .ds-tree-node.is-phase { border-color: var(--accent); background: var(--bg-3); font-weight: 600; }
3641
3796
  .ds-tree-node.is-deviation { border-color: var(--warn); background: var(--danger-surface); color: var(--warn); }
@@ -3650,17 +3805,26 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3650
3805
  /* BarRow */
3651
3806
  .ds-bar-row { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: var(--fs-tiny); }
3652
3807
  .ds-bar-row-label { width: 100px; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
3653
- .ds-bar-bg { flex: 1; background: var(--bg-3); border-radius: 2px; height: 6px; overflow: hidden; }
3808
+ .ds-bar-bg { flex: 1; min-width: 60px; background: var(--bg-3); border-radius: 2px; height: 6px; overflow: hidden; }
3654
3809
  .ds-bar-fill { background: var(--accent); height: 100%; border-radius: 2px; }
3655
- .ds-bar-row-value { flex-shrink: 0; color: var(--fg-2); }
3810
+ .ds-bar-row-value { flex-shrink: 0; color: var(--fg-2); max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
3811
+ @media (max-width: 400px) {
3812
+ .ds-bar-row-label { width: 72px; }
3813
+ }
3656
3814
 
3657
3815
  /* StatTile / StatsGrid */
3658
- .ds-stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-2); }
3816
+ /* min(140px, 100%) keeps the grid from collapsing to 1 column early inside
3817
+ padded panels; the wrapper div stretches its tile to equal row height. */
3818
+ .ds-stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); gap: var(--space-2); }
3819
+ .ds-stats-grid > div { display: grid; }
3820
+ @media (max-width: 360px) {
3821
+ .ds-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-1); }
3822
+ }
3659
3823
  .ds-stats-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
3660
- .ds-stat { background: var(--bg-3); border-radius: 4px; padding: 10px 12px; }
3661
- .ds-stat-val { font-size: 22px; font-weight: 700; color: var(--accent-ink); }
3662
- .ds-stat-val.rate-big { font-size: 32px; color: var(--success); }
3663
- .ds-stat-val.err-rate { font-size: 32px; color: var(--warn); }
3824
+ .ds-stat { min-width: 0; background: var(--bg-3); border-radius: 4px; padding: 10px 12px; }
3825
+ .ds-stat-val { font-size: clamp(18px, 5cqi, 22px); font-weight: 700; color: var(--accent-ink); overflow-wrap: anywhere; }
3826
+ .ds-stat-val.rate-big { font-size: clamp(24px, 7cqi, 32px); color: var(--success); }
3827
+ .ds-stat-val.err-rate { font-size: clamp(24px, 7cqi, 32px); color: var(--warn); }
3664
3828
  .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: 2px; }
3665
3829
 
3666
3830
  /* SubGrid */
@@ -3677,14 +3841,22 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3677
3841
  /* SessionRow */
3678
3842
  .ds-session-row {
3679
3843
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
3844
+ flex-wrap: wrap; min-width: 0;
3680
3845
  border-bottom: var(--bw-hair) solid var(--bg-3); cursor: pointer;
3681
3846
  }
3682
3847
  .ds-session-row:hover { background: var(--bg-3); }
3683
3848
  .ds-session-row-id {
3684
3849
  font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--accent-ink);
3685
- width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
3850
+ flex: 0 1 160px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
3851
+ }
3852
+ .ds-session-row-counts {
3853
+ font-size: var(--fs-micro); color: var(--fg-3);
3854
+ flex: 1 1 200px; min-width: 0;
3855
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
3856
+ }
3857
+ @media (max-width: 640px) {
3858
+ .ds-session-row-span { flex-basis: 100%; }
3686
3859
  }
3687
- .ds-session-row-counts { font-size: var(--fs-micro); color: var(--fg-3); width: 280px; }
3688
3860
  .ds-session-row-devcnt { color: var(--warn); font-weight: 600; }
3689
3861
  .ds-session-row-span { font-size: var(--fs-micro); color: var(--fg-3); }
3690
3862
 
@@ -3695,14 +3867,345 @@ input[type="password"]:not(:placeholder-shown) + .input-clear {
3695
3867
  }
3696
3868
  .ds-dev-row strong { color: var(--warn); }
3697
3869
 
3698
- /* LiveLog */
3870
+ /* LiveLog — natural height with a viewport-tracking cap (dvh follows mobile
3871
+ URL-bar chrome; min-height keeps short-landscape from going near-zero). */
3699
3872
  .ds-live-log {
3700
- height: calc(100vh - 200px); overflow-y: auto;
3873
+ height: auto;
3874
+ max-height: calc(100vh - 200px);
3875
+ max-height: calc(100dvh - 200px);
3876
+ min-height: 160px;
3877
+ overflow-y: auto; overflow-x: hidden;
3701
3878
  font-family: var(--ff-mono); font-size: var(--fs-micro); line-height: 1.5;
3702
3879
  }
3703
- .ds-live-log-empty { height: auto; padding: var(--space-3); color: var(--fg-3); }
3704
- .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); }
3880
+ /* Embedded in a WM window the viewport calc is meaningless — fill the container. */
3881
+ .fd-root .ds-live-log { height: 100%; max-height: none; min-height: 0; flex: 1 1 auto; }
3882
+ .ds-live-log-empty { height: auto; min-height: 0; padding: var(--space-3); color: var(--fg-3); }
3883
+ .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
3705
3884
  .ds-live-log-entry:hover { background: var(--bg-3); }
3706
3885
  .ds-live-log-ts { margin-right: 6px; color: var(--fg-3); }
3707
3886
  .ds-live-log-subtag { margin-right: 6px; padding: 0 5px; border-radius: 2px; font-size: var(--fs-micro); }
3708
- .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); }
3887
+ .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); word-break: break-word; }
3888
+
3889
+ /* Touch floors for the dense controls (not covered by the mobile width blocks). */
3890
+ @media (pointer: coarse) {
3891
+ .ds-sub-btn { min-height: 44px; }
3892
+ .ds-session-row { min-height: 44px; }
3893
+ .ds-live-log-entry { padding-block: 6px; }
3894
+ }
3895
+
3896
+
3897
+ /* == appended: popovers-files == */
3898
+ /* FilePreviewMedia controls row — spacing + coarse-pointer tap floor */
3899
+ .ds-preview-media-controls {
3900
+ display: flex;
3901
+ align-items: center;
3902
+ gap: var(--space-2);
3903
+ flex-wrap: wrap;
3904
+ }
3905
+ @media (hover: none), (pointer: coarse) {
3906
+ .ds-preview-media-controls .chat-code-copy,
3907
+ .chat-code-copy-head {
3908
+ min-height: 44px;
3909
+ min-width: 44px;
3910
+ }
3911
+ }
3912
+
3913
+ /* == appended: ui-kits == */
3914
+ /* ============================================================
3915
+ ui_kit responsive helpers (kits-grids sweep) */
3916
+ .ds-section-pad { padding: clamp(6px, 1.2vw, 16px); }
3917
+ .ds-panel-gap { margin: var(--space-2) 0; }
3918
+ .ds-panel-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin: var(--space-2) 0; }
3919
+ @media (max-width: 760px) {
3920
+ .ds-panel-duo { grid-template-columns: 1fr; }
3921
+ }
3922
+ /* wide dense rows/tables scroll inside their panel, never the page */
3923
+ .ds-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
3924
+
3925
+ /* --- slide deck ------------------------------------------- */
3926
+ .ds-deck-stage {
3927
+ aspect-ratio: 16 / 9;
3928
+ width: 100%;
3929
+ max-width: min(1100px, 100%);
3930
+ margin: var(--space-3) auto;
3931
+ background: var(--bg-2);
3932
+ border-radius: 18px;
3933
+ padding: clamp(16px, 5vw, 64px);
3934
+ box-sizing: border-box;
3935
+ display: flex;
3936
+ overflow: hidden;
3937
+ container-type: inline-size; /* cqw units track the stage, not the viewport */
3938
+ }
3939
+ @media (max-height: 500px) and (orientation: landscape) {
3940
+ .ds-deck-stage {
3941
+ max-height: calc(100vh - 140px);
3942
+ max-height: calc(100dvh - 140px);
3943
+ aspect-ratio: auto;
3944
+ }
3945
+ }
3946
+ .ds-deck-slide { flex: 1; display: flex; min-width: 0; }
3947
+ .ds-deck-controls {
3948
+ display: flex; align-items: center; justify-content: center; gap: 14px;
3949
+ padding: 8px; font-family: var(--ff-mono); font-size: var(--fs-sm);
3950
+ }
3951
+ .ds-deck-count { color: var(--fg-3); }
3952
+ @media (pointer: coarse) {
3953
+ .ds-deck-controls .btn { min-height: 44px; min-width: 44px; }
3954
+ }
3955
+ .ds-slide-eyebrow {
3956
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.1em;
3957
+ text-transform: uppercase; color: var(--fg-3); margin-bottom: clamp(12px, 2.5cqw, 24px);
3958
+ }
3959
+ .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
3960
+ .ds-slide-col--start { align-items: flex-start; }
3961
+ .ds-slide-col--narrow { max-width: 38ch; }
3962
+ .ds-slide-col--quote { max-width: 42ch; }
3963
+ .ds-slide-hero {
3964
+ font-size: clamp(var(--fs-h2), 6cqw, var(--fs-hero));
3965
+ line-height: var(--lh-tight); letter-spacing: var(--tr-tight); font-weight: 600;
3966
+ color: var(--slide-accent, var(--accent-ink));
3967
+ overflow-wrap: anywhere;
3968
+ }
3969
+ .ds-slide-h1 {
3970
+ font-size: clamp(var(--fs-h3), 4.5cqw, var(--fs-h1));
3971
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 500; min-width: 0;
3972
+ }
3973
+ .ds-slide-h1--lead { margin-bottom: 12px; }
3974
+ .ds-slide-quote-body {
3975
+ font-size: clamp(var(--fs-lg), 3.5cqw, var(--fs-h2));
3976
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 400; font-style: italic;
3977
+ }
3978
+ .ds-slide-cite { font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-3); }
3979
+ .ds-slide-bullet {
3980
+ display: flex; gap: clamp(8px, 2vw, 18px); align-items: baseline;
3981
+ border-bottom: 1px solid var(--rule); padding: 12px 0; flex-wrap: wrap;
3982
+ }
3983
+ .ds-slide-bullet-key {
3984
+ flex: 0 1 clamp(56px, 18%, 100px); min-width: 0;
3985
+ font-family: var(--ff-mono); font-size: var(--fs-sm);
3986
+ color: var(--slide-accent, var(--accent-ink));
3987
+ }
3988
+ .ds-slide-bullet-val { color: var(--fg-2); font-size: var(--fs-lg); min-width: 0; }
3989
+ .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 3vw, 32px); margin-top: 12px; }
3990
+ @media (max-width: 760px) {
3991
+ .ds-slide-split { grid-template-columns: 1fr; }
3992
+ }
3993
+ .ds-slide-split-cell {
3994
+ padding: 18px; background: var(--bg-2); border-radius: 14px;
3995
+ color: var(--fg-2); font-size: var(--fs-lg); line-height: var(--lh-base); min-width: 0;
3996
+ }
3997
+ .ds-slide-split-cell--accent { border-left: 3px solid var(--slide-accent, var(--accent)); }
3998
+
3999
+ /* --- error 404 --------------------------------------------- */
4000
+ .ds-err-hero {
4001
+ padding: clamp(16px, 5vw, 36px) clamp(12px, 4vw, 22px);
4002
+ text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center;
4003
+ }
4004
+ .ds-err-numeral {
4005
+ font-family: var(--ff-mono); font-size: clamp(56px, 20vw, 120px);
4006
+ line-height: 1; color: var(--panel-text-3); letter-spacing: -0.03em;
4007
+ }
4008
+ .ds-err-path {
4009
+ display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; max-width: 100%;
4010
+ font-family: var(--ff-mono); font-size: 13px; color: var(--panel-text-2);
4011
+ background: var(--panel-1); padding: 6px 12px; border-radius: 8px;
4012
+ overflow-wrap: anywhere; word-break: break-all;
4013
+ }
4014
+
4015
+ /* --- gallery ------------------------------------------------ */
4016
+ .ds-tile-grid {
4017
+ padding: clamp(8px, 2.5vw, 16px);
4018
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 8px;
4019
+ }
4020
+ .ds-tile-grid--tight { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
4021
+ .ds-swatch-grid {
4022
+ padding: clamp(8px, 2.5vw, 16px);
4023
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: 12px;
4024
+ }
4025
+ .ds-gallery-tile {
4026
+ cursor: pointer; display: flex; flex-direction: column; gap: 6px;
4027
+ padding: 12px; border-radius: 10px; min-height: clamp(120px, 18vw, 160px);
4028
+ border: 0; text-align: left; font: inherit; color: inherit;
4029
+ background: var(--tile-tone, var(--panel-1));
4030
+ }
4031
+ .ds-gallery-tile:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
4032
+ .ds-gallery-tile--tight { min-height: clamp(96px, 14vw, 120px); }
4033
+ .ds-lightbox {
4034
+ position: fixed; inset: 0; background: var(--scrim);
4035
+ display: flex; align-items: center; justify-content: center;
4036
+ padding: clamp(12px, 4vw, 32px);
4037
+ padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
4038
+ z-index: 50;
4039
+ }
4040
+ .ds-lightbox-card {
4041
+ background: var(--panel-0); border-radius: 14px; padding: clamp(16px, 4vw, 28px);
4042
+ width: min(520px, 100%); min-width: 0;
4043
+ max-height: calc(100vh - 24px);
4044
+ max-height: calc(100dvh - 24px);
4045
+ overflow: auto;
4046
+ display: flex; flex-direction: column; gap: 14px;
4047
+ }
4048
+ .ds-lightbox-preview {
4049
+ padding: clamp(16px, 6vw, 36px); border-radius: 10px; text-align: center;
4050
+ font-family: var(--ff-mono); white-space: pre-line; font-size: clamp(16px, 5vw, 24px);
4051
+ background: var(--tile-tone, var(--panel-1));
4052
+ }
4053
+
4054
+ /* --- search ------------------------------------------------- */
4055
+ .ds-topbar-search { width: min(280px, 100%); min-width: 0; flex: 1 1 clamp(140px, 30vw, 280px); }
4056
+ @media (max-width: 480px) {
4057
+ .ds-topbar-search { flex-basis: 100%; }
4058
+ }
4059
+ .ds-empty-state { padding: clamp(16px, 5vw, 24px); text-align: center; color: var(--panel-text-3); }
4060
+ .ds-empty-state-glyph { font-size: clamp(24px, 6vw, 32px); }
4061
+ .ds-empty-state-msg { margin: 6px 0; }
4062
+ .ds-empty-state-hint { margin: 0; font-size: var(--fs-sm); }
4063
+
4064
+ /* --- system primer ------------------------------------------ */
4065
+ .ds-swatch-grid-sm {
4066
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
4067
+ gap: 12px; padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
4068
+ }
4069
+ .ds-swatch-grid-lg { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
4070
+ .ds-swatch-col { display: flex; flex-direction: column; gap: 6px; }
4071
+ .ds-swatch-chip { height: 48px; border-radius: 10px; border: 1px solid var(--rule); background: var(--swatch, var(--panel-1)); }
4072
+ .ds-swatch-chip--big { height: 64px; }
4073
+ .ds-swatch-name { font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4074
+ .ds-type-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 14px; }
4075
+ .ds-type-row {
4076
+ display: flex; align-items: baseline; gap: 14px;
4077
+ border-bottom: 1px solid var(--rule); padding-bottom: 8px; flex-wrap: wrap;
4078
+ }
4079
+ .ds-type-row-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4080
+ .ds-type-sample {
4081
+ min-width: 0; overflow-wrap: anywhere; line-height: var(--lh-tight); color: var(--fg);
4082
+ font-size: var(--sample-size, var(--fs-body));
4083
+ }
4084
+ .ds-prim-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 18px; }
4085
+ .ds-prim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
4086
+ .ds-prim-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4087
+
4088
+ /* == appended: content-site == */
4089
+ /* Home landing wrappers (site/theme.mjs) — replace banned inline styles. */
4090
+ .ds-home-hero-wrap { padding: 0 var(--space-2, 8px); }
4091
+ .ds-home-panel { margin: var(--space-2, 8px); }
4092
+ @media (max-width: 480px) {
4093
+ .ds-home-panel { margin: var(--space-1, 4px) 0; }
4094
+ }
4095
+ .ds-quickstart {
4096
+ padding: var(--space-3, 16px) var(--space-4, 22px);
4097
+ display: flex;
4098
+ flex-direction: column;
4099
+ gap: 6px;
4100
+ }
4101
+ /* Table() scroll containment — wide tables scroll inside their own box,
4102
+ never the page body. */
4103
+ .ds-table-wrap {
4104
+ overflow-x: auto;
4105
+ -webkit-overflow-scrolling: touch;
4106
+ max-width: 100%;
4107
+ }
4108
+ .ds-table-wrap > table { min-width: 100%; }
4109
+
4110
+
4111
+ /* == appended: settings kit cleanup == */
4112
+ /* == appended: settings kit == */
4113
+ .ds-settings-main { padding: 8px; }
4114
+ .ds-settings-body { padding: 14px 18px; }
4115
+ .ds-settings-body-stack { display: flex; flex-direction: column; gap: 10px; }
4116
+ .ds-field-block { margin: 10px 0; }
4117
+ .ds-field-eyebrow {
4118
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em;
4119
+ text-transform: uppercase; color: var(--panel-text-3);
4120
+ }
4121
+ .ds-hint-sm { font-size: 12px; color: var(--panel-text-2); }
4122
+ .ds-note-quiet { margin: 0; color: var(--panel-text-2); }
4123
+ .ds-btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
4124
+ .ds-btn-row-tight { gap: 6px; }
4125
+ .ds-key-input { flex: 1 1 160px; min-width: 0; font-family: var(--ff-mono); }
4126
+ .ds-toggle-btn { min-width: 78px; }
4127
+ .ds-toggle-label { margin-left: 8px; color: inherit; opacity: 0.7; }
4128
+ .ds-btn-warn { color: var(--warn); }
4129
+ .ds-btn-mascot { color: var(--mascot); }
4130
+ .ds-savebar {
4131
+ position: sticky; bottom: 8px; display: flex; align-items: center;
4132
+ justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding: 10px;
4133
+ background: var(--panel-2); border-radius: 10px; margin: 8px 0;
4134
+ }
4135
+ .ds-savebar-note { flex: 1 1 160px; min-width: 0; color: var(--panel-text-2); }
4136
+ .ds-settings-modal { min-width: min(320px, calc(100vw - 32px)); max-width: 480px; }
4137
+ .ds-modal-body-form { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
4138
+ .ds-modal-note { margin: 0 0 8px; color: var(--panel-text-2); font-size: 14px; }
4139
+ .ds-draft-preview {
4140
+ background: var(--panel-1); padding: 12px; border-radius: 6px;
4141
+ font-size: 13px; color: var(--panel-text-2); max-height: 120px;
4142
+ overflow-y: auto; font-family: var(--ff-mono); overflow-wrap: anywhere;
4143
+ }
4144
+ .ds-modal-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: space-between; flex-wrap: wrap; }
4145
+
4146
+ /* == appended: signin kit cleanup == */
4147
+ /* -- signin kit (ui_kits/signin) -- */
4148
+ .ds-auth-wrap { padding: var(--space-2, 8px); display: flex; flex-direction: column; align-items: center; }
4149
+ .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 8px; margin: clamp(12px, 4vw, 24px) 0; min-width: 0; }
4150
+ .ds-auth-form { padding: clamp(12px, 3vw, 18px); display: flex; flex-direction: column; gap: 10px; }
4151
+ .ds-auth-sent { align-items: center; text-align: center; }
4152
+ .ds-auth-sent-glyph { font-size: 32px; color: var(--panel-accent); }
4153
+ .ds-auth-sent-title { margin: 0; font-weight: 600; }
4154
+ .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
4155
+ .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
4156
+ .ds-auth-field-label { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
4157
+ .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
4158
+ .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
4159
+ .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
4160
+ .ds-auth-forgot { font-size: 13px; }
4161
+ .ds-auth-error { padding: 8px 10px; background: var(--panel-1); border-radius: 8px; color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
4162
+ .ds-auth-divider { display: flex; align-items: center; gap: 10px; margin: 6px 0; color: var(--panel-text-3); font-size: 12px; }
4163
+ .ds-auth-divider-line { flex: 1; height: 1px; background: var(--panel-2); }
4164
+ .ds-auth-providers { display: flex; gap: 8px; flex-wrap: wrap; }
4165
+ .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; }
4166
+ .ds-auth-provider-btn--loading { opacity: 0.7; pointer-events: none; }
4167
+ .ds-auth-provider-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); display: inline-flex; }
4168
+ .ds-auth-modes { display: flex; justify-content: center; gap: 14px; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
4169
+ .ds-auth-mode-link { color: var(--panel-text-3); text-decoration: none; }
4170
+ .ds-auth-mode-link--active { color: var(--panel-text); text-decoration: underline; }
4171
+ .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: 6px 0; }
4172
+
4173
+ /* == appended: gallery-misc kit cleanup == */
4174
+ /* --- shared helpers (converted from inline styles) --- */
4175
+ .ds-m0 { margin: 0; }
4176
+ .ds-text-2 { color: var(--panel-text-2); }
4177
+ .ds-text-3 { color: var(--panel-text-3); }
4178
+ .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(8px, 2vw, 16px); flex-wrap: wrap; }
4179
+
4180
+ /* --- gallery kit --- */
4181
+ .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; }
4182
+ .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; flex-wrap: wrap; min-width: 0; }
4183
+ .ds-tile-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); }
4184
+ .ds-tile-label { color: var(--panel-text); overflow-wrap: anywhere; }
4185
+ .ds-gal-swatch { height: 64px; border-radius: 8px; background: var(--swatch, var(--panel-1)); }
4186
+ .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; }
4187
+ .ds-gal-swatch-name { color: var(--panel-text); }
4188
+ .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
4189
+ .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
4190
+ .ds-lightbox-tag { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
4191
+
4192
+ /* --- error_404 kit --- */
4193
+ .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
4194
+ .ds-err-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
4195
+
4196
+ /* == appended: terminal-capp kit cleanup == */
4197
+ /* --- terminal kit ------------------------------------------ */
4198
+ .ds-section-pad-sm { padding: 8px; }
4199
+ .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
4200
+ .ds-cli-cmt .cmd { color: var(--fg-3); }
4201
+ .ds-cli-out .cmd { color: var(--fg-2); }
4202
+ .ds-cli-ok .prompt, .ds-cli-ok .cmd { color: var(--accent-ink); }
4203
+ .ds-cli-warn .prompt, .ds-cli-warn .cmd { color: var(--mascot); }
4204
+ .ds-cli-log .prompt { color: var(--fg-3); }
4205
+ .ds-cli-log .cmd { color: var(--fg-2); font-family: var(--ff-mono); }
4206
+ .ds-term-body { padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; background: var(--bg-2); border-radius: 10px; }
4207
+ .ds-term-body--tall { min-height: 280px; }
4208
+ .ds-term-input-row { margin-top: 6px; }
4209
+ .ds-term-input { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; font-family: var(--ff-mono); font-size: 13px; color: var(--fg); }
4210
+ /* full-viewport render root (community-app) */
4211
+ .ds-root-viewport { height: 100vh; height: 100dvh; }