/* ==========================================================================
   961 Music Web Player — Core Theme (Phase 1)
   Dark theme inspired by Winamp Classic: deep navy/black chassis,
   phosphor-green accents, LCD-style typography for meta text.
   Mobile-first, touch targets >= 48px.
   ========================================================================== */

:root {
  --bg-0: #05070c;
  --bg-1: #0a0e16;
  --bg-2: #10151f;
  --bg-3: #171d2a;
  --line: #232b3a;

  --text-0: #eef2f6;
  --text-1: #9aa7bb;
  --text-2: #5f6b80;

  --accent: #39ff14;      /* Winamp phosphor green */
  --accent-dim: #1f8a0d;
  --accent-soft: rgba(57, 255, 20, 0.12);
  --accent-2: #ff9d2f;     /* amber LCD secondary accent */

  --danger: #ff4d4f;

  --radius-s: 6px;
  --radius-m: 10px;
  --radius-l: 16px;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);

  --app-bar-h: 56px;
  --player-bar-h: 72px;

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  background: var(--bg-0);
  color: var(--text-0);
  font-family: "Segoe UI", "Cairo", "Tahoma", system-ui, -apple-system, sans-serif;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; }

/* ---------- Splash ---------- */
.splash {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: radial-gradient(circle at 50% 40%, var(--bg-2), var(--bg-0));
  animation: splash-out 0.5s ease 1.1s forwards;
}
.splash__mark {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  height: 40px;
}
.eq-bar {
  width: 7px;
  border-radius: 3px;
  background: var(--accent);
  box-shadow: 0 0 10px var(--accent-soft);
  animation: eq 0.9s ease-in-out infinite;
}
.eq-bar:nth-child(1){ height: 40%; animation-delay: 0s; }
.eq-bar:nth-child(2){ height: 70%; animation-delay: .1s; }
.eq-bar:nth-child(3){ height: 100%; animation-delay: .2s; }
.eq-bar:nth-child(4){ height: 55%; animation-delay: .3s; }
.eq-bar:nth-child(5){ height: 30%; animation-delay: .4s; }
@keyframes eq {
  0%, 100% { transform: scaleY(0.4); }
  50% { transform: scaleY(1); }
}
.splash__title {
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-1);
  text-transform: uppercase;
  font-size: 13px;
}
@keyframes splash-out {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

/* ---------- App shell ---------- */
.app-shell {
  min-height: 100%;
  display: flex;
  flex-direction: column;
}

.app-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  height: calc(var(--app-bar-h) + var(--safe-top));
  padding-top: var(--safe-top);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: calc(8px + var(--safe-left));
  padding-right: calc(8px + var(--safe-right));
  background: rgba(10, 14, 22, 0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.app-bar__icon {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: none;
  color: var(--text-1);
  border-radius: var(--radius-m);
}
.app-bar__icon:active { background: var(--bg-3); color: var(--accent); }

.offline-banner {
  position: sticky;
  top: 0;
  z-index: 45;
  background: rgba(255, 157, 47, .14);
  border-bottom: 1px solid rgba(255, 157, 47, .35);
  color: var(--accent-2);
  font-size: 12.5px;
  font-weight: 700;
  text-align: center;
  padding: 8px 12px;
}

.theme-popover {
  position: fixed;
  top: calc(var(--safe-top) + var(--app-bar-h) + 6px);
  inset-inline-end: 8px;
  z-index: 60;
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 140px;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
}
.theme-option {
  text-align: start;
  padding: 10px 12px;
  min-height: 44px;
  display: flex;
  align-items: center;
  border-radius: var(--radius-s);
  background: none;
  border: none;
  color: var(--text-1);
  font-size: 13.5px;
}
.theme-option:active { background: var(--bg-2); }
.theme-option.is-active { color: var(--accent); font-weight: 700; }

.app-bar__brand { display: flex; align-items: center; gap: 8px; }
.brand__dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}
.brand__logo {
  width: 24px; height: 24px;
  border-radius: 6px;
  object-fit: cover;
}
.brand__name {
  font-weight: 800;
  letter-spacing: 0.04em;
  font-size: 15px;
}

/* ---------- Side nav (mobile drawer) ---------- */
.side-nav {
  position: fixed;
  inset-inline-start: 0;
  top: 0;
  bottom: 0;
  width: min(78vw, 300px);
  background: var(--bg-1);
  border-inline-end: 1px solid var(--line);
  padding-top: calc(var(--safe-top) + 16px);
  padding-bottom: calc(var(--safe-bottom) + 16px);
  padding-left: calc(12px + var(--safe-left));
  padding-right: calc(12px + var(--safe-right));
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  touch-action: pan-y;
  transform: translateX(-105%);
  transition: transform .25s ease;
  z-index: 40;
}
/* BLOCKER-MOBILE-RTL-01 fix: `inset-inline-start:0` is a logical property — it
   correctly flips to anchor the drawer at the RIGHT edge in RTL (Arabic), matching
   `border-inline-end` (also logical) flipping to the left border. But `translateX`
   is a PHYSICAL transform — it always moves in the negative-X (left) direction
   regardless of `dir`, with no logical equivalent in CSS. The closed-state
   transform therefore never actually matched the drawer's real anchored edge in
   RTL: a drawer anchored at right:0 that's told to translate further LEFT moves
   INTO the viewport instead of off-screen past its own right edge — reproduced
   directly: closed-state rect.right measured at 75px in Arabic (should be ≤0,
   fully off-screen) at 390px viewport width. The open state (transform:
   translateX(0), an identity transform) was never affected by this — only the
   closed state's *direction* of travel was wrong, which is why the drawer looked
   broken/"leaking" specifically when nominally closed, not while actually open. */
[dir="rtl"] .side-nav { transform: translateX(105%); }
.side-nav.is-open { transform: translateX(0); }

.side-nav__link {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 12px;
  border-radius: var(--radius-m);
  color: var(--text-1);
  font-size: 14px;
  font-weight: 600;
}
.side-nav__link.is-active,
.side-nav__link:active {
  background: var(--accent-soft);
  color: var(--accent);
}

.side-nav__overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.55);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease;
  z-index: 30;
}
.side-nav__overlay.is-open { opacity: 1; pointer-events: auto; }

