/* ══════════════════════════════════════════════════════════════════════════════
   THE PLAYER. The thing the whole site is actually for.

   ⚠ HOW THIS CAME TO BE WRITTEN. The player's styles lived in site.css, which the v2 homepage
   does not load, so every A/B player in every room rendered as RAW BROWSER DEFAULTS — native
   buttons, stacked unstyled text, and the product name, blurb and a second Buy control repeated
   underneath a room that had already said all three. 20 of its 23 classes were undefined.
   `styledclasses.mjs` could not see it: the player is built by JS at runtime, so none of its
   markup is in the shipped HTML the gate reads.

   THE IDEA. This is an instrument, not a media player. So: the measurement is the picture, the
   controls sit under your hand at the bottom edge, and the numbers are always on screen because
   a number you have to go looking for is a number you do not trust. Nothing here animates for
   decoration — every moving thing is showing you audio.
   ══════════════════════════════════════════════════════════════════════════════ */

.inst{
  position:relative;
  --acc:var(--lamp);
  background:#08080a;
  border:1px solid var(--edge-2);
  outline:none
}
.inst:focus-visible{border-color:var(--acc)}
.inst[data-over="1"]{border-color:var(--acc);background:#0a0d0c}

/* THREE BANDS, which is what makes it read as a panel rather than as a dark rectangle with
   controls loose in it: a status strip you read, a picture you watch, and a deck you touch.
   Every real instrument in this market is built the same way, and it is built that way because
   your eyes and your hands want different parts of the object. */
.inst .inst-stage{position:relative;min-height:min(58vh,540px);
  display:grid;grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0,1fr)}

/* the difference view fills the stage and everything else floats over it */
.inst .inst-view{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:pan-y}

/* ⚠ grid-template-COLUMNS is not optional here. Without it the single implicit column sizes to
   content, and the status strip, the picture and the deck all shrink-wrap to the width of the
   longest label instead of spanning the panel. The panel was 1512px wide with its bands at 614. */
.inst .inst-ui{position:relative;z-index:2;height:100%;display:grid;
  grid-template-rows:auto 1fr auto;grid-template-columns:minmax(0,1fr);
  pointer-events:auto;padding:0;gap:0}

/* ── the top line: what engine is running, and what we measured ───────────────
   Both halves are always present. The left half is a disclosure we are required to make, the
   right half is the measurement that makes the comparison honest, and neither is a hover state. */
.inst .inst-top{display:flex;justify-content:space-between;align-items:baseline;gap:calc(var(--u)*3);
  padding:calc(var(--u)*2) calc(var(--u)*3);border-bottom:1px solid var(--edge-2);
  background:rgba(8,8,10,.6);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  font-family:var(--mark);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dust);flex-wrap:wrap;min-height:38px}
.inst .inst-eng{color:var(--dust)}
.inst .inst-num{color:var(--chalk-2);font-variant-numeric:tabular-nums;text-align:right;
  font-size:13px;letter-spacing:.08em}

/* ── the drop target, which is the whole middle until something is loaded ───── */
.inst .inst-drop{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:calc(var(--u)*3);text-align:center;padding:calc(var(--u)*4);
  transition:opacity .6s var(--slow)}
.inst[data-state="playing"] .inst-drop{opacity:.28}
.inst[data-state="playing"] .inst-drop:hover{opacity:1}
.inst .inst-cue{font-family:var(--display);font-weight:var(--display-weight);letter-spacing:-.025em;
  font-size:clamp(1.1rem,2.1vw,1.65rem);color:var(--chalk);line-height:1.15;max-width:30ch;
  text-wrap:balance}
.inst .inst-files{display:flex;flex-wrap:wrap;gap:calc(var(--u)*1.25);justify-content:center}
.inst .inst-files button{
  background:transparent;border:1px solid var(--edge);color:var(--chalk-2);cursor:pointer;
  font-family:var(--mark);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  padding:calc(var(--u)*1.4) calc(var(--u)*2.25);
  transition:border-color .3s var(--slow),color .3s var(--slow)}
