:root {
    /* Weight-Based Design System */
    --weight-neutral: #0a0b0c; /* Matte Obsidian Canvas */
    --weight-primary: #e6e6dc; /* Architectural Limestone Ink */
    --weight-secondary: #4a4a44; /* Charcoal Slate Detail */
    --weight-tertiary: #ff3e00;  /* High-weight Vermilion Accent */
    
    --bg-color: var(--weight-neutral);
    --text-color: var(--weight-primary);
    --accent-color: var(--weight-tertiary);
    --accent-glow: rgba(255, 62, 0, 0.3);
    
    --ui-bg: rgba(10, 11, 12, 0.4);
    --glass-border: rgba(230, 230, 220, 0.25);
    --sidebar-width: 340px;
}

@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;700;800&display=swap');

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    user-select: none;
    font-family: inherit;
}

body {
    background-color: var(--bg-color);
    color: var(--text-color);
    font-family: 'JetBrains Mono', monospace;
    overflow: hidden;
    height: 100vh;
}

#canvas-holder {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
}

.ui-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    pointer-events: none;
    display: flex;
    flex-direction: column;
    padding: 2.5rem;
}

.ui-overlay > * {
    pointer-events: auto;
}

header {
    margin-bottom: 2rem;
    transition: 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.sidebar.collapsed ~ header {
    opacity: 0.3;
    pointer-events: none;
}

header h1 {
    font-size: 3rem;
    font-weight: 800;
    letter-spacing: -1px;
    margin-bottom: 0.2rem;
}

header h1 span {
    color: var(--accent-color);
    text-shadow: 0 0 20px var(--accent-glow);
}

.subtitle-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    max-width: var(--sidebar-width);
}

header p {
    color: rgba(255,255,255,0.5);
    font-size: 0.9rem;
    font-weight: 400;
}

#backend-status-container {
    display: flex;
    align-items: center;
    gap: 0.8rem;
}

#backend-status {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #ff4444;
    box-shadow: 0 0 8px #ff4444;
    transition: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

#fps-counter {
    font-family: monospace;
    font-size: 0.7rem;
    color: var(--accent-color);
    opacity: 0.8;
}

.glass {
    background: linear-gradient(135deg, rgba(230, 230, 220, 0.05), rgba(10, 11, 12, 0.4));
    backdrop-filter: blur(40px) saturate(120%);
    -webkit-backdrop-filter: blur(40px) saturate(120%);
    border: 1px solid var(--glass-border);
    border-radius: 4px; /* Architectural rigor */
    box-shadow: 0 40px 80px rgba(0,0,0,0.6);
}

.sidebar {
    width: var(--sidebar-width);
    padding: clamp(1rem, 2vw, 2rem);
    padding-right: clamp(0.5rem, 1.5vw, 1.5rem); /* Allow space for scrollbar */
    display: flex;
    flex-direction: column;
    gap: clamp(1rem, 2vw, 2rem);
    flex-grow: 1;
    max-height: 90vh; /* Controlled height for scrolling */
    overflow-y: auto;
    overflow-x: hidden;
    transition: 0.5s cubic-bezier(0.4, 0, 0.2, 1);
    transform-origin: left;
}

/* Minimalist Architectural Scrollbar */
.sidebar::-webkit-scrollbar {
    width: 3px;
}
.sidebar::-webkit-scrollbar-track {
    background: transparent;
}
.sidebar::-webkit-scrollbar-thumb {
    background: rgba(230, 230, 220, 0.1);
    border-radius: 4px;
}
.sidebar::-webkit-scrollbar-thumb:hover {
    background: var(--accent-color);
}

.sidebar.collapsed {
    transform: translateX(calc(-100% - 3rem));
    opacity: 0;
    pointer-events: none;
}

#sidebar-toggle {
    position: fixed;
    top: 2.5rem;
    right: 2.5rem;
    width: 50px;
    height: 50px;
    z-index: 100;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: 0.3s all ease;
    pointer-events: auto;
}

#sidebar-toggle:hover {
    background: var(--accent-color);
    color: #000;
    box-shadow: 0 0 20px var(--accent-glow);
}

