/* ---------------------------------------------------------------
   ARTIFACTORY — mobile + craft layer.  Added 2026-08-26.
   Appended over the compiled Next stylesheet; app source unavailable.
   Port into source and delete this file if the tree is recovered.

   Measured problem (iPhone 390x844, live):
     .pod-tools is a 374px scroll strip holding ~746px of content.
     input.title-in = 132px, a.stamp = 87px, and the primary action
     (EXPORT) renders at x=573-765 — entirely off-screen. The mobile
     controls exist; they are simply unreachable without scrubbing a
     39px-tall bar sideways.
   Approach: demote identity/labels on small screens so the controls
   fit, rather than restructuring the app's own mobile pattern.
   --------------------------------------------------------------- */

@media (max-width: 560px) {
  /* Reclaim the ~300px spent on identity and the title field.
     The artifact title stays editable in the ARTIFACTS panel. */
  .pod-tools .title-in,
  .pod-tools .stamp,
  .pod-tools .pod-div { display: none; }
  .pod-tools .wordmark { display: none; }

  /* Below ~430px the brand mark is the last 35px between a usable
     EXPORT button and a clipped one. The menu button carries identity. */
  @media (max-width: 430px) {
    .pod-tools .brand-mark-btn { display: none; }
  }

  /* Bar clears the home indicator and centres what remains. */
  .pod.pod-tools {
    bottom: calc(8px + env(safe-area-inset-bottom));
    gap: 3px;
    padding: 4px 4px;
    justify-content: center;
  }

  /* Touch targets: icon buttons ship at 28px, under the 44px floor.
     36px is the most that fits alongside FORMS/BACKGROUND/EXPORT. */
  /* 33px is the largest square that lets all seven controls fit 374px
     without scrolling. Still short of the 44px floor: the real fix is
     to move the three secondary icons into the menu, which needs source. */
  .pod-tools .icon-btn { min-width: 32px; min-height: 32px; }
  .pod-tools .cta { min-height: 32px; }

  /* Panels stay the app's bottom sheet (bottom:62px, top:auto). Never set
     .panel{top} here: it turned the sheet into a stage-covering slab twice
     (2026-09-07, 2026-11-01). Section 11 sizes the sheet. */
}

/* Dynamic viewport units: the iOS URL bar cuts 100vh/46vh panels. */
@supports (height: 100dvh) {
  .stage { height: 100dvh; }
}

/* Craft: the LIGHTING selector truncates three of its four printed
   legends (STUDIO / OVER... / GOLD... / HARD), which defeats the point
   of a legended switch. Tighten tracking and padding so all four read. */
.rig-sw { letter-spacing: 0; }
.rig-sw button { padding-left: 4px; padding-right: 4px; letter-spacing: .01em; }

/* Craft: hover states stick after tap on touch devices. */
@media (hover: none) {
  .tile:hover, .icon-btn:hover, .mini:hover, .reg-tab:hover { filter: none; }
}


/* =================================================================
   CRAFT FIXES (desktop + mobile)
   ================================================================= */

/* 1. Phantom display face.
   --display led with "Helvetica Now Display", which is NOT among the
   fonts this build ships (the only webfont is Inter, 6 variable
   subsets via next/font). It therefore rendered only on machines with
   Helvetica Now installed locally — i.e. the art director saw a
   different site from every visitor. Lead with the face that actually
   loads. To restore the intent, self-host a licensed Helvetica Now
   and re-add it here (NOT the TRIAL files, which were removed). */
:root {
  --display: var(--font-inter), "Inter", "Helvetica Neue", Arial, sans-serif;
}

/* 2. LIGHTING selector truncated three of four printed legends
   (STUDIO / OVER... / GOLD... / HARD). The base rule intends a 2x2
   grid; rendering 4-across gives ~42px cells while .rig-leg needs
   ~48px at var(--t-9). Restore 2x2 so every legend reads in full —
   a legended switch that can't be read defeats its own premise. */
.rig .rig-sw { grid-template-columns: 1fr 1fr; }

/* 3. Orphaned knob row. .dials is flex-wrap with 8 dials in a 188px
   well = rows of 3/3/2, leaving the last row jammed left against a
   dead cell. Centring only moves incomplete rows (full rows already
   fill the width), so this fixes the orphan and nothing else. */
.dials { justify-content: center; }

/* 4. Panel titles sat at different x across the three pods.
   .panel-bar is `12px 1fr auto`, so the centred title centres inside a
   residual width that shrinks when a third control exists (FORMS has a
   close X, SCENE a refresh, ARTIFACTS neither). Reserving the third
   column at a constant 20px aligns all three titles identically. */
.panel-bar { grid-template-columns: 12px 1fr 20px; }

/* 5. No monospace in the UI. --mono and --code both resolve to Inter;
   tabular-nums carries the numerals. Only exported code (.code) keeps a
   monospace face, because there it is actually code. See section 9. */
:root { --mono: var(--display); --code: var(--display); }

/* 6. The artifact title used `border-bottom: 1px dotted var(--ink-4)`,
   which reads as a spellcheck squiggle / validation error rather than
   an editable field. A solid hairline that strengthens on hover and
   focus keeps the affordance and loses the error connotation. */
.title-in { border-bottom: 1px solid var(--hair); }
.title-in:hover { border-bottom-color: var(--ink-4); }
.title-in:focus { border-bottom-color: var(--ink-2); }

/* 7. Panel stacking. .panel-files (ARTIFACTS) and .panel-form (OBJECT)
   share the left rail; .panel-form is bottom-anchored, so as its tile
   grid grows its top rises into the panel above. Adding four objects
   took the grid from three rows to four and produced a measured 46px
   overlap. Cap the height and let the body scroll instead.
   Note: .panel-files grows with saved artifacts, so this constant
   assumes a short list — the real fix is a flex column in source. */
@media (min-width: 1101px) {
  .panel-form { max-height: calc(100dvh - 215px); overflow-y: auto; overscroll-behavior: contain; }
  .panel-params { max-height: calc(100dvh - 120px); overflow-y: auto; overscroll-behavior: contain; }
}