.inst .inst-files button:hover{border-color:var(--acc);color:var(--acc)}
.inst .inst-files button:focus-visible{outline:2px solid var(--acc);outline-offset:2px}

/* ── the controls, at the bottom edge where a hand expects them ───────────────
   A knob is a vertical drag, which is the cross-vendor gesture every plug-in in this market
   uses. It is also focusable and arrow-key driven, because a control you cannot reach from the
   keyboard is a control half our own fleet still gets wrong. */
/* THE DECK. Knobs on the left under your left hand, the comparison on the right under your
   right, the hint beneath both. It has its own ground and its own top rule so it reads as the
   part of the object you are allowed to touch. */
.inst .inst-deck{display:grid;grid-template-columns:auto 1fr;gap:calc(var(--u)*3) calc(var(--u)*5);
  align-items:end;padding:calc(var(--u)*3);
  border-top:1px solid var(--edge-2);background:rgba(8,8,10,.72);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.inst .inst-ctl{position:static;opacity:1;display:flex;gap:calc(var(--u)*3.5);
  flex-wrap:wrap;align-items:flex-end;margin:0}
.inst .inst-deck .inst-right{display:flex;flex-direction:column;align-items:flex-end;
  gap:calc(var(--u)*1.5);justify-self:end}
@media(max-width:720px){
  .inst .inst-deck{grid-template-columns:1fr}
  .inst .inst-deck .inst-right{align-items:flex-start;justify-self:start}
}
.inst .inst-knob{
  --p:0;
  position:relative;width:auto;min-width:62px;cursor:ns-resize;user-select:none;touch-action:none;
  display:flex;flex-direction:column;align-items:center;gap:calc(var(--u)*.9);
  outline:none
}
/* A RING that reads the value, and a CAP that does not pretend to be photographed. The value
   arc is the only lit thing, so the eye goes to the number and not to a fake highlight. */
.inst .inst-knob .dial{
  width:46px;height:46px;border-radius:50%;position:relative;margin:0;
  background:conic-gradient(from 220deg,
    var(--acc) calc(var(--p) * 280deg), rgba(239,236,229,.10) 0 280deg, transparent 280deg)
}
.inst .inst-knob .dial::before{
  content:"";position:absolute;inset:4px;border-radius:50%;
  background:radial-gradient(circle at 50% 34%, #1e1e24, #131317 60%, #0c0c0f);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 2px 7px rgba(0,0,0,.55)
}
/* the index mark rotates with the value; the LIGHT on the dial does not, because a real knob
   turns under a fixed lamp. That is the defect still open on PEAK2's face. */
/* the index mark turns with the value; the shading above does NOT, because a real knob turns
   under a fixed lamp. That is the open defect on PEAK2's face, and it is not repeated here. */
.inst .inst-knob .dial::after{
  content:"";position:absolute;left:50%;top:9px;width:2px;height:10px;background:var(--acc);
  border-radius:1px;transform-origin:50% 14px;
  transform:translateX(-50%) rotate(calc(-140deg + var(--p) * 280deg))
}
.inst .inst-knob .k{font-family:var(--mark);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dust)}
.inst .inst-knob .v{font-family:var(--mark);font-size:13px;color:var(--chalk);font-variant-numeric:tabular-nums}
.inst .inst-knob:focus-visible .dial{outline:2px solid var(--acc);outline-offset:3px}

/* ── THE TRANSPORT. The reason anybody is here. ───────────────────────────────
   Three named states, always visible, always saying what you are hearing in words rather than
   in a symbol. "Bypassed" and "Only the change" are what an engineer would call them. */
.inst .inst-transport{display:flex;gap:1px;background:var(--edge-2);border:1px solid var(--edge);
  width:fit-content;max-width:100%;flex-wrap:wrap}
.inst .inst-ab{
  display:inline-flex;align-items:center;gap:calc(var(--u)*1.25);
  background:#0b0b0d;border:0;cursor:pointer;color:var(--chalk-2);
  font-family:var(--mark);font-size:var(--t-act);letter-spacing:.12em;text-transform:uppercase;
  padding:calc(var(--u)*1.6) calc(var(--u)*2.5);
  transition:color .25s var(--slow),background .25s var(--slow)
}
.inst .inst-ab i{width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.35;
  transition:opacity .25s var(--slow),background .25s var(--slow)}
.inst .inst-ab:hover{color:var(--chalk)}
.inst .inst-ab[aria-pressed="true"]{color:var(--air);background:var(--acc)}
.inst .inst-ab[aria-pressed="true"] i{opacity:1;background:var(--air)}
.inst .inst-ab:focus-visible{outline:2px solid var(--acc);outline-offset:2px;z-index:1}
/* the difference view is a measurement, not a mode of the audio you are buying, so it is set
   apart twice: a dividing rule, and a SQUARE indicator where the heard states carry a dot —
   position alone must never be the only thing telling three identical controls apart */
.inst .inst-ab-d{border-left:1px solid var(--edge)}
.inst .inst-ab-d i{border-radius:0}
/* STOP: the door out. Marked as an edge, not a state — it ends the audition rather than
   choosing within it. */
.inst .inst-ab-stop{color:var(--chalk-2)}
.inst .inst-ab-stop i{border-radius:0;width:7px;height:7px}
.inst .inst-ab-stop[aria-pressed="true"]{background:var(--smoke);color:var(--dust)}
/* until a file is loaded the transport is visibly disarmed and says why on hover */
.inst .inst-transport[data-armed="0"] .inst-ab{opacity:.4;cursor:not-allowed}
@media(max-width:520px){.inst-ab span{display:none}.inst-ab{padding:calc(var(--u)*1.8)}}

.inst .inst-hint{font-family:var(--mark);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dust)}