#toggle-icon {
    font-size: 1.2rem;
    font-weight: 800;
    transition: 0.5s cubic-bezier(1, 0, 0, 1);
}

.sidebar.collapsed ~ #sidebar-toggle #toggle-icon {
    transform: rotate(180deg);
}

.section h3 {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: rgba(255,255,255,0.3);
    margin-bottom: 1.2rem;
    font-weight: 600;
}

.mode-selector {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.mode-btn {
    background: rgba(255,255,255,0.03);
    border: 1px solid var(--glass-border);
    color: rgba(255,255,255,0.6);
    padding: 0.8rem 1rem;
    border-radius: 4px; /* Architectural rigor */
    font-weight: 600;
    font-size: 0.85rem;
    font-family: 'JetBrains Mono', monospace;
    cursor: pointer;
    transition: 0.2s all ease;
    text-align: left;
}

.mode-btn:hover {
    background: rgba(255,255,255,0.08);
    color: white;
}

.mode-btn.active {
    background: var(--accent-color);
    color: #000;
    border-color: var(--accent-color);
    box-shadow: 0 0 20px var(--accent-glow);
}

.btn {
    width: 100%;
    padding: 1rem;
    border-radius: 4px; /* Architectural rigor */
    font-weight: 700;
    font-size: 0.9rem;
    font-family: 'JetBrains Mono', monospace;
    border: none;
    cursor: pointer;
    transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.btn-primary {
    background: var(--accent-color);
    color: #000;
}

.control-item {
    margin-bottom: 1.2rem;
}

.label-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 0.8rem;
}

.label-row label {
    font-size: 0.85rem;
    font-weight: 500;
    color: rgba(255,255,255,0.8);
}

.val-display {
    font-family: monospace;
    font-size: 0.8rem;
    color: var(--accent-color);
}

input[type="range"] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    width: 100%;
    height: 2px;
    background: transparent;
    border-radius: 2px;
    outline: none;
}

/* ASTERISK SLIDER: Perfect Centering with weight-based ink */
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 24px;
    height: 24px;
    /* Using dominant-baseline:central for surgical precision on the track */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ctext x='12' y='12' text-anchor='middle' dominant-baseline='central' font-family='JetBrains Mono' font-weight='800' font-size='32' fill='%23ff3e00'%3E*%3C/text%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    background-color: transparent;
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    cursor: pointer;
    filter: drop-shadow(0 0 8px var(--accent-glow));
    margin-top: -11px; /* Center 24px thumb on 2px track */
}

input[type="range"]::-moz-range-thumb {
    width: 24px;
    height: 24px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ctext x='12' y='12' text-anchor='middle' dominant-baseline='central' font-family='Outfit' font-weight='800' font-size='32' fill='%23ff3e00'%3E*%3C/text%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    background-color: transparent;
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
    cursor: pointer;
    filter: drop-shadow(0 0 8px var(--accent-glow));
}

.toggle-section {
    margin-top: auto;
}

.switch-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
}

.switch-label span {
    font-size: 0.95rem;
    font-weight: 600;
}

.switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255,255,255,0.1);
    transition: .4s;
}

.slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: .4s;
}

input:checked + .slider {
    background-color: var(--accent-color);
}

input:checked + .slider:before {
    transform: translateX(20px);
}

.slider.round {
    border-radius: 34px;
}

.slider.round:before {
    border-radius: 50%;
}

.upload-btn-wrapper {
    position: relative;
    overflow: hidden;
}

.upload-btn-wrapper input[type=file] {
    font-size: 100px;
    position: absolute;
    left: 0; top: 0;
    opacity: 0;
    cursor: pointer;
}

