/* The blind A/B rig's SKIN — shared, because the overlay reader needs it.

   This lived in /listen/'s own <head> until 2026-09-12. The reader lifts a resource page's
   <main> into the home page, and a <style> in the head is outside <main>: the decks arrived
   with their markup and their JS (assets/ab-rigs.js, extracted the same day for exactly this
   reason) and NONE of their styling. Andrea saw the result and asked "does it seem fixed to
   you??" — measured in the panel against the standalone page: .ab-play 16x21 wearing default
   button chrome instead of a 40x40 dark circle, its play triangle collapsed to 0x0, and
   .ab-vote's heart blown up to 101x101, because an <svg> carrying only a viewBox has no
   intrinsic size until CSS gives it one. That is the THIRD thing the reader strips, after the
   scripts and everything outside </main>.

   ONE SELECTOR IS SCOPED AND THE REST ARE NOT. `.ab-nohost` exists on the home page too with
   its own padding and border, so this file's copy is written `.ab-rig .ab-nohost` — the home
   page's notice is not inside a rig and keeps its own skin. Nothing else collides: of the
   classes the home page carries, only `.ab-play.ab-loading` / `.ab-btn.ab-loading` appear
   below, and that rule is character-identical to the home page's own.

   Loaded by BOTH /listen/ and the home page, like assets/ab-rigs.js beside it. Every var()
   resolves against the tokens the .ab-rig root re-points onto the host page's palette, so the
   rig wears whichever page it lands in.
*/
/* ============================================================
   BLIND A/B RIG — grafted from prototype 03 (the swan test).
   EVERY 03 selector is prefixed `ab-` because three of them collide with
   01's skin and would ship broken:
     .reveal  01 = opacity:0 scroll-in   · 03 = max-height:0 accordion
     .player  01 = A/B card              · 03 = transport row
     .mono    01 = bordered brass pill   · 03 = uppercase mono label
   The rule bodies are 03's, unchanged — they wear 01's palette via the token
   re-point on the rig root below.
   ============================================================ */
.ab-rig{
  --sig:       var(--brass);
  --sig-dim:   var(--brass-deep);
  --sig-glow:  rgba(217,164,65,.16);
  --amber:     var(--brass-hi);
  --amber-dim: var(--brass-deep);
  --bg:        var(--stage);
  --bg-2:      var(--stage-2);
  --panel:     var(--stage-3);
  --panel-2:   var(--stage-2);
  --line:      var(--hair-2);
  --line-soft: var(--hair);
  --ink-2:     var(--ink-soft);
  --ink-3:     var(--ink-faint);
  --ink-4:     var(--ink-faint);
  --mono:      ui-monospace,SFMono-Regular,Menlo,monospace;
}
.ab-rig{margin-top:28px;border:1px solid var(--line);border-radius:6px;
  background:linear-gradient(180deg,var(--panel),var(--bg-2));
  box-shadow:0 40px 90px -50px #000, inset 0 1px 0 rgba(255,255,255,.02);
  overflow:hidden}
.ab-rig-head{display:flex;align-items:center;justify-content:space-between;
  padding:14px 22px;border-bottom:1px solid var(--line-soft);
  background:var(--bg-2)}
.ab-mono{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase}
.ab-rig-head .ab-mono{color:var(--ink-3)}
.ab-rig-head .ab-livedot{display:flex;align-items:center;gap:8px;color:var(--ink-3)}
.ab-rig-head .ab-livedot i{width:6px;height:6px;border-radius:50%;background:var(--amber);
  box-shadow:0 0 8px var(--amber);animation:pulse 2.4s infinite;font-style:normal}
@media(max-width:640px){.ab-rig-head{flex-wrap:wrap;gap:10px}}

.ab-decks{display:grid;grid-template-columns:1fr 48px 1fr}
@media(max-width:760px){.ab-decks{grid-template-columns:1fr}}