/* ---------- Main content ---------- */
.main-content {
  flex: 1;
  min-width: 0; /* S1 fix: a flex item's default min-width is `auto`, which lets its
                   own content (e.g. a wide grid) force it — and the whole page —
                   wider than the viewport when it sits beside the sticky sidebar
                   at desktop widths. This is the actual root cause of the
                   reported horizontal overflow, not any single grid or card. */
  padding-top: 20px;
  padding-right: calc(16px + var(--safe-right));
  padding-bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 24px);
  padding-left: calc(16px + var(--safe-left));
  /* W3-width: was max-width:960px. With the 220px desktop sidebar (see
     @media (min-width:900px) .side-nav below), a 1760px screen had roughly
     580px of dead space to the right of a centered 960px column -- visible
     directly in the shipped screenshots. 960px was never a design choice for
     wide screens, it was the mobile-first base value that nothing later
     raised. The grid system underneath (.track-grid in browse.css) already
     drives its column count from this container's own container-query size
     via auto-fit + minmax(150px,1fr) -- it was BUILT to respond to a wider
     box, it just never got one. Raising the cap is therefore sufficient on
     its own; no grid rule needs to change alongside it. */
  max-width: 1440px;
  margin-inline: auto;
  width: 100%;
  /* S1.1 BLOCKER-UI-01 fix: makes real available width (not raw viewport width)
     queryable by descendants — see .track-grid/.playlist-grid in browse.css,
     which use this instead of viewport-based @media breakpoints so they can
     never again be handed a column count wider than the space actually available
     (desktop sidebar, browser zoom, etc. all correctly change this container's
     own size, which is what the grid now actually responds to). */
  container-type: inline-size;
  container-name: main;
}

