:root{
  --ink:#E8EEF4;
  --ink2:rgba(232,238,244,.74);
  --ink3:rgba(232,238,244,.48);
  --ground:#07090C;
  --glass:rgba(10,16,24,.46);
  --glass-2:rgba(201,212,222,.08);
  --line:rgba(201,212,222,.14);
  --line2:rgba(201,212,222,.07);
  --blue:#0A84FF;
  --blue-2:#4DB8E8;
  --silver:#C9D4DE;
  --bad:#FF7A6E;
  --good:#3ADB7A;
  --red-hot:#FF3B4A;   /* red, nudged just off the orange side toward the wash's rose */
  --radius:16px;
  --ease:cubic-bezier(.2,0,0,1);
  --font:Satoshi,ui-sans-serif,system-ui,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,monospace;
  --shadow-border:0 0 0 1px rgba(255,255,255,.08);
  --shadow-border-hover:0 0 0 1px rgba(255,255,255,.16);
  --lx:20%; --ly:20%;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--ground);color:var(--ink)}
html{
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  scroll-behavior:auto;
}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto}
body{
  font-family:var(--font);
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  min-height:100%;
}
img{max-width:100%;display:block}
button,input{font:inherit;color:inherit}
button{cursor:pointer}
a{color:inherit}
:focus-visible{outline:2px solid var(--blue);outline-offset:3px}

.grain{
  pointer-events:none;position:fixed;inset:0;z-index:40;
  background-image:url(../img/noise.png);
  opacity:.09;mix-blend-mode:overlay;
}
.wash{
  position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;
}
.wash-photo,.wash-video{
  position:absolute;inset:-8%;width:116%;height:116%;
  object-fit:cover;
}
.wash-photo{filter:saturate(1.05) contrast(1.04)}
.wash-video{z-index:1;opacity:0;transition:opacity .9s ease}
.wash-video.is-ready{opacity:1}
.wash-caustic{
  position:absolute;inset:-18%;width:136%;height:136%;object-fit:cover;
  mix-blend-mode:screen;opacity:.22;filter:blur(10px) saturate(1.2);
}
.wash-tint{
  position:absolute;inset:0;
  background:
    radial-gradient(90% 70% at 50% 18%, rgba(10,132,255,.22), transparent 58%),
    linear-gradient(180deg, rgba(7,9,12,.12) 0%, rgba(7,9,12,.55) 58%, var(--ground) 100%);
}

.lg{
  background:var(--glass);
  backdrop-filter:blur(22px) saturate(1.55);
  -webkit-backdrop-filter:blur(22px) saturate(1.55);
  box-shadow:var(--shadow-border), 0 18px 40px rgba(0,0,0,.32), inset 0 1px 0 rgba(255,255,255,.16);
  position:relative;
}
.lg::after{
  content:"";pointer-events:none;position:absolute;inset:0;border-radius:inherit;
  background:radial-gradient(120px 80px at var(--lx) var(--ly), rgba(255,255,255,.18), transparent 70%);
  mix-blend-mode:screen;opacity:.85;
}

