@font-face{
  font-family:'VT323';
  src:url('../assets/fonts/VT323-Regular.ttf') format('truetype');
  font-style:normal;
  font-weight:400;
  font-display:swap;
}

:root{
  --gfr-primary:#68c85f;
  --gfr-highlight:#a7f59a;
  --gfr-bg:#020502;
  --gfr-panel:#061006;
  --gfr-muted:#376f36;
  --gfr-max:720px;
  --gfr-scan:.10;
}
*{box-sizing:border-box}
html,body{margin:0;min-height:100%;background:#000}
body{color:var(--gfr-primary);font-family:'VT323',Consolas,'Courier New',monospace;font-size:18px}
button{font:inherit}

/* The browser canvas stays clean black. CRT treatment belongs to the terminal only. */
.gfr-jukebox{
  width:min(100%,var(--gfr-max));
  min-height:100vh;
  margin:0 auto;
  padding:4px 0 56px;
  position:relative;
  isolation:isolate;
  overflow:hidden;
  background:radial-gradient(circle at 50% 5%,#0b180b 0,#030703 40%,#010201 100%);
}
.gfr-jukebox::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:100;
  pointer-events:none;
  background:repeating-linear-gradient(0deg,rgba(150,255,130,var(--gfr-scan)) 0 1px,transparent 1px 4px);
  mix-blend-mode:screen;
  opacity:.32;
}
.gfr-jukebox::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:99;
  pointer-events:none;
  background:radial-gradient(ellipse at center,transparent 48%,rgba(0,0,0,.42) 100%);
}

.gfr-hero{
  position:relative;
  margin:10px clamp(12px,6vw,46px) 0;
  min-height:505px;
  border:1px solid var(--gfr-muted);
  border-radius:7px;
  padding:18px 18px 16px;
  background:linear-gradient(rgba(7,20,7,.84),rgba(3,8,3,.9)),repeating-linear-gradient(90deg,transparent 0 31px,rgba(93,194,84,.035) 32px);
  box-shadow:inset 0 0 30px rgba(78,179,71,.08),0 0 14px rgba(77,188,68,.08);
  overflow:hidden;
}
.gfr-hero__topline,.gfr-hero__footer{display:flex;justify-content:space-between;gap:14px;font-size:clamp(10px,2.2vw,14px);line-height:1.35;text-shadow:0 0 8px rgba(104,200,95,.45)}
.gfr-hero__code{text-align:right}.gfr-wave{letter-spacing:-.18em}.gfr-signal{font-size:.8em}
.gfr-hero__footer{position:absolute;left:18px;right:18px;bottom:14px;color:var(--gfr-muted);font-size:10px}