.hero { padding: 24px 4px 8px; }
.hero__title {
  font-size: clamp(22px, 6vw, 32px);
  font-weight: 800;
  margin: 0 0 8px;
  line-height: 1.25;
}
.hero__subtitle {
  color: var(--text-1);
  margin: 0;
  font-size: 14.5px;
}

.placeholder-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr)); /* S1 fix: see .track-grid note in browse.css */
  gap: 12px;
  margin-top: 24px;
}
/* S1.1 BLOCKER-UI-01 fix — same container-aware approach as .track-grid (browse.css). */
@container main (min-width: 640px) {
  .placeholder-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
@supports not (container-type: inline-size) {
  @media (min-width: 640px) {
    .placeholder-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  }
}
.placeholder-card {
  aspect-ratio: 1;
  border-radius: var(--radius-l);
  background: linear-gradient(160deg, var(--bg-2), var(--bg-3));
  border: 1px solid var(--line);
}

.phase-note {
  margin-top: 28px;
  padding: 12px 14px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-m);
  color: var(--text-2);
  font-size: 12.5px;
  line-height: 1.6;
}

/* ---------- Bottom player bar ---------- */
.player-bar {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 25;
  height: calc(var(--player-bar-h) + var(--safe-bottom));
  padding-bottom: var(--safe-bottom);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-left: calc(12px + var(--safe-left));
  padding-right: calc(12px + var(--safe-right));
  background: rgba(16, 21, 31, 0.92);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
}
.player-bar__meta { display: flex; align-items: center; gap: 10px; min-width: 0; }
.player-bar__art {
  width: 42px; height: 42px;
  border-radius: var(--radius-s);
  background: var(--bg-3);
  border: 1px solid var(--line);
  flex-shrink: 0;
}
.player-bar__text { display: flex; flex-direction: column; min-width: 0; }
.player-bar__title {
  font-size: 13px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 46vw;
}
.player-bar__artist { font-size: 11.5px; color: var(--text-2); }

.player-bar__controls { display: flex; align-items: center; gap: 4px; }
.ctrl-btn {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: none;
  background: var(--bg-3);
  color: var(--text-1);
  font-size: 15px;
  display: grid;
  place-items: center;
}
.ctrl-btn--play {
  width: 48px; height: 48px;
  background: var(--accent);
  color: #05130a;
}
.ctrl-btn:disabled { opacity: .5; }

/* ---------- Install toast ---------- */
.install-toast {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 12px);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  box-shadow: 0 12px 30px rgba(0,0,0,.4);
  font-size: 13px;
}
.install-toast span { flex: 1; color: var(--text-0); }
.install-toast button {
  min-height: 36px;
  padding: 0 12px;
  border-radius: var(--radius-s);
  border: none;
}
#installBtn { background: var(--accent); color: #05130a; font-weight: 700; }
#installDismiss { background: transparent; color: var(--text-2); }

