/* Palette pulled out of the paintings themselves — bone, ink, brick.
   No pure white anywhere, because there is none in the artwork either. */
:root{
  /* panel deliberately dimmer than the paintings' highlights so it never glares */
  --bone:#cbbda3;
  --bone-d:#b3a488;
  --bone-hi:#d8cbb3;
  --ink:#2a2018;
  --ink-2:#6d5c48;
  --brick:#a8452c;
  --edge:rgba(42,32,24,.34);
  --fade:2600ms;
  --hud:clamp(10.5px,1vw,12.5px);
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}

body{
  font-family:Bitter,Georgia,serif;
  background:#0d0f14;
  color:var(--bone);
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
}

/* ---------- background ---------- */

.stage{position:fixed;inset:0;z-index:0;cursor:pointer}

.bg{
  position:absolute;inset:0;
  background-size:cover;background-position:center;
  opacity:0;
  transition:opacity var(--fade) ease-in-out;
  animation:drift 64s ease-in-out infinite alternate;
  will-change:opacity,transform;
}
.bg.on{opacity:1}

@keyframes drift{
  from{transform:scale(1.04) translate3d(-.6%,-.4%,0)}
  to  {transform:scale(1.09) translate3d(.6%,.4%,0)}
}

.grain{
  position:absolute;inset:-120%;
  pointer-events:none;opacity:.16;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='180' height='180' filter='url(%23n)'/></svg>");
  animation:jitter 900ms steps(3) infinite;
}
@keyframes jitter{
  0%{transform:translate3d(0,0,0)}
  33%{transform:translate3d(-1.5%,1%,0)}
  66%{transform:translate3d(1%,-1.5%,0)}
  100%{transform:translate3d(0,0,0)}
}

.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to bottom,rgba(20,14,8,.32) 0,rgba(0,0,0,0) 20%,rgba(0,0,0,0) 60%,rgba(20,14,8,.40) 100%),
    radial-gradient(120% 80% at 50% 50%,rgba(0,0,0,0) 54%,rgba(20,14,8,.26) 100%);
}

/* ---------- hud ---------- */

.hud{
  position:fixed;z-index:3;top:0;left:0;right:0;
  display:flex;justify-content:flex-end;
  align-items:center;gap:16px;
  padding:clamp(14px,2.2vh,26px) clamp(16px,2.6vw,38px);
  padding-top:max(clamp(14px,2.2vh,26px),env(safe-area-inset-top));
  font-size:var(--hud);font-weight:500;
  letter-spacing:.22em;text-transform:lowercase;
  color:rgba(239,227,206,.72);
  text-shadow:0 1px 12px rgba(20,14,8,.65);
  pointer-events:none;
}
.hud a,.hud-right{pointer-events:auto}

.hud-right{display:flex;justify-content:flex-end;gap:clamp(14px,1.8vw,26px)}

.hud a{
  color:rgba(239,227,206,.72);text-decoration:none;
  display:inline-flex;align-items:center;gap:.45em;transition:color .25s;
}
.hud a:hover{color:var(--bone-hi)}
.hud a::after{content:"↗";font-size:.85em;opacity:.7}

/* ---------- hint ---------- */

.hint{
  position:fixed;z-index:3;left:0;right:0;
  bottom:calc(clamp(20px,4.5vh,46px) + 118px);
  text-align:center;
  font-size:11px;letter-spacing:.28em;text-transform:lowercase;
  color:rgba(239,227,206,.5);
  text-shadow:0 1px 10px rgba(20,14,8,.7);
  pointer-events:none;
  transition:opacity 1.4s ease;
}
.hint.gone{opacity:0}

/* ---------- the radio ---------- */