.ab-deck{padding:18px 16px 16px;position:relative}
.ab-deck:first-child{border-right:1px solid var(--line-soft)}
@media(max-width:760px){
  .ab-deck:first-child{border-right:0;border-bottom:1px solid var(--line-soft)}
}
.ab-deck-id{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.ab-deck-id .ab-tag{font-family:var(--mono);font-size:13px;letter-spacing:.28em;
  color:var(--ink-2);border:1px solid var(--line);padding:4px 12px;border-radius:2px}
.ab-deck-id .ab-meta{font-family:var(--mono);font-size:10px;letter-spacing:.14em;color:var(--ink-4)}

/* play control */
.ab-player{display:flex;align-items:center;gap:12px}
/* PLAY IS THE PRIMARY CONTROL. Measured on production 2026-09-15: the vote button was
   13.1x the play button's AREA on this page at desktop width (500x42 against 40x40), and
   the thing you are meant to press first was the smallest target in the deck. Andrea:
   "the buttons to vote are deceiving: lots of times I click on them instead of play." */
.ab-play{flex:0 0 auto;width:72px;height:72px;border-radius:50%;cursor:pointer;
  border:1px solid var(--line);background:var(--panel-2);
  display:grid;place-items:center;transition:.2s;position:relative}
.ab-play:hover{border-color:var(--sig-dim);box-shadow:0 0 0 6px var(--sig-glow)}
/* 40px reads fine under a pointer; a thumb needs 44+. Same floor as the home page. */
@media(max-width:760px){.ab-play{width:64px;height:64px}.ab-play svg{width:24px;height:24px}}
.ab-play svg{width:26px;height:26px;fill:var(--sig)}
.ab-play.ab-playing{border-color:var(--sig);box-shadow:0 0 0 6px var(--sig-glow)}
/* Between the click and the first audible sample there is a real wait: preload="none"
   means nothing is fetched until then — measured 603 ms on a fast link, 2.8 s on a slow
   one. Silence with no feedback is what reads as unresponsive, so the control says it is
   working. No new visual language: the existing button, dimmed. */
.ab-play.ab-loading,.ab-btn.ab-loading,button.ab-loading{opacity:.55;cursor:progress}
.ab-scope{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:12px}
.ab-scope .ab-bar{flex:1 1 auto;min-width:0}
/* Progress, and nothing else. What sat here was a "waveform" drawn from a seeded
   pseudo-random generator — it was never derived from the audio, so it told the ear
   nothing and told the eye something untrue. A blind test is the last place for a
   decorative shape that reads as evidence. Both decks get the same bar. */
.ab-bar{height:8px;border-radius:999px;background:var(--panel-2);
  border:1px solid var(--line-soft);overflow:hidden}
.ab-bar i{display:block;height:100%;width:0;background:var(--sig);border-radius:999px}
/* Position, which the waveform never actually gave — it was a fixed drawing. */
.ab-time{flex:0 0 auto;min-width:40px;text-align:right;font-family:var(--mono);
  font-size:11px;letter-spacing:.06em;color:var(--ink-4)}

/* session score — written by the rigs as votes land, hidden until the first one */
.ab-score{margin:26px auto 0;max-width:720px;text-align:center;font-size:.95rem;
  color:var(--ink-soft);text-wrap:pretty}
.ab-score[hidden]{display:none}
/* NB page-level tokens only: --sig, --mono and --ink-4 are declared on .ab-rig,
   and this line sits outside every rig — they resolve to nothing here. */
.ab-score b{color:var(--brass-hi);letter-spacing:.02em}
.ab-score .ab-score-note{display:block;margin-top:6px;font-size:.8rem;color:var(--ink-faint)}

.ab-deck-foot{margin-top:14px}
/* A static preview has no /api/ab-audio, so every deck's <source> 404s and the buttons do
   nothing. Say so instead of showing a dead control — the same rule as the home page. */
.ab-rig .ab-nohost{display:none;margin:0;padding:12px 16px;border-top:1px solid var(--line-soft);
  color:var(--ink-3);font-size:.86rem;text-align:center}
.ab-rig .ab-nohost a{color:var(--sig)}
[data-ab-audio="unavailable"] .ab-nohost{display:block}
[data-ab-audio="unavailable"] .ab-player,
[data-ab-audio="unavailable"] .ab-deck-foot{display:none}
/* VOTE IS A SECONDARY ACTION and comes AFTER listening: narrower, quieter, and disabled
   until both takes have been played once. It was enabled from page load, so a blind test
   could be voted on without either take being heard — a trap for the visitor and bad data
   for the test. */
.ab-vote{width:auto;min-width:62%;margin:0 auto;display:flex;align-items:center;
  justify-content:center;gap:8px;cursor:pointer;
  padding:9px 14px;border:1px solid var(--line);background:transparent;
  border-radius:3px;font-family:var(--mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);transition:.2s}
.ab-vote:disabled{opacity:.42;cursor:not-allowed}
.ab-vote svg{width:13px;height:13px}
.ab-vote-hint{margin:8px 0 0;text-align:center;font-family:var(--mono);font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-4)}
.ab-vote-hint[hidden]{display:none}
/* The listening advice, above the players on every rig. Andrea: "too low or too hot
   won't help catching the nuances." */
