anentrypoint-design 0.0.237 → 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/dist/247420.css CHANGED
@@ -882,6 +882,8 @@
882
882
  /* Status bar inherits the .app max-width cap above and stretches edge-to-edge
883
883
  within it; no separate width constraint (which previously narrowed it). */
884
884
  .ds-247420 .app-status { width: 100%; }
885
+ /* Cap row text measure inside the wide capped main (ultrawide readability). */
886
+ .ds-247420 .row .title, .ds-247420 .row .sub { max-width: var(--measure-wide); }
885
887
  }
886
888
 
887
889
  .ds-247420 .app-status {
@@ -1185,14 +1187,16 @@
1185
1187
  padding: var(--space-9) 0 var(--space-8);
1186
1188
  display: grid; gap: var(--space-5) var(--space-6);
1187
1189
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
1188
- grid-template-areas: 'title title' 'body actions';
1190
+ grid-template-areas: 'title title' 'body actions' 'badge badge';
1189
1191
  align-items: end;
1190
1192
  max-width: var(--measure-wide);
1191
1193
  }
1192
1194
  .ds-247420 .ds-hero-head { grid-area: title; display: grid; gap: var(--space-3); }
1193
1195
  .ds-247420 .ds-hero-body { grid-area: body; }
1194
1196
  .ds-247420 .ds-hero-actions { grid-area: actions; }
1195
- .ds-247420 .ds-hero-badge { grid-area: actions; }
1197
+ /* Badge gets its own row — sharing 'actions' overlapped it onto the CTAs
1198
+ whenever a caller passes both actions and badge. */
1199
+ .ds-247420 .ds-hero-badge { grid-area: badge; }
1196
1200
  .ds-247420 .ds-hero-title {
1197
1201
  font-family: var(--ff-display); font-weight: 700;
1198
1202
  font-size: clamp(40px, 9cqi, 116px);
@@ -1207,10 +1211,13 @@
1207
1211
  /* The lead phrase in the title — printed in the electric lead, not glowing. */
1208
1212
  .ds-247420 .ds-hero-accent { color: var(--accent-ink); font-weight: 700; }
1209
1213
  .ds-247420 .ds-hero-actions { display: flex; gap: var(--space-2, 10px); flex-wrap: wrap; align-self: end; }
1210
- @media (max-width: 900px) {
1214
+ /* Container-queried (the whole shell is; a 500px pane on a wide viewport
1215
+ would keep the two-column grid under a width @media). Left-aligned stack —
1216
+ no centering — preserving the asymmetric intent. */
1217
+ @container (max-width: 900px) {
1211
1218
  .ds-247420 .ds-hero {
1212
1219
  grid-template-columns: minmax(0, 1fr);
1213
- grid-template-areas: 'title' 'body' 'actions';
1220
+ grid-template-areas: 'title' 'body' 'actions' 'badge';
1214
1221
  align-items: start;
1215
1222
  padding: var(--space-7) 0 var(--space-6);
1216
1223
  }
@@ -1278,13 +1285,21 @@
1278
1285
  }
1279
1286
  .ds-247420 .ds-marquee-item { display: inline-flex; align-items: center; gap: var(--space-5); }
1280
1287
  .ds-247420 .ds-marquee-sep { color: var(--accent-ink); }
1281
- .ds-247420 .ds-marquee:hover .ds-marquee-track { animation-play-state: paused; }
1288
+ .ds-247420 .ds-marquee:hover .ds-marquee-track,
1289
+ .ds-247420 .ds-marquee:focus-within .ds-marquee-track,
1290
+ .ds-247420 .ds-marquee:active .ds-marquee-track { animation-play-state: paused; }
1282
1291
  @keyframes ds-marquee-run {
1283
1292
  from { transform: translateX(0); }
1284
1293
  to { transform: translateX(-50%); }
1285
1294
  }
1295
+ /* Touch has no hover-pause; slow the ticker so it burns less attention. */
1296
+ @media (hover: none), (pointer: coarse) {
1297
+ .ds-247420 .ds-marquee-track { animation-duration: 40s; }
1298
+ }
1286
1299
  @media (prefers-reduced-motion: reduce) {
1287
- .ds-247420 .ds-marquee-track { animation: none; }
1300
+ /* Static: wrap to a readable strip instead of a frozen half-offscreen run. */
1301
+ .ds-247420 .ds-marquee-track { animation: none; flex-wrap: wrap; white-space: normal; }
1302
+ .ds-247420 .ds-marquee-run-b { display: none; }
1288
1303
  }
1289
1304
 
1290
1305
  /* ============================================================
@@ -1292,6 +1307,7 @@
1292
1307
  ============================================================ */
1293
1308
  .ds-247420 .cli {
1294
1309
  display: flex; align-items: center; gap: 14px;
1310
+ overflow-x: auto;
1295
1311
  padding: 20px 24px;
1296
1312
  background: var(--ink); color: var(--paper);
1297
1313
  border-radius: var(--r-3);
@@ -1345,6 +1361,15 @@
1345
1361
  }
1346
1362
  .ds-247420 table.kv td:last-child {
1347
1363
  font-weight: 600;
1364
+ overflow-wrap: anywhere; min-width: 0;
1365
+ }
1366
+ /* Tiny screens: stack the key over the value instead of squeezing a 14ch
1367
+ label column beside long unbroken values (URLs, hashes). */
1368
+ @media (max-width: 400px) {
1369
+ .ds-247420 table.kv td { display: block; width: auto; padding: 4px 0; }
1370
+ .ds-247420 table.kv td:first-child { padding-top: 8px; }
1371
+ .ds-247420 table.kv tr + tr td { border-top: 0; }
1372
+ .ds-247420 table.kv tr + tr td:first-child { border-top: 1px solid var(--rule); }
1348
1373
  }
1349
1374
 
1350
1375
  /* ============================================================
@@ -1540,6 +1565,10 @@
1540
1565
  }
1541
1566
  .ds-247420 .row .sub { grid-column: 1 / -1; order: 3; }
1542
1567
  .ds-247420 .row .title { font-size: var(--fs-sm); }
1568
+ /* Changelog carries 3 children: give date+ver line one, message wraps below
1569
+ (the generic 2-col .row override staggers it into an implicit row). */
1570
+ .ds-247420 .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
1571
+ .ds-247420 .ds-changelog-row .title { grid-column: 1 / -1; }
1543
1572
 
1544
1573
  /* Buttons */
1545
1574
  .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost {
@@ -1583,7 +1612,9 @@
1583
1612
  gap: var(--space-2);
1584
1613
  }
1585
1614
  .ds-247420 .kpi-card { padding: var(--space-3); }
1586
- .ds-247420 .kpi-card .num { font-size: clamp(22px, 5vw, 32px); }
1615
+ /* Container-relative like the base rule (5vw sized against the viewport and
1616
+ jumped across the breakpoint). */
1617
+ .ds-247420 .kpi-card .num { font-size: clamp(22px, 8cqi, 32px); }
1587
1618
 
1588
1619
  /* Empty State */
1589
1620
  .ds-247420 .empty { padding: var(--space-5); font-size: var(--fs-xs); }
@@ -1617,10 +1648,11 @@
1617
1648
  @container (max-width: 760px) {
1618
1649
  .ds-247420 .app-body { grid-template-columns: 1fr !important; }
1619
1650
  .ds-247420 .app-side-shell { border-right: 0; border-bottom: 1px solid var(--rule); }
1620
- .ds-247420 .app-topbar { grid-template-columns: 1fr auto; }
1621
1651
  .ds-247420 .app-topbar nav { font-size: var(--fs-xs); gap: 14px; }
1622
1652
  .ds-247420 .row { grid-template-columns: minmax(0, 1fr) auto !important; row-gap: 4px !important; }
1623
1653
  .ds-247420 .row .sub { grid-column: 1 / -1; order: 3; }
1654
+ .ds-247420 .ds-changelog-row { grid-template-columns: minmax(70px, 10ch) minmax(0, 1fr) !important; }
1655
+ .ds-247420 .ds-changelog-row .title { grid-column: 1 / -1; }
1624
1656
  }
1625
1657
 
1626
1658
  /* --------------------------------------------------------------------
@@ -1635,9 +1667,8 @@
1635
1667
  min-height: 44px;
1636
1668
  }
1637
1669
 
1638
- /* Topbar Navigation */
1670
+ /* Topbar Navigation (flex container — no grid-template here) */
1639
1671
  .ds-247420 .app-topbar {
1640
- grid-template-columns: auto 1fr auto;
1641
1672
  gap: var(--space-3); padding: 12px var(--space-4);
1642
1673
  }
1643
1674
  .ds-247420 .app-topbar nav {
@@ -1716,6 +1747,8 @@
1716
1747
  gap: var(--space-2);
1717
1748
  }
1718
1749
  .ds-247420 .row .code { display: none; }
1750
+ /* Changelog's date lives in span.code — hiding it is data loss, not reflow. */
1751
+ .ds-247420 .ds-changelog-row .code { display: inline; font-size: var(--fs-micro); }
1719
1752
  .ds-247420 .row .sub { grid-column: 1 / -1; }
1720
1753
  }
1721
1754
 
@@ -2066,6 +2099,10 @@
2066
2099
  padding: 4px 8px; border-radius: var(--r-1);
2067
2100
  color: var(--fg-3); font-family: inherit; font-size: var(--fs-sm);
2068
2101
  transition: background var(--dur-snap) var(--ease), color var(--dur-snap) var(--ease);
2102
+ /* A single long unbroken segment (hash-named dir) must never force the
2103
+ whole path past the viewport. */
2104
+ max-width: min(40vw, 220px);
2105
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
2069
2106
  }
2070
2107
  .ds-247420 .ds-crumb-seg:hover { background: var(--bg-2); color: var(--fg); }
2071
2108
  .ds-247420 .ds-crumb-seg.leaf { color: var(--fg); font-weight: 600; }
@@ -2162,6 +2199,14 @@
2162
2199
  border-radius: var(--r-3);
2163
2200
  }
2164
2201
  .ds-247420 .ds-dropzone--wrap.dragover { animation: none; }