/* v5 additions */
[hidden] { display: none !important; }
#reset-view { width: 100%; margin-bottom: 0.5rem; }
#samples { margin-top: 0.75rem; }
.stat-row { font-family: "JetBrains Mono", monospace; font-size: 0.7rem; color: var(--weight-secondary); margin: 6px 0 0; }
#fps-counter { color: inherit; }
.stat-line { font-family: "JetBrains Mono", monospace; font-size: 0.7rem; color: var(--weight-secondary); margin-left: 8px; }
.status-msg { font-family: "JetBrains Mono", monospace; font-size: 0.75rem; color: var(--accent-color); min-height: 1em; margin: 4px 0 0; }

/* Hierarchy pass: vermilion fill is reserved for the one primary action.
   Option groups become compact segmented rows; the selected option is marked
   by a light fill + limestone text and a thin accent underline. */
.mode-selector {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
    margin-bottom: 1rem;
}
.mode-btn {
    padding: 0.55rem 0.5rem;
    font-size: 0.75rem;
    text-align: center;
    color: rgba(230, 230, 220, 0.55);
}
.mode-btn.active {
    background: rgba(230, 230, 220, 0.12);
    color: var(--weight-primary);
    border-color: rgba(230, 230, 220, 0.45);
    box-shadow: inset 0 -2px 0 var(--accent-color);
}
.mode-btn:focus-visible, .btn:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; }
#samples .mode-btn { font-weight: 500; }

.mode-btn:disabled { opacity: 0.35; cursor: not-allowed; }

/* ---------- Layout fixes (v5.1) ---------- */
body { height: 100%; height: 100dvh; }

/* The sidebar fills whatever height the header leaves, and scrolls inside it. */
.sidebar {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
    gap: 0;
}
.sidebar > .section { padding-block: 1.1rem; }
.sidebar > .section:first-child { padding-top: 0; }
.sidebar > .section + .section { border-top: 1px solid rgba(230, 230, 220, 0.08); }
.section h3 { margin-bottom: 0.8rem; }

/* Header: title, subtitle, stats and status stack instead of squeezing into one row. */
.subtitle-container { flex-direction: column; align-items: flex-start; gap: 2px; }
header { margin-bottom: 1.25rem; }

/* Switches line up with the slider labels. */
.toggle-section { margin-top: 0.75rem; }
.switch-label span { font-size: 0.85rem; font-weight: 500; color: rgba(255, 255, 255, 0.8); }
.control-item { margin-bottom: 1rem; }
.label-row { margin-bottom: 0.25rem; }

/* Collapse button sits on the sidebar's edge and follows it. */
#sidebar-toggle {
    top: 2.5rem;
    right: auto;
    left: calc(2.5rem + var(--sidebar-width) + 12px);
    width: 40px;
    height: 40px;
    color: var(--weight-primary);
    transition: left 0.5s cubic-bezier(0.4, 0, 0.2, 1), background 0.2s;
}
body.sidebar-collapsed #sidebar-toggle { left: 2.5rem; }
body.sidebar-collapsed #toggle-icon { transform: rotate(180deg); }
body.sidebar-collapsed header { opacity: 0.3; }
#sidebar-toggle:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; }

/* ---------- Asterisk sliders: a faint rail shows where to grab ---------- */
input[type="range"] {
    --fill: 50%;
    height: 24px;
    background: transparent;
    cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
    height: 24px;
    background:
        linear-gradient(rgba(255, 62, 0, 0.45), rgba(255, 62, 0, 0.45)) left center / var(--fill) 1px no-repeat,
        linear-gradient(rgba(230, 230, 220, 0.14), rgba(230, 230, 220, 0.14)) center / 100% 1px no-repeat;
}
input[type="range"]:hover::-webkit-slider-runnable-track,
input[type="range"]:focus-visible::-webkit-slider-runnable-track {
    background:
        linear-gradient(rgba(255, 62, 0, 0.7), rgba(255, 62, 0, 0.7)) left center / var(--fill) 1px no-repeat,
        linear-gradient(rgba(230, 230, 220, 0.3), rgba(230, 230, 220, 0.3)) center / 100% 1px no-repeat;
}
input[type="range"]::-webkit-slider-thumb { margin-top: 0; }
input[type="range"]::-moz-range-track { height: 1px; background: rgba(230, 230, 220, 0.14); }
input[type="range"]::-moz-range-progress { height: 1px; background: rgba(255, 62, 0, 0.45); }
input[type="range"]:hover::-moz-range-track { background: rgba(230, 230, 220, 0.3); }
input[type="range"]:focus-visible { outline: 1px dashed rgba(230, 230, 220, 0.35); outline-offset: 2px; }