.ab-volume{display:flex;align-items:center;justify-content:center;gap:8px;
  margin:0 0 14px;font-size:12px;color:var(--ink-3);text-align:center}
.ab-volume svg{width:15px;height:15px;flex:0 0 auto;stroke:currentColor;fill:none}
.ab-vote:hover:not(:disabled){border-color:var(--sig-dim);color:var(--ink);background:var(--panel)}
.ab-vote:disabled{cursor:default;opacity:.9}
[data-play]:disabled{cursor:default;opacity:.45}
.ab-deck.ab-voted-here .ab-vote{background:var(--sig);color:var(--bg);border-color:var(--sig)}
.ab-vote svg{width:14px;height:14px;fill:currentColor}

/* center divider */
.ab-vs{display:grid;place-items:center;color:var(--ink-4);position:relative}
.ab-vs .ab-line{position:absolute;top:22px;bottom:22px;width:1px;background:var(--line-soft)}
.ab-vs span{font-family:var(--mono);font-size:11px;letter-spacing:.2em;
  background:var(--bg-2);padding:8px 0;color:var(--ink-3);z-index:1}
@media(max-width:760px){.ab-vs{height:44px}.ab-vs .ab-line{top:50%;bottom:auto;left:22px;right:22px;width:auto;height:1px}}

/* rig footer / tally + reveal trigger */
.ab-rig-foot{border-top:1px solid var(--line-soft);background:var(--bg-2);
  padding:18px 22px;display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
.ab-tally{display:flex;align-items:center;gap:22px;font-family:var(--mono);font-size:11px;
  letter-spacing:.1em;color:var(--ink-3)}
.ab-tally .ab-n{color:var(--ink);font-size:15px;letter-spacing:0}
.ab-tally .ab-none{color:var(--ink-3);font-style:normal}
.ab-reveal-hint{font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--ink-4)}

/* reveal panel (gated behind the vote) */
.ab-reveal{overflow:hidden;max-height:0;transition:max-height .6s cubic-bezier(.4,0,.1,1);
  border-top:1px solid transparent}
.ab-reveal.ab-open{max-height:1200px;border-top-color:var(--line-soft)}
.ab-reveal:focus-visible{outline-offset:-2px}
.ab-reveal-in{padding:26px 24px 28px;background:linear-gradient(180deg,var(--panel),var(--bg-2))}
.ab-reveal-grid{display:grid;grid-template-columns:1fr 1fr;gap:22px}
@media(max-width:640px){.ab-reveal-grid{grid-template-columns:1fr}}
.ab-rv-card{border:1px solid var(--line);border-radius:4px;padding:18px;background:var(--bg-2)}
.ab-rv-card h3{font-family:var(--mono);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  margin:0 0 10px;display:flex;align-items:center;gap:9px}
.ab-rv-card.ab-flat h3{color:var(--amber)}
.ab-rv-card.ab-respiro h3{color:var(--sig)}
.ab-rv-card h3 .ab-b{font-family:var(--serif);font-size:19px;letter-spacing:.02em;
  border:1px solid currentColor;width:26px;height:26px;display:grid;place-items:center;border-radius:3px}
.ab-rv-card p{margin:0;font-size:15px;color:var(--ink-2);line-height:1.55}
.ab-verdict{margin-top:20px;font-family:var(--mono);font-size:12px;letter-spacing:.06em;color:var(--ink-2);
  border-left:2px solid var(--sig);padding-left:14px;line-height:1.7}
.ab-verdict b{color:var(--ink);font-weight:400}
.ab-replay{margin-top:16px;background:none;border:0;cursor:pointer;font-family:var(--mono);font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);border-bottom:1px dashed var(--line);padding:0 0 3px}
.ab-replay:hover{color:var(--sig)}

/* audio-pending degraded state (JS-driven; this rig has NO veil-on-false CSS) */
.ab-demo-missing{margin-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;
  color:var(--amber-dim);display:none;align-items:center;gap:8px;line-height:1.6}
.ab-demo-missing.ab-show{display:flex}
.ab-demo-missing i{width:5px;height:5px;border-radius:50%;background:var(--amber-dim);font-style:normal;flex:0 0 auto}

/* a collapsed gated region must not trap keyboard focus */
#ab-rig [inert]{pointer-events:none}
@media (prefers-reduced-motion:reduce){
  .ab-rig-head .ab-livedot i{animation:none!important}
  .ab-reveal{transition:none!important}
}