2202
+ /* Touch devices can never fire dragover — keep the pick-files affordance
2203
+ visible as a compact static row so upload stays reachable in wrap mode. */
2204
+ @media (hover: none) and (pointer: coarse) {
2205
+ .ds-247420 .ds-dropzone--wrap > .ds-dropzone-inner {
2206
+ display: flex; position: static; padding: var(--space-2);
2207
+ outline: none; background: transparent;
2208
+ }
2209
+ }
2165
2210
 
2166
2211
  /* Upload progress */
2167
2212
  .ds-247420 .ds-upload-progress { display: flex; flex-direction: column; gap: 6px; }
@@ -2190,7 +2235,12 @@
2190
2235
  .ds-247420 .ds-upload-item.error .ds-upload-fill { background: var(--warn); }
2191
2236
  .ds-247420 .ds-upload-item.error .ds-upload-pct { color: var(--warn); }
2192
2237
  /* Per-row upload recovery actions (replace / dismiss) — error rows are not dead ends. */
2193
- .ds-247420 .ds-upload-item { grid-template-columns: minmax(0, 1fr) 120px 44px auto; }
2238
+ .ds-247420 .ds-upload-item { grid-template-columns: minmax(0, 1fr) minmax(60px, 120px) 44px auto; }
2239
+ @media (max-width: 480px) {
2240
+ .ds-247420 .ds-upload-item { grid-template-columns: minmax(0, 1fr) 44px; }
2241
+ .ds-247420 .ds-upload-bar { grid-column: 1 / -1; order: 3; }
2242
+ .ds-247420 .ds-upload-actions { grid-column: 1 / -1; justify-content: flex-end; }
2243
+ }
2194
2244
  .ds-247420 .ds-upload-actions { display: inline-flex; gap: var(--space-1); justify-content: flex-end; }
2195
2245
  .ds-247420 .ds-upload-act {
2196
2246
  padding: 2px 10px; min-height: 24px; cursor: pointer;
@@ -2201,6 +2251,11 @@
2201
2251
  .ds-247420 .ds-upload-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2202
2252
  @media (hover: none), (pointer: coarse) {
2203
2253
  .ds-247420 .ds-upload-act { min-height: 44px; min-width: 44px; }
2254
+ /* 44px floor for file controls on ANY touch device, not only narrow ones
2255
+ (the width-based mobile block misses wide touch tablets). */
2256
+ .ds-247420 .ds-file-act, .ds-247420 .ds-file-sort-btn, .ds-247420 .ds-crumb-seg, .ds-247420 .ds-file-filter-input { min-height: 44px; }
2257
+ .ds-247420 .ds-file-act { min-width: 44px; }
2258
+ .ds-247420 .ds-file-check, .ds-247420 .ds-file-selectall, .ds-247420 .ds-density-btn { min-height: 44px; min-width: 44px; }
2204
2259
  }
2205
2260
 
2206
2261
  /* Empty state */
@@ -2216,7 +2271,11 @@
2216
2271
  .ds-247420 .ds-modal-backdrop {
2217
2272
  position: fixed; inset: 0; z-index: var(--z-modal, 800);
2218
2273
  display: flex; align-items: center; justify-content: center;
2219
- padding: var(--space-3);
2274
+ /* Notch/home-indicator safe: near-fullscreen modals must not slide under. */
2275
+ padding: max(var(--space-3), env(safe-area-inset-top))
2276
+ max(var(--space-3), env(safe-area-inset-right))
2277
+ max(var(--space-3), env(safe-area-inset-bottom))
2278
+ max(var(--space-3), env(safe-area-inset-left));
2220
2279
  background: color-mix(in oklab, var(--ink) 55%, transparent);
2221
2280
  backdrop-filter: blur(3px);
2222
2281
  }
@@ -2226,7 +2285,9 @@
2226
2285
  @keyframes ds-modal-fade { from { opacity: 0; } to { opacity: 1; } }
2227
2286
  .ds-247420 .ds-modal {
2228
2287
  display: flex; flex-direction: column;
2229
- width: 100%; max-width: 460px; max-height: calc(100vh - 2 * var(--space-4));
2288
+ width: 100%; max-width: 460px;
2289
+ max-height: calc(100vh - 2 * var(--space-4));
2290
+ max-height: calc(100dvh - 2 * var(--space-4));
2230
2291
  background: var(--bg); color: var(--fg);
2231
2292
  border: var(--bw-hair) solid var(--rule);
2232
2293
  border-radius: var(--r-3); box-shadow: var(--shadow-3);
@@ -2259,6 +2320,10 @@
2259
2320
  font-family: inherit; font-size: var(--fs-sm);
2260
2321
  }
2261
2322
  .ds-247420 .ds-modal-input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2323
+ /* iOS auto-zooms inputs under 16px on focus, breaking the modal layout. */
2324
+ @media (hover: none), (pointer: coarse) {
2325
+ .ds-247420 .ds-modal-input { font-size: 16px; min-height: 44px; }
2326
+ }
2262
2327
  /* In-body modal error (role=alert): mutation failures (409/403) surface INSIDE
2263
2328
  the dialog, not behind the fixed overlay. */
2264
2329
  .ds-247420 .ds-modal-error {
@@ -2282,10 +2347,12 @@
2282
2347
  .ds-247420 .ds-preview-name {
2283
2348
  font-weight: 600; font-size: var(--fs-body);
2284
2349
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
2350
+ flex: 1 1 auto;
2285
2351
  }
2286
2352
  .ds-247420 .ds-preview-meta {
2287
2353
  font-family: var(--ff-mono); font-size: var(--fs-xs);
2288
2354
  color: var(--fg-3); white-space: nowrap;
2355
+ flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
2289
2356
  }
2290
2357
  .ds-247420 .ds-preview-actions { display: inline-flex; gap: 2px; margin-left: auto; }
2291
2358
  .ds-247420 .ds-preview-body {
@@ -2294,7 +2361,9 @@
2294
2361
  display: flex; flex-direction: column;
2295
2362
  }
2296
2363
  .ds-247420 .ds-preview-media {
2297
- max-width: 100%; max-height: 70vh; margin: 0 auto;
2364
+ max-width: 100%;
2365
+ max-height: 70vh; max-height: 70dvh;
2366
+ margin: 0 auto;
2298
2367
  border-radius: var(--r-2); object-fit: contain;
2299
2368
  }
2300
2369
  .ds-247420 .ds-preview-audio { width: 100%; }
@@ -2340,10 +2409,22 @@
2340
2409
 
2341
2410
  /* Mobile — modals go near-fullscreen, preview media shrinks. */
2342
2411
  @media (max-width: 560px) {
2343
- .ds-247420 .ds-modal { max-width: 100%; max-height: calc(100vh - 2 * var(--space-3)); }
2344
- .ds-247420 .ds-modal-preview { width: 100%; height: calc(100vh - 2 * var(--space-3)); max-height: none; }
2345
- .ds-247420 .ds-preview-media { max-height: 50vh; }
2412
+ .ds-247420 .ds-modal {
2413
+ max-width: 100%;
2414
+ max-height: calc(100vh - 2 * var(--space-3));
2415
+ max-height: calc(100dvh - 2 * var(--space-3));
2416
+ }
2417
+ .ds-247420 .ds-modal-preview {
2418
+ width: 100%; max-height: none;
2419
+ height: calc(100vh - 2 * var(--space-3));
2420
+ height: calc(100dvh - 2 * var(--space-3));
2421
+ }
2422
+ .ds-247420 .ds-preview-media { max-height: 50vh; max-height: 50dvh; }
2346
2423
  .ds-247420 .ds-file-stage { padding: var(--space-3) var(--space-2); }
2424
+ /* Preview head: let it wrap and drop the nowrap meta (duplicated in body)
2425
+ so the close button can never be pushed past the modal edge. */
2426
+ .ds-247420 .ds-preview-head { flex-wrap: wrap; row-gap: 4px; }
2427
+ .ds-247420 .ds-preview-meta { display: none; }
2347
2428
  }
2348
2429
 
2349
2430
  /* -- File browser UX affordances ---------------------------- */
@@ -2960,10 +3041,21 @@
2960
3041
  .ds-247420 .chat-composer textarea { padding: 10px 12px; }
2961
3042
  }
2962
3043
 
2963
- /* --- landscape orientation: reduce vertical space for composer --- */
3044
+ /* --- landscape orientation: reduce vertical space for chrome + composer --- */
2964
3045
  @media (max-height: 500px) and (orientation: landscape) {
2965
- .ds-247420 .chat-composer { padding: 6px 0; }
2966
- .ds-247420 .chat-composer textarea { min-height: 44px; max-height: 120px; }
3046
+ /* Keep horizontal padding: 0 put the textarea/focus ring flush on the edge. */
3047
+ .ds-247420 .chat-composer { padding: 6px var(--space-2); }
3048
+ .ds-247420 .chat-composer textarea { min-height: 36px; max-height: 96px; }
3049
+ .ds-247420 .chat-composer .chat-composer-hint,
3050
+ .ds-247420 .chat-composer .chat-composer-context { display: none; }
3051
+ /* Compact the shell chrome: ~114px of topbar+crumb+status is a third of a
3052
+ 360px-tall landscape fold. */
3053
+ .ds-247420 { --app-topbar-h: 40px; --app-crumb-h: 24px; }
3054
+ .ds-247420 .app-chrome { padding: 4px var(--pad-x); }
3055
+ .ds-247420 .app-status { display: none; }
3056
+ .ds-247420 .ws-crumb { min-height: 32px; }
3057
+ .ds-247420 .ds-hero { padding: var(--space-4) 0 var(--space-3); }
3058
+ .ds-247420 .ds-hero-title { font-size: clamp(28px, 6cqi, 56px); }
2967
3059
  }
2968
3060
 
2969
3061
  /* ============================================================
@@ -3387,6 +3479,15 @@
3387
3479
  }
3388
3480
  }
3389
3481
 
3482
+ /* Touch floor also for coarse-pointer devices that report hover (hybrid
3483
+ laptops/tablets with mice) — the block above requires hover:none too. */
3484
+ @media (pointer: coarse) {
3485
+ .ds-247420 .ds-icon-btn, .ds-247420 .ds-icon-btn-xs, .ds-247420 .ds-icon-btn-sm, .ds-247420 .ds-icon-btn-base {
3486
+ min-width: 44px; min-height: 44px;
3487
+ }
3488
+ .ds-247420 .btn, .ds-247420 .btn-primary, .ds-247420 .btn-ghost, .ds-247420 .app-topbar nav a, .ds-247420 .app-side a { min-height: 44px; }
3489
+ }
3490
+
3390
3491
  /* ------------------------------------------------------------
3391
3492
  Theme Transition Smoothness
3392
3493
  -------------------------------------------------------------- */
@@ -3618,16 +3719,24 @@
3618
3719
  .ds-247420 .app-body.no-side { grid-template-columns: 1fr !important; }
3619
3720
  .ds-247420 .app-side-shell {
3620
3721
  position: absolute;
3621
- left: 0; top: var(--app-topbar-h);
3622
- height: calc(100% - var(--app-topbar-h) - var(--app-status-h));
3722
+ /* Full-height overlay drawer: the merged .app-chrome wraps and its real
3723
+ height drifts from --app-topbar-h, so anchoring below it misplaces the
3724
+ drawer. Overlay the chrome instead (z above --z-header), like ws drawers. */
3725
+ left: 0; top: 0;
3726
+ height: 100%;
3623
3727
  width: 280px; max-width: 80%;
3624
3728
  transform: translateX(-100%);
3625
3729
  transition: transform var(--dur-base, 240ms) var(--ease, ease);
3626
- z-index: 50;
3730
+ /* Above the sticky chrome (z-header): scrim > chrome > content budget. */
3731
+ z-index: calc(var(--z-header, 100) + 2);
3627
3732
  background: var(--bg);
3628
3733
  border-right: 1px solid color-mix(in oklab, var(--fg) 8%, transparent);
3629
3734
  overflow-y: auto;
3735
+ overscroll-behavior: contain;
3630
3736
  }
3737
+ /* Lock the content scroller while the drawer is open so touch pans don't
3738
+ scroll the page behind the scrim. */
3739
+ .ds-247420 .app-body.side-open .app-main { overflow: hidden; }
3631
3740
  .ds-247420 .app-side-shell.open,
3632
3741
  .ds-247420 .app-side.open,
3633
3742
  .ds-247420 .app-body.side-open .app-side-shell { transform: translateX(0); }
@@ -3660,7 +3769,8 @@
3660
3769
  display: none;
3661
3770
  position: absolute; inset: 0;
3662
3771
  background: color-mix(in oklab, var(--bg) 60%, transparent);
3663
- z-index: 49;
3772
+ /* Above the sticky chrome so nav behind an open drawer is not clickable. */
3773
+ z-index: calc(var(--z-header, 100) + 1);
3664
3774
  }