/* 8. The capped panels scroll, but macOS auto-hides overlay scrollbars,
   so a knob sliced at the boundary reads as a clipping bug rather than
   as "there is more below". Give the two scrolling panels a persistent
   thin rail so the affordance is visible. */
.panel-form, .panel-params { scrollbar-width: thin; scrollbar-color: var(--ink-4) transparent; }
.panel-form::-webkit-scrollbar, .panel-params::-webkit-scrollbar { width: 6px; }
.panel-form::-webkit-scrollbar-track, .panel-params::-webkit-scrollbar-track { background: transparent; }
.panel-form::-webkit-scrollbar-thumb, .panel-params::-webkit-scrollbar-thumb {
  background: var(--ink-4); border-radius: var(--r-pill); border: 1px solid transparent; background-clip: padding-box;
}


/* =================================================================
   9. WHITE (2026-11-01)
   Reference: Scenario's 3D OS panels — solid docked surfaces, sentence
   case, one accent for selection. White is the default theme; dark is
   still offered under Settings → Theme and inherits the type changes.

   Rules of this layer:
   - Surfaces are solid white with a hairline and a soft offset shadow.
     No backdrop blur: glass over a 3D stage read as decoration.
   - Blue means selected (tile, switch position, file, dial arc), nothing
     else. Export is the one filled control, in ink.
   - Text is Inter in sentence case. The base sheet set
     body{text-transform:uppercase}, which is where the shouting came from.
   ================================================================= */

:root:not([data-theme=dark]) {
  --pod: #ffffff;
  --pod-edge: rgba(17, 19, 24, .10);
  --pod-in: #f4f5f7;
  --pod-in-2: #eaecef;
  --ink: #15171c;
  --ink-2: #4a4f59;
  --ink-3: #686d77;
  --ink-4: #b1b5bc;
  --hair: rgba(17, 19, 24, .08);
  --screen: #f1f2f4;
  --well: #f6f7f8;
  --bg: #eef0f2;
  --signal: #2f5bea;
  --on-signal: #ffffff;
  --blur: none;
  --sh-pod: 0 1px 2px rgba(16, 18, 24, .04), 0 8px 24px rgba(16, 18, 24, .07);
}

/* Type, both themes */
body { text-transform: none; letter-spacing: -.006em; }
button, input, select, textarea { font-family: inherit; }
.code { font-family: ui-monospace, "SF Mono", Menlo, monospace; }

.panel-t { text-align: left; font-size: var(--t-13); font-weight: 600; letter-spacing: -.01em; }
.sec { text-align: left; font-size: var(--t-12); font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-2); padding: 8px 2px 2px; }
.sec-row { padding-inline: 2px; }
.title-in, .title-in::placeholder { text-transform: none; }
.title-in { font-size: var(--t-13); }

.cta, .icon-btn, .seg-btn, .mini, .ctrl-tab, .tsw-opt, .tg, .stamp,
.dh-lbl, .empty-hint, .sub, .index-n, .index-rg, .file-at,
.dial-label, .hlabel, .rig-leg, .slrow-label {
  text-transform: none;
  letter-spacing: 0;
}
.cta { font-size: var(--t-12); font-weight: 600; }
.icon-btn, .seg-btn, .tsw-opt { font-size: var(--t-12); }
.mini, .ctrl-tab, .tg { font-size: var(--t-11); font-weight: 500; }
.dh-lbl, .empty-hint, .sub, .index-n, .index-rg, .file-at { font-size: var(--t-11); color: var(--ink-3); }
.dh-lbl { font-size: var(--t-12); font-weight: 500; color: var(--ink-2); }
.purpose { font-size: var(--t-12); line-height: 1.5; }
.file-nm { font-size: var(--t-12); font-weight: 500; }
.dial-label { font-size: var(--t-11); color: var(--ink-2); }
.dial-val { font-size: var(--t-11); font-weight: 500; }
.hlabel { font-size: var(--t-12); }
.hex { font-size: var(--t-11); letter-spacing: 0; text-transform: uppercase; font-variant-numeric: tabular-nums; }
.rig-leg { font-size: var(--t-11); font-weight: 500; }
.rig-sw button { letter-spacing: 0; }

/* Dotted rules read as perforation; hairlines read as structure. */
.rig { border-bottom-style: solid; }
.dial { border-right-style: solid; border-bottom-style: solid; }

/* Surfaces and selection: owned by the macOS layer (section 12). */
.active-artifact .tg { text-transform: none; letter-spacing: 0; font-size: var(--t-11); }


/* =================================================================
   11. ROOM FOR THE ARTIFACT (2026-11-01)
   Desktop: chrome hugs the edges, the top bar is 40px, panel padding
   tightens, so the stage gets the space. Compact (<=1100px): one bottom
   sheet above the bar, at most 44% of the screen, scrolling inside,
   with the intro paragraph dropped and 6 tiles per row.
   ================================================================= */
