/* Pitcheon — site-fresh.
   The page is built from the same three materials as the app: the fascia
   (leather-grained panel), the glass (smoked, lit from behind by an amber
   lamp) and the metal (keys, knobs, the bird). Nothing here is a card or a
   badge; everything is either mounted on the panel or printed on the glass. */

@import url("fonts.css");

:root {
  --ground:    #0e0c0a;
  --fascia-a:  #221a12;
  --fascia-b:  #2a2119;
  --ink:       #f0e9dd;
  --ink-dim:   #a1968a;
  --ink-faint: #6a6156;
  --line:      rgba(255,255,255,.06);

  /* The light this machine runs on. Everything that glows reads --lit or
     --lit-rgb, so a theme is three values rather than a repaint. */
  --lit:      #f5b52a;
  --lit-rgb:  245, 181, 42;
  --lit-dim:  var(--lit-dim);
  --tune:  var(--lit);
  --tune-rgb: var(--lit-rgb);
  /* The alarm. Not a theme colour: the light and the alarm must never be
     the same thing. */
  --hot:   #cf2f18;
  --sharp: #e8663c;

  --font:    "Work Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --stencil: "Silkscreen", ui-monospace, monospace;
  --seg:     "DSEG7 Classic", ui-monospace, monospace;
  --mono:    ui-monospace, "SF Mono", Menlo, monospace;

  --grain: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27300%27%20height%3D%27300%27%3E%3Cfilter%20id%3D%27g%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.85%27%20numOctaves%3D%274%27%20seed%3D%2711%27%20stitchTiles%3D%27stitch%27%2F%3E%3CfeColorMatrix%20type%3D%27saturate%27%20values%3D%270%27%2F%3E%3CfeComponentTransfer%3E%3CfeFuncR%20type%3D%27linear%27%20slope%3D%271.0%27%20intercept%3D%270.38%27%2F%3E%3CfeFuncG%20type%3D%27linear%27%20slope%3D%271.0%27%20intercept%3D%270.38%27%2F%3E%3CfeFuncB%20type%3D%27linear%27%20slope%3D%271.0%27%20intercept%3D%270.38%27%2F%3E%3CfeFuncA%20type%3D%27linear%27%20slope%3D%270%27%20intercept%3D%271%27%2F%3E%3C%2FfeComponentTransfer%3E%3C%2Ffilter%3E%3Crect%20width%3D%27300%27%20height%3D%27300%27%20filter%3D%27url%28%23g%29%27%2F%3E%3C%2Fsvg%3E");

  /* The lamp lens on a radio key, as the app defines it: dark glass body, a
     catch where the room lands on the dome, the element showing through. */
  --lens-face:
    radial-gradient(circle at 34% 27%, rgba(255,255,255,.34) 0%, rgba(255,255,255,.08) 36%, rgba(255,255,255,0) 62%),
    radial-gradient(circle at 50% 64%, rgba(var(--lamp-rgb, 245,181,42), .22) 0%, rgba(var(--lamp-rgb, 245,181,42), .05) 52%, rgba(var(--lamp-rgb, 245,181,42), 0) 76%),
    linear-gradient(180deg, #2b251f 0%, #17130f 72%, #110e0b 100%);
  --lens-edge: inset 0 1px 1.5px rgba(0,0,0,.8), inset 0 -1px 0 rgba(255,255,255,.14), 0 1px 0 rgba(255,255,255,.05);
  --lens-catch: radial-gradient(circle at 34% 27%, rgba(255,255,255,.45) 0%, rgba(255,255,255,.12) 32%, rgba(255,255,255,0) 56%);

  --ease: cubic-bezier(.22,.68,.32,1);
  --radius: 12px;
  --measure: 58ch;
  --pad: clamp(1.1rem, 4.5vw, 3rem);
  --wrap: 72rem;
}

/* The lamps this machine can be fitted with (web/style.css). The panel, the
   glass, the shadows and the type are the same in all of them. */
:root[data-theme="green"] { --lit: #3fdd88; --lit-rgb: 63, 221, 136; --lit-dim: #4f8f6a; }
:root[data-theme="blue"]  { --lit: #4aa8ff; --lit-rgb: 74, 168, 255; --lit-dim: #567fa6; }
:root[data-theme="white"] { --lit: #eef2f6; --lit-rgb: 238, 242, 246; --lit-dim: #8b9199; }

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* The room. A warm source low-left (the valve behind the panel), a cold one
   high-right. Fixed layer so scrolling never repaints it. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(110% 80% at 6% 100%, #221912 0%, transparent 55%),
    radial-gradient(80% 60% at 100% 0%, #15181c 0%, transparent 60%),
    var(--ground);
}

a { color: var(--tune); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--lit); }
:focus-visible { outline: 2px solid var(--tune); outline-offset: 3px; border-radius: 4px; }
button { font: inherit; color: inherit; }
img, svg, canvas { max-width: 100%; display: block; }
p { margin: 0 0 1rem; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding-left: var(--pad); padding-right: var(--pad); }
.narrow { max-width: var(--measure); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- stencils & type ---------- */

.stencil {
  font-family: var(--stencil);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  -webkit-font-smoothing: none;
  font-smooth: never;
}
.stencil--lit { color: var(--tune); text-shadow: 0 0 10px rgba(var(--tune-rgb), .4); }
.stencil--engraved { color: #6c6152; text-shadow: 0 1px 0 rgba(0,0,0,.8); }

h1, h2, h3 { font-weight: 600; letter-spacing: -.03em; line-height: 1.05; margin: 0; text-wrap: balance; }
h2 { font-size: clamp(1.75rem, 4vw, 2.7rem); margin: .6rem 0 1.1rem; }
h3 { font-size: 1.12rem; letter-spacing: -.015em; line-height: 1.3; margin-bottom: .45rem; }
.lede { font-size: clamp(1.05rem, 1.5vw, 1.22rem); color: var(--ink-dim); max-width: var(--measure); text-wrap: pretty; }
.dim { color: var(--ink-dim); }
.faint { color: var(--ink-faint); }
em.lit { font-style: normal; color: var(--tune); text-shadow: 0 0 14px rgba(var(--tune-rgb), .35); }
em.hot { font-style: normal; color: var(--sharp); }
kbd { font-family: var(--mono); font-size: .8em; padding: .1em .4em; border: 1px solid rgba(255,255,255,.12); border-bottom-width: 2px; border-radius: 4px; background: rgba(0,0,0,.35); }
code { font-family: var(--mono); font-size: .88em; color: #d8cfbf; }

/* ---------- fascia ---------- */

.fascia {
  position: relative;
  background-image: var(--grain), linear-gradient(180deg, var(--fascia-a) 0%, var(--fascia-b) 100%);
  background-size: 150px 150px, auto;
  background-blend-mode: multiply, normal;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06), inset 0 -1px 0 rgba(0,0,0,.55);
}

/* ---------- glass ----------
   Smoked glass over a lamp. The lamp is a background layer; ::before is the
   ruling (scan lines); ::after is the vignette of the frame. Children sit at
   z-index 1 between the lamp and the ruling. */
.glass {
  --lamp-at: 50% 110%;
  --lamp-wide: 80%;
  --lamp-reach: 110%;
  --lamp-strength: 1;
  --vignette: 40px;
  --glass-top: #090807; --glass-mid: #0d0b09; --glass-foot: #14100b;
  position: relative;
  border-radius: var(--radius);
  background:
    radial-gradient(ellipse var(--lamp-wide) var(--lamp-reach) at var(--lamp-at),
      rgba(var(--tune-rgb), calc(.26 * var(--lamp-strength))) 0%,
      rgba(var(--tune-rgb), calc(.11 * var(--lamp-strength))) 34%,
      rgba(var(--tune-rgb), calc(.035 * var(--lamp-strength))) 58%,
      rgba(var(--tune-rgb), 0) 78%),
    linear-gradient(180deg, var(--glass-top) 0%, var(--glass-mid) 52%, var(--glass-foot) 100%);
  box-shadow: 0 0 0 2px rgba(0,0,0,.92), 0 0 0 3px rgba(255,255,255,.045), 0 24px 50px -24px rgba(0,0,0,.9);
  overflow: hidden;
  color: var(--tune);
}
.glass > * { position: relative; z-index: 1; }
/* The ruling: 1px of shadow, 1px of near-nothing, multiplied over whatever
   is printed on the glass. */
.glass .dsp-scan {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(0,0,0,.22) 0px, rgba(0,0,0,.22) 1px, rgba(255,255,255,.012) 1px, rgba(255,255,255,.012) 2px);
  mix-blend-mode: multiply; opacity: .55;
}
/* The wash (web/style.css .dsp-wash): when what is on the glass changes,
   a band sweeps across it and the pixels light where they are, the way a
   segment display flickers through everything it can show before it
   settles. Here it is how a panel arrives when it scrolls into view. The
   band moves and the dot grid does not: a static mask over a sweeping
   gradient. */
.glass .dsp-wash { position: absolute; inset: 0; z-index: 2; overflow: hidden; opacity: 0; pointer-events: none; }
.glass .dsp-wash::before {
  content: ""; position: absolute; inset: -20% -70%;
  background: linear-gradient(var(--wash-tilt, 104deg), transparent 0%, rgba(var(--tune-rgb), .6) var(--wash-lead, 20%), rgba(var(--tune-rgb), .6) var(--wash-trail, 34%), transparent calc(var(--wash-trail, 34%) + 20%));
  -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 1px, transparent 1px 3px), repeating-linear-gradient(180deg, #000 0 1px, transparent 1px 3px), repeating-linear-gradient(var(--wash-grain, 24deg), #000 0 4px, transparent 4px 7px);
  mask-image: repeating-linear-gradient(90deg, #000 0 1px, transparent 1px 3px), repeating-linear-gradient(180deg, #000 0 1px, transparent 1px 3px), repeating-linear-gradient(var(--wash-grain, 24deg), #000 0 4px, transparent 4px 7px);
  -webkit-mask-composite: source-in; mask-composite: intersect;
  transform: translateX(var(--wash-from, -55%));
}
[data-wash] .dsp-wash { animation: dsp-wash-fade var(--wash-ms, 520ms) linear both; }
[data-wash] .dsp-wash::before { animation: dsp-wash var(--wash-ms, 520ms) cubic-bezier(.3,.05,.3,1) both; }
@keyframes dsp-wash { from { transform: translateX(var(--wash-from, -55%)); } to { transform: translateX(var(--wash-to, 55%)); } }
@keyframes dsp-wash-fade { 0% { opacity: 0; } 16% { opacity: .62; } 70% { opacity: .45; } 100% { opacity: 0; } }
/* Everything arrives by lighting, with a moment of overshoot as the drive
   settles: the trace first, the engraved rows, the clocks last. */
@keyframes dsp-in { 0% { opacity: 0; } 55% { opacity: 1; filter: brightness(1.18); } 100% { opacity: 1; filter: none; } }
.display[data-wash] .dsp-trace { animation: dsp-in 460ms var(--in-trace, 90ms) both; }
.display[data-wash] .dsp-row   { animation: dsp-in 440ms var(--in-rows, 270ms) both; }
.display[data-wash] .dsp-time  { animation: dsp-in 400ms var(--in-times, 460ms) both; }
.panel-screen[data-wash] .screen-top, .panel-screen[data-wash] .screen-hint, .panel-screen[data-wash] .lyric-edit, .panel-screen[data-wash] .screen-note { animation: dsp-in 460ms var(--in-trace, 90ms) both; }
.panel-screen[data-wash] .spot { animation: dsp-in 340ms both; animation-delay: calc(var(--in-rows, 270ms) + var(--row, 0) * var(--in-step, 60ms)); }
/* Dark until the wash reaches it. */
.glass[data-unlit] .dsp-trace, .glass[data-unlit] .dsp-row, .glass[data-unlit] .dsp-time,
.glass[data-unlit] .screen-top, .glass[data-unlit] .screen-hint, .glass[data-unlit] .lyric-edit, .glass[data-unlit] .screen-note, .glass[data-unlit] .spot { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  [data-wash] .dsp-wash, [data-wash] .dsp-wash::before, [data-wash] .dsp-trace, [data-wash] .dsp-row, [data-wash] .dsp-time,
  [data-wash] .screen-top, [data-wash] .screen-hint, [data-wash] .lyric-edit, [data-wash] .screen-note, [data-wash] .spot { animation: none; }
}
/* The beam: the same ruling drawn in light, cut to a wedge from the fixed
   source toward the pointer and faded with distance so it has died by the
   time it arrives. glass.js writes the four values. */
.glass::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 3; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(255,255,255,.1) 0px, rgba(255,255,255,.1) 1px, rgba(255,255,255,0) 1px, rgba(255,255,255,0) 2px);
  --beam-half: 34deg;
  -webkit-mask-image:
    conic-gradient(from calc(var(--beam-deg, 180deg) - var(--beam-half)) at var(--sx, 135%) var(--sy, -90%), transparent 0deg, #000 calc(var(--beam-half) * .6), #000 calc(var(--beam-half) * 1.4), transparent calc(var(--beam-half) * 2)),
    radial-gradient(circle var(--beam-len, 900px) at var(--sx, 135%) var(--sy, -90%), #000 0%, #000 38%, rgba(0,0,0,.45) 70%, transparent 100%);
  mask-image:
    conic-gradient(from calc(var(--beam-deg, 180deg) - var(--beam-half)) at var(--sx, 135%) var(--sy, -90%), transparent 0deg, #000 calc(var(--beam-half) * .6), #000 calc(var(--beam-half) * 1.4), transparent calc(var(--beam-half) * 2)),
    radial-gradient(circle var(--beam-len, 900px) at var(--sx, 135%) var(--sy, -90%), #000 0%, #000 38%, rgba(0,0,0,.45) 70%, transparent 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect;
  opacity: 0; transition: opacity .4s var(--ease);
}
.glass[data-lit]::before { opacity: 1; }
/* The front surface: the room's light spilling in over the corner nearest
   the lamp, the rim rings, and the frame's shade reaching in. */
.glass::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: 4; pointer-events: none;
  background:
    radial-gradient(ellipse 58% 46% at 96% -6%, rgba(255,255,255,.085) 0%, rgba(255,255,255,.03) 42%, rgba(255,255,255,0) 76%),
    linear-gradient(180deg, rgba(255,255,255,.05) 0%, rgba(255,255,255,.01) 14%, rgba(255,255,255,0) 30%);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.5), inset 0 0 0 2px rgba(255,255,255,.1), inset 0 0 var(--vignette) rgba(0,0,0,.55);
}

/* ---------- keys ----------
   A machined cap in a ring. A latched key sits lower and its legend lights. */
.key {
  --key-base: #221b13;
  position: relative;
  display: inline-block;
  padding: 0; border: 0;
  border-radius: 11px;
  background:
    linear-gradient(180deg, rgba(0,0,0,.14) 0%, rgba(0,0,0,.03) 46%, rgba(255,255,255,.05) 100%),
    color-mix(in srgb, var(--key-base) 55%, transparent);
  box-shadow: inset 0 2px 5px rgba(0,0,0,.05), inset 0 -2px 4px rgba(255,255,255,.04);
  color: var(--ink-dim);
  cursor: pointer;
  -webkit-appearance: none; appearance: none;
  -webkit-tap-highlight-color: transparent;
  transition: color .16s var(--ease);
  user-select: none;
}
/* The collar: one flat dark ring the whole way round, the darkest thing on
   the key, which is what seats it in the fascia rather than leaving it
   floating on the grain. Concentric with the outer corner. */
.key::after {
  content: ""; position: absolute; inset: 2.5px; border-radius: 8.5px;
  border: 2px solid rgba(0,0,0,.6); pointer-events: none;
}
.key--play::after { border-radius: 50%; }
.key-face {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: 4.5px;
  min-height: 30px;
  padding: 7px 14px;
  border-radius: 6.5px;
  /* The legend is engraved in the panel's own face, as on the app's .btn:
     Work Sans, not the pixel face, which is for what the glass says. */
  font-family: var(--font); font-size: 10px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  background:
    linear-gradient(180deg, rgba(0,0,0,.17) 0%, rgba(0,0,0,.09) 32%, rgba(255,255,255,.025) 66%, rgba(255,255,255,.055) 100%),
    var(--key-base);
  box-shadow: inset 0 -3px 7px rgba(0,0,0,.45), 0 8px 10px -7px rgba(0,0,0,1), 0 14px 22px -12px rgba(0,0,0,1);
  text-shadow: 0 1px 0 rgba(0,0,0,.7);
  transition: background .18s var(--ease), box-shadow .18s var(--ease), color .18s var(--ease);
  white-space: nowrap;
}
/* A 2px edge round the cap, bright along the top and faint elsewhere. */
.key-face::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; border: 2px solid transparent;
  background: linear-gradient(180deg, rgba(255,255,255,.18) 0%, rgba(255,255,255,.07) 28%, rgba(255,255,255,.04) 56%, rgba(255,255,255,.03) 100%) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
/* Hover leaves the legend alone: the cap shifting under the cursor is the
   whole of it. */
.key:hover .key-face { background: linear-gradient(180deg, rgba(0,0,0,.155) 0%, rgba(0,0,0,.08) 32%, rgba(255,255,255,.032) 66%, rgba(255,255,255,.066) 100%), var(--key-base); }
.key:active .key-face, .key[aria-pressed="true"] .key-face, .key[data-on] .key-face {
  background: linear-gradient(180deg, rgba(255,255,255,.035) 0%, rgba(0,0,0,.2) 52%, rgba(0,0,0,.34) 100%), var(--key-base);
  box-shadow: inset 0 3px 7px rgba(0,0,0,.7), inset 0 -1px 0 rgba(255,255,255,.05);
}
.key[aria-pressed="true"], .key[data-on] { color: var(--tune); }
.key[aria-pressed="true"] .key-face, .key[data-on] .key-face { text-shadow: 0 0 9px rgba(var(--tune-rgb), .55), 0 1px 0 rgba(0,0,0,.7); }
.key[data-tone="hot"][aria-pressed="true"] { color: var(--sharp); }
.key[data-tone="hot"][aria-pressed="true"] .key-face { text-shadow: 0 0 9px rgba(232,102,60,.55); }
.key[disabled] { opacity: .5; cursor: default; }
.key--icon .key-face { padding: 7px 9px; min-width: 30px; }
.key--wide .key-face { padding-left: 20px; padding-right: 20px; }

/* Lamp. */
.lamp {
  --lamp: var(--tune); --lamp-rgb: var(--lit-rgb);
  display: inline-block; flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--lens-face); box-shadow: var(--lens-edge);
  transition: background .16s var(--ease), box-shadow .16s var(--ease);
  vertical-align: middle;
}
.lamp[data-on], [data-on] > .lamp, [aria-pressed="true"] > .lamp {
  background: var(--lens-catch), var(--lamp);
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.2), 0 0 7px rgba(var(--lamp-rgb), .55), 0 0 14px rgba(var(--lamp-rgb), .25);
}
.lamp--hot { --lamp: var(--sharp); --lamp-rgb: 232,102,60; }

/* ---------- knob ---------- */
.knob { display: grid; justify-items: center; gap: 6px; width: max-content; touch-action: none; }
.knob-dial {
  position: relative; width: var(--knob-size, 62px); height: var(--knob-size, 62px); border-radius: 50%;
  cursor: ns-resize;
  background:
    radial-gradient(circle at 50% 36%, rgba(255,255,255,.07) 0%, transparent 46%),
    radial-gradient(circle at 50% 50%, #2a221a 0 60%, #1b1610 61% 100%),
    linear-gradient(180deg, #332a20, #15110d);
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,.12), inset 0 -2px 4px rgba(0,0,0,.6),
    0 8px 14px -6px rgba(0,0,0,1), 0 0 0 1px rgba(0,0,0,.6), 0 0 0 2px rgba(255,255,255,.03);
}
.knob-dial:focus-visible { outline: 2px solid var(--tune); outline-offset: 4px; }
.knob-dial::before {                 /* the pointer groove */
  content: ""; position: absolute; left: 50%; top: 6px; width: 3px; height: 30%;
  margin-left: -1.5px; border-radius: 2px;
  background: var(--tune); box-shadow: 0 0 6px rgba(var(--tune-rgb), .7);
  transform-origin: 50% calc(var(--knob-size, 62px) / 2 - 6px);
  transform: rotate(var(--angle, 0deg));
  transition: transform .06s linear;
}
.knob-scale {
  position: absolute; inset: -9px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from -135deg, transparent 0 0deg, transparent 270deg, transparent 360deg);
}
.knob-scale i {
  position: absolute; left: 50%; top: 0; width: 1px; height: 4px; margin-left: -.5px;
  background: rgba(240,233,221,.32); transform-origin: 50% calc(var(--knob-size, 62px) / 2 + 9px);
  transform: rotate(var(--a));
}
.knob-scale i.is-lit { background: var(--tune); box-shadow: 0 0 4px rgba(var(--tune-rgb), .6); }
.knob-label { font-family: var(--stencil); font-size: .5rem; letter-spacing: .12em; text-transform: uppercase; color: #6c6152; text-shadow: 0 1px 0 rgba(0,0,0,.8); -webkit-font-smoothing: none; }
.knob-value { font-family: var(--seg); font-size: .8rem; color: var(--tune); text-shadow: 0 0 6px rgba(var(--tune-rgb), .5); line-height: 1; }

/* ---------- seven-segment ---------- */
.seg { font-family: var(--seg); color: var(--tune); text-shadow: 0 0 7px rgba(var(--tune-rgb), .5), 0 0 16px rgba(var(--tune-rgb), .2); font-variant-numeric: tabular-nums; }
.seg-ghost { position: relative; }
.seg-ghost::before { content: attr(data-ghost); position: absolute; inset: 0; color: rgba(var(--tune-rgb), .09); text-shadow: none; }

/* ---------- radio key ----------
   The app's stem key: a square cap with nothing on it but a lens in the
   middle, dark until the key is down. The mark that says what it selects
   sits above it, engraved on the panel. */
.key--radio { --key-size: 34px; --lamp: var(--tune); --lamp-rgb: var(--lit-rgb); width: var(--key-size); height: var(--key-size); flex: none; }
.key--radio .key-face { position: relative; height: calc(var(--key-size) - 9px); min-height: 0; padding: 0; margin: 4.5px; }
.key--radio .key-face::before {
  content: ""; position: absolute; top: 50%; left: 50%; width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
  border-radius: 50%; background: var(--lens-face); box-shadow: var(--lens-edge);
  transition: background .16s var(--ease), box-shadow .16s var(--ease);
}
.key--radio[aria-checked="true"] .key-face {
  background: linear-gradient(180deg, rgba(255,255,255,.035) 0%, rgba(0,0,0,.2) 52%, rgba(0,0,0,.34) 100%), var(--key-base);
  box-shadow: inset 0 3px 7px rgba(0,0,0,.7), inset 0 -1px 0 rgba(255,255,255,.05);
}
.key--radio[aria-checked="true"] .key-face::before {
  background: var(--lens-catch), var(--lamp);
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.2), 0 0 7px rgba(var(--lamp-rgb), .55), 0 0 14px rgba(var(--lamp-rgb), .25);
}
.stem-select { display: flex; gap: 8px; }
.stem-select--row { gap: 14px; }
.stem-select--row .stem-opt { flex-direction: row; gap: 7px; }
.stem-opt { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.stem-mark { width: 15px; height: 15px; color: #6a6053; filter: drop-shadow(0 1px 0 rgba(0,0,0,.75)); }

/* ---------- the display ----------
   The amp's transport display, as the app builds it: a head row with the
   title, the status on the centre of the glass and a detail at the right;
   the trace between two seven-segment times; engine and notes along the
   foot. All legends in the 8px pixel face. */
.display { --lamp-at: 50% 128%; --lamp-wide: 72%; --lamp-reach: 118%; --vignette: 34px; height: 172px; padding: 14px 18px 12px; display: flex; flex-direction: column; }
.dsp-row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; line-height: 1; }
.dsp-row--head { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; }
.dsp-row--head > :last-child { justify-self: end; text-align: right; }
.dsp-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsp-text { font-family: var(--stencil); font-size: 8px; font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: var(--tune); text-shadow: 0 0 7px rgba(var(--tune-rgb), .45), 0 0 15px rgba(var(--tune-rgb), .2); -webkit-font-smoothing: none; }
.dsp-text--dim { color: var(--lit-dim); text-shadow: 0 0 6px rgba(var(--tune-rgb), .22); }
.dsp-status { color: var(--lit-dim); }
.dsp-body { flex: none; height: 108px; display: flex; align-items: center; gap: 16px; }
.dsp-time { flex: none; font-family: var(--seg); font-size: 17px; font-weight: 700; letter-spacing: .06em; color: var(--tune); text-shadow: 0 0 8px rgba(var(--tune-rgb), .5), 0 0 16px rgba(var(--tune-rgb), .22); }
.dsp-trace { flex: 1; min-width: 0; height: 100%; }
.dsp-trace canvas { width: 100%; height: 100%; display: block; }
@media (max-width: 520px) {
  .display { padding: 12px 12px 10px; }
  .dsp-row--head > :last-child { display: none; }
  .dsp-row--head { grid-template-columns: 1fr auto; }
}

/* ======================================================================
   MASTHEAD
   ====================================================================== */
.mast {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  height: 64px; padding: 0 var(--pad);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  background: rgba(14,12,10,.72);
  border-bottom: 1px solid var(--line);
}
.mast-brand { text-decoration: none; }
.mast nav { display: flex; align-items: center; gap: 1.6rem; }
.mast nav a { font-size: .86rem; color: var(--ink-dim); text-decoration: none; }
.mast nav a:hover { color: var(--ink); }
.mast nav a.mast-key { color: var(--ink-dim); margin-left: .4rem; }
.mast nav a.mast-key:hover { color: var(--ink-dim); }
.mast-key .key-face { min-height: 0; height: 25px; padding: 0 16px; }
.mast-key { height: 34px; }
/* Which lamp the machine is fitted with: the app's selector, as a small
   fascia fixed at the foot of the page, keys in a column. Each key shows
   its own colour behind the lens, chosen or not. */
.lamp-fab {
  position: fixed; right: 18px; top: 50%; transform: translateY(-50%); z-index: 30;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 10px 8px 8px; border-radius: 14px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.7), 0 18px 34px -18px rgba(0,0,0,.9);
}
.lamp-fab .knob-label { font-family: var(--font); font-size: 9px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); text-shadow: 0 1px 0 rgba(0,0,0,.7); margin-bottom: 2px; }
.lamp-fab-keys { display: flex; flex-direction: column; gap: 6px; }
.lamp-fab .key--radio { --key-size: 30px; }
.lamp-fab [data-theme="amber"] { --lamp: #f5b52a; --lamp-rgb: 245, 181, 42; }
.lamp-fab [data-theme="green"] { --lamp: #3fdd88; --lamp-rgb: 63, 221, 136; }
.lamp-fab [data-theme="blue"]  { --lamp: #4aa8ff; --lamp-rgb: 74, 168, 255; }
.lamp-fab [data-theme="white"] { --lamp: #eef2f6; --lamp-rgb: 238, 242, 246; }
/* ---------- the phone menu ----------
   The masthead keeps the wordmark and one key; everything else drops into
   a fascia drawer under it: the sections, the lamp, the download. */
.mast-menu { display: none; }
.mast-menu .key-face svg { width: 14px; height: 14px; }
.mast-drawer {
  display: none; position: fixed; left: 10px; right: 10px; top: 72px; z-index: 25;
  padding: 14px; border-radius: 16px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.7), 0 30px 60px -20px rgba(0,0,0,.95);
}
.mast-drawer nav { display: grid; gap: 2px; }
.mast-drawer nav a { display: block; padding: 10px 6px; font-size: 1rem; color: var(--ink); text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.05); }
.drawer-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 6px 4px; }
.drawer-row .knob-label { font-family: var(--font); font-size: 10px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.drawer-lamps { display: flex; gap: 8px; }
.drawer-lamps .key--radio { --key-size: 30px; }
.drawer-lamps [data-theme="amber"], .lamp-fab [data-theme="amber"] { --lamp: #f5b52a; --lamp-rgb: 245, 181, 42; }
.drawer-lamps [data-theme="green"], .lamp-fab [data-theme="green"] { --lamp: #3fdd88; --lamp-rgb: 63, 221, 136; }
.drawer-lamps [data-theme="blue"],  .lamp-fab [data-theme="blue"]  { --lamp: #4aa8ff; --lamp-rgb: 74, 168, 255; }
.drawer-lamps [data-theme="white"], .lamp-fab [data-theme="white"] { --lamp: #eef2f6; --lamp-rgb: 238, 242, 246; }
body[data-menu] .mast-drawer { display: block; }
@media (max-width: 640px) {
  .mast nav a:not(.mast-key) { display: none; }
  .mast nav { gap: 8px; }
  .mast-menu { display: inline-block; }
  .lamp-fab { display: none; }
}
.phone-only { display: none; }
@media (max-width: 640px) {
  .phone-only { display: block; margin: 0 0 1.2rem; padding: .9rem 1.1rem; border-radius: 10px; background: rgba(0,0,0,.3); box-shadow: inset 0 0 0 1px rgba(var(--lit-rgb), .18); font-size: .9rem; color: var(--ink-dim); }
  .phone-only b { color: var(--ink); font-weight: 500; }
}

/* ======================================================================
   HERO — the machine
   ====================================================================== */
.hero { padding: clamp(2.5rem, 7vh, 5rem) 0 clamp(3rem, 8vh, 6rem); }
.hero-copy { display: grid; gap: 1.2rem; margin-bottom: clamp(1.8rem, 4vh, 3rem); max-width: 46rem; }
.hero h1 {
  font-size: clamp(2.6rem, 7.2vw, 5.6rem);
  line-height: .98; letter-spacing: -.045em;
  text-shadow: 0 1px 0 rgba(0,0,0,.6);
}
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.4rem; margin-top: .4rem; }
.hero-aside { margin: 0; line-height: 1; }
.cta-key { color: var(--ink-dim); text-decoration: none; }
.cta-key .key-face { font-size: 11px; padding: 12px 24px; }
.hero-aside { font-size: .86rem; color: var(--ink-faint); }
.hero-aside b { color: var(--ink-dim); font-weight: 500; }

/* The amp: the app's fascia. The roll sits in a 14px inset of panel; the
   stage-keys ledge and the amp face run the full width beneath it. */
/* The amp is drawn at one size and scaled to the room it has. Purely
   visual, so on a phone it simply gets small. */
.amp-stage { position: relative; }
.amp {
  --amp-w: 1056px;
  width: var(--amp-w); transform-origin: 0 0;
  border-radius: 18px; padding: 14px 14px 0; overflow: hidden;
  display: grid; gap: 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.55), 0 40px 80px -30px rgba(0,0,0,.95), 0 0 0 1px rgba(0,0,0,.7);
}
.roll-glass {
  --lamp-at: 50% 62%; --lamp-wide: 66%; --lamp-reach: 90%; --lamp-strength: .75; --vignette: 90px;
  height: clamp(300px, 46vh, 440px);
  display: grid;
  contain: paint;
}
.roll-glass canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
.roll-foot { align-self: end; justify-self: center; display: grid; justify-items: center; gap: 4px; padding-bottom: 14px; pointer-events: none; }
.readout { display: flex; align-items: flex-end; gap: 28px; }
.readout-slot { display: grid; justify-items: center; gap: 2px; min-width: 64px; }
.readout-note { font-size: 1.9rem; font-weight: 600; letter-spacing: -.03em; line-height: 1; color: #b9ad97; text-shadow: 0 0 14px rgba(240,233,221,.15); transition: color .12s; }
.readout-note--you { color: var(--tune); text-shadow: 0 0 14px rgba(var(--tune-rgb), .5); }
.readout-note[data-empty] { color: rgba(240,233,221,.18); text-shadow: none; }
.readout-cap { font-family: var(--stencil); font-size: .5rem; letter-spacing: .16em; text-transform: uppercase; color: #8a7d66; -webkit-font-smoothing: none; }
.readout-sep { width: 1px; height: 26px; background: rgba(var(--tune-rgb), .2); margin-bottom: 14px; }
.verdict { font-family: var(--stencil); font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--lit-dim); -webkit-font-smoothing: none; margin: 4px 0 0; min-height: 1.2em; transition: color .12s; }
.is-tune .readout-note--you, .is-tune .verdict { color: var(--tune); }
.is-sharp .readout-note--you, .is-sharp .verdict, .is-flat .readout-note--you, .is-flat .verdict { color: var(--lit-dim); text-shadow: none; }
.lyric { margin-top: 10px; text-align: center; }
.lyric-now { font-size: clamp(1.1rem, 2.2vw, 1.45rem); font-weight: 600; letter-spacing: -.01em; margin: 0; color: rgba(var(--tune-rgb), .32); line-height: 1.3; }
.lyric-now .w { transition: color .08s, text-shadow .08s; }
.lyric-now .w.sung { color: var(--tune); text-shadow: 0 0 12px rgba(var(--tune-rgb), .45); }
.lyric-next { margin: 2px 0 0; font-size: .92rem; color: rgba(240,233,221,.28); }
.roll-tag { position: absolute; top: 12px; left: 16px; font-family: var(--stencil); font-size: .52rem; letter-spacing: .14em; text-transform: uppercase; color: var(--lit-dim); -webkit-font-smoothing: none; z-index: 1; }
.roll-tag b { color: var(--tune); font-weight: 400; text-shadow: 0 0 8px rgba(var(--tune-rgb), .5); }

/* ---------- the stage-keys ledge (web/style.css) ---------- */
.stage-keys {
  margin: 14px -14px 0;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px;
  padding: 7px 22px 16px;
  background-image: var(--grain), linear-gradient(180deg, #221a12 0%, #2a2119 100%);
  background-size: 150px 150px, auto; background-blend-mode: multiply, normal;
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.055);
}
/* One key height on the fascia, legend keys and icon keys alike. */
.stage-keys .key, .amp-under .key { height: 34px; }
.stage-keys .key:not(.key--radio):not(.key--icon) .key-face, .amp-under .key:not(.key--radio):not(.key--icon) .key-face { min-height: 0; height: 25px; padding: 0 16px; }
.keys-left, .keys-right { display: flex; align-items: center; gap: 12px; }
.keys-left { justify-self: start; }
.keys-right { justify-self: end; }
.scoreboard { display: flex; align-items: center; gap: 22px; }
.stat { display: flex; align-items: center; gap: 9px; }
.stat-label { font-size: 10px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.led { position: relative; display: inline-block; padding: 6px 11px; border-radius: 6px; background: #0a0806; box-shadow: inset 0 2px 4px rgba(0,0,0,.85), inset 0 0 0 1px rgba(0,0,0,.6), 0 1px 0 rgba(255,255,255,.04); font-family: var(--seg); font-size: 13px; font-weight: 700; line-height: 1; letter-spacing: .06em; }
.led .led-off { color: rgba(var(--tune-rgb), .085); text-shadow: none; }
.led .led-on { position: absolute; color: var(--tune); text-shadow: 0 0 7px rgba(var(--tune-rgb), .5), 0 0 16px rgba(var(--tune-rgb), .2); }
.led--stat { min-width: 54px; padding: 7px 10px; font-size: 15px; text-align: right; }
.led--stat .led-on { top: 7px; right: 10px; font-size: 15px; }
.led--count { min-width: 40px; padding: 6px 8px; font-size: 13px; text-align: right; }
.led--count .led-on { top: 6px; right: 8px; font-size: 13px; }
.head-takes { display: flex; align-items: center; gap: 8px; }

/* ---------- the amp face (web/style.css .amp) ---------- */
.amp-face {
  --amp-key: 128px; --amp-line: 75px; --key-gap: 8px;
  margin: 0 -14px;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-rows: auto auto;
  align-items: center; column-gap: 26px; row-gap: 4px;
  padding: 20px 26px 18px;
  background-image: var(--grain), linear-gradient(180deg, #201810 0%, #17110c 58%, #0f0b08 100%);
  background-size: 150px 150px, auto; background-blend-mode: multiply, normal;
}
.amp-play { grid-column: 1; grid-row: 1; align-self: start; margin-top: calc(var(--amp-line) - var(--amp-key) / 2); display: flex; justify-content: center; }
.amp-face .stem-select { grid-column: 1; grid-row: 2; justify-content: center; gap: var(--key-gap); }
.amp-face .stem-select .stem-opt { gap: 0; }
.amp-face .stem-select .stem-mark { position: absolute; bottom: calc(100% + 7px); left: 50%; transform: translateX(-50%); }
.amp-display { grid-column: 2; grid-row: 1; padding-bottom: 8px; min-width: 0; }
.amp-under { grid-column: 2; grid-row: 2; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px; }
.amp-under-left { display: flex; align-items: center; gap: var(--key-gap); }
.amp-under-right { display: flex; align-items: center; justify-content: flex-end; gap: var(--key-gap); }
.amp-under .key--icon { width: 34px; height: 34px; }
.amp-under .key--icon .key-face { width: 25px; height: 25px; min-height: 0; padding: 0; min-width: 0; }
.amp-under .key--icon .key-face svg { width: 13px; height: 13px; }
.amp-mic { display: flex; align-items: center; gap: 5px; }
.amp-mic .key--radio { --lamp: var(--hot); --lamp-rgb: 207,47,24; }

/* The play key: round, and deliberately not a push key. It does not travel
   and has no pressed face; the glyph lights, and the cap warms round it. */
.key--play { --key-size: var(--amp-key, 96px); width: var(--key-size); height: var(--key-size); border-radius: 50%; flex: none; }
.key--play::after { border-radius: 50%; }
.key--play .key-face { height: calc(var(--key-size) - 9px); min-height: 0; padding: 0; border-radius: 50%; }
.key--play .key-face::after { border-radius: 50%; }
.key--play:active .key-face, .key--play[data-state="on"] .key-face {
  background: linear-gradient(180deg, rgba(0,0,0,.17) 0%, rgba(0,0,0,.09) 32%, rgba(255,255,255,.025) 66%, rgba(255,255,255,.055) 100%), var(--key-base);
  box-shadow: inset 0 -3px 7px rgba(0,0,0,.45), 0 8px 10px -7px rgba(0,0,0,1), 0 14px 22px -12px rgba(0,0,0,1);
}
.key--play .play-glyph { position: relative; display: block; width: calc(var(--key-size) * .3); height: calc(var(--key-size) * .3); }
.key--play .play-glyph::before {
  content: ""; position: absolute; inset: -100%; border-radius: 50%;
  background: radial-gradient(closest-side circle, rgba(var(--lit-rgb),.17) 0%, rgba(var(--lit-rgb),.07) 42%, rgba(var(--lit-rgb),0) 74%);
  opacity: 0; transition: opacity .22s var(--ease); pointer-events: none;
}
.key--play[data-state="on"] .play-glyph::before { opacity: 1; }
.key--play .play-glyph svg { position: relative; width: 100%; height: 100%; display: block; transform: translateX(4%); filter: drop-shadow(0 1px 0 rgba(0,0,0,.55)); transition: filter .2s var(--ease); }
.key--play .play-glyph path { fill: #5d5545; transition: fill .18s var(--ease); }
.key--play[data-state="on"] .play-glyph path { fill: var(--tune); }
.key--play[data-state="on"] .play-glyph svg { filter: drop-shadow(0 0 2px rgba(var(--lit-rgb),.85)) drop-shadow(0 0 7px rgba(var(--lit-rgb),.5)) drop-shadow(0 0 16px rgba(var(--lit-rgb),.25)); }

/* The wordmark, engraved on the panel between the two key clusters. */
.wordmark { display: flex; align-items: center; gap: 13px; }
.wordmark-mark { width: 26px; height: 26px; flex: none; line-height: 0; filter: drop-shadow(0 1px 0 rgba(0,0,0,.8)); }
.wordmark-mark img { display: block; width: 100%; height: 100%; }
.wordmark span { font-size: 15px; font-weight: 500; letter-spacing: .38em; text-transform: uppercase; background: linear-gradient(180deg, #c2b298 0%, #8a7d6a 38%, #5a5145 68%, #3f382f 100%); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 1px 0 rgba(0,0,0,.8)); }

/* The master, and the meter under it. One figure (--amp-key) sizes both
   ends of the fascia so the face does not lean. */
.amp-volume {
  grid-column: 3; grid-row: 1; align-self: start; width: var(--amp-key);
  --amp-ring: calc(var(--amp-key) + 20px);
  --dial: calc((var(--amp-ring) / 2 - 17px) / 0.31);
  margin-top: calc(var(--amp-line) - var(--dial) / 2);
  height: 172px; display: flex; align-items: flex-start; justify-content: center;
}
.amp-face .dial-wrap { --cap: calc(var(--dial, 116px) * .62); }
.amp-volume .dial-wrap { --bead: 7px; --bead-inset: 13px; }
.knob--stack { display: flex; flex-direction: column; align-items: center; gap: 0; }
.knob--stack .knob-head { margin-top: calc(var(--dial, 116px) * -.05); display: flex; flex-direction: column; align-items: center; gap: 5px; }
.knob--stack .knob-label { font-size: 10px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); text-shadow: 0 1px 0 rgba(0,0,0,.7); font-family: var(--font); -webkit-font-smoothing: antialiased; text-align: center; }
.dial-min, .dial-max { position: absolute; font-size: 8.5px; font-weight: 500; line-height: 1; letter-spacing: .06em; color: var(--ink-faint); font-variant-numeric: tabular-nums; text-shadow: 0 1px 0 rgba(0,0,0,.8); }
.dial-min { left: 9px; bottom: 9px; }
.dial-max { right: 9px; bottom: 9px; }
.knob--mix .dial-min, .knob--mix .dial-max { display: none; }
.amp-volume .dial-mid { display: none; }
.amp-volume .dial-min, .amp-volume .dial-max { --ring: calc(var(--tick-r) + 16px); left: auto; right: auto; bottom: auto; transform: translate(-50%, -50%); }
.amp-volume .dial-min { left: calc(50% - var(--ring) * 0.707); top: calc(50% + var(--ring) * 0.707); }
.amp-volume .dial-max { left: calc(50% + var(--ring) * 0.707); top: calc(50% + var(--ring) * 0.707); }
.amp-meter {
  grid-column: 3; grid-row: 2; justify-self: center; align-self: center; position: relative;
  width: var(--amp-key); height: 15px; border-radius: 3px; background: rgba(0,0,0,.38);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.62), inset 0 -1px 0 rgba(255,255,255,.04), 0 1px 0 rgba(255,255,255,.035);
  --meter-track: calc(var(--amp-key) - 6px);
}
.meter-bed, .meter-fill { position: absolute; top: 3px; bottom: 3px; left: 3px; -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 3px, transparent 3px 5px); mask-image: repeating-linear-gradient(90deg, #000 0 3px, transparent 3px 5px); }
.meter-bed { right: 3px; background: rgba(var(--lit-rgb),.085); }
.meter-fill { width: calc(var(--meter-track) * var(--level, 0)); background: linear-gradient(90deg, rgba(var(--lit-rgb),.85) 0%, rgba(var(--lit-rgb),.95) 64%, #e8663c 86%, var(--hot) 100%); background-size: var(--meter-track) 100%; background-repeat: no-repeat; }
.meter-peak { position: absolute; top: 3px; bottom: 3px; left: 3px; width: 2px; margin-left: -2px; transform: translateX(calc(var(--meter-track) * var(--peak, 0))); background: #f7d489; opacity: 0; transition: opacity .25s var(--ease); }
.amp-meter[data-live] .meter-peak { opacity: .92; }


/* The fine print under the machine. */
.hero-note { margin: 1.1rem 0 0; font-size: .84rem; color: var(--ink-faint); max-width: 70ch; }
.hero-note a { color: var(--ink-dim); }

/* ======================================================================
   SECTIONS
   ====================================================================== */
section { padding: clamp(3.5rem, 9vw, 7rem) 0; }
.band { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.sec-head { display: grid; gap: .2rem; margin-bottom: clamp(1.8rem, 4vw, 3rem); }
.sec-head .lede { margin: .2rem 0 0; }
.two { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: clamp(1.5rem, 4vw, 4rem); align-items: start; }
.two > * { min-width: 0; }

/* thesis */
.thesis { padding-top: clamp(2rem, 6vw, 4rem); }
.thesis-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.thesis-cell { background: #15110e; padding: 1.5rem 1.6rem 1.7rem; }
.thesis-cell .stencil { display: block; margin-bottom: .8rem; }
.thesis-cell p { font-size: .95rem; color: var(--ink-dim); margin: 0; }

/* ---------- signal chain ----------
   Modules screwed to the panel in two rows. A real order: song in one end,
   your voice in the other, the roll in the middle where they meet. */
.chain { display: grid; gap: 14px; margin-top: 2rem; }
.chain-title { margin: 1.2rem 0 .2rem; font-family: var(--stencil); font-weight: 400; font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: #8a7d66; text-shadow: 0 1px 0 rgba(0,0,0,.8); -webkit-font-smoothing: none; }
.chain-title:first-child { margin-top: 0; }
.chain-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; align-items: stretch; }
.mod {
  position: relative;
  border-radius: 12px; padding: 1.1rem 1.15rem 1.1rem;
  background-image: var(--grain), linear-gradient(180deg, #241c14 0%, #1d1710 100%);
  background-size: 150px 150px, auto; background-blend-mode: multiply, normal;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.6), 0 0 0 1px rgba(0,0,0,.7);
  display: flex; flex-direction: column; gap: .6rem;
}
.mod-title { margin: 0; font-family: var(--font); font-weight: 500; font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink); text-shadow: 0 1px 0 rgba(0,0,0,.7); line-height: 1.3; }
.mod p { font-size: .9rem; color: var(--ink-dim); margin: 0; }
/* The figure, along the foot: legend at the left, the window at the right,
   the way the stat windows sit under the app's roll. Dark until the section
   is in view, then lit one after another. */
.mod-fig { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: auto; padding-top: .6rem; }
.mod-fig .led { position: relative; padding: 5px 9px; font-family: var(--seg); font-size: 13px; font-weight: 700; letter-spacing: .06em; line-height: 1; border-radius: 6px; background: #0a0806; box-shadow: inset 0 2px 4px rgba(0,0,0,.85), inset 0 0 0 1px rgba(0,0,0,.6), 0 1px 0 rgba(255,255,255,.04); }
.mod-fig .led-off { color: rgba(var(--tune-rgb), .085); }
.mod-fig .led-on { position: absolute; top: 5px; right: 9px; font-size: 13px; transition: color .34s var(--ease), text-shadow .34s var(--ease); }
.mod-fig[data-dark] .led-on { color: #2b2620; text-shadow: none; }
.mod-fig small { font-family: var(--stencil); font-size: .6rem; letter-spacing: .12em; text-transform: uppercase; color: #8a7d66; -webkit-font-smoothing: none; }
.mod--glass { background: linear-gradient(180deg, #0a0807, #120e0a); box-shadow: 0 0 0 2px rgba(0,0,0,.92), 0 0 0 3px rgba(255,255,255,.05), inset 0 0 40px rgba(var(--tune-rgb), .06); }
.mod--glass .mod-title { color: var(--tune); text-shadow: 0 0 8px rgba(var(--tune-rgb), .4); }
@media (max-width: 800px) { .chain-row { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .chain-row { grid-template-columns: 1fr; } }
.chain-note { font-size: .88rem; color: var(--ink-faint); margin-top: 1.4rem; max-width: 70ch; }

/* ---------- feature panels ----------
   Each feature is a panel from the app, rebuilt small: a strip of fascia
   with a screen cut into it. */
.fit-stage { position: relative; }
.fit-stage > .panel { --fit-w: 496px; width: var(--fit-w); transform-origin: 0 0; }
.panel {
  border-radius: 16px; padding: 12px;
  display: grid; gap: 12px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.7);
}
/* A taller display: the head and foot rows keep to the edges and the trace
   takes whatever is between them. */
.display--tall { height: 210px; }
.display--tall .dsp-body { flex: 1; height: auto; min-height: 0; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 2px; min-height: 34px; }
.panel-head h4 { margin: 0 auto 0 0; font-family: var(--font); font-weight: 500; font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-dim); text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.panel-keys { display: flex; gap: 8px; align-items: center; }
.panel-keys .lamp { margin-right: 4px; }
.panel-head .key { height: 34px; }
.panel-head .key:not(.key--radio):not(.key--icon) .key-face { min-height: 0; height: 25px; padding: 0 14px; }
.panel-head .key--icon .key-face { min-height: 0; height: 25px; }
/* Icon keys on a panel head are square, as on the app's fascia. */
.panel-head .key--icon { width: 34px; }
.panel-head .key--icon .key-face { width: 25px; min-width: 0; padding: 0; }
.key--icon svg { width: 13px; height: 13px; flex: none; filter: drop-shadow(0 1px 0 rgba(0,0,0,.7)); }
.panel-screen { --lamp-at: 50% 120%; --lamp-strength: .7; --vignette: 30px; padding: 16px 18px; min-height: 200px; }

/* stems */
.stem-say { font-size: .92rem; color: var(--ink-faint); margin: 1.1rem 0 0; min-height: 2.6em; }
.stem-say b { color: var(--ink-dim); font-weight: 500; }

/* lyrics editor: web/style.css, brought over whole */
.panel-screen--lyrics {
  --vignette: 44px; --lamp-at: 50% 118%; --lamp-wide: 96%; --lamp-reach: 74%; --lamp-strength: .78;
  color: var(--lit-dim); padding: 0; height: 340px; display: flex; flex-direction: column;
}
.screen-body { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.panel-view { flex: 1; min-height: 0; padding: 15px 12px 18px 18px; margin-right: 6px; overflow-y: auto; }
.panel-view::-webkit-scrollbar { width: 3px; }
.panel-view::-webkit-scrollbar-track { background: transparent; margin: 15px 0 18px; }
.panel-view::-webkit-scrollbar-thumb { background: rgba(var(--tune-rgb), .18); border-radius: 2px; }
.panel-view:hover::-webkit-scrollbar-thumb { background: rgba(var(--tune-rgb), .4); }
/* Haze at the edges of what scrolls, so a line running out of the window
   dissolves into the rim rather than being sliced by it. Only where
   something is actually running under it. */
.screen-haze { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.screen-haze::before, .screen-haze::after {
  content: ""; position: absolute; left: 0; right: 0; height: 34px;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; transition: opacity .22s var(--ease);
}
.screen-haze::before {
  top: 0;
  -webkit-mask-image: linear-gradient(to bottom, #000 0 22%, rgba(0,0,0,.5) 62%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0 22%, rgba(0,0,0,.5) 62%, transparent 100%);
  background: linear-gradient(to bottom, var(--glass-top) 0%, color-mix(in srgb, var(--glass-top) 52%, transparent) 46%, transparent 100%);
}
.screen-haze::after {
  bottom: 0;
  -webkit-mask-image: linear-gradient(to top, #000 0 22%, rgba(0,0,0,.5) 62%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0 22%, rgba(0,0,0,.5) 62%, transparent 100%);
  background: linear-gradient(to top, var(--glass-foot) 0%, color-mix(in srgb, var(--glass-foot) 52%, transparent) 46%, transparent 100%);
}
.panel-screen[data-over] .screen-haze::before, .panel-screen[data-under] .screen-haze::after { opacity: 1; }
.screen-hint { margin: 0 0 16px; line-height: 1.8; display: block; }
.lyric-edit { --lyric-line: 26px; --lyric-size: 14px; position: relative; display: grid; grid-template-columns: auto 1fr; gap: 10px; }
.lyric-gutter { position: relative; padding: 10px 0; min-width: 56px; text-align: right; }
.lyric-at-line { position: absolute; right: 0; display: flex; align-items: center; justify-content: flex-end; gap: 5px; height: var(--lyric-line); white-space: nowrap; color: rgba(232,226,214,.62); }
.lyric-at { padding: 0 2px; border: 0; background: none; font-family: var(--stencil); font-size: 11px; font-weight: 400; letter-spacing: .04em; line-height: var(--lyric-line); color: inherit; cursor: pointer; -webkit-font-smoothing: none; }
.lyric-at:hover, .lyric-stamp:hover { color: rgba(246,242,234,.95); }
.lyric-at-line--none .lyric-at { cursor: default; opacity: .4; }
.lyric-at-line--none .lyric-at:hover { color: inherit; }
.lyric-stamp { position: relative; flex: none; width: 11px; height: var(--lyric-line); padding: 0; border: 0; background: none; color: inherit; cursor: pointer; opacity: 0; transition: opacity .14s var(--ease), color .14s var(--ease); }
.lyric-stamp::before, .lyric-stamp::after { content: ""; position: absolute; left: 50%; background: currentColor; }
.lyric-stamp::before { top: 50%; width: 1px; height: 11px; margin: -6px 0 0 -1px; }
.lyric-stamp::after  { top: 50%; width: 5px; height: 1px; margin: -1px 0 0 -3px; }
.lyric-at-line:hover .lyric-stamp, .lyric-at-line--none .lyric-stamp, .lyric-stamp:focus-visible { opacity: .75; }
.lyric-stamp:hover { opacity: 1; }
.lyric-area, .lyric-mirror {
  min-width: 0; padding: 10px 12px 10px 0; border: 0; background: none; resize: none; overflow: hidden;
  color: var(--tune); font: inherit; font-family: var(--font); font-size: var(--lyric-size); line-height: var(--lyric-line);
  white-space: pre-wrap; overflow-wrap: break-word; outline: none; caret-color: var(--tune);
}
.lyric-area::selection { background: rgba(var(--tune-rgb), .3); }
.lyric-mirror { position: absolute; visibility: hidden; pointer-events: none; top: 0; left: -9999px; }
.lyric-edit.dirty .lyric-gutter { opacity: .4; }

/* alignment figure: two rows of the same words, whisper's guess vs aligned */
.align-fig { display: grid; gap: 10px; margin-top: 1.6rem; }
.align-row { display: grid; grid-template-columns: 5.5rem 1fr; align-items: center; gap: 12px; }
.align-row .stencil { color: #8a7d66; }
.align-track { position: relative; height: 34px; border-radius: 6px; background: rgba(0,0,0,.35); box-shadow: inset 0 1px 2px rgba(0,0,0,.6); overflow: hidden; }
.align-track .onset { position: absolute; top: 0; bottom: 0; width: 2px; background: rgba(240,233,221,.22); }
.align-track .word { position: absolute; top: 7px; height: 20px; padding: 0 6px; border-radius: 4px; font-size: .74rem; line-height: 20px; font-weight: 500; background: rgba(var(--tune-rgb), .14); color: var(--tune); border-left: 2px solid var(--tune); white-space: nowrap; }
.align-track .word.off { background: rgba(232,102,60,.14); color: var(--sharp); border-left-color: var(--sharp); }
.align-cap { font-size: .84rem; color: var(--ink-faint); margin: .3rem 0 0; }

/* takes: web/style.css, brought over whole */
.panel-screen--takes {
  --vignette: 44px; --lamp-at: 50% 118%; --lamp-wide: 96%; --lamp-reach: 74%; --lamp-strength: .78;
  color: var(--lit-dim); padding: 0; display: flex; flex-direction: column; min-height: 360px;
}
.screen-top { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; margin: 2px 0 12px; }
.screen-head { margin: 0; font-family: var(--stencil); font-size: 11px; font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: var(--lit-dim); text-shadow: 0 0 7px rgba(var(--tune-rgb), .24); -webkit-font-smoothing: none; }
.screen-tag { font-size: 8px; letter-spacing: .1em; }
.trouble { display: flex; flex-direction: column; }
.spot {
  position: relative; width: 100%; padding: 9px 10px 9px 22px; border: 0; background: none;
  font-family: var(--stencil); font-size: 13px; font-weight: 400; letter-spacing: .05em; text-transform: uppercase; text-align: left;
  color: var(--lit-dim); cursor: pointer; transition: color .16s var(--ease); -webkit-font-smoothing: none;
  display: flex; align-items: baseline; gap: 11px;
}
.spot:hover { color: var(--tune); }
.spot-time { min-width: 34px; opacity: .55; }
.spot-what { flex: 1; }
.spot-what b { font-weight: 400; color: var(--tune); }
.spot-amt { opacity: .55; }
/* The mark of selection: a pointer in the margin, one 2px pixel and its
   shadows, the same resolution as the rest of the glass. */
.spot::before {
  content: ""; position: absolute; left: 4px; top: 50%; width: 2px; height: 2px; margin-top: -5px; background: var(--tune);
  box-shadow: 0 2px 0 var(--tune), 2px 2px 0 var(--tune), 0 4px 0 var(--tune), 2px 4px 0 var(--tune), 4px 4px 0 var(--tune), 0 6px 0 var(--tune), 2px 6px 0 var(--tune), 0 8px 0 var(--tune);
  opacity: 0; transition: opacity .14s var(--ease);
}
.spot:hover::before { opacity: 1; }
.screen-note { flex: none; display: flex; flex-direction: column; margin: 0; padding: 11px 18px 13px; border-top: 1px solid rgba(var(--tune-rgb), .13); }
.screen-note p { margin: 0; font-size: 11px; letter-spacing: .06em; line-height: 1.75; }

/* the mix, at the foot of the panel */
.mix-block { flex: none; padding: 2px 2px 0; margin-top: 2px; }
.mix-head { display: flex; align-items: center; gap: 10px; margin-bottom: 30px; }
.mix-legend { font-size: 13px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint); text-shadow: 0 1px 0 rgba(0,0,0,.7); }
.mix-stems { display: flex; align-items: center; gap: 12px; margin-left: 12px; }
.mix-stem { display: flex; align-items: center; gap: 7px; }
.mix-stem svg { width: 13px; height: 13px; color: #5a5045; }
.mix-keys { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.mix-keys .lamp { margin-right: -1px; }
.mix-keys .key { height: 38px; }
.mix-keys .key:not(.key--radio) .key-face { min-height: 0; height: 29px; padding: 0 14px; }
.mix-keys .key--radio { --key-size: 38px; }
.lamp[data-tone="done"] { --lamp: #7ed37a; --lamp-rgb: 126,211,122; }
.ledge-voice { display: flex; align-items: center; gap: 5px; }
.ledge-voice svg { width: 15px; height: 15px; color: #6a6053; filter: drop-shadow(0 1px 0 rgba(0,0,0,.75)); }
/* ---------- the app's dial (web/style.css) ----------
   Four layers that only read as hardware together: the dish bevelled into
   the panel, the collar the cap turns inside, the cap, and the handle's lit
   bead. Dish and collar are lit from the bottom: in a depression the near
   wall is shadowed and the far wall catches the light. */
.dial-wrap {
  position: relative; width: var(--dial, 116px); height: var(--dial, 116px);
  --cap: calc(var(--dial, 116px) * .5); --dish: 11px; --bead: 4px; --bead-inset: 8px;
  --tick-r: calc(var(--cap) / 2 + var(--dish) + 5px);
}
.dial-wrap::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: calc(var(--cap) + var(--dish) * 2); height: calc(var(--cap) + var(--dish) * 2);
  margin: calc((var(--cap) + var(--dish) * 2) / -2) 0 0 calc((var(--cap) + var(--dish) * 2) / -2);
  border-radius: 50%;
  background: linear-gradient(90deg, #131010 0%, #191411 46%, #241d18 100%);
  box-shadow: inset 0 2px 5px rgba(0,0,0,.5), inset 0 -2px 4px rgba(255,255,255,.04), 0 1px 0 rgba(255,255,255,.025);
  pointer-events: none;
}
.dial-scale i {
  position: absolute; top: 50%; left: 50%; width: 2px; height: 2px; margin: -1px; border-radius: 50%;
  background: #837767; box-shadow: 0 1px 0 rgba(0,0,0,.7);
  transform: rotate(var(--a)) translateY(calc(var(--tick-r) * -1));
}
.dial-scale i:first-child, .dial-scale i:last-child { background: #b3a695; }
.dial-mid {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  font-size: 8.5px; font-weight: 500; line-height: 1; letter-spacing: .06em; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; text-shadow: 0 1px 0 rgba(0,0,0,.8);
}
.dial {
  position: absolute; top: 50%; left: 50%; width: var(--cap); height: var(--cap);
  margin: calc(var(--cap) / -2) 0 0 calc(var(--cap) / -2); border-radius: 50%; border: 0;
  background: linear-gradient(94deg, #363029 0%, #2c2620 44%, #1d1813 78%, #151110 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), inset 0 -3px 7px rgba(0,0,0,.45), 0 3px 7px rgba(0,0,0,.55);
  cursor: ns-resize; touch-action: none; transition: box-shadow .12s var(--ease);
}
.dial::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 1px solid transparent;
  background: linear-gradient(180deg, #141110 0%, #141110 50%, #2b241d 100%) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
.dial::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 4px solid #0c0a09; pointer-events: none; }
.dial:focus-visible, .dial.turning {
  outline: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -4px 8px rgba(0,0,0,.55), 0 3px 7px rgba(0,0,0,.55), 0 0 0 1px rgba(var(--lit-rgb), .18);
}
.dial-rim {
  position: absolute; inset: 0; border-radius: 50%; border: 1px solid transparent;
  background: linear-gradient(158deg, rgba(255,255,255,.16) 0%, rgba(255,255,255,.07) 26%, rgba(255,255,255,0) 56%) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
.dial-mark { position: absolute; inset: 0; transform: rotate(var(--angle, 0deg)); pointer-events: none; }
/* A channel that is not reading: the window's segments go out over a third
   of a second, following the "--" the script writes first, and the bead on
   the cap goes with it. Red for a channel held somewhere you cannot move it. */
.led-on { transition: color .34s var(--ease), text-shadow .34s var(--ease); }
.knob[data-dark] .led-on { color: #2b2620; text-shadow: none; }
.dial-mark::after { transition: background .34s var(--ease), box-shadow .34s var(--ease); }
.knob[data-lamp="off"] .dial-mark::after { background: var(--lens-face); box-shadow: var(--lens-edge); }
.knob[data-lamp="locked"] .dial-mark::after { --lamp-rgb: 207,47,24; background: var(--lens-catch), var(--hot); box-shadow: inset 0 -1px 0 rgba(255,255,255,.2), 0 0 7px rgba(207,47,24,.6), 0 0 14px rgba(207,47,24,.28); }
.dial-mark::after {
  content: ""; position: absolute; left: 50%; top: var(--bead-inset); width: var(--bead); height: var(--bead);
  margin-left: calc(var(--bead) / -2); border-radius: 50%;
  background: var(--lens-catch), var(--tune);
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.2), 0 0 7px rgba(var(--lit-rgb),.55), 0 0 14px rgba(var(--lit-rgb),.25);
}

.mix-knobs { display: flex; align-items: flex-start; gap: 8px; margin-top: 4px; }
.knob--mix { flex: 1 1 0; min-width: 0; display: grid; grid-template-columns: auto auto; justify-content: center; align-items: center; column-gap: 8px; row-gap: 10px; padding-bottom: 4px; }
.knob--mix .dial-wrap { grid-column: 1; grid-row: 1; }
.knob--mix .dial-mid { top: -13px; }
.knob--mix .led { grid-column: 2; grid-row: 1; }
.knob--mix .knob-label { grid-column: 1; grid-row: 2; font-size: 9px; letter-spacing: .12em; line-height: 1.4; text-align: center; white-space: nowrap; color: var(--ink-faint); font-family: var(--font); font-weight: 500; -webkit-font-smoothing: antialiased; }
.led--mini { min-width: 44px; padding: 4px 6px; font-size: 11px; background: #0a0806; box-shadow: inset 0 2px 4px rgba(0,0,0,.85), inset 0 0 0 1px rgba(0,0,0,.6), 0 1px 0 rgba(255,255,255,.04); border-radius: 6px; text-align: right; }
.led--mini { position: relative; font-family: var(--seg); font-weight: 700; letter-spacing: .06em; line-height: 1; }
.led--mini .led-off { color: rgba(var(--tune-rgb), .085); text-shadow: none; }
.led--mini .led-on { position: absolute; top: 4px; right: 6px; font-size: 11px; }

/* mic delay */
.delay-fig { display: grid; gap: 8px; margin-top: 1.4rem; }
.delay-row { display: grid; grid-template-columns: 5.5rem 1fr auto; align-items: center; gap: 12px; font-size: .84rem; color: var(--ink-dim); }
.delay-bar { height: 8px; border-radius: 4px; background: rgba(0,0,0,.4); box-shadow: inset 0 1px 2px rgba(0,0,0,.7); overflow: hidden; }
.delay-bar i { display: block; height: 100%; width: var(--w); background: linear-gradient(90deg, rgba(var(--tune-rgb), .5), var(--tune)); box-shadow: 0 0 8px rgba(var(--tune-rgb), .4); }
.delay-row .seg { font-size: .9rem; }

/* ---------- privacy ---------- */
.ledger { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-top: 1.4rem; }
.ledger-row { display: grid; grid-template-columns: 8px 1fr; gap: 14px; align-items: start; background: #15110e; padding: 1rem 1.2rem; }
.ledger-row .lamp { margin-top: 9px; }
.ledger-row p { margin: 0; font-size: .93rem; color: var(--ink-dim); }
.ledger-row b { display: block; color: var(--ink); font-weight: 500; margin-bottom: .1rem; }
.ledger-row--off .lamp { --lamp: var(--sharp); --lamp-rgb: 232,102,60; }

/* ---------- requirements ---------- */
.scroller { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: rgba(0,0,0,.22); }
table { border-collapse: collapse; width: 100%; min-width: 30rem; font-size: .92rem; }
th, td { text-align: left; padding: .75rem 1rem; border-bottom: 1px solid rgba(255,255,255,.045); vertical-align: top; }
thead th { font-family: var(--stencil); font-size: .52rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; -webkit-font-smoothing: none; }
tbody th { font-weight: 500; color: var(--ink-dim); white-space: nowrap; }
tbody tr:last-child th, tbody tr:last-child td { border-bottom: 0; }
td { color: var(--ink-dim); }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 640px) {
  .scroller { overflow: visible; }
  table, tbody, tr, th, td { display: block; min-width: 0; }
  thead { display: none; }
  tbody tr { padding: 1rem 1.1rem 1.1rem; border-bottom: 1px solid rgba(255,255,255,.06); }
  tbody tr:last-child { border-bottom: 0; }
  tbody th { padding: 0 0 .55rem; border: 0; color: var(--ink); white-space: normal; }
  /* Each value on its own line: the machine at the left, the reading at
     the right, a hairline between the two lines. */
  td { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; padding: .5rem 0; border: 0; border-top: 1px solid rgba(255,255,255,.045); white-space: normal; text-align: right; }
  td:last-child { padding-bottom: 0; }
  td[data-col]::before { content: attr(data-col); flex: none; text-align: left; font-family: var(--stencil); font-size: .5rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); -webkit-font-smoothing: none; }
  td[colspan] { display: block; text-align: left; }
}

/* ---------- download ----------
   Two builds, the same panel each: a metal mark, what it is, and a key to
   press. Neither is "selected"; the one to take says so in words. */
.download { padding-bottom: clamp(4rem, 10vw, 8rem); }
.builds { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 14px; margin-top: 2rem; }
.build {
  position: relative; display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto; gap: 6px 18px; align-items: start;
  padding: 1.4rem 1.5rem 1.5rem; border-radius: 16px; text-decoration: none; color: inherit;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), inset 0 -1px 0 rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.7);
}
.build:hover { color: inherit; }
.build-art { grid-row: 1 / 3; display: flex; align-items: center; padding-top: 2px; }
.build-art svg { display: block; filter: drop-shadow(0 1px 0 rgba(255,255,255,.06)) drop-shadow(0 -1px 0 rgba(0,0,0,.8)); }
.build-art .bird { width: 44px; height: 44px; }
.build-body { display: grid; gap: 2px; min-width: 0; }
.build-name { font-size: 1.35rem; font-weight: 600; letter-spacing: -.02em; line-height: 1.2; }
.build-meta { font-family: var(--mono); font-size: .74rem; color: #8a7d6a; margin-top: .1rem; }
.build-meta b { font-weight: 500; color: var(--tune); text-shadow: 0 0 9px rgba(var(--tune-rgb), .35); }
/* The key is the only thing here that reacts: the tile is a link, but it
   is the key you are pressing. */
.build-key { grid-column: 2; justify-self: start; margin-top: .6rem; color: var(--ink-dim); }
.build-key .key-face { font-size: 11px; padding: 11px 24px; }
.build:active .build-key .key-face { background: linear-gradient(180deg, rgba(255,255,255,.035) 0%, rgba(0,0,0,.2) 52%, rgba(0,0,0,.34) 100%), var(--key-base); box-shadow: inset 0 3px 7px rgba(0,0,0,.7), inset 0 -1px 0 rgba(255,255,255,.05); }
.build-sha { font-family: var(--mono); font-size: .66rem; color: var(--ink-faint); word-break: break-all; grid-column: 1 / -1; }
.build-sha:empty { display: none; }
.download-note { margin-top: 1.4rem; font-size: .9rem; color: var(--ink-faint); max-width: none; }
.download-note a { color: var(--ink-dim); }
@media (max-width: 480px) { .build { grid-template-columns: 1fr; } .build-art { grid-row: auto; } .build-key { grid-column: 1; } }

/* ---------- footer ---------- */
footer { padding: 2.5rem 0 3.5rem; color: var(--ink-faint); font-size: .86rem; }
.foot { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 1.5rem 2.5rem; }
.foot-brand { display: flex; gap: 14px; align-items: flex-start; }
.foot-brand img { width: 32px; height: 32px; margin-top: 2px; }
.foot-by { margin: 0 0 .25rem; color: var(--ink-dim); font-size: .95rem; }
.foot-by a { color: var(--ink); text-decoration-color: rgba(240,233,221,.3); }
.foot-note { margin: 0; max-width: 36ch; }
footer nav { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; }
footer nav a { color: var(--ink-dim); text-decoration: none; }
footer nav a:hover { color: var(--tune); }

/* ---------- long-form pages ---------- */
.doc { padding: clamp(2.5rem, 7vw, 4.5rem) 0 4rem; max-width: 48rem; }
.doc h1 { font-size: clamp(1.9rem, 4.5vw, 2.6rem); margin-bottom: .6rem; }
.doc .updated { font-family: var(--stencil); font-size: .52rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 2.2rem; -webkit-font-smoothing: none; }
.doc h2 { font-size: 1.25rem; margin: 2.4rem 0 .7rem; }
.doc p, .doc li { color: var(--ink-dim); max-width: var(--measure); }
.doc .todo { border-left: 2px solid var(--sharp); background: rgba(232,102,60,.06); padding: .9rem 1.15rem; margin: 1.3rem 0; max-width: var(--measure); font-size: .9rem; border-radius: 0 8px 8px 0; }
.doc .todo b { display: block; color: var(--sharp); font-family: var(--stencil); font-size: .52rem; letter-spacing: .1em; text-transform: uppercase; margin-bottom: .4rem; -webkit-font-smoothing: none; }
.licence-group { margin-top: 1.8rem; }
.licence-group h3 { font-family: var(--stencil); font-size: .56rem; letter-spacing: .12em; text-transform: uppercase; color: var(--tune); margin: 0 0 .7rem; font-weight: 400; -webkit-font-smoothing: none; }
.licence-list { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; list-style: none; }
.licence-list li { font-family: var(--mono); font-size: .76rem; color: var(--ink-dim); background: rgba(0,0,0,.3); border: 1px solid var(--line); padding: .3rem .6rem; border-radius: 5px; }