3665
3775
  @container (max-width: 900px) {
3666
3776
  .ds-247420 .app-body.side-open .app-side-scrim { display: block; }
@@ -3672,7 +3782,9 @@
3672
3782
  .ds-247420 .app-side-toggle {
3673
3783
  display: none;
3674
3784
  position: absolute; top: calc((var(--app-topbar-h) - 44px) / 2); left: 10px;
3675
- z-index: 51;
3785
+ /* Above the sticky topbar/chrome (z-header) and the drawer/scrim so the
3786
+ translucent blurred chrome never paints over or intercepts the toggle. */
3787
+ z-index: calc(var(--z-header, 100) + 3);
3676
3788
  /* 44x44 minimum hit area (WCAG 2.5.5 / Apple HIG) - 36px is below the
3677
3789
  reliable-tap threshold on touch. */
3678
3790
  width: 44px; height: 44px;
@@ -3724,6 +3836,8 @@
3724
3836
  .ds-247420 .app-topbar nav,
3725
3837
  .ds-247420 .app-topbar > :last-child { display: none; }
3726
3838
  .ds-247420 .brand { font-size: var(--fs-tiny); }
3839
+ /* Slightly narrower drawer on tiny phones; max-width:80% remains the guard. */
3840
+ .ds-247420 .app-side-shell { width: 260px; }
3727
3841
  }
3728
3842
 
3729
3843
  /* ----------------------------------------------------------------------------
@@ -3797,6 +3911,11 @@
3797
3911
  @media (prefers-reduced-motion: no-preference) {
3798
3912
  .ds-247420 .ws-shell { transition: grid-template-columns var(--dur-base) var(--ease); }
3799
3913
  }
3914
+ /* Ultrawide: cap the shell so the 1fr content track doesn't stretch to
3915
+ unreadable measures while the fixed side columns pin to their clamps. */
3916
+ @media (min-width: 1920px) {
3917
+ .ds-247420 .ws-shell { max-width: 1920px; margin-inline: auto; }
3918
+ }
3800
3919
 
3801
3920
  /* Rail (left nav) */
3802
3921
  .ds-247420 .ws-rail {
@@ -3832,7 +3951,7 @@
3832
3951
  }
3833
3952
  .ds-247420 .ws-rail-action:hover { filter: brightness(1.08); }
3834
3953
  .ds-247420 .ws-rail-action:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
3835
- .ds-247420 .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; }
3954
+ .ds-247420 .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; }
3836
3955
  .ds-247420 .ws-rail-item {
3837
3956
  display: flex; align-items: center; gap: var(--space-2);
3838
3957
  width: 100%; padding: var(--space-2); min-height: 44px;
@@ -3895,6 +4014,7 @@
3895
4014
  min-height: 0; display: flex; flex-direction: column;
3896
4015
  background: var(--bg-2); border-left: var(--bw-hair) solid var(--bg-3);
3897
4016
  overflow: hidden; transition: width var(--dur-base) var(--ease);
4017
+ overscroll-behavior: contain;
3898
4018
  }
3899
4019
  .ds-247420 .ws-pane-collapsed .ws-pane { width: 0; border-left: none; }
3900
4020
  .ds-247420 .ws-pane-collapsed .ws-pane > * { display: none; }
@@ -3979,12 +4099,19 @@
3979
4099
  }
3980
4100
  .ds-247420 .ws-sessions {
3981
4101
  position: fixed; inset: 0 auto 0 0;
3982
- width: min(var(--ws-sessions-w), 80vw);
4102
+ /* Immune to the desktop collapse var (--ws-sessions-w:0px persisted from
4103
+ a desktop session would open an invisible 0-width drawer). */
4104
+ width: min(max(var(--ws-sessions-w), 280px), 80vw);
3983
4105
  z-index: 42; transform: translateX(-110%);
3984
4106
  transition: transform var(--dur-base) var(--ease);
3985
4107
  border-right: var(--bw-hair) solid var(--bg-3);
4108
+ overscroll-behavior: contain;
3986
4109
  }
3987
4110
  .ds-247420 .ws-shell.ws-sessions-open .ws-sessions { transform: translateX(0); }
4111
+ /* Drawer mode ignores the desktop collapsed state: children stay rendered
4112
+ and the border returns, so a persisted collapse can't blank the drawer. */
4113
+ .ds-247420 .ws-shell.ws-sessions-collapsed .ws-sessions > * { display: revert; }
4114
+ .ds-247420 .ws-shell.ws-sessions-collapsed .ws-sessions { border-right: var(--bw-hair) solid var(--bg-3); }
3988
4115
  .ds-247420 .ws-sessions-drawer-toggle { display: inline-flex; }
3989
4116
  }
3990
4117
 
@@ -4094,6 +4221,21 @@
4094
4221
  .ds-247420 .ws-crumb,
4095
4222
  .ds-247420 .app-status { display: none; }
4096
4223
  .ds-247420 .ws-main { overflow: visible; height: auto; }
4224
+ /* AppShell: unpin the viewport-height frame so content flows across pages,
4225
+ and drop all chrome (it prints as page furniture otherwise). */
4226
+ .ds-247420 .app { height: auto; min-height: 0; overflow: visible; display: block; }
4227
+ .ds-247420 .app-body { display: block; }
4228
+ .ds-247420 .app-main { overflow: visible; height: auto; display: block; max-width: 100%; }
4229
+ .ds-247420 .app-topbar, .ds-247420 .app-chrome, .ds-247420 .app-crumb, .ds-247420 .app-side-shell, .ds-247420 .app-side-scrim, .ds-247420 .app-side-toggle, .ds-247420 .btn-fab, .ds-247420 .skip-link, .ds-247420 .ds-marquee { display: none; }
4230
+ /* Modals/preview: print the content, not a blurred overlay clipped to one page. */
4231
+ .ds-247420 .ds-modal-backdrop { position: static; background: none; backdrop-filter: none; padding: 0; }
4232
+ .ds-247420 .ds-modal, .ds-247420 .ds-modal-preview { max-width: 100%; max-height: none; box-shadow: none; }
4233
+ .ds-247420 .ds-modal-body, .ds-247420 .ds-preview-body, .ds-247420 .ds-preview-code, .ds-247420 .ds-preview-text { overflow: visible; }
4234
+ .ds-247420 .ds-modal-actions, .ds-247420 .ds-preview-actions { display: none; }
4235
+ /* Data-density: fixed-height log clips; bg-only tiles lose their boundary. */
4236
+ .ds-247420 .ds-live-log { height: auto; max-height: none; overflow: visible; }
4237
+ .ds-247420 .ds-stat, .ds-247420 .kpi-card { border: 1px solid var(--rule); }
4238
+ .ds-247420 .ds-session-row { break-inside: avoid; }
4097
4239
  }
4098
4240
 
4099
4241
  /* ============================================================
@@ -4118,15 +4260,26 @@
4118
4260
  }
4119
4261
  .ds-247420 .ds-phasewalk-seg.is-reached { background: var(--success); }
4120
4262
  .ds-247420 .ds-phasewalk-seg.is-gap { background: var(--warn); }
4263
+ /* Standalone PhaseWalk reserves headroom for the labels instead of letting
4264
+ them escape upward and overlap the element above. */
4265
+ .ds-247420 .ds-phasewalk { padding-top: 15px; }
4121
4266
  .ds-247420 .ds-phasewalk-lbl {
4122
4267
  position: absolute; top: -15px; left: 0;
4123
4268
  font-size: var(--fs-micro); color: var(--fg-3); white-space: nowrap;
4124
4269
  }