@media (min-width: 1101px) {
  :root { --edge: 6px; }
  .pod-tools { padding: 2px 6px 2px 8px; min-height: 40px; }
  .panel-bar { padding-top: 8px; padding-bottom: 6px; }
  .panel-body { padding-inline: 10px; }
  .purpose { padding-top: 8px; padding-bottom: 8px; }
}
@media (max-width: 1100px) {
  .panel-code, .panel-form, .panels, .panels > .panel, .panel-params {
    max-height: 44dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .panel-form, .panels { bottom: calc(60px + env(safe-area-inset-bottom)); }
  .pod-tools { bottom: calc(8px + env(safe-area-inset-bottom)); justify-content: space-between; }
  .purpose { display: none; }
  /* the sheet is a flex column with a max-height: without this the dial
     grid shrinks to 0 instead of the sheet scrolling */
  .panel > *, .panel-body > * { flex-shrink: 0; }
  /* previews fill by size, not by count: about eight a row on a phone, each still a 40px+ target */
  .tiles { grid-template-columns: repeat(auto-fill, minmax(42px, 1fr)); gap: 6px; }
  .dials { grid-template-columns: repeat(4, 1fr); }
  .tile { border-radius: 10px; }
}



/* Fill: every block inside a panel spans the panel's inner width. */
.panel-body > *, .rig, .rig-sw, .tiles, .dials, .seg-row, .sec-row, .files, .list {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  margin-inline: 0;
}
.rig { padding-inline: 0 !important; }
.rig-sw { display: grid; }


/* =================================================================
   12. macOS (2026-11-01; replaces the TE and hardware-glass layers)
   Reference: macOS Sonoma, dark appearance. Panels are HUD-style
   floating panels: vibrancy material (blur + saturate) over the stage,
   a hairline edge and one shadow, because they actually float.
   - System font, sentence case, 13px controls, 11px secondary labels.
   - Accent is the system blue (#0a84ff dark / #007aff light). It marks
     the selection ring, the default button (Export) and dial arcs.
   - Push buttons are flat fills with a faint top highlight; no glow,
     no drop shadow under controls.
   - Radii by job: 10 panel, 6 control, 8 tile and group box.
   ================================================================= */
:root[data-theme=dark] {
  --bg: #1e1e1e; --screen: #161616;
  --pod: rgba(40, 40, 42, .72);
  --pod-edge: rgba(255, 255, 255, .10);
  --pod-in: rgba(255, 255, 255, .09);
  --pod-in-2: rgba(255, 255, 255, .16);
  --ink: rgba(255, 255, 255, .88); --ink-2: rgba(235, 235, 245, .62);
  --ink-3: rgba(235, 235, 245, .45); --ink-4: rgba(235, 235, 245, .22);
  --hair: rgba(255, 255, 255, .08); --well: rgba(0, 0, 0, .18);
  --signal: #0a84ff; --on-signal: #fff;
  --mac-sel: rgba(255, 255, 255, .20);
  --mac-shadow: 0 0 0 .5px rgba(0, 0, 0, .8), 0 12px 32px rgba(0, 0, 0, .45);
  --mac-hi: inset 0 .5px 0 rgba(255, 255, 255, .12);
}
:root:not([data-theme=dark]) {
  --bg: #ececec; --screen: #e5e5e5;
  --pod: rgba(246, 246, 246, .76);
  --pod-edge: rgba(0, 0, 0, .10);
  --pod-in: rgba(0, 0, 0, .05);
  --pod-in-2: rgba(0, 0, 0, .09);
  --ink: rgba(0, 0, 0, .85); --ink-2: rgba(60, 60, 67, .62);
  --ink-3: rgba(60, 60, 67, .45); --ink-4: rgba(60, 60, 67, .22);
  --hair: rgba(0, 0, 0, .08); --well: rgba(0, 0, 0, .04);
  --signal: #007aff; --on-signal: #fff;
  --mac-sel: #fff;
  --mac-shadow: 0 0 0 .5px rgba(0, 0, 0, .18), 0 12px 32px rgba(0, 0, 0, .16);
  --mac-hi: inset 0 .5px 0 rgba(255, 255, 255, .6);
}
:root {
  --display: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", var(--font-inter), "Inter", sans-serif;
  --sans: var(--display); --mono: var(--display);
  --r-pod: 10px; --blur: saturate(180%) blur(30px); --sh-pod: var(--mac-shadow);
}
body { font-family: var(--display); text-transform: none; letter-spacing: 0; -webkit-font-smoothing: antialiased; }

/* panels: vibrancy */
.panel, .pod, .index {
  background: var(--pod);
  backdrop-filter: saturate(180%) blur(30px);
  -webkit-backdrop-filter: saturate(180%) blur(30px);
  border: 1px solid var(--pod-edge);
  border-radius: 10px;
  box-shadow: var(--mac-shadow);
}

/* type: sentence case, system sizes */
.panel-t, .sec, .dh-lbl, .dial-label, .hlabel, .rig-leg, .mini, .ctrl-tab, .icon-btn, .seg-btn,
.tsw-opt, .tg, .cta, .sub, .file-at, .empty-hint, .slrow-label, .pod-tools .wordmark {
  text-transform: none; letter-spacing: 0;
}
.panel-t { font-size: 13px; font-weight: 600; color: var(--ink); }
.sec, .dh-lbl, .hlabel, .dial-label, .rig-leg { font-size: 11px; font-weight: 500; color: var(--ink-2); }
.dial-val { font-size: 11px; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.pod-tools .wordmark { font-size: 13px; font-weight: 600; }
.empty-hint, .sub, .file-at { font-size: 11px; color: var(--ink-3); }
.purpose { font-size: 12px; line-height: 1.45; color: var(--ink-2); }

/* push buttons */
.cta, .icon-btn, .mini, .seg-btn, .view-t button, .x, .reg-tab {
  border-radius: 6px; font-size: 12px; font-weight: 500;
}
.icon-btn, .mini, .x, .reg-tab, .view-t button {
  background: var(--pod-in); color: var(--ink); border: 0; box-shadow: var(--mac-hi);
}
.icon-btn:hover, .mini:hover, .x:hover { background: var(--pod-in-2); }
.icon-btn:active, .mini:active, .x:active { background: var(--mac-sel); }
.icon-btn.sel, .reg-tab.on, .view-t button.on { background: var(--mac-sel); color: var(--ink); box-shadow: var(--mac-hi); }
:root:not([data-theme=dark]) .icon-btn.sel, :root:not([data-theme=dark]) .view-t button.on { box-shadow: 0 0 0 .5px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.08); }
.cta { background: var(--signal); color: #fff; border: 0; padding: 5px 12px; box-shadow: var(--mac-hi); }
.cta:hover, .cta.open { background: #2a92ff; }
.cta::before { content: none; }

/* segmented controls: gray selection, as in macOS */
.rig-sw { background: var(--pod-in); border: 0; border-radius: 7px; padding: 2px; box-shadow: none; }
.rig-pos { border-radius: 5px; font-size: 12px; font-weight: 500; color: var(--ink); }
.rig-pos.on, .seg-row .seg-btn.on { background: var(--mac-sel); color: var(--ink); box-shadow: 0 0 0 .5px rgba(0,0,0,.2), 0 1px 2px rgba(0,0,0,.2), var(--mac-hi); }
.seg-row .seg-btn { background: var(--pod-in); color: var(--ink); }

/* group boxes */
.dials { background: var(--well); border: 1px solid var(--hair); border-radius: 8px; overflow: hidden; }
.dial, .rig { border-color: var(--hair); border-style: solid; }
/* The name edits in place: no fill and no pill on hover or focus. Ink rises on
   hover; while editing, a hairline under the text and the caret mark the field. */
.title-in { background: transparent; border: 0; border-bottom: 1px solid transparent; border-radius: 0; font-size: 13px; font-weight: 500; }
.title-in:hover, .title-in:focus { background: transparent; color: var(--ink); }
/* the global focus ring is a rounded outline; for the name it reads as a pill */
.title-in:focus, .title-in:focus-visible { border-radius: 0 !important; border-bottom-color: var(--ink-3); }

/* tiles: selection ring, as in Finder */
.tile, .file-open { border-radius: 8px; border: 1px solid var(--hair); box-shadow: none; }
.tile.on { border-color: transparent; box-shadow: 0 0 0 3px var(--signal); }
.file.on .file-open { border-color: transparent; background: var(--signal); box-shadow: none; }
.file.on .file-open .file-nm, .file.on .file-open .file-at { color: #fff; }

/* dials: neutral knobs, accent arc */
/* knob face, skirt and shadow moved to section 18 (physical knob) */
.dial-notch { stroke: #fff; }
:root:not([data-theme=dark]) .dial-notch { stroke: #3a3a3c; }
.dial-arc { stroke: var(--signal); filter: none; }
.dial-track { stroke: var(--hair); }
.dial-tick { stroke: var(--ink-4); }

::selection { background: rgba(10, 132, 255, .35); }
:focus-visible { outline: 3px solid rgba(10, 132, 255, .5); outline-offset: 0; border-radius: 6px; }
.panel-form, .panel-params { scrollbar-color: rgba(255,255,255,.25) transparent; }

/* =================================================================
   13. ACCESS (2026-11-01)
   Measured with axe-core and a target-size sweep at 1440 and 390.
   - Filled blue carries white text, so it uses #0064d1 (5.6:1); the
     brighter system blue stays on rings and arcs, which need only 3:1.
   - Every control is at least 24x24 (WCAG 2.2 target size). Drawn
     glyphs stay small; the hit area grows with a pseudo-element.
   - Reduced motion: transitions off, and the stage starts paused
     (patched in the bundle).
   - Forced colors (Windows high contrast) keep borders and the ring.
   ================================================================= */
:root { --fill-blue: #0064d1; }
.cta, .file.on .file-open { background: var(--fill-blue) !important; }
.cta:hover, .cta.open { background: #0058b8 !important; }
.x, .info-btn, .view-t button, .reg-tab, .mini { position: relative; min-width: 24px; min-height: 24px; }
.grip { position: relative; }
.grip::after, .info-btn::after, .x::after {
  content: ""; position: absolute; inset: 50% auto auto 50%; width: 28px; height: 28px; transform: translate(-50%, -50%);
}
.reg-tab { padding-inline: 6px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; animation-duration: 0s !important; scroll-behavior: auto !important; }
}
@media (forced-colors: active) {
  .panel, .pod, .tile, .icon-btn, .cta, .rig-sw { border: 1px solid CanvasText !important; }
  .tile.on, .file.on .file-open, .rig-pos.on { outline: 3px solid Highlight; }
}
@media (prefers-contrast: more) {
  :root[data-theme=dark] { --ink-2: rgba(235,235,245,.85); --ink-3: rgba(235,235,245,.7); --hair: rgba(255,255,255,.3); --pod: rgba(30,30,32,.96); }
  :root:not([data-theme=dark]) { --ink-2: rgba(0,0,0,.8); --ink-3: rgba(0,0,0,.7); --hair: rgba(0,0,0,.35); --pod: rgba(250,250,250,.97); }
}

/* =================================================================
   14. WHITE ACCENT + SCULPT IN THE STAGE (2026-11-01)
   No hue in the chrome: selection, the default button and dial arcs
   are white (dark) or near-black (light). Filled buttons invert.
   Sculpt mode renders /sculpt/?embed over the live scene with a
   transparent canvas; the object is cleared while sculpting and
   restored on Done (bundle). The side panels step out of the way.
   ================================================================= */
:root[data-theme=dark] { --signal: #ffffff; --on-signal: #000; --fill: #f2f2f2; --fill-ink: #111; --ring: rgba(255,255,255,.9); }
:root:not([data-theme=dark]) { --signal: #1d1d1f; --on-signal: #fff; --fill: #1d1d1f; --fill-ink: #fff; --ring: rgba(0,0,0,.85); }
.cta { background: var(--fill) !important; color: var(--fill-ink) !important; }
.cta:hover, .cta.open { background: var(--fill) !important; filter: brightness(.92); }
.cta svg, .cta .ico { color: var(--fill-ink); fill: currentColor; stroke: none; }
.file.on .file-open { background: var(--mac-sel) !important; }
.file.on .file-open .file-nm { color: var(--ink) !important; }
.file.on .file-open .file-at { color: var(--ink-2) !important; }
.dial-arc { stroke: var(--signal) !important; }
::selection { background: rgba(255,255,255,.28); }
:focus-visible { outline: 2px solid var(--ring) !important; outline-offset: 1px; }
.brand-mark-btn, .title-in { min-height: 24px; }

.sculpt-embed { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; background: transparent; color-scheme: normal; }
.sculpting .panel, .sculpting .panels, .sculpting .index-scrim { display: none !important; }
.sculpting .pod-tools .icon-btn.sel { background: var(--fill) !important; color: var(--fill-ink) !important; }
.sculpting .pod-tools .cta { display: none !important; }

/* Scene libraries: a heading row spans the tile grid */
.tiles .lib-h { grid-column: 1 / -1; font-size: 11px; font-weight: 600; color: var(--ink-2); padding: 10px 2px 2px; text-transform: none; letter-spacing: 0; }
.tiles .lib-h:first-of-type { padding-top: 2px; }

/* Phone bar: six keys fit 358px; collapsing panels has no job when panels are sheets */
@media (max-width: 560px) {
  .pod-tools [aria-label="Collapse panels"] { display: none !important; }
  .pod-tools { gap: 4px; padding-inline: 4px; }
  .pod-tools .icon-btn, .pod-tools .cta { padding-inline: 8px; }
}

/* =================================================================
   15. GLASS CHIP BUTTONS (2026-11-02)
   From a reference Renaise sent: each button is its own dark glass
   chip, icon then label, the emphasized one a lighter glass. Applies
   to the bar and Save only; tiles, segmented controls and close
   buttons keep section 12. Icons are CSS masks keyed off each
   button's title, because the bundle renders text-only buttons.
   ================================================================= */
:root[data-theme=dark] { --chip: rgba(30,32,38,.74); --chip-hover: rgba(48,50,56,.82); --chip-on: rgba(150,144,140,.42); --chip-on-hover: rgba(170,164,160,.5); --chip-ink: #fff; --chip-edge: rgba(255,255,255,.07); }
:root:not([data-theme=dark]) { --chip: rgba(255,255,255,.72); --chip-hover: rgba(255,255,255,.92); --chip-on: rgba(0,0,0,.12); --chip-on-hover: rgba(0,0,0,.17); --chip-ink: #1d1d1f; --chip-edge: rgba(0,0,0,.08); }

.pod-tools .icon-btn, .pod-tools .cta, .mini {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: var(--ds-h); padding: 0 10px; border-radius: var(--ds-r);
  background: var(--chip) !important; color: var(--chip-ink) !important;
  filter: none !important;
  backdrop-filter: saturate(160%) blur(20px); -webkit-backdrop-filter: saturate(160%) blur(20px);
  font-size: 13px; font-weight: 500; letter-spacing: 0;
  transition: background-color .15s ease;
}
.pod-tools .icon-btn:has(svg) { min-width: 32px; padding: 0; }
.pod-tools .icon-btn:hover, .mini:hover { background: var(--chip-hover) !important; }
.pod-tools .icon-btn.sel, .pod-tools .cta, .pod-tools .cta.open,
.sculpting .pod-tools .icon-btn.sel { background: var(--chip-on) !important; color: var(--chip-ink) !important; }
.pod-tools .icon-btn.sel:hover, .pod-tools .cta:hover { background: var(--chip-on-hover) !important; }
.pod-tools .cta svg, .pod-tools .cta .ico { color: var(--chip-ink); fill: currentColor; stroke: none; }

.pod-tools .icon-btn[title]:not(:has(svg))::before, .pod-tools .cta::before {
  content: ""; display: block; flex: none; width: 15px; height: 15px;
  background: currentColor; -webkit-mask: var(--ico) center / contain no-repeat; mask: var(--ico) center / contain no-repeat;
}
.pod-tools [title="Sculpt a form in this scene"], .pod-tools [title="Edit mode"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M232,32a8,8,0,0,0-8-8c-44.08,0-89.31,49.71-114.43,82.63A60,60,0,0,0,32,164c0,30.88-19.54,44.73-20.47,45.37A8,8,0,0,0,16,224H92a60,60,0,0,0,57.37-77.57C182.3,121.31,232,76.08,232,32ZM124.42,113.55q5.14-6.66,10.09-12.55A76.23,76.23,0,0,1,155,121.49q-5.9,4.94-12.55,10.09A60.54,60.54,0,0,0,124.42,113.55Zm42.7-2.68a92.57,92.57,0,0,0-22-22c31.78-34.53,55.75-45,69.9-47.91C212.17,55.12,201.65,79.09,167.12,110.87Z'/%3E%3C/svg%3E"); }
.pod-tools [title="Leave sculpt mode"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z'/%3E%3C/svg%3E"); }
.pod-tools [title="Open object panel"], .pod-tools [title="Object mode"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M223.68,66.15,135.68,18a15.88,15.88,0,0,0-15.36,0l-88,48.17a16,16,0,0,0-8.32,14v95.64a16,16,0,0,0,8.32,14l88,48.17a15.88,15.88,0,0,0,15.36,0l88-48.17a16,16,0,0,0,8.32-14V80.18A16,16,0,0,0,223.68,66.15ZM128,120,47.65,76,128,32l80.35,44Zm8,99.64V133.83l80-43.78v85.76Z'/%3E%3C/svg%3E"); }
.pod-tools [title="Toggle scene panel"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40ZM156,88a12,12,0,1,1-12,12A12,12,0,0,1,156,88Zm60,112H40V160.69l46.34-46.35a8,8,0,0,1,11.32,0h0L165,181.66a8,8,0,0,0,11.32-11.32l-17.66-17.65L173,138.34a8,8,0,0,1,11.31,0L216,170.07V200Z'/%3E%3C/svg%3E"); }
.pod-tools .cta::before { display: none !important; }
.pod-tools .cta { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M204,64V168a12,12,0,0,1-24,0V93L72.49,200.49a12,12,0,0,1-17-17L163,76H88a12,12,0,0,1,0-24H192A12,12,0,0,1,204,64Z'/%3E%3C/svg%3E"); }

@media (min-width: 561px) { .pod-tools .mob-only { display: none !important; } }

@media (forced-colors: active) {
  .pod-tools .icon-btn[title]:not(:has(svg))::before, .pod-tools .cta::before { background: ButtonText; }
}

/* Phone: chips grow to a thumb's size; the three labeled modes show their
   icon alone (the label stays in the DOM as the accessible name) so seven
   chips fit 358px. Export keeps its label. */
@media (max-width: 560px) {
  .pod-tools { gap: 5px; padding-inline: 5px; }
  .pod-tools .icon-btn, .pod-tools .cta { min-height: 40px; border-radius: 11px; font-size: 15px; padding-inline: 12px; }
  .pod-tools .icon-btn:has(svg) { min-width: 40px; }
  .pod-tools .icon-btn[title]:not(:has(svg)) { font-size: 0; gap: 0; min-width: 40px; padding: 0; }
  .pod-tools .icon-btn[title]:not(:has(svg))::before, .pod-tools .cta::before { width: 18px; height: 18px; }
  .pod-tools .cta svg:last-child { display: none; }
}

/* =================================================================
   16. TRACKING AND CENTERING (2026-11-02)
   Chrome draws SF without Apple's size-specific tracking, and the
   bundle mixed a -0.195px title with untracked text everywhere else.
   One rule tracks every element by its own size, fitted to Apple's
   SF Pro Text table: 11px +0.07, 12px 0, 13px -0.08, 15px -0.23,
   17px -0.38, floored at -0.4px for display sizes. letter-spacing
   inherits as a computed length, so it is set on every element.
   ================================================================= */
*, *::before, *::after {
  letter-spacing: max(-0.4px, calc(0.9px - 0.075em)) !important;
  font-kerning: normal;
  text-rendering: optimizeLegibility;
}
.dial-val, .hexrow, [class*="hex"] { font-variant-numeric: tabular-nums; }

/* The wordmark's 13px line box sat at the top of a 20px box, 4px above the bar's center line. */
.brand-mark-btn { display: inline-flex; align-items: center; align-self: stretch; }
.pod-tools .wordmark { display: block; line-height: 1; }

/* Panel bodies are flex columns: without this the dial grid shrank to 49px and clipped its labels. */
.panel-body > * { flex-shrink: 0; }

/* §17 Deslop + describe (2026-11-03) ----------------------------------------
   The chip under the Object title repeated what the title and the grid label
   already say ("Object" / "Orb · void" / "Object · Orb"). One label is enough. */
.active-artifact { display: none; }
.export-note { padding-inline: 2px; }

/* Describe field (afx.js). Same height and radius as the app's other controls. */
.gen-prompt { display: flex; flex-direction: column; gap: var(--ds-gap); margin: 0 0 var(--ds-pad); }
.gen-row { display: flex; gap: var(--ds-gap); }
.gen-row input {
  flex: 1; min-width: 0; height: var(--ds-h); padding: 0 8px; border-radius: var(--ds-r);
  background: var(--well); color: var(--ink);
  font: inherit; font-size: 12px;
}
.gen-row input::placeholder { color: var(--ink-3, var(--ink-2)); }
.gen-go {
  flex: none; width: var(--ds-h); height: var(--ds-h); padding: 0; border-radius: var(--ds-r); border: 0; cursor: pointer;
  display: grid; place-items: center;
  background: var(--fill); color: var(--fill-ink); font: inherit; font-size: 12px; font-weight: 500;
}
.gen-go:disabled, .gen-row input:disabled { opacity: .55; cursor: progress; }
.gen-prompt.busy .gen-go svg { animation: gen-pulse 1s ease-in-out infinite alternate; }
@keyframes gen-pulse { to { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .gen-prompt.busy .gen-go svg { animation: none; } }
.gen-status { margin: 0; font-size: 11px; line-height: 1.35; color: var(--ink-2); min-height: 1em; }
.gen-status:empty { display: none; }
@media (max-width: 560px) {
  .gen-row input { height: 40px; font-size: 16px; }
  .gen-go { width: 40px; height: 40px; }  /* 16px stops iOS zoom on focus */
}

/* =================================================================
   18. SHARED DESIGN SYSTEM (2026-11-04, strokes removed same day)
   Every page loads /ds.css; this maps the app's variables onto its
   tokens so the main app, /sculpt/, /assembly/ and /vector/ read as
   one product. ds.css removes every border and ring shadow; nothing
   here may add one back. Every fill is ink at an opacity: cards are a
   frosted --ds-surface, controls sit on --ds-raised, hover and
   selection step to --ds-raised-2, and a pressed toggle inverts to
   ink. Monochrome: no hue in the chrome. Regular weight only. The
   dials are the one physical object: a lit knob with a cast shadow.
   ================================================================= */
:root[data-theme=dark], :root:not([data-theme=dark]) {
  --display: var(--ds-font); --sans: var(--ds-font);
  --bg: var(--ds-canvas); --screen: var(--ds-canvas);
  --pod: var(--ds-surface); --pod-edge: transparent;
  --pod-in: var(--ds-raised); --pod-in-2: var(--ds-raised-2);
  --ink: var(--ds-ink); --ink-2: var(--ds-ink-2); --ink-3: var(--ds-ink-3); --ink-4: var(--ds-ink-3);
  --hair: transparent; --well: var(--ds-raised);
  --signal: var(--ds-primary); --on-signal: var(--ds-on-primary);
  --fill: var(--ds-primary); --fill-ink: var(--ds-on-primary); --ring: var(--ds-select);
  --mac-sel: var(--ds-raised-2); --mac-shadow: none; --mac-hi: none;
  --chip: var(--ds-raised); --chip-hover: var(--ds-raised-2); --chip-on: var(--ds-raised-2); --chip-on-hover: var(--ds-raised-2);
  --chip-ink: var(--ds-ink); --chip-edge: transparent;
  /* tighter: radii, edge inset and group spacing from the same scale */
  --r-sm: var(--ds-r); --r-md: var(--ds-r); --r-pod: var(--ds-r-card);
  --edge: var(--ds-edge); --d-group: 6px; --d-lock: 4px; --d-tight: 2px;
}
body, .app { background: var(--ds-canvas); font-family: var(--ds-font); }

/* Surfaces: frosted alpha over the stage. */
.pod, .panel, .export-pop, .settings-pop, .index {
  background: var(--ds-surface) !important;
  box-shadow: var(--ds-elev) !important;
  border-radius: var(--ds-r-card) !important;
  backdrop-filter: var(--ds-blur) !important; -webkit-backdrop-filter: var(--ds-blur) !important;
}
.panel .pod, .panel .panel { background: transparent !important; box-shadow: none !important; backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }

/* Buttons: one system. Filled raised by default, light fill for Export. */
.pod-tools .icon-btn, .pod-tools .cta, .mini {
  border-radius: var(--ds-r) !important;
  backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
  font-family: var(--ds-font);
}
.pod-tools .icon-btn:hover, .mini:hover { background: var(--ds-raised-2) !important; }
.pod-tools .icon-btn.sel, .sculpting .pod-tools .icon-btn.sel { background: var(--ds-ink) !important; color: var(--ds-canvas) !important; }
.pod-tools .cta, .pod-tools .cta.open { background: var(--ds-primary) !important; color: var(--ds-on-primary) !important; }
.pod-tools .cta:hover { background: var(--ds-primary) !important; filter: none !important; opacity: .86; }
.pod-tools .cta svg, .pod-tools .cta .ico { color: var(--ds-on-primary); }
.pod-div { background: transparent !important; }
.title-in { text-decoration: none; }

/* Tiles: dimmed until chosen; the chosen one is full strength and lifts on a
   raised plate (padding, not a ring), so selection reads without a stroke. */
.tiles { gap: 4px !important; }
.tile { border-radius: var(--ds-r) !important; opacity: .55; background-clip: content-box; transition: opacity var(--ds-dur), padding var(--ds-dur), background-color var(--ds-dur); }
.tile:hover { opacity: .85; }
.tile.on, .tile[aria-pressed="true"], .lrow.on .tile.sm { opacity: 1; padding: 3px !important; background-color: var(--ds-raised-2) !important; background-clip: border-box; background-origin: content-box; background-repeat: no-repeat; }
.tile.ghost, .tile.plain.none { background: var(--ds-raised) !important; color: var(--ds-ink-3); opacity: 1; }
.tile.ghost:hover, .tile.plain.none:hover { background: var(--ds-raised-2) !important; color: var(--ds-ink); }
.tile-x { background: var(--ds-raised-2) !important; }

/* Segments, rows, cards: selection is a fill step. */
.seg-btn.on, .reg-tab.on, .rig-pos.on, .ctrl-tab.on, .rack-slot.on { background: var(--ds-raised-2) !important; color: var(--ds-ink) !important; }
.hexrow:hover, .index-card:hover, .file-open:hover { background: var(--ds-raised) !important; }
.hexrow.on, .index-card.on, .file.on .file-open { background: var(--ds-raised-2) !important; }
.dial { padding-block: 5px 4px !important; }

/* Generate: a filled step, no hue. */
.gen-go { background: var(--ds-raised-2) !important; color: var(--ds-ink) !important; }
.gen-go:hover { background: var(--ds-ink) !important; color: var(--ds-canvas) !important; }

/* Mode switch, as in Blender's header: Object mode | Sculpt mode. */
.mode-sw { display: inline-flex; gap: 2px; padding: 2px; border-radius: var(--ds-r); background: var(--ds-raised); }
.pod-tools .mode-sw .mode-opt { min-height: calc(var(--ds-h) - 4px); padding: 0 8px; border-radius: var(--ds-r-sm) !important; background: transparent !important; color: var(--ds-ink-2) !important; }
.pod-tools .mode-sw .mode-opt:hover { color: var(--ds-ink) !important; }
.pod-tools .mode-sw .mode-opt.on, .sculpting .pod-tools .mode-sw .mode-opt.on { background: var(--ds-raised-2) !important; color: var(--ds-ink) !important; }
@media (max-width: 560px) { .mode-sw { padding: 0; background: transparent; } .pod-tools .mode-sw .mode-opt { min-height: 40px; } }

/* Dials: a physical knob. A shadow cast below, a skirt lit from above, a
   domed cap, a sheen across its top, and an indicator. Colors are knob
   tokens in ds.css so the light theme gets a pale cap. */
.dial-knob .kf0 { stop-color: var(--ds-knob-hi); }
.dial-knob .kf1 { stop-color: var(--ds-knob-mid); }
.dial-knob .kf2 { stop-color: var(--ds-knob-lo); }
.dial-knob .ks0 { stop-color: var(--ds-knob-skirt-hi); }
.dial-knob .ks1 { stop-color: var(--ds-knob-skirt-lo); }
.dial-knob .kh0 { stop-color: var(--ds-knob-sheen); }
.dial-knob .kh1 { stop-color: var(--ds-knob-sheen); stop-opacity: 0; }
.dial-shadow { display: none; } /* no drop shadows anywhere, knobs included */
.dial-bezel { stroke: none !important; }
.dial-face { stroke: none !important; }
.dial-sheen { pointer-events: none; }
.dial-notch { stroke: var(--ds-knob-ind) !important; stroke-width: 2.4 !important; }
.dial-track { stroke: var(--ds-raised-2) !important; }
.dial-arc { stroke: var(--ds-ink) !important; }
.dial-tick { stroke: var(--ds-ink-3) !important; opacity: .5; }
.dial-tick.on { opacity: .9; }
.dial-knob { width: 46px !important; height: 46px !important; }
.dial-knob:active .dial-face { filter: brightness(1.08); }
.gen-row input { background: var(--ds-raised); border-radius: var(--ds-r); }

/* The color-wheel marker sits on arbitrary color and needs its edge. */
.cw-marker.cw-marker { border: 2px solid #fff !important; box-shadow: 0 0 0 1px rgba(0,0,0,.6) !important; }
/* Windows high contrast: strokes come back, since fills are flattened there. */
@media (forced-colors: active) {
  .panel.panel, .pod.pod, .tile.tile, .icon-btn.icon-btn, .cta.cta { border: 1px solid CanvasText !important; }
}

/* Geist carries its own spacing; section 16's SF tracking table no longer applies. */
*, *::before, *::after { letter-spacing: 0 !important; }

/* Blender export section (afx.js) */
.afx-blender .export-do { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ds-gap); }
.afx-blender button:disabled { opacity: .4; }

/* Export: four formats on one row; a control that doesn't apply is removed, not shown. */
.export-pop .seg-row { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; }
.export-pop .seg-row .seg-btn { min-width: 0; padding-left: 4px; padding-right: 4px; }
.export-pop [hidden] { display: none !important; }

/* Export popover (/cd pass 2026-11-05): one control height, even padding,
   token timing, a square source toggle. */
.export-pop { padding: 10px 12px 12px !important; }
.export-pop .seg-btn, .export-pop .cta, .export-pop .icon-btn { height: var(--ds-h) !important; min-height: 0 !important; transition: background var(--ds-dur), color var(--ds-dur), opacity var(--ds-dur) !important; }
.export-pop .icon-btn.gl { width: var(--ds-h) !important; padding: 0 !important; justify-content: center; }
.export-pop .icon-btn.gl.sel, .export-pop .icon-btn.gl[aria-pressed="true"] { background: var(--ds-raised-2) !important; color: var(--ds-ink) !important; }
@media (max-width: 760px) { .export-pop .seg-btn, .export-pop .cta, .export-pop .icon-btn { height: var(--ds-h-touch) !important; } .export-pop .icon-btn.gl { width: var(--ds-h-touch) !important; } }

/* Lighting: every setup is a tile with a rendered preview of the same form
   under that light (thumbs/light-*.png, made by gen/light-thumbs.cjs). */
.rig .rig-sw { grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; }
.rig-pos { flex-direction: column; gap: 5px; padding: 4px 4px 6px; }
.rig-prev { display: block; width: 100%; aspect-ratio: 1; border-radius: var(--ds-r-sm, 5px); background: var(--ds-raised, #333) center / cover no-repeat; opacity: .7; transition: opacity var(--ds-dur, 140ms); }
.rig-pos:hover .rig-prev, .rig-pos.on .rig-prev { opacity: 1; }

/* §19 Orbit toggle: one chip at the bottom center of the stage */
.stage > .afx-orbit { position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 5;
  display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px 0 10px; border: 0; border-radius: var(--ds-r, 8px);
  background: var(--ds-surface); color: var(--ds-ink-2); font: 400 13px/1 var(--ds-font); cursor: pointer;
  backdrop-filter: var(--ds-blur); -webkit-backdrop-filter: var(--ds-blur); transition: color var(--ds-dur), box-shadow var(--ds-dur); }
/* it floats over the stage, so it takes the bar's surface (the stage stays dark in light theme);
   on = full ink plus the raised fill the bar uses for a selected key */
.stage > .afx-orbit:hover { color: var(--ds-ink); }
.stage > .afx-orbit[aria-pressed="true"] { color: var(--ds-ink); box-shadow: inset 0 0 0 100px var(--ds-raised-2); }
.stage > .afx-orbit:focus-visible { outline: 2px solid var(--ds-select); outline-offset: 2px; }
.sculpting .stage > .afx-orbit { display: none; }
@media (max-width: 1100px) { .stage > .afx-orbit { bottom: calc(64px + env(safe-area-inset-bottom)); height: 40px; } }

/* §20 Phones: every popover is a bottom sheet over the bar, next to the key that opened it */
@media (max-width: 560px) {
  .panel-files, .settings-pop, .export-pop {
    top: auto !important; left: 8px !important; right: 8px !important; width: auto !important;
    bottom: calc(60px + env(safe-area-inset-bottom)) !important; transform: none !important;
    max-height: 60dvh; overflow-y: auto; overscroll-behavior: contain;
  }
}

/* §21 Desktop top bar: the artifact name sits by the menu, the mode switch takes the center */
@media (min-width: 1101px) {
  .pod-tools { grid-template-columns: auto minmax(0, 1fr) auto !important; }
  .pod-tools .mode-sw { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
  .pod-tools .title-in { justify-self: start; text-align: left; margin-left: 4px; max-width: calc(50vw - 220px); }
}

/* §22 Compact: with a panel sheet open, the stage ends where the sheet begins, so the
   object recenters in the space you can see instead of sitting behind the sheet */
@media (max-width: 1100px) {
  div:has(> .panel-form) > main.stage, div:has(> .panels > .panel-params) > main.stage {
    bottom: calc(44dvh + 60px + env(safe-area-inset-bottom)) !important; height: auto !important;
  }
  div:has(> .panel-form) > main.stage > .afx-orbit, div:has(> .panels > .panel-params) > main.stage > .afx-orbit { bottom: 12px; }
}

/* the Object panel key opens the object library: a grid, so it is not a second cube beside Object mode */
.pod-tools [title="Open object panel"] { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='black'%3E%3Cpath d='M120%2C56v48a16%2C16%2C0%2C0%2C1-16%2C16H56a16%2C16%2C0%2C0%2C1-16-16V56A16%2C16%2C0%2C0%2C1%2C56%2C40h48A16%2C16%2C0%2C0%2C1%2C120%2C56Zm80-16H152a16%2C16%2C0%2C0%2C0-16%2C16v48a16%2C16%2C0%2C0%2C0%2C16%2C16h48a16%2C16%2C0%2C0%2C0%2C16-16V56A16%2C16%2C0%2C0%2C0%2C200%2C40Zm-96%2C96H56a16%2C16%2C0%2C0%2C0-16%2C16v48a16%2C16%2C0%2C0%2C0%2C16%2C16h48a16%2C16%2C0%2C0%2C0%2C16-16V152A16%2C16%2C0%2C0%2C0%2C104%2C136Zm96%2C0H152a16%2C16%2C0%2C0%2C0-16%2C16v48a16%2C16%2C0%2C0%2C0%2C16%2C16h48a16%2C16%2C0%2C0%2C0%2C16-16V152A16%2C16%2C0%2C0%2C0%2C200%2C136Z'/%3E%3C/svg%3E"); }