/* ---------- Desktop layout ---------- */
@media (min-width: 900px) {
  .side-nav {
    position: sticky;
    transform: none;
    width: 220px;
    top: var(--app-bar-h);
    height: calc(100vh - var(--app-bar-h));
  }
  [dir="rtl"] .side-nav {
    transform: none;
  }
  .app-shell { flex-direction: row; flex-wrap: wrap; }
  .app-bar { width: 100%; }
  .main-content { flex: 1; }
  .side-nav__overlay { display: none; }
  #menuToggle { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .eq-bar { animation: none !important; }
  .splash {
    animation: none !important;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
}

/* ---------------- Bugfix: [hidden] must always win ----------------
 * Several components (install toast, theme/language popover, live badge,
 * search bar) set their own `display` value unconditionally, which — per
 * normal CSS specificity — silently overrides the browser's built-in
 * `[hidden] { display: none }` rule. That made them stay visible forever
 * regardless of the `hidden` attribute JS was toggling. This single rule
 * (last in the cascade, !important) guarantees `hidden` always wins,
 * site-wide, regardless of whatever `display` a component sets.
 */
[hidden] { display: none !important; }

/* ---------------- Safety net: no image can ever overflow its container ----------------
 * Every cover-art element in the app is sized via a fixed width/height (or aspect-ratio)
 * plus `background-size: cover` on its own class — but that means correct sizing depends
 * on each new spot remembering to set it. This is a blanket guarantee instead: any raw
 * <img> tag anywhere always respects its container's width, and any element using an
 * inline `background-image` (the pattern this app uses for cover art) always gets
 * cover/center sizing as a default — so a track/album/video thumbnail can never render
 * at its original (possibly huge) resolution and break the layout, even in a spot that
 * forgets to size it explicitly.
 */
img { max-width: 100%; height: auto; display: block; }
[style*="background-image"] {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* ---------------- S1 stabilization: final defensive safety net ----------------
 * The actual overflow sources (grid tracks without a zero minimum, and
 * .main-content missing min-width:0 beside the desktop sidebar) are fixed
 * above and in browse.css — this is only a last-resort net for anything not
 * yet audited, per the phase brief. It must never be the primary fix.
 */
html, body { overflow-x: hidden; max-width: 100%; }

/* ---------------- S1 PWA Readiness additions ---------------- */

/* Persistent "Install App" menu entry (PWA-05) — reuses .side-nav__link's layout
   but resets the plain <button> defaults an <a> doesn't need. */
#installMenuEntry {
  background: none;
  border: none;
  width: 100%;
  text-align: start;
  cursor: pointer;
  font: inherit;
}

/* Update-available toast (PWA-10) reuses .install-toast's existing look;
   just needs its own button spacing since it has three children instead of two. */
#swUpdateToast button { margin-inline-start: 8px; }
#swUpdateReloadBtn { background: var(--accent); color: #05130a; font-weight: 700; border: none; border-radius: var(--radius-s); padding: 6px 12px; }
#swUpdateDismissBtn { background: transparent; color: var(--text-2); border: none; }


/* ---------------- IOS-SAFARI-01-R3: short-landscape mobile shell ----------------
 * Large iPhones can expose a CSS landscape width above the 900px desktop
 * breakpoint. Width alone must therefore never switch the mobile app into the
 * persistent desktop-sidebar composition when the viewport is short/touch-like.
 */
@media (orientation: landscape) and (max-height: 520px) {
  :root {
    --app-bar-h: 50px;
    --player-bar-h: 60px;
  }

  .app-shell {
    flex-direction: column;
    flex-wrap: nowrap;
    min-height: 100dvh;
  }

  .app-bar {
    width: 100%;
    min-height: calc(var(--app-bar-h) + var(--safe-top));
  }

  #menuToggle {
    display: grid;
  }

  .side-nav {
    position: fixed;
    inset-inline-start: 0;
    top: 0;
    bottom: 0;
    width: min(72vw, 300px);
    height: auto;
    padding-top: calc(var(--safe-top) + 10px);
    transform: translateX(-105%);
    z-index: 40;
  }

  [dir="rtl"] .side-nav {
    transform: translateX(105%);
  }

  .side-nav.is-open {
    transform: translateX(0);
  }

  .side-nav__overlay {
    display: block;
  }

  .main-content {
    flex: 1;
    width: 100%;
    max-width: 100%;
    margin-inline: 0;
    padding-top: 10px;
    padding-right: calc(14px + var(--safe-right));
    padding-left: calc(14px + var(--safe-left));
    padding-bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 16px);
  }

  .hero {
    padding: 10px 2px 6px;
  }

  .hero__title {
    font-size: clamp(22px, 4.2vw, 28px);
    line-height: 1.15;
    margin-bottom: 5px;
  }

  .hero__subtitle {
    font-size: 13px;
  }

  .player-bar {
    height: calc(var(--player-bar-h) + var(--safe-bottom));
    gap: 8px;
    padding-left: calc(10px + var(--safe-left));
    padding-right: calc(10px + var(--safe-right));
  }

  .player-bar__art {
    width: 38px;
    height: 38px;
  }

  .player-bar__title {
    max-width: min(40vw, 360px);
    font-size: 12.5px;
  }

  .player-bar__artist {
    font-size: 10.5px;
  }

  .ctrl-btn {
    width: 40px;
    height: 40px;
  }

  .ctrl-btn--play {
    width: 44px;
    height: 44px;
  }

  .install-toast {
    left: calc(10px + var(--safe-left));
    right: auto;
    width: min(430px, calc(100vw - var(--safe-left) - var(--safe-right) - 20px));
    bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 8px);
    padding: 9px 11px;
    gap: 8px;
    font-size: 12px;
    border-radius: 12px;
  }

  .install-toast button {
    min-height: 34px;
    padding-inline: 10px;
  }
}