4270
+ /* Inline in a single-line SessionRow the labels would overlap the row above —
4271
+ segments already carry title tooltips. */
4272
+ .ds-247420 .ds-session-row .ds-phasewalk { padding-top: 0; }
4273
+ .ds-247420 .ds-session-row .ds-phasewalk-lbl { display: none; }
4125
4274
 
4126
4275
  /* TreeNode */
4127
4276
  .ds-247420 .ds-tree-node {
4128
4277
  padding: 5px 10px; border-left: var(--bw-rule) solid var(--bg-3);
4129
4278
  margin: 2px 0 2px 16px; font-size: var(--fs-tiny);
4279
+ min-width: 0; overflow-wrap: anywhere;
4280
+ }
4281
+ @media (max-width: 400px) {
4282
+ .ds-247420 .ds-tree-node { margin-left: 8px; padding-left: 8px; }
4130
4283
  }
4131
4284
  .ds-247420 .ds-tree-node.is-phase { border-color: var(--accent); background: var(--bg-3); font-weight: 600; }
4132
4285
  .ds-247420 .ds-tree-node.is-deviation { border-color: var(--warn); background: var(--danger-surface); color: var(--warn); }
@@ -4141,17 +4294,26 @@
4141
4294
  /* BarRow */
4142
4295
  .ds-247420 .ds-bar-row { display: flex; align-items: center; gap: 8px; margin: 3px 0; font-size: var(--fs-tiny); }
4143
4296
  .ds-247420 .ds-bar-row-label { width: 100px; flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
4144
- .ds-247420 .ds-bar-bg { flex: 1; background: var(--bg-3); border-radius: 2px; height: 6px; overflow: hidden; }
4297
+ .ds-247420 .ds-bar-bg { flex: 1; min-width: 60px; background: var(--bg-3); border-radius: 2px; height: 6px; overflow: hidden; }
4145
4298
  .ds-247420 .ds-bar-fill { background: var(--accent); height: 100%; border-radius: 2px; }
4146
- .ds-247420 .ds-bar-row-value { flex-shrink: 0; color: var(--fg-2); }
4299
+ .ds-247420 .ds-bar-row-value { flex-shrink: 0; color: var(--fg-2); max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
4300
+ @media (max-width: 400px) {
4301
+ .ds-247420 .ds-bar-row-label { width: 72px; }
4302
+ }
4147
4303
 
4148
4304
  /* StatTile / StatsGrid */
4149
- .ds-247420 .ds-stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-2); }
4305
+ /* min(140px, 100%) keeps the grid from collapsing to 1 column early inside
4306
+ padded panels; the wrapper div stretches its tile to equal row height. */
4307
+ .ds-247420 .ds-stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); gap: var(--space-2); }
4308
+ .ds-247420 .ds-stats-grid > div { display: grid; }
4309
+ @media (max-width: 360px) {
4310
+ .ds-247420 .ds-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-1); }
4311
+ }
4150
4312
  .ds-247420 .ds-stats-grid-empty { padding: var(--space-3); color: var(--fg-3); font-size: var(--fs-tiny); }
4151
- .ds-247420 .ds-stat { background: var(--bg-3); border-radius: 4px; padding: 10px 12px; }
4152
- .ds-247420 .ds-stat-val { font-size: 22px; font-weight: 700; color: var(--accent-ink); }
4153
- .ds-247420 .ds-stat-val.rate-big { font-size: 32px; color: var(--success); }
4154
- .ds-247420 .ds-stat-val.err-rate { font-size: 32px; color: var(--warn); }
4313
+ .ds-247420 .ds-stat { min-width: 0; background: var(--bg-3); border-radius: 4px; padding: 10px 12px; }
4314
+ .ds-247420 .ds-stat-val { font-size: clamp(18px, 5cqi, 22px); font-weight: 700; color: var(--accent-ink); overflow-wrap: anywhere; }
4315
+ .ds-247420 .ds-stat-val.rate-big { font-size: clamp(24px, 7cqi, 32px); color: var(--success); }
4316
+ .ds-247420 .ds-stat-val.err-rate { font-size: clamp(24px, 7cqi, 32px); color: var(--warn); }
4155
4317
  .ds-247420 .ds-stat-lbl { font-size: var(--fs-micro); color: var(--fg-3); margin-top: 2px; }
4156
4318
 
4157
4319
  /* SubGrid */
@@ -4168,14 +4330,22 @@
4168
4330
  /* SessionRow */
4169
4331
  .ds-247420 .ds-session-row {
4170
4332
  display: flex; align-items: center; gap: 8px; padding: 6px 10px;
4333
+ flex-wrap: wrap; min-width: 0;
4171
4334
  border-bottom: var(--bw-hair) solid var(--bg-3); cursor: pointer;
4172
4335
  }
4173
4336
  .ds-247420 .ds-session-row:hover { background: var(--bg-3); }
4174
4337
  .ds-247420 .ds-session-row-id {
4175
4338
  font-family: var(--ff-mono); font-size: var(--fs-micro); color: var(--accent-ink);
4176
- width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
4339
+ flex: 0 1 160px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
4340
+ }
4341
+ .ds-247420 .ds-session-row-counts {
4342
+ font-size: var(--fs-micro); color: var(--fg-3);
4343
+ flex: 1 1 200px; min-width: 0;
4344
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
4345
+ }
4346
+ @media (max-width: 640px) {
4347
+ .ds-247420 .ds-session-row-span { flex-basis: 100%; }
4177
4348
  }
4178
- .ds-247420 .ds-session-row-counts { font-size: var(--fs-micro); color: var(--fg-3); width: 280px; }
4179
4349
  .ds-247420 .ds-session-row-devcnt { color: var(--warn); font-weight: 600; }
4180
4350
  .ds-247420 .ds-session-row-span { font-size: var(--fs-micro); color: var(--fg-3); }
4181
4351
 
@@ -4186,17 +4356,348 @@
4186
4356
  }
4187
4357
  .ds-247420 .ds-dev-row strong { color: var(--warn); }
4188
4358
 
4189
- /* LiveLog */
4359
+ /* LiveLog — natural height with a viewport-tracking cap (dvh follows mobile
4360
+ URL-bar chrome; min-height keeps short-landscape from going near-zero). */
4190
4361
  .ds-247420 .ds-live-log {
4191
- height: calc(100vh - 200px); overflow-y: auto;
4362
+ height: auto;
4363
+ max-height: calc(100vh - 200px);
4364
+ max-height: calc(100dvh - 200px);
4365
+ min-height: 160px;
4366
+ overflow-y: auto; overflow-x: hidden;
4192
4367
  font-family: var(--ff-mono); font-size: var(--fs-micro); line-height: 1.5;
4193
4368
  }
4194
- .ds-247420 .ds-live-log-empty { height: auto; padding: var(--space-3); color: var(--fg-3); }
4195
- .ds-247420 .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); }
4369
+ /* Embedded in a WM window the viewport calc is meaningless — fill the container. */
4370
+ .ds-247420 .fd-root .ds-live-log { height: 100%; max-height: none; min-height: 0; flex: 1 1 auto; }
4371
+ .ds-247420 .ds-live-log-empty { height: auto; min-height: 0; padding: var(--space-3); color: var(--fg-3); }
4372
+ .ds-247420 .ds-live-log-entry { padding: 2px 8px; border-bottom: var(--bw-hair) solid var(--bg-3); overflow-wrap: anywhere; }
4196
4373
  .ds-247420 .ds-live-log-entry:hover { background: var(--bg-3); }
4197
4374
  .ds-247420 .ds-live-log-ts { margin-right: 6px; color: var(--fg-3); }
4198
4375
  .ds-247420 .ds-live-log-subtag { margin-right: 6px; padding: 0 5px; border-radius: 2px; font-size: var(--fs-micro); }
