/* Monolith Studio - app CSS extracted from studio.html <style> (shared by studio.html + builder.html). */
  /* ── Monolith docs-match theme (approved proposal v3.13) ──
     slate ladder + desaturated purple family from the LIVE docs site (sidebar-nav.css);
     purple marks interactive things only - headers are muted gray; one filled primary per surface. */
  /* design tokens (:root) now live in core/tokens.css - linked in <head> (ARCHITECTURE_PLAN.md Phase 1). Edit colors there. */
  *{ box-sizing:border-box; }
  html,body{ margin:0; height:100%; overflow:hidden; background:var(--bg); color:var(--txt); font:13px/1.5 Roboto,system-ui,-apple-system,"Segoe UI",Helvetica,Arial,sans-serif; }
  #c{ width:max(1px, calc(100% - var(--studio-viewport-right-inset, 0px))); height:max(1px, calc(100% - var(--studio-viewport-bottom-inset, 0px))); touch-action:none; }   /* the render viewport stops before docked authoring surfaces; OrbitControls still own touch gestures */
  .lockup{ color:var(--primary-hi); font-weight:700; letter-spacing:.11em; }
  :root{ --studio-menu-h:26px; --timeline-h:284px; --timeline-float-gap:16px; --timeline-inspector-w:380px; }
  .app{ display:flex; height:calc(100dvh - var(--studio-menu-h)); height:calc(var(--app-h, 100dvh) - var(--studio-menu-h)); }   /* track the VISIBLE viewport (JS sets --app-h from visualViewport; dvh is the CSS fallback) so bottom-anchored UI lands at the visible bottom, not the address-bar-hidden 100vh bottom */
  #studioMenuBar{ height:var(--studio-menu-h); display:block; background:#2f2f2f; color:var(--txt); border-bottom:1px solid #111; user-select:none; -webkit-user-select:none; }
  .studio-menuline{ height:26px; display:flex; align-items:center; gap:0; padding:0 7px; background:#2f2f2f; }
  .studio-menu{ position:relative; height:100%; display:inline-flex; align-items:stretch; }
  .studio-menu-btn{ height:100%; padding:0 8px; border:0; border-radius:0; background:transparent; color:var(--txt); font:inherit; font-size:12px; cursor:default; }
  .studio-menu:hover .studio-menu-btn, .studio-menu.open .studio-menu-btn, .studio-menu-btn:focus-visible{ outline:none; background:rgba(169,133,221,.16); color:var(--link); }
  .studio-menu-btn:disabled{ color:var(--low); }
  .studio-menu:hover .studio-menu-btn:disabled{ background:transparent; color:var(--low); }
  .studio-menu-pop{ display:none; position:absolute; top:100%; left:0; min-width:268px; z-index:var(--z-dropdown); padding:5px; background:#1b1b1b; border:1px solid rgba(255,255,255,.14); box-shadow:0 4px 8px rgba(0,0,0,.32); }
  .studio-menu.open .studio-menu-pop{ display:flex; flex-direction:column; }
  .studio-menu-pop button{ width:100%; text-align:left; border:0; border-radius:4px; background:transparent; color:var(--txt); font:inherit; font-size:12px; padding:6px 9px; cursor:default; }
  .studio-menu-pop .studio-menu-item{ display:grid; grid-template-columns:16px minmax(0,1fr) minmax(28px,auto); align-items:center; gap:8px; }
  .studio-menu-pop .studio-menu-label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .studio-menu-pop .studio-menu-check{ color:var(--link); font:700 11px/1 var(--mono); text-align:center; min-height:1em; }
  .studio-menu-pop .studio-menu-kbd{ min-width:28px; min-height:14px; justify-self:end; padding:1px 4px; border:1px solid rgba(255,255,255,.12); border-radius:3px; background:rgba(255,255,255,.04); color:var(--muted); font:600 10px/1.2 var(--mono); text-align:center; }
  .studio-menu-pop .studio-menu-shortcut-spacer{ width:28px; min-height:14px; justify-self:end; }
  .studio-menu-pop .studio-menu-sep{ display:block; height:1px; margin:5px 4px; background:var(--line); }
  .studio-menu-pop button:hover, .studio-menu-pop button:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
  .studio-menu-pop button.danger{ color:#e8a09a; }
  .studio-menu-pop button.danger:hover, .studio-menu-pop button.danger:focus-visible{ color:#fff; background:var(--bad-press); }
  .studio-menu-fill{ flex:1 1 auto; min-width:12px; }
  .studio-menu-brand{ flex:0 0 auto; display:inline-flex; align-items:center; gap:6px; min-width:0; height:100%; padding:0 5px 0 10px; color:var(--muted); font-size:12px; white-space:nowrap; }
  .commandPaletteDlg{ width:min(720px, calc(100vw - 52px)); }
  .command-palette{ display:flex; flex-direction:column; gap:9px; }
  .command-palette-input{ width:100%; box-sizing:border-box; border:1px solid var(--line); border-radius:4px; background:rgba(28,28,28,.95); color:var(--txt); font:500 14px/1.3 Roboto,system-ui,sans-serif; padding:9px 10px; outline:none; }
  .command-palette-input:focus{ border-color:rgba(169,133,221,.42); box-shadow:0 0 0 2px rgba(169,133,221,.12); }
  .command-palette-hint{ display:flex; justify-content:space-between; gap:12px; color:var(--low); font-size:11px; line-height:1.3; }
  .command-palette-mode{ color:var(--link); font-weight:700; }
  .command-palette-list{ max-height:min(520px, 58vh); overflow:auto; border:1px solid var(--line); border-radius:8px; background:rgba(20,20,20,.58); padding:4px; }   /* scrollbar treatment comes from the shared scroll group above */
  .command-palette-row{ width:100%; min-height:42px; display:grid; grid-template-columns:70px minmax(0,1fr) minmax(34px,auto); align-items:center; gap:10px; border:0; border-radius:4px; background:transparent; color:var(--txt); padding:7px 8px; text-align:left; font:inherit; cursor:default; }
  .command-palette-row.on, .command-palette-row:hover, .command-palette-row:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
  .command-palette-kind{ color:var(--muted); text-transform:uppercase; letter-spacing:.04em; font:700 10px/1.2 Roboto,system-ui,sans-serif; }
  .command-palette-copy{ min-width:0; display:flex; flex-direction:column; gap:2px; }
  .command-palette-copy b{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; line-height:1.25; }
  .command-palette-copy small{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font-size:11px; line-height:1.2; }
  .command-palette-row kbd{ min-width:28px; min-height:14px; justify-self:end; padding:1px 4px; border:1px solid rgba(255,255,255,.12); border-radius:3px; background:rgba(255,255,255,.04); color:var(--muted); font:600 10px/1.2 var(--mono); text-align:center; }
  .command-palette-shortcut-spacer{ width:28px; min-height:14px; justify-self:end; }
  .command-palette-empty{ padding:24px 12px; color:var(--muted); text-align:center; font-size:12px; }
  .studio-import-watch{ height:20px; max-width:260px; min-width:0; margin-left:6px; padding:0 8px; border:1px solid rgba(255,255,255,.08); border-radius:4px; background:rgba(27,27,27,.42); color:rgba(255,255,255,.42); font:600 11px/18px var(--mono); letter-spacing:.02em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; cursor:default; transition:color .14s,border-color .14s,background .14s,opacity .14s; }
  .studio-import-watch::before{ content:""; display:inline-block; width:6px; height:6px; margin-right:6px; border-radius:50%; background:currentColor; vertical-align:1px; opacity:.75; }
  .studio-import-watch.is-landing{ color:var(--muted); border-color:rgba(255,255,255,.12); background:rgba(27,27,27,.58); }
  .studio-import-watch.is-ready{ color:var(--link); border-color:rgba(169,133,221,.38); background:rgba(116,80,182,.16); cursor:pointer; }
  .studio-import-watch.is-reloading{ color:var(--link); border-color:rgba(169,133,221,.28); background:rgba(116,80,182,.12); }
  .studio-agent-lease{ height:20px; max-width:300px; min-width:0; margin-left:6px; padding:0 8px; border:1px solid rgba(169,133,221,.38); border-radius:4px; background:rgba(116,80,182,.16); color:var(--link); font:650 11px/18px var(--mono); letter-spacing:.02em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .studio-agent-lease::before{ content:""; display:inline-block; width:6px; height:6px; margin-right:6px; border-radius:50%; background:currentColor; vertical-align:1px; }
  .studio-agent-lease[hidden]{ display:none; }
  .studio-agent-edit-shield{ position:fixed; inset:var(--studio-menu-h) 0 0; z-index:9998; background:transparent; cursor:progress; }
  .studio-agent-edit-shield[hidden]{ display:none; }
  body.studio-agent-editing .studio-menu, body.studio-agent-editing #autoload{ pointer-events:none; opacity:.5; }
  .err-banner{ position:fixed; left:50%; top:14px; transform:translateX(-50%); z-index:9999; max-width:min(560px,calc(100% - 28px)); display:flex; gap:10px; align-items:flex-start; background:rgba(40,28,28,.94); border:1px solid var(--bad-rest); border-radius:8px; padding:10px 12px; box-shadow:var(--elev); backdrop-filter:blur(6px); font:13px Roboto,system-ui,sans-serif; color:#fff; }
  .err-dismiss{ flex:0 0 auto; padding:3px 9px; border:1px solid var(--bad-rest); border-radius:4px; background:transparent; color:var(--bad-rest); cursor:pointer; font:inherit; }
  .fatal-page{ position:fixed; inset:0; display:flex; align-items:center; justify-content:center; padding:32px; text-align:center; font:15px Roboto,system-ui,sans-serif; color:#fff; background:var(--bg); }
  .fatal-page-box{ max-width:460px; }
  .fatal-page-title{ font-weight:700; font-size:17px; margin-bottom:10px; }
  .ui-scroll, .side, .ordrop-menu, #buildPanel, #projPanel, #delivPanel, #guidePanel, #treeGridWrap, .cfg-selector, .studioToolDlg .studio-tool-mount, .command-palette-list, .material-library-list { scrollbar-gutter:stable; scrollbar-width:thin; scrollbar-color:rgba(176,176,184,.46) transparent; }
  .ui-scroll::-webkit-scrollbar, .side::-webkit-scrollbar, .ordrop-menu::-webkit-scrollbar, #buildPanel::-webkit-scrollbar, #projPanel::-webkit-scrollbar, #delivPanel::-webkit-scrollbar, #guidePanel::-webkit-scrollbar, #treeGridWrap::-webkit-scrollbar, .cfg-selector::-webkit-scrollbar, .studioToolDlg .studio-tool-mount::-webkit-scrollbar, .command-palette-list::-webkit-scrollbar, .material-library-list::-webkit-scrollbar { width:7px; height:7px; }
  .ui-scroll::-webkit-scrollbar-track, .side::-webkit-scrollbar-track, .ordrop-menu::-webkit-scrollbar-track, #buildPanel::-webkit-scrollbar-track, #projPanel::-webkit-scrollbar-track, #delivPanel::-webkit-scrollbar-track, #guidePanel::-webkit-scrollbar-track, #treeGridWrap::-webkit-scrollbar-track, .cfg-selector::-webkit-scrollbar-track, .studioToolDlg .studio-tool-mount::-webkit-scrollbar-track, .command-palette-list::-webkit-scrollbar-track, .material-library-list::-webkit-scrollbar-track { background:transparent; }
  .ui-scroll::-webkit-scrollbar-thumb, .side::-webkit-scrollbar-thumb, .ordrop-menu::-webkit-scrollbar-thumb, #buildPanel::-webkit-scrollbar-thumb, #projPanel::-webkit-scrollbar-thumb, #delivPanel::-webkit-scrollbar-thumb, #guidePanel::-webkit-scrollbar-thumb, #treeGridWrap::-webkit-scrollbar-thumb, .cfg-selector::-webkit-scrollbar-thumb, .studioToolDlg .studio-tool-mount::-webkit-scrollbar-thumb, .command-palette-list::-webkit-scrollbar-thumb, .material-library-list::-webkit-scrollbar-thumb { background:rgba(176,176,184,.38); border-radius:8px; border:2px solid transparent; background-clip:content-box; }
  .ui-scroll::-webkit-scrollbar-thumb:hover, .side::-webkit-scrollbar-thumb:hover, .ordrop-menu::-webkit-scrollbar-thumb:hover, #buildPanel::-webkit-scrollbar-thumb:hover, #projPanel::-webkit-scrollbar-thumb:hover, #delivPanel::-webkit-scrollbar-thumb:hover, #guidePanel::-webkit-scrollbar-thumb:hover, #treeGridWrap::-webkit-scrollbar-thumb:hover, .cfg-selector::-webkit-scrollbar-thumb:hover, .studioToolDlg .studio-tool-mount::-webkit-scrollbar-thumb:hover, .command-palette-list::-webkit-scrollbar-thumb:hover, .material-library-list::-webkit-scrollbar-thumb:hover { background:rgba(188,188,196,.54); background-clip:content-box; }
  .ui-scroll::-webkit-scrollbar-button, .side::-webkit-scrollbar-button, .ordrop-menu::-webkit-scrollbar-button, #buildPanel::-webkit-scrollbar-button, #projPanel::-webkit-scrollbar-button, #delivPanel::-webkit-scrollbar-button, #guidePanel::-webkit-scrollbar-button, #treeGridWrap::-webkit-scrollbar-button, .cfg-selector::-webkit-scrollbar-button, .studioToolDlg .studio-tool-mount::-webkit-scrollbar-button, .command-palette-list::-webkit-scrollbar-button, .material-library-list::-webkit-scrollbar-button { display:none; width:0; height:0; }
  body.builderdeploy, body.builder, body.config, body.projects, body.deliv{ --studio-menu-h:0px; }
  body.builderdeploy #studioMenuBar, body.builder #studioMenuBar, body.config #studioMenuBar, body.projects #studioMenuBar, body.deliv #studioMenuBar{ display:none; }
  body.builderdeploy #autoload, body.builder #autoload, body.config #autoload, body.projects #autoload, body.deliv #autoload, body.preview #autoload, body.orient #autoload{ display:none !important; }
  .studio-shortcuts, .studio-info-rows{ display:grid; gap:7px; margin:10px 0; }
  .studio-shortcuts>div, .studio-info-rows>div{ display:grid; grid-template-columns:92px minmax(0,1fr); gap:10px; align-items:center; padding:7px 0; border-bottom:1px solid var(--line); }
  .studio-shortcuts kbd{ justify-self:start; min-width:54px; padding:2px 6px; border:1px solid rgba(255,255,255,.12); border-radius:3px; background:rgba(255,255,255,.04); color:var(--muted); font:600 11px/1.2 var(--mono); text-align:center; }
  .studio-info-rows b{ color:var(--muted); font-size:12px; }
  .studio-info-rows span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-family:var(--mono); font-size:12px; color:var(--txt); }
  .backup-status-card{ margin-top:14px; padding-top:12px; border-top:1px solid var(--line); }
  .backup-status-card:first-of-type{ margin-top:10px; }
  .backup-status-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; color:var(--txt); }
  .backup-status-head b{ font-size:13px; }
  .backup-status-head span{ color:var(--muted); font:700 10px/1 var(--mono); text-transform:uppercase; letter-spacing:.04em; }
  .backup-status-card.warn .backup-status-head span{ color:var(--bad-rest); }
  .backup-status-warning{ margin-top:10px; padding:9px 10px; border:1px solid rgba(255,100,100,.32); border-radius:4px; background:rgba(255,70,70,.06); color:var(--txt); font:700 12px/1.35 Roboto,system-ui,sans-serif; }
  .backup-status-files{ display:flex; flex-direction:column; gap:4px; margin-top:8px; }
  .backup-status-files code, .backup-status-files em{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:600 11px/1.3 var(--mono); }
  .revision-history-list{ display:flex; flex-direction:column; margin-top:8px; border-top:1px solid var(--line); }
  .revision-history-row{ display:grid; grid-template-columns:minmax(82px,.7fr) minmax(150px,1.25fr) minmax(64px,.5fr) minmax(146px,1fr); gap:12px; align-items:center; padding:8px 0; border-bottom:1px solid var(--line); }
  .revision-history-row b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font-size:12px; }
  .revision-history-row span, .revision-history-row code, .revision-history-row time{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:600 11px/1.3 var(--mono); }
  @media(max-width:900px){ .studio-import-watch, .studio-agent-lease{ max-width:160px; } }
  /* showroom backdrop (.stage/.weave/.weaveGlow/#c/.hud) -> core/showroom.css (decomposition step 1) */
  /* orientation cube */
  /* ViewCube - ORIENT MODE ONLY (it rotates the ASSEMBLY via quaternions, never the camera → limitless tumble, no pole/gimbal locks). Editor/preview have no cube. */
  .gizmo{ display:none; position:absolute; top:6px; right:10px; width:160px; height:160px; perspective:620px; z-index:6; touch-action:none; user-select:none; -webkit-user-select:none; }
  body.orient .gizmo{ display:block; }
  .home{ position:absolute; left:2px; top:2px; width:28px; height:28px; border:1px solid var(--accent); border-radius:4px;
    background:var(--wash); color:#e7ddf5; cursor:pointer; font-size:16px; line-height:26px; text-align:center;
    z-index:25; opacity:0; pointer-events:none; transition:opacity .14s; box-shadow:0 2px 7px rgba(0,0,0,.45); }
  .gizmo:hover .home{ opacity:1; pointer-events:auto; }
  .home:hover{ background:var(--accent); color:#1b1030; }
  .arrow,.rollset{ position:absolute; cursor:pointer; z-index:25; opacity:0; pointer-events:none; transition:opacity .14s; }
  .gizmo.faceview:hover .arrow{ opacity:.55; pointer-events:auto; }
  .gizmo.faceview:hover .rollset{ opacity:.75; visibility:visible; }
  .arrow:hover{ opacity:1; }
  .arrow{ width:18px; height:14px; background:var(--accent); filter:drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
  .arrow.up   { left:50%; top:24px;    transform:translateX(-50%); clip-path:polygon(50% 0,0 100%,100% 100%); }
  .arrow.down { left:50%; bottom:24px; transform:translateX(-50%); clip-path:polygon(0 0,100% 0,50% 100%); }
  .arrow.left { top:50%; left:24px;    transform:translateY(-50%); width:14px; height:18px; clip-path:polygon(100% 0,100% 100%,0 50%); }
  .arrow.right{ top:50%; right:24px;   transform:translateY(-50%); width:14px; height:18px; clip-path:polygon(0 0,0 100%,100% 50%); }
  .rollset{ top:2px; right:2px; width:70px; height:70px; color:var(--accent); overflow:visible; visibility:hidden; filter:drop-shadow(0 1px 2px rgba(0,0,0,.55)); }
  .roll{ cursor:pointer; } .roll:hover{ color:#e7ddf5; }
  .cube{ position:absolute; inset:0; transform-style:preserve-3d; will-change:transform; z-index:20; pointer-events:none; }
  .face{ position:absolute; width:72px; height:72px; left:44px; top:44px; backface-visibility:hidden;
    display:grid; grid-template-columns:18% 64% 18%; grid-template-rows:18% 64% 18%;
    background:rgba(32,33,38,.85); box-shadow:inset 0 0 0 1.5px #4e4e5a; }
  .cell{ pointer-events:inherit; }
  .cell.hot{ background:rgba(169,133,221,.82); }
  .cell.c{ display:flex; align-items:center; justify-content:center; font-size:10px; font-weight:700; letter-spacing:.04em; color:#d8d8e0; }
  .cell.c.hot{ background:var(--accent); color:#1b1030; }
  /* playback bar - importance-centred 4+4 flank (approved v3.13): toggles left, [Previous|step name|Next] pager
     in the true middle (the name slot flexes, sized for 60-70 chars), Play/Play-all/Exit right.
     Rounded RECTANGLES only; spacing normalized to one 10px unit; elevated card, not a pill. */
  .play{ position:absolute; left:50%; bottom:calc(var(--timeline-float-gap) + env(safe-area-inset-bottom, 0px)); transform:translateX(-50%); display:grid; grid-template-columns:auto 1fr auto;
    width:min(1500px, calc(100% - 28px)); gap:10px; align-items:center; white-space:nowrap;
    background:rgba(27,27,27,.94); border:1px solid var(--line); border-radius:8px; padding:10px;
    box-shadow:var(--elev); backdrop-filter:blur(6px); z-index:5; font-size:15px; overflow:hidden; }
  .play .zone{ display:flex; gap:10px; align-items:center; min-width:0; overflow:hidden; }
  .play .zone.zl{ justify-self:start; }
  .play .zone.zr{ justify-self:end; }
  .play button{ background:var(--panel2); color:var(--txt); border:1px solid var(--line); border-radius:4px; padding:8px 14px; cursor:pointer;
    font:inherit; display:inline-flex; align-items:center; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; transition:color 140ms ease, border-color 140ms ease, background 140ms ease; }
  /* Hover is a POINTER state, gated through :where(.dev-pointer) - the device primitive this file
     already argues for ("DEVICE mode, not viewport size"). Ungated, a tap left the accent
     border burned into the button until you tapped elsewhere, and on desktop a button lit up merely
     because the cursor was resting on it while you drove from the keyboard: highlights that did not
     correspond to anything the builder was doing. :not(:disabled) keeps a spent control looking spent. */
  :where(.dev-pointer) .play button:hover:not(:disabled){ color:var(--link); border-color:var(--accent); }
  /* Keyboard focus is explicit and separate; a mouse click leaves no ring behind. */
  .play button:focus{ outline:none; }
  .play button:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  /* A spent control reads spent: no hover, no press, no pointer response. */
  .play button:disabled{ color:var(--low); border-color:var(--line); background:var(--panel2); box-shadow:none; cursor:default; pointer-events:none; }
  .play button:disabled kbd{ opacity:.45; }
  .play button:not(.danger):active, .play button:not(.danger).shortcut-pressed{ color:var(--link); border-color:var(--accent); background:var(--wash); box-shadow:inset 0 0 0 1px rgba(169,133,221,.18); }   /* .danger keeps the red family - its pressed level is in types.css */
  .play button.primary:hover{ background:var(--primary-hi); border-color:var(--primary-hi); color:#fff; }
  .play button.primary:active, .play button.primary.shortcut-pressed{ background:var(--primary-hi); border-color:var(--primary-hi); color:#fff; box-shadow:inset 0 0 0 1px rgba(255,255,255,.24); }
  .play input[type=range]{ width:140px; accent-color:var(--accent); }
  /* step readout: the most visible text in the bar; flexes between the arrows, long titles ellipsize.
     The counter is the purple STEP X / Y kicker (lifted from the preview caption - it lives ONLY here now) */
  .play .lbl{ flex:1; min-width:0; text-align:center; overflow:hidden; text-overflow:ellipsis; }   /* text = .t-control */
  .play .lbl .frac{ margin-right:10px; }   /* type = .t-kicker */
  /* .play .lbl2 → type .t-meta (types.css) */
  /* ONE merged button: "Details [D]" in the base view (opens the scrub+spread popover);
     "Description [D]" in preview (toggles the step caption) */
  .moreWrap{ position:relative; display:inline-flex; }
  .moreMenu{ display:none; position:absolute; bottom:calc(100% + 10px); left:50%; transform:translateX(-50%); z-index:30;
    padding:10px 12px; box-shadow:var(--elev-float); max-width:calc(100vw - 28px); overflow:hidden; white-space:nowrap; }
  .moreWrap.open .moreMenu{ display:flex; flex-direction:column; gap:8px; }
  .moreMenu .mrow{ display:flex; align-items:center; gap:8px; }
  .moreMenu .mrow .lbl2{ min-width:46px; }
  .lblPv{ display:none; }
  body.preview .lblPv{ display:inline; } body.preview .lblEd{ display:none; }
  body.preview .moreMenu{ display:none !important; }   /* the tools popover is editor-only */
  /* in the base view the caption-state wash is meaningless - the button is a plain popover trigger */
  body:not(.preview) #descTgl.on{ background:var(--panel2); color:var(--muted); border-color:var(--line); }
  body:not(.preview) .moreWrap.open>#descTgl, body:not(.preview) .moreWrap.open>#descTgl.on{ color:var(--link); border-color:var(--accent); }
  body:not(.preview) #descTgl{ display:none; }
  /* keycaps: unmistakably keyboard keys - mono, raised cap, on EVERY control */
  #playBtn{ display:inline-flex; align-items:center; }
  /* .play button kbd → .kbd keycap primitive (types.css) */
  /* .play button.primary kbd → on-primary keycap (.primary .kbd, types.css) */
  .play .navbtn{ display:inline-flex; align-items:center; }
  @media(max-width:680px){
    body:not(.preview):not(.builderdeploy):not(.orient) .play{ display:none; }
    .play{ grid-template-columns:1fr; width:calc(100% - 16px); gap:8px; padding:8px; white-space:normal; font-size:12px; }
    .play .zone{ justify-content:center; flex-wrap:wrap; gap:6px; overflow:visible; }
    .play .zone.zl, .play .zone.zr{ justify-self:stretch; }
    .play button{ min-width:0; padding:6px 8px; }
    .play .lbl{ flex:0 1 100%; }
  }

  .studio-legacy-stores{ display:none !important; }
  /* Geometry organization lives in a floating browser, independent of narration. */
  #secParts{ position:fixed; top:calc(var(--studio-menu-h) + 16px); left:16px; bottom:calc(var(--timeline-h) + 104px); z-index:5; width:286px; min-height:180px; margin:0; padding:0; overflow:hidden; background:var(--panel); border:1px solid var(--line); box-shadow:var(--elev); color:var(--txt); }
  #secParts[open]{ display:flex; flex-direction:column; }
  #secParts[open]>summary{ margin-bottom:0; }
  #secParts:not([open]){ bottom:auto; min-height:0; }
  body.preview #secParts, body.orient #secParts, body.operation #secParts, body.tree #secParts,
  body.mbuilder #secParts, body.config #secParts, body.projects #secParts, body.deliverables #secParts,
  body.builderdeploy #secParts{ display:none; }
  #secParts>summary{ flex:0 0 34px; min-width:0; display:grid; grid-template-columns:12px minmax(0,1fr) auto; align-items:center; gap:6px; padding:0 7px; border-bottom:1px solid var(--line); background:var(--panel2); cursor:pointer; list-style:none; }
  #secParts>summary::-webkit-details-marker{ display:none; }
  #secParts>summary::before{ content:'▾'; color:var(--muted); font-size:10px; }
  #secParts:not([open])>summary::before{ content:'▸'; }
  #secParts>summary h2{ min-width:0; margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font-size:12px; font-weight:600; letter-spacing:0; text-transform:none; }
  #secParts>summary .collapseAll{ min-width:0; padding:3px 6px; font-size:10px; }
  #secParts>.row{ flex:0 0 auto; margin:0 !important; padding:6px; border-bottom:1px solid var(--line); background:var(--panel); }
  #secParts>.row #addGroup{ min-width:0; padding:4px 7px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:10px; }
  #secParts>.row #selCt{ margin-left:auto; color:var(--muted); font-size:10px; }
  #secParts #partList{ position:absolute; inset:69px 0 0; min-height:0; overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; padding:4px 5px 8px; scrollbar-gutter:stable; scrollbar-width:thin; }
  #secParts .part{ min-height:24px; gap:5px; padding:2px 5px; border-top:0; border-radius:2px; font-size:11px; }
  #secParts .part:hover{ background:var(--panel2); }
  #secParts .part.grp .pn{ color:var(--txt); font-weight:500; }
  #secParts .part.sel{ background:var(--wash); outline:1px solid rgba(169,133,221,.45); }
  #secParts .vsep{ margin-top:3px; padding:6px 4px 3px; background:var(--panel); font-size:10px; }
  h1{ margin:0; padding:14px 16px 3px; }   /* The sidebar title uses .t-title as its shared base. */
  .sub{ color:var(--muted); font-size:11.5px; padding:0 16px 10px; border-bottom:1px solid var(--line); }
  .sec{ border-bottom:1px solid var(--line); padding:10px 16px 13px; }
  /* section labels: muted-gray uppercase (docs dev-feed-month style) - purple is NOT for headers */
  .sec h2{ margin:0 0 8px; }   /* type = .t-section (12px) */
  .steps{ list-style:none; margin:0; padding:0; }
  .steps li{ padding:7px 9px; border-radius:4px; cursor:pointer; display:flex; gap:9px; align-items:center; transition:color 140ms ease, background 140ms ease; }
  .steps li:hover{ background:var(--panel2); color:var(--link); }
  .steps li.active{ background:var(--wash); color:var(--link); font-weight:500; }
  .steps li .n{ color:var(--low); font-size:12px; width:18px; font-family:var(--mono); } .steps li .g{ color:var(--muted); cursor:grab; }
  .steps li .stagin{ accent-color:var(--accent); margin:0 0 0 6px; cursor:pointer; flex:0 0 auto; }
  .steps li .spreadin{ width:36px; text-align:center; }
  .steps li.stagger-empty{ color:var(--muted); cursor:default; }
  .steps li .st{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .steps li .stin{ flex:1; min-width:0; background:var(--code); color:var(--txt); border:1px solid var(--accent); border-radius:4px; padding:1px 5px; font:inherit; outline:none; }
  /* step-group headers: auto-derived from each step's subassembly, collapsible, rename + drag-to-regroup */
  .steps li.stepgrp{ padding:8px 6px 4px; margin-top:5px; border-top:1px solid var(--line); gap:6px; cursor:pointer; }   /* type = .t-section (11px) */
  .steps li.stepgrp:first-child{ margin-top:0; border-top:0; }
  .steps li.stepgrp:hover{ color:var(--txt); background:transparent; }
  .steps li.stepgrp.dragover{ background:var(--wash); color:var(--link); }
  .steps li.stepgrp .tw{ display:inline-block; width:10px; font-size:9px; color:var(--low); flex:0 0 auto; }
  .steps li.stepgrp .tw::before{ content:'▾'; } .steps li.stepgrp.collapsed .tw::before{ content:'▸'; }
  .steps li.stepgrp .gn{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .steps li.stepgrp .ct{ color:var(--muted); font-weight:600; text-transform:none; letter-spacing:0; }
  .steps li.stepgrp .gnin{ flex:1; min-width:0; background:var(--code); color:var(--txt); border:1px solid var(--accent); border-radius:4px; padding:1px 5px; font:inherit; text-transform:none; letter-spacing:0; outline:none; }
  .steps li.stepgrp .gdel{ flex:0 0 auto; background:none; border:0; color:var(--low); font:inherit; font-size:14px; line-height:1; cursor:pointer; padding:0 2px; opacity:0; transition:opacity 140ms ease, color 140ms ease; }
  .steps li.stepgrp:hover .gdel{ opacity:.7; } .steps li.stepgrp .gdel:hover{ opacity:1; color:var(--bad); }
  .steps li.stephidden{ display:none; }   /* step in a collapsed group (kept in the DOM so navigation can reveal it without a rebuild) */
  .row{ display:flex; gap:7px; flex-wrap:wrap; align-items:center; margin-top:8px; }
  #stepBtns .b, #asmBtns .b{ flex:1 1 auto; }   /* buttons fill the row, sitting next to each other (wrap+fill on a narrow panel) */
  #secAssembly, #secSteps, #asmBtns, #appx, #secStatus{ display:none !important; }   /* utility actions moved to the Studio menu/dialogs; stage navigation now lives in the timeline */
  button.b{ background:var(--panel2); color:var(--txt); border:1px solid var(--line); border-radius:4px; padding:4px 10px; cursor:pointer; font-size:12px; transition:color 140ms ease, border-color 140ms ease, background 140ms ease; }   /* the ONE .b base look; the bars override ONLY padding/layout */
  button.b:hover{ color:var(--link); border-color:var(--accent); }
  button.b:disabled{ pointer-events:none; }
  button.b.danger{ color:var(--bad-rest); border-color:rgba(232,160,154,.35); }
  button.b.danger:hover{ color:var(--bad); border-color:var(--bad); background:var(--bad-fill); }
  input[type=text],textarea,select{ width:100%; background:var(--code); color:var(--txt); border:1px solid var(--line); border-radius:4px; padding:7px 9px; font:inherit; }
  input[type=text]:focus,textarea:focus,select:focus{ outline:none; border-color:var(--accent); }
  textarea{ resize:vertical; min-height:64px; }
  label.fld{ display:block; color:var(--low); font-size:12px; margin:8px 0 3px; }
  #edInternalWorkflow{ min-height:54px; }
  .internalWorkflowLabel{ margin-top:12px; }
  .internalWorkflowHint{ margin-top:4px; color:var(--low); }
  /* part rows */
  .part{ display:flex; align-items:center; gap:6px; padding:4px 0; border-top:1px solid rgba(255,255,255,.05); font-size:12px; }
  .part:first-child{ border-top:0; }
  .part input[type=checkbox]{ accent-color:var(--accent); }
  .part .pn{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); }
  .part .pn.off{ color:rgba(255,255,255,.30); }
  .part .xyz{ display:flex; gap:3px; }
  .part .xyz input{ width:38px; background:var(--code); color:var(--txt); border:1px solid var(--line); border-radius:4px; padding:3px 4px; font-size:11px; text-align:right; }
  .part.grp .pn{ color:var(--link); font-weight:500; }
  .part .tw{ width:12px; flex:0 0 auto; color:var(--muted); cursor:pointer; text-align:center; user-select:none; }
  .part .tw.sp{ cursor:default; color:rgba(255,255,255,.18); }
  .visibility-icon{ width:15px; height:15px; display:block; }
  .browser-visibility{ flex:0 0 20px; width:20px; height:22px; display:inline-grid; place-items:center; vertical-align:middle; margin:0; padding:0; border:0; border-radius:3px; background:transparent; color:var(--low); cursor:pointer; }
  .browser-visibility.visible{ color:var(--muted); }
  .browser-visibility.mixed{ color:var(--accent); opacity:.72; }
  .browser-visibility:hover,.browser-visibility:focus-visible{ outline:none; color:var(--link); background:var(--wash); }
  .part.occvar{ border-top:0; padding-top:1px; padding-bottom:1px; }   /* per-config child row under an occurrence */
  .part.occvar .pn{ color:var(--muted); font-size:11px; }
  .part.occvar.logical-build-lane .tw.sp{ color:var(--accent); }
  .part .pg{ flex:0 0 auto; background:var(--panel2); color:var(--muted); border:1px solid var(--line); border-radius:4px; font-size:10px; padding:2px 3px; max-width:58px; }
  .part .gx{ flex:0 0 auto; background:none; border:0; color:var(--muted); cursor:pointer; font-size:12px; line-height:1; padding:0 2px; }
  .part .gx:hover{ color:var(--bad); }
  .part .gx.ok{ color:var(--bad); font-weight:600; }
  .part .gnin{ flex:1 1 60px; min-width:40px; background:var(--code); color:var(--txt); border:1px solid var(--accent); border-radius:4px; padding:1px 5px; font:inherit; outline:none; }
  .part.grp{ cursor:grab; }
  .part.grp.ungrouped-group{ cursor:pointer; }
  .part .gc{ flex:0 0 auto; font-size:10px; color:var(--muted); min-width:14px; text-align:right; }
  .part[data-key]{ cursor:pointer; }
  .part.sel{ background:var(--wash); outline:1px solid rgba(169,133,221,.5); }
  .part.dragover, .vsep.dragover{ outline:1px dashed var(--accent); background:rgba(169,133,221,.08); }
  .part.grp.dropbefore{ box-shadow:inset 0 2px 0 var(--accent); }   /* sibling insert lines (drop in the gap between rows = same level, not nested) */
  .part.grp.dropafter{ box-shadow:inset 0 -2px 0 var(--accent); }
  .part.grp.drophot{ outline:2px solid var(--accent); background:rgba(169,133,221,.22); }
  .part.grp.hassel, .vsep.hassel{ box-shadow:inset 3px 0 0 var(--accent); color:var(--link); }
  .dragchip{ position:fixed; z-index:9999; pointer-events:none; background:var(--accent); color:#1b1030; font-size:11px; font-weight:600; padding:2px 7px; border-radius:4px; box-shadow:0 2px 6px rgba(0,0,0,.5); }
  /* Fusion-style box-select marquee. Window selection is solid; crossing selection is dashed. The palette follows the no-green UI rule. */
  .marqbox{ position:fixed; z-index:9998; pointer-events:none; border:1px solid var(--accent); background:rgba(169,133,221,.12); box-shadow:0 0 0 1px rgba(0,0,0,.35); }
  .marqbox.cross{ border-style:dashed; background:rgba(169,133,221,.06); }
  .part .pn{ user-select:none; }
  /* variant separators: normal case (capitalization unified with the panel) */
  .vsep{ color:var(--muted); font-size:12px; font-weight:600; padding:8px 4px 3px; border-top:1px solid var(--line); margin-top:5px; position:sticky; top:0; background:var(--panel); z-index:1; cursor:pointer; user-select:none; }
  .vsep:hover{ color:var(--txt); } .vsep .tw{ display:inline-block; width:11px; }
  .vsep.passive{ position:static; cursor:default; }   /* a passive control row (preview/orientation), not a collapsible header */
  .vsep.passive:hover{ color:var(--muted); }
  .grpsec{ padding:8px 4px 3px; border-top:1px solid var(--line); margin-top:5px; cursor:pointer; user-select:none; }   /* type = .t-section (11px) */
  .grpsec.passive{ cursor:default; }
  .grpsec:hover{ color:var(--txt); } .grpsec.passive:hover{ color:var(--muted); } .grpsec .tw{ display:inline-block; width:11px; }
  .part-load-more{ width:calc(100% - 18px); min-height:30px; margin-top:5px; padding:5px 9px; display:flex; align-items:center; justify-content:space-between; gap:8px; background:var(--panel2); color:var(--link); border:1px solid var(--line); border-radius:4px; cursor:pointer; font:600 11px/1.2 var(--ui); }
  .part-load-more:hover, .part-load-more:focus-visible{ outline:none; border-color:var(--accent); background:var(--wash); }
  .part-load-more span{ color:var(--low); font:500 10px/1.2 var(--mono); }
  /* per-variant chips: rounded rectangles (no pills) */
  .vsep .pvbtn{ float:right; margin-top:-1px; margin-left:6px; background:var(--panel2); color:var(--muted); border:1px solid var(--line); border-radius:4px;
    font-size:11px; font-weight:500; text-transform:none; letter-spacing:0; padding:3px 9px; cursor:pointer; transition:color 140ms ease, border-color 140ms ease, background 140ms ease; }
  .vsep .pvbtn:hover{ border-color:var(--accent); color:var(--link); }
  .vsep .pvbtn:disabled{ pointer-events:none; }   /* variant has no change in this step */
  /* Orientation + its Reset: ONE fused segmented chip (single outer border, hairline divider, no doubles) */
  .vsep .fuse{ float:right; margin-top:-1px; margin-left:6px; display:inline-flex; border:1px solid var(--line); border-radius:4px; overflow:hidden; }
  .vsep .fuse .pvbtn{ float:none; margin:0; border:0; border-radius:0; }
  .vsep .fuse .pvbtn + .pvbtn{ border-left:1px solid var(--line); }
  /* start/finish stage tabs: ONE fused segmented control (same recipe as Orientation|Reset) */
  .stagetabs{ display:flex; align-items:center; gap:8px; margin:0 0 8px; }
  .seg{ display:inline-flex; flex-flow:row nowrap; border:1px solid var(--line); border-radius:4px; overflow:hidden; }
  .stab{ flex:0 0 auto; white-space:nowrap; background:var(--panel2); color:var(--muted); border:0; border-radius:0; padding:6px 16px; cursor:pointer; font:inherit; font-size:12px; line-height:1.1; }
  .stab + .stab{ border-left:1px solid var(--line); }
  .stab:hover{ color:var(--txt); }
  .stab.on{ background:var(--wash); color:var(--link); font-weight:600; }
  /* generic fused button pair (orient bar: step pager + copy pair) */
  .fusegrp{ display:inline-flex; border:1px solid var(--line); border-radius:4px; overflow:hidden; }
  .fusegrp>.b{ border:0; border-radius:0; margin:0; }
  .fusegrp>.b+.b{ border-left:1px solid var(--line); }
  /* diagnostics live in the Status section (collapsed by default) - no (i) tooltips */
  #secStatus .mini{ display:block; margin-top:4px; }
  /* collapsible sidebar sections (every blue category folds like Lighting) */
  details.sec>summary{ display:flex; align-items:center; gap:7px; cursor:pointer; list-style:none; user-select:none; margin:0; }
  details.sec>summary::-webkit-details-marker{ display:none; }
  details.sec>summary::before{ content:'▾'; color:var(--low); font-size:9px; width:9px; flex:0 0 auto; }
  details.sec:not([open])>summary::before{ content:'▸'; }
  details.sec>summary h2{ margin:0; }
  details.sec[open]>summary{ margin-bottom:9px; }
  .sec>summary .collapseAll{ margin-left:auto; font-size:11px; padding:2px 8px; }   /* per-section collapse-all/expand-all toggle, right-aligned in its header (single source for both sections) */
  /* preview key legend - videogame-style keycaps, bottom-right */
  #pvExit.studio-view-as{ display:inline-flex; align-items:center; color:var(--muted); }
  #pvExit.studio-view-as.on{ color:var(--link); border-color:rgba(169,133,221,.55); background:var(--wash); }
  #pvExit .preview-exit-copy,#pvExit .preview-exit-key{ display:none; }
  body.preview #pvExit{ display:inline-flex; align-items:center; color:var(--bad-rest); }
  body.preview #pvExit .view-as-copy,body.preview #pvExit .view-as-key{ display:none; }
  body.preview #pvExit .preview-exit-copy,body.preview #pvExit .preview-exit-key{ display:inline-flex; }
  /* body.stage-end (builder/app.ts, set with Next's disabled state) JOINS the hover selector rather than
     restating the red: at the end of a stage Exit wears its hover look and holds it. No motion of its own
     - the pointer hover transition on .play button is what carries it, and reduced-motion already clamps that. */
  body.preview #pvExit:hover, body.preview.stage-end #pvExit{ color:var(--bad) !important; border-color:var(--bad) !important; }
  body.preview #pvExit:active, body.preview #pvExit.shortcut-pressed{ color:var(--bad); border-color:var(--bad); background:var(--bad-press); }   /* the id rest rule outranks .danger:active (types.css), so the pressed level is restated at this specificity */
  /* orientation editor - aim the preview camera per step/variant with the ViewCube */
  .vsep .orbtn.set{ background:var(--wash); color:var(--link); }
  #orientBar, #operationBar{ display:none; }
  body.orient .side, body.orient .play, body.orient .hud{ display:none; }
  /* The orientation and occurrence-operation viewfinders share one bar anatomy, but remain separate surfaces. */
  .viewfinder-bar{ grid-template-columns:auto 1fr auto; width:min(1800px, calc(100% - 28px));
    gap:10px; align-items:center; min-width:0; overflow:visible; white-space:nowrap; position:absolute; left:50%; bottom:16px; transform:translateX(-50%); z-index:9;
    background:rgba(27,27,27,.94); border:1px solid var(--line); border-radius:8px; padding:10px;
    box-shadow:var(--elev); backdrop-filter:blur(6px); font-size:15px; }
  body.orient:not(.operation) #orientBar, body.operation #operationBar{ display:grid; }
  body.cfgorient #orientBar{ z-index:13; }
  body.cfgorient #cfgTop,
  body.cfgorient #cfgBar,
  body.cfgorient #viewCtl{ display:none !important; }
  body.cfgorient #orApplyWrap,
  body.cfgorient #orMirrorWrap,
  body.cfgorient #orStageOrient,
  body.cfgorient #orCoverBtn,
  body.cfgorient #orStepPrev,
  body.cfgorient #orStepNext,
  body.cfgorient .orzoom{ display:none !important; }
  /* Stage-cover editing is a state OF the Orient bar, not a second bar: the
     same orientation, zoom and Sets controls stay in place and write the
     cover's values instead of the step's. Only the per-stage bulk actions and
     the orientation link leave - a cover is one step's leaf value. */
  #orCoverDone, #orCoverRemove{ display:none; }
  body.coverediting #orCoverBtn{ display:none; }
  body.coverediting #orCoverDone, body.coverediting #orCoverRemove{ display:inline-flex; }
  body.coverediting #orStageOrient,
  body.coverediting #orMirrorWrap,
  body.coverediting #orExclStage{ display:none !important; }
  body.coverediting #orientBar{ border-color:var(--accent); }
  body.coverediting #orTop .tail{ color:var(--accent); }
  .viewfinder-bar .zone{ display:flex; gap:10px; align-items:center; min-width:0; }
  .viewfinder-bar .zone.zl{ justify-self:start; }
  .viewfinder-bar .zone.zr{ justify-self:end; }
  .viewfinder-bar .b{ display:inline-flex; align-items:center; font:inherit; padding:8px 14px; white-space:nowrap; }
  #orLbl{ flex:1; min-width:0; text-align:center; overflow:hidden; text-overflow:ellipsis; }   /* text = .t-control */
  #orLbl .frac{ margin-right:10px; }   /* type = .t-kicker */
  /* #orLbl b → text = .t-control (500, not default bold) */
  /* #orientBar .b kbd → .kbd keycap primitive (types.css) */
  #orientBar .ordrop-menu{ top:auto; bottom:calc(100% + 6px); max-height:min(420px, calc(100dvh - 164px)); }   /* utilities open upward and remain fully usable above the bottom bar */
  #orientBar #orApplyMenu{ left:0; transform:none; }   /* the left-edge utility must open inward, not off-screen */
  #orientBar #orMirrorMenu{ min-width:320px; }
  /* orient identity, top-left (the preview pvTop pattern) */
  .viewfinder-top{ display:none; }
  body.orient:not(.operation) #orTop, body.operation #operationTop{ display:block; position:absolute; left:18px; top:16px; z-index:8; font-size:17px; font-weight:600; color:var(--txt); pointer-events:none; }
  .viewfinder-top .tail{ color:var(--low); font-size:13px; font-weight:400; }
  #orientBar #orOk:hover{ background:var(--primary-hi); border-color:var(--primary-hi); color:#fff; }
  #operationBar #operationOk:hover{ background:var(--primary-hi); border-color:var(--primary-hi); color:#fff; }
  #operationBar #orOperationColorWrap,
  #operationBar #orOperationClear,
  #operationBar #orOperationDelete{ display:flex; }
  #operationLbl{ color:var(--muted); font-size:11px; font-weight:400; text-align:center; overflow:hidden; text-overflow:ellipsis; }
  .operation-color{ align-items:center; gap:6px; color:var(--muted); font-size:11px; }
  .operation-color input{ width:34px; height:28px; box-sizing:border-box; border:1px solid var(--line); border-radius:4px; background:var(--panel2); padding:2px; }
  @media(max-width:1740px){
    body.orient:not(.operation) #orientBar{
      grid-template-columns:minmax(0,1fr) auto;
      grid-template-areas:"actions commit" "pager pager";
      row-gap:8px;
    }
    #orientBar .viewfinder-actions{ grid-area:actions; flex-wrap:wrap; }
    #orientBar .viewfinder-pager{ grid-area:pager; width:100%; justify-content:center; }
    #orientBar .viewfinder-commit{ grid-area:commit; }
  }
  @media(max-width:900px){
    body.orient:not(.operation) #orientBar,
    body.operation #operationBar{
      grid-template-columns:minmax(0,1fr);
      grid-template-areas:"actions" "pager" "commit";
    }
    .viewfinder-bar .viewfinder-actions{ grid-area:actions; justify-self:center; flex-wrap:wrap; justify-content:center; }
    .viewfinder-bar .viewfinder-pager{ grid-area:pager; justify-self:stretch; justify-content:center; }
    .viewfinder-bar .viewfinder-commit{ grid-area:commit; justify-self:center; }
  }
  /* #orientBar #orOk kbd → on-primary keycap (types.css) */
  /* #orRevert → folded into .danger in core/types.css */
  /* apply-to-variants dropdown (replaces the old "apply to all") */
  .ordrop{ position:relative; }
  .ordrop>button::after{ content:' ▾'; opacity:.7; }
  .ordrop-menu{ display:none; position:absolute; top:calc(100% + 6px); left:50%; transform:translateX(-50%); min-width:210px; max-height:300px; overflow:auto;
    background:var(--panel2); border:1px solid var(--line); border-radius:8px; padding:6px; z-index:14; box-shadow:0 10px 28px rgba(0,0,0,.45); text-align:left; }
  .ordrop.open .ordrop-menu{ display:block; }
.ordrop-heading{ color:var(--low); font-size:11px; font-weight:600; padding:2px 8px 5px; }
.ordrop-menu label{ display:flex; align-items:center; gap:8px; padding:6px 8px; border-radius:4px; cursor:pointer; color:var(--txt); font-size:13px; white-space:nowrap; }
/* Sets panel rows (Orient bar): frame tick · step-specific label the builder reads · builder callout + framing origin */
#orientBar #orApplyMenu{ min-width:440px; max-width:min(620px, calc(100vw - 24px)); }
.ordrop-menu .orset{ display:grid; grid-template-columns:auto minmax(0,1fr); gap:2px 8px; align-items:center; padding:5px 8px; border-radius:4px; }
.ordrop-menu .orset:hover{ background:var(--panel); }
.ordrop-menu .orset input[type=checkbox]{ accent-color:var(--accent); margin:0; }
.ordrop-menu .orset input[type=text]{ width:100%; min-width:0; box-sizing:border-box; padding:4px 7px; font:500 12px/1.2 var(--ui); }
.ordrop-menu .orset input[type=text]:disabled{ opacity:.55; }
.ordrop-menu .orset small{ grid-column:2; color:var(--low); font-size:11px; line-height:1.3; white-space:normal; }

/* Stage timeline: the authoring source for motion, visibility, and step bridges. */
#timelinePanel{ position:absolute; left:0; right:0; bottom:0; height:calc(var(--timeline-h) + env(safe-area-inset-bottom, 0px)); z-index:6; display:flex; flex-direction:column; min-width:0; overflow:hidden; container:stage-timeline / inline-size;
  padding-bottom:env(safe-area-inset-bottom, 0px); background:rgba(23,23,23,.97); border:1px solid var(--line); border-width:1px 0 0; border-radius:8px 8px 0 0; box-shadow:none; backdrop-filter:blur(8px); }
body.preview #timelinePanel, body.orient #timelinePanel, body.operation #timelinePanel, body.tree #timelinePanel,
body.mbuilder #timelinePanel, body.config #timelinePanel, body.projects #timelinePanel, body.deliverables #timelinePanel,
body.builder #timelinePanel, body.deliv #timelinePanel, body.guide #timelinePanel, body.builderdeploy #timelinePanel{ display:none; }
body:not(.preview):not(.orient):not(.operation):not(.tree):not(.mbuilder):not(.config):not(.projects):not(.deliverables):not(.builder):not(.deliv):not(.guide):not(.builderdeploy){ --studio-viewport-bottom-inset:calc(var(--timeline-h) + env(safe-area-inset-bottom, 0px)); }
.timeline-transform-confirm{ display:none; position:absolute; top:16px; left:50%; transform:translateX(-50%); z-index:8; align-items:center; gap:8px; padding:8px; border:1px solid var(--line); border-radius:8px; background:rgba(27,27,27,.96); box-shadow:var(--elev); backdrop-filter:blur(6px); }
.timeline-transform-confirm.open{ display:flex; }
.timeline-transform-confirm>span{ display:flex; flex-direction:column; min-width:240px; padding:0 8px; color:var(--txt); }
.timeline-transform-confirm small{ color:var(--muted); font-size:11px; font-weight:400; }
.timeline-transform-confirm .b{ display:inline-flex; align-items:center; gap:7px; white-space:nowrap; }
body:not(.preview):not(.orient):not(.operation):not(.tree):not(.mbuilder):not(.config):not(.projects):not(.deliverables):not(.builder):not(.deliv):not(.guide):not(.builderdeploy){ --studio-viewport-right-inset:calc(var(--timeline-inspector-w) + 32px); }
body:not(.preview):not(.orient):not(.operation):not(.tree):not(.mbuilder):not(.config):not(.projects):not(.deliverables):not(.builder):not(.deliv):not(.guide):not(.builderdeploy) .stage{ --monolith-showroom-spot-x:calc(50% - 206px); }
body:not(.preview):not(.orient):not(.operation):not(.tree):not(.mbuilder):not(.config):not(.projects):not(.deliverables):not(.builder):not(.deliv):not(.guide):not(.builderdeploy) .play{ bottom:calc(var(--timeline-h) + var(--timeline-float-gap) + env(safe-area-inset-bottom, 0px)); }
.timeline-head{ min-height:46px; display:grid; grid-template-columns:minmax(180px,1fr) auto minmax(270px,1fr); align-items:center; gap:14px; padding:0 12px; border-bottom:1px solid var(--line); background:var(--panel); }
.timeline-stage{ min-width:0; display:flex; align-items:center; gap:5px; overflow:hidden; }
.timeline-stage-arrows{ display:flex; align-items:center; gap:2px; }
.timeline-stage-arrows button{ width:23px; height:23px; display:grid; place-items:center; margin:0; padding:0; border:1px solid transparent; border-radius:var(--m-ui-radius-control,4px); background:transparent; color:var(--muted); cursor:pointer; }
.timeline-stage-arrows button:hover,.timeline-stage-arrows button:focus-visible{ outline:none; border-color:var(--line); background:var(--wash); color:var(--link); }
.timeline-stage-arrows button:disabled{ pointer-events:none; }
.timeline-stage-arrows .timeline-icon{ width:14px; height:14px; }
.timeline-nav-picker{ min-width:0; width:max-content; max-width:100%;   /* maintainer 2026-09-04: the stage and step names show whole while the head column has room; the flex column (min-width:0) shrinks them only when it runs out */ display:inline-flex; align-items:center; gap:3px; margin:0; padding:3px 4px 3px 5px; overflow:hidden; border:1px solid transparent; border-radius:var(--m-ui-radius-control,4px); background:transparent; color:var(--txt); font:600 12px/1.2 var(--ui); cursor:pointer; white-space:nowrap; }
.timeline-nav-picker>span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.timeline-nav-picker>.timeline-icon{ flex:0 0 auto; width:13px; height:13px; color:var(--low); }
.timeline-nav-picker[data-tl-step-picker]{ flex-shrink:0; }   /* when the column still runs out, the stage name gives way before the step name he reads */
.timeline-nav-picker:hover,.timeline-nav-picker:focus-visible,.timeline-stage-manage:hover,.timeline-stage-manage:focus-visible{ outline:none; border-color:var(--line); background:var(--wash); color:var(--link); }
.timeline-step-picker{ color:var(--muted); font-weight:500; }
.timeline-stage-manage{ flex:0 0 24px; width:24px; height:24px; display:grid; place-items:center; margin:0; padding:0; border:1px solid transparent; border-radius:var(--m-ui-radius-control,4px); background:transparent; color:var(--muted); cursor:pointer; }
.timeline-stage-manage .timeline-icon{ width:14px; height:14px; }
.timeline-stage>i{ color:var(--low); font:500 11px/1 var(--ui); font-style:normal; }
.studio-context-menu.timeline-navigation-menu{ width:max-content; min-width:220px; max-width:min(760px,calc(100vw - 12px)); max-height:min(60vh,520px); overflow-y:auto; overscroll-behavior:contain; }   /* maintainer 2026-09-04: the step picker grows to its longest step name; the generic .studio-context-menu cap (320px, declared later) used to win on equal specificity and ellipsised the names */
.timeline-stage-manager{ min-width:min(520px,calc(100vw - 72px)); display:flex; flex-direction:column; gap:14px; padding:16px; }
.timeline-stage-manager-list{ display:flex; flex-direction:column; gap:5px; max-height:min(56vh,560px); margin:0; padding:0; overflow:auto; list-style:none; }
.timeline-stage-manager-list li{ display:grid; grid-template-columns:28px minmax(0,1fr) auto; align-items:center; gap:7px; }
.timeline-stage-number{ color:var(--low); font:600 10px/1 var(--mono); text-align:right; }
.timeline-stage-manager input{ width:100%; min-width:0; box-sizing:border-box; padding:7px 9px; border:1px solid var(--line); border-radius:var(--m-ui-radius-control,4px); background:var(--code); color:var(--txt); font:500 12px/1.2 var(--ui); }
.timeline-stage-manager input:focus{ outline:none; border-color:var(--accent); }
.timeline-stage-manager-controls{ display:flex; gap:3px; }
.timeline-stage-manager-controls .b{ width:28px; height:28px; display:grid; place-items:center; padding:0; }
.timeline-stage-manager-controls .timeline-icon{ width:14px; height:14px; }
.timeline-stage-create{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:7px; padding-top:12px; border-top:1px solid var(--line); }
.timeline-tools{ min-width:0; display:flex; align-items:center; justify-content:center; gap:5px; overflow-x:auto; scrollbar-width:none; }
.timeline-tools::-webkit-scrollbar{ display:none; }
.timeline-tools .b{ padding:4px 8px; font-size:11px; }
.timeline-tool-separator{ flex:0 0 1px; align-self:stretch; margin:4px 2px; background:var(--line); }
.timeline-tools .timeline-visibility-tool{ display:inline-flex; align-items:center; gap:5px; }
.timeline-tools .timeline-visibility-tool .visibility-icon{ width:14px; height:14px; }
.timeline-tools .timeline-visibility-tool.timeline-duplicate-removal{ border-color:rgba(169,133,221,.5); background:var(--wash); color:var(--link); }
.timeline-tools .timeline-visibility-tool.timeline-duplicate-removal .timeline-icon{ width:14px; height:14px; }
.timeline-view-controls{ min-width:0; justify-self:end; display:flex; align-items:center; justify-content:flex-end; gap:10px; }
.timeline-focus-filter{ display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.timeline-focus-filter[aria-pressed="true"]{ border-color:rgba(169,133,221,.55); background:var(--wash); color:var(--link); }
.timeline-focus-filter .timeline-icon{ width:15px; height:15px; }
.timeline-scale{ justify-self:end; display:flex; align-items:center; gap:7px; color:var(--low); font:600 10px/1 var(--mono); }
.timeline-scale input{ width:100px; accent-color:var(--accent); }
.timeline-scale span{ min-width:72px; text-align:right; color:var(--muted); }
.timeline-workbench{ position:relative; flex:1; min-height:0; display:block; }
.timeline-viewport{ position:relative; width:100%; height:100%; min-width:0; overflow-x:hidden; overflow-y:auto; background:var(--code); scrollbar-color:var(--line) var(--code); }
.timeline-canvas{ min-height:100%; position:relative; padding:0 0 10px; box-sizing:border-box; }
.timeline-lane{ height:26px; display:grid; grid-template-columns:var(--timeline-label-w,286px) auto; border-top:1px solid rgba(255,255,255,.045); }
.timeline-label-resizer{ position:absolute; top:0; bottom:0; left:calc(var(--timeline-label-w,286px) - 4px); z-index:8; width:9px; cursor:col-resize; touch-action:none; outline:none; }
.timeline-label-resizer::after{ content:''; position:absolute; top:0; bottom:0; left:4px; width:1px; background:transparent; transition:background 120ms ease,box-shadow 120ms ease; }
.timeline-label-resizer:hover::after,.timeline-label-resizer:focus-visible::after,.timeline-label-resizer.dragging::after{ background:var(--accent); box-shadow:0 0 0 1px rgba(169,133,221,.18); }
.timeline-lane:first-child{ border-top:0; }
.timeline-lane-label{ position:sticky; left:0; z-index:3; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:left; padding:0 10px; border:0; border-right:1px solid var(--line); background:#181818; color:var(--muted); font:500 11px/26px Roboto,system-ui,-apple-system,"Segoe UI",Helvetica,Arial,sans-serif; }
button.timeline-lane-label{ cursor:pointer; }
button.timeline-lane-label:hover{ color:var(--link); background:var(--panel2); }
.timeline-tree-label{ display:flex; align-items:center; gap:2px; padding:0 7px 0 calc(6px + var(--timeline-depth,0)*14px); line-height:normal; }
.timeline-tree-label.group{ color:var(--txt); font-weight:500; }
.timeline-tree-label.part{ color:var(--txt); font-weight:400; }
.timeline-tree-label.selected{ background:var(--wash); color:var(--link); }
.timeline-disclosure{ flex:0 0 20px; width:20px; height:22px; display:grid; place-items:center; margin:0; padding:0; border:0; border-radius:3px; background:transparent; color:var(--low); cursor:pointer; }
.timeline-disclosure:hover,.timeline-disclosure:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
.timeline-disclosure span::before{ content:'▸'; display:block; font-size:9px; transform-origin:center; transition:transform 140ms ease; }
.timeline-disclosure[aria-expanded="true"] span::before{ transform:rotate(90deg); }
.timeline-disclosure.empty{ pointer-events:none; color:rgba(255,255,255,.16); }
.timeline-target-label{ flex:1 1 auto; min-width:0; height:24px; margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; border:0; border-radius:3px; background:transparent; color:inherit; padding:0 4px; text-align:left; font:inherit; cursor:pointer; }
.timeline-target-label:hover,.timeline-target-label:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
.timeline-ruler{ position:sticky; top:0; z-index:6; height:24px; display:grid; grid-template-columns:var(--timeline-label-w,286px) auto; background:var(--code); box-shadow:0 1px 0 rgba(255,255,255,.045); }
.timeline-ruler-label{ position:sticky; left:0; z-index:2; border-right:1px solid var(--line); background:#181818; }
.timeline-ruler-track{ height:100%; background-color:var(--code); background-image:linear-gradient(to right,rgba(255,255,255,.08) 1px,transparent 1px); background-size:80px 100%; }
.timeline-steps-lane{ height:42px; position:sticky; top:24px; z-index:5; background:var(--code); }
.timeline-steps-lane .timeline-lane-label{ color:var(--txt); font-weight:600; line-height:42px; }
.timeline-steps-lane .timeline-track,.timeline-camera-lane .timeline-track{ background-color:var(--code); }
.timeline-camera-lane{ position:sticky; top:66px; z-index:5; background:var(--code); box-shadow:0 1px 0 var(--line); }
.timeline-camera-lane .timeline-lane-label{ color:var(--txt); font-weight:600; }
.timeline-track{ position:relative; height:100%; min-width:0; background-image:linear-gradient(to right,rgba(255,255,255,.035) 1px,transparent 1px); background-size:80px 100%; }
.timeline-span,.timeline-clip,.timeline-event{ position:absolute; box-sizing:border-box; margin:0; cursor:pointer; }
.timeline-span{ top:5px; height:32px; overflow:hidden; border:1px solid var(--line); border-radius:4px; background:var(--panel2); color:var(--muted); padding:0 12px 0 8px; text-align:left; }
.timeline-span span{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font:600 10px/30px var(--ui); }
.timeline-span.step span{ text-align:center; }
.timeline-span.step.active{ border-color:var(--accent); color:var(--link); background:var(--wash); }
.timeline-span.selected{ outline:1px solid var(--accent); outline-offset:-2px; }
/* A chain follower: an ordinary step to author, ONE displayed step to the
   reader (core/step-chain.ts). The left edge is welded to the step before it,
   and the accent tick says the motion runs on from there. */
.timeline-span.step.continues{ border-left-color:var(--accent); border-top-left-radius:0; border-bottom-left-radius:0; }
.timeline-span.step.continues::before{ content:''; position:absolute; left:0; top:9px; bottom:9px; width:2px; background:var(--accent); opacity:.7; }
.timeline-span.bridge{ border-style:dashed; color:var(--low); background:rgba(255,255,255,.015); padding-left:4px; }
.timeline-span.bridge span{ font:600 9px/30px var(--mono); text-align:center; }
.timeline-camera{ position:absolute; top:2px; height:22px; margin:0; overflow:hidden; border:0; border-right:1px solid rgba(255,255,255,.08); background:rgba(255,255,255,.025); color:var(--low); cursor:pointer; padding:0; }
.timeline-camera span{ height:100%; display:flex; align-items:center; justify-content:center; gap:3px; }
.timeline-camera:hover,.timeline-camera:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
.timeline-camera.oriented,.timeline-camera.linked,.timeline-camera.focus-change,.timeline-camera.cover{ color:var(--accent); }
.timeline-camera.focus-change:not(.oriented):not(.linked){ color:var(--link); }
.timeline-camera.focus{ background:rgba(122,162,247,.10); border-right-color:rgba(122,162,247,.22); }
.timeline-camera.active{ background:rgba(169,133,221,.08); }
.timeline-icon{ width:17px; height:17px; display:block; flex:0 0 auto; }
.timeline-camera .timeline-icon{ width:15px; height:15px; }
.timeline-span i,.timeline-clip i{ position:absolute; right:0; top:0; width:7px; height:100%; cursor:ew-resize; border-left:1px solid rgba(255,255,255,.12); }
.timeline-clip{ top:3px; height:20px; min-width:18px; border:1px solid rgba(169,133,221,.45); border-radius:3px; background:rgba(169,133,221,.13); color:var(--link); padding:0 9px 0 5px; }
.timeline-clip.transform{ border-color:rgba(212,190,244,.5); background:linear-gradient(90deg,rgba(169,133,221,.17),rgba(212,190,244,.09)); }
.timeline-clip.selected{ outline:1px solid var(--accent); background:rgba(169,133,221,.28); }
.timeline-clip span{ font:700 14px/18px var(--mono); }
.timeline-clip em{ float:right; padding-right:2px; color:var(--txt); font:700 8px/18px var(--mono); font-style:normal; letter-spacing:.04em; }
.timeline-clip .timeline-fastener-spin{ width:15px; height:18px; display:grid; place-items:center; padding:0; color:var(--accent); }
.timeline-fastener-spin .timeline-icon{ width:14px; height:14px; }
.timeline-clip .timeline-clip-detail{ margin-left:2px; }
.timeline-event{ top:1px; width:24px; height:24px; display:grid; place-items:center; padding:0; border:0; border-radius:3px; background:transparent; color:var(--low); }
.timeline-event .visibility-icon{ width:18px; height:18px; }
.timeline-event.temporary .timeline-icon{ width:16px; height:16px; color:var(--link); }
.timeline-event.reveal{ color:var(--accent); }
.timeline-event.hide{ color:var(--muted); }
.timeline-event:hover,.timeline-event:focus-visible{ outline:none; color:var(--link); background:var(--wash); }
.timeline-tree-label.temporary{ background:rgba(169,133,221,.045); }
.timeline-tree-label.temporary .timeline-target-label{ color:var(--link); }
.timeline-temporary-badge{ flex:0 0 auto; margin-left:7px; padding:2px 4px; border:1px solid rgba(169,133,221,.35); border-radius:3px; color:var(--accent); font:700 8px/1 var(--mono); letter-spacing:.06em; }
.timeline-clip.aggregate,.timeline-event.aggregate{ cursor:default; pointer-events:none; opacity:.72; }
.timeline-clip.aggregate{ border-style:dashed; }
.timeline-event.aggregate{ background:rgba(169,133,221,.05); }
.timeline-child-activity{ position:absolute; top:2px; bottom:2px; box-sizing:border-box; border-left:1px solid rgba(169,133,221,.42); background:rgba(169,133,221,.06); pointer-events:none; }
.timeline-span.inapplicable,.timeline-camera.inapplicable,.timeline-clip.inapplicable,.timeline-event.inapplicable,.timeline-child-activity.inapplicable{ opacity:.28; filter:saturate(.2); }
.timeline-span.inapplicable:hover,.timeline-camera.inapplicable:hover,.timeline-clip.inapplicable:hover,.timeline-event.inapplicable:hover{ opacity:.52; }
.timeline-playhead{ position:absolute; top:0; bottom:0; left:0; width:1px; z-index:7; pointer-events:none; background:var(--accent); box-shadow:0 0 0 1px rgba(169,133,221,.18); transform:translate3d(0,0,0); will-change:transform; }
.timeline-playhead::before{ content:''; position:sticky; top:14px; display:block; margin-left:-4px; width:9px; height:9px; background:var(--accent); clip-path:polygon(0 0,100% 0,50% 100%); }
.timeline-inspector-rail{ position:absolute; top:16px; right:16px; bottom:calc(var(--timeline-h) + 104px); z-index:5; width:var(--timeline-inspector-w); min-height:220px; display:flex; flex-direction:column; overflow:hidden; background:var(--panel); border:1px solid rgba(255,255,255,.08); border-radius:8px; box-shadow:var(--elev-float); color:var(--txt); }
body.preview #timelineInspector,body.orient #timelineInspector,body.operation #timelineInspector,body.tree #timelineInspector,
body.mbuilder #timelineInspector,body.config #timelineInspector,body.projects #timelineInspector,body.deliverables #timelineInspector,
body.builder #timelineInspector,body.deliv #timelineInspector,body.guide #timelineInspector,body.builderdeploy #timelineInspector{ display:none; }
.timeline-inspector-rail-head{ flex:0 0 auto; min-height:66px; display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:15px 14px 13px 18px; border-bottom:1px solid var(--line); }
.timeline-inspector-rail-head>div{ min-width:0; }
.timeline-inspector-rail-head h2{ margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font-size:14px; line-height:1.25; font-weight:600; }
.timeline-inspector-rail-head p{ margin:4px 0 0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font-size:11px; line-height:1.3; }
.timeline-inspector-close{ flex:0 0 32px; width:32px; height:32px; display:grid; place-items:center; margin:-2px 0 0; padding:0; border:1px solid var(--line); border-radius:4px; background:var(--panel2); color:var(--muted); font:500 18px/1 var(--ui); cursor:pointer; }
.timeline-inspector-close:hover,.timeline-inspector-close:focus-visible{ outline:none; border-color:var(--accent); background:var(--wash); color:var(--link); }
.timeline-inspector-scroll{ flex:1 1 auto; min-height:0; height:0; overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; padding:17px 7px 17px 17px; scrollbar-gutter:stable; scrollbar-width:thin; }
.timeline-external-scroll{ padding:0; overflow:hidden; }
.timeline-external-scroll>[data-tl-external-panel]{ height:100%; min-height:0; display:flex; flex-direction:column; }
.timeline-view-as-panel{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.timeline-view-as-config{ flex:1 1 auto; min-height:0; overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; padding:17px 7px 17px 17px; scrollbar-gutter:stable; scrollbar-width:thin; }
.timeline-inspector-section{ display:flex; flex-direction:column; gap:10px; margin:0 0 21px; padding:0 10px 0 0; }
.timeline-inspector-section:last-child{ margin-bottom:0; }
.timeline-inspector-section h3{ margin:0; color:var(--muted); font:600 11px/1.2 var(--ui); letter-spacing:.03em; text-transform:uppercase; }
.timeline-inspector-empty{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px; padding:24px; text-align:center; color:var(--muted); }
.timeline-inspector-empty strong{ color:var(--txt); font-size:13px; font-weight:600; }
.timeline-inspector-empty span{ max-width:26ch; font-size:11px; line-height:1.5; }
.timeline-empty,.timeline-help{ color:var(--low); font-size:11px; line-height:1.45; }
.timeline-narration-note{ display:flex; flex-direction:column; gap:4px; margin:0 10px 20px 0; padding:10px 11px; border-left:2px solid var(--accent); background:rgba(169,133,221,.06); color:var(--low); font-size:11px; line-height:1.45; }
.timeline-narration-note strong{ color:var(--link); font-size:11px; font-weight:600; }
.timeline-inspector-grid,.timeline-vector{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:6px; }
.timeline-vector{ grid-template-columns:repeat(3,minmax(0,1fr)); }
.timeline-inherited{ display:grid; grid-template-columns:auto minmax(0,1fr); gap:7px 12px; align-items:baseline; padding:9px 10px; border:1px solid var(--line); border-radius:6px; background:var(--code); }
.timeline-inherited span{ color:var(--low); font:600 9px/1 var(--mono); text-transform:uppercase; letter-spacing:.04em; }
.timeline-inherited output{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:500 11px/1.3 var(--mono); }
.timeline-field{ min-width:0; display:flex; flex-direction:column; gap:3px; color:var(--low); font:600 9px/1 var(--mono); text-transform:uppercase; letter-spacing:.04em; }
.timeline-field input,.timeline-field select{ width:100%; min-width:0; box-sizing:border-box; padding:8px 9px; background:var(--code); color:var(--txt); border:1px solid rgba(255,255,255,.14); border-radius:8px; font:500 12px/1 var(--mono); }
.timeline-field input:focus,.timeline-field select:focus{ outline:none; border-color:var(--accent); }
.timeline-behavior-list{ display:flex; flex-direction:column; gap:5px; margin-bottom:8px; }
.timeline-behavior-toggle{ display:flex; align-items:center; gap:7px; min-height:28px; padding:4px 7px; border:1px solid rgba(255,255,255,.06); border-radius:4px; background:var(--code); color:var(--txt); font-size:10px; }
.timeline-behavior-toggle input{ accent-color:var(--accent); }
.timeline-participant-heading{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
.timeline-participant-heading .b{ padding:3px 6px; font-size:9px; }
.timeline-participant-list{ display:flex; flex-direction:column; gap:3px; margin:0; padding:0; list-style:none; }
.timeline-participant-list li{ display:grid; grid-template-columns:20px minmax(0,1fr) auto; align-items:center; gap:6px; min-height:30px; padding:4px 6px; border:1px solid rgba(255,255,255,.06); border-radius:3px; background:var(--code); color:var(--muted); font-size:10px; }
.timeline-participant-list li[draggable="true"]{ cursor:grab; }
.timeline-participant-index{ color:var(--low); font:600 9px/1 var(--mono); text-align:center; }
.timeline-participant-name{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); }
.timeline-participant-grip{ grid-column:3; grid-row:1; color:var(--low); letter-spacing:-3px; }
#timelineInspector [data-tl-step-copy]{ margin-top:4px; padding-top:12px; border-top:1px solid var(--line); }
#timelineInspector [data-tl-step-copy] textarea{ min-height:72px; }
.timeline-delete{ width:100%; margin-top:12px; }
.studio-context-menu{ display:none; position:fixed; z-index:80; min-width:200px; max-width:min(320px,calc(100vw - 12px)); padding:5px; background:var(--panel2); border:1px solid var(--line); border-radius:6px; box-shadow:var(--elev); }
.studio-context-menu.open{ display:flex; flex-direction:column; }
.studio-context-menu button{ position:relative; display:flex; align-items:center; justify-content:space-between; gap:18px; min-height:30px; border:0; border-radius:3px; background:transparent; color:var(--txt); padding:7px 9px; text-align:left; font:500 12px/1.2 var(--ui); cursor:pointer; }
.studio-context-menu button[role="menuitemcheckbox"]{ padding-left:27px; }
.studio-context-menu button[role="menuitemcheckbox"]::before{ content:''; position:absolute; left:9px; color:var(--accent); font:700 11px/1 var(--mono); }
.studio-context-menu button[role="menuitemcheckbox"][aria-checked="true"]::before{ content:'\2713'; }
.studio-context-menu button[role="menuitemcheckbox"][aria-checked="mixed"]::before{ content:'\2013'; }
.studio-context-menu .studio-context-label{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.studio-context-menu button small{ margin-left:auto; color:var(--low); font:600 9px/1.2 var(--mono); text-transform:uppercase; white-space:nowrap; }
.studio-context-menu button:hover,.studio-context-menu button:focus-visible{ outline:none; background:var(--wash); color:var(--link); }
.studio-context-menu button:disabled{ background:transparent; color:var(--muted); }
.studio-context-menu button.danger{ color:var(--bad); }
.studio-context-separator{ height:1px; margin:4px 3px; background:var(--line); }
@container stage-timeline (max-width:900px){
  .timeline-stage>i{ display:none; }
  .timeline-nav-picker{ max-width:190px; }
  .timeline-focus-filter span{ display:none; }
}
@media(max-width:1200px){
  .timeline-head{ grid-template-columns:minmax(120px,1fr) minmax(0,auto) auto; gap:8px; }
  .timeline-scale{ display:none; }
}
  .ordrop-menu label:hover{ background:var(--panel); }
  .ordrop-menu label input{ accent-color:var(--accent); }
  .ordrop-menu .ordrop-all{ font-weight:600; }
  .ordrop-menu .ordrop-cat{ color:var(--muted); padding-left:18px; }
  .ordrop-menu .ordrop-cat:last-of-type{ border-bottom:1px solid var(--line); margin-bottom:4px; padding-bottom:7px; }
  .ordrop-menu .mirror-section{ color:var(--low); font:600 10px/1.2 var(--mono); letter-spacing:.04em; text-transform:uppercase; padding:8px 8px 3px; }
  body.mirrorlinked #gizmo{ opacity:.28; pointer-events:none; }
  body.mirrorlinked #orRevert,
  body.mirrorlinked #orStageOrient,
  body.mirrorlinked .orzoom{ opacity:.38; }
  /* ── decision-tree matrix mode: a hand-editable subassembly × option grid (3-state cells) ──
     A separate full-surface mode (like orient/preview): the 3D stage is hidden and replaced by a
     scrollable matrix. Each cell cycles independent → needed(✓) → ruled-out(✗). New matrices are
     seeded from the current project's imported CAD hierarchy. */
  #treePanel{ display:none; }
  body.tree .side, body.tree .play, body.tree .hud, body.tree .gizmo,
  body.tree #c, body.tree .weave, body.tree .weaveGlow, body.tree #orientBar, body.tree #orTop,
  body.tree #pvTop, body.tree #pvCap{ display:none !important; }
  body.tree #treePanel{ display:flex; flex-direction:column; position:absolute; inset:0; z-index:9; background:var(--bg); }
  /* builder-facing build surface: step groups as tiles (Hub gallery-tile kit, studio palette) */
  :root{ --builder-page-max:1280px; --builder-page-pad-x:22px; --builder-page-head-top:20px; --builder-page-body-top:14px; --builder-page-body-bottom:40px; }
  #buildPanel, #projPanel, #delivPanel, #guidePanel{ display:none; scrollbar-gutter:auto; }
  body.builder .side, body.builder .play, body.builder .hud, body.builder .gizmo,
  body.builder #c, body.builder .weave, body.builder .weaveGlow, body.builder #orientBar, body.builder #orTop,
  body.builder #pvTop, body.builder #pvCap{ display:none !important; }
  body.builder #buildPanel{ display:flex; flex-direction:column; position:absolute; inset:0; z-index:10; background:var(--bg); overflow:auto; }
  /* ── STAGE BARS - ONE source (DIR: control bars share one anatomy). Solid header bars = .bartop (buildTop/projTop/
     delivTop); the config bar floats over the 3D = .bartop.floatbar. Edit a stage-bar control ONCE here → every bar follows. ── */
  .bartop{ display:flex; align-items:center; gap:12px; padding:14px 22px; }
  .bartop:not(.floatbar){ border-bottom:1px solid var(--line); background:rgba(27,27,27,.94); position:sticky; top:0; z-index:2; }   /* solid header bars */
  .floatbar{ display:none; position:absolute; left:0; right:0; top:0; z-index:12; pointer-events:none; }   /* config bar: no chrome over the 3D - content floats, empty areas pass clicks to the scene */
  body.config #cfgTop.floatbar, body.preview #pvTop.floatbar{ display:flex; }   /* each floating header belongs to ONE view: a bare .floatbar match showed Configure's bar over playback */
  body.builderdeploy.config #cfgTop.floatbar.builder-page-top, body.builderdeploy.preview #pvTop.floatbar.builder-page-top{ display:grid; }   /* the 3-zone grid survives the display switch on both floating headers */
  .bartop .ttl{ display:flex; align-items:center; gap:8px; }   /* title TEXT is .t-title (17px/600) - this keeps only the lockup-row layout; gap 9->8 to match the sidebar h1 */
  .bartop .acts{ margin-left:auto; display:flex; gap:8px; }
  #bProjects, #bShare, #delivBack{ display:none !important; }   /* breadcrumbs + share QR own these flows now */
  .floatbar .ttl, .floatbar .acts{ pointer-events:auto; }   /* the floating config bar's interactive bits still take clicks */
  .bartop .b{ padding:7px 13px; font:inherit; font-size:12px; display:inline-flex; align-items:center; }   /* look + hover inherited from button.b (it's a button.b); only bar padding/layout differ */
  /* .bartop .b kbd → folded into the .kbd keycap primitive in core/types.css (was a smaller 18/11 re-derivation) */
  /* #buildName / #projName → type .t-mono-name (types.css); the max-width + mobile rules stay below */
  #buildTop #buildName, #delivTop #delivName, #guideTop #guideName{ max-width:28vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }   /* defensive: never let the build name grow into the absolutely-centred journey stepper */
  /* journey stepper (.journey/.jstep/.jsep) -> core/chrome.css (decomposition) */
  @media(max-width:560px){ #buildTop #buildName, #delivTop #delivName{ display:none; } }   /* phone: drop the redundant build label so the title bar doesn't wrap */
  @media(max-width:560px){
    .bartop{ flex-wrap:wrap; align-items:flex-start; gap:8px; padding:12px 18px; }
    .bartop .acts{ margin-left:0; width:100%; min-width:0; display:flex; flex-wrap:wrap; justify-content:flex-start; }
    .bartop .b{ flex:1 1 min(92px,100%); justify-content:center; min-width:0; }
  }
  #buildHd, #projHd, #delivHd, #guideHd, .builder-page-intro{ max-width:var(--builder-page-max); width:100%; margin:0 auto; padding:var(--builder-page-head-top) var(--builder-page-pad-x) 0; box-sizing:border-box; }
  /* #buildHd/#projHd/#delivHd .k → type .t-kicker (11px), grouped in types.css */
  #buildHd .lead, #projHd .lead, #delivHd .lead, #guideHd .lead, .builder-page-intro .lead{ color:var(--muted); font-size:13px; margin-top:6px; }   /* 6px is the shipped value; the base block said 3px and lost to the builderdeploy duplicate */
  body.builderdeploy #buildTop #buildName, body.builderdeploy #projTop #projName, body.builderdeploy #guideTop #guideName, body.builderdeploy #delivTop #delivName,
  body.builder #buildTop #buildName, body.projects #projTop #projName, body.guide #guideTop #guideName, body.deliv #delivTop #delivName{ display:none; }   /* Builder context lives in breadcrumbs, the horizontal configure-choice strip, and page bodies - not beside the MONOLITH Studio title */
  #buildChoiceStrip{ max-width:calc(var(--builder-page-max) - var(--builder-page-pad-x) - var(--builder-page-pad-x)); width:calc(100% - var(--builder-page-pad-x) - var(--builder-page-pad-x)); height:auto; flex:0 0 auto; margin:16px auto 0; padding:0; box-sizing:border-box; display:grid; grid-template-columns:repeat(8,minmax(0,1fr)); overflow:hidden; border:1px solid var(--line); border-radius:8px; background:var(--code); box-shadow:inset 0 1px 0 rgba(255,255,255,.04); }   /* the configuration facts are a recessed read-only panel, not a ruled band: fill + hairline + 8px, deliberately no light and no hover - the affordance stays on the Configure tile's action */
  #buildChoiceStrip[hidden]{ display:none !important; }
  .build-choice-cell{ width:auto; min-width:0; box-sizing:border-box; display:flex; flex-direction:column; align-items:flex-start; justify-content:center; gap:5px; padding:11px 14px 12px; border:0; border-left:1px solid rgba(255,255,255,.07); border-radius:0; background:transparent; color:var(--txt); overflow:hidden; white-space:nowrap; }
  .build-choice-cell:first-child{ border-left:0; }   /* the cells keep their inset inside the panel; padding-left:0 belonged to the flush band */
  .build-choice-cell b{ flex:0 0 auto; min-width:0; max-width:100%; color:var(--low); font:600 9px/1 var(--mono); text-transform:uppercase; letter-spacing:.09em; overflow:hidden; text-overflow:ellipsis; }
  .build-choice-cell span{ flex:0 1 auto; min-width:0; max-width:100%; color:rgba(255,255,255,.87); font:600 12.5px/1 Roboto,system-ui,sans-serif; overflow:hidden; text-overflow:ellipsis; }
  @media(max-width:980px){
    #buildChoiceStrip{ grid-template-columns:repeat(4,minmax(0,1fr)); }
    .build-choice-cell:nth-child(4n+1){ border-left:0; }
    .build-choice-cell:nth-child(n+5){ border-top:1px solid var(--line); }   /* wrapped rows are ruled: with a fill behind them, unruled cells read as one block */
  }
  @media(max-width:600px){
    #buildChoiceStrip{ grid-template-columns:repeat(2,minmax(0,1fr)); }
    .build-choice-cell:nth-child(odd){ border-left:0; }
    .build-choice-cell:nth-child(n+3){ border-top:1px solid var(--line); }
  }
  #buildTiles, #projTiles{ max-width:var(--builder-page-max); width:100%; margin:0 auto; padding:var(--builder-page-body-top) var(--builder-page-pad-x) calc(var(--builder-page-body-bottom) + env(safe-area-inset-bottom, 0px)); box-sizing:border-box; display:grid; grid-template-columns:repeat(auto-fill,minmax(min(340px,100%),1fr)); gap:16px; align-content:start; }   /* 720p (1280) = smallest supported desktop → exactly 3 large columns (max-width 1280 + 340 min caps it at 3, can never reach 4). min(340px,100%) collapses to 1 full-width column on mobile with no overflow. Larger 4:3 tiles preserve more thumbnail detail. */
  .project-empty{ grid-column:1/-1; min-height:220px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; color:var(--muted); text-align:center; }
  .project-empty b, .studio-empty b{ color:var(--txt); font-size:18px; font-weight:650; }   /* --text is not a token (tokens.css defines --txt); the two rules were byte-identical */
  .project-empty span{ font-size:13px; }
  .studio-empty{ position:absolute; inset:0; z-index:24; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; padding:24px; text-align:center; color:var(--muted); background:var(--bg); }
  .studio-empty span{ max-width:420px; font-size:13px; }
  .studio-empty .b{ margin-top:6px; pointer-events:auto; }
  body.studio-empty-state .side{ opacity:.45; }
  @media(max-width:680px){
    body.studio-empty-state .side{ display:none; }
    body.studio-empty-state .stage{ flex:1 1 100%; width:100%; min-width:0; }
  }
  .btile{ box-shadow:none; display:flex; flex-direction:column; cursor:pointer; overflow:hidden; transition:transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease; }
  .btile:hover{ transform:translateY(-1px); border-color:rgba(255,255,255,.2); box-shadow:var(--elev); }   /* the bespoke 0 4px 8px was a third elevation scale */
  .btile .cover{ --stage-progress:0%; --stage-segment:100%; aspect-ratio:16/9; background:#1a1622 center/cover no-repeat; border-bottom:1px solid var(--line); position:relative; overflow:hidden; }   /* the progress values live on the cover and the rail reads them from there; reader-surfaces.ts sets them here */
  .btile .cover::after{ content:''; position:absolute; inset:0; pointer-events:none; z-index:2; background:var(--cover-scrim); }
  .btile .cover .bar{ position:absolute; left:0; right:0; bottom:0; z-index:3; width:100%; height:7px; background:#1c1c1c; box-shadow:inset 0 1px 0 rgba(0,0,0,.55), 0 -1px 3px rgba(0,0,0,.55); }   /* ONE progress indicator: a segment per step, filled to --stage-progress. reader-surfaces.ts is the sole emitter. The outer shadow is the rail's contact shadow on the light plate: a tight dark edge with no spread (.cover clips it to the top side) that keeps the purple apart from the thumbnail without drawing a hairline. */
  .btile .cover .bar::before{ content:''; position:absolute; inset:0; background:repeating-linear-gradient(to right,rgba(255,255,255,.24) 0 calc(var(--stage-segment) - 2px),transparent calc(var(--stage-segment) - 2px) var(--stage-segment)); }
  .btile .cover .bar::after{ content:''; position:absolute; inset:0; background:repeating-linear-gradient(to right,#9674cb 0 calc(var(--stage-segment) - 2px),transparent calc(var(--stage-segment) - 2px) var(--stage-segment)); clip-path:inset(0 calc(100% - var(--stage-progress)) 0 0); transition:clip-path .42s cubic-bezier(.2,.8,.2,1); }   /* the fill animates when a tile re-renders in place. The lit segments do not glow: a purple bleed over the plate lowered the rail's own contrast against the thumbnail (maintainer, 2026-09-04) */
  .btile.seqlocked .cover .bar::before{ background:repeating-linear-gradient(to right,rgba(255,255,255,.11) 0 calc(var(--stage-segment) - 2px),transparent calc(var(--stage-segment) - 2px) var(--stage-segment)); }
  .btile.done .nm .gname::after{ content:' ✓'; color:var(--accent); font-weight:700; }   /* completed flag */
  /* The light thumbnail plate: floor contact, spotlight pool, ONE vignette (showroom.css:15 geometry - two vignettes at
     different centres cancel into a flat wash), a top light that gives the vignette a cause, then the base.
     core/thumb-backdrop.ts bakes the same stack under captured renders. */
  .cover.stagecover{ background:
    linear-gradient(0deg, rgba(43,36,50,.34) 0%, rgba(43,36,50,.12) 10%, rgba(43,36,50,0) 26%),
    radial-gradient(ellipse 60% 42% at 50% 66%, rgba(172,120,252,.16) 0%, rgba(146,90,236,.05) 50%, rgba(146,90,236,0) 100%),
    radial-gradient(ellipse 74% 62% at 50% 58%, rgba(43,36,50,0) 34%, rgba(43,36,50,.13) 66%, rgba(43,36,50,.42) 100%),
    radial-gradient(ellipse 78% 46% at 50% 2%, rgba(255,255,255,.72) 0%, rgba(255,255,255,0) 72%),
    linear-gradient(180deg, var(--thumb-bg0) 0%, var(--thumb-bg1) 56%, var(--thumb-bg2) 100%); }
  .cover.stagecover::before{ content:""; position:absolute; inset:-50vmax; z-index:0; pointer-events:none; opacity:.20; transform:rotate(45deg);
    background:
      linear-gradient(45deg, rgba(255,255,255,.48) 25%, transparent 25% 75%, rgba(255,255,255,.48) 75%),
      linear-gradient(45deg, rgba(74,68,80,.10) 25%, transparent 25% 75%, rgba(74,68,80,.10) 75%),
      linear-gradient(-45deg, rgba(255,255,255,.30) 25%, transparent 25% 75%, rgba(255,255,255,.30) 75%),
      linear-gradient(-45deg, rgba(56,51,63,.075) 25%, transparent 25% 75%, rgba(56,51,63,.075) 75%);
    background-position:0 0, 7px 7px, 0 7px, 7px 0; background-size:14px 14px; }
  .cover.stagecover .stage-thumb{ position:absolute; inset:0; z-index:1; background:center/cover no-repeat; overflow:hidden; }
  .cover.stagecover .stage-thumb::before{ content:""; position:absolute; inset:-50vmax; z-index:1; pointer-events:none; opacity:.055; transform:rotate(45deg); mix-blend-mode:multiply;
    background:
      linear-gradient(45deg, rgba(56,51,63,.22) 25%, transparent 25% 75%, rgba(56,51,63,.22) 75%),
      linear-gradient(45deg, rgba(255,255,255,.34) 25%, transparent 25% 75%, rgba(255,255,255,.34) 75%),
      linear-gradient(-45deg, rgba(74,68,80,.16) 25%, transparent 25% 75%, rgba(74,68,80,.16) 75%),
      linear-gradient(-45deg, rgba(255,255,255,.26) 25%, transparent 25% 75%, rgba(255,255,255,.26) 75%);
    background-position:0 0, 7px 7px, 0 7px, 7px 0; background-size:14px 14px; }
  /* .cover.stagecover::after carried a second vignette at a different centre; the single vignette lives in the background stack above, so ::after is the shared cover scrim again (the builder's seqlocked darkening still rides on it). */
  .cover.stagecover .bar{ z-index:3; }
  .cfgtile .cover{ background:linear-gradient(135deg, rgba(116,80,182,.45), rgba(169,133,221,.12)); display:flex; align-items:center; justify-content:center; font-size:36px; color:var(--accent); }
  /* Configure tile cover - hub th-conf mini-mock (option rows + lit selection → preview panel). Compound .cover.cfgcover overrides the legacy gradient/emoji above; mock children z-index:0 sit under the ::after vignette (1) + progress .bar (2). DIR-040: interchangeable with the hub configurator tile. */
  .cover.cfgcover{ background:radial-gradient(ellipse at 38% 45%, #17131f 0%, #0c0b10 72%) !important; display:block !important; font-size:0 !important; }
  .cover.cfgcover > *{ position:absolute; z-index:0; }
  .cover.cfgcover .opt{ left:8%; width:40%; height:8%; border-radius:3px; background:rgba(255,255,255,.08); }
  .cover.cfgcover .opt:nth-of-type(1){ top:20%; } .cover.cfgcover .opt:nth-of-type(2){ top:36%; } .cover.cfgcover .opt:nth-of-type(3){ top:52%; } .cover.cfgcover .opt:nth-of-type(4){ top:68%; width:30%; background:rgba(255,255,255,.05); }
  .cover.cfgcover .opt.sel{ background:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.28); }   /* the lit, selected option */
  .cover.cfgcover .res{ left:56%; top:14%; width:36%; height:72%; border:1px solid rgba(255,255,255,.09); border-radius:4px; background:rgba(116,80,182,.10); }
  .cover.cfgcover .res i{ position:absolute; left:14%; right:14%; height:6px; border-radius:3px; background:rgba(255,255,255,.10); }
  .cover.cfgcover .res .r1{ top:18%; right:30%; } .cover.cfgcover .res .r2{ top:38%; background:rgba(169,133,221,.40); } .cover.cfgcover .res .r3{ top:58%; } .cover.cfgcover .res .r4{ top:78%; right:40%; }
  /* Deliverables tile cover - a BOM/receipt sheet: purple check ticks (preparation checks) + line items & a qty column (BOM) + a heavier total row + a files/zip pip. Same hub primitives; overrides the legacy .delivtile .cover below. */
  .cover.delivcover{ background:radial-gradient(ellipse at 50% 45%, #16131c 0%, #0c0b10 72%) !important; display:block !important; font-size:0 !important; }
  .cover.delivcover > *{ position:absolute; z-index:0; }
  .cover.delivcover .sheet{ left:13%; top:9%; right:13%; bottom:9%; border:1px solid rgba(255,255,255,.08); border-radius:3px; background:rgba(255,255,255,.035); }
  .cover.delivcover .sheet > i, .cover.delivcover .sheet > .row{ position:absolute; }
  .cover.delivcover .hdr{ left:7%; top:9%; width:44%; height:10%; border-radius:3px; background:rgba(255,255,255,.13); }
  .cover.delivcover .zip{ right:7%; top:8%; width:12%; height:13%; border-radius:3px; background:rgba(169,133,221,.50); box-shadow:0 0 0 1px rgba(169,133,221,.22); }
  .cover.delivcover .row{ left:7%; right:7%; height:8%; }
  .cover.delivcover .row.r1{ top:28%; } .cover.delivcover .row.r2{ top:41%; } .cover.delivcover .row.r3{ top:54%; } .cover.delivcover .row.r4{ top:67%; }
  .cover.delivcover .row i{ position:absolute; top:0; }
  .cover.delivcover .tick{ left:0; width:8%; height:100%; border-radius:3px; background:rgba(169,133,221,.55); }
  .cover.delivcover .line{ left:14%; height:100%; border-radius:3px; background:rgba(255,255,255,.09); }
  .cover.delivcover .r1 .line{ right:28%; } .cover.delivcover .r2 .line{ right:20%; } .cover.delivcover .r3 .line{ right:34%; } .cover.delivcover .r4 .line{ right:24%; }
  .cover.delivcover .qty{ right:0; width:11%; height:100%; border-radius:3px; background:rgba(255,255,255,.06); }
  .cover.delivcover .rule{ left:7%; right:7%; top:84%; height:1px; background:rgba(255,255,255,.10); }
  .cover.delivcover .tot{ left:7%; top:88%; width:30%; height:7%; border-radius:3px; background:rgba(116,80,182,.40); }
  .cover.delivcover .totq{ right:7%; top:88%; width:15%; height:7%; border-radius:3px; background:rgba(255,255,255,.10); }
  .btile .body{ flex:1 1 auto; min-height:116px; box-sizing:border-box; padding:12px 14px; display:flex; flex-direction:column; gap:7px; }
  .btile .nm{ font-size:15px; font-weight:600; color:var(--txt); display:flex; align-items:center; gap:8px; }
  .btile .nm .ix{ font-family:var(--mono); color:var(--low); font-size:12px; font-weight:500; }
  .btile .nm .gname{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .btile .chip{ font-size:10px; font-weight:500; padding:2px 8px; border-radius:4px; background:var(--panel2); border:1px solid var(--line); color:var(--muted); white-space:nowrap; }
  .btile .meta{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }   /* type = .t-meta */
  .btile .facts{ font-size:11px; color:var(--low); font-family:var(--mono); letter-spacing:.01em; }   /* quiet mono facts line */
  .btile .pv{ flex:0 0 36px; min-height:36px; box-sizing:border-box; margin-top:auto; display:flex; align-items:center; justify-content:center; padding:0 12px; text-align:center; font-size:12px; font-weight:600; color:var(--link); background:var(--wash); border:1px solid rgba(169,133,221,.4); border-radius:4px; }
  .btile.locked{ pointer-events:none; }   /* not buildable yet - type .is-inert, no hover affordance */
  .btile.locked .pv{ background:none; color:var(--low); border-color:var(--line); }
  /* .btile.seqlocked - type .is-out-of-sequence (types.css). Still CLICKABLE (override → confirm dialog), unlike .locked. */
  .btile.seqlocked:hover{ filter:grayscale(.45) brightness(.78); transform:none; box-shadow:var(--elev); }   /* lifts out of the out-of-sequence treatment on hover to signal it IS clickable (no big translate - it's not the current step) */
  .btile.seqlocked .pv{ color:var(--low); }
  .btile.seqlocked .pv::before{ content:'Locked - '; }   /* sequence gate prefix without fragile icon glyphs */
  /* breadcrumb trail (.crumbs) -> core/chrome.css (decomposition) */
  /* shared confirm/share/QR dialog (.dlgback/.dlg/.qrcard) -> core/chrome.css (decomposition) */
  .qrslot{ font-size:12px; color:#555; text-align:center; }
  .qrlink{ margin-top:10px; font:11px var(--mono); color:var(--link); word-break:break-all; text-align:center; background:var(--code); border:1px solid var(--line); border-radius:4px; padding:7px 9px; line-height:1.5; }
  .qrcard.qrhidden{ display:none; }   /* QR is generated on demand (Show QR code) */
  .shtoggle{ display:flex; align-items:center; justify-content:space-between; gap:14px; margin:14px 0 8px; cursor:pointer; }   /* "Send my progress" switch */
  .shtoggle.disabled{ }   /* shown but inert when the build has no saved progress to send - type .is-inert */
  .shtoggle .shlbl{ display:flex; flex-direction:column; gap:2px; font-size:13px; color:var(--txt); }
  .shtoggle .shlbl small{ font-size:11px; color:var(--muted); font-weight:400; }
  .shtoggle input{ position:absolute; opacity:0; width:0; height:0; }
  .shtoggle .sw{ flex:0 0 auto; width:38px; height:22px; border-radius:var(--radius-pill); background:var(--code); border:1px solid var(--line); position:relative; transition:background 140ms ease, border-color 140ms ease; }
  .shtoggle .sw::after{ content:''; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:var(--muted); transition:transform 140ms ease, background 140ms ease; }
  .shtoggle input:checked + .sw{ background:var(--wash); border-color:var(--accent); }
  .shtoggle input:checked + .sw::after{ transform:translateX(16px); background:var(--accent); }
  .btile:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--accent), var(--elev); }   /* keyboard focus ring (tiles are role=button) */
  .b:focus-visible, .play button:focus-visible, .cfg-selector .stab:focus-visible, #viewCtl button:focus-visible, .cfgdone:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--accent); }   /* keyboard focus rings on the chrome buttons/toggles (UA outline was suppressed → invisible focus for keyboard nav) */
  #loadOverlay{ position:fixed; inset:0; z-index:20000; display:flex; align-items:center; justify-content:center; background:var(--bg); opacity:1; transition:opacity 180ms ease; }   /* shown until boot routing, config state, and first render settle */
  #loadOverlay.done{ opacity:0; pointer-events:none; }
  #loadOverlay .lo-logo{ text-align:center; margin-bottom:22px; font-size:19px; }   /* branded first impression: the MONOLITH lockup above the loading bar */
  #loadOverlay .lo-logo .lockup{ letter-spacing:.2em; }
  #loadOverlay .lo-bar{ width:220px; height:4px; border-radius:3px; background:rgba(255,255,255,.1); overflow:hidden; margin:0 auto 12px; }
  #loadOverlay .lo-bar span{ display:block; width:38%; height:100%; background:var(--accent); border-radius:3px; animation:loSlide 1.1s ease-in-out infinite; }
  #loadOverlay .lo-txt{ font-size:13px; color:var(--muted); letter-spacing:.02em; text-align:center; }
  @keyframes loSlide{ 0%{ transform:translateX(-120%); } 100%{ transform:translateX(320%); } }
  /* BOOT GATE - the deployed Builder mounts its whole shell at once (builder/shell.js), so the play bar and
     every header, caption, control and panel exist before the sequence, matrix and project have loaded. Until
     builder/app.js confirms a finished boot with `booted`, none of it renders: a failed load is the dark weave
     and the error banner, nothing else (maintainer 2026-09-04: "error banner only"). visibility, not display,
     so the chrome keeps its real box while it waits and the reveal under the load cover costs no reflow. Only
     the deployed Builder adds `bootgate`; the editor's own Builder view is untouched. */
  body.bootgate:not(.booted) :is(.play,#pvTop,#pvCap,#viewCtl,#cfgTop,#cfgBar,#buildPanel,#projPanel,#guidePanel,#delivPanel){ visibility:hidden !important; }
  /* The failure half. Geometry loads before the sequence, so a failed boot otherwise left a half-loaded
     printer standing behind the banner; the model goes with the chrome (maintainer 2026-09-04). Only the
     render viewport is dropped - .weave and .weaveGlow are CSS backdrop and stay, so what is left is the
     dark weave and the banner. `bootfailed` is set on the failure path alone (builder/app.js showError),
     never during a normal boot, so nothing here can reach a booting or booted canvas. */
  body.bootfailed #c{ visibility:hidden !important; }
  /* deployable builder mode (?builder=1): tiles + preview ONLY, zero maintainer chrome or nav */
  body.builderdeploy .side, body.builderdeploy .hud{ display:none !important; }   /* never show the authoring sidebar (also kills the load flash) */
  body.builderdeploy #bBack, body.builderdeploy #bExit, body.builderdeploy #bDeploy{ display:none; }   /* no path back to authoring, and no link-to-itself */
  body.builderdeploy #builderTgl, body.preview #builderTgl, body.builder #builderTgl, body.config #builderTgl, body.deliv #builderTgl, body.guide #builderTgl, body.projects #builderTgl{ display:none; }   /* the Builder-view toggle lives only in the authoring editor's play bar */
  #mbExit{ display:none; position:fixed; left:12px; bottom:12px; z-index:60; padding:8px 13px; background:rgba(27,27,27,.92); border:1px solid var(--line); border-radius:4px; color:var(--muted); cursor:pointer; font:inherit; font-size:12px; backdrop-filter:blur(6px); }
  #mbExit:hover{ color:var(--link); border-color:var(--accent); }
  body.mbuilder #mbExit{ display:inline-flex; align-items:center; }   /* maintainer-only exit from the builder preview (the real deploy hides every exit) */
  /* Configure view: the live 3D preview shows behind a bottom options bar (the configurator without the matrix) */
  body.config .side, body.config .hud, body.config #buildPanel, body.config .play{ display:none !important; }
  body.config #cfgBar{ display:flex; }
  /* highest layer: project-selection tiles */
  body.projects .side, body.projects .play, body.projects .hud, body.projects .gizmo,
  body.projects #c, body.projects .weave, body.projects .weaveGlow, body.projects #orientBar, body.projects #orTop,
  body.projects #pvTop, body.projects #pvCap, body.projects #buildPanel, body.projects #guidePanel, body.projects #cfgBar, body.projects #treePanel{ display:none !important; }
  body.projects #projPanel{ display:flex; flex-direction:column; position:absolute; inset:0; z-index:10; background:var(--bg); overflow:auto; }
  body.projects #projHd{ margin-top:0; text-align:left; }
  body.projects #projTiles{ margin-bottom:0; }
  /* Deliverables view */
  body.deliv .side, body.deliv .play, body.deliv .hud, body.deliv .gizmo, body.deliv #c, body.deliv .weave, body.deliv .weaveGlow, body.deliv #orientBar, body.deliv #buildPanel, body.deliv #guidePanel, body.deliv #cfgBar, body.deliv #pvTop, body.deliv #pvCap, body.deliv #projPanel{ display:none !important; }
  body.deliv #delivPanel{ display:flex; flex-direction:column; position:absolute; inset:0; z-index:10; background:var(--bg); overflow:auto; }
  body.guide .side, body.guide .play, body.guide .hud, body.guide .gizmo, body.guide #c, body.guide .weave, body.guide .weaveGlow, body.guide #orientBar, body.guide #buildPanel, body.guide #delivPanel, body.guide #cfgBar, body.guide #pvTop, body.guide #pvCap, body.guide #projPanel{ display:none !important; }
  body.guide #guidePanel{ display:flex; flex-direction:column; position:absolute; inset:0; z-index:10; background:var(--bg); overflow:auto; }
  body.guide #guideTop{ min-height:42px; padding-top:10px; padding-bottom:10px; }
  /* #delivName → type .t-mono-name (types.css) */
  #delivBody, #guideBody, .builder-page-body{ max-width:var(--builder-page-max); width:100%; margin:0 auto; padding:var(--builder-page-body-top) var(--builder-page-pad-x) calc(44px + env(safe-area-inset-bottom, 0px)); box-sizing:border-box; display:flex; flex-direction:column; gap:28px; }
  .delivsec h3{ font-size:13px; font-weight:700; color:var(--txt); margin:0 0 10px; display:flex; align-items:baseline; gap:9px; }
  .delivsec h3 .delivc{ font-family:var(--mono); font-size:12px; color:var(--low); font-weight:500; }
  .delivnote{ font-size:12.5px; color:var(--muted); line-height:1.55; }
  .action-details{ border:1px solid var(--bad-rest); border-radius:8px; background:var(--bad-fill); margin-top:10px; overflow:hidden; }
  .action-details summary{ cursor:pointer; display:flex; align-items:baseline; gap:9px; padding:10px 12px; color:var(--txt); }
  .action-details summary b{ font-size:12px; }
  .action-details summary span{ color:var(--muted); font-size:12px; }
  .action-details-body{ border-top:1px solid rgba(239,83,80,.22); padding:10px 12px; display:flex; flex-direction:column; gap:8px; }
  .action-details-row{ display:grid; grid-template-columns:minmax(0,1fr); gap:2px; align-items:start; }   /* label ABOVE value: the 72px + ellipsis layout hid the end of a failure URL, which is the only reason the row exists */
  .action-details-row span{ color:var(--low); font:700 10px/1.2 var(--mono); text-transform:uppercase; }
  .action-details-row code{ min-width:0; overflow-wrap:anywhere; color:var(--txt); font:600 11px/1.35 var(--mono); }
  .action-details-actions{ display:flex; justify-content:flex-start; }
  #bomNote{ margin-bottom:10px; }
  #filesSec .dlrow{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin-top:12px; }
  #filesSec .dlbtn{ border:1px solid var(--primary-hi); border-radius:4px; padding:11px 18px; font:inherit; font-size:15px; font-weight:600; cursor:pointer; transition:background .12s; }   /* prominent 15px - a page CTA, same weight as the play bar (departure 23) */
  #filesSec .dlbtn:hover:not(:disabled){ background:var(--primary-hi); }
  #filesSec .dlbtn:focus-visible{ outline:none; box-shadow:0 0 0 2px var(--accent); }
  #filesSec .dlprog{ font-size:12.5px; color:var(--link); font-family:var(--mono); min-height:1em; }
  table.bom{ width:100%; border-collapse:collapse; }
  table.bom th{ text-align:left; padding:6px 10px; border-bottom:1px solid var(--line); }   /* type = .t-section (11px) */
  table.bom td{ font-size:13px; color:var(--txt); padding:9px 10px; border-bottom:1px solid var(--line); vertical-align:top; }
  table.bom td.qty{ font-family:var(--mono); color:var(--accent); max-width:8ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  table.bom td.filescell{ white-space:nowrap; text-align:right; width:1%; }
  table.bom a{ color:var(--link); text-decoration:none; white-space:nowrap; }
  table.bom a:hover{ text-decoration:underline; }
  .bomcat{ margin-bottom:10px; overflow:hidden; }
  @media(max-width:680px){
    /* three columns cannot hold a part name at phone width. One line per row: name + STL on top,
       the quantity and process as a mono meta line beneath. */
    table.bom thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
    table.bom tr{ display:grid; grid-template-columns:minmax(0,1fr) auto; column-gap:10px; padding:9px 10px; border-bottom:1px solid var(--line); }
    table.bom td{ padding:0; border:0; }
    table.bom td.qty{ grid-column:1; grid-row:2; max-width:none; color:var(--low); font-size:11px; }
    table.bom td:not(.qty):not(.filescell){ grid-column:1; grid-row:1; min-width:0; overflow-wrap:anywhere; }
    table.bom td.filescell{ grid-column:2; grid-row:1/3; align-self:center; width:auto; }
  }
  .bomcat > summary{ list-style:none; cursor:pointer; display:flex; align-items:center; gap:10px; padding:11px 14px; font-size:13px; font-weight:600; color:var(--txt); }
  .bomcat > summary::-webkit-details-marker{ display:none; }
  .bomcat > summary::before{ content:'▸'; color:var(--accent); font-size:11px; transition:transform .15s ease; }
  .bomcat[open] > summary::before{ transform:rotate(90deg); }
  .bomcat .bcname{ flex:1; }
  .bomcat .bccount{ font-family:var(--mono); font-size:11px; color:var(--low); font-weight:500; }
  .bomcat[open] table.bom{ border-top:1px solid var(--line); }
  .bomcat table.bom td:first-child{ padding-left:14px; } .bomcat table.bom td:last-child{ padding-right:14px; }
  .bomcat table.bom tr:last-child td{ border-bottom:none; }
  .preflight-sec{ margin-bottom:14px; }
  .preflight-sec .pft{ margin-bottom:6px; }   /* type = .t-section (12px) */
  .preflight-sec ul{ margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:6px; }   /* the only disc-bulleted list in the builder - check rows instead */
  .preflight-sec li{ display:grid; grid-template-columns:auto minmax(0,1fr); align-items:start; gap:10px; padding:10px 12px; background:var(--panel2); border:1px solid var(--line); border-radius:8px; font-size:13px; color:var(--muted); line-height:1.55; }
  .preflight-sec li .tick{ width:8px; height:14px; margin-top:3px; border-radius:3px; background:rgba(169,133,221,.55); }   /* the same purple tick the deliverables cover draws */
  .preflight-sec li span{ min-width:0; overflow-wrap:anywhere; }
  .guide-main{ display:block; width:100%; min-width:0; }
  .guide-validation-summary{ border:1px solid var(--bad-rest); border-radius:8px; background:var(--bad-fill); padding:10px 12px; margin-top:12px; color:var(--txt); }
  .guide-validation-summary b{ display:block; font-size:12px; margin-bottom:6px; }
  .guide-validation-summary ul{ margin:0; padding-left:18px; color:var(--muted); font-size:12px; line-height:1.55; }
  .guidetile .cover{ background:radial-gradient(ellipse at 44% 45%, #17131f 0%, #0c0b10 72%) !important; display:block !important; font-size:0 !important; }
  .cover.guidecover > *{ position:absolute; z-index:0; }
  .cover.guidecover .qline{ left:13%; right:13%; height:7%; border-radius:3px; background:rgba(255,255,255,.10); }
  .cover.guidecover .q1{ top:18%; right:34%; } .cover.guidecover .q2{ top:33%; right:24%; } .cover.guidecover .q3{ top:48%; right:42%; }
  .cover.guidecover .choice{ left:13%; width:24%; height:11%; border-radius:3px; background:rgba(255,255,255,.065); }
  .cover.guidecover .c1{ top:66%; } .cover.guidecover .c2{ top:66%; left:41%; background:rgba(116,80,182,.50); box-shadow:0 0 0 1px rgba(169,133,221,.22); } .cover.guidecover .c3{ top:66%; left:69%; }
  .cover.guidecover .route{ left:23%; right:23%; top:84%; height:5%; border-radius:3px; background:rgba(169,133,221,.36); }
  .delivtile .cover{ background:linear-gradient(135deg, rgba(116,80,182,.4), rgba(169,133,221,.1)); display:flex; align-items:center; justify-content:center; font-size:32px; }
  .projtile .projectcover{ display:flex; align-items:center; justify-content:center; font:700 40px/1 var(--mono); color:rgba(32,28,38,.62); }
  .project-thumb-fallback{ position:relative; z-index:0; }
  .project-thumb{ position:absolute; inset:0; z-index:0; width:100%; height:100%; display:block; object-fit:cover; }
  /* Standalone Builder refinement. Keep the authoring Studio and playback chrome outside this boundary. */
  body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop,#pvTop).builder-page-top{ height:54px; min-height:54px; box-sizing:border-box; padding:14px 22px; grid-template-columns:minmax(max-content,1fr) auto minmax(max-content,1fr); align-items:center; gap:12px; border-bottom:1px solid transparent; }   /* symmetric 3-zone grid: equal 1fr flanks hold TRUE screen centre while there is room, and minmax(max-content,...) stops a flank shrinking under its own lockup - so the stepper gets pushed rather than overlapping. It is IN FLOW; the old position:absolute left:50% is what let it sit on top of the wordmark. */
  body.builderdeploy :is(#buildTop,#guideTop,#projTop,#delivTop).builder-page-top{ display:grid; }   /* the SOLID page headers show with their panel; the floating Configure one stays owned by .floatbar/body.config */
  body.builderdeploy .builder-page-top > .ttl{ grid-column:1; justify-self:start; min-width:0; }
  body.builderdeploy .builder-page-top > .journey{ grid-column:2; justify-self:center; }
  body.builderdeploy .builder-page-top > .acts{ grid-column:3; justify-self:end; }
  body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop,#pvTop).builder-page-top:not(.floatbar){ background:rgba(27,27,27,.94); border-bottom-color:var(--line); }
  /* scrollbar-gutter:auto, not stable: this scrollbar is fully transparent, so a reserved gutter buys
     nothing visually while taking 10px out of the header's content box, which pushed Configure's stepper
     5px left of every other surface. #pvTop was never in this rule, so the two floating headers also
     disagreed with each other. */
  body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop).builder-page-top.floatbar{ overflow-x:hidden; overflow-y:auto; scrollbar-gutter:auto; scrollbar-width:thin; scrollbar-color:transparent transparent; background:transparent; border-bottom-color:transparent; }
  body.builderdeploy :is(#buildPanel,#projPanel,#delivPanel,#guidePanel){ overflow-x:hidden; overflow-y:auto; scrollbar-gutter:stable; }
  body.builderdeploy :is(.builder-page-top,#pvTop) .t-title{ display:flex; align-items:center; gap:8px; }
  body.builderdeploy :is(.builder-page-top,#pvTop) .t-title::after{ content:'BETA'; display:inline-flex; align-items:center; justify-content:center; align-self:center; padding:3px 5px 2px; border-radius:3px; background:rgba(116,80,182,.32); color:#cdb9ef; font:700 9px/1.35 var(--mono); letter-spacing:.13em; }
  body.builderdeploy .builder-page-top .journey{ position:static; left:auto; top:auto; transform:none; gap:7px; }   /* in flow now - the absolute centring hack is gone */
  body.builderdeploy .builder-page-top .journey .jn{ padding-top:0; }
  body.builderdeploy .builder-page-top .journey .jsep{ width:18px; }
  @media(max-width:1018px){ body.builderdeploy .builder-page-top .journey .jsep{ width:8px; } }   /* separators tighten with the labels (chrome.css owns the label step) */
  /* CONFIGURE compacts earlier. Its options island keeps the same 16px inset as its right and bottom
     edges, so the island and the viewer control beside it sit IN the header band (a lower island read as
     an asymmetric gap - maintainer 2026-09-04). The stepper stays on the true screen centre like every
     other surface and yields instead: the island column costs it 496px on the right (14 inset + 74
     cluster + 28 park gap + 380 island), and the header's 12px grid gap is kept clear of the cluster.
       full stepper 558px: W/2 + 279 + 12 <= W - 496  ->  labels stay above 1574
       compact stepper 276px: W/2 + 138 + 12 <= W - 496  ->  numerals stay above 1292
     Below 1292 the compact stepper is PUSHED left, only as far as the cluster needs (maintainer
     2026-09-04: "push it left only when colliding"). The header already refuses to let its LEFT flank
     shrink under the lockup's max-content, which pushes the stepper off centre rather than under the
     wordmark; Configure gives the RIGHT flank the same floor with an empty grid item: 474px = the
     496px cluster edge + 12px clearance - 22px header padding - 12px grid gap. Above 1292 both flanks
     are wider than that anyway, so the stepper is on the shared centre pixel; below it the left flank
     gives way pixel for pixel until it reaches the lockup, at 1025 (22 + 207 lockup + 12 + 276 + 12 +
     474 + 22). At and below 1024 the grid overflows and the stepper hides, for exactly as long as the
     island is a side column (min-width matches the bottom-sheet switch below); once the island is a
     bottom sheet the header is free again and the shared 760px rule takes over. */
  @media(max-width:1573px){
    body.builderdeploy.config .builder-page-top .jstep:not(.active) .jlbl{ display:none; }
    body.builderdeploy.config .builder-page-top .journey .jsep{ width:8px; }
  }
  @media(min-width:901px) and (max-width:1291px){
    body.builderdeploy.config #cfgTop.builder-page-top::after{ content:''; grid-column:3; min-width:474px; pointer-events:none; }   /* the floor, not a reservation: it takes no width the stepper could have used */
  }
  @media(min-width:901px) and (max-width:1024px){ body.builderdeploy.config .builder-page-top .journey{ display:none; } }
  /* Below 760 the stepper is hidden entirely, so there is no centre to hold and the max-content flanks
     only serve to push the header wider than the screen. Let the lockup shrink again at phone width. */
  @media(max-width:760px){
    body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop,#pvTop).builder-page-top{ grid-template-columns:minmax(0,1fr) auto auto; padding:14px 16px; }
    body.builderdeploy .builder-page-top > .ttl{ min-width:0; overflow:hidden; }
  }
  body.builderdeploy .builder-page-top .acts{ position:static; right:auto; top:auto; width:auto; min-width:0; margin-left:0; flex-wrap:nowrap; justify-content:flex-end; transform:none; }   /* the grid's third zone right-aligns it; no absolute offset to hand-tune */
  body.builderdeploy .builder-page-top .acts .b{ flex:0 0 auto; }

  body.builderdeploy :is(#buildHd,#guideHd,#delivHd,#projHd){ padding-top:18px; }
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd) .crumbs{ gap:9px; margin-bottom:11px; }
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd) .crumbs .clink{ display:flex; align-items:center; gap:7px; height:30px; padding:0 4px 0 0; }   /* colour/weight now come from chrome.css - base and builder agree on loud-link crumbs */
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd) .crumbs .clink::before{ content:'\2039'; color:#b99ae6; font-size:13px; font-weight:500; }
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd) .crumbs .csep{ font-size:0; }
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd) .crumbs .csep::before{ content:'/'; color:rgba(255,255,255,.28); font-size:12px; }
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd,#projHd) .k{ display:flex; align-items:center; gap:14px; }   /* type .t-kicker--page owns the font; this is the layout only */
  body.builderdeploy :is(#buildHd,#guideHd,#delivHd,#projHd) .k::after{ content:''; flex:1; height:1px; background:linear-gradient(to right,rgba(169,133,221,.34),rgba(255,255,255,.06) 40%,rgba(255,255,255,.05)); }
  body.builderdeploy.builder #buildTiles{ padding-top:18px; }

  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile){ position:relative; min-height:76px; background:var(--panel); border-color:var(--line); border-radius:8px; box-shadow:none; transform:none; transition:transform .22s cubic-bezier(.2,.8,.2,1),border-color .22s cubic-bezier(.2,.8,.2,1); }   /* one curve with the stage tiles; scoped to the three entry classes, the base .btile keeps its 140ms */
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile):hover{ border-color:rgba(169,133,221,.42); box-shadow:none; transform:translateY(-2px); }   /* an accent edge and the shared 2px lift; NO tinted shadow and no emission - these are secondary to the stage grid and must not compete with it */
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .cover{ display:none !important; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .body{ position:relative; min-height:76px; padding:13px 100px 13px 15px; display:grid; grid-template-columns:20px minmax(0,1fr); grid-template-rows:auto auto; align-content:center; column-gap:15px; row-gap:4px; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .body::before{ content:''; grid-column:1; grid-row:1/3; align-self:center; width:20px; height:20px; background-repeat:no-repeat; }
  body.builderdeploy.builder #buildTiles > .guidetile .body::before{ background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Crect x='0' y='1' width='20' height='3' rx='1.5' fill='white' fill-opacity='.34'/%3E%3Crect x='0' y='8' width='12' height='4' rx='2' fill='white' fill-opacity='.72'/%3E%3Crect x='0' y='16' width='16' height='3' rx='1.5' fill='white' fill-opacity='.34'/%3E%3C/svg%3E"); }
  body.builderdeploy.builder #buildTiles > .cfgtile .body::before{ background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Crect x='0' y='3' width='20' height='3' rx='1.5' fill='white' fill-opacity='.34'/%3E%3Crect x='11' y='0' width='6' height='9' rx='2' fill='white' fill-opacity='.72'/%3E%3Crect x='0' y='14' width='20' height='3' rx='1.5' fill='white' fill-opacity='.34'/%3E%3Crect x='3' y='11' width='6' height='9' rx='2' fill='white' fill-opacity='.72'/%3E%3C/svg%3E"); }
  body.builderdeploy.builder #buildTiles > .delivtile .body::before{ background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Crect x='8.5' y='0' width='3' height='11' rx='1.5' fill='white' fill-opacity='.72'/%3E%3Cpath d='M14.5 5.5v8h-8' transform='rotate(45 10.5 9.5)' fill='none' stroke='white' stroke-opacity='.72' stroke-width='3' stroke-linecap='butt' stroke-linejoin='round'/%3E%3Crect x='0' y='17' width='20' height='3' rx='1.5' fill='white' fill-opacity='.34'/%3E%3C/svg%3E"); }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .nm{ grid-column:2; grid-row:1; min-width:0; color:var(--txt); font-size:14px; font-weight:600; line-height:1.25; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .meta{ grid-column:2; grid-row:2; min-width:0; color:var(--low); font-size:12px; line-height:1.4; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .facts{ display:none; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .pv{ position:absolute; right:18px; top:50%; width:auto; min-width:0; min-height:0; height:auto; margin:0; padding:0; transform:translateY(-50%); background:transparent; border:0; border-radius:0; color:#b99ae6; font-size:12.5px; font-weight:500; transition:color .22s cubic-bezier(.2,.8,.2,1); }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile):hover .pv{ background:transparent; border:0; color:#cdb9ef; }
  body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) + :is(.stagetile,.soontile){ grid-column-start:1; }   /* the coming-soon tile of a withheld path starts its own row like a stage tile, so the Configure row keeps its utility height instead of stretching to the thumbnail */

  /* Stage and project tile chrome. The box-shadow is COMPOSED from three slots so no state clobbers another: the
     keyboard ring (:focus-visible), the resting elevation, and an accent-tinted second layer that lifts on hover. The
     tint is not a new elevation scale, and .seqlocked / .locked never receive it. */
  body.builderdeploy :is(.stagetile,.projtile){ --tile-ring:0 0 0 0 transparent; --tile-elev:0 0 0 0 transparent; --tile-tint:0 0 0 0 transparent; position:relative; background:var(--panel); border-color:var(--line); border-radius:8px; box-shadow:var(--tile-ring), var(--tile-elev), var(--tile-tint); transition:transform .22s cubic-bezier(.2,.8,.2,1),border-color .22s cubic-bezier(.2,.8,.2,1),box-shadow .22s cubic-bezier(.2,.8,.2,1); }
  body.builderdeploy .stagetile:is(.done,.inprogress), body.builderdeploy .projtile:not(.locked,.ready){ border-color:rgba(255,255,255,.12); --tile-elev:0 2px 10px rgba(0,0,0,.34); --tile-tint:0 8px 22px -10px rgba(116,80,182,.24); }
  body.builderdeploy .stagetile:is(.done,.inprogress):hover, body.builderdeploy .projtile:not(.locked,.ready):hover{ --tile-tint:0 16px 34px -12px rgba(116,80,182,.34); }
  /* THE actionable tile (.ready is unique on the stage grid; at most one project carries it): the rim REPLACES the lighter
     border - the tile keeps var(--line) and a 1px gradient rim sits just inside it, so the corner edge is drawn once. */
  body.builderdeploy :is(.stagetile,.projtile).ready{ border-color:var(--line); --tile-elev:0 2px 10px rgba(0,0,0,.34); --tile-tint:0 12px 30px -12px rgba(116,80,182,.4); }
  body.builderdeploy :is(.stagetile,.projtile).ready:hover{ --tile-tint:0 18px 40px -14px rgba(116,80,182,.5); }
  body.builderdeploy :is(.stagetile,.projtile).ready::before{ content:''; position:absolute; inset:0; z-index:6; border-radius:8px; padding:1px; background:linear-gradient(180deg,rgba(169,133,221,.62),rgba(169,133,221,.14) 34%,rgba(255,255,255,.05)); -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0); -webkit-mask-composite:xor; mask-composite:exclude; pointer-events:none; }
  body.builderdeploy :is(.stagetile,.projtile):focus-visible{ --tile-ring:0 0 0 2px var(--accent); }   /* the keyboard ring is appended to whatever the state composes, so it always wins over the tint */
  body.builderdeploy :is(.stagetile:not(.seqlocked),.projtile:not(.locked)):hover{ transform:translateY(-2px); }   /* 1px is invisible at 44px+ row heights */
  body.builderdeploy :is(.stagetile,.projtile) .cover{ aspect-ratio:4/3; }   /* no background here on purpose: .cover.stagecover owns the light showroom surface, and this rule outranks it (0,3,1 vs 0,2,0). It used to repaint the old dark gradient, so covers with no rendered image stayed dark in the builder only. */
  body.builderdeploy :is(.stagetile,.projtile) .cover::before{ opacity:.10; }   /* the plate's weave stays on in the builder at .10 (authoring keeps .20): the 14px cell is coarse, so .10 is about the ceiling before it reads as perforated sheet */
  body.builderdeploy .stagetile .stage-thumb::before{ display:none; }   /* the multiply weave over a captured render stays off - the capture bakes its own plate */
  /* The rail IS the stage cover's bottom edge, so the .btile hairline is dropped here. It sat under the rail, and because the
     light plate paints to the border box it showed through the translucent line as a white seam between the rail and the
     title block - one the concept (whose cover had no plate of its own) never showed. The rail's contact shadow carries the
     edge instead. Project covers keep the hairline: they have no rail. */
  body.builderdeploy :is(.stagetile,.projtile) .cover{ border-bottom:0; }   /* maintainer 2026-09-04: no hairline under any tile cover - it showed as a bright seam over the light plate */
  body.builderdeploy .stagetile.seqlocked .cover::after{ background:var(--cover-scrim),rgba(9,8,11,.26); }
  body.builderdeploy :is(.stagetile,.projtile) :is(.stage-thumb,.project-thumb){ position:absolute; inset:0; z-index:1; width:100%; height:100%; display:block; object-fit:cover; background-position:center; background-size:cover; background-repeat:no-repeat; transition:transform .5s cubic-bezier(.2,.7,.2,1),filter .18s ease; }
  body.builderdeploy :is(.stagetile:not(.seqlocked),.projtile:not(.locked)):hover :is(.stage-thumb,.project-thumb){ transform:scale(1.035); }
  body.builderdeploy .projtile .project-thumb-fallback{ z-index:1; }
  body.builderdeploy .stagetile.seqlocked{ filter:none; }   /* the builder greys the THUMB only (below) so the stage name stays legible */
  body.builderdeploy .stagetile.seqlocked:hover{ filter:none; transform:none; border-color:var(--line); box-shadow:none; }
  body.builderdeploy .stagetile.seqlocked .cover{ filter:grayscale(.75) brightness(.62); }   /* the COVER, not the tile: "later, not yet" still has to be readable, so the stage name and step count keep full contrast */
  body.builderdeploy :is(.stagetile,.projtile) .body{ min-height:155px; padding:13px 15px 0; display:grid; column-gap:15px; row-gap:0; }
  body.builderdeploy .stagetile .body{ grid-template-columns:38px minmax(0,1fr); grid-template-rows:auto auto auto minmax(0,1fr) 44px; }   /* two digits: 30px mono is ~18px per digit, so the old 19px track held exactly one and stage 10 overran into the 15px gap and then the title */
  body.builderdeploy .stagetile .nm{ display:contents; }
  body.builderdeploy .stagetile .nm .ix{ grid-column:1; grid-row:1/4; width:38px; align-self:start; margin-top:-1px; color:rgba(255,255,255,.8); font:500 30px/1 var(--mono); letter-spacing:0; }   /* left-aligned on purpose: single digits stay exactly where they were, the second digit just has somewhere to go */
  body.builderdeploy :is(.stagetile,.projtile) .nm .gname{ color:var(--txt); font-size:15px; font-weight:600; line-height:1.3; overflow:visible; text-overflow:clip; white-space:normal; text-wrap:pretty; }
  body.builderdeploy .stagetile .nm .gname{ grid-column:2; grid-row:1; }
  body.builderdeploy .stagetile.done .nm .gname::after{ content:none; }
  body.builderdeploy :is(.stagetile,.projtile) .meta{ margin-top:7px; padding:0; color:var(--low); font-size:12px; line-height:1.4; white-space:normal; }
  body.builderdeploy .stagetile .meta{ grid-column:2; grid-row:2; }
  body.builderdeploy :is(.stagetile,.projtile) .facts{ margin-top:7px; padding:0; color:var(--low); font:400 11px/1 var(--mono); }
  body.builderdeploy .stagetile .facts{ grid-column:2; grid-row:3; }
  body.builderdeploy .stagetile .chip{ position:absolute; top:11px; right:11px; z-index:4; display:flex; align-items:center; gap:6px; padding:4px 9px; border-radius:4px; background:rgba(8,9,11,.72); border:1px solid rgba(255,255,255,.16); color:rgba(255,255,255,.82); font:500 10px/1.3 var(--mono); letter-spacing:.05em; text-transform:uppercase; }
  body.builderdeploy .stagetile.done .chip{ border-color:rgba(150,116,203,.62); color:#b99ae6; }
  body.builderdeploy .stagetile.done .chip::before{ content:'\2713'; font-size:11px; font-weight:700; line-height:1; }
  body.builderdeploy .stagetile.seqlocked .chip{ border-color:rgba(255,255,255,.1); color:rgba(255,255,255,.42); }
  body.builderdeploy .stagetile.done .nm .ix{ color:#b99ae6; }
  body.builderdeploy .stagetile.inprogress .nm .ix{ color:rgba(255,255,255,.92); }
  body.builderdeploy .stagetile.seqlocked .nm .ix{ color:rgba(255,255,255,.54); }
  body.builderdeploy .stagetile.seqlocked .nm .gname{ color:rgba(255,255,255,.62); }
  body.builderdeploy .stagetile.seqlocked :is(.meta,.facts){ color:rgba(255,255,255,.3); }
  body.builderdeploy :is(.stagetile,.projtile) .pv{ width:auto; height:44px; min-height:44px; margin:0 -15px; padding:0; display:grid; place-items:center; align-self:end; justify-content:stretch; background:var(--panel2); border:0; border-top:1px solid var(--line); border-radius:0; color:var(--muted); font-size:12.5px; font-weight:500; }
  body.builderdeploy .stagetile .pv{ grid-column:1/-1; grid-row:5; }
  body.builderdeploy :is(.stagetile,.projtile).ready .pv, body.builderdeploy :is(.stagetile,.projtile).ready:hover .pv{ background:linear-gradient(180deg,#7d59bf,#6d49ae); box-shadow:inset 0 1px 0 rgba(255,255,255,.18); border-color:#9674cb; color:#fff; font-weight:600; }   /* the one filled-primary per surface reads lit rather than printed: the same two token hues as a gradient under a top highlight */
  body.builderdeploy .stagetile.done .pv, body.builderdeploy .stagetile.done:hover .pv{ background:var(--panel2); border-color:var(--line); color:var(--muted); }
  body.builderdeploy .stagetile.inprogress .pv, body.builderdeploy .stagetile.inprogress:hover .pv{ background:var(--panel2); border-color:var(--line); color:#b99ae6; }
  body.builderdeploy :is(.stagetile.seqlocked,.projtile.locked) .pv{ background:var(--code); border-color:var(--line); color:var(--low); }   /* was the .38 literal, and on --code that read 3.49:1 - the worst of the six the token raise never reached */
  /* Swapping the label via ::before puts TWO items in a display:grid .pv - the pseudo and the anonymous
     box around the real text - so the button became two stretched 21.5px rows and "Locked" centred in the
     top half, ~11px above every other tile's label. align-content packs the rows to the middle, so the
     visible row lands where the normal single-row label does. */
  body.builderdeploy .stagetile.seqlocked .pv, body.builderdeploy .stagetile.seqlocked:hover .pv{ font-size:0; line-height:0; align-content:center; }
  body.builderdeploy .stagetile.seqlocked .pv::before{ content:'Locked'; font-size:12.5px; line-height:20px; }

  body.builderdeploy .projtile .body{ grid-template-columns:minmax(0,1fr); grid-template-rows:auto auto minmax(0,1fr) 44px; }
  body.builderdeploy .projtile .nm{ grid-column:1; grid-row:1; min-width:0; display:block; }
  body.builderdeploy .projtile .nm .gname{ display:block; }
  body.builderdeploy .projtile .meta{ grid-column:1; grid-row:2; }
  body.builderdeploy .projtile .facts{ grid-column:1; grid-row:3; }
  body.builderdeploy .projtile .pv{ grid-column:1; grid-row:4; }
  /* A sparse selector (1-3 projects) centres in the remaining panel instead of sitting top-left on an otherwise empty page.
     #projPanel is a flex column, so growing the grid gives it exactly the height below the header and page head without
     measuring that chrome. 400px is deliberate: (1236 - 32) / 3 = 401.33, so a single centred tile is the size it would be
     in a 3-up row - it moves, it does not grow. Gated on :has(), so 4+ projects keep the top-aligned auto-fill grid exactly. */
  body.builderdeploy #projTiles:has(> .projtile:nth-child(-n+3):last-child){ flex:1 0 auto; align-content:center; justify-content:center; grid-template-columns:repeat(auto-fit,minmax(min(340px,100%),400px)); }
  @media(max-width:560px){
    body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .body{ padding-right:88px; }
    body.builderdeploy.builder #buildTiles > :is(.guidetile,.cfgtile,.delivtile) .pv{ right:14px; }
  }
  /* Configure - a proper panel: right rail on desktop, bottom sheet on mobile */
  /* --cfg-island-w is the ONE place the options island's width is stated. The header's right-flank
     reservation and the viewport-chrome park distance are both built from it, so they cannot drift
     apart the way a second literal would. */
  #cfgBar{ --cfg-island-w:380px; --cfg-island-gap:16px; display:none; flex-direction:column; position:absolute; z-index:11; top:16px; right:16px; bottom:16px; left:auto; margin:0; width:var(--cfg-island-w);   /* island extends to the top with a uniform 16px margin matching bottom + right; the Configure stepper compacts around it (see the header rules) */
    box-shadow:var(--elev-float); overflow:hidden; transition:transform 220ms ease; }   /* radius matches the .play preview bar (8px) */
  #cfgBar .cfgttl{ flex:0 0 auto; padding:17px 18px 14px; border-bottom:1px solid var(--line); display:flex; flex-direction:column; gap:0; font-size:14px; text-transform:none; letter-spacing:0; font-weight:600; color:var(--txt); }
  #cfgBar .cfgttl .lead{ margin-top:6px; color:var(--muted); font-size:13px; font-weight:400; line-height:1.5; }   /* same kicker+lead rhythm as the page heads */
  #cfgBar .cfgqr{ position:absolute; top:13px; right:14px; z-index:3; width:32px; height:32px; padding:0; display:inline-flex; align-items:center; justify-content:center; background:var(--panel2); border:1px solid var(--line); border-radius:4px; color:var(--muted); cursor:pointer; transition:color 140ms ease, border-color 140ms ease, background 140ms ease; }   /* share-build QR, top-right of the config header */
  #cfgBar .cfgqr:hover{ color:var(--link); border-color:var(--accent); background:var(--wash); }
  #cfgBar .cfgqr svg{ width:17px; height:17px; }
  .cfg-selector{ flex:1 1 auto; overflow-x:hidden; overflow-y:auto; padding:17px 7px 17px 17px; display:flex; flex-direction:column; gap:0; align-items:stretch; }   /* groups space via margin-bottom (not flex gap) so a collapsing drawer can animate the gap closed; right padding is reduced because the stable scrollbar gutter supplies the rest of the visual inset */
  .cfggrp{ display:flex; flex-direction:column; flex-shrink:0; gap:12px; margin-bottom:21px; transition:height .3s cubic-bezier(.4,0,.2,1), margin-bottom .3s cubic-bezier(.4,0,.2,1), opacity .3s ease; }   /* flex-shrink:0 so an explicit drawer height isn't collapsed to 0 by the column flex */
  .cfg-selector .cfggrp.gnoanim{ transition:none; }   /* suppress the drawer transition for instant/baseline frames */
  .cfg-selector .cfggrp:last-child{ margin-bottom:0; }
  .cfg-selector .cfggrp.gcollapsed{ height:0; margin-bottom:0; opacity:0; overflow:hidden; }   /* drawer-closed resting state for the conditional groups (Z-joint on VT, Drive train on 9mm) */
  /* .cfggh → type .t-kicker (11px); snaps 700/.07em → 600/.08em to match the kicker, grouped in types.css */
  .cfgcells{ display:flex; flex-direction:column; gap:0; }
  .cfg-selector .cs{ display:flex; flex-direction:column; flex-shrink:0; gap:7px; min-width:0; margin-bottom:13px; transition:height .3s cubic-bezier(.4,0,.2,1), margin-bottom .3s cubic-bezier(.4,0,.2,1), opacity .26s ease; }
  .cfg-selector .cs.clast{ margin-bottom:0; }
  .cfg-selector .cs.cnoanim{ transition:none; }
  .cfg-selector .cs.ccollapsed{ height:0; margin-bottom:0; opacity:0; overflow:hidden; }
  .cfg-selector .csl{ font-size:11px; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); text-align:left; }
  .cfg-selector .seg{ display:flex; gap:7px; border:0; border-radius:0; overflow:visible; }
  .cfg-selector .stab{ flex:1 1 0; text-align:center; background:transparent; color:var(--muted); border:1px solid rgba(255,255,255,.14); border-radius:8px; padding:11px 8px; cursor:pointer; font:inherit; font-size:12.5px; line-height:1.1; white-space:nowrap; transition:color .12s, border-color .12s, background .12s; }
  .cfg-selector .stab:hover:not(:disabled){ color:var(--txt); border-color:rgba(255,255,255,.34); background:rgba(255,255,255,.03); }
  .cfg-selector .stab.on{ background:var(--wash); color:#cdb9ef; font-weight:600; border-color:var(--accent); box-shadow:none; }
  .cfg-selector .stab:disabled{ color:rgba(255,255,255,.22); background:transparent; border-color:rgba(255,255,255,.06); cursor:not-allowed; box-shadow:none; }
  /* fused segmented control - MERGED look: one bordered container (well) with a single SOLID purple pill that slides to the selected slot. The pill has NO border (just fill + shadow), so the only border is the container's → no double border. Behaviours: the pill slides, and inapplicable options drawer their width to 0. */
  .cfg-selector .seg.fused{ position:relative; display:flex; gap:0; border:1px solid rgba(255,255,255,.14); border-radius:8px; overflow:hidden; background:var(--code); isolation:isolate; }
  .cfg-selector .seg.fused .segthumb{ position:absolute; box-sizing:border-box; top:0; bottom:0; left:0; width:0; z-index:0; background:var(--primary); border-radius:8px; pointer-events:none; will-change:left,width; transition:left .3s cubic-bezier(.4,0,.2,1), width .3s cubic-bezier(.4,0,.2,1); }   /* fills the slot (no inset); the container's overflow:hidden rounds the outer corners */
  .cfg-selector .seg.fused .segthumb::before{ content:""; position:absolute; left:50%; bottom:-16px; width:8px; height:8px; border-right:1.6px solid rgba(222,222,228,.82); border-bottom:1.6px solid rgba(222,222,228,.82); opacity:0; transform:translate(-50%,-3px) rotate(45deg); pointer-events:none; filter:drop-shadow(0 1px 2px rgba(0,0,0,.55)); }
  .cfg-selector .seg.fused .segthumb::after{ content:""; position:absolute; inset:0; border-radius:inherit; background:inherit; opacity:0; pointer-events:none; }
  .cfg-selector .seg.fused .segthumb.noanim{ transition:none; }
  .cfg-selector .seg.fused.detailhint{ overflow:visible; }
  .cfg-selector .seg.fused.detailhint .segthumb::before{ animation:cfgDetailArrowHint 1.64s cubic-bezier(.22,1,.36,1) 1; }
  .cfg-selector .seg.fused.detailhint .segthumb::after{ animation:cfgThumbHint 1.64s cubic-bezier(.22,1,.36,1) 1; }
  @keyframes cfgThumbHint{ 0%,40%,50%,90%,100%{ inset:0; opacity:0; } 20%,70%{ inset:calc(-1 * var(--cfg-thumb-pulse-outset, 2px)); opacity:1; } }
  @keyframes cfgDetailArrowHint{ 0%,40%,50%,90%,100%{ opacity:0; transform:translate(-50%,-3px) rotate(45deg); } 20%,70%{ opacity:.9; transform:translate(-50%,0) rotate(45deg); } }
  .cfg-selector .seg.fused .stab{ position:relative; z-index:1; flex:1 1 0; min-width:0; text-align:center; overflow:hidden; white-space:nowrap; background:transparent; color:var(--muted); border:0; border-radius:0; padding:11px 8px; box-shadow:none; transition:flex-grow .3s cubic-bezier(.4,0,.2,1), flex-basis .3s cubic-bezier(.4,0,.2,1), padding .3s cubic-bezier(.4,0,.2,1), opacity .26s ease, color .15s ease; }
  .cfg-selector .seg.fused .stab.bnoanim{ transition:none; }   /* suppress the drawer transition for instant/baseline frames */
  .cfg-selector .seg.fused .stab.bcollapsed{ flex-grow:0; flex-basis:0; padding-left:0; padding-right:0; opacity:0; pointer-events:none; }   /* inapplicable option, drawered shut */
  .cfg-selector .seg.fused .stab:hover:not(.on):not(.bcollapsed){ color:var(--txt); }
  .cfg-selector .seg.fused .stab.on{ background:transparent; color:#fff; font-weight:600; }   /* selected: white text on the solid purple pill */
  .cfg-selector .csx{ display:none; font-size:11px; color:var(--muted); margin-top:6px; line-height:1.45; }   /* exclusion reason - DEVICE mode, not width: desktop has the hover title= tooltip, so only surface this inline on TOUCH (no hover), at any width */
  .cfg-selector .cfgdetail{ max-height:0; opacity:0; overflow:hidden; margin-top:0; padding:0 11px; border:1px solid transparent; border-radius:8px; background:rgba(255,255,255,.025); color:var(--muted); transform:translateY(-3px); transition:max-height .3s cubic-bezier(.4,0,.2,1), opacity .26s ease, margin-top .3s cubic-bezier(.4,0,.2,1), padding-top .3s cubic-bezier(.4,0,.2,1), padding-bottom .3s cubic-bezier(.4,0,.2,1), border-color .18s ease, transform .3s cubic-bezier(.4,0,.2,1); }
  .cfg-selector .cfgdetail.dnoanim{ transition:none; }
  .cfg-selector .cfgdetail.open{ max-height:220px; opacity:1; margin-top:8px; padding-top:10px; padding-bottom:11px; border-color:rgba(169,133,221,.26); transform:translateY(0); }
  .cfg-selector .cfgdt{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:5px; }
  .cfg-selector .cfgdt span{ font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; color:var(--low); font-weight:600; }
  .cfg-selector .cfgdt b{ color:var(--link); font:600 11px/1.3 var(--mono); min-width:0; max-width:18ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .cfg-selector .cfgdi, .cfg-selector .cfgdb{ font-size:11.5px; line-height:1.5; }
  .cfg-selector .cfgdb{ margin-top:5px; color:var(--txt); }
  .cfg-selector .cfgdn{ margin-top:6px; font-size:11px; line-height:1.45; color:var(--muted); border-left:2px solid rgba(169,133,221,.42); padding-left:8px; }
  .cfg-selector .cfgcopybar{ display:flex; justify-content:flex-end; margin-top:8px; }
  .cfg-selector .cfgcopyedit{ appearance:none; border:1px solid var(--line); background:rgba(255,255,255,.025); color:var(--muted); border-radius:4px; padding:3px 8px; font:600 10.5px/1.2 Roboto,system-ui,sans-serif; cursor:pointer; }
  .cfg-selector .cfgcopyedit:hover{ color:var(--link); border-color:rgba(169,133,221,.35); background:rgba(169,133,221,.08); }
  .dev-touch .cfg-selector .csx{ display:block; }
  .cfg-selector .cfgrails{ display:flex; gap:10px; margin-top:9px; }
  .cfg-selector .railin{ flex:1 1 0; min-width:0; display:flex; align-items:center; gap:6px; background:var(--code); border:1px solid rgba(255,255,255,.14); border-radius:8px; padding:8px 10px; cursor:text; transition:border-color .12s; }
  .cfg-selector .railin:focus-within{ border-color:var(--accent); }
  .cfg-selector .railin .raillbl{ font-size:11px; color:var(--muted); white-space:nowrap; }
  .cfg-selector .railin input{ flex:1 1 0; min-width:0; width:100%; background:transparent; border:0; color:var(--txt); font:13px/1 var(--mono); outline:none; -moz-appearance:textfield; }
  .cfg-selector .railin input::-webkit-outer-spin-button, .cfg-selector .railin input::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
  .cfg-selector .railin .railsuf{ font-size:11px; color:var(--low); }
  .cfg-selector .cfgbelt{ display:block; margin-top:9px; font-size:11.5px; color:var(--link); font-family:var(--mono); }
  @media(prefers-reduced-motion:reduce){ *,*::before,*::after{ transition-duration:0.01ms !important; animation-duration:0.01ms !important; animation-iteration-count:1 !important; scroll-behavior:auto !important; } }   /* a11y: honour the OS reduced-motion pref for DECORATIVE CSS motion (hover/wash/lift/slide/breathe) - the assembly playback is JS-driven + stays under the Animate toggle */
  #cfgBar .cfgdone, .timeline-view-as-panel .cfgdone{ flex:0 0 auto; align-self:stretch; border:0; border-top:1px solid var(--primary-hi); border-radius:0; padding:15px; cursor:pointer; font:inherit; font-size:15px; font-weight:600; }   /* prominent 15px - the Configure commit is a page CTA */
  #cfgBar .cfgdone:hover, .timeline-view-as-panel .cfgdone:hover{ background:var(--primary-hi); }
  /* BOTTOM SHEET at 900 and below. The switch used to sit at the phone width (680), which left the side
     column standing at 800 with a 404px strip of 3D beside it (maintainer 2026-09-04: unusable). The column
     needs a viewport at least as wide as ~1.3 islands: 396px of island + inset plus 504px of scene = 900.
     Width-only, so touch phones switch exactly as before and desktop windows switch earlier; the
     landscape-phone and portrait-tablet band (681-900) now gets the sheet too. frameCfg() in builder/app.ts
     reads the same number (CFG_SHEET_MAX_W) to compose the camera - keep the two equal. */
  @media (max-width:900px){
    #cfgBar{ top:auto; right:8px; left:8px; bottom:calc(8px + env(safe-area-inset-bottom, 0px)); width:auto; max-height:min(50%, 460px); border-radius:8px; }   /* bottom half only (50% of the visual-viewport-accurate container, capped), lifted above the Android gesture bar; radius matches the preview bar */
    .cfg-selector{ padding:14px 16px; gap:18px; scrollbar-gutter:auto; scrollbar-width:none; }   /* overlay scrollbars on touch: a reserved gutter is invisible chrome AND pushed the symmetric padding off-centre */
    .cfg-selector::-webkit-scrollbar{ width:0; height:0; }
    /* With the scrollbar hidden there is nothing left to say the sheet continues past its 50% cap,
       so the last 28px ramp out. Always on rather than scroll-driven: a scroll-linked mask needs
       animation-timeline, and a permanently soft last row costs less than no affordance at all. */
    .cfg-selector{ mask-image:linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
      -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%); }
    .cfg-selector .stab{ padding:12px 8px; }
  }
  #treeTop{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 18px; flex:0 0 auto; }   /* Standard top bar: transparent, with the divider on the filter row below. */
  #treeTop .ttl{ display:flex; align-items:baseline; gap:10px; }
  #treeTop .ttl strong{ font-size:17px; font-weight:600; color:var(--txt); }
  #treeTop .ttl .counts{ font-variant-numeric:tabular-nums; }   /* type = .t-meta */
  #treeTop .leg{ display:flex; align-items:center; gap:14px; color:var(--low); font-size:12px; }
  #treeTop .leg .k{ display:inline-flex; align-items:center; gap:6px; }
  #treeTop .leg .sw{ width:17px; height:17px; border-radius:4px; border:1px solid var(--line); display:inline-flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; }
  #treeTop .leg .sw.need{ background:var(--wash); color:var(--link); border-color:rgba(169,133,221,.4); }
  #treeTop .leg .sw.out{ background:rgba(232,160,154,.16); color:var(--bad-rest); border-color:rgba(232,160,154,.4); }
  /* config tester row: pick a value per axis, watch the tree resolve */
  #treeGridWrap{ flex:1; overflow:auto; }
  /* EXCEL-STYLE matrix scaled to fill the screen width; full option titles in the sticky header, checkbox cells */
  table.tg{ width:100%; table-layout:fixed; border-collapse:separate; border-spacing:0; font-size:11px; }
  .tg col.namecol{ width:230px; }
  .tg th, .tg td{ padding:0; }
  .tg thead th{ position:sticky; top:0; z-index:3; background:var(--panel2); border-bottom:1px solid var(--line); }
  .tg th.secg{ padding:5px 4px; line-height:1.15; text-align:center; border-left:2px solid var(--line); color:var(--link); font:700 10px/1.15 var(--mono); text-transform:uppercase; letter-spacing:.08em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; background:linear-gradient(var(--wash),var(--wash)), var(--panel2); }
  .tg th.axg{ padding:6px 4px; line-height:1.2; text-align:center; border-left:2px solid var(--line); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }   /* type = .t-section (11px) */
  .tg thead tr.r2 th{ top:26px; }
  /* value headers ARE the config selector: each reads as a button under its axis-group label - click to pick that value */
  .tg th.vcol{ cursor:pointer; background:var(--panel2); color:var(--muted); font-weight:600; font-size:11px; padding:6px 5px; text-align:center; vertical-align:middle; line-height:1.2; border-left:1px solid var(--line); white-space:normal; word-break:break-word; transition:color 140ms ease; }
  .tg th.vcol:hover{ color:var(--txt); }
  .tg th.vcol.g0{ border-left:2px solid var(--line); }   /* axis-group divider (segment break) */
  .tg th.vcol.hi{ color:var(--link); font-weight:700; background:linear-gradient(var(--wash),var(--wash)), var(--panel2); }   /* selected value = on; opaque (wash over panel2) so rows don't show through the sticky header */
  .tg th.vcol.hi:hover{ color:var(--link); }
  .tg th.vcol.off{ color:rgba(255,255,255,.20); cursor:not-allowed; }   /* value ruled out by the current config = disabled button */
  .tg th.vcol.off:hover{ color:rgba(255,255,255,.20); }
  /* sticky subassembly-name column */
  .tg th.rh{ position:sticky; left:0; z-index:2; background:var(--panel); color:var(--txt); font-weight:400; text-align:left; padding:7px 12px;
    border-bottom:1px solid rgba(255,255,255,.05); border-right:1px solid var(--line); font-family:var(--mono); font-size:14px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; transition:background 140ms ease, color 140ms ease; }
  .tg th.rh .rn{ color:#a985dd; font-weight:700; margin-right:8px; }
  .tg thead th.rh{ z-index:4; background:var(--panel2); color:var(--low); }
  .tg tbody tr:hover th.rh{ color:var(--link); background:rgba(169,133,221,.07); }
  .tg tbody tr:hover td.cell{ background:rgba(169,133,221,.05); }
  .tg tbody tr.rsel th.rh{ background:var(--wash); color:var(--link); box-shadow:inset 3px 0 0 rgba(169,133,221,.72); }   /* resolved by the test config */
  /* section header rows (collapsible) */
  .tg tr.sec th{ position:sticky; left:0; background:var(--panel2);
    text-align:left; padding:7px 12px; border-top:1px solid var(--line); border-bottom:1px solid var(--line); cursor:pointer; user-select:none; z-index:2; }   /* type = .t-section (11px) */
  .tg tr.sec th .tw{ display:inline-block; width:12px; color:var(--low); font-size:9px; } .tg tr.sec th .tw::before{ content:'▾'; } .tg tr.sec.collapsed th .tw::before{ content:'▸'; }
  .tg tr.sec th .ct{ color:var(--muted); font-weight:600; margin-left:8px; text-transform:none; letter-spacing:0; }
  .tg tbody tr.seccoll{ display:none; }                       /* rows of a collapsed section are hidden... */
  .tg tbody tr.seccoll.show{ display:table-row; }             /* ...except the resolved one, surfaced under the header when highlight-resolved is on */
  /* 3-state checkbox cells */
  /* the WHOLE cell is the 3-state checkbox: empty = independent, wash + ✓ = needed, red + ✗ = ruled-out */
  .tg td.cell{ text-align:center; border-left:1px solid rgba(255,255,255,.05); border-bottom:1px solid rgba(255,255,255,.05); padding:7px 0; cursor:pointer;
    font-weight:700; font-size:13px; color:transparent; user-select:none; transition:background 140ms ease, color 140ms ease, box-shadow 140ms ease; }
  .tg td.cell.g0{ border-left:2px solid var(--line); }
  .tg td.cell:hover{ box-shadow:inset 0 0 0 2px var(--accent); }
  .tg td.cell.need{ background:var(--wash); color:var(--link); }
  .tg td.cell.out{ background:rgba(232,160,154,.18); color:var(--bad-rest); }
  .tg td.cell.dirty{ box-shadow:inset 0 0 0 2px var(--accent); }   /* edited since the last save - highlights the changes you make */
  /* bottom bar - same anatomy as the play/orient bar */
  #treeBar{ display:none; }
  body.tree #treeBar{ display:grid; grid-template-columns:auto 1fr auto; gap:10px; align-items:center; white-space:nowrap;
    position:absolute; left:50%; bottom:16px; transform:translateX(-50%); width:min(1500px, calc(100% - 28px)); z-index:11;
    background:rgba(27,27,27,.94); border:1px solid var(--line); border-radius:8px; padding:10px; box-shadow:var(--elev); backdrop-filter:blur(6px); font-size:13px; }
  #treeBar .zone{ display:flex; gap:10px; align-items:center; min-width:0; }
  #treeBar .zone.zl{ justify-self:start; } #treeBar .zone.zr{ justify-self:end; }
  #treeBar .zone.zc{ justify-content:center; color:var(--muted); }
  #treeBar .b{ padding:8px 14px; font:inherit; display:inline-flex; align-items:center; }   /* look + transition + hover inherited from button.b */
  #treeBar .b.primary:hover{ background:var(--primary-hi); border-color:var(--primary-hi); }
  /* #tExit → folded into .danger in core/types.css */
  /* #treeBar .b kbd → .kbd keycap primitive (types.css) */
  /* #treeBar .b.primary kbd → on-primary keycap (types.css) */
  #treeBar .b.view{ background:var(--wash); color:var(--link); border-color:rgba(169,133,221,.4); font-weight:600; }
  #treeBar .b.view:hover{ border-color:var(--accent); color:var(--link); }
  #treeBar .res{ margin-left:10px; color:var(--link); font-size:12px; font-weight:600; font-variant-numeric:tabular-nums; font-family:var(--mono); }
  #treeBar .savestat{ margin-left:10px; color:var(--accent); font-size:12px; font-weight:600; font-variant-numeric:tabular-nums; }
  #treeBar .savestat:empty{ display:none; }
  @media(max-width:560px){
    body.tree #treePanel{ overflow-x:hidden; }
    #treeTop{ flex-wrap:wrap; align-items:flex-start; gap:8px; padding:10px 14px; }
    #treeTop .ttl{ min-width:0; flex:1 1 100%; flex-wrap:wrap; }
    #treeTop .leg{ min-width:0; flex:1 1 100%; flex-wrap:wrap; gap:8px; }
    #treeGridWrap{ overflow-x:hidden; }
    .tg col.namecol{ width:150px; }
    .tg th.rh{ padding:7px 8px; font-size:12px; }
    .tg th.vcol{ padding:5px 2px; font-size:10px; }
    body.tree #treeBar{ grid-template-columns:1fr; width:calc(100% - 16px); gap:6px; padding:8px; white-space:normal; }
    #treeBar .zone{ justify-content:center; flex-wrap:wrap; gap:6px; }
    #treeBar .zone.zl, #treeBar .zone.zr{ justify-self:stretch; }
    #treeBar .b{ flex:1 1 min(92px,100%); justify-content:center; min-width:0; padding:6px 8px; }
    #treeBar .res, #treeBar .savestat{ margin-left:0; }
  }
  /* preview mode = consumer manual view for one variant (maintainer chrome hidden) */
  .pvchrome{ display:none; }
  body.preview .side{ display:none; }
  body.preview .hud{ display:none; }
  body.preview #spreadCtl{ display:none; }
  body.preview .editoronly{ display:none !important; }   /* scrub + spread are editor-only */
  #playAll.on, .play .tgl.on{ background:var(--wash); color:var(--link); border-color:rgba(169,133,221,.4); }   /* selected = tonal wash, never a fill */
  .play .tgl{ color:var(--muted); } .play .tgl:hover{ color:var(--link); }
  body.descoff #pvCap{ display:none !important; }   /* Description toggle [D] hides the step caption in preview */
  body.preview .pvchrome{ display:block; }
  body.preview button.pvchrome{ display:inline-flex; }   /* bar toggles keep their flex layout */
  #viewCtl{ position:absolute; top:14px; right:14px; z-index:12; gap:6px; }   /* persistent viewer control */
  /* A panel header sits INSIDE a scroller that reserves a stable gutter, so its box was narrower than a
     floatbar header over the stage, moving the stepper by half the gutter between surfaces. Spanning the
     scroller's padding box keeps every header full width with symmetric padding. (Above the phone width
     only, where this block has always lived; the Configure island and viewer control no longer have
     rules here - they keep the base 16px / 14px insets, see the Configure stepper rules by the header.) */
  @media(min-width:681px){
  body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop,#pvTop).builder-page-top:not(.floatbar){
    margin-right:calc(-1 * var(--sb-gutter, 0px)); }
  }
  body.config #viewCtl{ right:calc(14px + var(--cfg-viewctl-offset, 0px)); }   /* Configure: park reset on the 3D viewport side of the options island */
  body.preview #viewCtl, body.config #viewCtl{ display:flex; }
  #viewCtl button, body.builderdeploy.preview #pvTop .pvcluster button{ width:34px; height:34px; padding:0; display:flex; align-items:center; justify-content:center; font:inherit; font-size:16px; line-height:1; background:rgba(27,27,27,.62); border:1px solid var(--line); border-radius:8px; cursor:pointer; backdrop-filter:blur(6px); }   /* ONE floating viewport-chrome icon button; the preview cluster is the same thing in a different corner */
  #viewCtl button:not(.danger), body.builderdeploy.preview #pvTop .pvcluster button:not(.danger){ color:var(--txt); }   /* .danger (types.css) owns the red rest/hover/pressed states, so it must not be overwritten here */
  :where(.dev-pointer) #viewCtl button:not(.danger):hover, :where(.dev-pointer) body.builderdeploy.preview #pvTop .pvcluster button:not(.danger):hover{ background:rgba(40,40,40,.85); color:#fff; border-color:var(--accent); }
  #viewCtl #vcSpin{ display:none; }
  body.config #viewCtl #vcSpin{ display:flex; }
  #viewCtl #vcSpin.on{ color:var(--link); border-color:var(--accent); background:var(--wash); }
  #playLbl{ display:inline-block; min-width:78px; text-align:center; }   /* sized for the longest label (▷ Resume / ↻ Replay) so the button - and the middle text - never shift */
  .play button:disabled{ pointer-events:none; }
  #pvPart{ display:none; color:var(--accent); font-weight:600; font-size:18px; }   /* option 8: bigger centre - keeps its purple + opacity-pulse flash (driven in updateMoveHighlight) */
  @keyframes pvflyin{ from{ transform:translateX(34px); opacity:0; } to{ transform:translateX(0); opacity:1; } }   /* the new callout name enters from the RIGHT */
  @keyframes pvflyout{ from{ transform:translateX(0); opacity:1; } to{ transform:translateX(-34px); opacity:0; } }   /* the old name exits to the LEFT */
  :is(#pvPart,#pvCap .pvPart).flyin{ animation:pvflyin .2s cubic-bezier(.2,.7,.2,1); }
  :is(#pvPart,#pvCap .pvPart).flyout{ animation:pvflyout .12s ease forwards; }
  @keyframes pvflyinR{ from{ transform:translateX(-34px); opacity:0; } to{ transform:translateX(0); opacity:1; } }   /* REVERSE playback: the new name enters from the LEFT */
  @keyframes pvflyoutR{ from{ transform:translateX(0); opacity:1; } to{ transform:translateX(34px); opacity:0; } }   /* REVERSE playback: the old name exits to the RIGHT */
  :is(#pvPart,#pvCap .pvPart).flyinR{ animation:pvflyinR .2s cubic-bezier(.2,.7,.2,1); }
  :is(#pvPart,#pvCap .pvPart).flyoutR{ animation:pvflyoutR .12s ease forwards; }
  body.preview #pvPart{ display:block; }
  /* Same callout, the caption's copy. Hidden on a pointer (the bar centre owns it there) and shown
     on touch, where the bar is a three-slot transport with nowhere to put a part name. */
  #pvCap .pvPart{ display:none; margin-top:7px; color:var(--accent); font-weight:600; font-size:16px; }
  :where(.dev-touch) body.preview #pvCap .pvPart{ display:block; }
  /* On a phone the 540px cap never binds, so the title ran to the bare viewport edge. Give the caption
     the same inset on both sides and let the width fall out of it. */
  :where(.dev-touch) body.preview #pvCap{ right:18px; max-width:none; }
  body.preview #stepLbl{ display:none; }   /* in preview: the bar centre names the moving part; #pvCap owns the step counter */
  /* consumer (builderdeploy) preview shows the SAME full bar as the maintainer preview - what you preview is what ships.
     Repeat · Animate · Description · Play all + the centred part callout stay (the callout names are clean group names now,
     e.g. "Frame" / "smooth idler", not raw meshes). stepLbl stays hidden via the body.preview rule above - the #pvCap
     caption owns the "Step N / M" counter, so the bar centre is free to name the moving part. */
  /* the step rail: portrait playback's progress, drawn with the SAME segmented recipe as the stage tile
     cover so the bar ties back to the tile it was launched from. Fed by updatePreviewText. */
  .playrail{ display:none; }
  .playrail::before, .playrail::after{ content:''; position:absolute; inset:0; }
  .playrail::before{ background:repeating-linear-gradient(to right,rgba(255,255,255,.24) 0 calc(var(--stage-segment) - 2px),transparent calc(var(--stage-segment) - 2px) var(--stage-segment)); }
  .playrail::after{ background:repeating-linear-gradient(to right,#9674cb 0 calc(var(--stage-segment) - 2px),transparent calc(var(--stage-segment) - 2px) var(--stage-segment)); clip-path:inset(0 calc(100% - var(--stage-progress)) 0 0); }
  .play .pvmore{ display:none; }   /* .play button already sets display:inline-flex at (0,1,1), so the hide has to carry two classes to win */
  /* Narrow VIEWPORT only: with no options island beside it (bottom sheet, same 900 as the #cfgBar switch),
     Reset returns to the plain 14px inset. */
  @media(max-width:900px){
    body.config #viewCtl{ right:14px; }
  }
  /* Desktop shed. The bar is a full-width 3-column grid, so it never overflows: it TRUNCATES, and the
     first thing to go is the transport label a builder reads every step. Measured on this tree, not
     taken from the audit's table (whose control widths predate the current padding): Previous and Next
     start ellipsising just under 1077px, by 35px and 25px at 1000px wide.
     The eight keycaps are worth 207px and are the least load-bearing thing in the bar, since the
     shortcut keeps working whether or not it is advertised. They shed first. Pointer only: on touch the
     kbd IS the arrow glyph, and there is no keyboard to advertise anyway. */
  @media(max-width:1080px){
    :where(.dev-pointer) body.preview .play kbd{ display:none; }
  }
  /* Next rung, measured the same way: with the keycaps gone the transport survives to 860 and truncates
     again by 700 (Previous by 52px). The secondary toggles are 286px of the 3-column grid, so they shed
     next, least load-bearing first. Repeat and Animate change how playback behaves; Description changes
     what is on the screen, so it outlives them. Every one of them keeps its keyboard shortcut. */
  @media(max-width:860px){
    :where(.dev-pointer) body.preview .play #repeatAll,
    :where(.dev-pointer) body.preview .play #animTgl{ display:none; }
  }
  @media(max-width:706px){
    :where(.dev-pointer) body.preview .play .zone.zl{ display:none; }
  }
  /* Review bar: one row instead of the 3-zone desktop grid (finding 18). Gated on the DEVICE, not the
     viewport - a phone in landscape is 844x390, wider than any sane width trigger, and used to get the
     desktop bar inside a 390px-tall viewport. :where() keeps the specificity these rules had while they
     lived in a media query, so nothing downstream changes weight. */
  :where(.dev-touch) body.preview #pvPart{ display:none !important; }   /* the moving-part callout lives in the caption; it was never in this bar */
  /* Geometry lives on body.preview, NOT on .play: #pvCap is .play's SIBLING, so anything declared
     on the bar is unreachable from the caption and has to be re-guessed as a literal. Declared here,
     both inherit the same numbers and every offset below is derived rather than restated. */
  :where(.dev-touch) body.preview{ --pv-rail-h:7px; --pv-btn-h:64px; --pv-pad:10px; --pv-gap:8px;
    --pv-bar-h:calc(var(--pv-rail-h) + var(--pv-gap) + var(--pv-btn-h) + var(--pv-pad) * 2);   /* 103px */
    --pv-more-h:168px;   /* three 44px rows + two gaps + padding; both popover columns take it so their TOPS line up */
    --pv-cap-gap:14px;   /* breathing room between the caption's last line and the bar */
    --pv-cap-h:172px; }   /* the reserved caption block: step line + a two-line title + a two-line description + the part callout */
  :where(.dev-touch) body.preview .play{ left:8px; right:8px; width:auto; transform:none; gap:var(--pv-gap); padding:var(--pv-pad); font-size:13px;
    display:grid; grid-template-columns:1fr var(--pv-btn-h) 1fr; grid-template-rows:auto auto; }
  /* the caption sat at bottom:84px, which the taller portrait bar overlapped: its last line ran under the rail */
  :where(.dev-touch) body.preview #pvCap{ bottom:calc(var(--timeline-float-gap) + env(safe-area-inset-bottom, 0px) + var(--pv-bar-h) + var(--pv-cap-gap)); }
  /* The caption reserves a FIXED block and scrolls inside it. A description that ran one line longer used
     to shrink the clear area, which re-framed the model on every step: the camera visibly re-centred as you
     paged. Constant reserved height means the usable frame is a property of the stage, not of the sentence. */
  :where(.dev-touch) body.preview #pvCap{ height:var(--pv-cap-h); overflow-y:auto; overscroll-behavior:contain; pointer-events:auto; }
  :where(.dev-touch) body.preview .play .playrail{ display:block; position:relative; grid-column:1/-1; grid-row:1; height:7px; border-radius:4px; overflow:hidden; background:var(--code); box-shadow:inset 0 1px 0 rgba(0,0,0,.55); }
  :where(.dev-touch) body.preview .play .zone.zc{ display:contents; }   /* the transport row's children become the grid's second row */
  :where(.dev-touch) body.preview .play .zone.zl, :where(.dev-touch) body.preview .play .zone.zr{ display:none; }   /* secondary controls only exist in the popover */
  :where(.dev-touch) body.preview .play .navbtn{ grid-row:2; height:var(--pv-btn-h); min-height:var(--pv-btn-h); justify-content:center; gap:10px; padding:0; font-size:14px; font-weight:600; }
  :where(.dev-touch) body.preview .play #prev{ flex-direction:row-reverse; }   /* markup is label-then-kbd; the back arrow has to lead */
  :where(.dev-touch) body.preview .play #prev{ grid-column:1; }
  :where(.dev-touch) body.preview .play #next{ grid-column:3; }
  :where(.dev-touch) body.preview .play .navbtn kbd{ font-size:19px; margin:0; padding:0; min-width:0; height:auto; background:none; border:0; box-shadow:none; color:var(--txt); }
  :where(.dev-touch) body.preview .play .pvmore{ display:inline-flex; grid-column:2; grid-row:2; align-items:center; justify-content:center; width:var(--pv-btn-h); height:var(--pv-btn-h); padding:0; font-size:19px; line-height:1; }
  /* Overflow, not a drawer: no grab handle promising a bottom sheet, and no drag gesture to implement.
     The panel is the bar's own zl/zr zones repositioned - actions left, toggles right, hairline between. */
  :where(.dev-touch) body.preview .play.moreopen{ overflow:visible; }   /* .play sets overflow:hidden and is their containing block */
  :where(.dev-touch) body.preview .play.moreopen::before{ content:''; position:absolute; left:0; right:0; bottom:calc(100% + var(--pv-gap)); height:var(--pv-more-h);
    background:var(--panel2); border:1px solid var(--line); border-radius:8px; box-shadow:var(--elev-float); z-index:29; }   /* ONE panel behind both columns */
  :where(.dev-touch) body.preview .play.moreopen .zone.zl, :where(.dev-touch) body.preview .play.moreopen .zone.zr{ display:flex; flex-direction:column; align-items:stretch; justify-content:flex-start; gap:8px;
    position:absolute; bottom:calc(100% + var(--pv-gap)); height:var(--pv-more-h); width:50%; padding:10px 12px; box-sizing:border-box; z-index:30; }
  :where(.dev-touch) body.preview .play.moreopen .zone.zr{ left:0; }                                        /* actions */
  :where(.dev-touch) body.preview .play.moreopen .zone.zl{ right:0; border-left:1px solid var(--line); }   /* toggles, hairline between */
  :where(.dev-touch) body.preview .play.moreopen :is(.zone.zl,.zone.zr) button{ min-height:44px; justify-content:flex-start; }   /* popover buttons only: .zone.zc is display:contents, so the bare .zone rule also reached Previous / more / Next and left-packed them (Previous, row-reverse, packed right) whenever the panel was open */
  :where(.dev-touch) body.preview .play.moreopen .zone .moreWrap{ display:flex; }
  :where(.dev-touch) body.preview .play.moreopen .zone .moreWrap > button{ width:100%; }
  /* the popover covered all three lines of the caption a builder reads while working, so lift it clear */
  :where(.dev-touch) body.preview .play.moreopen ~ #pvCap{ bottom:calc(var(--timeline-float-gap) + env(safe-area-inset-bottom, 0px) + var(--pv-bar-h) + var(--pv-gap) + var(--pv-more-h) + var(--pv-cap-gap)); }
  /* LANDSCAPE PREVIEW - one right-hand island instead of a stack.
     Held sideways, caption over bar left a 7:1 slit to build from (measured 740x106 of a 740x360 viewport).
     Landscape moves the whole control stack into a single rail so the viewport keeps a real rectangle,
     the way Configure already treats its island. Additive and orientation-scoped: portrait and desktop
     never read these rules, so reverting is deleting this block. The island IS .play, so the camera
     composition sees ONE full-height band to subtract rather than two partial ones it would ignore. */
  @media (orientation:landscape) and (max-height:560px){
    :where(.dev-touch) body.preview{ --pv-rail-w:min(320px, 44vw); --pv-btn-h:56px; --pv-head-h:54px;
      --pv-foot-h:calc(var(--pv-rail-h) + var(--pv-gap) + var(--pv-btn-h)); }
    /* The island spans the full height so the camera composition sees ONE band to subtract, but it is
       TRANSPARENT: the caption reads on the bare 3D, per the revert that put it back there. Only the
       transport foot carries a panel, drawn by ::after behind the rail and buttons. */
    :where(.dev-touch) body.preview .play{ left:auto; right:8px; width:var(--pv-rail-w); height:auto; transform:none;
      top:calc(var(--pv-head-h) + 8px); bottom:calc(8px + env(safe-area-inset-bottom, 0px));
      background:transparent; border-color:transparent; box-shadow:none; backdrop-filter:none;
      grid-template-columns:1fr 1fr; grid-template-rows:1fr auto auto; }
    :where(.dev-touch) body.preview .play::after{ content:''; position:absolute; left:0; right:0; bottom:0;
      height:calc(var(--pv-foot-h) + var(--pv-pad) * 2); z-index:0;
      background:rgba(27,27,27,.94); border:1px solid var(--line); border-radius:8px; box-shadow:var(--elev); backdrop-filter:blur(6px); }
    :where(.dev-touch) body.preview .play > *{ position:relative; z-index:1; }   /* controls ride above the foot panel */
    :where(.dev-touch) body.preview .play .playrail{ grid-column:1/-1; grid-row:2; }
    :where(.dev-touch) body.preview .play #prev{ grid-column:1; grid-row:3; }
    :where(.dev-touch) body.preview .play #next{ grid-column:2; grid-row:3; }
    /* the overflow key leaves the transport row and sits in the island's corner, so Previous/Next split it 50/50 */
    :where(.dev-touch) body.preview .play .pvmore{ position:absolute; top:var(--pv-pad); right:var(--pv-pad);
      width:44px; height:44px; grid-column:auto; grid-row:auto; z-index:2; }
    /* the caption becomes the island's body and scrolls, so a long description cannot push the transport away */
    /* height:auto - the rail spans top to foot, so the caption is bounded by the island, not by the
       portrait reserve. The frame is already constant here because the rail's width never varies. */
    :where(.dev-touch) body.preview #pvCap{ left:auto; right:calc(8px + var(--pv-pad)); max-width:none; height:auto;
      width:calc(var(--pv-rail-w) - var(--pv-pad) * 2); padding-right:52px;
      top:calc(var(--pv-head-h) + 8px + var(--pv-pad));
      bottom:calc(8px + env(safe-area-inset-bottom, 0px) + var(--pv-pad) + var(--pv-foot-h) + var(--pv-gap));
      overflow-y:auto; overscroll-behavior:contain; pointer-events:auto; }
    :where(.dev-touch) body.preview #pvCap .pvTitle{ font-size:17px; margin:2px 0 5px; }
    /* overflow takes over the island's body instead of floating a second panel across the scene */
    :where(.dev-touch) body.preview .play.moreopen{ grid-template-rows:auto auto auto auto; align-content:start; overflow:auto; }
    :where(.dev-touch) body.preview .play.moreopen::after{ top:0; height:auto; }   /* the panel grows to cover the open overflow */
    :where(.dev-touch) body.preview .play.moreopen::before{ display:none; }
    :where(.dev-touch) body.preview .play.moreopen ~ #pvCap{ display:none; }
    :where(.dev-touch) body.preview .play.moreopen .zone.zl,
    :where(.dev-touch) body.preview .play.moreopen .zone.zr{ position:static; grid-column:1/-1; width:auto; height:auto; padding:0; }
    :where(.dev-touch) body.preview .play.moreopen .zone.zr{ grid-row:1; }
    :where(.dev-touch) body.preview .play.moreopen .zone.zl{ grid-row:2; border-left:0; border-top:1px solid var(--line); padding-top:var(--pv-gap); }
    :where(.dev-touch) body.preview .play.moreopen .playrail{ grid-row:3; }
    :where(.dev-touch) body.preview .play.moreopen #prev, :where(.dev-touch) body.preview .play.moreopen #next{ grid-row:4; }
  }
  /* TOUCH tap targets (DEVICE mode, not viewport size): bump the small chrome controls to ~44px (Apple HIG 44pt) when the
     device is touch - a coarse pointer needs finger-size targets at ANY width, and a narrow MOUSE window does NOT (it would
     just waste height). Tiles/rows already use the whole-container-is-the-button pattern. The bar-padding trim rides along
     (it exists only so the 44px buttons don't make the bar tall). */
  .dev-touch .bartop{ padding-top:9px; padding-bottom:9px; }
  /* The header box stays 54px, but a 44px touch control plus 14px+14px of padding is 72px, so the row
     overflowed and pushed the lockup 9px down on the only header that carries one (playback). 5px each
     side makes 44 fit exactly; headers without a tall control are unaffected, since align-items:center
     puts a 20px lockup at the same y either way. */
  .dev-touch body.builderdeploy :is(#buildTop,#guideTop,#cfgTop,#projTop,#delivTop,#pvTop).builder-page-top{ padding-top:5px; padding-bottom:5px; }
  .dev-touch body.builderdeploy #pvTop.builder-page-top{ padding-left:5px; padding-right:5px; }   /* the playback header's inset is the same on all four sides: the 44px reset / exit controls sat 5px from the top and bottom but 16px from the right (maintainer 2026-09-03: the smaller padding) */
  .dev-touch .bartop .b{ min-height:44px; display:inline-flex; align-items:center; justify-content:center; }
  .dev-touch .cfg-selector .stab{ min-height:44px; }
  .dev-touch body.preview .play button{ min-height:44px; }
  .dev-touch body.preview .play .navbtn{ min-width:44px; }
  .dev-touch :is(body.preview,body.config) #viewCtl button, .dev-touch body.builderdeploy.preview #pvTop .pvcluster button{ width:44px; height:44px; font-size:18px; }   /* body.config as well as body.preview: the bump was written for the preview corner, but #viewCtl also runs in Configure, where Reset and the showcase toggle sat at 34px on touch. */
  .dev-touch #cfgBar .cfgqr{ width:44px; height:44px; }   /* the share button was the last sub-44 target on a builder surface */   /* the existing touch bump covers both corners */
  .dev-touch .sec>summary .collapseAll{ min-height:44px; display:inline-flex; align-items:center; }   /* sidebar collapse-all toggle: finger-size target on touch (the .bartop rule above doesn't reach the sidebar) */
  /* Type on touch. Source's @760 took .chrome-question-head h3 DOWN to 16px; shrinking type on a phone is
     the wrong direction, so these only ever hold or raise. Tiles are deliberately absent: they match desktop
     exactly (15px title, 12px meta, the 5-row grid whose spacer holds the action band off the text). */
  .dev-touch .chrome-question-head h3{ font-size:18px; }
  .dev-touch .delivsec h3{ font-size:14px; }
  .dev-touch table.bom td{ font-size:14px; }
  .dev-touch .action-details-row code{ font-size:12px; }
  .orzoom{ display:inline-flex; flex:0 0 auto; align-items:center; gap:7px; margin-right:6px; color:var(--muted); }
  .orzoom input{ width:clamp(82px, 8vw, 110px); accent-color:var(--accent); }
  .orzoom b{ min-width:46px; text-align:right; color:var(--txt); font:600 12px/1 var(--mono); }
  /* preview title = the sidebar h1 format: 17px lockup + 600-weight name; the "assembly manual" tail stays quiet */
  body.builderdeploy.preview #pvTop .acts{ display:none; }   /* pointer devices keep Reset in #viewCtl and Exit in the play bar */
  .dev-touch body.builderdeploy.preview #pvTop .acts{ margin-left:auto; display:flex; align-items:center; gap:8px; pointer-events:auto; }   /* on touch, nothing destructive sits beside the control used on every step */
  /* The corner cluster is the SAME floating chrome as #viewCtl (grouped above) with the SAME glyphs the
     app already uses: vcReset's gapped circle arrow and the dialogs' times. Exit carries .danger, so its
     red rest/hover/pressed states come from the type. Only the times glyph's optical size differs.
     Browser back does the same thing (builder.preview.exit IS history.back), so this is the visible
     affordance for it, not the only way out. */
  body.builderdeploy.preview #pvTop .pvcluster #pvExitTop{ font-size:22px; }
  .dev-touch body.builderdeploy.preview #pvTop .pvcluster #pvExitTop{ font-size:24px; }
  .dev-touch body.builderdeploy.preview .play #pvExit{ display:none; }   /* Exit appears ONCE - the header copy wins on touch */
  .dev-touch body.builderdeploy.preview #viewCtl{ display:none !important; }   /* Reset moved to the header; the showcase toggle beside it only ever ran in Configure */
  #pvCap{ position:absolute; left:18px; bottom:84px; max-width:540px; z-index:8; pointer-events:none; }
  /* The step counter, title and description sit DIRECTLY on the 3D with nothing behind them. A scrim
     was tried here and removed: the caption is meant to read as part of the scene, not as a panel over
     it. Do not reintroduce a background, gradient or blur on #pvCap or its children. */
  #pvCap .pvStep{ display:block; }   /* the preview step counter - type .t-kicker (types.css). The .pvflank pair that used to carry it never rendered: .play sets overflow:hidden and is their containing block. */
  #pvCap .pvTitle{ font-size:21px; font-weight:700; letter-spacing:0; margin:4px 0 6px; }
  #pvCap .pvDesc{ color:var(--muted); font-size:13.5px; line-height:1.65; white-space:pre-wrap; }
  .mini{ color:var(--muted); font-size:11px; }
  .slid{ display:flex; align-items:center; gap:8px; margin:5px 0; color:var(--muted); font-size:12px; }
  .slid input[type=range]{ flex:1; accent-color:var(--accent); } .slid b{ width:36px; text-align:right; color:var(--txt); font-variant-numeric:tabular-nums; font-family:var(--mono); font-size:12px; }
  #studioLightControls .slid{ min-height:30px; }
  #studioLightControls .slid b{ width:48px; }
  #studioLightControls .light-color input[type=color]{ width:42px; height:26px; margin-left:auto; padding:2px; border:1px solid var(--line); border-radius:4px; background:var(--panel2); cursor:pointer; }
  #studioLightControls .light-color input[type=color]::-webkit-color-swatch-wrapper{ padding:0; }
  #studioLightControls .light-color input[type=color]::-webkit-color-swatch{ border:0; border-radius:2px; }
  #studioLightControls .light-color input[type=color]::-moz-color-swatch{ border:0; border-radius:2px; }
  #studioLightControls .light-section-head{ display:flex; align-items:center; justify-content:space-between; margin-top:12px; padding-top:11px; border-top:1px solid var(--line); }
  .studioToolDlg{ width:min(620px, calc(100vw - 40px)); max-height:min(760px, calc(100dvh - 40px)); display:flex; flex-direction:column; }
  .studioToolDlg .dialog-body:has(.studio-tool-mount){ display:flex; overflow:hidden; }
  .studioToolDlg .studio-tool-mount{ flex:1 1 auto; min-width:0; min-height:0; overflow:auto; overflow-x:hidden; padding:2px 2px 0; }
  .studioToolDlg .studio-tool-content{ display:flex; flex-direction:column; gap:4px; min-width:0; max-width:100%; }
  #saveNote[data-save-state="queued"], #saveNote[data-save-state="note"]{ color:var(--muted); }
  #saveNote[data-save-state="saved"]{ color:var(--accent); }
  #saveNote[data-save-state="error"]{ color:var(--bad); }
  .durability-notices{ display:flex; flex-direction:column; gap:6px; margin-top:8px; }
  .durability-note{ display:flex; align-items:center; gap:8px; padding:8px; border:1px solid var(--line); background:rgba(255,255,255,.03); border-radius:4px; color:var(--txt); }
  .durability-note.bad{ border-color:rgba(255,100,100,.35); background:rgba(255,70,70,.07); }
  .durability-note b{ color:var(--bad); font-size:11px; white-space:nowrap; }
  .durability-note span{ flex:1; min-width:0; color:var(--muted); font-size:11px; line-height:1.35; }
  .durability-note .b{ flex:0 0 auto; padding:3px 8px; font-size:11px; }
  .studioToolDlg.lightdlg{ width:min(520px, calc(100vw - 40px)); }
  .studioToolDlg.matdlg{ width:min(1220px, calc(100vw - 32px)); max-height:min(720px, calc(100dvh - 32px)); }
  .studioToolDlg.matdlg .dialog-body{ flex:1 1 auto; overflow:hidden; padding:20px 24px; }
  .studioToolDlg.matdlg .studio-tool-mount{ overflow:hidden; padding:0; }
  .studioToolDlg.matdlg .studio-tool-content{ height:100%; min-height:0; }
  .studioToolDlg.importdlg{ width:min(820px, calc(100vw - 40px)); }
  .studioToolDlg.statusdlg{ width:min(720px, calc(100vw - 40px)); }
  .studioToolDlg.projectdlg{ width:min(430px, calc(100vw - 40px)); }
  .studioToolDlg.phasedlg{ width:min(980px, calc(100vw - 40px)); max-height:min(760px, calc(100dvh - 40px)); }
  .studioToolDlg.phasedlg .dialog-body{ flex:1 1 auto; min-height:0; overflow:hidden; padding:0; }
  .studioToolDlg.phasedlg .studio-tool-mount{ height:100%; overflow:hidden; padding:0; }
  .studioToolDlg.phasedlg .phase-list{ height:100%; }
  .studioToolDlg.suppdlg{ width:min(720px, calc(100vw - 40px)); }
  .studioToolDlg.partlibdlg{ width:min(1080px, calc(100vw - 40px)); max-height:min(820px, calc(100dvh - 40px)); }
  .studioToolDlg.partlibdlg .studio-tool-mount{ overflow:hidden; padding:0; }
  .studioToolDlg.treeoptdlg{ width:min(760px, calc(100vw - 40px)); }
  .studioToolDlg.onboarddlg{ width:min(860px, calc(100vw - 40px)); }
  /* The routing matrix is the decision tree read from the other side, so it gets the decision tree's room, not a dialog's. */
  .studioToolDlg.questiontreedlg{ width:calc(100vw - 32px); height:calc(100dvh - 32px); max-height:calc(100dvh - 32px); }
  .studioToolDlg.questiontreedlg .dialog-body{ flex:1 1 auto; min-height:0; overflow:hidden; }
  .studioToolDlg.questiontreedlg .studio-tool-mount{ display:flex; flex-direction:column; min-height:0; height:100%; overflow:hidden; }
  .studioToolDlg.questiontreedlg .form-tree-grid{ flex:1 1 auto; max-height:none; min-height:0; }
  .studioToolDlg .slid{ margin:7px 0; }
  .studioToolDlg input[type=range]:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  .studioToolDlg .matrow{ box-sizing:border-box; padding:10px 12px; }
  #matCtls{ min-width:0; min-height:0; height:100%; display:grid; grid-template-columns:minmax(320px,360px) minmax(0,1fr); align-items:stretch; gap:28px; }
  .material-library-pane{ min-width:0; min-height:0; height:100%; grid-column:1; grid-row:1; display:flex; flex-direction:column; }
  .material-library-toolbar{ flex:0 0 auto; min-height:38px; display:flex; align-items:center; justify-content:space-between; gap:12px; padding:0 0 12px; border-bottom:1px solid var(--line); }
  .material-library-toolbar>span{ min-width:0; display:flex; align-items:center; gap:8px; }
  .material-library-toolbar b{ color:var(--txt); font:650 12px/1.2 Roboto,system-ui,sans-serif; }
  .material-library-toolbar small{ color:var(--muted); font:650 10px/1 var(--mono); }
  .material-library-create{ display:grid; grid-template-columns:minmax(0,1fr) auto auto; gap:7px; padding:10px 0; border-bottom:1px solid var(--line); }
  .material-library-create input, .material-library-name input{ min-width:0; height:32px; box-sizing:border-box; border:1px solid var(--line); border-radius:4px; background:#181818; color:var(--txt); padding:0 9px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .material-library-create input:focus, .material-library-name input:focus{ border-color:rgba(169,133,221,.5); box-shadow:0 0 0 2px rgba(116,80,182,.16); }
  .material-library-list{ min-width:0; min-height:0; flex:1 1 auto; display:flex; flex-direction:column; overflow-y:auto; overflow-x:hidden; padding:4px 6px 0 0; }   /* scrollbar treatment comes from the shared scroll group above */
  .material-library-item{ appearance:none; width:100%; min-width:0; min-height:56px; display:grid; grid-template-columns:28px minmax(0,1fr); align-items:center; gap:12px; border:0; border-bottom:1px solid var(--line); background:transparent; color:var(--txt); padding:9px 12px; text-align:left; cursor:pointer; }
  .material-library-item:hover{ background:rgba(255,255,255,.035); }
  .material-library-item.selected{ background:var(--wash); box-shadow:inset 2px 0 var(--accent); }
  .material-library-item>i{ width:24px; height:24px; box-sizing:border-box; border:1px solid rgba(255,255,255,.24); border-radius:4px; background:var(--material-color); }
  .material-library-item>span{ min-width:0; display:flex; flex-direction:column; gap:4px; }
  .material-library-item b{ overflow-wrap:anywhere; font:600 12px/1.3 Roboto,system-ui,sans-serif; }
  .material-library-item small{ color:var(--muted); font:600 10px/1 var(--mono); }
  .material-library-empty{ padding:24px 10px; color:var(--muted); font:12px/1.4 Roboto,system-ui,sans-serif; }
  .material-rows{ min-width:0; display:flex; flex-direction:column; grid-column:1; grid-row:1; }
  .material-preview{ position:static; grid-column:2; grid-row:1; min-width:0; min-height:0; display:grid; grid-template-columns:minmax(320px,360px) minmax(340px,1fr); grid-template-rows:auto auto; align-content:start; gap:18px 24px; overflow:visible; padding:0 0 0 28px; border-left:1px solid var(--line); background:var(--panel); }
  .material-preview-stage{ grid-column:1; grid-row:2; align-self:start; justify-self:center; width:100%; max-width:360px; height:auto; aspect-ratio:1; box-sizing:border-box; overflow:hidden; border:1px solid var(--line); border-radius:4px; background:#151519; }
  .material-preview-stage canvas{ display:block; width:100%; height:100%; }
  .material-preview-meta{ grid-column:1 / -1; grid-row:1; min-width:0; min-height:0; display:grid; grid-template-columns:minmax(150px,.7fr) minmax(250px,1.15fr) auto; align-items:center; gap:18px; padding:0 0 14px; }
  #matCtls .material-preview-values{ display:none; }
  .material-library-name{ grid-column:2; grid-row:1; width:100%; min-width:0; display:grid; grid-template-columns:40px minmax(0,1fr); align-items:center; gap:8px; margin:0; }
  .material-library-name>span{ color:var(--muted); font:650 11px/1 var(--mono); }
  .material-library-usage{ grid-column:1; grid-row:1; min-width:0; margin:0; color:var(--muted); font:11px/1.3 Roboto,system-ui,sans-serif; overflow-wrap:anywhere; }
  .material-library-actions{ grid-column:3; grid-row:1; display:flex; align-items:center; justify-content:flex-end; gap:8px; margin:0; }
  .material-library-actions .material-reference-save.is-dirty:hover{ background:var(--primary-hi); border-color:var(--primary-hi); color:#fff; }
  .material-library-actions .material-library-delete{ color:var(--bad-rest); }
  .material-library-actions .material-library-delete:disabled{ color:var(--low); }
  .material-library-editor{ grid-column:2; grid-row:2; align-self:start; width:100%; padding:0!important; background:transparent!important; }
  .matrow.material-library-editor{ border-top:0; }
  .material-color-editor{ display:flex; flex-direction:column; gap:9px; margin-bottom:14px; padding-bottom:14px; border-bottom:1px solid var(--line); }
  .material-color-head{ min-height:30px; display:grid; grid-template-columns:minmax(72px,1fr) auto 24px; align-items:center; gap:10px; }
  .material-color-head>.ml{ color:var(--txt); font:600 12px/1.2 Roboto,system-ui,sans-serif; }
  .material-color-modes{ justify-self:end; }
  .material-color-modes .stab{ min-width:42px; padding:6px 8px; font:650 10px/1 var(--mono); }
  .material-color-modes .stab:focus-visible{ position:relative; z-index:1; outline:2px solid var(--accent); outline-offset:-2px; }
  .material-color-values{ min-height:30px; }
  .material-color-value-row{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); align-items:center; gap:8px; }
  .material-color-value-row[hidden]{ display:none; }
  .material-color-value-row[data-material-color-values="hex"]{ grid-template-columns:minmax(0,160px); }
  .material-color-value-row label{ min-width:0; display:grid; grid-template-columns:18px minmax(0,1fr); align-items:center; gap:6px; color:var(--muted); font:650 10px/1 var(--mono); }
  .material-color-value-row[data-material-color-values="hex"] label{ grid-template-columns:28px minmax(0,1fr); }
  .material-color-value-row input{ width:100%; min-width:0; height:30px; box-sizing:border-box; border:1px solid var(--line); border-radius:4px; background:#181818; color:var(--txt); padding:0 8px; font:600 11px/1 var(--mono); font-variant-numeric:tabular-nums; outline:none; }
  .material-color-value-row[data-material-color-values="hex"] input{ text-transform:uppercase; }
  .material-color-value-row input:focus{ border-color:rgba(169,133,221,.5); box-shadow:0 0 0 2px rgba(116,80,182,.16); }
  .material-color-field{ --material-hue:#f00; --material-saturation:0%; --material-value:0%; position:relative; width:100%; height:112px; box-sizing:border-box; border:1px solid rgba(255,255,255,.16); border-radius:4px; background:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,var(--material-hue)); cursor:crosshair; touch-action:none; outline:none; }
  .material-color-field:focus-visible{ border-color:var(--accent); box-shadow:0 0 0 2px rgba(116,80,182,.22); }
  .material-color-field>i{ position:absolute; left:var(--material-saturation); top:var(--material-value); width:12px; height:12px; box-sizing:border-box; border:2px solid #fff; border-radius:50%; box-shadow:0 0 0 1px rgba(0,0,0,.72); transform:translate(-50%,-50%); pointer-events:none; }
  .material-color-hue{ display:grid; grid-template-columns:72px minmax(0,1fr) 42px; align-items:center; gap:10px; min-height:28px; color:var(--muted); }
  .material-color-hue input[type=range]{ appearance:none; width:100%; height:14px; margin:0; border-radius:4px; background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00); cursor:pointer; }
  .material-color-hue input[type=range]::-webkit-slider-runnable-track{ height:10px; border-radius:4px; background:transparent; }
  .material-color-hue input[type=range]::-webkit-slider-thumb{ appearance:none; width:14px; height:14px; margin-top:-2px; border:2px solid #fff; border-radius:50%; background:#262229; box-shadow:0 0 0 1px rgba(0,0,0,.66); }
  .material-color-hue input[type=range]::-moz-range-track{ height:10px; border:0; border-radius:4px; background:linear-gradient(to right,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00); }
  .material-color-hue input[type=range]::-moz-range-thumb{ width:10px; height:10px; border:2px solid #fff; border-radius:50%; background:#262229; box-shadow:0 0 0 1px rgba(0,0,0,.66); }
  .material-color-hue b{ color:var(--txt); text-align:right; font:600 11px/1 var(--mono); font-variant-numeric:tabular-nums; }
  .material-library-editor .slid{ min-height:30px; margin:7px 0; }
  .material-library-editor .slid .matlbl{ width:72px; flex:0 0 72px; }
  .look-lock-note{ padding:8px 9px; border:1px solid var(--line); border-radius:4px; background:rgba(255,255,255,.03); color:var(--muted); font:600 11px/1.35 var(--mono); }
  [data-look-locked="1"]{ opacity:.82; }
  .project-select-row{ display:flex; flex-direction:column; gap:5px; padding:2px 0; }
  .project-select-row select{ width:100%; }
  .project-availability{ margin-top:12px; }
  .project-availability-list{ margin-top:12px; }
  .project-enable-row{ display:flex; align-items:center; gap:12px; min-height:38px; padding:8px 0; border-top:1px solid var(--line); }
  .project-enable-row:first-of-type{ border-top:0; }
  .project-enable-row .chrome-field-main{ flex:1 1 auto; }
  .project-enable-main{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
  .project-enable-row .chrome-field-label,
  .project-enable-main b{ color:var(--txt); font-weight:500; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .project-enable-row .chrome-field-value,
  .project-enable-main small{ color:var(--low); font:600 10px/1 var(--mono); }
  .project-enable-row input{ accent-color:var(--accent); flex:0 0 auto; }
  .phase-list{ gap:0; min-height:0; }
  .phase-editor{ height:min(620px, calc(100dvh - 174px)); min-height:500px; display:grid; grid-template-columns:230px minmax(0,1fr); overflow:hidden; }
  .phase-nav{ min-width:0; min-height:0; display:grid; grid-template-rows:auto minmax(0,1fr) auto; border-right:1px solid var(--line); background:#181818; }
  .phase-nav-head{ display:flex; flex-direction:column; gap:3px; padding:16px 16px 13px; border-bottom:1px solid var(--line); }
  .phase-nav-head strong{ font:600 13px/1.3 Roboto,system-ui,sans-serif; color:var(--txt); }
  .phase-nav-head span{ color:var(--muted); font:600 10px/1.3 var(--mono); }
  .phase-nav-list{ min-height:0; overflow-y:auto; }
  .phase-nav-row{ appearance:none; width:100%; min-height:56px; display:grid; grid-template-columns:26px minmax(0,1fr) auto; align-items:center; gap:8px; padding:9px 12px; border:0; border-bottom:1px solid var(--line); border-left:2px solid transparent; background:transparent; color:var(--txt); text-align:left; cursor:pointer; }
  .phase-nav-row:hover{ background:rgba(255,255,255,.035); }
  .phase-nav-row:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  .phase-nav-row.selected{ border-left-color:var(--accent); background:var(--wash); }
  .phase-nav-index{ color:var(--low); font:600 10px/1 var(--mono); }
  .phase-nav-copy{ min-width:0; display:flex; flex-direction:column; gap:3px; }
  .phase-nav-copy strong{ font:600 12px/1.25 Roboto,system-ui,sans-serif; }
  .phase-nav-copy span{ overflow:hidden; color:var(--muted); font:10px/1.25 Roboto,system-ui,sans-serif; text-overflow:ellipsis; white-space:nowrap; }
  .phase-nav-state{ color:var(--link); font:600 9px/1 var(--mono); text-transform:uppercase; }
  .phase-nav-note{ display:flex; flex-direction:column; gap:4px; padding:11px 14px 13px; border-top:1px solid var(--line); }
  .phase-nav-note strong{ color:var(--muted); font:600 10px/1.2 var(--mono); text-transform:uppercase; }
  .phase-nav-note span{ color:var(--low); font:10px/1.35 Roboto,system-ui,sans-serif; }
  .phase-inspector{ min-width:0; min-height:0; display:grid; grid-template-rows:auto auto auto minmax(0,1fr); gap:0; padding:16px 20px 18px; overflow:hidden; }
  .phase-inspector-head{ min-height:46px; display:flex; align-items:flex-start; justify-content:space-between; gap:16px; padding-bottom:12px; border-bottom:1px solid var(--line); }
  .phase-inspector-head div{ display:flex; flex-direction:column; gap:2px; }
  .phase-inspector-head span{ color:var(--low); font:700 10px/1.2 var(--mono); text-transform:uppercase; }
  .phase-inspector-head h3{ margin:0; color:var(--txt); font:600 16px/1.3 Roboto,system-ui,sans-serif; }
  .phase-use-state{ color:var(--low); font:600 10px/1.2 var(--mono); text-transform:uppercase; }
  .phase-use-state.active{ color:var(--link); }
  .phase-intro-field{ display:grid; grid-template-columns:140px minmax(0,1fr); align-items:start; gap:8px 12px; padding:14px 0; border-bottom:1px solid var(--line); }
  .phase-intro-field>span{ padding-top:8px; color:var(--muted); font:600 11px/1.3 Roboto,system-ui,sans-serif; }
  .phase-intro-field textarea{ width:100%; min-height:64px; box-sizing:border-box; resize:none; border:1px solid var(--line); border-radius:4px; background:var(--code); color:var(--txt); padding:8px 9px; font:12px/1.4 Roboto,system-ui,sans-serif; outline:none; }
  .phase-intro-field textarea:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .phase-intro-field small{ grid-column:2; color:var(--low); font:10px/1.3 Roboto,system-ui,sans-serif; }
  .phase-editor-section{ min-width:0; min-height:0; padding:12px 0 0; border-bottom:1px solid var(--line); }
  .phase-editor-section.phase-stages{ display:grid; grid-template-rows:auto minmax(0,1fr); border-bottom:0; }
  .phase-section-head{ min-height:30px; display:flex; align-items:flex-start; justify-content:space-between; gap:14px; }
  .phase-section-head>div{ display:flex; align-items:baseline; gap:8px; }
  .phase-section-head strong{ color:var(--txt); font:600 12px/1.3 Roboto,system-ui,sans-serif; }
  .phase-section-head span{ color:var(--low); font:600 10px/1 var(--mono); }
  .phase-add, .phase-assignment-select{ min-width:160px; height:30px; border:1px solid var(--line); border-radius:4px; background:#1c1c1c; color:var(--txt); padding:0 8px; font:11px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .phase-add:focus, .phase-assignment-select:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .phase-assignment-list{ min-width:0; }
  .phase-stage-list{ min-height:0; overflow-y:auto; scrollbar-gutter:stable; }
  .phase-assignment-row{ min-height:42px; display:grid; grid-template-columns:minmax(0,1fr) 174px; align-items:center; gap:12px; padding:6px 0; border-top:1px solid var(--line); }
  .phase-assignment-row:first-child{ border-top:0; }
  .phase-assignment-copy{ min-width:0; display:flex; flex-direction:column; gap:2px; }
  .phase-assignment-copy strong{ overflow:hidden; color:var(--txt); font:600 11px/1.25 Roboto,system-ui,sans-serif; text-overflow:ellipsis; white-space:nowrap; }
  .phase-assignment-copy span{ overflow:hidden; color:var(--muted); font:10px/1.25 Roboto,system-ui,sans-serif; text-overflow:ellipsis; white-space:nowrap; }
  .phase-editor-empty{ min-height:38px; display:flex; align-items:center; color:var(--muted); font:11px/1.35 Roboto,system-ui,sans-serif; }
  .supp-list{ gap:0; }
  .supp-list .grpsec:first-child{ margin-top:0; border-top:0; }
  .supp-row{ min-height:34px; padding-top:7px; padding-bottom:7px; color:var(--txt); cursor:pointer; }
  .supp-row:first-child{ border-top:0; }
  .supp-row:hover{ background:var(--wash); }
  .supp-row input{ flex:0 0 auto; accent-color:var(--accent); }
  .supp-row.on{ background:rgba(169,133,221,.08); }
  .supp-row.on .pn{ color:var(--link); }
  .supp-toolbar{ display:grid; grid-template-columns:minmax(220px,1fr) auto auto; align-items:center; gap:8px; min-height:30px; }
  .supp-search{ width:100%; min-width:0; height:30px; box-sizing:border-box; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:0 9px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .supp-search:focus, .supp-rename-input:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .supp-grid{ display:flex; flex-direction:column; gap:0; }
  .supp-row-list{ display:grid; grid-template-columns:minmax(126px,.75fr) minmax(0,1.25fr) auto auto; gap:9px; align-items:center; min-height:42px; padding:8px 0 8px var(--supp-depth,0); border-top:1px solid var(--line); }
  .supp-row-list:first-child{ border-top:0; }
  .supp-row-list.on{ background:rgba(169,133,221,.055); }
  .supp-check{ display:flex; align-items:center; gap:6px; color:var(--muted); font:700 10px/1 var(--mono); text-transform:uppercase; letter-spacing:.04em; cursor:pointer; }
  .supp-check input{ accent-color:var(--accent); margin:0; }
  .supp-ident{ min-width:0; display:flex; flex-direction:column; gap:3px; }
  .supp-ident b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font-size:12px; }
  .supp-ident code, .supp-count{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:600 10px/1.2 var(--mono); }
  .supp-rename{ min-width:0; display:grid; grid-template-columns:minmax(130px,1fr) auto auto; gap:6px; align-items:center; }
  .supp-rename-input{ min-width:0; height:28px; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:0 8px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .supp-rename-btn{ height:28px; padding:3px 9px; font-size:11px; color:var(--muted); }
  .supp-empty{ color:var(--muted); font-size:12px; padding:10px 8px; }
  .section-list{ display:flex; flex-direction:column; gap:0; min-width:0; }
  .section-list-head{ display:flex; flex-direction:column; gap:8px; padding:0 0 9px; border-bottom:1px solid var(--line); }
  .section-list-title{ display:flex; align-items:center; gap:8px; color:var(--txt); font-weight:700; }
  .section-list-count{ color:var(--muted); font:700 10px/1 var(--mono); text-transform:uppercase; letter-spacing:.04em; }
  .section-list-body{ min-width:0; }
  .chrome-field-row{ min-width:0; display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:10px; }
  .chrome-field-main{ min-width:0; display:flex; flex-direction:column; gap:3px; }
  .chrome-field-label{ color:var(--txt); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .chrome-field-value{ color:var(--low); font:600 10px/1 var(--mono); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .chrome-field-note{ color:var(--muted); font:600 10px/1.25 var(--mono); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .chrome-field-control{ display:flex; align-items:center; justify-content:flex-end; }
  .partlib-list{ gap:0; }
  .partlib-section{ display:grid; grid-template-columns:minmax(300px,.78fr) minmax(420px,1.22fr); grid-template-rows:auto minmax(0,1fr); height:min(640px,calc(100vh - 180px)); min-height:480px; }
  .partlib-section .section-list-head{ grid-column:1/-1; padding:0 0 12px; }
  .partlib-section .section-list-title{ display:none; }
  .partlib-section .section-list-controls{ min-width:0; }
  .partlib-toolbar{ display:grid; grid-template-columns:minmax(220px,1fr) auto auto auto; align-items:center; gap:10px; min-height:34px; }
  .partlib-search{ width:100%; min-width:0; box-sizing:border-box; height:34px; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:0 10px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .partlib-search::placeholder{ color:rgba(255,255,255,.46); }
  .partlib-search:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 2px rgba(169,133,221,.12); }
  .partlib-scopes{ display:grid; grid-auto-flow:column; border:1px solid var(--line); border-radius:4px; overflow:hidden; background:#181818; }
  .partlib-scope-button{ appearance:none; min-width:74px; height:32px; display:flex; align-items:center; justify-content:center; gap:6px; border:0; border-left:1px solid var(--line); background:transparent; color:var(--muted); padding:0 9px; font:600 11px/1 Roboto,system-ui,sans-serif; cursor:pointer; }
  .partlib-scope-button:first-child{ border-left:0; }
  .partlib-scope-button b{ color:var(--low); font:600 10px/1 var(--mono); }
  .partlib-scope-button:hover, .partlib-scope-button:focus-visible{ outline:none; color:var(--txt); background:rgba(255,255,255,.035); }
  .partlib-scope-button.on{ color:var(--link); background:var(--wash); box-shadow:inset 0 -2px var(--accent); }
  .partlib-scope-button.on b{ color:var(--link); }
  .partlib-count{ color:var(--muted); font:600 10px/1 var(--mono); white-space:nowrap; }
  .partlib-icon-button{ appearance:none; width:28px; height:28px; display:grid; place-items:center; border:1px solid var(--line); border-radius:4px; background:rgba(255,255,255,.02); color:var(--muted); padding:0; font:18px/1 Roboto,system-ui,sans-serif; cursor:pointer; }
  .partlib-icon-button:hover, .partlib-icon-button:focus-visible{ outline:none; color:var(--link); border-color:rgba(169,133,221,.35); background:var(--wash); }
  .partlib-grid{ min-width:0; overflow:auto; border-right:1px solid var(--line); padding-right:10px; }
  .partlib-list-head{ position:sticky; top:0; z-index:2; min-height:36px; display:flex; align-items:center; justify-content:space-between; border-bottom:1px solid var(--line); background:var(--panel); color:var(--muted); }
  .partlib-list-head>span{ font:600 10px/1 var(--mono); }
  .partlib-select-all{ display:inline-flex; align-items:center; gap:8px; min-height:28px; color:var(--muted); font:700 10px/1 Roboto,system-ui,sans-serif; text-transform:uppercase; letter-spacing:.04em; cursor:pointer; }
  .partlib-select-all input, .partlib-bulk-check input{ accent-color:var(--accent); margin:0; }
  .partlib-bulk{ position:sticky; top:36px; z-index:2; min-height:42px; display:grid; grid-template-columns:auto minmax(0,1fr) auto auto; align-items:center; gap:7px; border-bottom:1px solid rgba(169,133,221,.28); background:#27212f; padding:5px 7px; }
  .partlib-bulk>b{ color:var(--link); font:700 10px/1 var(--mono); white-space:nowrap; }
  .partlib-bulk label{ min-width:0; display:grid; grid-template-columns:auto minmax(0,1fr); align-items:center; gap:6px; }
  .partlib-bulk label>span{ color:var(--muted); font-size:10px; }
  .partlib-bulk select{ width:100%; min-width:0; height:28px; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:0 7px; font:11px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .partlib-bulk .b{ height:28px; padding:3px 9px; font-size:11px; }
  .partlib-bulk .partlib-icon-button{ width:28px; height:28px; }
  .partlib-empty{ min-height:90px; display:flex; align-items:center; justify-content:center; gap:8px; text-align:center; }
  .partlib-row{ display:grid; grid-template-columns:32px minmax(0,1fr); align-items:stretch; min-height:58px; border-bottom:1px solid var(--line); transition:background 140ms ease; }
  .partlib-row:hover{ background:rgba(255,255,255,.025); }
  .partlib-row.active{ background:var(--wash); }
  .partlib-bulk-check{ display:grid; place-items:center; cursor:pointer; }
  .partlib-result{ appearance:none; min-width:0; display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:10px; border:0; background:transparent; color:var(--txt); padding:9px 8px 9px 2px; text-align:left; font:inherit; cursor:pointer; }
  .partlib-result:focus-visible{ outline:1px solid var(--accent); outline-offset:-2px; }
  .partlib-result-copy{ min-width:0; display:flex; flex-direction:column; gap:4px; }
  .partlib-result-copy b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:12px; line-height:1.2; font-weight:600; }
  .partlib-result-copy small{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:600 10px/1.2 var(--mono); }
  .partlib-row.active .partlib-result-copy b{ color:var(--link); }
  .partlib-result-status{ display:flex; flex-direction:column; align-items:flex-end; gap:4px; }
  .partlib-result-status em{ color:var(--low); font:600 9px/1 var(--mono); font-style:normal; white-space:nowrap; }
  .partlib-inspector{ min-width:0; overflow:auto; padding:0 0 8px 18px; }
  .partlib-inspector-empty{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:6px; color:var(--muted); text-align:center; }
  .partlib-inspector-empty b{ color:var(--txt); font-size:13px; }
  .partlib-inspector-head{ min-height:52px; display:flex; align-items:flex-start; justify-content:space-between; gap:16px; padding:2px 0 14px; border-bottom:1px solid var(--line); }
  .partlib-inspector-head>div{ min-width:0; }
  .partlib-inspector-head h3{ margin:0; color:var(--txt); font-size:15px; line-height:1.3; font-weight:650; overflow-wrap:anywhere; }
  .partlib-inspector-head p{ margin:4px 0 0; color:var(--muted); font:600 10px/1.2 var(--mono); }
  .partlib-facts{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); margin:0; padding:12px 0; border-bottom:1px solid var(--line); }
  .partlib-facts>div{ min-width:0; padding:0 10px; border-left:1px solid var(--line); }
  .partlib-facts>div:first-child{ padding-left:0; border-left:0; }
  .partlib-facts dt{ color:var(--muted); font-size:10px; line-height:1.2; }
  .partlib-facts dd{ margin:4px 0 0; color:var(--txt); font:700 13px/1 var(--mono); }
  .partlib-inspector-section{ padding:14px 0; border-bottom:1px solid var(--line); }
  .partlib-inspector-section-head{ min-height:18px; display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:8px; }
  .partlib-inspector-section-head h4{ margin:0; color:var(--muted); font-size:11px; line-height:1.2; font-weight:700; text-transform:uppercase; letter-spacing:.04em; }
  .partlib-inspector-section-head span{ color:var(--low); font:600 10px/1 var(--mono); }
  .partlib-appearances{ min-width:0; display:flex; flex-direction:column; }
  .partlib-appearance{ display:grid; grid-template-columns:minmax(120px,.75fr) minmax(180px,1.25fr); align-items:center; gap:12px; min-height:48px; border-top:1px solid var(--line); color:var(--muted); }
  .partlib-appearance:first-child{ border-top:0; }
  .partlib-appearance.overridden{ background:rgba(169,133,221,.08); }
  .partlib-appearance-copy{ min-width:0; display:flex; flex-direction:column; gap:3px; }
  .partlib-appearance-copy b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font-size:11px; line-height:1.2; font-weight:600; }
  .partlib-appearance-copy small{ color:var(--muted); font:600 9px/1.2 var(--mono); }
  .partlib-appearance.overridden .partlib-appearance-copy small{ color:var(--link); }
  .partlib-app-pick{ min-width:0; display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:6px; }
  .partlib-appearance select{ width:100%; min-width:0; height:32px; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); font:11px/1 Roboto,system-ui,sans-serif; padding:0 8px; outline:none; }
  .partlib-appearance select:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 2px rgba(169,133,221,.12); }
  .partlib-reset{ appearance:none; width:30px; height:30px; display:grid; place-items:center; border:1px solid var(--line); border-radius:4px; background:rgba(255,255,255,.02); color:var(--muted); padding:0; font:15px/1 Roboto,system-ui,sans-serif; cursor:pointer; }
  .partlib-reset:hover, .partlib-reset:focus-visible{ outline:none; color:var(--link); border-color:rgba(169,133,221,.32); background:var(--wash); }
  .partlib-appearance-empty{ min-height:44px; display:flex; align-items:center; color:var(--low); font:600 10px/1.3 var(--mono); }
  .partlib-meta-editor{ display:flex; flex-direction:column; gap:9px; }
  .partlib-meta-field{ min-width:0; display:grid; grid-template-columns:76px minmax(0,1fr); align-items:start; gap:10px; }
  .partlib-meta-field>span{ padding-top:8px; color:var(--muted); font-size:11px; line-height:1.2; }
  .partlib-meta-field textarea{ width:100%; min-width:0; min-height:54px; max-height:140px; box-sizing:border-box; resize:vertical; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:8px 9px; font:12px/1.4 Roboto,system-ui,sans-serif; outline:none; }
  .partlib-meta-field textarea::placeholder, .partlib-link-row input::placeholder{ color:rgba(255,255,255,.46); }
  .partlib-meta-field textarea:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .partlib-meta-actions{ min-height:28px; display:flex; align-items:center; justify-content:flex-end; gap:10px; padding-left:86px; }
  .partlib-meta-actions>span{ margin-right:auto; color:var(--muted); font:600 10px/1 var(--mono); }
  .partlib-meta-actions>span.saved{ color:var(--link); }
  .partlib-meta-actions .b{ height:28px; padding:3px 9px; font-size:11px; }
  .partlib-technical{ padding:12px 0 2px; color:var(--muted); }
  .partlib-technical summary{ cursor:pointer; color:var(--muted); font-size:11px; font-weight:600; }
  .partlib-technical code, .partlib-technical>span{ display:block; margin-top:8px; color:var(--low); font:600 10px/1.35 var(--mono); overflow-wrap:anywhere; }
  .partlib-filters{ display:flex; align-items:center; gap:5px; flex-wrap:wrap; }
  .partlib-chip{ appearance:none; min-height:28px; display:inline-flex; align-items:center; gap:6px; border:1px solid var(--line); border-radius:4px; background:rgba(255,255,255,.025); color:var(--muted); padding:0 8px; font:700 10px/1 var(--mono); cursor:pointer; }
  .partlib-chip b{ color:var(--low); font:inherit; }
  .partlib-chip.on, .partlib-chip:hover{ color:var(--link); border-color:rgba(169,133,221,.35); background:rgba(169,133,221,.08); }
  .partlib-clear{ min-height:28px; padding:0 8px; font-size:11px; color:var(--muted); }
  .partlib-links{ display:flex; flex-direction:column; gap:6px; }
  .partlib-link-row{ display:grid; grid-template-columns:minmax(100px,.72fr) minmax(0,1.28fr); gap:6px; }
  .partlib-link-row input{ min-width:0; height:30px; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); padding:0 9px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .partlib-link-row input:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .importdlg{ width:min(680px,calc(100vw - 32px)); }
  .project-import-form{ display:flex; flex-direction:column; gap:18px; padding:2px 2px 4px; }
  .project-import-mode{ display:grid; grid-template-columns:1fr 1fr; width:100%; border:1px solid var(--line); border-radius:5px; overflow:hidden; background:#141414; }
  .project-import-mode button{ appearance:none; min-height:38px; border:0; border-left:1px solid var(--line); background:transparent; color:var(--muted); font:650 12px/1 Roboto,system-ui,sans-serif; cursor:pointer; }
  .project-import-mode button:first-child{ border-left:0; }
  .project-import-mode button:hover:not(:disabled){ color:var(--txt); background:rgba(255,255,255,.035); }
  .project-import-mode button:focus-visible{ position:relative; z-index:1; outline:2px solid var(--accent); outline-offset:-2px; }
  .project-import-mode button.selected{ color:var(--link); background:var(--wash); box-shadow:inset 0 -2px var(--accent); }
  .project-import-mode button:disabled{ }   /* type .is-ruled-out */
  .project-import-field{ display:grid; grid-template-columns:120px minmax(0,1fr); align-items:center; gap:14px; }
  .project-import-field>span{ color:var(--muted); font:650 12px/1.2 Roboto,system-ui,sans-serif; }
  .project-import-field input, .project-import-field select{ width:100%; min-width:0; box-sizing:border-box; height:38px; border:1px solid var(--line); border-radius:5px; background:#181818; color:var(--txt); padding:0 11px; font:12px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .project-import-field input:focus, .project-import-field select:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 2px rgba(116,80,182,.18); }
  .project-import-files{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  .project-import-file{ position:relative; min-width:0; min-height:82px; box-sizing:border-box; display:grid; grid-template-columns:44px minmax(0,1fr) auto; align-items:center; gap:10px; border:1px dashed #4b4b4b; border-radius:6px; background:#171717; padding:12px; cursor:pointer; }
  .project-import-file.optional{ grid-column:1 / -1; min-height:64px; }
  .project-import-file:hover{ border-color:#727272; background:#1b1b1b; }
  .project-import-file.ready{ border-style:solid; border-color:rgba(169,133,221,.5); background:rgba(169,133,221,.07); }
  .project-import-file input{ position:absolute; inset:0; width:100%; height:100%; opacity:0; cursor:pointer; }
  .project-import-file-type{ display:grid; place-items:center; width:42px; height:42px; border:1px solid #505050; border-radius:5px; color:#d8d8d8; background:#222; font:750 10px/1 var(--mono); }
  .project-import-file.ready .project-import-file-type{ border-color:rgba(169,133,221,.45); color:var(--link); }
  .project-import-file-copy{ min-width:0; display:flex; flex-direction:column; gap:5px; }
  .project-import-file-copy b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font:650 12px/1.2 Roboto,system-ui,sans-serif; }
  .project-import-file-copy small{ color:var(--low); font:650 10px/1 var(--mono); }
  .project-import-file-action{ color:var(--link); font:650 11px/1 Roboto,system-ui,sans-serif; }
  .project-import-error{ border:1px solid rgba(239,83,80,.34); border-radius:4px; background:var(--bad-fill); color:var(--bad-rest); padding:9px 11px; font:600 11px/1.45 Roboto,system-ui,sans-serif; }
  .project-import-progress{ display:flex; flex-direction:column; gap:14px; padding:4px 2px; }
  .project-import-progress-head{ display:flex; align-items:center; justify-content:space-between; gap:20px; }
  .project-import-progress-head b{ color:var(--txt); font:700 14px/1.2 Roboto,system-ui,sans-serif; }
  .project-import-progress-head span{ color:var(--link); font:750 12px/1 var(--mono); }
  .project-import-progress-track{ width:100%; height:8px; overflow:hidden; border-radius:4px; background:#292929; }
  .project-import-progress-track i{ display:block; height:100%; border-radius:4px; background:var(--primary); transition:width .2s ease; }
  .project-import-log{ display:flex; flex-direction:column; border-top:1px solid var(--line); }
  .project-import-log-row{ display:grid; grid-template-columns:18px minmax(0,1fr); align-items:center; gap:10px; min-height:42px; border-bottom:1px solid var(--line); }
  .project-import-log-row>span{ min-width:0; display:flex; align-items:baseline; justify-content:space-between; gap:16px; }
  .project-import-log-row b{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--muted); font:600 12px/1.3 Roboto,system-ui,sans-serif; }
  .project-import-log-row small{ flex:none; color:var(--low); font:600 10px/1 var(--mono); }
  .project-import-log-mark{ position:relative; width:12px; height:12px; box-sizing:border-box; }
  .project-import-log-row.done .project-import-log-mark::after{ content:""; position:absolute; left:2px; top:1px; width:5px; height:8px; border:solid var(--primary); border-width:0 2px 2px 0; transform:rotate(45deg); }
  .project-import-log-row.active b{ color:var(--txt); }
  .project-import-log-row.active small{ color:var(--link); }
  .project-import-log-row.active .project-import-log-mark{ border:2px solid rgba(169,133,221,.28); border-top-color:var(--primary); border-radius:50%; animation:project-import-spin .8s linear infinite; }
  @keyframes project-import-spin{ to{ transform:rotate(360deg); } }
  .project-import-materials{ min-width:0; display:flex; flex-direction:column; }
  .project-import-materials-head{ min-height:48px; display:flex; align-items:center; justify-content:space-between; gap:18px; padding:0 0 12px; border-bottom:1px solid var(--line); }
  .project-import-materials-head>div{ min-width:0; display:flex; flex-direction:column; gap:5px; }
  .project-import-materials-head b{ color:var(--txt); font:700 14px/1.2 Roboto,system-ui,sans-serif; }
  .project-import-materials-head span{ color:var(--muted); font:600 10px/1 var(--mono); }
  .project-import-material-bulk{ min-height:44px; display:grid; grid-template-columns:145px minmax(190px,1fr) auto; align-items:center; gap:8px; border-bottom:1px solid var(--line); }
  .project-import-material-bulk label{ display:flex; align-items:center; gap:8px; color:var(--muted); font:600 11px/1 Roboto,system-ui,sans-serif; }
  .project-import-material-bulk input, .project-import-material-row>input{ accent-color:var(--accent); }
  .project-import-material-bulk select, .project-import-material-row select{ min-width:0; height:32px; border:1px solid var(--line); border-radius:4px; background:#181818; color:var(--txt); padding:0 8px; font:11px/1.2 Roboto,system-ui,sans-serif; outline:none; }
  .project-import-material-bulk select:focus, .project-import-material-row select:focus{ border-color:rgba(169,133,221,.5); box-shadow:0 0 0 2px rgba(116,80,182,.16); }
  .project-import-material-list{ min-width:0; display:flex; flex-direction:column; }
  .project-import-material-row{ min-width:0; min-height:58px; display:grid; grid-template-columns:18px 24px minmax(160px,.85fr) minmax(220px,1.15fr); align-items:center; gap:10px; border-bottom:1px solid var(--line); padding:7px 0; }
  .project-import-material-swatch{ width:20px; height:20px; box-sizing:border-box; border:1px solid rgba(255,255,255,.24); border-radius:4px; background:var(--material-color); }
  .project-import-material-source{ min-width:0; display:flex; flex-direction:column; gap:4px; }
  .project-import-material-source b{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--txt); font:600 12px/1.2 Roboto,system-ui,sans-serif; }
  .project-import-material-source small{ color:var(--muted); font:600 10px/1 var(--mono); }
  @media(max-width:680px){
    .partlib-link-row{ grid-template-columns:1fr; }
  }
  .onboard-note{ color:var(--muted); font-size:12px; line-height:1.5; margin:0 0 12px; }
  .onboarddlg input, .onboarddlg textarea, .onboarddlg select{ min-width:0; border:1px solid var(--line); border-radius:4px; background:#1A1A1A; color:var(--txt); font:12px/1.35 Roboto,system-ui,sans-serif; outline:none; }
  .onboarddlg input, .onboarddlg select{ height:30px; padding:0 9px; }
  .onboarddlg input[data-form-field="title"]{ width:100%; box-sizing:border-box; }
  .onboarddlg textarea{ width:100%; min-height:48px; resize:vertical; padding:8px 9px; box-sizing:border-box; }
  .onboarddlg input:focus, .onboarddlg textarea:focus, .onboarddlg select:focus{ border-color:rgba(169,133,221,.45); box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .onboard-count{ color:var(--muted); font:600 11px/1 var(--mono); }
  .onboard-list, .onboard-card-list{ display:flex; flex-direction:column; gap:10px; }
  .onboard-list .section-list-head, .onboard-card-list .section-list-head{ display:none; }
  .onboard-list .section-list-body, .onboard-card-list .section-list-body{ display:flex; flex-direction:column; gap:10px; }
  .onboard-q{ border:1px solid var(--line); border-radius:8px; background:rgba(255,255,255,.025); padding:12px; display:flex; flex-direction:column; gap:8px; }
  .onboard-card{ border:1px solid var(--line); border-radius:8px; background:rgba(27,27,27,.48); padding:12px; display:flex; flex-direction:column; gap:8px; }
  .onboard-qhead, .onboard-ahead{ display:grid; grid-template-columns:auto minmax(180px,1fr) auto auto; gap:8px; align-items:center; }
  .onboard-cardhead{ display:grid; grid-template-columns:auto minmax(120px,.6fr) minmax(110px,.4fr) auto; gap:8px; align-items:center; }
  .onboard-qhead b, .onboard-ahead b, .onboard-cardhead b{ color:var(--accent); font:700 12px/1 var(--mono); }
  .onboard-cardhead input[readonly]{ color:var(--low); background:#151515; }
  .onboard-answers{ display:flex; flex-direction:column; gap:8px; margin-top:2px; }
  .onboard-a{ border-top:1px solid var(--line); padding-top:8px; display:flex; flex-direction:column; gap:7px; }
  .form-routes{ display:flex; flex-direction:column; gap:6px; }
  .form-route{ display:grid; grid-template-columns:minmax(160px,.8fr) minmax(160px,1fr) auto; gap:7px; align-items:center; }
  .form-route.empty{ display:block; color:var(--muted); font:600 11px/1.4 var(--mono); padding:5px 0; }
  .form-tree-toolbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:0 0 10px; }
  .form-tree-legend{ display:flex; align-items:center; gap:12px; color:var(--muted); font:600 10px/1 var(--mono); }
  .form-tree-legend .need{ color:var(--link); }
  .form-tree-legend .out{ color:var(--bad-rest); }
  .form-tree-count{ margin-left:auto; color:var(--muted); font:600 10px/1 var(--mono); white-space:nowrap; }
  .form-tree-warning{ border:1px solid rgba(232,160,154,.34); border-radius:4px; padding:8px 9px; background:var(--bad-fill); color:var(--bad-rest); }
  .form-tree-grid{ min-height:280px; max-height:min(65vh,680px); overflow:auto; border:1px solid var(--line); border-radius:4px; background:var(--panel); }
  .form-question-tree th.rh{ width:280px; min-width:280px; padding:7px 9px; font:600 11px/1.25 Roboto,system-ui,sans-serif; }
  .form-question-tree .form-tree-name{ display:block; padding-right:48px; overflow:hidden; text-overflow:ellipsis; }
  .form-question-tree .form-tree-or{ margin-left:6px; color:var(--link); font:700 9px/1 var(--mono); }
  .form-question-tree .form-tree-actions{ position:absolute; top:50%; right:7px; display:flex; gap:3px; transform:translateY(-50%); }
  .form-question-tree .form-tree-actions .gx{ min-width:20px; width:20px; height:20px; padding:0; color:var(--muted); font:700 11px/1 var(--mono); }
  .form-question-tree .form-tree-actions .gx:hover{ color:var(--link); }
  .form-question-tree .form-tree-actions .gx:last-child:hover{ color:var(--bad-rest); }
  .form-question-tree .form-tree-always{ display:block; margin-top:3px; color:var(--low); font:500 9px/1.3 var(--mono); white-space:normal; }
  .form-question-tree td.cell.off{ cursor:not-allowed; background:rgba(255,255,255,.014); color:transparent; }
  .form-question-tree td.cell.off:hover{ box-shadow:none; }
  @media(max-width:680px){ .onboard-qhead, .onboard-ahead, .onboard-cardhead, .form-route{ grid-template-columns:1fr; } .onboard-qhead b, .onboard-ahead b, .onboard-cardhead b{ display:none; } }
  .treeopt-toolbar{ display:flex; align-items:center; gap:10px; padding:0 0 10px; border-bottom:1px solid var(--line); margin-bottom:4px; }
  .treeopt-count{ color:var(--muted); font:600 11px/1 var(--mono); }
  .treeopt-section-head input, .treeopt-head input, .treeopt-row .treeopt-option-label{ width:100%; min-width:0; box-sizing:border-box; border:1px solid transparent; border-radius:4px; background:transparent; color:var(--txt); font:12px/1.35 Roboto,system-ui,sans-serif; padding:4px 6px; outline:none; }
  .treeopt-section-head input:focus, .treeopt-head input:focus, .treeopt-row .treeopt-option-label:focus{ border-color:rgba(169,133,221,.45); background:#1C1C1C; box-shadow:0 0 0 1px rgba(169,133,221,.16); }
  .treeopt-list{ display:flex; flex-direction:column; gap:0; }
  .treeopt-list .dragging{ opacity:.48; }
  .treeopt-section:first-child .treeopt-section-head, .treeopt-axis:first-child .treeopt-head{ margin-top:0; border-top:0; }
  .treeopt-section-head{ display:grid; grid-template-columns:18px minmax(150px,1fr) 26px 24px 24px; align-items:center; gap:6px; min-height:36px; padding:7px 0; border-top:1px solid var(--line); }
  .treeopt-section-head .tw, .treeopt-head .tw{ text-align:center; color:var(--muted); }
  .treeopt-section-head .gc, .treeopt-head .gc{ color:var(--muted); font:600 10px/1 var(--mono); text-align:right; }
  .treeopt-section-fields{ padding:0 0 8px 18px; }
  .treeopt-section-fields.closed{ display:none; }
  .treeopt-section-fields .treeopt-axis:first-child .treeopt-head{ border-top:0; }
  .treeopt-loose{ border-top:1px solid var(--line); margin-top:4px; }
  .treeopt-loose-head{ display:grid; grid-template-columns:18px minmax(150px,1fr) 26px; align-items:center; gap:6px; min-height:34px; padding:6px 0; color:var(--muted); }
  .treeopt-loose-head .pn{ font-weight:500; }
  .treeopt-empty{ padding:7px 0 10px 24px; }
  .treeopt-axis:first-child .treeopt-head{ margin-top:0; border-top:0; }
  .treeopt-head{ display:grid; grid-template-columns:18px minmax(150px,1fr) 26px 24px 24px; align-items:center; gap:6px; min-height:34px; padding:6px 0; }
  .treeopt-values{ padding:0 0 8px 18px; }
  .treeopt-values.closed{ display:none; }
  .treeopt-row{ min-height:34px; padding:4px 0; display:grid; grid-template-columns:18px minmax(130px,.75fr) minmax(220px,1.25fr) 82px 24px; align-items:start; gap:6px; }
  .treeopt-detail-preview{ min-width:0; color:var(--muted); font:11px/1.35 Roboto,system-ui,sans-serif; padding:4px 6px 0; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
  .treeopt-detail-preview.empty{ color:var(--low); font-style:italic; }
  .treeopt-detail{ height:24px; padding:2px 10px; font-size:11px; justify-self:end; color:var(--muted); }
  .treeopt-detail.hascopy{ color:var(--accent); border-color:rgba(169,133,221,.38); background:rgba(116,80,182,.14); }
  .treeopt-section-head .gx, .treeopt-head .gx, .treeopt-row .gx{ color:var(--muted); }
  .treeopt-section-head .treeopt-add-field:hover, .treeopt-head .treeopt-add-option:hover{ color:var(--link); }
  .treeopt-section-head .gx:not(.treeopt-add-field):hover, .treeopt-head .gx:not(.treeopt-add-option):hover, .treeopt-row .gx:hover{ color:var(--bad); }
  .treeopt-row.drophot{ outline:2px solid var(--accent); background:rgba(169,133,221,.18); }
  .treeopt-row.dropbefore{ box-shadow:inset 0 2px 0 var(--accent); }
  .treeopt-row.dropafter{ box-shadow:inset 0 -2px 0 var(--accent); }
  @media (max-width:760px){
    .treeopt-section-head, .treeopt-head{ grid-template-columns:18px minmax(120px,1fr) 24px 24px 24px; }
    .treeopt-row{ grid-template-columns:18px minmax(95px,.8fr) minmax(120px,1.1fr) 74px 24px; }
  }
  @media (max-width:520px){
    .treeopt-toolbar{ flex-wrap:wrap; gap:8px; }
    .treeopt-section-fields, .treeopt-values{ padding-left:10px; }
    .treeopt-section-head, .treeopt-head{ grid-template-columns:18px minmax(0,1fr) 24px 24px 24px; gap:5px; }
    .treeopt-row{ grid-template-columns:18px minmax(0,1fr) 24px; gap:5px; }
    .treeopt-detail-preview{ grid-column:2 / -1; padding-left:0; }
    .treeopt-detail{ grid-column:2; justify-self:start; }
    .treeopt-row>.gx{ grid-column:3; grid-row:1; justify-self:end; }
  }
  .matrow{ border-top:1px solid var(--line); padding:6px 0; }
  .matrow.previewing{ background:var(--wash); }
  .matrow.previewing .mn .ml{ color:var(--link); }
  .matrow.matsel{ background:var(--wash); outline:1px solid rgba(169,133,221,.5); border-radius:4px; }   /* highlighted when its part is selected */
  .matrow .mn{ display:flex; align-items:center; gap:7px; color:var(--txt); margin-bottom:3px; }
  .matrow .mn input[type=color]{ width:22px; height:17px; border:1px solid var(--line); border-radius:4px; background:none; padding:0; cursor:pointer; }
  .matrow .mn .ml{ flex:1; }
  .matrow .matlbl{ width:58px; }
  .matrow .mn .uisw{ width:22px; height:17px; border:1px solid var(--line); border-radius:4px; flex:0 0 auto; }
  .uihdr{ display:flex; align-items:center; margin:14px 0 2px; border-top:1px solid var(--line); padding-top:10px; }   /* type = .t-section (11px) */
  .rs{ flex:0 0 auto; background:none; border:0; color:var(--muted); cursor:pointer; font-size:13px; line-height:1; padding:0 2px; }
  .rs:hover{ color:var(--accent); }
  details>summary{ cursor:pointer; color:var(--muted); list-style:none; } details[open]>summary{ color:var(--txt); }
  .note{ color:var(--muted); font-size:11px; }