/* ==========================================================================
   961 Music — SKIN-R2 premium production polish
   Restrained premium system; no decorative AI-template chrome.
   ========================================================================== */
:root {
  --bg-0: #070910;
  --bg-1: #0c0f18;
  --bg-2: #121725;
  --bg-3: #1a2030;
  --line: rgba(173, 184, 214, .14);
  --text-0: #f4f6fb;
  --text-1: #b7c0d5;
  --text-2: #758198;
  --accent: #E63946;
  --accent-dim: #BE2B38;
  --accent-soft: rgba(230, 57, 70, .14);
  --accent-2: #4bb8ff;
  --radius-s: 10px;
  --radius-m: 14px;
  --radius-l: 20px;
}

html, body {
  background:
    radial-gradient(900px 460px at 62% -10%, rgba(87, 78, 190, .12), transparent 60%),
    var(--bg-0);
}

.app-bar {
  background: rgba(8, 11, 18, .82);
  border-bottom-color: rgba(173,184,214,.10);
  backdrop-filter: blur(18px) saturate(125%);
}

.side-nav__link {
  border-radius: 12px;
  transition: background .18s ease, color .18s ease, transform .18s ease;
}
.side-nav__link:hover {
  background: rgba(255,255,255,.045);
  color: var(--text-0);
}
.side-nav__link.is-active {
  background: var(--accent-soft);
  color: #d9d2ff;
}

.player-bar {
  background: rgba(10, 13, 21, .94);
  border-top-color: rgba(173,184,214,.13);
  box-shadow: 0 -14px 36px rgba(0,0,0,.28);
  backdrop-filter: blur(20px) saturate(130%);
}
.player-bar__progress {
  background: rgba(255,255,255,.07);
}
.player-bar__progress span {
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  box-shadow: none;
}
.player-bar__art {
  border-radius: 10px;
  box-shadow: 0 5px 16px rgba(0,0,0,.26);
}
.player-bar__art.is-youtube {
  width: 62px;
  height: 35px;
  aspect-ratio: 16 / 9;
}
.player-bar__art.is-playing::after { display: none; }

.ctrl-btn {
  color: var(--text-1);
  transition: background .16s ease, color .16s ease, transform .16s ease;
}
.ctrl-btn:hover { background: rgba(255,255,255,.055); color: var(--text-0); }
.ctrl-btn--play {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 7px 22px rgba(230,57,70,.28);
}

/* Premium install/update surface; always clears the mini player and safe area. */
.install-toast {
  left: max(14px, var(--safe-left));
  right: max(14px, var(--safe-right));
  bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 14px);
  max-width: 560px;
  margin-inline: auto;
  gap: 12px;
  padding: 13px 14px;
  background: rgba(15, 19, 29, .96);
  border: 1px solid rgba(173,184,214,.16);
  border-radius: 16px;
  box-shadow: 0 18px 50px rgba(0,0,0,.38);
  backdrop-filter: blur(18px);
}
.install-toast span {
  line-height: 1.4;
  font-weight: 650;
}
.install-toast button {
  min-height: 40px;
  border-radius: 10px;
}
#installBtn,
#swUpdateReloadBtn {
  background: var(--accent);
  color: #fff;
  font-weight: 750;
  padding-inline: 15px;
}
#installDismiss,
#swUpdateDismissBtn {
  color: var(--text-1);
  width: 40px;
  padding: 0;
}
#installDismiss:hover,
#swUpdateDismissBtn:hover { background: rgba(255,255,255,.05); color: var(--text-0); }