.gfr-hero-idle{text-align:center;position:relative}
.gfr-hero-idle-asset{position:absolute;inset:8px 0 30px;display:grid;place-items:center;z-index:3;overflow:hidden}
.gfr-hero-idle-asset[hidden]{display:none}
.gfr-hero-idle-asset img{display:block;width:100%;height:100%;object-fit:contain;filter:saturate(.9) contrast(1.04);opacity:.96}
.gfr-hero-fallback{position:relative}
.gfr-hero-fallback[hidden]{display:none}
.gfr-hero__core{height:200px;display:grid;place-items:center;position:relative;margin-top:14px}
.gfr-radar{position:absolute;width:min(68vw,310px);aspect-ratio:1;border:1px solid rgba(104,200,95,.12);border-radius:50%;background:repeating-radial-gradient(circle,transparent 0 29px,rgba(104,200,95,.07) 30px 31px),linear-gradient(90deg,transparent 49.7%,rgba(104,200,95,.07) 50%,transparent 50.3%),linear-gradient(0deg,transparent 49.7%,rgba(104,200,95,.07) 50%,transparent 50.3%);opacity:.8}
.gfr-mic{font-size:clamp(55px,14vw,90px);font-weight:900;letter-spacing:-.16em;z-index:1;text-shadow:0 0 14px rgba(104,200,95,.4)}
.gfr-radio-waves{position:absolute;left:61%;font-weight:900;font-size:clamp(34px,8vw,58px);letter-spacing:-.25em;text-shadow:0 0 14px rgba(104,200,95,.4)}
.gfr-hero h1{margin:2px 0 -6px;text-align:center;font-size:clamp(52px,14vw,94px);line-height:.92;letter-spacing:-.07em;color:#559b50;text-shadow:1px 0 #163b16,-1px 0 #8ee983,0 0 12px rgba(96,205,87,.22)}
.gfr-radio-title{text-align:center;font-weight:900;font-size:clamp(31px,8vw,54px);letter-spacing:.12em;color:#559b50}
.gfr-library-badge{width:max-content;max-width:100%;margin:11px auto 22px;border:1px solid var(--gfr-muted);padding:7px 14px;border-radius:3px;font-size:clamp(12px,3vw,18px);white-space:nowrap}

/* RC0.2 functionality, re-fitted to the calmer RC0.1 proportions. */
.gfr-hero-playing{padding:42px 0 28px;display:grid;grid-template-columns:minmax(150px,210px) 1fr;gap:20px;align-items:center}
.gfr-hero-playing[hidden]{display:none}
.gfr-hero-back{grid-column:1/-1;justify-self:start;border:1px solid var(--gfr-muted);background:#061006;color:#79cf70;padding:7px 10px;cursor:pointer;font-size:10px;letter-spacing:.07em;border-radius:2px}
.gfr-hero-back:hover,.gfr-hero-back:focus-visible{border-color:var(--gfr-highlight);color:var(--gfr-highlight);outline:none;box-shadow:0 0 8px rgba(167,245,154,.16)}
.gfr-hero-cover{width:100%;aspect-ratio:1;border:1px solid var(--gfr-muted);background:radial-gradient(circle at 50% 40%,#173217,#051005 68%);display:grid;place-items:center;font-size:68px;font-weight:900;color:#62bd59;text-shadow:0 0 17px rgba(104,200,95,.45);position:relative;overflow:hidden;box-shadow:0 0 20px rgba(110,230,100,.08)}
.gfr-hero-cover::after{content:"CAPTURED TRANSMISSION";position:absolute;left:8px;right:8px;bottom:7px;font-size:8px;letter-spacing:.08em;color:#62a85d;text-align:center}
.gfr-hero-cover img{width:100%;height:100%;object-fit:cover;display:block;filter:saturate(.8) contrast(1.05)}
.gfr-hero-frequency{font-size:15px;color:var(--gfr-highlight);margin-bottom:8px}
.gfr-hero-song-title{font-weight:900;font-size:clamp(25px,5vw,40px);line-height:.98;letter-spacing:.035em;color:#7cdb72;text-shadow:0 0 10px rgba(104,200,95,.28);overflow-wrap:anywhere}
.gfr-hero-subtitle{margin-top:10px;font-size:12px;line-height:1.35;color:#64b75e}
.gfr-hero-player{grid-column:1/-1;display:grid;grid-template-columns:34px 1fr auto;gap:9px;align-items:center;margin-top:2px}
.gfr-hero-play{height:31px;border:1px solid var(--gfr-highlight);background:#071207;color:var(--gfr-highlight);cursor:pointer}
.gfr-hero-progress{height:11px;border:1px solid var(--gfr-muted);padding:2px}
.gfr-hero-progress span{display:block;height:100%;width:0;background:var(--gfr-highlight);box-shadow:0 0 9px rgba(167,245,154,.42)}
.gfr-hero-time{font-size:9px;color:var(--gfr-highlight);white-space:nowrap}
.gfr-hero-audio-state{grid-column:1/-1;text-align:center;font-size:8px;letter-spacing:.14em;color:#5da656;margin-top:-3px}
.gfr-hero-audio-state.is-warning{color:#96a45a}

.gfr-intro{padding:20px clamp(16px,7vw,52px) 15px;text-align:center;background:linear-gradient(90deg,transparent,rgba(104,200,95,.04),transparent)}
.gfr-intro h2{margin:0 0 9px;font-size:clamp(16px,4vw,24px);font-weight:700;letter-spacing:.07em;color:var(--gfr-highlight);text-shadow:0 0 9px rgba(104,200,95,.25)}
.gfr-intro p{margin:0 0 12px;font-size:clamp(10px,2.4vw,13px)}
.gfr-signal-meter{height:22px;border:1px solid var(--gfr-primary);padding:2px;display:grid;grid-template-columns:repeat(18,1fr);gap:2px;box-shadow:0 0 8px rgba(104,200,95,.2)}
.gfr-signal-meter span{border:1px solid #479444;background:#0a170a}
.gfr-signal-meter span:nth-child(-n+7){background:#92e985;box-shadow:0 0 6px rgba(146,233,133,.26)}
.gfr-demo-note{margin-top:7px;font-size:9px;color:var(--gfr-muted);letter-spacing:.09em}.gfr-demo-note.is-runtime{color:#82d978}
.gfr-build-version{margin-top:4px;font-size:8px;color:#315f2f;letter-spacing:.08em}

/* RC0.1 card geometry restored: side padding makes the entries feel portrait/terminal-like again. */
.gfr-song-list{display:flex;flex-direction:column;gap:7px;padding:0 clamp(8px,4vw,28px) 8px}
.gfr-card{position:relative;width:100%;min-height:112px;border:1px solid var(--gfr-primary);border-radius:7px;background:linear-gradient(90deg,rgba(7,18,7,.94),rgba(3,9,3,.94));display:grid;grid-template-columns:76px 98px 1fr;gap:11px;align-items:center;padding:9px;cursor:pointer;outline:none;box-shadow:inset 0 0 16px rgba(82,181,75,.05),0 0 7px rgba(82,181,75,.12);transition:border-color .12s ease,box-shadow .12s ease,background .12s ease,transform .06s ease}
.gfr-card:hover{background:linear-gradient(90deg,rgba(9,23,9,.98),rgba(4,12,4,.98));border-color:#80dc77}
.gfr-card:focus-visible{outline:2px solid var(--gfr-highlight);outline-offset:2px}
.gfr-card:active{transform:scale(.997)}
.gfr-card.is-active{border-color:var(--gfr-highlight);background:linear-gradient(90deg,rgba(13,31,13,.98),rgba(5,13,5,.98));box-shadow:inset 0 0 22px rgba(137,239,126,.09),0 0 13px rgba(137,239,126,.28)}
.gfr-cover{width:76px;aspect-ratio:1;border:1px solid var(--gfr-muted);display:grid;place-items:center;position:relative;overflow:hidden;background:radial-gradient(circle at 50% 40%,#173217,#051005 68%);font-size:28px;font-weight:900;color:#4c9a48;text-shadow:0 0 8px rgba(104,200,95,.4)}
.gfr-cover::before{content:"";position:absolute;inset:0;background:repeating-linear-gradient(0deg,transparent 0 4px,rgba(131,225,116,.07) 5px);pointer-events:none;z-index:2}
.gfr-cover::after{content:attr(data-code);position:absolute;left:4px;right:4px;bottom:3px;font-size:7px;text-align:center;color:#6abf63;letter-spacing:.02em;z-index:3}
.gfr-cover img{width:100%;height:100%;object-fit:cover;display:block}
.gfr-frequency{font-size:clamp(11px,2.7vw,15px);font-weight:700;white-space:nowrap}.gfr-active-marker{display:inline-block;width:12px;color:var(--gfr-highlight)}
.gfr-card-main{min-width:0}.gfr-title{font-weight:900;font-size:clamp(18px,4.9vw,31px);letter-spacing:.04em;line-height:1.02;color:#73ce6b;text-shadow:0 0 7px rgba(104,200,95,.22);overflow-wrap:anywhere}.gfr-subtitle{margin-top:8px;font-size:clamp(10px,2.5vw,14px);line-height:1.2;color:#67b961}
.gfr-card.is-active .gfr-title,.gfr-card.is-active .gfr-frequency{color:var(--gfr-highlight)}
.gfr-player{grid-column:2/-1;display:none;grid-template-columns:auto 1fr auto;align-items:center;gap:8px;margin-top:1px}.gfr-card.is-active .gfr-player{display:grid}
.gfr-play{width:30px;height:26px;padding:0;border:1px solid var(--gfr-highlight);background:#081408;color:var(--gfr-highlight);cursor:pointer;border-radius:2px}
.gfr-progress{height:9px;border:1px solid var(--gfr-muted);padding:1px;position:relative}.gfr-progress-fill{display:block;height:100%;width:0;background:var(--gfr-highlight);box-shadow:0 0 7px rgba(167,245,154,.35)}
.gfr-time{font-size:9px;color:var(--gfr-highlight);white-space:nowrap}.gfr-now{position:absolute;right:8px;top:6px;font-size:8px;color:var(--gfr-highlight);letter-spacing:.12em;display:none}.gfr-card.is-active .gfr-now{display:block}
.gfr-audio-badge{font-size:7px;color:#466f43;margin-top:6px;letter-spacing:.08em}.gfr-card.is-active .gfr-audio-badge{color:#6ebc67}
.gfr-error{margin:20px;border:1px solid #985c42;padding:14px;color:#da8e68}.gfr-page-footer{text-align:center;color:var(--gfr-muted);font-size:9px;padding:25px 14px 0;letter-spacing:.08em}

@media(max-width:520px){
  .gfr-hero{min-height:430px}
  .gfr-hero__core{height:165px}
  .gfr-hero-playing{padding-top:32px;grid-template-columns:120px 1fr;gap:12px}
  .gfr-hero-song-title{font-size:23px}.gfr-hero-subtitle{font-size:10px}
  .gfr-hero-player{grid-template-columns:34px 1fr}.gfr-hero-time{grid-column:1/-1;text-align:center}
  .gfr-card{grid-template-columns:68px 84px 1fr;gap:8px;min-height:100px;padding:8px}
  .gfr-cover{width:68px}.gfr-subtitle{margin-top:6px}.gfr-player{grid-column:1/-1;margin-top:5px}.gfr-now{top:4px}
}
@media(max-width:390px){
  .gfr-hero{margin-left:8px;margin-right:8px}
  .gfr-card{grid-template-columns:62px 72px 1fr;padding:7px}.gfr-cover{width:62px}.gfr-frequency{white-space:normal}.gfr-title{font-size:17px}.gfr-subtitle{font-size:9px}
  .gfr-hero-playing{grid-template-columns:102px 1fr}.gfr-hero-song-title{font-size:19px}.gfr-hero-frequency{font-size:12px}.gfr-library-badge{font-size:11px;padding:7px 10px}
}
@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}

/* RC0.7 — living CRT pass -------------------------------------------------- */
:root{
  --gfr-cover-tint-opacity:.36;
  --gfr-grain-opacity:.045;
  --gfr-flicker-opacity:.028;
}

/* Keep every CRT effect inside the terminal surface. */
.gfr-crt-grain,
.gfr-crt-flicker{
  position:absolute;
  inset:0;
  pointer-events:none;
  z-index:98;
}

/* Tiny local texture, shifted only once per second. This avoids a costly
   per-frame Canvas noise renderer while still keeping the phosphor alive. */
.gfr-crt-grain{
  background-image:url('../assets/noise/grain.png');
  background-repeat:repeat;
  background-size:96px 96px;
  opacity:var(--gfr-grain-opacity);
  mix-blend-mode:screen;
  animation:gfr-grain-shift 1s steps(1,end) infinite;
}

/* Rare luminance ticks. The overlay is intentionally tiny; it should be felt,
   not read as a visible blink. */
.gfr-crt-flicker{
  background:rgba(154,255,134,.12);
  opacity:0;
  mix-blend-mode:screen;
  animation:gfr-crt-flicker 7.1s steps(1,end) infinite;
}

@keyframes gfr-grain-shift{
  0%{background-position:0 0}
  20%{background-position:-31px 17px}
  40%{background-position:19px -43px}
  60%{background-position:-57px -11px}
  80%{background-position:43px 37px}
  100%{background-position:0 0}
}

@keyframes gfr-crt-flicker{
  0%,31.9%,32.7%,67.9%,68.4%,100%{opacity:0}
  32.0%{opacity:var(--gfr-flicker-opacity)}
  32.2%{opacity:.010}
  68.0%{opacity:.018}
  68.2%{opacity:var(--gfr-flicker-opacity)}
}

/* Covers remain untouched on disk. The web view first removes source colour,
   then lays the current phosphor colour over luminance with blend-mode:color. */
.gfr-cover img,
.gfr-hero-cover img,
.gfr-hero-idle-asset img{
  filter:grayscale(.88) saturate(.28) contrast(1.08) brightness(1.06);
}

.gfr-cover::before,
.gfr-hero-cover::before,
.gfr-hero-idle-asset::after{
  content:"";
  position:absolute;
  inset:0;
  pointer-events:none;
  background:var(--gfr-primary);
  opacity:var(--gfr-cover-tint-opacity);
  mix-blend-mode:color;
  z-index:2;
}

.gfr-card.is-active .gfr-cover img,
.gfr-hero-cover img{
  filter:grayscale(.84) saturate(.32) contrast(1.10) brightness(1.12);
}
.gfr-card.is-active .gfr-cover::before,
.gfr-hero-cover::before{
  opacity:.43;
}

/* RC0.8 scanlines: the overlay sits ABOVE text, glow and artwork.
   Dark 1px grooves cut through the phosphor while a very faint green edge
   keeps the screen luminous. At 100% browser zoom this maps cleanly to CSS pixels. */
.gfr-jukebox::before{
  background:repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 2px,
    rgba(0,0,0,.30) 2px,
    rgba(0,0,0,.30) 3px,
    rgba(150,255,130,.035) 3px,
    rgba(150,255,130,.035) 4px
  );
  background-size:auto;
  background-repeat:repeat;
  mix-blend-mode:normal;
  opacity:.72;
}

@media(prefers-reduced-motion:reduce){
  .gfr-crt-grain,.gfr-crt-flicker{animation:none!important}
  .gfr-crt-flicker{display:none}
}
.gfr-hero-cover::after{z-index:3}

/* RC0.8 VT323 optical compensation */
.gfr-demo-note,.gfr-build-version,.gfr-audio-badge,.gfr-now,.gfr-page-footer,.gfr-hero-audio-state{letter-spacing:.06em}


/* RC1.2 — conservative phosphor readability pass ------------------------- */
:root{
  --gfr-cover-tint-opacity:.20;
}

/* Preserve the existing palette, but let more original luminance/details through. */
.gfr-cover img,
.gfr-hero-cover img,
.gfr-hero-idle-asset img{
  filter:grayscale(.72) saturate(.42) contrast(1.04) brightness(1.14);
}
.gfr-card.is-active .gfr-cover img,
.gfr-hero-cover img{
  filter:grayscale(.68) saturate(.46) contrast(1.05) brightness(1.18);
}
.gfr-card.is-active .gfr-cover::before,
.gfr-hero-cover::before{
  opacity:.25;
}

/* Compact phosphor glow: bright enough to feel emissive, not so broad that it
   washes away the dark scanline grooves above it. */
.gfr-title,
.gfr-frequency,
.gfr-hero-song-title,
.gfr-hero-frequency,
.gfr-intro h2,
.gfr-library-badge,
.gfr-hero-play,
.gfr-play{
  text-shadow:
    0 0 2px rgba(185,255,170,.55),
    0 0 6px rgba(104,200,95,.28);
}

/* Grooves remain the top-most terminal treatment and therefore cut through
   text, glow and artwork alike. Keep them narrow to preserve readability. */
.gfr-jukebox::before{
  z-index:120;
  background:repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0) 0,
    rgba(0,0,0,0) 2px,
    rgba(0,0,0,.38) 2px,
    rgba(0,0,0,.38) 3px,
    rgba(146,255,130,.025) 3px,
    rgba(146,255,130,.025) 4px
  );
  opacity:.82;
  mix-blend-mode:normal;
}


/* RC1.3 — album metadata + colour recovery + compact phosphor pass -------- */
.gfr-hero-album{
  margin-top:7px;
  font-size:10px;
  line-height:1.2;
  color:#4f944a;
  letter-spacing:.055em;
}
.gfr-card-meta{
  font-size:8px;
  color:#466f43;
  margin-top:6px;
  letter-spacing:.055em;
}
.gfr-card.is-active .gfr-card-meta{color:#67aa61}

/* Keep the source artwork recognisable: mild desaturation, only a whisper of
   phosphor tint, and enough luminance to survive the CRT overlay. */
:root{--gfr-cover-tint-opacity:.10}
.gfr-cover img,
.gfr-hero-cover img{
  filter:grayscale(.30) saturate(.80) contrast(1.03) brightness(1.13);
}
.gfr-hero-idle-asset img{
  filter:grayscale(.12) saturate(.90) contrast(1.03) brightness(1.10);
}
.gfr-card.is-active .gfr-cover img,
.gfr-hero-cover img{
  filter:grayscale(.24) saturate(.86) contrast(1.04) brightness(1.17);
}
.gfr-card.is-active .gfr-cover::before,
.gfr-hero-cover::before{opacity:.14}
.gfr-hero-idle-asset::after{opacity:.06}

/* Tighter glow leaves the VT323 glyph shape visible while the top-most
   scanline overlay still cuts narrow grooves through the illuminated text. */
.gfr-title,
.gfr-frequency,
.gfr-hero-song-title,
.gfr-hero-frequency,
.gfr-intro h2,
.gfr-library-badge,
.gfr-hero-play,
.gfr-play{
  text-shadow:
    0 0 1px rgba(205,255,190,.48),
    0 0 4px rgba(104,200,95,.22);
}
.gfr-jukebox::before{
  opacity:.86;
  background:repeating-linear-gradient(
    to bottom,
    rgba(0,0,0,0) 0,
    rgba(0,0,0,0) 2px,
    rgba(0,0,0,.40) 2px,
    rgba(0,0,0,.40) 3px,
    rgba(146,255,130,.022) 3px,
    rgba(146,255,130,.022) 4px
  );
}


/* RC1.4 — real collection hero + Studio signal cover renderer ------------ */
/* The idle asset is absolutely positioned; give its parent a real box so
   hiding the fallback no longer collapses the hero image to zero height. */
.gfr-hero-idle{min-height:390px}
.gfr-hero-idle-asset{inset:10px 0 18px}
.gfr-hero-idle-asset img{
  filter:none;
  opacity:1;
}
.gfr-hero-idle-asset::after{opacity:.035}

/* display_cover is pre-rendered by the exporter with the same luminance /
   autocontrast / signal-colour method used by Broadcast Studio. Do not apply
   a second grayscale/tint pass in the browser. */
.gfr-cover img,
.gfr-hero-cover img,
.gfr-card.is-active .gfr-cover img{
  filter:none;
  opacity:1;
}
.gfr-cover::before,
.gfr-hero-cover::before,
.gfr-card.is-active .gfr-cover::before{
  opacity:0;
}

/* Wider but much more transparent phosphor halo. The glyph core remains crisp
   while the scanline overlay above the page can still cut visible grooves. */
.gfr-title,
.gfr-frequency,
.gfr-hero-song-title,
.gfr-hero-frequency,
.gfr-intro h2,
.gfr-library-badge,
.gfr-hero-play,
.gfr-play{
  text-shadow:
    0 0 1px rgba(220,255,210,.30),
    0 0 7px rgba(118,220,105,.12),
    0 0 15px rgba(92,190,82,.055);
}

/* RC1.5 — Hero state polish -------------------------------------------------
   Idle: collection art behaves like a dim phosphor background, not a hard
   album card. Playing: the active song gets a little more visual weight. */
.gfr-hero-idle-asset{
  inset:10px 0 18px;
  background:radial-gradient(circle at 50% 42%,rgba(65,145,58,.08),rgba(0,0,0,.30) 68%,rgba(0,0,0,.54));
}
.gfr-hero-idle-asset img{
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center;
  opacity:.38;
  filter:grayscale(1) sepia(1) saturate(3.2) hue-rotate(67deg) brightness(.76) contrast(1.10);
  transform:scale(1.015);
}
.gfr-hero-idle-asset::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:4;
  pointer-events:none;
  background:
    radial-gradient(circle at 50% 43%,rgba(111,215,99,.14),transparent 54%),
    linear-gradient(rgba(2,7,2,.06),rgba(0,0,0,.28));
  opacity:.78;
  mix-blend-mode:screen;
}

/* Give the active transmission more presence once the library hero yields. */
.gfr-hero-playing{
  grid-template-columns:minmax(175px,230px) 1fr;
  gap:22px;
}
.gfr-hero-cover{
  box-shadow:0 0 24px rgba(110,230,100,.10);
}

@media(max-width:520px){
  .gfr-hero-playing{grid-template-columns:135px 1fr;gap:13px}
}
@media(max-width:390px){
  .gfr-hero-playing{grid-template-columns:112px 1fr}
}


/* RC1.6 — Layout tightening ---------------------------------------------- */
/* Idle hero: keep the full artwork inside the green frame. A little air at
   the sides is welcome; this reads more like a terminal panel than a cropped
   album cover. */
.gfr-hero-idle-asset{
  inset:14px 12px 20px;
  display:grid;
  place-items:center;
  background:
    radial-gradient(circle at 50% 44%,rgba(68,156,61,.10),rgba(0,0,0,.26) 64%,rgba(0,0,0,.50)),
    linear-gradient(rgba(2,7,2,.08),rgba(0,0,0,.24));
}
.gfr-hero-idle-asset img{
  width:100%;
  height:100%;
  object-fit:contain;
  object-position:center;
  opacity:.54;
  transform:none;
  filter:grayscale(1) sepia(1) saturate(3.1) hue-rotate(58deg) brightness(.82) contrast(1.08);
}
.gfr-hero-idle-asset::after{
  opacity:.62;
}

/* Playing state: use more of the available hero width for the active cover
   and tighten the composition so less space is visually wasted. */
.gfr-hero-playing{
  grid-template-columns:minmax(220px,270px) minmax(0,1fr);
  gap:18px;
  padding:34px 0 24px;
  align-items:start;
}
.gfr-hero-cover{
  align-self:start;
}
.gfr-hero-meta{
  align-self:center;
  min-width:0;
}
.gfr-hero-song-title{
  margin-top:2px;
}
.gfr-hero-player{
  margin-top:8px;
}

/* Keep album metadata firmly in the text column; never let it visually creep
   into the cover area. */
.gfr-card-main,
.gfr-hero-meta{
  min-width:0;
  overflow:hidden;
}
.gfr-card-main{
  display:flex;
  flex-direction:column;
  justify-content:center;
}
.gfr-card-meta,
.gfr-hero-album{
  display:block;
  max-width:100%;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

@media(max-width:520px){
  .gfr-hero-playing{grid-template-columns:150px minmax(0,1fr);gap:12px;padding-top:28px}
}
@media(max-width:390px){
  .gfr-hero-playing{grid-template-columns:122px minmax(0,1fr)}
}


/* RC1.7 — Responsive hero rebuild -----------------------------------------
   The hero content now participates in normal document flow. Its artwork
   decides its own height from aspect-ratio instead of being stretched inside
   a fixed/absolute middle band. This makes desktop, portrait and browser zoom
   behave consistently. */
.gfr-hero{
  min-height:0;
  display:flex;
  flex-direction:column;
  padding:18px 18px 14px;
}
.gfr-hero__topline{
  flex:0 0 auto;
}
.gfr-hero__footer{
  position:static;
  flex:0 0 auto;
  margin-top:18px;
  left:auto;
  right:auto;
  bottom:auto;
}

.gfr-hero-idle{
  min-height:0;
  width:100%;
  margin-top:14px;
  position:relative;
}
.gfr-hero-idle-asset{
  position:relative;
  inset:auto;
  width:100%;
  height:auto;
  display:block;
  overflow:hidden;
  padding:12px;
  background:
    radial-gradient(circle at 50% 44%,rgba(68,156,61,.10),rgba(0,0,0,.26) 64%,rgba(0,0,0,.50)),
    linear-gradient(rgba(2,7,2,.08),rgba(0,0,0,.24));
}
.gfr-hero-idle-asset img{
  display:block;
  width:100%;
  height:auto;
  max-height:none;
  aspect-ratio:auto;
  object-fit:contain;
  object-position:center;
  margin:0 auto;
  opacity:.54;
  transform:none;
  filter:grayscale(1) sepia(1) saturate(3.1) hue-rotate(58deg) brightness(.82) contrast(1.08);
}
.gfr-hero-idle-asset::after{
  inset:12px;
}
.gfr-hero-fallback{
  margin-top:8px;
}

/* Playing state uses intrinsic square cover geometry and a responsive grid.
   The hero grows with the cover instead of limiting it with a fixed row. */
.gfr-hero-playing{
  width:100%;
  padding:28px 0 4px;
  display:grid;
  grid-template-columns:minmax(250px,42%) minmax(0,1fr);
  grid-template-rows:auto auto auto;
  gap:18px 22px;
  align-items:center;
}
.gfr-hero-playing[hidden]{display:none}
.gfr-hero-back{
  grid-column:1/-1;
  grid-row:1;
}
.gfr-hero-cover{
  grid-column:1;
  grid-row:2;
  width:100%;
  max-width:none;
  aspect-ratio:1/1;
  align-self:start;
}
.gfr-hero-meta{
  grid-column:2;
  grid-row:2;
  align-self:center;
  overflow:visible;
}
.gfr-hero-player{
  grid-column:1/-1;
  grid-row:3;
  margin-top:0;
}
.gfr-hero-audio-state{
  grid-column:1/-1;
}

/* Real cover art already contains its own typography. Remove the old demo
   ID/caption overlay entirely so no generated label can sit over artwork. */
.gfr-cover::after{
  content:none !important;
  display:none !important;
}

/* Album metadata belongs only to the information column. */
.gfr-card-main{
  position:relative;
  z-index:1;
  overflow:hidden;
}
.gfr-card-meta{
  position:static;
  z-index:auto;
  max-width:100%;
}

@media(max-width:620px){
  .gfr-hero-playing{
    grid-template-columns:minmax(150px,40%) minmax(0,1fr);
    gap:14px;
  }
}
@media(max-width:430px){
  .gfr-hero-playing{
    grid-template-columns:1fr;
    grid-template-rows:auto auto auto auto;
  }
  .gfr-hero-back{grid-column:1;grid-row:1}
  .gfr-hero-cover{
    grid-column:1;
    grid-row:2;
    width:min(78vw,290px);
    justify-self:center;
  }
  .gfr-hero-meta{
    grid-column:1;
    grid-row:3;
    width:100%;
  }
  .gfr-hero-player{
    grid-column:1;
    grid-row:4;
  }
}


/* RC1.8 — Playing hero reflow ----------------------------------------------
   One primary content row (large cover + metadata) followed by one dedicated
   transport row. The back control floats above the composition instead of
   consuming a grid row, so the cover can use the available hero area. */
.gfr-hero-playing{
  position:relative;
  grid-template-columns:minmax(300px,54%) minmax(0,1fr);
  grid-template-rows:auto auto auto;
  column-gap:24px;
  row-gap:15px;
  padding:38px 0 6px;
  align-items:center;
}
.gfr-hero-back{
  position:absolute;
  top:0;
  right:0;
  z-index:5;
  grid-column:auto;
  grid-row:auto;
}
.gfr-hero-cover{
  grid-column:1;
  grid-row:1;
  width:100%;
  aspect-ratio:1/1;
  justify-self:start;
  align-self:center;
}
.gfr-hero-meta{
  grid-column:2;
  grid-row:1;
  align-self:center;
  padding-right:4px;
}
.gfr-hero-player{
  grid-column:1/-1;
  grid-row:2;
  width:100%;
  display:grid;
  grid-template-columns:38px minmax(0,1fr) auto;
  gap:10px;
  align-items:center;
  margin:0;
}
.gfr-hero-audio-state{
  grid-column:1/-1;
  grid-row:3;
  margin-top:-5px;
}

/* Hardware-like transport control: the running state is represented by a
   solid square while keeping the same pause behaviour underneath. */
.gfr-hero-play,
.gfr-play{
  display:grid;
  place-items:center;
  line-height:1;
  font-family:Consolas,'Courier New',monospace;
  font-weight:700;
}
.gfr-hero-play{
  width:38px;
  height:38px;
  padding:0;
}
.gfr-play{
  width:32px;
  height:30px;
}

@media(max-width:620px){
  .gfr-hero-playing{
    grid-template-columns:minmax(180px,48%) minmax(0,1fr);
    column-gap:14px;
    padding-top:36px;
  }
}
@media(max-width:430px){
  .gfr-hero-playing{
    grid-template-columns:1fr;
    grid-template-rows:auto auto auto auto;
    padding-top:38px;
  }
  .gfr-hero-back{top:0;right:0}
  .gfr-hero-cover{
    grid-column:1;
    grid-row:1;
    width:min(86vw,320px);
    justify-self:center;
  }
  .gfr-hero-meta{
    grid-column:1;
    grid-row:2;
    width:100%;
  }
  .gfr-hero-player{
    grid-column:1;
    grid-row:3;
  }
  .gfr-hero-audio-state{
    grid-column:1;
    grid-row:4;
  }
}


/* RC1.9 — Hero luminance-as-alpha experiment ------------------------------
   The exported idle hero image now already carries transparency derived from
   luminance. Keep the browser treatment light so the signal can float in the
   panel instead of becoming a heavy opaque block. */
.gfr-hero-idle-asset img{
  filter:none;
  opacity:.88;
}
.gfr-hero-idle-asset::after{
  opacity:.44;
  background:
    radial-gradient(circle at 50% 43%,rgba(111,215,99,.10),transparent 56%),
    linear-gradient(rgba(2,7,2,.03),rgba(0,0,0,.18));
}


/* RC2.0 — Signal brightness pass -------------------------------------------
   Lift the perceived brightness of the idle hero so it sits closer to the
   luminous text, while still remaining slightly subordinate. */
.gfr-hero-idle-asset img{
  opacity:.96;
}
.gfr-hero-idle-asset::after{
  opacity:.34;
}


/* RC2.3 — Authored alpha hero pass -----------------------------------------
   A manually authored Web Hero Override is treated as the final RGBA artwork.
   No luminance remap, grayscale, inversion or rectangular overlay is applied.
   Only a tiny brightness lift and soft phosphor halo are added in the browser. */
.gfr-hero-idle-asset.is-authored-alpha{
  background:transparent;
}
.gfr-hero-idle-asset.is-authored-alpha img{
  filter:
    brightness(1.05)
    drop-shadow(0 0 5px rgba(125,255,112,.16))
    drop-shadow(0 0 16px rgba(88,210,78,.07));
  opacity:.92;
}
.gfr-hero-idle-asset.is-authored-alpha::after{
  display:none;
}

/* Generated fallback hero keeps the existing screen treatment. */
.gfr-hero-idle-asset.is-generated-signal img{
  opacity:.96;
}


/* RC2.7 — Mobile CRT normalization -----------------------------------------
   High-DPI phones rasterize 1 CSS-pixel scanline grooves across multiple
   physical pixels, which makes the desktop pattern look harder/coarser.
   Desktop remains untouched; mobile gets a finer, softer groove pattern. */
@media (max-width: 760px) {
  .gfr-jukebox::before {
    background: repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,0) 0,
      rgba(0,0,0,0) 1.5px,
      rgba(0,0,0,.22) 1.5px,
      rgba(0,0,0,.22) 2px,
      rgba(146,255,130,.014) 2px,
      rgba(146,255,130,.014) 3px
    );
    opacity: .62;
  }

  .gfr-crt-grain {
    opacity: .032;
  }
}

@media (orientation: landscape) and (max-height: 600px) {
  .gfr-jukebox::before {
    background: repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,0) 0,
      rgba(0,0,0,0) 1.25px,
      rgba(0,0,0,.18) 1.25px,
      rgba(0,0,0,.18) 1.75px,
      rgba(146,255,130,.012) 1.75px,
      rgba(146,255,130,.012) 2.75px
    );
    opacity: .56;
  }
}