/* ── the tell: what this is and how to own it ─────────────────────────────────
   Only ever shown where the surrounding page has NOT already said it. In a room it is hidden,
   because the room is already the product page. */
.inst .inst-tell{border-top:1px solid var(--edge-2);padding:calc(var(--u)*4) calc(var(--u)*3)}
.inst .inst-tell-in{display:grid;grid-template-columns:1fr auto;gap:calc(var(--u)*5);align-items:center}
.inst .inst-lane{font-family:var(--mark);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--acc)}
.inst .inst-what h3{margin-top:calc(var(--u)*1.5);
  font-family:var(--display);font-weight:var(--display-weight);letter-spacing:-.03em;
  font-size:clamp(1.4rem,2.6vw,2rem);line-height:1;color:var(--chalk)}
.inst .inst-what p{margin-top:calc(var(--u)*2);color:var(--chalk-2);line-height:1.55;max-width:44ch;font-weight:300}
.inst .inst-what ul{margin-top:calc(var(--u)*2);display:flex;gap:calc(var(--u)*3);flex-wrap:wrap;list-style:none}
.inst .inst-what li{font-family:var(--mark);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--dust)}
.inst .inst-buy{display:flex;flex-direction:column;align-items:flex-end;gap:calc(var(--u)*1.5)}
.inst .inst-cta{background:var(--acc);color:var(--air);white-space:nowrap;
  font-family:var(--mark);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  padding:calc(var(--u)*1.9) calc(var(--u)*3.5);transition:filter .3s var(--slow)}
.inst .inst-cta:hover{filter:brightness(1.12)}
.inst .inst-more{font-family:var(--mark);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--chalk-2);border-bottom:1px solid var(--edge)}
.inst .inst-more:hover{color:var(--acc);border-color:var(--acc)}
.inst .inst-terms{font-family:var(--mark);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dust)}
@media(max-width:760px){
 .inst .inst-tell-in{grid-template-columns:1fr;gap:calc(var(--u)*3)}
 .inst .inst-buy{align-items:flex-start}
}