@media (min-width: 900px) {
  /* The desktop mini player belongs to content, never under the persistent sidebar. */
  .player-bar {
    inset-inline-start: 220px;
  }
}

@media (orientation: landscape) and (max-height: 520px) {
  .player-bar { inset-inline-start: 0; }
}

@media (max-width: 560px) {
  .install-toast {
    align-items: center;
    padding: 12px;
  }
  .install-toast span { font-size: 12.5px; }
}


/* ==========================================================================
   961 Music — SKIN-06/07 final responsive + install/update polish
   ========================================================================== */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.install-toast__icon {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: rgba(230,57,70,.12);
  color: #d7d0ff;
  font-size: 18px;
  font-weight: 800;
}
.install-toast__copy {
  min-width: 0;
  flex: 1 1 auto;
}
#swUpdateToast::before {
  content: "↻";
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: rgba(75,184,255,.10);
  color: #a9dcff;
  font-size: 17px;
  font-weight: 800;
}

@media (max-width: 520px) {
  .install-toast {
    bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 12px);
    max-width: calc(100vw - var(--safe-left) - var(--safe-right) - 24px);
  }
  .install-toast__icon,
  #swUpdateToast::before {
    flex-basis: 30px;
    width: 30px;
    height: 30px;
  }
}

@media (hover: hover) and (pointer: fine) {
  .side-nav__link:hover,
  .ctrl-btn:hover,
  .install-toast button:hover {
    transform: translateY(-1px);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}


/* SHARE-01 — always-available song sharing */
.ctrl-btn--share { color: var(--text-1); }
.ctrl-btn--share:hover {
  color: #d9d2ff;
  background: rgba(230,57,70,.10);
}
.share-feedback {
  position: fixed;
  z-index: 1200;
  inset-inline-start: 50%;
  bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 18px);
  transform: translateX(-50%);
  width: max-content;
  max-width: min(88vw, 420px);
  padding: 10px 14px;
  border: 1px solid rgba(173,184,214,.16);
  border-radius: 12px;
  background: rgba(13,17,27,.96);
  color: var(--text-0);
  box-shadow: 0 14px 38px rgba(0,0,0,.32);
  backdrop-filter: blur(16px);
  font-size: 12.5px;
  font-weight: 700;
  text-align: center;
}
[dir="rtl"] .share-feedback { transform: translateX(50%); }
@media (max-width: 520px) {
  .ctrl-btn--share { min-width: 40px; min-height: 40px; }
  .share-feedback { bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 12px); }
}


/* ==========================================================================
   961 Music — SKIN-R3 final rendered visual closure
   Fixes observed mobile install overlap and tightens premium hierarchy.
   ========================================================================== */

/* Mobile hero should feel intentional, not like a landing-page billboard. */
@media (max-width: 640px) {
  .hero {
    padding: 18px 4px 4px;
  }
  .hero__title {
    font-size: clamp(27px, 7.3vw, 36px);
    line-height: 1.18;
    letter-spacing: -.035em;
    max-width: 13ch;
  }
  .hero__subtitle {
    margin-top: 12px;
    max-width: 32ch;
    font-size: 14px;
    line-height: 1.5;
  }
}