/* Sections keep their natural height; the sidebar scrolls instead of squashing them. */
.sidebar > * { flex-shrink: 0; }
/* Segmented rows share the width evenly and never push past the sidebar edge. */
.mode-selector { grid-auto-columns: minmax(0, 1fr); }
.mode-btn { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.switch { flex-shrink: 0; }

/* Geometric asterisk: the font glyph sits high in its line box, so the rail missed its centre.
   Three strokes cross at exactly (12,12) of a 24px thumb on a 24px track, and the 1px rail
   spans y 11.5–12.5, so the rail passes through the true centre. */
input[type="range"]::-webkit-slider-thumb { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg stroke='%23ff3e00' stroke-width='2.2' stroke-linecap='round'%3E%3Cline x1='12' y1='5' x2='12' y2='19'/%3E%3Cline x1='5.938' y1='8.5' x2='18.062' y2='15.5'/%3E%3Cline x1='5.938' y1='15.5' x2='18.062' y2='8.5'/%3E%3C/g%3E%3C/svg%3E"); background-position: center; background-size: 24px 24px; }
input[type="range"]::-moz-range-thumb { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg stroke='%23ff3e00' stroke-width='2.2' stroke-linecap='round'%3E%3Cline x1='12' y1='5' x2='12' y2='19'/%3E%3Cline x1='5.938' y1='8.5' x2='18.062' y2='15.5'/%3E%3Cline x1='5.938' y1='15.5' x2='18.062' y2='8.5'/%3E%3C/g%3E%3C/svg%3E"); background-position: center; background-size: 24px 24px; }

/* ---------- Floating view buttons ---------- */
#reset-fab {
    position: fixed;
    z-index: 100;
    top: calc(2.5rem + 48px);
    left: calc(2.5rem + var(--sidebar-width) + 12px);
    width: 40px;
    height: 40px;
    color: var(--weight-primary);
    font-size: 1.15rem;
    cursor: pointer;
    transition: left 0.5s cubic-bezier(0.4, 0, 0.2, 1), background 0.2s;
}
#reset-fab:hover { background: rgba(230, 230, 220, 0.12); }
#reset-fab:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; }
body.sidebar-collapsed #reset-fab { left: 2.5rem; }
.toggle-label { display: none; }

/* ---------- Phones: bottom sheet ---------- */
@media (max-width: 600px) {
    :root { --sheet-h: 60dvh; }
    .ui-overlay { padding: 16px; }
    header { pointer-events: none; margin: 0; }
    body.sidebar-collapsed header { opacity: 1; }
    header h1 { font-size: 1.75rem; }
    header p { font-size: 0.75rem; }

    .sidebar {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        width: 100%;
        height: var(--sheet-h);
        max-height: none;
        margin: 0;
        padding: 20px 16px calc(16px + env(safe-area-inset-bottom, 0px));
        border-radius: 14px 14px 0 0;
        border-bottom: none;
        transform: none;
        transform-origin: bottom;
    }
    .sidebar.collapsed { transform: translateY(105%); opacity: 1; }

    /* "Controls" pill: bottom-right when closed, riding just above the sheet when open. */
    #sidebar-toggle,
    body.sidebar-collapsed #sidebar-toggle {
        top: auto;
        left: auto;
        right: 16px;
        bottom: calc(16px + env(safe-area-inset-bottom, 0px));
        width: auto;
        height: 44px;
        padding: 0 16px;
        gap: 8px;
        transition: bottom 0.5s cubic-bezier(0.4, 0, 0.2, 1);
    }
    body:not(.sidebar-collapsed) #sidebar-toggle { bottom: calc(var(--sheet-h) + 12px); }
    #toggle-icon { transform: rotate(-90deg); font-size: 0.9rem; }
    body.sidebar-collapsed #toggle-icon { transform: rotate(90deg); }
    .toggle-label { display: inline; font-size: 0.8rem; font-weight: 700; }
    .toggle-label::after { content: "Close"; }
    body.sidebar-collapsed .toggle-label::after { content: "Controls"; }

    #reset-fab,
    body.sidebar-collapsed #reset-fab { top: 16px; left: auto; right: 16px; width: 44px; height: 44px; }

    /* Touch targets: 44px buttons, 36px slider rows with the asterisk still centred (6 + 12 = 18). */
    .mode-btn { min-height: 44px; }
    input[type="range"],
    input[type="range"]::-webkit-slider-runnable-track { height: 36px; }
    input[type="range"]::-webkit-slider-thumb { margin-top: 6px; }
}

/* ═════════════════════════════════════════════════════════════
   LiquidToggle — from Bencho "Liquid toggle" (MIT, bencho.dev/licence).
   Everything down to the line "end of Bencho's CSS" is the original,
   comments included. The source pasted in was cut off inside the
   `.liq-sw` rule; the rules after that line complete it and are ours.
   ═════════════════════════════════════════════════════════════ */

/* ── the rest of them ────────────────────────────────────────
   Not every block has a ::before to hang a border on, and
   giving each one a pseudo-element it does not otherwise need
   is a lot of stylesheet for a hairline. A 1px spread shadow
   is the same mark by another means — the create menu has
   used exactly this since it was written, for exactly this
   reason — and it composites without touching layout.

   This is what makes Stroke honest on every entry rather than
   on the dozen that happened to be built on a glass pane. */
[data-stroke="on"] .bal,
[data-stroke="on"] .bar-rail,
[data-stroke="on"] .fan-core,
[data-stroke="on"] .step-pill,
[data-stroke="on"] .liq-sw,
[data-stroke="on"] .deck-card,
[data-stroke="on"] .tick-row,
/* NOT the rows. Stroke is a question about the block's own
   edge, and hanging it on every row inside drew four
   hairlines in the middle of a panel that still had none
   round it. `.lab` already carries the ::before this control
   was built for, and the roster's box is a .lab. */

/* ── a ring on a metaball ────────────────────────────────────
   The reorder list's rows are blobs on a filtered layer, and a
   spread shadow drawn there does not survive: the blur smears
   it and the alpha row then crushes what is left to nothing,
   so Stroke appeared to do nothing on this block in either
   theme.

   The ring goes on the UNFILTERED twin instead. Every row is
   drawn twice — a blob that merges and an ink layer above it
   that carries the avatar and the name — and the two share
   their geometry exactly, so an outline on the top one traces
   the shape of the bottom one for free. */
/* ── and the node card ─────────────────────────────────────
   It drew its hairline unconditionally for a revision, which
   is the one thing a block with a Stroke control must not do:
   the control then reads as broken in the Off position,
   because the edge it promises to remove is still there. The
   ring follows the card's own corner, which is a knob. */
[data-stroke="on"] .nod-card {
  box-shadow: 0 0 0 1px var(--pane-edge);
  border-radius: var(--nod-r, 20px);}

/* ════ liquid ═══════════════════════════════════════════════
   Three studies in one filter. Prefix liq-.

   Every one of these is two layers in register: opaque shapes
   on a layer carrying url(#liq-goo), and anything that needs
   a crisp edge — text, a hit area — riding above on a layer
   that carries no filter at all. The goo eats translucency
   and mangles glyphs, so nothing else can share the layer. */

/* ── 1 · liquid toggle ───────────────────────────────────── */
.liq-well {
  width: 240px; height: 130px;
  display: grid; place-items: center;}

/* ── BLACK AND WHITE, AND NO EDGE OF ITS OWN ────────────────
   The on state was a green wash with a green ring, which made
   this the only block on the bench asserting a colour nothing
   else uses — and a switch does not need a hue to say it is
   on. It inverts instead: a light track with a dark thumb
   becomes a dark track with a light one, which is the strongest
   thing two colours can say and the only thing this component
   has to say.

   `--fill-on` / `--fill-slab` rather than --ink / --board, so
   the pair follows the Fill control the entry declares instead
   of naming a colour twice.

   And no inset ring. It carried one unconditionally, which is
   an edge the Stroke switch cannot take away — the same bug
   the sleep pill, the command bar and the Notify pill all had.
   Stroke's own rule is a few hundred lines up. */
.liq-sw {
  position: relative;
  width: 92px; height: 46px;
  padding: 0; border: 0;
  /* ── ALWAYS A PILL ────────────────────────────────────────
     It took a Corner knob for a while and does not any more.
     A switch is
     ── end of Bencho's CSS (the pasted source stops here) ── */

  /* ── ours: completing the rule ───────────────────────────
     23 is half the 46px height, so the track is the pill the
     component's own notes say it already is. */
  border-radius: 23px;
  cursor: pointer;
  flex-shrink: 0;
  touch-action: none; /* a drag on the thumb must not scroll the sheet */

  /* ── ours: Bencho's tokens, mapped to this project ───────
     Defined on the component root so nothing leaks out.
     --ink / --board are the project's limestone ink and
     obsidian ground. --card has no opaque equivalent here
     (--ui-bg is translucent, and these fills must be opaque),
     so it is a solid step above the ground. The Fill pair
     follows the same polarity: on = ink, slab = ground.
     --pane-edge is the project's glass hairline. --nod-r is
     only read by .nod-card, which this project does not have;
     its rule carries its own 20px fallback. */
  --ink: var(--weight-primary);
  --board: var(--weight-neutral);
  --card: #1a1c1d;
  --fill-on: var(--weight-primary);
  --fill-slab: var(--weight-neutral);
  --pane-edge: var(--glass-border);

  /* ours: the inversion in this project's polarity. The sidebar
     is dark, so off is a dark track carrying a light droplet,
     and on turns the track to ink with a ground-coloured drop. */
  background: var(--card);
  transition: background 0.28s ease;
}
.liq-sw[data-on="true"] { background: var(--fill-on); }
.liq-sw:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 3px; }

