/* Faraday — faradaysounds.com
   Tokens follow the app: lib/src/components/theme.dart and
   lib/src/player/player_tokens.dart. */

@font-face {
  font-family: "Marvin Visions";
  src: url("/assets/fonts/MarvinVisionsBig-Bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Departure Mono";
  src: url("/assets/fonts/DepartureMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* Palette colours blend like the app's PaletteBlend: 700 ms, ease in out. */
@property --base { syntax: "<color>"; inherits: true; initial-value: #3c2eaf; }
@property --glow { syntax: "<color>"; inherits: true; initial-value: #b3bdd5; }
@property --glow-edge { syntax: "<color>"; inherits: true; initial-value: #3455b9; }
@property --band { syntax: "<color>"; inherits: true; initial-value: #d22b5b; }
@property --sheen { syntax: "<color>"; inherits: true; initial-value: #cbab9f; }
@property --title { syntax: "<color>"; inherits: true; initial-value: #c8d2ed; }
@property --coil { syntax: "<color>"; inherits: true; initial-value: #3b52ff; }

:root {
  --bg: #20201e;
  --fg: #e2ddcd;
  --fg-2: rgb(226 221 205 / 0.75);
  --fg-3: rgb(226 221 205 / 0.14);
  --fg-4: rgb(226 221 205 / 0.07);
  --player-fg: #e2ddcd;
  --pill: #121211;
  --display: "Marvin Visions", "Arial Black", system-ui, sans-serif;
  --mono: "Departure Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --radius: 32px;
  --ease: cubic-bezier(0.42, 0, 0.58, 1);
  --spring: cubic-bezier(0.2, 0.9, 0.25, 1.15);
  --pad: clamp(20px, 5vw, 64px);
  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root[data-appearance="device"] {
    --bg: #f2f0e7; --fg: #2e2d28; --fg-2: rgb(80 78 70 / 0.85); --fg-3: rgb(80 78 70 / 0.2); --fg-4: rgb(80 78 70 / 0.08);
    --pill: #121211;
    color-scheme: light;
  }
}
:root[data-appearance="light"] {
  --bg: #f2f0e7; --fg: #2e2d28; --fg-2: rgb(80 78 70 / 0.85); --fg-3: rgb(80 78 70 / 0.2); --fg-4: rgb(80 78 70 / 0.08);
  color-scheme: light;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 17px/1.5 var(--mono);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  transition: background-color 400ms var(--ease), color 400ms var(--ease);
}

/* The faint grain over the app's backgrounds. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: 0.07;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 1.4 -.2'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

img, video, canvas, svg { display: block; max-width: 100%; }
svg use { fill: currentColor; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; border-radius: 12px; }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: -9999px; top: 8px; z-index: 200; padding: 10px 14px; background: var(--fg); color: var(--bg); border-radius: 12px; }
.skip:focus { left: 12px; }

.display {
  font: 700 clamp(44px, 7.4vw, 104px) / 0.86 var(--display);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin: 0 0 0.35em;
  text-wrap: balance;
}
.eyebrow { margin: 0 0 18px; color: var(--fg-2); font-size: 15px; letter-spacing: 0.02em; }
.big { font-size: clamp(19px, 2.1vw, 26px); line-height: 1.45; max-width: 34em; margin: 0; text-wrap: pretty; }
.quiet { color: var(--fg-2); }
p { text-wrap: pretty; }

/* ------------------------------------------------------------------ topbar */

.topbar {
  position: fixed;
  inset: 0 0 auto;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: max(12px, env(safe-area-inset-top)) clamp(16px, 3vw, 28px) 12px;
  height: calc(80px + env(safe-area-inset-top));
}
/* The glass reaches up past the bar's own top, so when Safari pins the bar
   below the status bar the gap above it is frosted too, not see-through. */
.topbar::before {
  content: "";
  position: absolute;
  inset: -120px 0 0;
  z-index: -1;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(20px) saturate(1.2);
  -webkit-backdrop-filter: blur(20px) saturate(1.2);
  opacity: 0;
  pointer-events: none;
  transition: opacity 300ms var(--ease);
}
.topbar.scrolled::before { opacity: 1; }
.top-cta {
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 14px;
  text-decoration: none;
  color: var(--fg-2);
  transition: color 200ms var(--ease), background-color 200ms var(--ease);
}
.top-cta:hover { color: var(--fg); background: var(--fg-4); }
/* The hero says it already, until it's scrolled away. */
.top-cta { opacity: 0; pointer-events: none; transition: opacity 400ms var(--ease), color 200ms var(--ease), background-color 200ms var(--ease); }
.topbar.scrolled .top-cta { opacity: 1; pointer-events: auto; }
@media (max-width: 760px) { .top-cta { display: none; } }
.brand { display: flex; align-items: center; gap: 12px; margin-right: auto; text-decoration: none; font-size: 18px; }

/* While a sound plays and its room is out of sight, a way to stop it. */
.now-playing {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px 0 13px;
  border-radius: 999px;
  font-size: 14px;
  color: var(--player-fg);
  background: var(--pill);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06), 0 10px 30px rgb(0 0 0 / 0.25);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 300ms var(--ease), transform 300ms var(--ease), visibility 0s 300ms;
}
.now-playing.show { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.now-playing:active { transform: scale(0.95); }
.now-playing svg { width: 15px; height: 15px; }
.brand img { width: 40px; height: 40px; border-radius: 11px; box-shadow: 0 4px 14px rgb(0 0 0 / 0.35); }

/* The radio pill, as in the app: dark glass, lit radios, ice when trapped. */
.pill-frame { border-radius: 999px; box-shadow: 0 10px 30px rgb(0 0 0 / 0.35); }
.pill {
  display: flex;
  gap: 4px;
  padding: 4px 6px;
  border-radius: 999px;
  overflow: hidden;
  clip-path: inset(0 round 999px);
  background: var(--pill);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.06);
}
.radio {
  position: relative;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  transition: transform 160ms var(--ease);
}
.radio:active { transform: scale(0.92); }
.radio img { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: screen; pointer-events: none; }
.radio .ice { opacity: 0; transform: scale(0.2) rotate(-200deg); inset: 3px; width: calc(100% - 6px); height: calc(100% - 6px); mix-blend-mode: lighten; filter: blur(6px); }
.radio[aria-pressed="false"] .lit { opacity: 0; transition: opacity 500ms 300ms var(--ease); }
.radio[aria-pressed="false"] .ice { animation: freeze 1.8s var(--ease) forwards; }
.radio.cracking .ice { animation: crack 0.9s var(--ease) forwards; }
.radio.cracking .lit { opacity: 1; transition: opacity 400ms 350ms var(--ease); }
.radio::after {
  /* frost flash as the ice lands */
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(220 236 255 / 0.9), rgb(220 236 255 / 0) 70%);
  opacity: 0;
  pointer-events: none;
}
.radio[aria-pressed="false"]::after { animation: frost 1.8s var(--ease) forwards; }

@keyframes freeze {
  0% { opacity: 0; transform: scale(0.2) rotate(-200deg) translate(-6px, -8px); filter: blur(6px); }
  14% { opacity: 0.4; }
  64% { opacity: 1; transform: scale(1.08) rotate(6deg); filter: blur(0); }
  76% { transform: scale(0.96) rotate(-3deg); }
  88% { transform: scale(1.02) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); filter: blur(0); }
}
@keyframes frost {
  0%, 58% { opacity: 0; transform: scale(0.6); }
  66% { opacity: 0.9; transform: scale(1.1); }
  100% { opacity: 0; transform: scale(1.3); }
}
@keyframes crack {
  0% { opacity: 1; transform: scale(1); filter: brightness(1); }
  10% { transform: translateX(-1px) rotate(-1deg); }
  20% { transform: translateX(1.5px) rotate(1.5deg); }
  30% { transform: translateX(-2px) rotate(-2deg); filter: brightness(1.4); }
  38% { opacity: 1; transform: scale(1.06); filter: brightness(2.2); }
  60% { opacity: 0; transform: scale(1.7) rotate(12deg); filter: brightness(2.5) blur(4px); }
  100% { opacity: 0; transform: scale(1.8); }
}

.pill-hint {
  position: absolute;
  right: clamp(24px, 3vw, 36px);
  top: calc(100% + 14px);
  margin: 0;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 13px;
  color: #ffd2a8;
  background: rgb(40 20 8 / 0.55);
  clip-path: inset(0 round 999px);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
  pointer-events: none;
  animation: hint 3s 1.4s var(--ease) both;
}
.pill-hint.gone { opacity: 0; transform: translateY(-6px); animation: none; }
@keyframes hint { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* -------------------------------------------------------------------- hero */

.hero {
  height: 100svh;
  min-height: 600px;
  padding: calc(80px + env(safe-area-inset-top)) clamp(10px, 1.6vw, 20px) clamp(10px, 1.6vw, 20px);
}

/* A room is the app's artwork. Its frame casts the shadow, and the room
   clips everything in it to its corners, canvases and glass included, even
   while they move: overflow alone lets Safari square them off mid-animation. */
.frame {
  position: relative;
  height: 100%;
  border-radius: var(--radius);
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.12), 0 30px 80px -20px rgb(0 0 0 / 0.5);
}
.room {
  position: relative;
  height: 100%;
  border-radius: inherit;
  overflow: hidden;
  clip-path: inset(0 round var(--radius));
  isolation: isolate;
  background: var(--base);
  contain: layout paint;
}
.room::after {
  /* the app's artwork border */
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.18);
  pointer-events: none;
  z-index: 9;
}

.room-glow, .room-band { position: absolute; z-index: 2; pointer-events: none; }
.room-glow { left: 0; top: 0; width: var(--glow-w, 74%); height: var(--glow-h, 61%); }
.room-band { left: 0; top: 9%; width: 100%; height: 91%; }
.room-glow svg, .room-band svg { width: 100%; height: 100%; }

.room-title {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  top: var(--title-top, 52%);
  margin: 0;
  text-align: center;
  font: 700 var(--title-size, 120px) / 0.82 var(--display);
  text-transform: uppercase;
  color: var(--title);
  white-space: pre-line;
  letter-spacing: -0.005em;
}

.room-coil {
  position: absolute;
  z-index: 3;
  left: var(--coil-x, 30%);
  top: var(--coil-y, 10%);
  width: var(--coil-size, 400px);
  height: var(--coil-size, 400px);
  max-width: none;
  pointer-events: none;
}

/* The cage and its title arrive once they're laid out, rather than jumping there. */
.js .room-title, .js .room-coil { opacity: 0; transition: opacity 700ms var(--ease); }
.js .room.ready .room-title, .js .room.ready .room-coil { opacity: 1; }

.room-env { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; pointer-events: none; transition: opacity 260ms var(--ease); }
.interference { position: absolute; inset: 0; z-index: 4; width: 100%; height: 100%; pointer-events: none; transition: opacity 600ms var(--ease); }

/* The plastic sleeve over everything, as the app's two ShaderMasks:
   screen, then overlay. Portrait cards turn the texture on its side. */
.plastic {
  position: absolute;
  z-index: 5;
  left: 50%;
  top: 50%;
  width: var(--plastic-w, 100%);
  height: var(--plastic-h, 100%);
  transform: translate(-50%, -50%) rotate(var(--plastic-turn, 0deg));
  background: url("/assets/img/plastic.webp") center / cover no-repeat;
  pointer-events: none;
}
.plastic.screen { mix-blend-mode: screen; }
.plastic.overlay { mix-blend-mode: overlay; }
.plastic.shine {
  z-index: 6;
  mix-blend-mode: screen;
  filter: grayscale(1) brightness(1.275) contrast(4);
  -webkit-mask-image: linear-gradient(var(--shine-angle, 135deg), transparent calc(var(--shine, 50%) - 22%), rgb(0 0 0 / 0.25) calc(var(--shine, 50%) - 7%), rgb(0 0 0 / 0.7) var(--shine, 50%), rgb(0 0 0 / 0.25) calc(var(--shine, 50%) + 7%), transparent calc(var(--shine, 50%) + 22%));
  mask-image: linear-gradient(var(--shine-angle, 135deg), transparent calc(var(--shine, 50%) - 22%), rgb(0 0 0 / 0.25) calc(var(--shine, 50%) - 7%), rgb(0 0 0 / 0.7) var(--shine, 50%), rgb(0 0 0 / 0.25) calc(var(--shine, 50%) + 7%), transparent calc(var(--shine, 50%) + 22%));
}
.room-sheen {
  position: absolute;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  mix-blend-mode: screen;
  background: linear-gradient(135deg, transparent calc(var(--shine, 50%) - 35%), rgb(255 255 255 / 0.13) var(--shine, 50%), transparent calc(var(--shine, 50%) + 35%));
}

.room-clean {
  position: absolute;
  z-index: 7;
  left: 50%;
  top: 22px;
  translate: -50% 0;
  margin: 0;
  padding: 7px 14px;
  border-radius: 999px;
  clip-path: inset(0 round 999px);
  font-size: 14px;
  color: var(--player-fg);
  background: rgb(0 0 0 / 0.28);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
  white-space: nowrap;
}
.room-clean.show { opacity: 1; transform: none; }

.hero-copy {
  position: absolute;
  z-index: 7;
  left: 0;
  right: 0;
  top: var(--copy-top, 72%);
  text-align: center;
  color: var(--player-fg);
  padding: 0 20px;
  text-shadow: 0 1px 14px rgb(0 0 0 / 0.25);
}
.tagline { margin: 0 0 4px; font-size: clamp(15px, 1.5vw, 19px); letter-spacing: 0.02em; }
.lede { margin: 0; font-size: clamp(13px, 1.2vw, 16px); opacity: 0.78; }
.soon {
  display: inline-block;
  margin-top: 16px;
  padding: 9px 16px;
  border-radius: 999px;
  clip-path: inset(0 round 999px);
  font-size: 14px;
  text-decoration: none;
  color: var(--player-fg);
  background: rgb(0 0 0 / 0.28);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.14);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: background-color 200ms var(--ease);
  text-shadow: none;
}
.soon:hover { background: rgb(0 0 0 / 0.4); }

/* The app's glass (player_glass_surface.dart): the surface casts its shadows
   outside itself, and its pane, the blur and fill, is clipped to its corners
   however it moves. Whatever sits on the glass is positioned above the pane. */
.glass {
  border-radius: var(--glass-radius, 28px);
  box-shadow: 5px 6px 17px rgb(0 0 0 / 0.32), 21px 23px 32px rgb(0 0 0 / 0.28), 47px 53px 43px rgb(0 0 0 / 0.17);
}
.glass-pane {
  position: absolute;
  inset: 0;
  border: 1px solid transparent;
  border-radius: inherit;
  clip-path: inset(0 round var(--glass-radius, 28px));
  background:
    linear-gradient(160deg, rgb(255 255 255 / 0.18), rgb(255 255 255 / 0) 55%) border-box,
    linear-gradient(170deg, rgb(0 0 0 / 0.7), rgb(0 0 0 / 0.4)) padding-box;
  backdrop-filter: blur(var(--glass-blur, 32px)) saturate(1.3);
  -webkit-backdrop-filter: blur(var(--glass-blur, 32px)) saturate(1.3);
  pointer-events: none;
}

/* ---------------------------------------------------------------- sections */

main > section:not(.hero) { padding: clamp(80px, 13vw, 180px) var(--pad); max-width: 1320px; margin: 0 auto; }

.intro { text-align: left; }
.intro .display { font-size: clamp(64px, 13vw, 200px); }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 7vw, 110px); align-items: center; }
.split.reverse > :first-child { order: 2; }
.copy p { max-width: 31em; }
@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; }
  .split.reverse > :first-child { order: 0; }
}

/* A record sleeve, with the app's plastic and a sheen that follows you. */
.sleeve {
  position: relative;
  margin: 0;
  border-radius: 10px;
  overflow: hidden;
  aspect-ratio: 1;
  transform: perspective(1200px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 500ms var(--ease);
  box-shadow: 0 40px 80px -30px rgb(0 0 0 / 0.6), 0 0 0 1px rgb(255 255 255 / 0.08);
  isolation: isolate;
}
.sleeve > * { clip-path: inset(0 round 10px); }
.sleeve img { width: 100%; height: 100%; object-fit: cover; }
.sleeve-plastic { position: absolute; inset: 0; background: url("/assets/img/plastic.webp") center / cover; mix-blend-mode: screen; opacity: 0.55; }
.sleeve-shine {
  position: absolute; inset: 0; mix-blend-mode: screen;
  background: linear-gradient(135deg, transparent calc(var(--shine, 50%) - 30%), rgb(255 255 255 / 0.22) var(--shine, 50%), transparent calc(var(--shine, 50%) + 30%));
}

/* ------------------------------------------------------------------ listen */

/* One room, the size of the app's card, and the one key the page plays from. */
.card {
  width: min(100%, 440px);
  height: auto;
  aspect-ratio: 0.68;
  justify-self: center;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 0.12), 0 50px 100px -40px color-mix(in srgb, var(--base) 80%, #000);
}
.key {
  --glass-radius: 26px;
  position: absolute;
  z-index: 8;
  left: 50%;
  bottom: clamp(18px, 5%, 26px);
  width: 104px;
  height: 76px;
  margin-left: -52px;
  transform: translate(var(--float-x, 0px), var(--float-y, 0px));
  transition: transform 600ms var(--ease);
}
.key-button {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: inherit;
  color: var(--player-fg);
}
.key-button svg { position: relative; width: 40px; height: 40px; }
.key-button.swap svg { animation: glyph 420ms var(--spring); }
@keyframes glyph { from { transform: scale(0.5); opacity: 0; } }
/* The app's press (player_control_button.dart): a highlight grows in behind
   the glyph in 60 ms, and takes its time letting go. */
.key-button::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 32px;
  height: 24px;
  translate: -50% -50%;
  border-radius: 20px;
  transition: width 560ms var(--ease), height 560ms var(--ease), background-color 560ms var(--ease);
}
.key-button:hover::before { width: calc(100% - 12px); height: calc(100% - 12px); background: rgb(226 221 205 / 0.07); }
.key-button:active::before { width: calc(100% - 8px); height: calc(100% - 8px); background: rgb(226 221 205 / 0.14); transition-duration: 60ms; }

/* ------------------------------------------------------------------ sounds */

.sounds { max-width: none !important; position: relative; transition: --base 700ms var(--ease), --band 700ms var(--ease); }
.sounds::before {
  /* the page picks up the room's colours */
  content: "";
  position: absolute;
  inset: 10% -10% 0;
  z-index: -1;
  background:
    radial-gradient(40% 50% at 28% 40%, color-mix(in srgb, var(--base) 55%, transparent), transparent 70%),
    radial-gradient(35% 45% at 80% 70%, color-mix(in srgb, var(--band) 30%, transparent), transparent 70%);
  filter: blur(40px);
  opacity: 0.8;
  pointer-events: none;
}
.sounds-head { max-width: 1320px; margin: 0 auto 56px; }
.sounds-head p:last-child { max-width: 36em; }
.sounds-stage {
  max-width: 1320px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(32px, 6vw, 96px);
  align-items: center;
}
@media (max-width: 860px) { .sounds-stage { grid-template-columns: minmax(0, 1fr); } }

/* A phone, drawn in CSS around real captures from the app. */
.phone {
  --w: clamp(250px, 26vw, 330px);
  position: relative;
  width: var(--w);
  aspect-ratio: 402 / 874;
  margin: 0 auto;
  padding: calc(var(--w) * 0.035);
  border-radius: calc(var(--w) * 0.16);
  background: linear-gradient(145deg, #3a3a38, #0b0b0a 40%, #1c1c1b);
  box-shadow:
    inset 0 0 0 1.5px rgb(255 255 255 / 0.14),
    inset 0 0 0 4px #090909,
    0 50px 90px -30px rgb(0 0 0 / 0.7),
    0 24px 40px -20px rgb(0 0 0 / 0.5);
  transform: perspective(1400px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 600ms var(--ease);
}
.phone-screen {
  position: relative;
  height: 100%;
  border-radius: calc(var(--w) * 0.13);
  overflow: hidden;
  clip-path: inset(0 round calc(var(--w) * 0.13));
  background: #20201e;
  isolation: isolate;
}
.phone-screen::before {
  /* the island */
  content: "";
  position: absolute;
  z-index: 3;
  top: 2.2%;
  left: 50%;
  width: 31%;
  height: 4%;
  translate: -50% 0;
  border-radius: 999px;
  background: #000;
}
.phone.bare video, .phone.bare img { width: 100%; height: 100%; object-fit: cover; }
.phone-status { position: absolute; z-index: 2; inset: 2.6% 9% auto; display: flex; justify-content: space-between; font: 600 calc(var(--w) * 0.045)/1 system-ui, sans-serif; color: #e8e6df; }
.phone-status i { width: 9%; height: calc(var(--w) * 0.04); border-radius: 3px; border: 1.5px solid #e8e6df; opacity: 0.9; }
.phone-header { position: absolute; z-index: 2; top: 8.6%; left: 6%; right: 6%; display: flex; justify-content: space-between; align-items: center; }
.phone-gear { width: calc(var(--w) * 0.15); aspect-ratio: 1; border-radius: 50%; background: #181817; display: grid; place-items: center; color: #e2ddcd; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.05); }
.phone-gear svg { width: 46%; }
.phone-pill { display: flex; gap: 6%; padding: 1.5% 4%; border-radius: 999px; background: #121211; width: 50%; justify-content: space-between; }
.phone-pill img { width: 30%; mix-blend-mode: screen; }
/* The app's player as captured from it (540 × 1006), at the foot of the
   screen. A new room fades in over the last; both share one geometry. */
.phone-room { position: absolute; left: 0; right: 0; bottom: 0; aspect-ratio: 540 / 1006; }
.phone-layer { position: absolute; inset: 0; transition: opacity 450ms var(--ease); }
.phone-layer.enter { opacity: 0; }
.phone-layer video { width: 100%; height: 100%; object-fit: cover; }
/* Sounds without a capture: their artwork where the capture's card is, under a still of its glass. */
.phone-card {
  position: absolute;
  left: 0.4%;
  top: 0.3%;
  width: 99.2%;
  height: 92.6%;
  border-radius: calc(var(--w) * 0.069);
  overflow: hidden;
  clip-path: inset(0 round calc(var(--w) * 0.069));
  isolation: isolate;
}
.phone-card img { width: 100%; height: 100%; object-fit: cover; }
.phone-card span { position: absolute; left: 0; right: 0; top: 44%; translate: 0 -50%; text-align: center; font: 700 calc(var(--w) * 0.2)/0.82 var(--display); text-transform: uppercase; text-shadow: 0 2px 20px rgb(0 0 0 / 0.25); }
.phone-card::after { content: ""; position: absolute; inset: 0; background: url("/assets/img/plastic.webp") center / cover; mix-blend-mode: screen; opacity: 0.6; }
.phone-panel {
  --glass-radius: calc(var(--w) * 0.083);
  --glass-blur: 18px;
  position: absolute;
  left: 7.2%;
  right: 7.2%;
  top: 75.8%;
  bottom: 0.2%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: 58% 42%;
  place-items: center;
  padding: 6% 3% 0;
  color: var(--player-fg);
  font-size: calc(var(--w) * 0.05);
  box-shadow: 4px 6px 14px rgb(0 0 0 / 0.3), 14px 18px 28px rgb(0 0 0 / 0.22);
}
.phone-panel > :not(.glass-pane) { position: relative; }
.phone-panel svg { width: calc(var(--w) * 0.075); height: calc(var(--w) * 0.075); }
.phone-panel .big { width: calc(var(--w) * 0.11); height: calc(var(--w) * 0.11); }
.phone-panel .small, .phone-panel .small svg { width: calc(var(--w) * 0.05); height: calc(var(--w) * 0.05); }
.phone-panel span.small { display: flex; align-items: center; gap: 0.35em; width: auto; height: auto; }

.shelf-wrap { min-width: 0; }
.now { margin: 0; font-size: 15px; color: var(--fg-2); }
.now strong { font: 700 clamp(30px, 3.6vw, 48px)/1 var(--display); text-transform: uppercase; color: var(--fg); display: block; margin-top: 8px; }
.now-blurb { min-height: 4.5em; max-width: 32em; margin: 14px 0 22px; color: var(--fg-2); }
.shelf {
  list-style: none;
  margin: 0 calc(var(--pad) * -1) 0 0;
  padding: 10px var(--pad) 26px 4px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(132px, 13vw, 176px);
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.shelf::-webkit-scrollbar { display: none; }
.shelf li { scroll-snap-align: start; }
.shelf button {
  width: 100%;
  text-align: left;
  display: grid;
  border-radius: 10px;
  box-shadow: 0 18px 30px -16px rgb(0 0 0 / 0.7), 0 0 0 1px rgb(255 255 255 / 0.06);
  transition: transform 300ms var(--spring), box-shadow 250ms var(--ease);
}
.shelf button:focus-visible { border-radius: 10px; }
.shelf button:hover { transform: translateY(-6px) rotate(-1deg); }
.shelf button:active { transform: scale(0.97); }
.shelf .art {
  position: relative;
  aspect-ratio: 1;
  border-radius: inherit;
  overflow: hidden;
  clip-path: inset(0 round 10px);
  isolation: isolate;
}
.shelf .art img { width: 100%; height: 100%; object-fit: cover; }
.shelf .art span {
  position: absolute;
  inset: auto 8px 8px;
  font: 700 clamp(17px, 1.6vw, 22px)/0.84 var(--display);
  text-transform: uppercase;
  color: var(--t);
  text-shadow: 0 2px 12px rgb(0 0 0 / 0.35);
}
.shelf .art::after { content: ""; position: absolute; inset: 0; background: url("/assets/img/plastic.webp") center / cover; mix-blend-mode: screen; opacity: 0.5; }
.shelf button[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--fg), 0 18px 30px -16px rgb(0 0 0 / 0.7); }
.shelf-nav { display: flex; gap: 10px; }
.round { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; background: var(--fg-4); transition: background-color 200ms var(--ease), transform 120ms var(--ease); }
.round:hover { background: var(--fg-3); }
.round:active { transform: scale(0.92); }
.round svg { width: 20px; height: 20px; }

/* ------------------------------------------------------------------- timer */

.timer-section { max-width: none !important; padding-left: 0 !important; padding-right: 0 !important; height: 260vh; padding-top: 0 !important; padding-bottom: 0 !important; }
.timer-sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  max-width: 1320px;
  margin: 0 auto;
  padding: 90px var(--pad) 40px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(24px, 5vw, 80px);
  align-items: center;
}
.timer-copy p { max-width: 30em; }
.timer-visual { position: relative; height: min(78svh, 680px); display: grid; place-items: center; }
.timer-coil { width: 100%; height: 100%; }
.readout { position: absolute; bottom: 4%; left: 0; right: 0; text-align: center; margin: 0; font-size: 18px; color: var(--fg-2); font-variant-numeric: tabular-nums; }
@media (max-width: 860px) {
  .timer-section { height: 240vh; }
  .timer-sticky { grid-template-columns: 1fr; grid-template-rows: auto 1fr; padding-top: 96px; gap: 0; align-content: start; }
  .timer-copy .quiet { display: none; }
  .timer-visual { height: 100%; min-height: 0; }
  .timer-copy .display { font-size: 44px; }
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.chips button {
  min-width: 60px;
  height: 44px;
  padding: 0 16px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  font-size: 17px;
  background: var(--fg-4);
  transition: background-color 200ms var(--ease), color 200ms var(--ease), transform 120ms var(--ease);
}
.chips button svg { width: 22px; height: 22px; }
.chips button:hover { background: var(--fg-3); }
.chips button:active { transform: scale(0.94); }
.chips button[aria-checked="true"] { background: var(--fg); color: var(--bg); }

/* ------------------------------------------------------------- containment */

.radios { list-style: none; padding: 0; margin: 34px 0; display: grid; gap: 18px; }
.radios li { display: grid; grid-template-columns: 76px 1fr; gap: 18px; align-items: center; }
.radios img { width: 76px; height: 76px; border-radius: 22px; background: #0d0d0c; mix-blend-mode: normal; }
.radios h3 { margin: 0 0 2px; font: 700 26px/1 var(--display); text-transform: uppercase; }
.radios p { margin: 0; color: var(--fg-2); font-size: 15px; }
:root[data-appearance="light"] .radios img { background: #121211; }

/* ----------------------------------------------------------------- details */

.tiles { list-style: none; padding: 0; margin: 48px 0 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 960px) { .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .tiles { grid-template-columns: 1fr; } }
.tile {
  border: 1px solid transparent;
  border-radius: 28px;
  padding: 26px 24px 24px;
  color: var(--player-fg);
  background:
    linear-gradient(160deg, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0) 50%) border-box,
    radial-gradient(120% 100% at 0% 0%, color-mix(in srgb, var(--base) 70%, #000), #121211 70%) padding-box;
  box-shadow: 0 30px 60px -30px rgb(0 0 0 / 0.6);
  transition: transform 400ms var(--spring);
}
.tile:hover { transform: translateY(-4px); }
.tile svg { width: 28px; height: 28px; margin-bottom: 26px; }
.tile h3 { margin: 0 0 8px; font: 700 24px/1 var(--display); text-transform: uppercase; }
.tile p { margin: 0; opacity: 0.75; font-size: 15px; }

/* ----------------------------------------------------------------- offline */

.offline { text-align: center; }
.offline .big { margin: 0 auto; }
.offline-switch { display: flex; justify-content: center; align-items: center; gap: 14px; margin-bottom: 48px; }
.plane { width: 34px; height: 34px; color: #f2a54a; transition: color 300ms var(--ease), transform 600ms var(--spring); }
.offline.on .plane { transform: translateX(6px) rotate(8deg); }

.switch { display: inline-flex; align-items: center; gap: 14px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch-track { position: relative; width: 64px; height: 38px; border-radius: 999px; background: var(--fg-3); transition: background-color 250ms var(--ease); }
.switch-thumb { position: absolute; top: 3px; left: 3px; width: 32px; height: 32px; border-radius: 50%; background: #f2f0e7; box-shadow: 0 3px 8px rgb(0 0 0 / 0.3); transition: transform 300ms var(--spring); }
.switch input:checked + .switch-track { background: #f2a54a; }
.switch input:checked + .switch-track .switch-thumb { transform: translateX(26px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--fg); outline-offset: 3px; }
.switch-label { font-size: 17px; }

/* ---------------------------------------------------------------- download */

.download { text-align: center; display: grid; justify-items: center; }
.app-icon {
  width: clamp(180px, 22vw, 280px);
  height: auto;
  border-radius: 22.5%;
  margin-bottom: 56px;
  box-shadow: 0 50px 90px -30px rgb(60 40 180 / 0.55), 0 0 0 1px rgb(255 255 255 / 0.08);
  transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 500ms var(--ease);
  animation: bob 6s var(--ease) infinite alternate;
}
@keyframes bob { from { translate: 0 -6px; } to { translate: 0 8px; } }
.download .display { max-width: 12em; font-size: clamp(40px, 6.4vw, 92px); }
.badge {
  margin: 12px 0 0;
  padding: 16px 26px;
  border-radius: 20px;
  font-size: 17px;
  background: var(--fg);
  color: var(--bg);
}

/* ------------------------------------------------------------------ footer */

.footer { padding: 80px var(--pad) calc(48px + env(safe-area-inset-bottom)); text-align: center; color: var(--fg-2); border-top: 1px solid var(--fg-4); }
.footer p { margin: 0 0 6px; }
.legal { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 24px; margin: 0 0 6px; }
.footer-mark { font: 700 40px/1 var(--display) !important; text-transform: uppercase; color: var(--fg); margin-bottom: 10px !important; }
.credits { margin: 16px 0 28px; font-size: 14px; color: var(--fg-2); }
.fine { font-size: 13px; opacity: 0.7; }
.fine .c { font-family: system-ui, sans-serif; }
.lab { max-width: 420px; margin: 0 auto 40px; text-align: left; padding: 24px; border-radius: 24px; background: var(--fg-4); }
.lab h2 { margin: 0 0 8px; font: 700 26px/1 var(--display); text-transform: uppercase; color: var(--fg); }
.lab > p { font-size: 14px; margin-bottom: 18px !important; }
.switch.row { display: flex; justify-content: space-between; width: 100%; padding: 8px 0; color: var(--fg); }
.appearance { border: 0; padding: 12px 0 0; margin: 0; display: flex; gap: 18px; flex-wrap: wrap; color: var(--fg); }
.appearance legend { padding: 0; margin-bottom: 10px; font-size: 14px; color: var(--fg-2); }

/* ------------------------------------------------------------------ reveal */

.reveal { opacity: 0; transform: translateY(28px); transition: opacity 900ms var(--ease), transform 900ms var(--ease); }
.reveal.seen { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
  .reveal { opacity: 1; transform: none; }
}

@media (max-width: 640px) {
  :root { --radius: 28px; }
  .brand span { display: none; }
  .radio { width: 46px; height: 46px; }
  .now-playing { width: 44px; height: 44px; padding: 0; justify-content: center; }
  .now-playing span { display: none; }
  .hero { padding-left: 8px; padding-right: 8px; padding-bottom: 8px; }
  .pill-hint { font-size: 12px; }
}