4199
- .ds-247420 .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); }
4376
+ .ds-247420 .ds-live-log-preview { margin-left: 6px; color: var(--fg-3); word-break: break-word; }
4377
+
4378
+ /* Touch floors for the dense controls (not covered by the mobile width blocks). */
4379
+ @media (pointer: coarse) {
4380
+ .ds-247420 .ds-sub-btn { min-height: 44px; }
4381
+ .ds-247420 .ds-session-row { min-height: 44px; }
4382
+ .ds-247420 .ds-live-log-entry { padding-block: 6px; }
4383
+ }
4384
+
4385
+
4386
+ /* == appended: popovers-files == */
4387
+ /* FilePreviewMedia controls row — spacing + coarse-pointer tap floor */
4388
+ .ds-247420 .ds-preview-media-controls {
4389
+ display: flex;
4390
+ align-items: center;
4391
+ gap: var(--space-2);
4392
+ flex-wrap: wrap;
4393
+ }
4394
+ @media (hover: none), (pointer: coarse) {
4395
+ .ds-247420 .ds-preview-media-controls .chat-code-copy,
4396
+ .ds-247420 .chat-code-copy-head {
4397
+ min-height: 44px;
4398
+ min-width: 44px;
4399
+ }
4400
+ }
4401
+
4402
+ /* == appended: ui-kits == */
4403
+ /* ============================================================
4404
+ ui_kit responsive helpers (kits-grids sweep) */
4405
+ .ds-247420 .ds-section-pad { padding: clamp(6px, 1.2vw, 16px); }
4406
+ .ds-247420 .ds-panel-gap { margin: var(--space-2) 0; }
4407
+ .ds-247420 .ds-panel-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin: var(--space-2) 0; }
4408
+ @media (max-width: 760px) {
4409
+ .ds-247420 .ds-panel-duo { grid-template-columns: 1fr; }
4410
+ }
4411
+ /* wide dense rows/tables scroll inside their panel, never the page */
4412
+ .ds-247420 .ds-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
4413
+
4414
+ /* --- slide deck ------------------------------------------- */
4415
+ .ds-247420 .ds-deck-stage {
4416
+ aspect-ratio: 16 / 9;
4417
+ width: 100%;
4418
+ max-width: min(1100px, 100%);
4419
+ margin: var(--space-3) auto;
4420
+ background: var(--bg-2);
4421
+ border-radius: 18px;
4422
+ padding: clamp(16px, 5vw, 64px);
4423
+ box-sizing: border-box;
4424
+ display: flex;
4425
+ overflow: hidden;
4426
+ container-type: inline-size; /* cqw units track the stage, not the viewport */
4427
+ }
4428
+ @media (max-height: 500px) and (orientation: landscape) {
4429
+ .ds-247420 .ds-deck-stage {
4430
+ max-height: calc(100vh - 140px);
4431
+ max-height: calc(100dvh - 140px);
4432
+ aspect-ratio: auto;
4433
+ }
4434
+ }
4435
+ .ds-247420 .ds-deck-slide { flex: 1; display: flex; min-width: 0; }
4436
+ .ds-247420 .ds-deck-controls {
4437
+ display: flex; align-items: center; justify-content: center; gap: 14px;
4438
+ padding: 8px; font-family: var(--ff-mono); font-size: var(--fs-sm);
4439
+ }
4440
+ .ds-247420 .ds-deck-count { color: var(--fg-3); }
4441
+ @media (pointer: coarse) {
4442
+ .ds-247420 .ds-deck-controls .btn { min-height: 44px; min-width: 44px; }
4443
+ }
4444
+ .ds-247420 .ds-slide-eyebrow {
4445
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.1em;
4446
+ text-transform: uppercase; color: var(--fg-3); margin-bottom: clamp(12px, 2.5cqw, 24px);
4447
+ }
4448
+ .ds-247420 .ds-slide-col { display: flex; flex-direction: column; justify-content: center; gap: clamp(12px, 2.5cqw, 24px); min-width: 0; }
4449
+ .ds-247420 .ds-slide-col--start { align-items: flex-start; }
4450
+ .ds-247420 .ds-slide-col--narrow { max-width: 38ch; }
4451
+ .ds-247420 .ds-slide-col--quote { max-width: 42ch; }
4452
+ .ds-247420 .ds-slide-hero {
4453
+ font-size: clamp(var(--fs-h2), 6cqw, var(--fs-hero));
4454
+ line-height: var(--lh-tight); letter-spacing: var(--tr-tight); font-weight: 600;
4455
+ color: var(--slide-accent, var(--accent-ink));
4456
+ overflow-wrap: anywhere;
4457
+ }
4458
+ .ds-247420 .ds-slide-h1 {
4459
+ font-size: clamp(var(--fs-h3), 4.5cqw, var(--fs-h1));
4460
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 500; min-width: 0;
4461
+ }
4462
+ .ds-247420 .ds-slide-h1--lead { margin-bottom: 12px; }
4463
+ .ds-247420 .ds-slide-quote-body {
4464
+ font-size: clamp(var(--fs-lg), 3.5cqw, var(--fs-h2));
4465
+ line-height: var(--lh-snug); color: var(--fg); font-weight: 400; font-style: italic;
4466
+ }
4467
+ .ds-247420 .ds-slide-cite { font-family: var(--ff-mono); font-size: var(--fs-sm); color: var(--fg-3); }
4468
+ .ds-247420 .ds-slide-bullet {
4469
+ display: flex; gap: clamp(8px, 2vw, 18px); align-items: baseline;
4470
+ border-bottom: 1px solid var(--rule); padding: 12px 0; flex-wrap: wrap;
4471
+ }
4472
+ .ds-247420 .ds-slide-bullet-key {
4473
+ flex: 0 1 clamp(56px, 18%, 100px); min-width: 0;
4474
+ font-family: var(--ff-mono); font-size: var(--fs-sm);
4475
+ color: var(--slide-accent, var(--accent-ink));
4476
+ }
4477
+ .ds-247420 .ds-slide-bullet-val { color: var(--fg-2); font-size: var(--fs-lg); min-width: 0; }
4478
+ .ds-247420 .ds-slide-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(12px, 3vw, 32px); margin-top: 12px; }
4479
+ @media (max-width: 760px) {
4480
+ .ds-247420 .ds-slide-split { grid-template-columns: 1fr; }
4481
+ }
4482
+ .ds-247420 .ds-slide-split-cell {
4483
+ padding: 18px; background: var(--bg-2); border-radius: 14px;
4484
+ color: var(--fg-2); font-size: var(--fs-lg); line-height: var(--lh-base); min-width: 0;
4485
+ }
4486
+ .ds-247420 .ds-slide-split-cell--accent { border-left: 3px solid var(--slide-accent, var(--accent)); }
4487
+
4488
+ /* --- error 404 --------------------------------------------- */
4489
+ .ds-247420 .ds-err-hero {
4490
+ padding: clamp(16px, 5vw, 36px) clamp(12px, 4vw, 22px);
4491
+ text-align: center; display: flex; flex-direction: column; gap: 14px; align-items: center;
4492
+ }
4493
+ .ds-247420 .ds-err-numeral {
4494
+ font-family: var(--ff-mono); font-size: clamp(56px, 20vw, 120px);
4495
+ line-height: 1; color: var(--panel-text-3); letter-spacing: -0.03em;
4496
+ }
4497
+ .ds-247420 .ds-err-path {
4498
+ display: inline-flex; gap: 6px; align-items: baseline; flex-wrap: wrap; max-width: 100%;
4499
+ font-family: var(--ff-mono); font-size: 13px; color: var(--panel-text-2);
4500
+ background: var(--panel-1); padding: 6px 12px; border-radius: 8px;
4501
+ overflow-wrap: anywhere; word-break: break-all;
4502
+ }
4503
+
4504
+ /* --- gallery ------------------------------------------------ */
4505
+ .ds-247420 .ds-tile-grid {
4506
+ padding: clamp(8px, 2.5vw, 16px);
4507
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr)); gap: 8px;
4508
+ }
4509
+ .ds-247420 .ds-tile-grid--tight { grid-template-columns: repeat(auto-fill, minmax(min(140px, 100%), 1fr)); }
4510
+ .ds-247420 .ds-swatch-grid {
4511
+ padding: clamp(8px, 2.5vw, 16px);
4512
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); gap: 12px;
4513
+ }
4514
+ .ds-247420 .ds-gallery-tile {
4515
+ cursor: pointer; display: flex; flex-direction: column; gap: 6px;
4516
+ padding: 12px; border-radius: 10px; min-height: clamp(120px, 18vw, 160px);
4517
+ border: 0; text-align: left; font: inherit; color: inherit;
4518
+ background: var(--tile-tone, var(--panel-1));
4519
+ }
4520
+ .ds-247420 .ds-gallery-tile:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
4521
+ .ds-247420 .ds-gallery-tile--tight { min-height: clamp(96px, 14vw, 120px); }
4522
+ .ds-247420 .ds-lightbox {
4523
+ position: fixed; inset: 0; background: var(--scrim);
4524
+ display: flex; align-items: center; justify-content: center;
4525
+ padding: clamp(12px, 4vw, 32px);
4526
+ padding-bottom: max(clamp(12px, 4vw, 32px), env(safe-area-inset-bottom));
4527
+ z-index: 50;
4528
+ }
4529
+ .ds-247420 .ds-lightbox-card {
4530
+ background: var(--panel-0); border-radius: 14px; padding: clamp(16px, 4vw, 28px);
4531
+ width: min(520px, 100%); min-width: 0;
4532
+ max-height: calc(100vh - 24px);
4533
+ max-height: calc(100dvh - 24px);
4534
+ overflow: auto;
4535
+ display: flex; flex-direction: column; gap: 14px;
4536
+ }
4537
+ .ds-247420 .ds-lightbox-preview {
4538
+ padding: clamp(16px, 6vw, 36px); border-radius: 10px; text-align: center;
4539
+ font-family: var(--ff-mono); white-space: pre-line; font-size: clamp(16px, 5vw, 24px);
4540
+ background: var(--tile-tone, var(--panel-1));
4541
+ }
4542
+
4543
+ /* --- search ------------------------------------------------- */
4544
+ .ds-247420 .ds-topbar-search { width: min(280px, 100%); min-width: 0; flex: 1 1 clamp(140px, 30vw, 280px); }
4545
+ @media (max-width: 480px) {
4546
+ .ds-247420 .ds-topbar-search { flex-basis: 100%; }
4547
+ }
4548
+ .ds-247420 .ds-empty-state { padding: clamp(16px, 5vw, 24px); text-align: center; color: var(--panel-text-3); }
4549
+ .ds-247420 .ds-empty-state-glyph { font-size: clamp(24px, 6vw, 32px); }
4550
+ .ds-247420 .ds-empty-state-msg { margin: 6px 0; }
4551
+ .ds-247420 .ds-empty-state-hint { margin: 0; font-size: var(--fs-sm); }
4552
+
4553
+ /* --- system primer ------------------------------------------ */
4554
+ .ds-247420 .ds-swatch-grid-sm {
4555
+ display: grid; grid-template-columns: repeat(auto-fill, minmax(min(110px, 100%), 1fr));
4556
+ gap: 12px; padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px);
4557
+ }
4558
+ .ds-247420 .ds-swatch-grid-lg { grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); }
4559
+ .ds-247420 .ds-swatch-col { display: flex; flex-direction: column; gap: 6px; }
4560
+ .ds-247420 .ds-swatch-chip { height: 48px; border-radius: 10px; border: 1px solid var(--rule); background: var(--swatch, var(--panel-1)); }
4561
+ .ds-247420 .ds-swatch-chip--big { height: 64px; }
4562
+ .ds-247420 .ds-swatch-name { font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4563
+ .ds-247420 .ds-type-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 14px; }
4564
+ .ds-247420 .ds-type-row {
4565
+ display: flex; align-items: baseline; gap: 14px;
4566
+ border-bottom: 1px solid var(--rule); padding-bottom: 8px; flex-wrap: wrap;
4567
+ }
4568
+ .ds-247420 .ds-type-row-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4569
+ .ds-247420 .ds-type-sample {
4570
+ min-width: 0; overflow-wrap: anywhere; line-height: var(--lh-tight); color: var(--fg);
4571
+ font-size: var(--sample-size, var(--fs-body));
4572
+ }
4573
+ .ds-247420 .ds-prim-panel { padding: clamp(10px, 2.5vw, 14px) clamp(10px, 3vw, 18px); display: flex; flex-direction: column; gap: 18px; }
4574
+ .ds-247420 .ds-prim-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
4575
+ .ds-247420 .ds-prim-label { flex: 0 0 64px; font-family: var(--ff-mono); font-size: 11px; color: var(--fg-3); }
4576
+
4577
+ /* == appended: content-site == */
4578
+ /* Home landing wrappers (site/theme.mjs) — replace banned inline styles. */
4579
+ .ds-247420 .ds-home-hero-wrap { padding: 0 var(--space-2, 8px); }
4580
+ .ds-247420 .ds-home-panel { margin: var(--space-2, 8px); }
4581
+ @media (max-width: 480px) {
4582
+ .ds-247420 .ds-home-panel { margin: var(--space-1, 4px) 0; }
4583
+ }
4584
+ .ds-247420 .ds-quickstart {
4585
+ padding: var(--space-3, 16px) var(--space-4, 22px);
4586
+ display: flex;
4587
+ flex-direction: column;
4588
+ gap: 6px;
4589
+ }
4590
+ /* Table() scroll containment — wide tables scroll inside their own box,
4591
+ never the page body. */
4592
+ .ds-247420 .ds-table-wrap {
4593
+ overflow-x: auto;
4594
+ -webkit-overflow-scrolling: touch;
4595
+ max-width: 100%;
4596
+ }
4597
+ .ds-247420 .ds-table-wrap > table { min-width: 100%; }
4598
+
4599
+
4600
+ /* == appended: settings kit cleanup == */
4601
+ /* == appended: settings kit == */
4602
+ .ds-247420 .ds-settings-main { padding: 8px; }
4603
+ .ds-247420 .ds-settings-body { padding: 14px 18px; }
4604
+ .ds-247420 .ds-settings-body-stack { display: flex; flex-direction: column; gap: 10px; }
4605
+ .ds-247420 .ds-field-block { margin: 10px 0; }
4606
+ .ds-247420 .ds-field-eyebrow {
4607
+ font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em;
4608
+ text-transform: uppercase; color: var(--panel-text-3);
4609
+ }
4610
+ .ds-247420 .ds-hint-sm { font-size: 12px; color: var(--panel-text-2); }
4611
+ .ds-247420 .ds-note-quiet { margin: 0; color: var(--panel-text-2); }
4612
+ .ds-247420 .ds-btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
4613
+ .ds-247420 .ds-btn-row-tight { gap: 6px; }
4614
+ .ds-247420 .ds-key-input { flex: 1 1 160px; min-width: 0; font-family: var(--ff-mono); }
4615
+ .ds-247420 .ds-toggle-btn { min-width: 78px; }
4616
+ .ds-247420 .ds-toggle-label { margin-left: 8px; color: inherit; opacity: 0.7; }
4617
+ .ds-247420 .ds-btn-warn { color: var(--warn); }
4618
+ .ds-247420 .ds-btn-mascot { color: var(--mascot); }
4619
+ .ds-247420 .ds-savebar {
4620
+ position: sticky; bottom: 8px; display: flex; align-items: center;
4621
+ justify-content: flex-end; gap: 8px; flex-wrap: wrap; padding: 10px;
4622
+ background: var(--panel-2); border-radius: 10px; margin: 8px 0;
4623
+ }
4624
+ .ds-247420 .ds-savebar-note { flex: 1 1 160px; min-width: 0; color: var(--panel-text-2); }
4625
+ .ds-247420 .ds-settings-modal { min-width: min(320px, calc(100vw - 32px)); max-width: 480px; }
4626
+ .ds-247420 .ds-modal-body-form { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
4627
+ .ds-247420 .ds-modal-note { margin: 0 0 8px; color: var(--panel-text-2); font-size: 14px; }
4628
+ .ds-247420 .ds-draft-preview {
4629
+ background: var(--panel-1); padding: 12px; border-radius: 6px;
4630
+ font-size: 13px; color: var(--panel-text-2); max-height: 120px;
4631
+ overflow-y: auto; font-family: var(--ff-mono); overflow-wrap: anywhere;
4632
+ }
4633
+ .ds-247420 .ds-modal-actions { display: flex; gap: 8px; margin-top: 12px; justify-content: space-between; flex-wrap: wrap; }
4634
+
4635
+ /* == appended: signin kit cleanup == */
4636
+ /* -- signin kit (ui_kits/signin) -- */
4637
+ .ds-247420 .ds-auth-wrap { padding: var(--space-2, 8px); display: flex; flex-direction: column; align-items: center; }
4638
+ .ds-247420 .ds-auth-col { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 8px; margin: clamp(12px, 4vw, 24px) 0; min-width: 0; }
4639
+ .ds-247420 .ds-auth-form { padding: clamp(12px, 3vw, 18px); display: flex; flex-direction: column; gap: 10px; }
4640
+ .ds-247420 .ds-auth-sent { align-items: center; text-align: center; }
4641
+ .ds-247420 .ds-auth-sent-glyph { font-size: 32px; color: var(--panel-accent); }
4642
+ .ds-247420 .ds-auth-sent-title { margin: 0; font-weight: 600; }
4643
+ .ds-247420 .ds-auth-sent-sub { margin: 0; color: var(--panel-text-2); overflow-wrap: anywhere; }
4644
+ .ds-247420 .ds-auth-field { display: flex; flex-direction: column; gap: 4px; }
4645
+ .ds-247420 .ds-auth-field-label { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
4646
+ .ds-247420 .ds-auth-row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
4647
+ .ds-247420 .ds-auth-remember { display: flex; align-items: center; gap: 6px; cursor: pointer; }
4648
+ .ds-247420 .ds-auth-remember-text { color: var(--panel-text-2); font-size: 13px; }
4649
+ .ds-247420 .ds-auth-forgot { font-size: 13px; }
4650
+ .ds-247420 .ds-auth-error { padding: 8px 10px; background: var(--panel-1); border-radius: 8px; color: var(--danger); font-size: 13px; overflow-wrap: anywhere; }
4651
+ .ds-247420 .ds-auth-divider { display: flex; align-items: center; gap: 10px; margin: 6px 0; color: var(--panel-text-3); font-size: 12px; }
4652
+ .ds-247420 .ds-auth-divider-line { flex: 1; height: 1px; background: var(--panel-2); }
4653
+ .ds-247420 .ds-auth-providers { display: flex; gap: 8px; flex-wrap: wrap; }
4654
+ .ds-247420 .ds-auth-provider-btn { flex: 1 1 100px; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px; }
4655
+ .ds-247420 .ds-auth-provider-btn--loading { opacity: 0.7; pointer-events: none; }
4656
+ .ds-247420 .ds-auth-provider-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); display: inline-flex; }
4657
+ .ds-247420 .ds-auth-modes { display: flex; justify-content: center; gap: 14px; margin-top: 8px; font-size: 13px; flex-wrap: wrap; }
4658
+ .ds-247420 .ds-auth-mode-link { color: var(--panel-text-3); text-decoration: none; }
4659
+ .ds-247420 .ds-auth-mode-link--active { color: var(--panel-text); text-decoration: underline; }
4660
+ .ds-247420 .ds-auth-fineprint { text-align: center; font-size: 12px; color: var(--panel-text-3); margin: 6px 0; }
4661
+
4662
+ /* == appended: gallery-misc kit cleanup == */
4663
+ /* --- shared helpers (converted from inline styles) --- */
4664
+ .ds-247420 .ds-m0 { margin: 0; }
4665
+ .ds-247420 .ds-text-2 { color: var(--panel-text-2); }
4666
+ .ds-247420 .ds-text-3 { color: var(--panel-text-3); }
4667
+ .ds-247420 .ds-kit-head { display: flex; align-items: center; justify-content: space-between; gap: clamp(8px, 2vw, 16px); flex-wrap: wrap; }
4668
+
4669
+ /* --- gallery kit --- */
4670
+ .ds-247420 .ds-tile-cap { flex: 1; display: flex; align-items: center; justify-content: center; font-family: var(--ff-mono); white-space: pre-line; color: var(--panel-text-2); font-size: 18px; min-width: 0; text-align: center; }
4671
+ .ds-247420 .ds-tile-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; flex-wrap: wrap; min-width: 0; }
4672
+ .ds-247420 .ds-tile-glyph { font-family: var(--ff-mono); color: var(--panel-text-3); }
4673
+ .ds-247420 .ds-tile-label { color: var(--panel-text); overflow-wrap: anywhere; }
4674
+ .ds-247420 .ds-gal-swatch { height: 64px; border-radius: 8px; background: var(--swatch, var(--panel-1)); }
4675
+ .ds-247420 .ds-gal-swatch-meta { display: flex; justify-content: space-between; gap: 6px; flex-wrap: wrap; font-family: var(--ff-mono); font-size: 11px; min-width: 0; }
4676
+ .ds-247420 .ds-gal-swatch-name { color: var(--panel-text); }
4677
+ .ds-247420 .ds-gal-swatch-hint { color: var(--panel-text-3); overflow-wrap: anywhere; }
4678
+ .ds-247420 .ds-lightbox-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
4679
+ .ds-247420 .ds-lightbox-tag { font-family: var(--ff-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--panel-text-3); }
4680
+
4681
+ /* --- error_404 kit --- */
4682
+ .ds-247420 .ds-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
4683
+ .ds-247420 .ds-err-chips { display: flex; gap: 6px; flex-wrap: wrap; justify-content: center; margin-top: 4px; }
4684
+
4685
+ /* == appended: terminal-capp kit cleanup == */
4686
+ /* --- terminal kit ------------------------------------------ */
4687
+ .ds-247420 .ds-section-pad-sm { padding: 8px; }
4688
+ .ds-247420 .ds-kit-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
4689
+ .ds-247420 .ds-cli-cmt .cmd { color: var(--fg-3); }
4690
+ .ds-247420 .ds-cli-out .cmd { color: var(--fg-2); }
4691
+ .ds-247420 .ds-cli-ok .prompt, .ds-247420 .ds-cli-ok .cmd { color: var(--accent-ink); }
4692
+ .ds-247420 .ds-cli-warn .prompt, .ds-247420 .ds-cli-warn .cmd { color: var(--mascot); }
4693
+ .ds-247420 .ds-cli-log .prompt { color: var(--fg-3); }
4694
+ .ds-247420 .ds-cli-log .cmd { color: var(--fg-2); font-family: var(--ff-mono); }
4695
+ .ds-247420 .ds-term-body { padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; background: var(--bg-2); border-radius: 10px; }
4696
+ .ds-247420 .ds-term-body--tall { min-height: 280px; }
4697
+ .ds-247420 .ds-term-input-row { margin-top: 6px; }
4698
+ .ds-247420 .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); }
4699
+ /* full-viewport render root (community-app) */
4700
+ .ds-247420 .ds-root-viewport { height: 100vh; height: 100dvh; }
4200
4701
 