.nav{
  position:fixed;top:18px;left:50%;transform:translateX(-50%);
  width:min(1200px, calc(100% - 32px));
  z-index:30;display:flex;align-items:center;justify-content:space-between;
  padding:8px 8px 8px 14px;
  border-radius:999px;
}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;padding:4px 8px;min-height:40px}
.brand img{
  width:28px;height:28px;border-radius:8px;
  outline:1px solid rgba(255,255,255,.12);outline-offset:-1px;
}
.brand span{font-weight:700;letter-spacing:.12em;font-size:12px;color:var(--silver)}
.nav-links{display:flex;align-items:center;gap:6px}
.nav-links a{
  text-decoration:none;font-size:13px;font-weight:500;color:var(--ink2);
  padding:10px 14px;border-radius:999px;min-height:40px;display:inline-flex;align-items:center;
  transition-property:color, background-color, box-shadow, scale;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.nav-links a:hover{color:var(--ink);background:var(--glass-2)}
.nav-links a:active{scale:.96}
.nav-links a.nav-cta{
  background:var(--ink);color:#0B1016;font-weight:700;
  box-shadow:0 8px 20px rgba(232,238,244,.12);
}
.nav-links a.nav-cta:hover{background:#fff;color:#0B1016}

.hero{
  position:relative;z-index:1;
  min-height:100svh;display:grid;place-items:center;
  padding:120px 24px 80px;
}
.hero-stage{position:relative;width:min(1180px,100%)}
.hero-copy{position:relative;z-index:2;text-align:center;max-width:720px;margin:0 auto}
/* the wash runs its hot core line straight through the headline; soften just that patch */
.hero-copy::before{
  content:'';position:absolute;inset:-18% -28% -24%;z-index:-1;
  pointer-events:none;border-radius:50%;
  -webkit-backdrop-filter:blur(26px) saturate(.9) brightness(.62);
  backdrop-filter:blur(26px) saturate(.9) brightness(.62);
  -webkit-mask-image:radial-gradient(58% 56% at 50% 48%, #000 0%, #000 42%, rgba(0,0,0,.55) 66%, transparent 82%);
  mask-image:radial-gradient(58% 56% at 50% 48%, #000 0%, #000 42%, rgba(0,0,0,.55) 66%, transparent 82%);
}
@supports not (backdrop-filter:blur(1px)){
  .hero-copy::before{
    -webkit-mask-image:none;mask-image:none;
    background:radial-gradient(58% 56% at 50% 48%,
      rgba(5,7,10,.88) 0%, rgba(5,7,10,.78) 34%, rgba(5,7,10,.44) 62%, rgba(5,7,10,0) 80%);
  }
}
.hero h1{
  margin:0;font-weight:700;letter-spacing:-.035em;line-height:.95;
  font-size:clamp(2.4rem, 6.4vw, 5.4rem);
  text-wrap:balance;
}
/* UPSAMPLED reads as an inspection stamp slapped onto the page. Everything is sized in
   em so the same class works at headline scale and at 11px inside the track cards.
   The red is semi-opaque over a blurred backdrop, so the wash shows through it.
   Elevation is declared once, as a border — no shadow underneath it. */
.tag-up{
  display:inline-block;position:relative;isolation:isolate;
  font-style:normal;font-weight:700;
  font-size:.6em;line-height:1.08;
  text-transform:uppercase;letter-spacing:.015em;
  color:#fff;
  padding:.18em .38em .21em;
  margin:0 .04em 0 .1em;
  /* same ring-as-shadow the glass surfaces use, so elevation is declared once */
  box-shadow:var(--shadow-border);
  border-radius:.34em;
  transform:rotate(-2.2deg) translateY(-.06em);
  transform-origin:50% 60%;
  -webkit-backdrop-filter:blur(9px) saturate(1.15);
  backdrop-filter:blur(9px) saturate(1.15);
  background-color:rgba(150,175,200,.10);
  /* the rising edge is baked into the gradient, so it travels with the fill:
     body, then a hot line at the waterline, then a short glow spilling above it.
     stops are halved on screen because the gradient is 200% of the badge height. */
  background-image:linear-gradient(to top,
    rgba(255,59,74,.72) 48.2%,
    rgba(255,152,162,.98) 49.3%,
    rgba(255,110,124,.86) 50%,
    rgba(255,84,98,.34) 51.6%,
    rgba(255,78,92,0) 54%,
    transparent 100%);
  background-size:100% 200%;
  background-position:0% 100%;   /* resting state is stamped red */
  background-repeat:no-repeat;
}
/* same grain as the page overlay, so the stamp sits in the same air as everything else */
.tag-up::after{
  content:"";position:absolute;inset:0;z-index:-1;
  border-radius:inherit;pointer-events:none;
  background-image:url(../img/noise.png);
  opacity:.22;mix-blend-mode:overlay;
}
/* Only the headline stamp animates. Three things move on one clock — the fill rises,
   the label warms grey to white, and the label softens — so they read as a single act. */
.hero h1 .tag-up{
  font-size:.62em;
  background-position:0% 0%;
  /* the search bar's elevation, drop scaled down to suit a badge rather than a 560px bar */
  box-shadow:var(--shadow-border),
             0 10px 26px rgba(0,0,0,.34),
             inset 0 1px 0 rgba(255,255,255,.16);
  /* near-linear: a fill should rise steadily, not snap then crawl */
  transition:background-position 1.25s cubic-bezier(.5,.08,.42,.96);
}
.hero h1 .tag-up.is-flooded{background-position:0% 100%}
/* the label softens as the red climbs — detail going out of focus, which is what the
   word means. text only, so the ring and the fill edge stay crisp. */
.hero h1 .tag-up > span{
  display:inline-block;
  color:#C2CBD6;
  filter:blur(0px);
  transition:filter 1.25s cubic-bezier(.5,.08,.42,.96);
}
.hero h1 .tag-up.is-flooded > span{filter:blur(1.4px)}

/* Letters light up as the waterline passes them, rather than all warming at once: a
   second gradient clipped to the glyphs, sweeping on the same clock as the fill.
   The handoff is soft on purpose — a hard edge here would have to align pixel-exactly
   with the badge's own waterline, and the two boxes differ by the badge's padding. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .hero h1 .tag-up > span{
    color:transparent;
    background-image:linear-gradient(to top,
      #ffffff 40%, #ffffff 46%, #C2CBD6 58%, #C2CBD6 100%);
    background-size:100% 200%;
    background-position:0% 0%;
    background-repeat:no-repeat;
    -webkit-background-clip:text;
    background-clip:text;
    transition:filter 1.25s cubic-bezier(.5,.08,.42,.96),
               background-position 1.25s cubic-bezier(.5,.08,.42,.96);
  }
  .hero h1 .tag-up.is-flooded > span{background-position:0% 100%}
}
/* card stamps sit on a small dark panel, so they need a touch more presence */
.float-meta .tag-up{
  font-size:9px;padding:.22em .4em .26em;
  margin:0;
  /* no stamp tilt at this scale: beside a text line it reads as misalignment */
  transform:none;
  /* these never animate, so they get a flat fill — the waterline glow would just be a
     stray bright rim at this size */
  background-image:linear-gradient(to top, rgba(255,59,74,.8) 50%, transparent 50%);
}
.lede{
  margin:22px auto 0;max-width:46ch;color:var(--ink2);font-size:16px;line-height:1.55;
  text-wrap:pretty;font-weight:400;
}
.glassbar{
  margin:28px auto 0;width:min(560px,100%);
  display:flex;align-items:center;gap:8px;
  padding:8px 8px 8px 16px;
  border-radius:24px;
}
.glassbar input{
  flex:1;min-width:0;border:0;background:transparent;outline:none;
  padding:12px 0;font-size:15px;color:var(--ink);caret-color:var(--blue);
}
.glassbar input::placeholder{color:var(--ink3)}
.chip{
  background:rgba(255,255,255,.06);
  color:var(--ink2);border-radius:999px;padding:8px 12px;font-size:12px;font-weight:600;
  box-shadow:var(--shadow-border);border:0;min-height:40px;
  transition-property:background-color, color, box-shadow, scale;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.chip:hover{background:rgba(255,255,255,.1);color:var(--ink);box-shadow:var(--shadow-border-hover)}
.chip:active{scale:.96}
.chip.is-on{background:var(--ink);color:#0B1016;box-shadow:none}
.go{
  border:0;border-radius:999px;padding:12px 16px;font-weight:700;font-size:13px;color:#fff;
  background:var(--blue);min-height:40px;
  box-shadow:0 8px 24px rgba(10,132,255,.32);
  transition-property:background-color, scale, box-shadow;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.go:hover{background:#3B9BFF}
.go:active{scale:.96}

.float{
  position:absolute;top:42%;width:min(228px,19vw);perspective:800px;z-index:1;
}
.float.is-left{left:0}
.float.is-right{right:0}
.float-card{
  position:relative;border-radius:16px;overflow:hidden;aspect-ratio:1;
  box-shadow:var(--shadow-border), 0 40px 80px rgba(0,0,0,.55);
  transform-style:preserve-3d;
  will-change:transform;
}
.float.is-left .float-card{transform:rotateY(18deg) rotateZ(-6deg) translateY(12px)}
.float.is-right .float-card{transform:rotateY(-18deg) rotateZ(6deg) translateY(-8px)}
.float-card img{
  width:100%;height:100%;object-fit:cover;
  outline:1px solid rgba(255,255,255,.1);outline-offset:-1px;
}
.float-meta{
  position:absolute;left:10px;right:10px;bottom:10px;
  padding:10px 12px;border-radius:8px;
  background:rgba(8,12,18,.5);
  backdrop-filter:blur(16px);
  box-shadow:var(--shadow-border);
}
.float-meta b{display:block;font-size:13px;font-weight:700;letter-spacing:-.02em}
/* the claimed rate, crossed out in the verdict's red — the text stays legible grey */
.float-meta s{
  text-decoration:line-through;
  text-decoration-color:var(--red-hot);
  text-decoration-thickness:1.5px;
}
/* flex rather than inline-block, so the stamp centres on the kHz text instead of
   hanging off its baseline */
.float-meta span{
  display:flex;align-items:center;gap:6px;
  font-size:11px;color:var(--ink2);margin-top:3px;font-variant-numeric:tabular-nums;
}
.play{
  position:absolute;left:50%;top:50%;width:52px;height:52px;margin:-26px 0 0 -26px;
  border-radius:50%;
  background:rgba(8,12,18,.45);backdrop-filter:blur(10px);
  box-shadow:var(--shadow-border);
  display:grid;place-items:center;
}
.play svg{margin-left:2px}

.stamp{
  margin:36px auto 0;display:flex;gap:28px;justify-content:center;flex-wrap:wrap;
  color:var(--ink3);font-size:12px;font-weight:600;letter-spacing:.04em;
  font-variant-numeric:tabular-nums;
}
.stamp b{color:var(--ink2);font-weight:700}

.section{
  position:relative;z-index:2;
  width:min(1100px, calc(100% - 40px));
  margin:0 auto;
  padding:28px 0 80px;
}
.panel{
  border-radius:16px;overflow:clip;
  background:rgba(8,12,18,.72);
  backdrop-filter:blur(28px) saturate(1.3);
  box-shadow:var(--shadow-border), 0 30px 80px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.08);
}
/* --- #spectrum · cinematic chapters ---------------------------------------
   Five full-viewport moments: enormous type plus one visual. CSS defaults
   describe the STATIC story (chapters stacked, split-view spectrogram with
   every annotation in place) so no-JS readers get the whole argument.
   motion.js adds .is-cine, rewinds everything, and pins. */
#spectrum{position:relative;z-index:2;width:100%}
.ch-stage{
  position:relative;
  display:flex;flex-direction:column;align-items:center;gap:44px;
  padding:110px 24px 90px;
  background:linear-gradient(180deg, rgba(7,9,12,.6), #07090C 12%, #07090C 88%, rgba(7,9,12,.45));
}
.ch-head{text-align:center;max-width:860px}
.ch-head h2{
  margin:0;font-weight:700;letter-spacing:-.04em;line-height:1.02;
  font-size:clamp(2.5rem, 5.6vw, 4.7rem);text-wrap:balance;
}
.ch-head p{
  margin:18px auto 0;max-width:52ch;color:var(--ink2);
  font-size:17px;line-height:1.55;text-wrap:pretty;
}
.ch-head p b{color:var(--ink);font-variant-numeric:tabular-nums}
.c-white{color:#fff}
.c-rose{color:var(--red-hot)}
.c-dim{color:var(--ink3)}
/* the sampling diagram: the math of the promise, drawn instead of asserted.
   In the static story it flows between chapters one and two; in cinema mode it
   sits centred on the still-empty canvas while chapter one holds the frame. */
.ch-wiggle{
  margin:0;display:flex;flex-direction:column;align-items:center;gap:14px;
  width:min(680px,92%);
}
.ch-wiggle canvas{display:block;width:100%;height:auto}
.ch-wiggle figcaption{
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink3);text-align:center;white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.ch-visual{
  display:flex;gap:12px;align-items:stretch;
  width:min(980px,100%);height:420px;
}
.ch-y{
  display:flex;flex-direction:column;justify-content:space-between;
  padding:0 0 0 2px;margin:-5px 0;text-align:right;min-width:34px;
  font-family:var(--mono);font-size:10px;color:var(--ink3);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
.ch-frame{
  position:relative;flex:1;margin:0;min-width:0;
  border-radius:12px;overflow:hidden;
  background:#050D1B;
  box-shadow:var(--shadow-border), 0 40px 90px rgba(0,0,0,.5);
}
.ch-frame canvas{position:absolute;inset:0;width:100%;height:100%}
#cv-real{z-index:1}
#cv-fake{z-index:2;clip-path:inset(0% 50% 0% 0%)} /* static default: split view */
.ch-ceilline{
  position:absolute;top:0;left:0;right:0;height:2px;z-index:3;
  background:linear-gradient(90deg, rgba(232,238,244,.7), rgba(232,238,244,.22));
  transform-origin:0 50%;
}
.ch-ceillab{
  position:absolute;top:9px;right:12px;z-index:3;
  font-family:var(--mono);font-size:10px;letter-spacing:.06em;color:rgba(201,212,222,.7);
}
.ch-playhead{
  position:absolute;top:0;bottom:0;left:0;width:2px;z-index:4;opacity:0;
  background:linear-gradient(180deg, rgba(232,238,244,.9), rgba(232,238,244,.06));
  pointer-events:none;
}
/* warm-up cues for chapter one: a faint radar-style sweep, and the ghost of
   coming energy idling at the floor — the instrument is on, mic open, before
   any disc is read. Hidden in the static story (opacity 0 defaults). */
.ch-scan{
  position:absolute;top:0;bottom:0;left:-14%;width:14%;z-index:2;opacity:0;
  background:linear-gradient(90deg, transparent, rgba(201,212,222,.08) 55%, rgba(232,238,244,.26));
  pointer-events:none;
}
.ch-floor{
  position:absolute;left:0;right:0;bottom:0;height:8%;z-index:1;opacity:0;
  background:linear-gradient(180deg, transparent, rgba(38,158,116,.4));
  pointer-events:none;
}
/* the guilt line — dashed rose, sitting exactly at 24.8 of 48 kHz */
.ch-cut{
  position:absolute;left:0;top:48.33%;width:50%;z-index:3;
  border-top:1px dashed rgba(255,59,74,.9);
  transform-origin:0 50%;pointer-events:none;
}
.ch-cutlab{
  position:absolute;left:12px;top:calc(48.33% - 24px);z-index:3;white-space:nowrap;
  font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:#FF8A93;pointer-events:none;
}
.ch-empty{
  /* dead centre of the silent region (top of canvas to the 48.33% cut line) */
  position:absolute;left:25%;top:24.17%;z-index:3;translate:-50% -50%;
  opacity:0; /* static end-state: the stamp has replaced it */
  font-family:var(--mono);font-size:11px;letter-spacing:.3em;text-transform:uppercase;
  color:rgba(201,212,222,.5);white-space:nowrap;pointer-events:none;
}
.ch-divider{
  position:absolute;left:50%;top:0;bottom:0;width:1px;z-index:4;
  background:rgba(232,238,244,.38);pointer-events:none;
}
.ch-chip{
  position:absolute;top:10px;z-index:4;padding:5px 9px;border-radius:6px;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink2);background:rgba(8,12,18,.72);box-shadow:var(--shadow-border);
  pointer-events:none;white-space:nowrap;
}
.ch-chip-real{left:10px;display:none}
.ch-chip-fake{left:10px;display:none}
.ch-chipL{left:10px}
.ch-chipR{left:calc(50% + 10px)}
.is-cine .ch-chip-real,.is-cine .ch-chip-fake{display:block}
.ch-readout{
  position:absolute;left:10px;bottom:10px;z-index:4;padding:5px 9px;border-radius:6px;
  font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink2);background:rgba(8,12,18,.72);box-shadow:var(--shadow-border);
  font-variant-numeric:tabular-nums;pointer-events:none;white-space:nowrap;
}
/* the verdict: the brand's stamp, slammed into the silence. A design juror called
   it loud; the client keeps it — the stamp IS the product's voice. */
.ch-flash{
  position:absolute;inset:0;z-index:4;opacity:0;pointer-events:none;
  background:radial-gradient(60% 70% at 25% 40%, rgba(255,59,74,.5), transparent 72%);
}
.ch-stamp{
  /* same centre as the EMPTY label it replaces */
  position:absolute;left:25%;top:24.17%;z-index:5;translate:-50% -50%;
  font-size:76px;line-height:1;pointer-events:none;white-space:nowrap;
}
.ch-stamp .tag-up{box-shadow:var(--shadow-border), 0 18px 46px rgba(0,0,0,.5)}
/* the analogy, kept inside the instrument language: a genuine crop of the
   suspect spectrogram, and the same crop blown up until its blocks show —
   same navy ground, same green energy, framed like every other readout */
.ch-photo{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:22px clamp(24px,4.5vw,60px);width:min(980px,100%);
}
.ph{margin:0;display:flex;flex-direction:column;align-items:center;gap:12px}
.ph canvas{
  display:block;border-radius:12px;background:#050D1B;
  box-shadow:var(--shadow-border);
  outline:1px solid rgba(255,255,255,.12);outline-offset:-1px;
}
.ph-small canvas{width:150px;height:150px}
.ph-big canvas{
  width:min(46svh,430px);height:min(46svh,430px);
  image-rendering:pixelated;
}
.ph figcaption{
  font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink3);white-space:nowrap;
}
.ph-arrow{color:var(--ink3);display:flex;align-items:center;padding-bottom:26px}
.ch-ticks{display:none}
/* cinema mode: one 100vh stage, everything choreographed by the timeline */
.ch-stage.is-cine{
  display:block;height:100svh;padding:0;overflow:hidden;
}
.is-cine .ch-head{
  position:absolute;top:16svh;left:50%;translate:-50% 0;
  width:min(940px,92vw);max-width:none;margin:0;
}
/* deliberate choreography: a quiet opener, one asymmetric beat at full width,
   the centred climax at full scale, then the type steps back so the evidence
   can lead. Same template never runs three frames straight. */
.is-cine .ch-head[data-ch="0"] h2{font-size:clamp(2.1rem,4.2vw,3.4rem)}
.is-cine .ch-head[data-ch="1"]{width:min(980px,90vw);text-align:left;padding-left:46px}
.is-cine .ch-head[data-ch="1"] h2{font-size:clamp(2.8rem,6vw,5.2rem)}
.is-cine .ch-head[data-ch="1"] p{margin-left:0}
.is-cine .ch-head[data-ch="3"]{top:14svh}
.is-cine .ch-head[data-ch="3"] h2{font-size:clamp(2rem,3.9vw,3.2rem)}
.is-cine .ch-visual,
.is-cine .ch-photo{
  position:absolute;top:42svh;left:50%;translate:-50% 0;
  width:min(980px,90vw);height:47svh;margin:0;
}
.is-cine .ch-photo{height:auto;top:38svh}
.is-cine .ch-wiggle{
  position:absolute;top:56svh;left:50%;translate:-50% 0;z-index:3;
  width:min(640px,58vw);
}
.is-cine .ch-ticks{
  display:flex;gap:6px;position:absolute;bottom:3.6svh;left:50%;translate:-50% 0;
  width:220px;
}
.is-cine .ch-ticks i{flex:1;height:2px;border-radius:2px;background:rgba(232,238,244,.16)}

.bar{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:14px 16px;
  box-shadow:inset 0 1px 0 var(--line2), inset 0 -1px 0 var(--line2);
  position:sticky;top:76px;z-index:5;
  background:rgba(9,13,19,.97);backdrop-filter:blur(24px) saturate(1.3);
}
/* while the bar is stuck, rows would otherwise scroll legibly through the
   76px of chrome above it (the floating nav). This shield paints that strip;
   at rest it sits above the panel edge and overflow:clip hides it. */
.bar::before{
  content:'';position:absolute;left:0;right:0;bottom:100%;height:77px;
  background:rgb(9,13,19);
}
.tab{
  background:transparent;color:var(--ink2);
  border-radius:999px;padding:8px 12px;font-size:13px;font-weight:600;border:0;
  box-shadow:var(--shadow-border);min-height:40px;
  transition-property:background-color, color, box-shadow, scale;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.tab .n{font-variant-numeric:tabular-nums;color:var(--ink3);margin-left:6px;font-family:var(--mono);font-size:11px}
.tab.is-on{background:var(--ink);color:#0B1016;box-shadow:none}
.tab.is-on .n{color:#5A6A78}
.tab:hover{box-shadow:var(--shadow-border-hover)}
.tab:active{scale:.96}
.spacer{flex:1}
.find{
  width:min(240px,100%);border-radius:999px;border:0;
  box-shadow:var(--shadow-border);
  background:rgba(255,255,255,.04);padding:9px 14px 9px 36px;outline:none;font-size:14px;min-height:40px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%238A9AAB' stroke-width='1.6'><circle cx='7' cy='7' r='5'/><path d='M11 11l3.2 3.2'/></svg>");
  background-repeat:no-repeat;background-position:12px 50%;
  transition-property:box-shadow;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.find:focus{box-shadow:0 0 0 1px rgba(10,132,255,.55)}
.find::placeholder{color:var(--ink3)}

.cathead{padding:28px 22px 6px;display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.cathead h3{margin:0;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink3);font-weight:700}
.cathead .meta{font-size:13px;color:var(--ink2);font-variant-numeric:tabular-nums}
.cathead .meta b{color:var(--bad)}
.cathead .meta i{font-style:normal;color:var(--good)}
.sectnote{margin:0;padding:0 22px 14px;font-size:13px;line-height:1.5;color:var(--ink3);max-width:66ch;text-wrap:pretty}

/* every row and the axis header share one column template, so the frequency
   strips stack into a single aligned chart and the header labels them once */
/* filtered lists can be one row tall; without reserved height the page gets too
   short to dock the section at the top, and the snap clamps mid-viewport */
#library{--cols:40px minmax(0,1.1fr) minmax(200px,1fr) 84px 100px 24px;min-height:calc(100svh - 76px)}

/* the reading surface: the wash stays a frame around the panel, not a ground
   under the rows — near-solid so the strips are read against flat dark */
#library .panel{background:rgba(8,12,18,.96)}

/* the axis: the strip column labelled once per category — a 0–50 kHz scale
   with the judge line (CD wall, or the SACD vote line) named on it.
   It sticks directly beneath the stuck tab/search bar (JS measures the bar
   and sets --stuck), so the line's name and the kHz unit stay on screen
   wherever the reader is in the list. */
/* stuck axis floats over rows while pinned; without this it eats their clicks */
.axis{pointer-events:none;
  display:grid;grid-template-columns:var(--cols);gap:14px;align-items:end;
  padding:18px 22px 7px;
  box-shadow:inset 0 -1px 0 var(--line);
  position:sticky;top:var(--stuck,144px);z-index:4;
  background:rgba(9,13,19,.97);backdrop-filter:blur(24px) saturate(1.3);
}
.axis-hint{grid-column:1/3}
.axis-hint,.axis-unit,.axis-verdict{
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink3);white-space:nowrap;
}
.axis-unit{text-align:right}
.axis-plot{position:relative;height:26px}
.axis-plot > span{
  position:absolute;bottom:0;transform:translateX(-50%);
  font-family:var(--mono);font-size:9px;color:var(--ink3);font-variant-numeric:tabular-nums;
}
.axis-plot > span:first-of-type{transform:none}
.axis-plot > span:last-of-type{transform:translateX(-100%)}
.axis-ref{position:absolute;bottom:-1px;height:8px;border-left:1px dashed rgba(201,212,222,.6)}
.axis-reflab{
  position:absolute;top:0;transform:translateX(-50%);
  font-family:var(--mono);font-size:9px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--silver);white-space:nowrap;
}

.row{box-shadow:inset 0 1px 0 var(--line2)}
/* the summary IS the row grid: display:contents left it boxless, so clicks in the
   gaps between columns fell through to the details element and did nothing */
.row-sum{
  display:grid;grid-template-columns:var(--cols);
  gap:0 14px;align-items:center;padding:9px 22px;
  transition-property:background-color;
  transition-duration:150ms;transition-timing-function:var(--ease);
}
.row-sum:hover{background:rgba(255,255,255,.045)}
.art{
  position:relative;width:40px;height:40px;border-radius:8px;overflow:hidden;
}
.art img{
  width:100%;height:100%;object-fit:cover;
  outline:1px solid rgba(255,255,255,.1);outline-offset:-1px;
}
/* the resolved hover: the cover reveals the expand affordance, the chevron
   resolves into a button — the row tells you it opens before you commit */
.art-peek{
  position:absolute;inset:0;display:grid;place-items:center;
  background:rgba(5,9,15,.62);color:var(--ink);
  opacity:0;transition-property:opacity;transition-duration:150ms;transition-timing-function:var(--ease);
}
.row:hover .art-peek,.row[open] .art-peek{opacity:1}
.row[open] .art-peek svg{transform:rotate(180deg)}
.who{min-width:0}
.who b{display:block;font-size:14px;letter-spacing:-.01em;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who span{display:block;margin-top:2px;font-size:12px;color:var(--ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* the visual column: a 0–50 kHz slice of this disc. Spectral energy runs from
   the left and stops at the cap — the disc's actual ceiling. The faint lit
   region behind it is what the format promises; the dashed line is the judge. */
.plot{display:flex;flex-direction:column;gap:5px;min-width:0}
.strip{
  position:relative;height:14px;border-radius:4px;
  background:#050D1B;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07);
}
.strip-promise{
  position:absolute;top:1px;bottom:1px;left:1px;border-radius:3px 0 0 3px;
  background:rgba(160,190,220,.05);
  border-right:1px solid rgba(201,212,222,.3);
}
.strip-fill{
  position:absolute;top:1px;bottom:1px;left:1px;border-radius:3px 0 0 3px;
  background:linear-gradient(90deg,
    hsl(58,88%,52%) 0%,
    hsl(84,80%,44%) 26%,
    hsl(112,72%,33%) 55%,
    hsl(138,66%,21%) 82%,
    hsl(152,64%,13%) 100%);
}
/* the stop-tick is one neutral colour on every row: the verdict is carried by
   the pill and by the bar's position against the dashed line, nothing else */
.strip-cap{
  position:absolute;top:-3px;bottom:-3px;width:2px;border-radius:1px;margin-left:-1px;
  background:var(--silver);box-shadow:0 0 6px rgba(201,212,222,.35);
}
.strip-ref{
  position:absolute;top:-4px;bottom:-4px;width:0;
  border-left:1px dashed rgba(201,212,222,.5);
}
.khz{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:13px;text-align:right;color:var(--ink2)}
.tag{
  justify-self:end;font-size:10px;font-weight:700;letter-spacing:.06em;
  padding:5px 8px;border-radius:999px;
}
.tag.is-bad{color:var(--bad);background:rgba(255,122,110,.14)}
.tag.is-good{color:var(--good);background:rgba(58,219,122,.12)}
.chev{
  color:var(--ink3);display:grid;place-items:center;width:28px;height:28px;border-radius:999px;
  transition-property:transform, background-color, color, box-shadow;
  transition-duration:200ms;transition-timing-function:var(--ease);
}
.row:hover .chev{
  color:var(--ink);background:rgba(255,255,255,.09);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14);
}
.row[open] .chev{transform:rotate(180deg)}
.row-sum{list-style:none;cursor:pointer}
.row-sum::-webkit-details-marker{display:none}
/* the drawer eases open: block-size 0 -> auto (interpolate-size makes auto
   animatable), content kept clipped while it grows. Browsers without support
   fall back to the instant open they had before. */
#library{interpolate-size:allow-keywords}
.row::details-content{
  block-size:0;overflow-y:clip;
  transition:block-size .42s var(--ease), content-visibility .42s allow-discrete;
}
.row[open]::details-content{block-size:auto}
.card{
  margin:16px 22px 20px;padding:16px 18px;border-radius:14px;
  transition:opacity .34s var(--ease) .08s, translate .34s var(--ease) .08s;
  background:rgba(255,255,255,.04);
  box-shadow:var(--shadow-border);
  cursor:auto;
}
.card p{margin:0 0 14px;color:var(--ink2);font-size:14px;max-width:70ch;text-wrap:pretty}
.spec{margin:0 0 14px;display:flex;flex-direction:column;gap:8px}
.spec-cv{
  display:block;width:100%;height:200px;border-radius:12px;
  background:#050D1B;
  box-shadow:var(--shadow-border);
}
.spec figcaption{font-size:11px;line-height:1.5;color:var(--ink3);max-width:70ch}
.facts{display:flex;flex-wrap:wrap;gap:14px 30px;margin-bottom:14px}
.fact .k{display:block;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);white-space:nowrap}
.fact .v{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:14px;white-space:nowrap}
.streams{width:100%;border-collapse:collapse;font-size:13px}
.streams th{text-align:left;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink3);font-weight:600;padding:6px 8px 8px 0}
.streams td{padding:7px 8px 7px 0;box-shadow:inset 0 1px 0 var(--line2)}
.streams .tnum{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:12px}
.card .prov{margin:12px 0 0;font-size:11px;color:var(--ink3)}
.card .card-foot{
  margin:12px 0 0;padding-top:12px;
  box-shadow:inset 0 1px 0 var(--line2);
  font-size:13px;color:var(--ink3);
}
.card .card-foot a,.card a{
  color:var(--blue-2);text-decoration:none;display:inline-block;
}
@media (hover:hover){
  .card a:hover{animation:link-blur .35s ease-out}
}
/* borrowed from websiteleads: the link defocuses and snaps back, no underline */
@keyframes link-blur{0%,100%{filter:blur(0)}50%{filter:blur(1.5px)}}
/* first painted frame after opening: the card starts lifted and transparent,
   then settles as the drawer height finishes */
@starting-style{
  .row[open] .card{opacity:0;translate:0 -10px}
}
/* the native clear (x) inside search fields is a control; it should say so */
input[type="search"]::-webkit-search-cancel-button{cursor:pointer}
.zero{display:none;padding:48px 22px;color:var(--ink3);text-align:center}
.zero.is-on{display:block}

@media (max-width: 980px){
  .hero-stage{display:flex;flex-wrap:wrap;justify-content:center;gap:16px}
  .hero-copy{order:-1;width:100%;padding:0 4px}
  .float{position:relative;top:auto;left:auto;right:auto;width:min(168px,44vw)}
  .hero h1{font-size:clamp(1.7rem, 8.2vw, 2.8rem);padding:0 4px}
  .ch-visual{height:320px}
  .ch-stamp{font-size:48px}
  .ch-head p{font-size:15px}
  .ph-big canvas{width:240px;height:240px}
  .ph-small canvas{width:96px;height:96px}
  .is-cine .ch-head{top:14svh}
  .is-cine .ch-visual{top:42svh;height:46svh}
  #library{--cols:40px minmax(0,1fr) 84px 24px}
  .plot,.khz,.axis{display:none}
  .who b,.who span{white-space:normal}
  .row-sum{gap:10px}
  .spec-cv{height:150px}
  .nav-links a:not(.nav-cta){display:none}
}
@media (max-width: 640px){
  .hero{padding:108px 16px 64px}
  .ch-empty{letter-spacing:.16em}
    .find{width:100%}
  .bar{top:68px}
}