/* Install / update UI is a compact floating card, never a wide banner. */
.install-toast {
  box-sizing: border-box;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  width: min(560px, calc(100vw - var(--safe-left) - var(--safe-right) - 28px));
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  margin: 0;
  gap: 10px;
}
.install-toast__copy,
.install-toast > span:not(.install-toast__icon) {
  min-width: 0;
  overflow-wrap: anywhere;
}
.install-toast[hidden] {
  display: none !important;
}
.install-toast--ios {
  grid-template-columns: auto minmax(0, 1fr) auto;
}
.install-toast--ios #installBtn {
  display: none !important;
}
.install-toast--ios .install-toast__copy {
  font-size: 12.5px;
  line-height: 1.42;
  font-weight: 650;
}
.install-toast--ios .install-toast__icon {
  background: rgba(230,57,70,.12);
  color: #d9d2ff;
}

@media (max-width: 560px) {
  .install-toast {
    width: calc(100vw - var(--safe-left) - var(--safe-right) - 24px);
    bottom: calc(var(--player-bar-h) + var(--safe-bottom) + 10px);
    grid-template-columns: 30px minmax(0, 1fr) auto auto;
    gap: 8px;
    padding: 11px 12px;
    border-radius: 15px;
  }
  .install-toast--ios {
    grid-template-columns: 30px minmax(0, 1fr) 36px;
  }
  .install-toast__copy,
  .install-toast span {
    font-size: 12px;
    line-height: 1.4;
  }
  #installDismiss,
  #swUpdateDismissBtn {
    width: 36px;
    height: 36px;
    min-height: 36px;
  }
  #installBtn,
  #swUpdateReloadBtn {
    min-height: 36px;
    padding-inline: 11px;
    white-space: nowrap;
  }
}

/* Mini player remains readable at 375px without crowding the share action. */
@media (max-width: 430px) {
  .player-bar {
    gap: 8px;
    padding-left: calc(10px + var(--safe-left));
    padding-right: calc(8px + var(--safe-right));
  }
  .player-bar__meta {
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
  }
  .player-bar__title {
    max-width: 27vw;
  }
  .player-bar__artist {
    max-width: 27vw;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .player-bar__controls {
    flex: 0 0 auto;
    gap: 1px;
  }
  .ctrl-btn {
    width: 40px;
    height: 40px;
  }
  .ctrl-btn--play {
    width: 46px;
    height: 46px;
  }
}/* PHASE19-01 — final public UX/accessibility hardening */
.sr-only{
  position:absolute!important;width:1px!important;height:1px!important;padding:0!important;
  margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;
  white-space:nowrap!important;border:0!important
}
.search-bar button,
.eq-panel__close{
  min-width:44px;
  min-height:44px;
}
.search-bar input[type="search"]{
  min-width:0;
}
@media(max-width:430px){
  .search-bar{
    gap:8px;
  }
  .search-bar input{
    width:100%;
    min-width:0;
  }
}
@media(max-width:412px){
  .app-bar__actions,
  .app-bar{
    min-width:0;
  }
}

/* W4 — shared local Lucide-style icon geometry */
.ui-icon {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
.ctrl-btn .ui-icon,
.app-bar__icon .ui-icon {
  pointer-events: none;
}
.ctrl-btn--share {
  color: var(--text-1);
}
@media (max-width: 520px) {
  .ctrl-btn,
  .ctrl-btn--share {
    min-width: 44px;
    min-height: 44px;
  }
}


/* ==========================================================================
   W4a — nav groups (Discover / Library). <details>/<summary> only, no new
   JS. .side-nav__link styling is reused unchanged for full visual
   consistency; these rules only add the group wrapper, the disclosure
   arrow, and indent for the nested links.
   ========================================================================== */

.side-nav__group { display: block; }
.side-nav__group-label {
  cursor: pointer;
  list-style: none;
  justify-content: space-between;
}
.side-nav__group-label::-webkit-details-marker { display: none; }
.side-nav__group-label::after {
  content: "";
  width: 8px;
  height: 8px;
  border-inline-end: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .18s ease;
  opacity: .6;
  flex-shrink: 0;
}
.side-nav__group[open] > .side-nav__group-label::after { transform: rotate(-135deg); }
.side-nav__group > .side-nav__link:not(.side-nav__group-label) {
  padding-inline-start: 32px;
  min-height: 42px;
  font-weight: 500;
}