.radio{
  position:fixed;z-index:4;
  left:50%;transform:translateX(-50%);
  bottom:max(clamp(20px,4.5vh,46px),env(safe-area-inset-bottom));
  width:min(400px,calc(100vw - 28px));
  display:grid;grid-template-columns:auto 1fr auto;
  align-items:center;gap:10px;
  padding:8px 11px;
  border-radius:8px;
  background:
    linear-gradient(178deg,var(--bone-hi) 0,var(--bone) 30%,var(--bone-d) 100%);
  border:1px solid var(--edge);
  color:var(--ink);
  box-shadow:
    0 1px 0 rgba(255,255,255,.26) inset,
    0 -1px 0 rgba(42,32,24,.12) inset,
    0 14px 30px rgba(20,14,8,.38),
    0 2px 5px rgba(20,14,8,.24);
}

/* album art, warmed and put behind a speaker grille so it reads as part of the set */
.sleeve{
  position:relative;
  width:34px;aspect-ratio:1;
  border-radius:4px;
  background:var(--bone-d) center/cover;
  border:1px solid var(--edge);
  box-shadow:0 1px 2px rgba(42,32,24,.28) inset;
  /* pushed hard toward the artwork's palette so a busy YouTube thumbnail
     reads as a sleeve behind a speaker grille, not as a screenshot */
  filter:sepia(.62) saturate(.7) contrast(.94) brightness(.94) blur(.3px);
  flex:none;overflow:hidden;
}
.grille{
  position:absolute;inset:0;
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(42,32,24,.46) 0 1px,
      rgba(251,244,230,.10) 1px 3px),
    radial-gradient(120% 120% at 50% 40%,rgba(0,0,0,0) 40%,rgba(42,32,24,.34) 100%);
  opacity:.9;
}
.radio[data-state="playing"] .grille{animation:hum 2.6s ease-in-out infinite}
@keyframes hum{0%,100%{opacity:.7}50%{opacity:.44}}

.face{min-width:0}

/* Fixed height and centre alignment, not baseline: Devanagari and Latin have
   different ascent/descent, so a script switch would otherwise resize the panel
   mid-track. Mukta is in the stack so Nepali titles use a known font instead of
   whatever the system picks. */