/* ours: the blob layer. No filter on it — the component's own
   "NO GOO" note explains why a single circle is crisper without. */
.liq-sw-blobs { position: absolute; inset: 0; pointer-events: none; }
.liq-thumb {
  position: absolute;
  left: 0;
  top: calc((46px - var(--liq-thumb)) / 2);
  width: var(--liq-thumb);
  height: var(--liq-thumb);
  border-radius: 50%;
  background: var(--ink);
  transition: background 0.28s ease;
  will-change: transform;
}
.liq-sw[data-on="true"] .liq-thumb { background: var(--fill-slab); }

/* ours: in the sidebar the 92×46 switch sits at the end of the row */
.switch-label .liq-sw { margin-left: 12px; }

/* ---------- Source morph menu ----------
   Pill → menu on one spring (components/morph-menu.js). The slot reserves the
   pill's 44px so the menu opens over the sections below instead of pushing them. */
.morph-slot { position: relative; height: 44px; z-index: 20; }
.morph {
    position: absolute;
    top: 0; left: 0; right: 0;
    overflow: hidden;
    border-radius: 22px;
    background: var(--accent-color);
    color: #000;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
    transform-origin: top left;
}
.morph[data-morph="menu"] {
    background: #141617; /* opaque: the menu sits over the controls below */
    color: var(--weight-primary);
    box-shadow: inset 0 0 0 1px var(--glass-border), 0 18px 40px rgba(0, 0, 0, 0.55);
}
.morph-pill {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    width: 100%; height: 44px;
    padding: 0 16px 0 14px;
    border: 0; background: transparent; color: inherit;
    font: 700 0.85rem 'JetBrains Mono', monospace;
    cursor: pointer;
}
[data-view="menu"] { display: flex; flex-direction: column; gap: 2px; padding: 4px; }
[data-view="menu"][hidden] { display: none; }
.morph-item {
    display: flex; align-items: center; gap: 8px;
    width: 100%; min-height: 40px;
    padding: 0 12px 0 10px;
    border: 0; border-radius: 8px;
    background: rgba(230, 230, 220, 0.04);
    color: var(--weight-primary);
    font: 500 0.8rem 'JetBrains Mono', monospace;
    text-align: left; white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s ease-out, color 0.15s ease-out;
}
.morph-item:hover, .morph-item:focus-visible { background: rgba(230, 230, 220, 0.12); outline: none; }
.morph-item:focus-visible { box-shadow: inset 0 0 0 1px var(--accent-color); }
.morph-pill:focus-visible { outline: 2px solid var(--weight-primary); outline-offset: -4px; border-radius: 20px; }
.morph-ico { width: 16px; height: 16px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* Incoming view: blur 4px → 0, scaleY 0.98 → 1, fade in; 0.2s after a 0.03s delay. */
.morph-enter { animation: morph-in 0.2s ease-out 0.03s both; transform-origin: top; }
@keyframes morph-in {
    from { opacity: 0; filter: blur(4px); transform: scaleY(0.98); }
    to   { opacity: 1; filter: blur(0); transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) { .morph-enter { animation: none; } }

/* ---------- Loader: thinking orb ----------
   Centred over the scene, never blocking it; the label names the orb's state. */
.loader {
    position: fixed; inset: 0; z-index: 5;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    pointer-events: none;
}
.loader[hidden] { display: none; }
.loader-label {
    font: 500 0.75rem 'JetBrains Mono', monospace;
    letter-spacing: 0.08em;
    color: rgba(230, 230, 220, 0.6);
}

/* ---------- Liquid-metal mark after the title ----------
   Chrome is a hard-banded grey gradient (bright, dark, bright, dark) clipped to the
   glyphs; sliding it sideways rolls the highlight across like light on a moving
   bead. The SVG ripple (#lm-liquid) adds the molten wobble. */
header h1 .lm {
    margin-left: 0.12em;
    background: linear-gradient(100deg,
        #5b5e62 0%, #f4f5f2 18%, #8d9196 30%, #2b2d30 42%,
        #e9ebe6 55%, #7c8085 68%, #fdfdfb 80%, #4a4d51 100%);
    background-size: 220% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    text-shadow: none;
    filter: url(#lm-liquid) drop-shadow(0 0 6px rgba(230, 230, 220, 0.25));
    animation: lm-roll 5.5s ease-in-out infinite alternate;
}
@keyframes lm-roll { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) {
    header h1 .lm { animation: none; filter: drop-shadow(0 0 6px rgba(230, 230, 220, 0.25)); }
}

/* Link to the standalone formula page; styled like the Reset view button above it. */
.studies-link { display: block; text-align: center; text-decoration: none; color: var(--weight-primary); margin-bottom: 0.5rem; }

/* ---------- Phones on their side (short screens) ----------
   A 390px-tall landscape phone is wider than 600px, so it used to get the desktop
   layout: the sidebar was squeezed to ~165px under the title. Here the controls
   become a full-height side sheet, and the title moves out of their way. */
@media (max-height: 520px) and (min-width: 601px) {
    .ui-overlay { padding: 12px; }
    header {
        position: fixed; top: 12px; right: 12px; margin: 0;
        text-align: right; pointer-events: none;
    }
    header h1 { font-size: 1.35rem; }
    .subtitle-container { align-items: flex-end; }
    .subtitle-container > p:first-child { display: none; } /* the tagline; stats stay */
    .sidebar {
        position: fixed; top: 12px; bottom: 12px; left: 12px;
        width: 300px; height: auto; max-height: none;
        padding: 16px;
    }
    .sidebar.collapsed { transform: translateX(calc(-100% - 24px)); }
    #sidebar-toggle { top: 12px; left: 320px; width: 44px; height: 44px; }
    #reset-fab { top: 64px; left: 320px; width: 44px; height: 44px; }
    body.sidebar-collapsed #sidebar-toggle,
    body.sidebar-collapsed #reset-fab { left: 12px; }
    .mode-btn { min-height: 40px; }
}