4201
4702
  /* community.css */
4202
4703
  /* ============================================================
@@ -4211,8 +4712,13 @@
4211
4712
  .ds-247420 .cm-shell {
4212
4713
  display: flex;
4213
4714
  height: 100vh;
4715
+ height: 100dvh;
4214
4716
  width: 100%;
4215
4717
  overflow: hidden;
4718
+ /* Notched devices: keep the rail and bottom chrome out of the unsafe zones. */
4719
+ padding-bottom: env(safe-area-inset-bottom);
4720
+ padding-left: env(safe-area-inset-left);
4721
+ padding-right: env(safe-area-inset-right);
4216
4722
  background: var(--bg);
4217
4723
  color: var(--fg);
4218
4724
  font-family: var(--ff-body);
@@ -4999,7 +5505,7 @@
4999
5505
  scrollbar-width: thin;
5000
5506
  scrollbar-color: color-mix(in oklab, var(--fg) 18%, transparent) transparent;
5001
5507
  transition: width var(--dur-base) var(--ease), flex-basis var(--dur-base) var(--ease);
5002
- will-change: width, flex-basis, opacity, transform; contain: layout style;
5508
+ contain: layout style;
5003
5509
  }
5004
5510
  .ds-247420 .cm-member-list:not(.open) {
5005
5511
  width: 0;
@@ -5144,7 +5650,7 @@
5144
5650
  /* ============================================================
5145
5651
  Responsive — collapse sidebars on narrow viewports
5146
5652
  ============================================================ */
5147
- @media (max-width: 768px) {
5653
+ @media (max-width: 900px) {
5148
5654
  .ds-247420 .cm-channel-sidebar {
5149
5655
  position: absolute;
5150
5656
  z-index: 20;
@@ -5171,6 +5677,21 @@
5171
5677
  .ds-247420 .cm-chat-header-topic { display: none; }
5172
5678
  }
5173
5679
 
5680
+ /* Drawer scrim — dims the chat while a drawer overlays it on narrow screens.
5681
+ Visual affordance only (pointer-events: none): tap-to-close needs a real
5682
+ element + handler in CommunityShell, which lives outside this stylesheet. */
5683
+ @media (max-width: 900px) {
5684
+ .ds-247420 .cm-shell:has(.cm-channel-sidebar.open) .cm-main::before,
5685
+ .ds-247420 .cm-shell:has(.cm-member-list.open) .cm-main::before {
5686
+ content: '';
5687
+ position: absolute;
5688
+ inset: 0;
5689
+ z-index: 15;
5690
+ background: color-mix(in oklab, var(--ink) 40%, transparent);
5691
+ pointer-events: none;
5692
+ }
5693
+ }
5694
+
5174
5695
  @media (max-width: 480px) {
5175
5696
  .ds-247420 .cm-server-rail {
5176
5697
  flex: 0 0 56px;
@@ -5183,22 +5704,12 @@
5183
5704
  height: 44px;
5184
5705
  padding: 4px;
5185
5706
  }
5186
- .ds-247420 .cm-channel-sidebar {
5187
- left: 56px;
5188
- width: 80vw;
5189
- max-width: 200px;
5190
- }
5707
+ .ds-247420 .cm-channel-sidebar,
5191
5708
  .ds-247420 .cm-channel-sidebar.open {
5709
+ left: 56px;
5192
5710
  width: 80vw;
5193
- max-width: 200px;
5194
- }
5195
-
5196
- /* Mobile touch target fixes for icon buttons */
5197
- .ds-247420 .cm-cat-add,
5198
- .ds-247420 .cm-ch-action-btn {
5199
- width: 44px;
5200
- height: 44px;
5201
- padding: 8px;
5711
+ /* Use the width beside the 56px rail, not a 200px sliver. */
5712
+ max-width: min(320px, calc(100vw - 56px));
5202
5713
  }
5203
5714
  .ds-247420 .cm-ch-icon {
5204
5715
  flex: 0 0 24px;
@@ -5207,6 +5718,44 @@
5207
5718
  }
5208
5719
  }
5209
5720
 
5721
+ /* Touch target floors — applies on any coarse-pointer device (phones AND
5722
+ touch tablets/laptops), not just narrow viewports. */
5723
+ @media (pointer: coarse) {
5724
+ .ds-247420 .cm-channel-item,
5725
+ .ds-247420 .cm-member-item { min-height: 44px; }
5726
+ .ds-247420 .cm-cat-add,
5727
+ .ds-247420 .cm-ch-action-btn,
5728
+ .ds-247420 .cm-user-btn,
5729
+ .ds-247420 .cm-vs-btn,
5730
+ .ds-247420 .cm-tp-new,
5731
+ .ds-247420 .cm-tp-close,
5732
+ .ds-247420 .cm-rb-cancel,
5733
+ .ds-247420 .cm-mh-btn {
5734
+ min-width: 44px;
5735
+ min-height: 44px;
5736
+ }
5737
+ .ds-247420 .cm-forum-search,
5738
+ .ds-247420 .cm-forum-sort,
5739
+ .ds-247420 .cm-forum-new { min-height: 44px; }
5740
+ }
5741
+
5742
+ /* Ultrawide: clamp the message/forum/page column to a readable measure. */
5743
+ @media (min-width: 1600px) {
5744
+ .ds-247420 .cm-main > .chat,
5745
+ .ds-247420 .cm-forum-list,
5746
+ .ds-247420 .cm-page-body {
5747
+ max-width: 110ch;
5748
+ margin-inline: auto;
5749
+ width: 100%;
5750
+ }
5751
+ }
5752
+
5753
+ /* No hover on touch: hover-revealed channel actions must stay reachable. */
5754
+ @media (hover: none) {
5755
+ .ds-247420 .cm-channel-item .cm-ch-actions { opacity: 0.6; }
5756
+ .ds-247420 .cm-category-header .cm-cat-add { opacity: 0.6; }
5757
+ }
5758
+
5210
5759
  /* ---------- a11y polish: focus-visible coverage on community interactive elements ---------- */
5211
5760
  /* Every interactive surface with a :hover state must also have a :focus-visible state so
5212
5761
  keyboard users get equivalent feedback. The selectors here mirror the existing :hover rules. */
@@ -5259,8 +5808,8 @@
5259
5808
  display: flex;
5260
5809
  align-items: center;
5261
5810
  gap: var(--space-2);
5262
- height: 48px;
5263
- padding: 0 var(--space-2);
5811
+ height: calc(48px + env(safe-area-inset-top));
5812
+ padding: env(safe-area-inset-top) max(var(--space-2), env(safe-area-inset-right)) 0 max(var(--space-2), env(safe-area-inset-left));
5264
5813
  background: var(--bg-2);
5265
5814
  border-bottom: 1px solid var(--panel-3);
5266
5815
  }
@@ -5535,6 +6084,7 @@
5535
6084
  .ds-247420 .vx-modal {
5536
6085
  width: 100%; max-width: 440px;
5537
6086
  max-height: 90vh;
6087
+ max-height: 90dvh;
5538
6088
  display: flex; flex-direction: column;
5539
6089
  border-radius: var(--r-3);
5540
6090
  background: var(--bg);
@@ -5660,10 +6210,21 @@
5660
6210
  /* ThreadPanel — cm-thread-panel / cm-tp-* */
5661
6211
  .ds-247420 .cm-thread-panel {
5662
6212
  display: flex; flex-direction: column;
6213
+ flex: 0 0 300px; width: 300px; min-width: 0;
5663
6214
  height: 100%; min-height: 0;
5664
6215
  background: var(--bg-2); color: var(--fg);
5665
6216
  border-left: var(--bw-hair) solid var(--rule);
5666
6217
  }
6218
+ @media (max-width: 900px) {
6219
+ .ds-247420 .cm-thread-panel {
6220
+ position: absolute;
6221
+ z-index: 20;
6222
+ top: 0; right: 0; bottom: 0;
6223
+ height: auto;
6224
+ width: min(320px, 90vw);
6225
+ box-shadow: -2px 0 16px color-mix(in oklab, var(--ink) 30%, transparent);
6226
+ }
6227
+ }
5667
6228
  .ds-247420 .cm-tp-head {
5668
6229
  display: flex; align-items: center; justify-content: space-between;
5669
6230
  padding: var(--space-2); border-bottom: var(--bw-hair) solid var(--rule);
@@ -5677,6 +6238,7 @@
5677
6238
  .ds-247420 .cm-tp-new:hover, .ds-247420 .cm-tp-close:hover { background: var(--bg-3); color: var(--fg); }
5678
6239
  .ds-247420 .cm-tp-list { flex: 1; min-height: 0; overflow-y: auto; }
5679
6240
  .ds-247420 .cm-tp-item {
6241
+ position: relative; /* anchors .cm-tp-dot to the row, not the panel */
5680
6242
  display: flex; flex-direction: column; gap: 2px;
5681
6243
  width: 100%; text-align: left; cursor: pointer;
5682
6244
  padding: var(--space-2); border: none; background: transparent;
@@ -5686,7 +6248,7 @@
5686
6248
  .ds-247420 .cm-tp-item:hover { background: var(--bg-3); }
5687
6249
  .ds-247420 .cm-tp-item.is-active { background: var(--bg-3); box-shadow: inset 3px 0 0 var(--accent); }
5688
6250
  .ds-247420 .cm-tp-item.is-unread .cm-tp-item-title { font-weight: 700; }
5689
- .ds-247420 .cm-tp-dot { position: absolute; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
6251
+ .ds-247420 .cm-tp-dot { position: absolute; left: 4px; top: 50%; transform: translateY(-50%); width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
5690
6252
  .ds-247420 .cm-tp-item-title { font-size: var(--fs-1, 14px); }
5691
6253
  .ds-247420 .cm-tp-item-snippet { font-size: var(--fs-0, 12px); color: var(--fg-2, var(--fg)); opacity: .8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
5692
6254
  .ds-247420 .cm-tp-item-meta { display: flex; gap: var(--space-2); font-size: var(--fs-micro, 11px); color: var(--fg-2, var(--fg)); opacity: .7; }
@@ -5694,7 +6256,7 @@
5694
6256
 
5695
6257
  /* ForumView — cm-forum / cm-forum-* */
5696
6258
  .ds-247420 .cm-forum { display: flex; flex-direction: column; height: 100%; min-height: 0; background: var(--bg-1, var(--bg-2)); color: var(--fg); }
5697
- .ds-247420 .cm-forum-toolbar { display: flex; gap: var(--space-2); align-items: center; padding: var(--space-2); border-bottom: var(--bw-hair) solid var(--rule); }
6259
+ .ds-247420 .cm-forum-toolbar { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; padding: var(--space-2); border-bottom: var(--bw-hair) solid var(--rule); }
5698
6260
  .ds-247420 .cm-forum-search { flex: 1; padding: var(--space-1) var(--space-2); border: var(--bw-hair) solid var(--rule-strong); border-radius: var(--r-1); background: var(--bg-3); color: var(--fg); }
5699
6261
  .ds-247420 .cm-forum-sort { padding: var(--space-1); border: var(--bw-hair) solid var(--rule-strong); border-radius: var(--r-1); background: var(--bg-3); color: var(--fg); }
5700
6262
  .ds-247420 .cm-forum-new { padding: var(--space-1) var(--space-2); border: none; border-radius: var(--r-1); background: var(--accent); color: var(--accent-fg); cursor: pointer; }
@@ -6611,6 +7173,9 @@
6611
7173
  neutral pill and from the accent-toned running pill (--success = green-2). */
6612
7174
  .ds-247420 .chat-msg .chat-tool.tool-done .chat-tool-status { color: var(--success); background: color-mix(in oklab, var(--success) 12%, transparent); }
6613
7175
  .ds-247420 .chat-tool-body { border-top: var(--bw-hair) solid var(--rule); padding: var(--space-2) var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
7176
+ /* details' intrinsic min-content sizing: an unbroken token in the pre must not
7177
+ widen the tool card past the bubble column. */
7178
+ .ds-247420 .chat-msg .chat-tool, .ds-247420 .chat-tool-body, .ds-247420 .chat-tool-section { min-width: 0; max-width: 100%; }
6614
7179
  .ds-247420 .chat-tool-section { display: flex; flex-direction: column; gap: var(--space-1); }
6615
7180
  .ds-247420 .chat-tool-section-label { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); font-size: var(--fs-tiny); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tr-caps); color: var(--fg-3); }
6616
7181
  .ds-247420 .chat-tool-copy { position: static; opacity: 0; }
@@ -7161,6 +7726,11 @@
7161
7726
  .ds-247420 .ds-ep-ctxmenu {
7162
7727
  position: absolute;
7163
7728
  min-width: 180px;
7729
+ max-width: calc(100vw - 8px);
7730
+ max-height: calc(100vh - 8px);
7731
+ max-height: calc(100dvh - 8px);
7732
+ overflow-y: auto;
7733
+ overscroll-behavior: contain;
7164
7734
  background: var(--panel-1, var(--panel-bg));
7165
7735
  color: var(--panel-text, var(--fg-text));
7166
7736
  border: 1px solid var(--rule);
@@ -7209,7 +7779,7 @@
7209
7779
  }
7210
7780
  .ds-247420 .ds-ep-drawer.side-left { left: 0; top: 0; bottom: 0; width: 86vw; max-width: 320px; }
7211
7781
  .ds-247420 .ds-ep-drawer.side-right { right: 0; top: 0; bottom: 0; width: 86vw; max-width: 320px; }
7212
- .ds-247420 .ds-ep-drawer.side-bottom { left: 0; right: 0; bottom: 0; max-height: 80vh; border-top-left-radius: 12px; border-top-right-radius: 12px; }
7782
+ .ds-247420 .ds-ep-drawer.side-bottom { left: 0; right: 0; bottom: 0; max-height: 80vh; max-height: 80dvh; border-top-left-radius: 12px; border-top-right-radius: 12px; }
7213
7783
  @media (min-width: 768px) {
7214
7784
  .ds-247420 .ds-ep-drawer.side-left, .ds-247420 .ds-ep-drawer.side-right { width: 360px; max-width: 360px; }
7215
7785
  }
@@ -7221,7 +7791,7 @@
7221
7791
  position: fixed; inset: 0; z-index: 9500;
7222
7792
  background: var(--scrim-strong);
7223
7793
  display: flex; align-items: center; justify-content: center;
7224
- padding: 16px;
7794
+ padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
7225
7795
  }
7226
7796
  .ds-247420 .ds-ep-dialog {
7227
7797
  background: var(--panel-1, var(--panel-bg));
@@ -7230,7 +7800,9 @@
7230
7800
  border-radius: var(--r-2, 10px);
7231
7801
  box-shadow: var(--shadow-overlay);
7232
7802
  min-width: 280px; max-width: min(560px, 100%);
7233
- max-height: 90vh; overflow: auto;
7803
+ max-height: 90vh;
7804
+ max-height: min(90dvh, calc(100dvh - 32px));
7805
+ overflow: auto;
7234
7806
  display: flex; flex-direction: column;
7235
7807
  outline: none;
7236
7808
  }
@@ -7506,6 +8078,11 @@
7506
8078
  padding: 0;
7507
8079
  outline: none;
7508
8080
  min-width: 160px;
8081
+ max-width: calc(100vw - 8px);
8082
+ max-height: calc(100vh - 8px);
8083
+ max-height: calc(100dvh - 8px);
8084
+ overflow-y: auto;
8085
+ overscroll-behavior: contain;
7509
8086
  }
7510
8087
  @media (prefers-reduced-motion: no-preference) {
7511
8088
  .ds-247420 .ds-popover { transition: opacity 140ms ease, transform 140ms ease; }
@@ -7979,6 +8556,7 @@
7979
8556
  display: flex;
7980
8557
  flex-direction: column;
7981
8558
  height: 100vh;
8559
+ height: 100dvh;
7982
8560
  min-height: 0;
7983
8561
  overflow: hidden;
7984
8562
  }
@@ -8304,6 +8882,11 @@
8304
8882
  .ds-247420 .app, .ds-247420 .app-main, .ds-247420 .panel, .ds-247420 .chat, .ds-247420 .chat-thread {
8305
8883
  background: var(--paper) !important; color: var(--ink) !important; box-shadow: none !important;
8306
8884
  }
8885
+ /* Community surface: unclamp the fixed-height shell and hide the chrome so a
8886
+ transcript prints as flowing pages instead of one clipped viewport. */
8887
+ .ds-247420 .cm-shell { height: auto; overflow: visible; display: block; }
8888
+ .ds-247420 .cm-server-rail, .ds-247420 .cm-channel-sidebar, .ds-247420 .cm-member-list, .ds-247420 .cm-mobile-header, .ds-247420 .cm-voice-strip { display: none !important; }
8889
+ .ds-247420 .cm-main, .ds-247420 .cm-channel-list { overflow: visible; height: auto; }
8307
8890
  }
8308
8891
 
8309
8892
  /* gm-prose.css */
@@ -8355,6 +8938,7 @@
8355
8938
  top: 24px;
8356
8939
  align-self: start;
8357
8940
  max-height: calc(100vh - 48px);
8941
+ max-height: calc(100dvh - 48px);
8358
8942
  overflow-y: auto;
8359
8943
  overscroll-behavior: contain;
8360
8944
  margin: 0;
@@ -8621,8 +9205,9 @@
8621
9205
  }
8622
9206
  .ds-247420 .sp-hud-ammo {
8623
9207
  position: fixed;
8624
- bottom: 50px;
8625
- right: 20px;
9208
+ /* Fixed chrome clears notch/home-indicator on cutout devices. */
9209
+ bottom: calc(50px + env(safe-area-inset-bottom, 0px));
9210
+ right: calc(20px + env(safe-area-inset-right, 0px));
8626
9211
  font-size: 24px;
8627
9212
  font-weight: bold;
8628
9213
  color: var(--fg);
@@ -8631,7 +9216,7 @@
8631
9216
  .ds-247420 .sp-hud-ammo-reloading { color: var(--warn); }
8632
9217
  .ds-247420 .sp-hud-health {
8633
9218
  position: fixed;
8634
- bottom: 20px;
9219
+ bottom: calc(20px + env(safe-area-inset-bottom, 0px));
8635
9220
  left: 50%;
8636
9221
  transform: translateX(-50%);
8637
9222
  width: 200px;
@@ -8658,7 +9243,7 @@
8658
9243
  .ds-247420 .sp-hud-boost {
8659
9244
  position: fixed;
8660
9245
  top: 80px;
8661
- right: 20px;
9246
+ right: calc(20px + env(safe-area-inset-right, 0px));
8662
9247
  padding: 8px 16px;
8663
9248
  background: var(--accent);
8664
9249
  color: var(--accent-fg);
@@ -8691,6 +9276,11 @@
8691
9276
  border: 1px solid var(--bw-rule, var(--rule));
8692
9277
  border-radius: var(--r-2, 10px);
8693
9278
  color: var(--fg);
9279
+ /* Short landscape phones: keep lower controls reachable inside the card. */
9280
+ max-height: calc(100vh - 32px);
9281
+ max-height: calc(100dvh - 32px);
9282
+ overflow-y: auto;
9283
+ overscroll-behavior: contain;
8694
9284
  }
8695
9285
  .ds-247420 .sp-lobby-title {
8696
9286
  margin: 0;