.track{display:flex;align-items:center;gap:.55em;min-width:0;height:17px}
.title{
  font-family:Bitter,Mukta,Georgia,serif;
  font-size:12px;font-weight:600;line-height:17px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* status line only ("press play", errors) — never the YouTube channel */
.artist{
  font-family:Bitter,Mukta,Georgia,serif;
  font-size:10px;font-weight:400;line-height:17px;color:var(--ink-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:none;max-width:50%;
}
.artist:empty{display:none}

/* progress as a tuning scale, not a Spotify bar */
.dial{
  position:relative;margin-top:6px;height:13px;cursor:pointer;
  border-top:1px solid rgba(42,32,24,.30);
}
.dial:focus-visible{outline:2px solid var(--brick);outline-offset:3px;border-radius:2px}
.ticks{
  position:absolute;inset:0 0 auto 0;height:7px;
  background:repeating-linear-gradient(
    to right,
    rgba(42,32,24,.42) 0 1px,
    transparent 1px 9px);
  opacity:.65;
}
.needle{
  position:absolute;top:-4px;bottom:2px;left:0;width:2px;
  background:var(--brick);
  box-shadow:0 0 5px rgba(168,69,44,.55);
  transition:left .28s linear;
}
.needle::before{
  content:"";position:absolute;top:-3px;left:-3px;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid var(--brick);
}

.readout{
  display:flex;justify-content:space-between;align-items:center;gap:8px;
  margin-top:2px;
  font-size:8.5px;letter-spacing:.14em;
  color:var(--ink-2);font-variant-numeric:tabular-nums;
}

/* ---------- controls ---------- */

.knobs{display:flex;align-items:center;gap:3px}

.ctl{
  appearance:none;border:0;background:none;cursor:pointer;
  color:var(--ink);
  display:grid;place-items:center;
  width:22px;height:22px;border-radius:50%;
  opacity:.62;transition:opacity .2s,transform .18s;
}
.ctl:hover{opacity:1}
.ctl:active{transform:scale(.9)}
.ctl:focus-visible{outline:2px solid var(--brick);outline-offset:2px}
.ctl svg{width:13px;height:13px;fill:currentColor;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}

/* ---------- volume ---------- */

.vol{display:flex;align-items:center;gap:3px;margin-left:3px}

.mute svg{width:14px;height:14px}
.i-muted{display:none}
.radio[data-muted="1"] .i-loud{display:none}
.radio[data-muted="1"] .i-muted{display:block}
.radio[data-muted="1"] .mute{color:var(--brick);opacity:.9}

/* a slim slide control, in keeping with the rest of the panel */
.slider{
  appearance:none;-webkit-appearance:none;
  width:46px;height:14px;background:none;cursor:pointer;
}
.slider:focus-visible{outline:2px solid var(--brick);outline-offset:2px;border-radius:3px}

.slider::-webkit-slider-runnable-track{
  height:3px;border-radius:2px;
  background:rgba(42,32,24,.30);
}
.slider::-webkit-slider-thumb{
  appearance:none;-webkit-appearance:none;
  width:9px;height:9px;border-radius:50%;margin-top:-3px;
  background:var(--brick);
  border:1px solid rgba(42,32,24,.35);
  box-shadow:0 1px 2px rgba(20,14,8,.3);
}
.slider::-moz-range-track{
  height:3px;border-radius:2px;background:rgba(42,32,24,.30);
}
.slider::-moz-range-thumb{
  width:9px;height:9px;border-radius:50%;
  background:var(--brick);border:1px solid rgba(42,32,24,.35);
}
.radio[data-muted="1"] .slider{opacity:.4}

.play{
  width:30px;height:30px;
  background:radial-gradient(120% 120% at 34% 26%,#c4573a 0,var(--brick) 58%,#8d3823 100%);
  color:var(--bone-hi);opacity:1;
  border:1px solid rgba(42,32,24,.34);
  box-shadow:
    0 1px 0 rgba(255,255,255,.32) inset,
    0 2px 7px rgba(20,14,8,.34);
}
.play:hover{transform:scale(1.05)}
.play svg{width:15px;height:15px;stroke:none}

.i-pause,.spinner{display:none}
.radio[data-state="playing"] .i-play{display:none}
.radio[data-state="playing"] .i-pause{display:block}
.radio[data-state="loading"] .i-play,
.radio[data-state="loading"] .i-pause{display:none}
.radio[data-state="loading"] .spinner{display:block}

.spinner{
  width:14px;height:14px;border-radius:50%;
  border:2px solid rgba(251,244,230,.3);
  border-top-color:var(--bone-hi);
  animation:spin .7s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}

.radio[data-state="error"] .artist{color:var(--brick);max-width:none}

/* YouTube throttles or refuses playback for players that are zero-size or parked
   off-screen, so this stays in the viewport at a real size — just behind the
   artwork, effectively invisible, and not clickable. */
.yt-host{
  position:fixed;left:0;bottom:0;
  width:200px;height:200px;
  opacity:.01;
  pointer-events:none;
  z-index:1;   /* not -1: behind the root background counts as unrendered and gets throttled */
}

/* ---------- responsive ---------- */

@media (max-width:640px){
  .hud{gap:10px}
  .hint{bottom:calc(clamp(20px,4.5vh,46px) + 132px)}
  .radio{
    grid-template-columns:auto 1fr;
    row-gap:9px;padding:11px 13px;
  }
  .knobs{grid-column:1 / -1;justify-content:center;gap:8px}
  .vol{margin-left:8px}
  .slider{width:56px}
  .track{flex-direction:column;align-items:flex-start;gap:0}
  .artist{max-width:100%}
}

@media (prefers-reduced-motion:reduce){
  .bg,.grain,.grille,.spinner{animation:none!important}
  .bg{transition-duration:600ms}
}
