/* MaxMusic dashboard — standalone UI port (chunk 2).
   Same design language as dashboard-2: deep green "Aurora" tokens, slim
   one-line metadata, a player bar pinned above the phone tab bar. The
   chrome tokens below are FIXED — album colors never tint buttons or
   controls (Max, 2026-10-13). Album artwork colors live only in
   backgrounds: the --amb-* vars consumed by #field and by the stacked
   bottom bars' gradient. The old orange accent (#e8862e) is gone
   entirely (Max, 2026-10-13): chrome emphasis is Spotify-style white —
   a white circular play toggle in the bottom player, white primary
   buttons, white active states, small plain white triangle skips, and
   bare white-arrow Play affordances (no fill) on detail pages/walls. */

/* Registered so palette changes INTERPOLATE: the background field (the
   sole consumer of --amb-*) melts over seconds when a new album's palette
   lands instead of hard-cutting. Where @property is unsupported the vars
   simply swap instantly. Initial values are the neutral nothing-playing
   field: deep blue / deep teal / deep blue-violet neighbors. */
@property --amb-a { syntax: "<color>"; inherits: true; initial-value: #132a42; }
@property --amb-b { syntax: "<color>"; inherits: true; initial-value: #0f3238; }
@property --amb-c { syntax: "<color>"; inherits: true; initial-value: #1d2440; }

:root {
  transition: --amb-a 6s ease, --amb-b 6s ease, --amb-c 6s ease;
  --bg: #0e1512;
  --surface: #16211a;
  --surface2: #1d2b21;
  --text: #e8f0ea;
  --dim: #9db3a4;
  --border: #2a3a2f;
  --sage: #8fbc94;
  --forest: #2f5d3a;
  --heart: #ff6b81;
  --amb-a: #132a42;
  --amb-b: #0f3238;
  --amb-c: #1d2440;
  --tabbar-h: 56px;
  --playerbar-h: 66px;
  --topbar-h: 52px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--text);
  background: var(--bg);
  min-height: 100vh;
}
a { color: var(--sage); }

/* --- living background field --------------------------------------------------
   The Gemini treatment (Max, 2026-10-13 — supersedes the blob drift and
   the old ambient takeover): ONE global field behind everything. A
   vertical wash: the palette hue is lit at the TOP and sinks to the fixed
   near-black #04060a by ~78% down, dark and moody at all times. Three
   stacked copies of that gradient — one per field hue (--amb-a: cover
   average, --amb-b: cover vibrant, --amb-c: vibrant's +26° neighbor, all
   pre-darkened in JS) — cross-fade on long offset loops, so the field
   slowly travels BETWEEN the playing album's own hues. Nothing playing:
   --amb-* hold the neutral deep blue-teal defaults and the same loops
   keep the field breathing. Under it all, three very faint wave-strata
   bands (inline SVGs, filled with the field hues at low opacity) sway
   horizontally low in the frame, barely there, like the reference.
   Motion is opacity/transform only (compositor-friendly) — no filters,
   no backdrop passes. The field and the stacked bottom bars' background
   gradient are the only consumers of --amb-*: album color lives in
   backgrounds only, never in a control, so no button ever recolors. */
#field {
  position: fixed; inset: 0; z-index: -1;
  overflow: hidden; pointer-events: none;
  background: #04060a;
}
.field-layer { position: absolute; inset: 0; will-change: opacity; }
.field-layer.l1 {
  background: linear-gradient(180deg,
    var(--amb-a) 0%,
    color-mix(in srgb, var(--amb-a) 52%, #04060a) 34%,
    color-mix(in srgb, var(--amb-a) 18%, #04060a) 58%,
    #04060a 78%);
}
.field-layer.l2 {
  background: linear-gradient(180deg,
    var(--amb-b) 0%,
    color-mix(in srgb, var(--amb-b) 52%, #04060a) 34%,
    color-mix(in srgb, var(--amb-b) 18%, #04060a) 58%,
    #04060a 78%);
  /* Static blend (also the reduced-motion state): both upper layers sit
     partially up so the field reads as a mix of its hues, not one flat. */
  opacity: 0.5;
}
.field-layer.l3 {
  background: linear-gradient(180deg,
    var(--amb-c) 0%,
    color-mix(in srgb, var(--amb-c) 52%, #04060a) 34%,
    color-mix(in srgb, var(--amb-c) 18%, #04060a) 58%,
    #04060a 78%);
  opacity: 0.34;
}
@keyframes field-fade { from { opacity: 0; } to { opacity: 1; } }
.field-wave {
  position: absolute; left: -60%; width: 220%;
  will-change: transform;
  transition: fill 6s ease;
}
.field-wave.w1 { bottom: 1vh; height: 17vh; fill: var(--amb-b); opacity: 0.16; }
.field-wave.w2 { bottom: 8.5vh; height: 12.5vh; fill: var(--amb-a); opacity: 0.11; }
.field-wave.w3 { bottom: 14.5vh; height: 9.5vh; fill: var(--amb-c); opacity: 0.08; }
@keyframes wave-sway-a { from { transform: translate3d(-2.2%, 0, 0); } to { transform: translate3d(2.2%, 0, 0); } }
@keyframes wave-sway-b { from { transform: translate3d(1.8%, 0, 0); } to { transform: translate3d(-1.8%, 0, 0); } }
/* Animations exist only while the page has opted in (body.field-on, set by
   initField when reduced-motion is NOT preferred). Negative delays desync
   the loops so the field never starts from a flat single-hue state. */
body.field-on .field-layer.l2 { animation: field-fade 88s ease-in-out -30s infinite alternate; }
body.field-on .field-layer.l3 { animation: field-fade 121s ease-in-out -74s infinite alternate; }
body.field-on .field-wave.w1 { animation: wave-sway-a 118s ease-in-out -40s infinite alternate; }
body.field-on .field-wave.w2 { animation: wave-sway-b 149s ease-in-out -83s infinite alternate; }
body.field-on .field-wave.w3 { animation: wave-sway-a 173s ease-in-out -21s infinite alternate; }
/* Hidden tab/app: everything freezes (the compositor would throttle
   RAF-less CSS animations anyway; this makes it explicit and testable). */
body.field-paused #field .field-layer,
body.field-paused #field .field-wave { animation-play-state: paused; }
/* Reduced motion: the static field above, no animation — enforced in CSS
   as well as in initField so the guarantee doesn't depend on JS state. */
@media (prefers-reduced-motion: reduce) {
  #field .field-layer, #field .field-wave { animation: none !important; }
}
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, select, textarea { font: inherit; color: var(--text); }
[hidden] { display: none !important; }
.muted { color: var(--dim); }
.err { color: #ff9d8a; }

/* --- chrome ------------------------------------------------------------------ */

.topbar {
  position: sticky; top: 0; z-index: 30;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 1rem;
  padding: 0 1rem;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.wordmark { font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; }
.wordmark .dot { color: #fff; }
.topnav { display: none; gap: 0.25rem; }
.topnav button {
  padding: 0.4rem 0.8rem; border-radius: 999px; color: var(--dim); font-weight: 600;
}
.topnav button.active { color: var(--text); background: var(--surface2); }
.topbar .spacer { flex: 1; }
.logout-btn { color: var(--dim); font-size: 0.85rem; }

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  display: flex;
  /* Bottom-chrome gradient (Max, 2026-10-13): the tab bar and the
     player bar above it read as ONE stacked unit wearing the playing
     album's colors. The gradient is built from the same --amb-* vars
     as the background field (so it melts over 6s with the palette and
     holds the neutral defaults when nothing plays), mixed deep into
     near-black so white text and controls stay legible at every
     palette. The player bar's bottom stop equals this bar's top stop,
     which is what makes the two bars read as one continuous treatment. */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--amb-b) 32%, #04060a),
    color-mix(in srgb, var(--amb-b) 16%, #04060a));
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}
.tabbar button {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; color: var(--dim); font-size: 0.68rem; font-weight: 600;
}
.tabbar button .ic { font-size: 1.15rem; line-height: 1; }
.tabbar button.active { color: #fff; }

main {
  max-width: 1060px; margin: 0 auto;
  padding: 1rem 1rem calc(var(--tabbar-h) + var(--playerbar-h) + env(safe-area-inset-bottom) + 1.5rem);
}
@media (min-width: 900px) {
  .topnav { display: flex; }
  .tabbar { display: none; }
  main { padding-bottom: calc(var(--playerbar-h) + 2rem); }
}

/* --- player bar ---------------------------------------------------------------- */

.playerbar {
  position: fixed; left: 0; right: 0; z-index: 35;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  min-height: var(--playerbar-h);
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.45rem 0.8rem;
  /* The denser top half of the bottom-chrome gradient (see .tabbar):
     --amb-a at the top melting into the --amb-b stop the tab bar
     starts from, both mixed deep into near-black for legibility. */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--amb-a) 40%, #05080a),
    color-mix(in srgb, var(--amb-b) 32%, #04060a));
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  color: var(--text);
}
@media (min-width: 900px) { .playerbar { bottom: 0; } }
.playerbar .pcover { width: 44px; height: 44px; border-radius: 6px; flex: none; }
.playerbar .pmeta { min-width: 0; flex: 1; }
.playerbar .ptitle { font-weight: 700; font-size: 0.92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playerbar .partist { color: var(--dim); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playerbar .pstatus { color: var(--text); font-size: 0.72rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.playerbar .transport { display: flex; align-items: center; gap: 0.15rem; flex: none; }
.playerbar .transport button { width: 38px; height: 38px; border-radius: 50%; font-size: 0.95rem; }
/* Spotify's bottom-player treatment (Max, 2026-10-13): the toggle is a
   plain WHITE CIRCLE with a dark glyph; the skips are small plain white
   triangles — no double-arrow fast-forward/rewind icons, no circle
   behind them. */
.playerbar .transport .play {
  width: 42px; height: 42px; background: #fff; color: #111; font-size: 1.05rem;
  display: inline-flex; align-items: center; justify-content: center;
}
/* The toggle's icons are drawn SVGs, not glyphs (Max, 2026-10-13):
   iOS paints the pause character as a blue emoji. The SVG fills with
   the button's dark glyph color and sits centered in the circle. */
.playerbar .transport .play svg { width: 17px; height: 17px; display: block; fill: currentColor; }
.playerbar .transport .skip { color: #fff; font-size: 0.78rem; background: none; }
.playerbar .progress {
  position: absolute; top: -2px; left: 0; height: 2px;
  background: #fff; opacity: 0.85;
}
.playerbar.notlive .pmeta, .playerbar.notlive .pcover { opacity: 0.55; }
.playerbar button:disabled { opacity: 0.45; cursor: default; }
.playerbar .device-chip {
  flex: none; max-width: 32vw;
  display: flex; align-items: center; gap: 0.3rem;
  padding: 0.32rem 0.6rem; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--dim); font-size: 0.78rem; font-weight: 600; white-space: nowrap;
}
.playerbar .device-chip .dot { color: var(--sage); font-size: 0.55rem; }
.playerbar .device-chip .dname { overflow: hidden; text-overflow: ellipsis; }
.playerbar .device-chip .chev { color: var(--dim); }

/* --- device sheet -------------------------------------------------------------- */

#device-sheet-wrap { position: fixed; inset: 0; z-index: 50; }
.sheet-backdrop { position: absolute; inset: 0; background: rgba(4, 8, 5, 0.55); }
.sheet {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: var(--surface); border-top: 1px solid var(--border);
  border-radius: 16px 16px 0 0;
  padding: 1rem 1rem calc(1.1rem + env(safe-area-inset-bottom));
  max-height: 72vh; overflow-y: auto;
}
@media (min-width: 900px) {
  .sheet { left: 50%; right: auto; transform: translateX(-50%); width: 30rem; max-width: 94vw; }
}
.sheet-head { display: flex; align-items: center; margin-bottom: 0.4rem; }
.sheet-head h2 { margin: 0; font-size: 1.05rem; flex: 1; }
.sheet-close {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  background: var(--surface2); border: 1px solid var(--border); color: var(--dim);
}
.sheet-err {
  color: #ff9d8a; background: color-mix(in srgb, #ff9d8a 12%, transparent);
  border: 1px solid color-mix(in srgb, #ff9d8a 45%, transparent);
  border-radius: 8px; padding: 0.55rem 0.7rem; font-size: 0.88rem; margin: 0.4rem 0;
}
.sheet-note, .sheet-loading { margin: 0.6rem 0.2rem; font-size: 0.9rem; }
.sheet-refresh { width: 100%; margin-top: 0.7rem; }
.device-row {
  display: flex; align-items: center; gap: 0.7rem; width: 100%;
  text-align: left; padding: 0.6rem 0.5rem; border-radius: 10px;
}
.device-row:hover { background: var(--surface2); }
.device-row.active { background: var(--surface2); }
.device-row:disabled { opacity: 0.45; cursor: default; }
.device-row .d-ic { font-size: 1.15rem; flex: none; }
.device-row .d-meta { min-width: 0; flex: 1; }
.device-row .d-name { display: block; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.device-row .d-type { display: block; color: var(--dim); font-size: 0.8rem; }
.device-row .d-on { color: var(--sage); font-size: 0.6rem; flex: none; }
.spin { display: inline-block; animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* --- generic bits ----------------------------------------------------------- */

.pills { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
.pill {
  padding: 0.32rem 0.75rem; border-radius: 999px; border: 1px solid var(--border);
  background: var(--surface); color: var(--dim); font-weight: 600; font-size: 0.85rem;
  white-space: nowrap;
}
.pill.active { color: var(--text); border-color: #fff; background: var(--surface2); }
.pill .cnt { color: #fff; font-weight: 700; }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 1rem 1.1rem; margin: 0.8rem 0;
}
.section-head {
  display: flex; align-items: baseline; gap: 0.6rem; margin: 1.4rem 0 0.5rem;
}
.section-head h2 { font-size: 1.05rem; margin: 0; }
.section-head .sub { color: var(--dim); font-size: 0.82rem; }
.section-head .spacer { flex: 1; }
.eyebrow { color: var(--text); font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.btn {
  padding: 0.45rem 0.9rem; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface2); font-weight: 600;
}
.btn.primary { background: #fff; border-color: #fff; color: #141414; }
/* Detail-page Play (Max, 2026-10-13 refinement): a BARE small white
   arrow — no fill, no border, no circle. "It should just show play."
   The white-circle treatment belongs to the bottom player bar only. */
.btn.bareplay {
  background: none; border-color: transparent; color: #fff;
  font-size: 1rem; line-height: 1; padding: 0.3rem 0.45rem;
}
/* Detail-header Pin is an icon-only pushpin (Max, 2026-10-13 header
   cleanup): a muted outline while unpinned, filled white while pinned. */
.btn.pin-btn { padding: 0.35rem 0.5rem; line-height: 0; color: var(--dim); }
.btn.pin-btn svg {
  width: 17px; height: 17px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round;
}
.btn.pin-btn.pinned { color: #fff; }
.btn.pin-btn.pinned svg { fill: currentColor; }
.btn.small { padding: 0.28rem 0.6rem; font-size: 0.82rem; border-radius: 7px; }
.icon-btn {
  width: 32px; height: 32px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--surface2); border: 1px solid var(--border); font-size: 0.85rem;
}
/* Wall-row play follows the same bare-arrow direction as the detail
   pages: a small white triangle, no fill — the 32px circle survives
   only as an invisible tap target. */
.icon-btn.play { background: none; border-color: transparent; color: #fff; font-weight: 700; }
.icon-btn:disabled { opacity: 0.4; }
.text-input, .select-input, textarea.text-input {
  padding: 0.5rem 0.7rem; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface); width: 100%;
}
.search-row { display: flex; gap: 0.5rem; }
.search-row .text-input { flex: 1; }

#flash {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 60;
  bottom: calc(var(--tabbar-h) + var(--playerbar-h) + env(safe-area-inset-bottom) + 0.8rem);
  background: var(--surface2); border: 1px solid rgba(255, 255, 255, 0.4); color: var(--text);
  padding: 0.5rem 0.9rem; border-radius: 999px; font-size: 0.85rem;
  max-width: min(92vw, 34rem); text-align: center;
  box-shadow: 0 6px 24px rgba(0,0,0,0.35);
}
@media (min-width: 900px) { #flash { bottom: calc(var(--playerbar-h) + 1rem); } }

/* --- covers ------------------------------------------------------------------- */

.cover { position: relative; overflow: hidden; background: var(--surface2); flex: none; }
.cover .tile {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-weight: 700; color: var(--dim); background: linear-gradient(140deg, var(--surface2), var(--forest));
}
.cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* --- album / playlist rows ------------------------------------------------------- */

.arow {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.55rem 0.4rem; border-radius: 10px; cursor: pointer;
}
.arow:hover { background: var(--surface); }
.arow .cover { width: 48px; height: 48px; border-radius: 7px; }
.arow .cover .tile { font-size: 1rem; }
.arow .meta { min-width: 0; flex: 1; }
.arow .t { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.arow .a { color: var(--dim); font-size: 0.85rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.arow .stats { color: var(--dim); font-size: 0.8rem; text-align: right; white-space: nowrap; }
.arow .stats b { color: var(--text); font-weight: 700; }
.arow .rank { color: var(--dim); font-size: 0.85rem; width: 1.9rem; text-align: right; flex: none; }
.arow .rowbtns { display: flex; gap: 0.3rem; flex: none; }

/* --- detail ----------------------------------------------------------------------- */

/* Header cleanup (Max, 2026-10-13): no backdrop band, no card behind
   the header — the cover sits directly on the page's gradient field,
   defined only by a 1px hairline edge and a soft drop shadow. */
.detail-head { margin-bottom: 1rem; }
.detail-head .inner { display: flex; gap: 1rem; }
.detail-head .cover {
  width: 104px; height: 104px; border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.13);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.35);
}
.detail-head .cover .tile { font-size: 1.8rem; }
.detail-head h1 { font-size: 1.25rem; margin: 0.1rem 0 0.2rem; line-height: 1.25; }
.detail-head .meta-line { color: var(--dim); font-size: 0.88rem; }
.detail-head .actions { display: flex; gap: 0.5rem; margin-top: 0.7rem; flex-wrap: wrap; }
.back-btn { margin: 0.4rem 0 0.8rem; color: var(--dim); font-weight: 600; }

.tracklist { list-style: none; margin: 0; padding: 0; }
.tracklist li {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.42rem 0.4rem; border-radius: 8px; cursor: pointer;
}
.tracklist li:hover { background: var(--surface); }
.tracklist .n { color: var(--dim); width: 1.6rem; text-align: right; font-size: 0.82rem; flex: none; }
.tracklist .tt { min-width: 0; flex: 1; }
.tracklist .tt .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tracklist .tt .a { color: var(--dim); font-size: 0.8rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tracklist .plays { color: var(--dim); font-size: 0.8rem; white-space: nowrap; }
.tracklist .plays b { color: var(--text); }
.heart { width: 1.2rem; text-align: center; flex: none; font-size: 0.95rem; }
.heart.on { color: var(--heart); }
.heart.off { color: var(--dim); opacity: 0.75; }
@media (min-width: 900px) {
  .tracklist { column-count: 2; column-gap: 2rem; }
  .tracklist li { break-inside: avoid; }
}

/* --- story ------------------------------------------------------------------------- */

.story-sticky {
  position: sticky; top: var(--topbar-h); z-index: 20;
  padding: 0.6rem 0; margin: 0 -0.2rem;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
}
.year-head {
  display: flex; align-items: baseline; gap: 0.6rem; width: 100%; text-align: left;
  padding: 0.6rem 0.2rem; border-bottom: 1px solid var(--border); margin-top: 1rem;
}
.year-head .y { font-size: 1.3rem; font-weight: 800; }
.year-head .sub { color: var(--dim); font-size: 0.85rem; }
.year-head .chev { margin-left: auto; color: var(--dim); }
.toptracks { list-style: none; margin: 0.2rem 0 0.6rem 3.4rem; padding: 0; }
.toptracks li { display: flex; gap: 0.5rem; padding: 0.22rem 0; font-size: 0.9rem; align-items: center; }
.toptracks .p { color: var(--text); font-weight: 700; font-size: 0.8rem; }

/* --- RS500 --------------------------------------------------------------------------- */

.rs-head { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin: 0.6rem 0; }
.rs-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 0.8rem; }
.rs-tile { cursor: pointer; }
.rs-tile .cover { width: 100%; aspect-ratio: 1; border-radius: 9px; }
.rs-tile .cover .tile { font-size: 1.3rem; }
.rank-chip {
  position: absolute; left: 6px; bottom: 6px; z-index: 2;
  background: rgba(10, 14, 11, 0.82); color: #f2f5f0;
  font-size: 0.72rem; font-weight: 700; padding: 0.12rem 0.45rem; border-radius: 999px;
}
.rs-badges { position: absolute; right: 6px; top: 6px; z-index: 2; display: flex; gap: 4px; }
.rs-badges .b {
  background: rgba(10, 14, 11, 0.82); color: #ffd9a8; font-size: 0.7rem; font-weight: 700;
  padding: 0.12rem 0.4rem; border-radius: 999px;
}
.rs-badges .b.done { color: #a8e6b0; }
.rs-tile .tt { margin-top: 0.35rem; font-size: 0.82rem; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.rs-tile .ta { color: var(--dim); font-size: 0.75rem; overflow-wrap: anywhere; }
.rs-detail .field { margin: 0.8rem 0; }
.rs-detail label { display: block; color: var(--dim); font-size: 0.8rem; font-weight: 600; margin-bottom: 0.3rem; }
.rating-row { display: flex; align-items: center; gap: 0.6rem; }
.rating-row input[type="range"] { flex: 1; accent-color: #fff; }
.rating-val { font-size: 1.2rem; font-weight: 800; min-width: 2.6rem; text-align: center; }

/* --- gatefold (RS500 pilot: Pet Sounds only) ----------------------------------
   The detail as a physical LP sleeve. The stage is a square box holding
   three layers: the tracklist panel (base), the spine rail the folded
   cover leaves behind at the left (middle), and the cover itself,
   hinged on its left edge (top). Folding is perspective rotateY driven
   from wireGatefold — transform/opacity only; the stage clips the
   swing so the page never gains horizontal overflow. */
.gatefold { margin-bottom: 1rem; }
.gf-stage {
  position: relative; width: min(100%, 430px); aspect-ratio: 1; margin: 0 auto;
  perspective: 1150px; border-radius: 10px; overflow: hidden;
  background: var(--surface); border: 1px solid var(--border);
}
.gf-panel {
  position: absolute; inset: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 0.75rem 0.75rem 0.75rem 3.5rem; visibility: hidden;
  touch-action: pan-y; background: var(--surface);
}
.gatefold[data-open="1"] .gf-panel { visibility: visible; }
.gf-panel.gf-anim { transition: transform 0.38s cubic-bezier(0.3, 0.7, 0.3, 1); }
.gf-panel-head {
  display: flex; align-items: baseline; gap: 0.6rem;
  padding-bottom: 0.45rem; margin-bottom: 0.35rem; border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}
.gf-panel .tracklist { column-count: 1; }
.gf-rail {
  position: absolute; left: 0; top: 0; bottom: 0; width: 44px; z-index: 2;
  display: none; flex-direction: column; align-items: center; gap: 0.65rem;
  padding: 0.6rem 0; background: var(--surface2);
  border-right: 1px solid var(--border); cursor: pointer;
}
.gatefold[data-open="1"] .gf-rail { display: flex; }
.gf-rail-cover { display: block; width: 30px; height: 30px; border-radius: 4px; }
.gf-rail-cover .tile { font-size: 0.6rem; }
.gf-rail-title {
  writing-mode: vertical-rl; color: var(--dim); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; white-space: nowrap;
  overflow: hidden; max-height: 46%;
}
.gf-rail-x { margin-top: auto; color: var(--dim); font-size: 0.95rem; }
.gf-cover {
  position: absolute; inset: 0; z-index: 3; cursor: pointer;
  transform-origin: 0% 50%; will-change: transform;
  touch-action: pan-y; user-select: none; -webkit-user-select: none;
}
.gatefold[data-open="1"] .gf-cover { pointer-events: none; }
.gf-cover.gf-anim { transition: transform 0.38s cubic-bezier(0.3, 0.7, 0.3, 1); }
.gf-cover.gf-anim .gf-sleeve { transition: opacity 0.38s ease; }
.gf-cover.gf-anim .gf-shade { transition: opacity 0.38s ease; }
.gf-sleeve {
  position: absolute; inset: 0; overflow: hidden; background: var(--surface2);
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.gf-sleeve .gf-art { position: absolute; inset: 0; width: 100%; height: 100%; }
.gf-sleeve .gf-art .tile { font-size: 2.6rem; }
.gf-sleeve .gf-art .rank-chip { z-index: 4; }
.gf-sleeve img { -webkit-user-drag: none; }
.gf-spine {
  position: absolute; left: 0; top: 0; bottom: 0; width: 15px; z-index: 2;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.16) 55%, rgba(255, 255, 255, 0.1) 78%, rgba(0, 0, 0, 0.3));
  box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.4);
  pointer-events: none;
}
.gf-shade { position: absolute; inset: 0; z-index: 3; background: #000; opacity: 0; pointer-events: none; }
.gf-meta { width: min(100%, 430px); margin: 0.85rem auto 0; }
.gf-meta h1 { font-size: 1.3rem; margin: 0.1rem 0 0.2rem; line-height: 1.25; }
.gf-meta .meta-line { color: var(--dim); font-size: 0.88rem; }
.gf-meta .actions { display: flex; gap: 0.5rem; margin-top: 0.7rem; flex-wrap: wrap; }
.gf-hint { font-size: 0.8rem; margin: 0.6rem 0 0; }
.gatefold[data-open="1"] .gf-hint { display: none; }
/* Reduced motion: no 3D, no drag-follow — the open state fades the
   cover out (wireGatefold skips the pointer machinery entirely). */
@media (prefers-reduced-motion: reduce) {
  .gf-cover { transition: opacity 0.25s ease, visibility 0s linear 0.25s; will-change: auto; }
  .gatefold[data-open="1"] .gf-cover { transform: none !important; opacity: 0; visibility: hidden; }
  .gatefold[data-open="0"] .gf-cover { transition: opacity 0.25s ease, visibility 0s; }
  .gf-panel.gf-anim, .gf-cover.gf-anim { transition: none; }
}

/* --- now playing (pilot: Pet Sounds) -------------------------------------------
   Full-screen album view over the tabs. Front (Living Cover): the
   square cover large and sharp, the tall screen around it filled by
   the album itself — a heavily blurred blow-up of the same artwork
   over a gradient built from the field's --amb-* palette. Back (Flip
   to the Back): the tracklist on a frosted panel, scrolling its own
   column. The flip is a 3D card turn (transform only); the close
   chevron and a swipe-down both leave. Chrome inside follows the
   player bar's language: white circle toggle with drawn icons, plain
   white triangle skips. */
#nowplaying {
  position: fixed; inset: 0; z-index: 45; overflow: hidden;
  color: var(--text);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--amb-a) 50%, #04060a),
    color-mix(in srgb, var(--amb-b) 30%, #04060a) 55%,
    #04060a);
}
.np-bg { position: absolute; inset: 0; overflow: hidden; }
.np-blur {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: blur(64px) saturate(1.35); transform: scale(1.45); opacity: 0.55;
}
.np-dim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(2, 4, 6, 0.28), rgba(2, 4, 6, 0.12) 40%, rgba(2, 4, 6, 0.55));
}
.np-close {
  position: absolute; z-index: 5;
  top: calc(env(safe-area-inset-top) + 0.4rem); left: 0.65rem;
  width: 40px; height: 40px; font-size: 1.55rem; line-height: 1; color: #fff;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
}
.np-stage { position: absolute; inset: 0; perspective: 1200px; transition: transform 0.32s ease; }
.np-stage.dragging { transition: none; }
.np-card {
  position: absolute; inset: 0;
  transform-style: preserve-3d; will-change: transform;
  transition: transform 0.6s cubic-bezier(0.3, 0.7, 0.3, 1);
}
#nowplaying.flipped .np-card { transform: rotateY(180deg); }
.np-face {
  position: absolute; inset: 0; overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
#nowplaying:not(.flipped) .np-back { pointer-events: none; }
#nowplaying.flipped .np-front { pointer-events: none; }
.np-front {
  display: flex; flex-direction: column; align-items: center;
  padding: calc(env(safe-area-inset-top) + 3.4rem) 1.25rem calc(1.3rem + env(safe-area-inset-bottom));
}
.np-cover {
  width: min(74vw, 320px); aspect-ratio: 1; border-radius: 12px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5), 0 3px 10px rgba(0, 0, 0, 0.4);
}
.np-cover .tile { font-size: 2.4rem; }
.np-info {
  margin-top: auto; width: 100%; max-width: 26rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.55rem;
}
.np-title { font-size: 1.22rem; font-weight: 800; text-align: center; line-height: 1.25; }
.np-artist { color: rgba(255, 255, 255, 0.75); font-size: 0.98rem; text-align: center; margin-top: -0.35rem; }
.np-progress { width: 100%; height: 3px; border-radius: 99px; background: rgba(255, 255, 255, 0.18); overflow: hidden; }
.np-progress-fill { height: 100%; background: #fff; border-radius: 99px; }
.np-transport {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.45rem 0.9rem; border-radius: 999px;
  background: rgba(255, 255, 255, 0.09); border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(16px);
}
.np-transport button { display: inline-flex; align-items: center; justify-content: center; flex: none; }
.np-toggle { width: 46px; height: 46px; border-radius: 50%; background: #fff; color: #111; }
.np-toggle svg { width: 18px; height: 18px; display: block; fill: currentColor; }
.np-skip { width: 40px; height: 40px; color: #fff; font-size: 0.8rem; background: none; }
.np-hint { color: rgba(255, 255, 255, 0.55); font-size: 0.78rem; margin: 0.1rem 0 0; }
.np-back {
  transform: rotateY(180deg);
  display: flex; flex-direction: column;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(22px);
}
.np-back-head {
  display: flex; align-items: center; gap: 0.75rem; width: 100%; text-align: left; flex: none;
  padding: calc(env(safe-area-inset-top) + 0.9rem) 1rem 0.8rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.np-thumb { width: 44px; height: 44px; border-radius: 6px; }
.np-thumb .tile { font-size: 0.85rem; }
.np-back-meta { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.np-back-title { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-back-artist { color: var(--dim); font-size: 0.82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-back-flip { color: var(--dim); font-size: 0.8rem; font-weight: 600; flex: none; }
.np-tracks {
  flex: 1; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y;
  padding: 0.4rem 0.6rem calc(1rem + env(safe-area-inset-bottom));
}
.np-tracks .tracklist { column-count: 1; max-width: 44rem; margin: 0 auto; }
.np-tracks .tracklist li.playing { background: rgba(255, 255, 255, 0.08); }
.np-tracks .tracklist li.playing .t { font-weight: 700; }
.np-tracks .tracklist li.playing .n { color: var(--sage); font-weight: 700; }
.np-loading { padding: 0.8rem 0.4rem; max-width: 44rem; margin: 0 auto; }
/* Reduced motion: no 3D turn and no drag (wireNpSwipe also stands
   down) — the faces cross-fade in place instead. */
@media (prefers-reduced-motion: reduce) {
  .np-stage { transition: none; }
  .np-card { transition: none; transform: none !important; }
  .np-back { transform: none; opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0s linear 0.25s; }
  .np-front { transition: opacity 0.25s ease, visibility 0s; }
  #nowplaying.flipped .np-back { opacity: 1; visibility: visible; transition: opacity 0.25s ease, visibility 0s; }
  #nowplaying.flipped .np-front { opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0s linear 0.25s; }
}

/* --- auth ---------------------------------------------------------------------------- */

.auth-wrap { max-width: 26rem; margin: 12vh auto 0; padding: 0 1rem; }
.auth-wrap h1 { font-size: 1.4rem; }
.auth-wrap .card { margin-top: 1rem; }
.auth-wrap input { margin: 0.4rem 0; }
