/* Melodili — theme-aware music player. Telegram owns the semantic colors via
   --tg-theme-*; the values below are browser fallbacks. Layout is a centered
   shell that stays comfortable from 320px phones to wide desktops. */
:root {
  --bg: var(--tg-theme-bg-color, #0b1014);
  --card: var(--tg-theme-secondary-bg-color, #151c23);
  --text: var(--tg-theme-text-color, #edf1f5);
  --muted: var(--tg-theme-hint-color, #98a6b5);
  /* Melodili brand: matches the logo (teal → ocean → indigo gradient, coral
     accent). Fixed so the app reads on-brand regardless of the Telegram theme. */
  --accent: #12a594;
  --accent-text: #04140f;
  --accent-2: #d97757;
  --brand-1: #0b8f83;
  --brand-2: #087f9c;
  --brand-3: #4654cb;
  --accent-gradient: linear-gradient(135deg, var(--brand-1) 0%, var(--brand-2) 50%, var(--brand-3) 100%);

  --line: color-mix(in srgb, var(--text) 10%, var(--bg));
  --hover: color-mix(in srgb, var(--text) 5%, var(--bg));
  --selected: color-mix(in srgb, var(--accent) 10%, var(--bg));
  --danger: var(--tg-theme-destructive-text-color, #e5484d);

  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px;

  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Tahoma, Arial, sans-serif;
  --text-xs: 12px; --text-sm: 13px; --text-base: 15px; --text-input: 16px; --text-lg: 18px;
  --text-title: clamp(20px, 2.4vw, 28px);

  --radius-art: 10px; --radius-control: 12px; --radius-panel: 24px;
  --shell-width: 960px; --gutter: 12px; --hit: 44px; --nav-height: 58px;

  --player-height: 0px;
  --safe-top: 0px; --safe-bottom: 0px; --safe-left: 0px; --safe-right: 0px;
  --inset-top: calc(max(var(--safe-top), env(safe-area-inset-top, 0px)) + var(--update-h, 0px));
  --inset-bottom: max(var(--safe-bottom), env(safe-area-inset-bottom, 0px));
  /* max() of Telegram's reported safe-area (applyInsets) and the browser env() — so
     horizontal insets are honored in landscape/notched Telegram too, not env-only (P22). */
  --inset-left: max(var(--safe-left), env(safe-area-inset-left, 0px));
  --inset-right: max(var(--safe-right), env(safe-area-inset-right, 0px));

  color-scheme: light dark;
}

/* Light mode. Auto (no explicit choice): follow the system in the browser, while
   inside Telegram the --tg-theme-* vars still win and follow the Telegram theme.
   An explicit [data-theme] choice overrides both. Only the four base tokens flip;
   --line/--hover/--selected derive from --text/--bg via color-mix. --accent stays
   the brand teal (reads on light and dark). */
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg: var(--tg-theme-bg-color, #f6f8fa);
    --card: var(--tg-theme-secondary-bg-color, #ffffff);
    --text: var(--tg-theme-text-color, #111820);
    --muted: var(--tg-theme-hint-color, #5c6b7a);
  }
}
:root[data-theme="light"] {
  --bg: #f6f8fa; --card: #ffffff; --text: #111820; --muted: #5c6b7a;
  color-scheme: light; /* pin native controls/scrollbars to the explicit choice, not the system (P25) */
}
:root[data-theme="dark"] {
  --bg: #0b1014; --card: #151c23; --text: #edf1f5; --muted: #98a6b5;
  color-scheme: dark;
}

* { box-sizing: border-box; }
/* Stroked icons: round the joins/caps. The default miter join + miterlimit:4
   bevels (shears flat) any corner sharper than the limit — e.g. the pointed
   bottom of the outline heart rendered with a cut-off tip. Round joins fix it
   for every stroked icon at once (fill-only icons ignore these). */
svg { stroke-linejoin: round; stroke-linecap: round; }

/* Vazirmatn (self-hosted variable font, all weights in one file) for Persian.
   Self-hosted rather than a font CDN so it loads for users where Google Fonts is
   blocked. Applied only when the UI language is Persian by redefining --font-ui,
   which the body/buttons/inputs all resolve — so every section, including the
   landing page, switches to Vazirmatn without per-rule changes. */
@font-face {
  font-family: "Vazirmatn";
  src: url("/vazirmatn.woff2?v=1") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
html[lang="fa"] { --font-ui: "Vazirmatn", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Tahoma, Arial, sans-serif; }

html, body { margin: 0; height: 100%; }
/* App-shell: the body is a fixed-height flex column and does NOT scroll — only
   <main> does. This kills the janky document-level scroll / rubber-band in the
   Telegram desktop webview. Height comes from Telegram's stable viewport (set as
   --app-height by JS), falling back to the dynamic viewport unit in a browser. */
body {
  background: var(--bg); color: var(--text);
  font: var(--text-base)/1.45 var(--font-ui);
  -webkit-tap-highlight-color: transparent;
  height: var(--app-height, 100dvh);
  display: flex; flex-direction: column;
  overflow: hidden;
}
[hidden] { display: none !important; }
button, input { font-family: inherit; }
button { touch-action: manipulation; cursor: pointer; }
button:focus-visible, input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---- header / shell ---- */
body > header {
  flex: 0 0 auto; z-index: 5; background: var(--bg);
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-2);
  width: 100%; max-width: var(--shell-width); margin-inline: auto;
  padding: calc(var(--inset-top) + 4px) max(var(--gutter), var(--inset-right)) var(--space-2) max(var(--gutter), var(--inset-left));
  border-bottom: 1px solid var(--line);
}
/* Thin indeterminate top bar during a keep-page navigation (shown only after a short
   delay, so instant cache hits never flash it). */
#nav-loading { position: fixed; inset: 0 auto auto 0; height: 2px; width: 100%; z-index: 60; opacity: 0; transition: opacity .15s ease; pointer-events: none; overflow: hidden; }
#nav-loading.on { opacity: 1; }
#nav-loading.on::before { content: ""; position: absolute; top: 0; bottom: 0; width: 40%; background: var(--accent); animation: nav-load 1.1s ease-in-out infinite; }
@keyframes nav-load { 0% { left: -40%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) { #nav-loading.on::before { animation: none; width: 100%; opacity: .5; } }

/* Skeleton placeholder rows for a genuinely-empty first paint (cold startup). Theme-
   neutral shimmer so it works in light and dark without extra tokens. */
/* direction:ltr + logical L/R insets so the art column stays on the LEFT and matches
   the real .track rows it stands in for, instead of flipping in RTL (P18). */
.skel-row { display: grid; direction: ltr; grid-template-columns: 44px 1fr; gap: 12px; align-items: center; padding: 8px max(var(--gutter), var(--inset-right)) 8px max(var(--gutter), var(--inset-left)); }
.skel-art { width: 44px; height: 44px; border-radius: 8px; }
.skel-lines { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.skel-line { height: 11px; border-radius: 6px; }
.skel-line.w1 { width: 58%; } .skel-line.w2 { width: 36%; }
.skel-art, .skel-line { background: linear-gradient(90deg, rgba(128,128,128,.14) 25%, rgba(128,128,128,.26) 37%, rgba(128,128,128,.14) 63%); background-size: 400% 100%; animation: skel 1.4s ease infinite; }
@keyframes skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

/* Subtle entrance when a view's content is committed into #list (keep-page swap). */
@keyframes viewIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
#list.view-in { animation: viewIn .18s ease both; }
@media (prefers-reduced-motion: reduce) { .skel-art, .skel-line { animation: none; } #list.view-in { animation: none; } }
body > main {
  flex: 1 1 auto; min-height: 0;             /* min-height:0 lets the flex child scroll */
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  width: 100%; max-width: var(--shell-width); margin-inline: auto;
  /* Only the floating player overlaps main now (nav is a flex sibling below). */
  padding: var(--space-1) max(var(--gutter), var(--inset-right))
    calc(var(--player-height) + 16px)
    max(var(--gutter), var(--inset-left));
}

.tabs { display: flex; gap: var(--space-5); min-width: 0; margin: 0; }
.tab {
  position: relative; flex: 0 0 auto; min-height: var(--hit); padding: 0 2px;
  border: 0; border-radius: 0; background: transparent; color: var(--muted);
  font-size: var(--text-base); font-weight: 600;
}
.tab.active { color: var(--text); }
.tab.active::after {
  content: ""; position: absolute; inset-inline: 2px; bottom: 2px;
  height: 3px; border-radius: 2px; background: var(--accent);
}

#search {
  min-width: 0; width: 100%; height: var(--hit); padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--card); color: var(--text); font-size: var(--text-input); outline: none;
}
#search::placeholder { color: var(--muted); opacity: 1; }
/* Restore a keyboard focus ring: #search's `outline:none` (id) out-specifies the
   generic input:focus-visible rule, so re-add it at id specificity (P23). */
#search:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.seg { justify-self: stretch; width: 100%; min-width: 0; display: flex; gap: var(--space-1); margin: 0; padding: 0; border: 0; background: transparent; }
.segbtn { flex: 0 0 auto; min-height: var(--hit); padding: 0 14px; border: none; border-radius: 10px;
  background: none; color: var(--muted); font-size: var(--text-sm); font-weight: 600; }
.segbtn.active { background: var(--card); color: var(--text); }

.titlebar { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tb-actions { flex: none; display: flex; align-items: center; gap: 8px; }
.icon-btn.lang { font-size: 13px; font-weight: 800; letter-spacing: .3px; }
#screen-title { margin: 4px 0 2px; font-size: 22px; font-weight: 800; letter-spacing: .2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.icon-btn { flex: none; width: 38px; height: 38px; border: none; border-radius: 999px;
  background: var(--card); color: var(--text); display: grid; place-items: center; }
.icon-btn:active { background: var(--hover); }
.icon-btn svg { width: 20px; height: 20px; }
/* in-app back arrow (header) + sheet close — visible in Telegram AND the browser */
.titlebar-heading { display: flex; align-items: center; gap: var(--space-1); flex: 1 1 auto; min-width: 0; }
.titlebar-heading #screen-title { min-width: 0; margin-inline: 0; }
.nav-control { flex: none; display: grid; place-items: center; width: 40px; height: 40px; padding: 8px;
  border: none; border-radius: var(--radius-control); background: transparent; color: var(--text); cursor: pointer; }
.nav-control svg { width: 24px; height: 24px; }
.nav-control:active { background: var(--card); }
[dir="rtl"] #app-back svg { transform: scaleX(-1); }
.sheet-close { position: absolute; top: 6px; inset-inline-end: 6px; z-index: 2; width: 36px; height: 36px; padding: 6px; }
.sheet-close svg { width: 22px; height: 22px; }

/* ---- home ---- */
#home-top { display: grid; gap: var(--space-4); padding: var(--space-3) 0 var(--space-2); }

/* Artist-name search: a persistent scoped field above the list (see loadArtists). */
.artist-search { display: flex; align-items: center; gap: 8px; margin: var(--space-3) 0 var(--space-2);
  padding: 0 12px; min-height: 44px; border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--card); }
.artist-search .as-icon { flex: none; display: grid; place-items: center; color: var(--muted); }
.artist-search .as-icon svg { width: 18px; height: 18px; }
.artist-search .as-input { flex: 1; min-width: 0; border: none; background: transparent; color: var(--text);
  font-size: var(--text-input); padding: 10px 0; outline: none; }
.artist-search .as-input::-webkit-search-cancel-button { display: none; } /* use our own clear button */
.artist-search .as-clear { flex: none; display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 0; background: none; color: var(--muted); border-radius: 8px; cursor: pointer; }
.artist-search .as-clear svg { width: 18px; height: 18px; }
/* Wrapping grid (not a horizontal carousel) so every card is reachable with a
   mouse on desktop / the narrow Telegram desktop panel. */
.mixrow { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
@media (min-width: 640px) { .mixrow { grid-template-columns: repeat(4, 1fr); } }
.mixcard { height: 128px; border: none;
  border-radius: 16px; padding: 12px; display: flex; flex-direction: column; justify-content: flex-end;
  text-align: start; color: #fff; position: relative; overflow: hidden; }
.mixcard::after { content: ""; position: absolute; inset: 0; background: linear-gradient(160deg, transparent 40%, rgb(0 0 0 / 45%)); }
.mixcard .mc-t { position: relative; z-index: 1; font-size: 16px; font-weight: 700; line-height: 1.2; }
.mixcard .mc-s { position: relative; z-index: 1; font-size: 12px; opacity: .85; margin-top: 2px; }
.mixcard .mc-note { position: absolute; top: 12px; inset-inline-end: 12px; width: 24px; height: 24px; opacity: .5; z-index: 1; }

/* genre browse: chip strip on Home, chip grid in Library */
.home-genres { display: grid; gap: 6px; }
.home-genres .gh { font-size: var(--text-sm); font-weight: 700; color: var(--muted); padding: 0 2px; }
.genre-strip { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; touch-action: auto; cursor: grab; user-select: none; -webkit-user-select: none; }
.genre-strip.dragging { cursor: grabbing; }
.genre-strip::-webkit-scrollbar { display: none; }
.genre-grid { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 2px; list-style: none; }
.genre-strip .chip, .genre-grid .chip, .browse-strip .chip { flex: 0 0 auto; min-height: 40px; font-size: var(--text-base); }
/* Browse-by-genre/language strips embedded at the top of the Artists tab. */
.browse-strip { list-style: none; display: grid; gap: 6px; padding: 8px 2px 2px; }
.browse-strip .gh { font-size: var(--text-sm); font-weight: 700; color: var(--muted); padding: 0 2px; }

/* ---- bottom nav ---- */
#nav {
  flex: 0 0 auto; z-index: 15;
  display: flex; background: var(--card); border-top: 1px solid var(--line);
  padding-bottom: var(--inset-bottom); padding-inline: max(0px, var(--inset-left)) max(0px, var(--inset-right));
}
.navbtn {
  flex: 1; min-height: var(--nav-height); display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; border: none; background: none; color: var(--muted); font-size: 11px; font-weight: 600;
}
.navbtn .ni { display: grid; place-items: center; }
/* offline mode: dim the nav tabs that need the network (Library stays active) */
body.is-offline .navbtn:not([data-mode="library"]) { opacity: 0.4; }
.offline-bar { position: sticky; top: 0; z-index: 12; background: var(--accent-gradient, linear-gradient(90deg,#0b8f83,#087f9c,#4654cb));
  color: #fff; font-size: var(--text-sm); font-weight: 600; text-align: center; padding: 7px 12px;
  box-shadow: 0 1px 6px rgb(0 0 0 / 18%); }
.offline-bar.tap { cursor: pointer; }
.install-banner { position: sticky; top: 0; z-index: 12; display: flex; align-items: center; gap: 10px;
  background: var(--surface); border-bottom: 1px solid var(--line); padding: 8px 12px; font-size: var(--text-sm); }
.install-banner .ib-t { flex: 1; min-width: 0; color: var(--text); }
.install-banner .ib-cta { flex: none; background: var(--accent-gradient, linear-gradient(90deg,#0b8f83,#087f9c,#4654cb)); color: #fff; border: 0; border-radius: 999px; padding: 6px 14px; font: inherit; font-weight: 600; }
.install-banner .ib-x { flex: none; background: none; border: 0; color: var(--muted); width: 32px; height: 32px; padding: 5px; }
.install-banner .ib-x svg { width: 20px; height: 20px; }
.navbtn .ni svg { width: 24px; height: 24px; }
.navbtn .nl { white-space: nowrap; }
.navbtn.active { color: var(--accent); }

/* ---- settings ---- */
.set-connect { list-style: none; padding: 6px 0 4px; }
.set-connect .pl-new { padding: 0; }
.set-msg { color: var(--muted); font-size: var(--text-sm); padding: 8px 4px 0; min-height: 0; }
.set-note { color: var(--muted); font-size: var(--text-sm); line-height: 1.5; padding: 0 4px 10px; }
.set-note b { color: var(--text); font-weight: 600; }
.sheet-sub { color: var(--muted); font-size: var(--text-sm); padding: 0 8px 10px; }
.sheet-chips { display: flex; gap: 8px; flex-wrap: wrap; padding: 8px 8px 2px; }
.set-channels { list-style: none; display: grid; gap: 2px; color: var(--muted); padding: 4px 0; }
.ch-row { display: flex; align-items: center; padding: 10px 8px; border-bottom: 1px solid var(--line); }
.ch-t { font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.ch-s { color: var(--muted); font-size: var(--text-sm); margin-top: 2px; }
.set-row { display: flex; align-items: center; gap: var(--space-3); min-height: 56px; padding: 10px 8px; border-bottom: 1px solid var(--line); }
.set-row.tappable { cursor: pointer; }
.set-row.tappable:active { background: var(--card); }
.set-main { flex: 1; min-width: 0; }
.set-t { font-weight: 600; }
.set-row.danger .set-t { color: var(--danger); }
.set-s { color: var(--muted); font-size: var(--text-sm); margin-top: 2px; }
.set-chev { color: var(--muted); font-size: 20px; }
[dir="rtl"] .set-chev, [dir="rtl"] .prow-chev { display: inline-block; transform: scaleX(-1); }
.help-h { font-weight: 600; color: var(--text); padding: 12px 8px 4px; font-size: var(--text-sm); }
.help-list { list-style: none; margin: 0; padding: 0 8px; }
.help-list li { color: var(--muted); font-size: var(--text-sm); line-height: 1.6; padding: 3px 0; }
.help-ver { color: var(--muted); font-size: var(--text-xs); text-align: center; padding: 10px 0 4px; }

/* ---- content ---- */
.status { color: var(--muted); text-align: center; padding: 28px 12px; }
.status:empty { display: none; }
.status .link { color: var(--accent); font-weight: 600; }
.empty-msg { max-width: 34ch; margin: 0 auto var(--space-4); line-height: 1.5; }
.empty-action { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 40px; padding: 0 var(--space-4);
  border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--selected);
  color: var(--accent); font-weight: 650; font-size: var(--text-sm); cursor: pointer; }
.empty-action:active { background: var(--hover); }
.section {
  list-style: none; padding: var(--space-6) var(--space-2) var(--space-2);
  font-size: var(--text-sm); font-weight: 700; color: var(--muted);
}
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.seeall { border: none; background: none; color: var(--accent); font-size: var(--text-sm); font-weight: 700; padding: 0; white-space: nowrap; }

/* ---- track row (grid: art | meta | heart | duration ; + overflow) ---- */
.tracks { list-style: none; margin: 0; padding: 0; }
.track {
  display: flex; align-items: center; direction: ltr; min-width: 0; min-height: 64px;
  border-bottom: 1px solid var(--line);
}
.track .row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) 16px 5ch; align-items: center; gap: var(--space-2);
  flex: 1 1 0%; min-width: 0; min-height: 64px; padding: 10px 0 10px 8px;
  background: none; border: none; color: inherit; text-align: start; border-radius: 10px;
}
.art {
  position: relative; width: 44px; height: 44px; border-radius: var(--radius-art);
  display: grid; place-items: center; overflow: hidden; background: var(--card); color: var(--muted);
}
.art img { width: 100%; height: 100%; object-fit: cover; }
.art svg { width: 20px; height: 20px; opacity: .7; }
.art-fallback { background: color-mix(in srgb, var(--art-tint) 28%, var(--card)); color: var(--text); }
.art-initial { font-size: var(--text-lg); line-height: 1; font-weight: 700; }

.meta { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; overflow: hidden; }
.meta .t, .meta .s {
  display: block; width: 100%; min-width: 0; overflow: hidden; white-space: nowrap;
  text-overflow: ellipsis; text-align: start; unicode-bidi: plaintext;
}
.meta .t { font-size: var(--text-base); font-weight: 600; line-height: 20px; }
/* The subtitle is a set of <bdi> fields whose order follows the container's explicit
   locale dir (set in setSubtitle) — isolate, not plaintext, so that dir is honored. */
.meta .s { color: var(--muted); font-size: var(--text-sm); line-height: 18px; unicode-bidi: isolate; }
.meta bdi { unicode-bidi: isolate; }

.track .heart { grid-column: 3; width: 16px; text-align: center; color: var(--accent); font-size: 13px; }
.track .dur { grid-column: 4; direction: ltr; unicode-bidi: isolate; white-space: nowrap;
  text-align: right; color: var(--muted); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.more-btn { display: grid; place-items: center; flex: 0 0 var(--hit); width: var(--hit); height: var(--hit);
  padding: 0; border: none; background: none; color: var(--muted); font-size: 20px; line-height: 1; border-radius: 10px; }

/* Drag-to-reorder handle (playlist detail tracks + playlist library cards). */
.reorder-handle { display: grid; place-items: center; flex: none; width: var(--hit); height: var(--hit);
  padding: 0; border: 0; background: none; color: var(--muted); border-radius: 10px;
  touch-action: none; cursor: grab; }
.reorder-handle svg { width: 20px; height: 20px; }
.reorder-handle:active { cursor: grabbing; }
.track.dragging, .pl-card.dragging { opacity: .72; background: var(--selected); }
body.reordering-active { user-select: none; -webkit-user-select: none; }

.track.playing { background: var(--selected); }
.track.playing .t { color: var(--text); }
.track .row > .eq { display: none; } /* legacy position guard */
.art .eq { position: absolute; inset-inline-end: 3px; bottom: 3px; display: none;
  align-items: flex-end; justify-content: center; gap: 2px; width: 22px; height: 20px;
  margin: 0; padding: 3px; border-radius: 4px; background: var(--bg); }
.track.playing .art .eq { display: flex; }
.eq i { width: 3px; height: 7px; background: var(--accent); border-radius: 1px; animation: eq .9s ease-in-out infinite; }
.eq i:nth-child(2){ animation-delay:.2s } .eq i:nth-child(3){ animation-delay:.4s }
.track.paused .eq i { animation-play-state: paused; }
@keyframes eq { 0%,100%{height:4px} 50%{height:16px} }

/* The same playing equalizer on the player artworks: a small one on the mini
   thumbnail (matches the list rows) and a larger one on the expanded now-playing
   art. Shown only while actually playing (the .playing class syncRows toggles). */
.now-art, .mini-art { position: relative; direction: ltr; } /* media chrome doesn't mirror: corner affordances (viz toggle, eq) stay on the physical right in RTL too */
.now-art > .eq, .mini-art > .eq { position: absolute; display: none; align-items: flex-end;
  justify-content: center; margin: 0; background: var(--bg); }
.mini-art > .eq { inset-inline-end: 3px; bottom: 3px; gap: 2px; width: 22px; height: 20px; padding: 3px; border-radius: 4px; }
.now-art > .eq { inset-inline-end: 12px; bottom: 12px; gap: 4px; width: 52px; height: 44px; padding: 9px; border-radius: 9px; }
.now-art.playing > .eq, .mini-art.playing > .eq { display: flex; }
.mini-art > .eq i { width: 3px; height: 7px; background: var(--accent); border-radius: 1px; animation: eq .9s ease-in-out infinite; }
.now-art > .eq i { width: 5px; height: 10px; background: var(--accent); border-radius: 2px; animation: eqLg .9s ease-in-out infinite; }
.mini-art > .eq i:nth-child(2), .now-art > .eq i:nth-child(2) { animation-delay: .2s; }
.mini-art > .eq i:nth-child(3), .now-art > .eq i:nth-child(3) { animation-delay: .4s; }
@keyframes eqLg { 0%,100%{height:8px} 50%{height:26px} }

@media (hover: hover) {
  .track:hover { background: var(--hover); }
  .track.playing:hover { background: var(--selected); }
  .more-btn:hover { background: var(--card); color: var(--text); }
}
@media (max-width: 359px) {
  .track .row { grid-template-columns: 44px minmax(0, 1fr) 16px; }
  .track .dur { display: none; }
}

.more { display: block; margin: 16px auto; padding: 9px 18px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); }
.more:disabled { opacity: .5; }

/* ---- artists ---- */
.artist-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2);
  min-height: 60px; border: none; background: none; width: 100%; color: inherit; text-align: start; }
.artist-row .art { border-radius: 50%; }
.artist-row .meta, .artist-row > span:last-child { min-width: 0; }
.a-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.a-count { color: var(--muted); font-size: var(--text-sm); }
li:has(> .artist-row) { border-bottom: 1px solid var(--line); }

/* ---- albums grid ---- */
.album-grid { list-style: none; display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-4); padding: var(--space-3) 0; }
@media (min-width: 640px) { .album-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { .album-grid { grid-template-columns: repeat(4, 1fr); } }
.album-card { display: flex; flex-direction: column; gap: 6px; border: none; background: none; color: inherit; text-align: start; padding: 0; }
.album-art { width: 100%; aspect-ratio: 1; border-radius: var(--radius-art); overflow: hidden;
  display: grid; place-items: center; background: var(--card); color: var(--muted); position: relative; }
.album-art img { width: 100%; height: 100%; object-fit: cover; }
.album-art .art-initial { font-size: clamp(24px, 8vw, 40px); }
.album-t { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.album-c { color: var(--muted); font-size: var(--text-xs); }

/* ---- playlists ---- */
.pl-card { display: flex; align-items: center; list-style: none; }
.pl-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; min-height: 76px;
  padding: 8px; background: none; border: none; color: inherit; text-align: start; }
.pl-cover { width: 56px; height: 56px; border-radius: 10px; flex: none; }
.pl-meta { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pl-t { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.pl-c { color: var(--muted); font-size: var(--text-sm); display: flex; align-items: center; gap: 4px; min-width: 0; }
.pl-badge { display: inline-flex; align-items: center; gap: 3px; white-space: nowrap; }
.pl-badge svg { width: 13px; height: 13px; }
.pl-card .more-btn { flex: none; width: 44px; height: 44px; }
/* pinned Liked Songs card */
.pl-liked { list-style: none; padding: 4px 8px 10px; }
.pl-liked-btn { display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px; border-radius: 16px;
  background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid var(--line); color: inherit; text-align: start; }
.pl-liked-cover { width: 64px; height: 64px; border-radius: 12px; flex: none; display: grid; place-items: center;
  background: linear-gradient(135deg, #0b8f83 0%, #087f9c 48%, #4654cb 100%); color: #fff; }
.pl-liked-cover svg { width: 30px; height: 30px; }
.pl-liked-meta { flex: 1; min-width: 0; }
.pl-liked-t { font-weight: 700; font-size: var(--text-base); }
.pl-liked-c { display: block; color: var(--muted); font-size: var(--text-sm); }
.pl-chev { color: var(--muted); flex: none; }
.pl-chev svg { width: 20px; height: 20px; }
[dir="rtl"] .pl-chev svg { transform: scaleX(-1); }
/* "Your playlists" heading row */
.pl-idx-head { list-style: none; display: flex; align-items: center; gap: 10px; padding: 10px 10px 6px; }
.pl-idx-title { font-weight: 700; font-size: var(--text-base); flex: 1; min-width: 0; }
.pl-sort { background: none; border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; color: var(--text); font: inherit; font-size: var(--text-sm); }
.pl-new-btn { display: inline-flex; align-items: center; gap: 5px; background: var(--accent-gradient, linear-gradient(90deg,#0b8f83,#087f9c,#4654cb));
  color: #fff; border: 0; border-radius: 999px; padding: 6px 13px 6px 10px; font: inherit; font-weight: 600; }
.pl-new-btn svg { width: 18px; height: 18px; }
/* empty state */
.pl-empty { list-style: none; text-align: center; color: var(--muted); padding: 8vh 1.5rem 0; }
.pl-empty p { margin: 0 0 1rem; }
.pl-create { background: var(--accent-gradient, linear-gradient(90deg,#0b8f83,#087f9c,#4654cb)); color: #fff; border: 0; border-radius: 999px; padding: 10px 20px; font: inherit; font-weight: 600; }
/* playlist / liked detail header */
.pl-head { list-style: none; padding: 8px 10px 6px; }
.pl-head-top { display: flex; align-items: center; gap: 14px; }
.pl-head-cover { width: 104px; height: 104px; border-radius: 14px; flex: none; }
.pl-head-cover.cover svg { width: 40px; height: 40px; }
.pl-head-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.pl-head-t { font-weight: 700; font-size: 22px; line-height: 1.15; unicode-bidi: plaintext; }
.pl-head-s { color: var(--muted); font-size: var(--text-sm); }
.pl-head-badge { color: var(--muted); font-size: var(--text-sm); }
.pl-head-more { flex: none; align-self: flex-start; width: 40px; height: 40px; padding: 8px; background: none; border: 0; color: var(--text); }
.pl-head-more svg { width: 22px; height: 22px; }
.pl-head-desc { color: var(--muted); font-size: var(--text-sm); line-height: 1.4; padding: 10px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.pl-head-acts { display: flex; gap: 10px; padding: 14px 0 6px; }
.pl-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 46px; padding: 0 18px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface, var(--card)); color: var(--text); font: inherit; font-weight: 600; }
.pl-btn svg { width: 20px; height: 20px; }
.pl-btn-play { flex: 1; background: var(--accent-gradient, linear-gradient(90deg,#0b8f83,#087f9c,#4654cb)); color: #fff; border: 0; }
.pl-btn-shuf { flex: none; }
.pl-btn-share { flex: none; }
/* playlist sheet header: reuse the track-sheet head geometry with a cover */
.track-sheet-head .cover.tsh-art { width: 48px; height: 48px; border-radius: 8px; }
.track-sheet-head .cover.tsh-art svg { width: 22px; height: 22px; }

/* ---- shared icon buttons ---- */
.iconbtn, .ctl { display: grid; place-items: center; border: none; background: none; color: var(--text); border-radius: 50%; }
.iconbtn svg, .ctl svg { width: 22px; height: 22px; }
.iconbtn { width: var(--hit); height: var(--hit); }
.iconbtn:disabled, .ctl:disabled { opacity: .35; }

/* PC-only hover tooltips for icon-only player controls. Gated to a real pointer
   so touch users never get a tooltip stuck on tap. The label is the button's
   (localized) aria-label, so it follows language and live state (Play/Pause,
   repeat mode). */
@media (hover: hover) and (pointer: fine) {
  .tip { position: relative; }
  .tip::after {
    content: attr(aria-label);
    position: absolute; bottom: calc(100% + 8px); left: 50%;
    transform: translateX(-50%) translateY(3px);
    padding: 5px 9px; border-radius: 7px;
    background: var(--text); color: var(--bg);
    font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap;
    text-align: center; unicode-bidi: plaintext;
    box-shadow: 0 4px 14px rgb(0 0 0 / 22%);
    opacity: 0; pointer-events: none; z-index: 40;
    transition: opacity .12s ease, transform .12s ease;
  }
  .tip:disabled::after { display: none; }
  .tip:hover::after, .tip:focus-visible::after {
    opacity: 1; transform: translateX(-50%) translateY(0); transition-delay: .35s;
  }
}

/* ---- floating mini-player ---- */
#player {
  position: fixed; left: max(8px, var(--inset-left)); right: max(8px, var(--inset-right));
  bottom: calc(var(--inset-bottom) + var(--nav-height) + 8px); z-index: 10; width: auto;
  max-width: calc(var(--shell-width) - 24px); margin-inline: auto;
  display: flex; align-items: center; gap: var(--space-2); padding: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 8px 28px rgb(0 0 0 / 18%); isolation: isolate;
}
#miniprog { position: absolute; left: 12px; top: 0; height: 2px; width: calc(100% - 24px);
  background: var(--line); border-radius: 2px; overflow: hidden; }
#miniprog span { display: block; height: 100%; width: 0; background: var(--accent); }
.mini-art { flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-art); padding: 0; border: none;
  background: var(--bg); color: var(--muted); display: grid; place-items: center; overflow: hidden; }
.mini-art img { width: 100%; height: 100%; object-fit: cover; }
.mini-art svg { width: 18px; height: 18px; }
.mini-meta { flex: 1; min-width: 0; min-height: 44px; display: flex; flex-direction: column; justify-content: center;
  gap: 2px; background: none; border: none; color: inherit; text-align: start; padding: 0; }
/* The mini-player bar is always LTR (see #player[dir=ltr]); pin the title/sub to
   the left next to the artwork. text-align:left (not start) so a Persian title
   still hugs the art — unicode-bidi:plaintext keeps its glyphs correctly RTL. */
.np-title, .np-sub { width: 100%; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-title { unicode-bidi: plaintext; } /* single title: direction from its own script */
.np-sub { unicode-bidi: isolate; }     /* concatenated <bdi> fields: order from the container's explicit dir */
.np-title { font-size: 14px; line-height: 20px; font-weight: 600; }
.np-sub { color: var(--muted); font-size: 12px; line-height: 18px; }
#player .iconbtn { flex: 0 0 44px; }
#player .js-toggle { background: var(--accent); color: var(--accent-text); }
/* cross-device session: the mini-player cast button appears only while following */
#mini-cast { display: none; }
body.following #mini-cast, body.separated #mini-cast { display: inline-flex; align-items: center; justify-content: center; }
.sess-note { color: var(--muted); font-size: var(--text-xs); padding: 8px 4px 2px; line-height: 1.45; }
.sheet-act.sess-primary { background: var(--accent-gradient); color: #fff; font-weight: 700; text-align: center; border-radius: 12px; margin-top: 4px; }
.js-cast.on { color: var(--accent); }
.sess-banner { display: flex; align-items: center; gap: 10px; margin-top: 8px; padding: 8px 10px; border-radius: 10px;
  background: rgb(127 127 127 / 12%); font-size: var(--text-sm); color: var(--muted); }
.sess-name { flex: 1; min-width: 0; unicode-bidi: plaintext; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sess-here { flex: 0 0 auto; border: none; border-radius: 8px; padding: 8px 14px; background: var(--accent-gradient);
  color: #fff; font-weight: 700; font-size: var(--text-sm); cursor: pointer; }
/* ---- Play all row + section play buttons ---- */
.playall-li { display: flex; align-items: center; gap: 12px; padding: 10px 8px; cursor: pointer; border-radius: 14px; direction: ltr; -webkit-tap-highlight-color: transparent; }
.playall-li:active { background: var(--hover); }
@media (hover: hover) { .playall-li:hover { background: var(--hover); } }
.pa-btn { width: 44px; height: 44px; flex: 0 0 44px; border-radius: 50%; border: none; background: var(--accent); color: var(--accent-text); display: grid; place-items: center; cursor: pointer; box-shadow: 0 4px 14px rgb(0 0 0 / 18%); }
.pa-btn svg { width: 20px; height: 20px; }
.pa-main { flex: 1; min-width: 0; }
.pa-t { font-weight: 700; font-size: var(--text-base); }
.pa-s { color: var(--muted); font-size: var(--text-xs); margin-top: 1px; }
.seeplay { background: none; border: none; color: var(--accent); width: 32px; height: 32px; display: grid; place-items: center; cursor: pointer; }
.seeplay svg { width: 16px; height: 16px; }
.section-head .sh-t { flex: 1 1 auto; min-width: 0; } /* title flexes so seeplay+seeall group right */
/* ---- update banner + changelog sheet ---- */
body.has-update { --update-h: 38px; }
#update-banner { position: fixed; top: 0; inset-inline: 0; z-index: 26; height: var(--update-h, 0); display: flex; align-items: center; gap: 8px;
  padding: 0 max(12px, var(--inset-right)) 0 max(12px, var(--inset-left));
  background: var(--accent); color: var(--accent-text); font-size: 13px; font-weight: 600; }
body:not(.has-update) #update-banner { display: none; }
.ub-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ub-act { border: 1px solid currentColor; background: transparent; color: inherit; border-radius: 8px; padding: 4px 10px; font: inherit; font-weight: 700; cursor: pointer; white-space: nowrap; }
.ub-act.ub-primary { background: var(--accent-text); color: var(--accent); border-color: transparent; }
.ub-x { background: none; border: none; color: inherit; width: 28px; height: 28px; display: grid; place-items: center; cursor: pointer; opacity: .8; }
.ub-x svg { width: 14px; height: 14px; }
.cl-head { display: flex; justify-content: space-between; align-items: baseline; padding: 12px 4px 4px; }
.cl-v { font-weight: 700; font-size: var(--text-base); }
.cl-d { color: var(--muted); font-size: var(--text-xs); }
.cl-items { margin: 0; padding: 0 4px 4px 22px; color: var(--text); font-size: var(--text-sm); display: grid; gap: 3px; }
/* ---- mini-player close button (hidden while following: the mirror would reappear) ---- */
#mini-close { flex: 0 0 34px; width: 34px; height: 34px; border: none; background: none; color: var(--muted); display: grid; place-items: center; cursor: pointer; border-radius: 50%; }
#mini-close svg { width: 15px; height: 15px; }
#mini-close:active { background: var(--hover); color: var(--text); }
body.following #mini-close, body.following #act-close { display: none; }
.sess-status { padding: 0 4px 12px; color: var(--text); font-size: var(--text-base); }
.sess-me { padding: 10px 4px 4px; color: var(--muted); font-size: var(--text-sm); }
/* ---- devices list (online devices + give control) ---- */
.sess-devhead { display: flex; justify-content: space-between; align-items: center; padding: 14px 4px 6px; }
.sess-devhead > span:first-child { color: var(--muted); font-size: var(--text-sm); font-weight: 700; }
.sess-dcount { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--text-xs); }
.sess-dcount::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #3ecf8e; }
.sess-dlist { display: grid; gap: 2px; margin-bottom: 8px; }
.sess-drow { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 8px 6px; border-radius: 12px; }
.sess-drow.me { outline: 1px solid var(--line); }
.sess-drow.tappable { cursor: pointer; }
.sess-drow.tappable:active { background: var(--hover); }
@media (hover: hover) { .sess-drow.tappable:hover { background: var(--hover); } }
.sess-dicon { width: 36px; height: 36px; border-radius: 10px; background: var(--hover); color: var(--muted); display: grid; place-items: center; }
.sess-dicon svg { width: 18px; height: 18px; }
.sess-drow.playing .sess-dicon { background: var(--accent); color: var(--accent-text); }
.sess-dname { font-size: var(--text-base); font-weight: 600; unicode-bidi: plaintext; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sess-dsub { font-size: var(--text-xs); color: var(--muted); }
.sess-dbadge { font-size: var(--text-xs); font-weight: 700; color: var(--accent); border: 1px solid var(--accent); border-radius: 999px; padding: 3px 10px; }
.sess-give { width: 38px; height: 38px; border-radius: 50%; border: none; background: var(--accent); color: var(--accent-text); display: grid; place-items: center; cursor: pointer; }
.sess-give svg { width: 16px; height: 16px; }
.sess-dempty { padding: 8px 6px; color: var(--muted); font-size: var(--text-sm); }

/* ---- expanded now-playing ---- */
.now {
  /* overflow-x must be set explicitly: with only overflow-y:auto the spec computes
     overflow-x to `auto`, so an absolutely-positioned edge tooltip (.tip::after,
     laid out even at opacity:0) that reaches past the panel edge adds a stray
     horizontal scrollbar. Clip it — the dialog only ever scrolls vertically. */
  position: fixed; inset: 0; z-index: 20; display: flex; flex-direction: column; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  background: var(--bg);
  padding: calc(var(--inset-top) + 8px) max(20px, var(--inset-right)) calc(var(--inset-bottom) + 20px) max(20px, var(--inset-left));
  transform: translateY(0); transition: transform .25s ease;
}
.now.closing { transform: translateY(100%); }
/* Portrait: a flex column that fits the viewport height — the artwork is the only
   element allowed to shrink, so the header/title/controls always stay on screen
   without a vertical scrollbar. The wide-screen 2-column grid (below) overrides it. */
.now-panel { display: flex; flex-direction: column; justify-content: center; gap: var(--space-5);
  width: 100%; max-width: 440px; margin: auto; flex: 1 1 auto; min-height: 0; }
.now-head, .now-details { flex: 0 0 auto; } /* fixed height; only the art absorbs slack */
.now-head { display: grid; grid-template-columns: 44px 44px minmax(0, 1fr) 44px 44px; align-items: center; gap: var(--space-2); }
.now-head h2 { margin: 0; text-align: center; font-size: 13px; font-weight: 600; color: var(--muted); }
.now-head-spacer { width: 44px; }
/* Header disco pair (mirrors the FABs, which the full-screen player covers): circles
   only shows while disco is on — hidden, not removed, so the title stays centered. */
.now-head .js-disco svg { width: 22px; height: 22px; }
.now-head .js-disco-circles svg { width: 20px; height: 20px; }
.now-head .js-disco.on, .now-head .js-disco-circles.on { color: var(--accent); }
.now-head .js-disco-circles { visibility: hidden; }
body.disco .now-head .js-disco-circles { visibility: visible; }
.now-art { align-self: center; flex: 0 1 auto; min-height: 0; height: min(320px, 38svh); width: auto; max-width: 100%; aspect-ratio: 1; margin: 0;
  border-radius: 20px; background: var(--card); color: var(--muted); display: grid; place-items: center; overflow: hidden; }
.now-art img { width: 100%; height: 100%; object-fit: cover; }
.now-art svg { width: 33%; height: 33%; opacity: .6; }
.now-art .art-initial { font-size: clamp(48px, 12vw, 96px); }
/* music visualizer overlay (Media-Player-Classic-style spectrum) */
.now-art > .viz-canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0;
  transition: opacity .16s ease; pointer-events: none; z-index: 1; }
/* The canvas is revealed only while genuinely playing (applyArtStatus sets
   .art-viz-visible) — never during loading/error, so no stale/empty spectrum shows. */
.now-art.art-viz-visible > .viz-canvas { opacity: 1; }
.now-art.art-viz-visible > img, .now-art.art-viz-visible > .art-initial { opacity: 0; transition: opacity .16s ease; }
.now-art.art-viz-visible > .eq { display: none !important; }
/* Loading / error / blocked treatments hide the eq bars and the visualizer canvas. */
:is(.now-art, .mini-art):is(.art-loading, .art-error, .art-blocked) > .eq { display: none !important; }
.now-art:is(.art-loading, .art-error, .art-blocked) > .viz-canvas { opacity: 0 !important; }
.now-art > .viz-toggle { position: absolute; top: 8px; inset-inline-end: 8px; width: 44px; height: 44px;
  display: grid; place-items: center; border: none; background: none; padding: 0; z-index: 3; cursor: pointer; }
.now-art > .viz-toggle::before { content: ""; position: absolute; width: 32px; height: 32px; border-radius: 50%;
  background: var(--card); opacity: .92; box-shadow: 0 1px 4px rgb(0 0 0 / 25%); }
.now-art > .viz-toggle svg { position: relative; width: 18px; height: 18px; opacity: 1; color: var(--text); }
/* Active-state affordance: when the visualizer preference is on, tint the toggle
   accent (like .ctl.on / .now-act.on / .js-cast.on) so it has a clear on/off state,
   not just an icon swap. #now-art carries the .viz-on marker (updateVizUI) (P25b). */
.now-art.viz-on > .viz-toggle svg { color: var(--accent); }
.now-art > .viz-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 50%; }

/* ---- disco lights ---- */
/* Rendered only while active (display:none otherwise) so the fixed overlay adds
   zero scroll/paint cost when off. No mix-blend-mode: a blended full-viewport
   fixed layer forces the whole page to re-composite on every scroll frame, which
   janks mobile badly. Plain alpha over the (forced) dark stage reads fine and
   stays cheap; paint containment keeps disc repaints off the page. */
#disco { position: fixed; inset: 0; z-index: 22; overflow: hidden; pointer-events: none;
  display: none; contain: layout paint; }
body.disco #disco { display: block; animation: discoIn .35s ease both; }
@keyframes discoIn { from { opacity: 0; } to { opacity: 1; } }
#disco .dd { position: absolute; width: min(72vw, 460px); height: min(49vw, 312px); border-radius: 50%;
  transform: translate(-50%, -50%); will-change: transform; }
/* Small light circles that pop in and fade out on the bass (color via inline hsl). */
#disco .disco-pop { position: absolute; border-radius: 50%; pointer-events: none; opacity: 0;
  background: radial-gradient(circle, currentColor 0%, currentColor 40%, transparent 72%);
  box-shadow: 0 0 10px currentColor; transform: translate(-50%, -50%) scale(0);
  will-change: transform, opacity; animation-name: discoPop; animation-timing-function: ease-out; animation-fill-mode: forwards; }
@keyframes discoPop {
  0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  30% { transform: translate(-50%, -50%) scale(1); opacity: .9; }
  100% { transform: translate(-50%, -50%) scale(1.35); opacity: 0; }
}
#disco .d1 { left: 44%; top: 42%; background: radial-gradient(closest-side, rgba(34,211,238,.55), rgba(34,211,238,.26) 46%, transparent 72%); }
#disco .d2 { left: 57%; top: 50%; background: radial-gradient(closest-side, rgba(139,92,246,.55), rgba(139,92,246,.26) 46%, transparent 72%); }
#disco .d3 { left: 47%; top: 60%; background: radial-gradient(closest-side, rgba(236,72,153,.55), rgba(236,72,153,.26) 46%, transparent 72%); }
#disco-fab { position: fixed; inset-inline-end: 16px; z-index: 16;
  bottom: calc(var(--inset-bottom) + var(--nav-height) + var(--player-height) + 12px);
  width: 48px; height: 48px; border-radius: 50%; border: 1px solid rgb(127 127 127 / 22%);
  background: var(--card); color: var(--text); display: grid; place-items: center; cursor: pointer;
  box-shadow: 0 3px 12px rgb(0 0 0 / 30%); transition: box-shadow .2s ease, color .2s ease; }
#disco-fab svg { width: 24px; height: 24px; }
#disco-fab.on { color: var(--accent); box-shadow: 0 0 0 2px var(--accent), 0 3px 12px rgb(0 0 0 / 30%); }
#disco-fab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* circles sub-toggle: revealed just above the disco FAB while disco is on */
#disco-circles-fab { position: fixed; inset-inline-end: 20px; z-index: 16;
  bottom: calc(var(--inset-bottom) + var(--nav-height) + var(--player-height) + 68px);
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgb(127 127 127 / 22%);
  background: var(--card); color: var(--text); display: grid; place-items: center; cursor: pointer;
  box-shadow: 0 3px 12px rgb(0 0 0 / 30%);
  /* visibility:hidden (not just opacity) so the off-state button is out of the tab
     order — otherwise it's a phantom keyboard focus stop while disco is off (P20).
     Transitioned so the flip waits for the fade-out. */
  opacity: 0; transform: translateY(16px) scale(.8); pointer-events: none; visibility: hidden;
  transition: opacity .22s ease, transform .22s ease, visibility .22s ease; }
body.disco #disco-circles-fab { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto; visibility: visible; }
#disco-circles-fab svg { width: 20px; height: 20px; }
#disco-circles-fab.on { color: var(--accent); box-shadow: 0 0 0 2px var(--accent), 0 3px 12px rgb(0 0 0 / 30%); }
#disco-circles-fab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.now-details { display: grid; align-content: center; gap: var(--space-4); min-width: 0; }
.now-heading { display: grid; grid-template-columns: minmax(0, 1fr) 44px; align-items: center; gap: var(--space-3); }
.now-copy { min-width: 0; }
.now-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  white-space: normal; overflow-wrap: anywhere; text-align: start; unicode-bidi: plaintext;
  font-size: var(--text-title); line-height: 1.35; font-weight: 700; }
.now-sub { display: block; margin-top: 6px; color: var(--muted); font-size: 14px; text-align: start; unicode-bidi: isolate; }
/* Active listeners: quiet pill under the now-playing subtitle (stays visible at zero) */
.now-listeners { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 5px 11px;
  border: 1px solid var(--line); border-radius: 999px; background: none; color: var(--muted);
  font: inherit; font-size: var(--text-sm); cursor: pointer; }
.now-listeners:active { background: var(--hover); }
.now-listeners .nl-i { display: grid; place-items: center; }
.now-listeners .nl-i svg { width: 15px; height: 15px; }
/* listeners sheet rows */
.ls-row { display: flex; align-items: center; gap: 12px; padding: 8px; }
.ls-row .avatar { width: 38px; height: 38px; font-size: 14px; }
.ls-name { min-width: 0; font-size: var(--text-base); unicode-bidi: plaintext; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-anon, .ls-empty { padding: 8px; color: var(--muted); font-size: var(--text-sm); }
/* Self presence status: a dot (grey = anonymous, accent = shown) + a line telling
   the viewer whether others can see them. */
.ls-self { display: flex; align-items: center; gap: 8px; padding: 10px 8px; margin-top: 4px;
  border-top: 1px solid var(--line); color: var(--muted); font-size: var(--text-sm); }
.ls-self-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--muted); }
.ls-self.on { color: var(--text); }
.ls-self.on .ls-self-dot { background: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.ls-privacy { border-bottom: none; }
.likebtn { position: static; display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: none; background: none; border-radius: 50%; color: var(--muted); }
.likebtn svg { width: 24px; height: 24px; }
.likebtn.on { color: var(--accent); background: var(--selected); }
/* visually-hidden (screen-reader only) live region — never display:none, or AT won't read it */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ===== artwork status overlay (loading spinner / error glyph / blocked play / caption) =====
   Every layer is absolutely positioned, so showing status NEVER changes the art box size
   and can't reflow the now-playing seek row or controls. */
.now-art, .mini-art { isolation: isolate; }
.art-status { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.art-status-shade { position: absolute; inset: 0; background: rgb(0 0 0 / 45%); opacity: 0;
  transition: opacity .16s ease; }
.art-status-spinner, .art-status-error { position: absolute; inset: 0; margin: auto;
  width: 34px; height: 34px; display: none; place-items: center; color: #fff; }
.mini-art .art-status-spinner, .mini-art .art-status-error { width: 18px; height: 18px; }
.art-status-spinner svg, .art-status-error svg { width: 100%; height: 100%; opacity: 1; }
.art-status-spinner svg { animation: spin .8s linear infinite; }
.art-status-error svg { color: #ffd45e; }
/* blocked → a tappable play affordance centered on the art */
.art-status-play { position: absolute; inset: 0; margin: auto; width: 56px; height: 56px; display: none;
  place-items: center; padding: 0; border: none; border-radius: 50%; cursor: pointer;
  background: rgb(0 0 0 / 55%); color: #fff; pointer-events: auto; }
.mini-art .art-status-play { width: 26px; height: 26px; background: none; pointer-events: none; }
.art-status-play svg { width: 55%; height: 55%; opacity: 1; }
/* the caption rides the bottom of the art as a gradient strip (now-art only) */
.art-status-caption { position: absolute; inset-inline: 0; bottom: 0; display: none; margin: 0;
  padding: 24px 12px 10px; color: #fff; font-size: var(--text-sm); text-align: start;
  unicode-bidi: plaintext; overflow-wrap: anywhere; overflow: hidden;
  -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  background: linear-gradient(to top, rgb(0 0 0 / 72%), rgb(0 0 0 / 0)); }

/* state reveals */
:is(.now-art, .mini-art):is(.art-loading, .art-error, .art-blocked) > .art-status > .art-status-shade { opacity: 1; }
:is(.now-art, .mini-art).art-loading > :is(img, .art-initial) { filter: blur(2px); transform: scale(1.04); }
:is(.now-art, .mini-art).art-loading > .art-status > .art-status-spinner { display: grid; }
:is(.now-art, .mini-art).art-error > .art-status > .art-status-error { display: grid; }
:is(.now-art, .mini-art).art-blocked > .art-status > .art-status-play { display: grid; }
.now-art:is(.art-loading, .art-error, .art-blocked) > .art-status > .art-status-caption { display: -webkit-box; }

@media (prefers-reduced-motion: reduce) { .art-status-spinner svg { animation: none; } .art-status-shade { transition: none; } }
@keyframes spin { to { transform: rotate(360deg); } }
.seekrow { display: grid; grid-template-columns: 5ch minmax(0, 1fr) 6ch; gap: var(--space-2); width: 100%; direction: ltr; }
.seekrow span { align-self: center; direction: ltr; unicode-bidi: isolate; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.seekrow span:last-child { text-align: right; }
.seek { width: 100%; min-width: 0; height: 44px; margin: 0; accent-color: var(--accent); }
.seek:disabled { opacity: .4; }
.now-controls { display: grid; grid-template-columns: 44px 48px 64px 48px 44px; justify-content: space-between;
  align-items: center; gap: var(--space-1); width: 100%; margin: 0; direction: ltr; }
.now-controls .ctl { width: 44px; height: 48px; padding: 0; }
.now-controls .js-prev, .now-controls .js-next { width: 48px; }
.now-controls .js-prev svg, .now-controls .js-next svg { width: 28px; height: 28px; }
.now-controls .ctl.big { width: 64px; height: 64px; background: var(--accent); color: var(--accent-text); }
.now-controls .ctl.big svg { width: 28px; height: 28px; }
.ctl.on { color: var(--accent); }
.now-actions { display: flex; justify-content: space-around; align-items: center; gap: var(--space-2); }
.now-act { display: flex; flex-direction: column; align-items: center; gap: 4px; border: none; background: none;
  color: var(--muted); font-size: 11px; font-weight: 600; padding: 6px 12px; border-radius: 10px; }
.now-act .na-i { display: grid; place-items: center; }
.now-act .na-i svg { width: 22px; height: 22px; }
.now-act.on { color: var(--accent); }
.queue-label { margin: 0; padding-top: var(--space-2); color: var(--muted); font-size: 13px; text-align: center; unicode-bidi: plaintext; }
/* queue sheet */
/* No own max-height/overflow: the .sheet-panel (85dvh, overflow-y:auto) is the sole
   scroll container and owns the infinite-scroll listener. A max-height here without
   overflow-y let long queues spill past the box and paint over the Load-more button,
   and adding overflow-y would create a nested scroller that kills the panel's
   infinite scroll — so the list just takes its natural height and the panel scrolls. */
.q-list .track { border-bottom: 1px solid var(--line); }
.q-now { color: var(--muted); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .4px; padding: 4px 8px; list-style: none; }

@media (min-width: 760px) {
  .now { display: grid; background: rgb(0 0 0 / 55%);
    padding: calc(var(--inset-top) + 24px) max(24px, var(--inset-right)) calc(var(--inset-bottom) + 24px) max(24px, var(--inset-left)); }
  /* Two-column split: keep the artwork on the physical LEFT in both directions — the
     media column doesn't mirror (Material/Apple). Force the grid LTR and restore the
     locale direction on the head/details so their text still reads/aligns correctly. */
  .now-panel { display: grid; direction: ltr; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); width: 100%; max-width: 840px; margin: auto;
    padding: 24px; gap: 24px 32px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius-panel);
    box-shadow: 0 24px 80px rgb(0 0 0 / 25%); }
  [dir="rtl"] .now-head, [dir="rtl"] .now-details { direction: rtl; }
  .now-head { grid-column: 1 / -1; }
  .now-art { width: 100%; height: auto; max-width: 360px; align-self: center; }
}
@media (max-height: 650px) and (max-width: 759px) {
  .now-panel { gap: var(--space-4); }
  .now-details { gap: var(--space-3); }
}

/* ---- bottom sheet ---- */
.sheet { position: fixed; inset: 0; z-index: 30; display: flex; align-items: flex-end;
  padding-top: calc(var(--inset-top) + 12px); padding-left: var(--inset-left); padding-right: var(--inset-right); }
.sheet-backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 55%); }
.sheet-panel { position: relative; width: 100%; max-height: 85dvh; overflow-y: auto; overscroll-behavior: contain;
  padding: 8px 16px calc(12px + var(--inset-bottom)); background: var(--card);
  border: 1px solid var(--line); border-bottom: 0; border-radius: 24px 24px 0 0; }
.sheet-panel::before { content: ""; display: block; width: 32px; height: 4px; margin: 0 auto 16px;
  border-radius: 2px; background: var(--muted); opacity: .5; }
.sheet-title { font-weight: 700; padding: 4px 8px 12px; color: var(--text); font-size: var(--text-base);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.sheet-act { display: block; width: 100%; min-height: 48px; text-align: start; padding: 12px 10px;
  background: none; border: none; border-radius: 10px; color: var(--text); font-size: var(--text-base); }
.sheet-act:active { background: var(--bg); }
.sheet-act.danger { color: var(--danger); }
.sheet-act.cancel { margin-top: var(--space-2); border-top: 1px solid var(--line); border-radius: 0; text-align: center; color: var(--muted); }
/* icon action rows (track sheet + playlist chooser) */
.sheet-act.ico { display: flex; align-items: center; gap: 12px; }
.sheet-act .sa-ic { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; flex: none; color: var(--muted); }
.sheet-act .sa-ic svg { width: 22px; height: 22px; }
.sheet-act.danger .sa-ic { color: var(--danger); }
.sheet-act .sa-t { flex: 1; min-width: 0; text-align: start; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-act .sa-ch { display: inline-flex; width: 18px; height: 18px; flex: none; color: var(--muted); }
.sheet-act .sa-ch svg { width: 18px; height: 18px; }
[dir="rtl"] .sheet-act .sa-ch { transform: scaleX(-1); }
.sheet-div { height: 1px; background: var(--line); margin: 6px 10px; }
/* track sheet header */
.track-sheet-head { display: flex; align-items: center; gap: 12px; padding: 2px 8px 12px; }
.tsh-art { width: 48px; height: 48px; border-radius: 8px; overflow: hidden; flex: none; background: var(--bg);
  display: flex; align-items: center; justify-content: center; }
.tsh-art img { width: 100%; height: 100%; object-fit: cover; }
.tsh-art .art-initial { font-size: 20px; font-weight: 700; color: #fff; }
.tsh-meta { min-width: 0; flex: 1; }
.tsh-t { font-weight: 600; font-size: var(--text-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
.tsh-s { color: var(--muted); font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; unicode-bidi: plaintext; }
/* playlist chooser rows */
.pl-search { padding: 2px 8px 8px; }
.pl-searchin { width: 100%; min-height: 44px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg); color: var(--text); font-size: var(--text-base); }
.sheet-act.pl-row .sa-t { display: flex; flex-direction: column; gap: 2px; white-space: normal; }
.pl-row .pl-rc { color: var(--muted); font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-act.pl-row.added { color: var(--muted); }
.sheet-act.pl-row.added .sa-ic { color: var(--accent); }
/* download toggle: cached = accent, in-progress = dimmed */
.sheet-act.ico.on .sa-ic { color: var(--accent); }
.sheet-act.ico.busy { color: var(--muted); }
/* sub-sheet back header */
.sheet-back { display: flex; align-items: center; gap: 6px; padding: 0 4px 10px; }
.sheet-back .sheet-title { padding: 4px 0; }
.sheet-backbtn { width: 36px; height: 36px; padding: 7px; flex: none; color: var(--text); background: none; border: none; }
.sheet-backbtn svg { width: 22px; height: 22px; transform: scaleX(-1); }
[dir="rtl"] .sheet-backbtn svg { transform: none; }
/* track info rows */
.tinfo { padding: 2px 10px 8px; }
.tinfo-row { display: flex; gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--line); }
.tinfo-row:last-child { border-bottom: none; }
.tinfo-k { color: var(--muted); font-size: var(--text-sm); flex: none; min-width: 84px; }
.tinfo-v { color: var(--text); min-width: 0; overflow-wrap: anywhere; text-align: end; margin-inline-start: auto; }
/* share / copy-link dialog (desktop share path) */
.share-dlg { padding: 4px 6px 8px; }
.share-sub { color: var(--muted); font-size: var(--text-sm); padding: 0 4px 10px; unicode-bidi: plaintext;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.share-url { width: 100%; box-sizing: border-box; padding: 12px 12px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--bg); color: var(--text); font-size: var(--text-base); font-family: inherit; }
.share-copy { width: 100%; margin-top: 10px; min-height: 48px; border: none; border-radius: 12px;
  background: var(--accent-gradient); color: #fff; font-size: var(--text-input); font-weight: 700; cursor: pointer; }
.share-status { min-height: 20px; margin-top: 8px; text-align: center; color: var(--accent); font-size: var(--text-sm); font-weight: 600; }
/* Community */
.comm-seg { display: flex; gap: var(--space-2); padding: 4px 0 10px; }
.comm-card { display: flex; gap: 12px; align-items: center; padding: 8px; border-radius: 14px; cursor: pointer; }
.comm-card:active { background: var(--card); }
.comm-body { min-width: 0; flex: 1; }
.comm-title { font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; unicode-bidi: plaintext; }
.comm-author { color: var(--accent); font-size: var(--text-sm); font-weight: 600; unicode-bidi: plaintext; }
.comm-meta { color: var(--muted); font-size: var(--text-sm); }
.cover { width: 64px; height: 64px; border-radius: 10px; overflow: hidden; flex: none; background: var(--card);
  display: grid; place-items: center; color: var(--muted); }
.cover svg { width: 28px; height: 28px; }
.cover-cell { background-size: cover; background-position: center; width: 100%; height: 100%; }
.cover-1 { grid-template-columns: 1fr; }
.cover-2, .cover-3, .cover-4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.cover-2 .cover-cell:first-child { grid-column: 1 / span 2; }
.cover-3 .cover-cell:first-child { grid-row: 1 / span 2; }
/* generated suggestions: weekly-mix hero + "Made by Melodili" shelf */
.home-weekly { padding: 4px var(--gutter) 0; }
.weekly-card { display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px; border-radius: 16px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); text-align: start; }
.weekly-card .cover { flex: 0 0 64px; width: 64px; height: 64px; border-radius: 10px; }
.weekly-meta { min-width: 0; }
.weekly-title { font-weight: 700; font-size: 16px; }
.weekly-sub { color: var(--muted); font-size: 13px; margin-top: 3px; unicode-bidi: plaintext; }
.sug-shelf { display: flex; gap: 12px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
  touch-action: auto; cursor: grab; user-select: none; -webkit-user-select: none; }
.sug-shelf.dragging { cursor: grabbing; }
.sug-shelf::-webkit-scrollbar { display: none; }
.sug-card { flex: 0 0 150px; display: flex; flex-direction: column; gap: 8px; padding: 0; border: none; background: none; color: var(--text); text-align: start; }
.sug-card .cover { width: 150px; height: 150px; border-radius: 12px; }
.sug-title { font-weight: 600; font-size: 14px; line-height: 1.3; white-space: normal;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; unicode-bidi: plaintext; }
.sug-sub { color: var(--muted); font-size: 12px; }
@media (hover: hover) { .weekly-card:hover { background: var(--hover); } }

/* Public playlist detail */
.pub-head { display: flex; gap: 14px; align-items: center; padding: 6px 4px 12px; }
.pub-head .cover { width: 88px; height: 88px; border-radius: 14px; }
.pub-info { min-width: 0; }
.pub-title { font-weight: 800; font-size: var(--text-base); color: var(--text); unicode-bidi: plaintext; }
.pub-author { color: var(--accent); font-weight: 600; font-size: var(--text-sm); unicode-bidi: plaintext; }
.pub-meta { color: var(--muted); font-size: var(--text-sm); }
.pub-bar { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px 14px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.react-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; gap: 5px; padding: 6px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); font-size: var(--text-sm); }
.chip.on { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 16%, var(--card)); }
.chip .ce { font-size: 15px; line-height: 1; }
.chip .cn { color: var(--muted); font-variant-numeric: tabular-nums; }

/* sort control: a chip above sortable lists → bottom sheet of options */
.sortbar { list-style: none; padding: 8px var(--gutter) 4px; display: flex; }
.sort-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); color: var(--text); font-size: 13px; font-weight: 600; }
.sort-chip svg { width: 16px; height: 16px; color: var(--muted); }
.sortsheet { padding: 2px 2px 6px; }
.sortsheet-h { padding: 6px 12px 10px; color: var(--muted); font-size: 13px; font-weight: 700; }
.sortsheet-row { display: grid; grid-template-columns: 22px minmax(0,1fr) auto; align-items: center; gap: 10px; width: 100%;
  padding: 13px 12px; border: none; background: none; color: var(--text); text-align: start; border-radius: 12px; }
.sortsheet-row .ss-chk { display: grid; place-items: center; color: var(--accent); }
.sortsheet-row .ss-chk svg { width: 18px; height: 18px; }
.sortsheet-row .ss-name { font-size: 15px; font-weight: 600; }
.sortsheet-row .ss-dir { color: var(--muted); font-size: 13px; unicode-bidi: plaintext; }
.sortsheet-row.on { background: var(--selected); }
@media (hover: hover) { .sort-chip:hover { background: var(--hover); } .sortsheet-row:hover { background: var(--hover); } }
.pub-acts { display: flex; gap: 8px; }
.pub-save { flex: 1; min-height: 40px; border-radius: 10px; border: 1px solid var(--line); background: var(--card); color: var(--text); font-weight: 600; }
.pub-save.on { border-color: var(--accent); color: var(--accent); }
.pub-more { width: 44px; border-radius: 10px; border: 1px solid var(--line); background: var(--card); color: var(--text); font-size: 18px; }
/* Library segment: scroll horizontally when it overflows (5 tabs). Touch pans
   natively; mouse (Telegram Desktop/Windows) uses JS drag-to-scroll + wheel. */
.set-theme { padding: 2px 0 8px; }
/* settings on/off toggle row: label block + a compact On|Off segment */
.set-toggle { align-items: center; gap: var(--space-3); }
.set-onoff { width: auto; flex: 0 0 auto; overflow: visible; }
.set-onoff .segbtn { padding: 0 14px; min-height: 40px; }
.seg { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.seg::-webkit-scrollbar { display: none; }
.segbtn { white-space: nowrap; }
#libseg { touch-action: auto; cursor: grab; user-select: none; -webkit-user-select: none; }
#libseg.dragging { cursor: grabbing; }
#libseg .segbtn { padding: 0 12px; }
/* Profile screen */
.avatar.lg { width: 72px; height: 72px; font-size: 26px; }
.prof-screen-head { display: flex; align-items: center; gap: 16px; padding: 8px 4px 16px; }
.prof-hinfo { min-width: 0; }
.prof-hname { font-weight: 800; font-size: 20px; color: var(--text); unicode-bidi: plaintext; }
.prof-edit { margin-top: 8px; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); color: var(--text); font-weight: 600; font-size: var(--text-sm); }
.stat-block { padding: 0 2px 14px; }
.stat-cap { color: var(--muted); font-size: 12px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; margin: 2px 2px 8px; }
.stat-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.stat-tile { background: var(--card); border-radius: 12px; padding: 10px 6px; text-align: center; }
.stat-v { font-weight: 800; font-size: 18px; color: var(--text); font-variant-numeric: tabular-nums; }
.stat-l { color: var(--muted); font-size: 11px; margin-top: 2px; }
.prof-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 4px 2px 12px; }
.grid-card { text-align: start; background: none; border: none; padding: 0; color: var(--text); cursor: pointer; }
.grid-cover { width: 100%; height: auto; aspect-ratio: 1 / 1; border-radius: 12px; }
.grid-title { font-weight: 700; margin-top: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; unicode-bidi: plaintext; }
.grid-meta { color: var(--muted); font-size: var(--text-sm); }
.prof-empty { color: var(--muted); padding: 8px 4px 16px; }
.prof-row { display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 8px 6px; border-top: 1px solid var(--line); cursor: pointer; }
.prof-row:active { background: var(--card); }
/* admin moderation queue */
.mod-card { background: var(--card); border-radius: 12px; padding: 12px; margin-bottom: 10px; }
.mod-head { display: flex; align-items: center; gap: 8px; }
.mod-badge { font-size: 11px; font-weight: 700; text-transform: uppercase; padding: 2px 7px; border-radius: 999px;
  color: var(--accent-text); background: var(--accent); }
.mod-badge.track { background: var(--accent-2); color: #fff; }
.mod-title { font-weight: 700; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; unicode-bidi: plaintext; }
.mod-meta { color: var(--muted); font-size: var(--text-sm); margin: 6px 0 10px; }
.mod-acts { display: flex; gap: 8px; }
.mod-btn { flex: 1; min-height: 38px; border-radius: 10px; border: 1px solid var(--line); background: var(--bg); color: var(--text); font-weight: 600; font-size: var(--text-sm); }
.mod-btn.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
.prof-row.danger .prow-t { color: var(--danger); }
.prow-ic { width: 20px; height: 20px; display: inline-flex; color: var(--muted); }
.prow-ic svg { width: 20px; height: 20px; }
.prow-t { flex: 1; }
.prow-chev { color: var(--muted); }
.sheet-sub { padding: 0 8px 10px; color: var(--muted); font-size: var(--text-sm); margin-top: -8px; }
.sheet-note { padding: 4px 10px 12px; color: var(--muted); font-size: var(--text-sm); line-height: 1.45; }
.avatar { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; flex: none; }
.avatar.mono { display: grid; place-items: center; background: color-mix(in srgb, var(--accent) 22%, var(--card));
  color: var(--text); font-weight: 700; font-size: 16px; }
.avatar.has-img { background-size: cover; background-position: center; color: transparent; }
.ava-actions { display: flex; flex-direction: column; }
.ava-actions label.sheet-act { cursor: pointer; }
.prof-head { display: flex; align-items: center; gap: 12px; padding: 4px 10px 12px; }
.prof-name { font-weight: 700; color: var(--text); font-size: var(--text-base); unicode-bidi: plaintext; }
.pl-new { display: flex; gap: var(--space-2); padding: 6px 8px; }
.pl-name { flex: 1; min-width: 0; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--bg); color: var(--text); font-size: var(--text-input); }
.pl-new .sheet-act { width: auto; background: var(--accent-gradient); color: #fff; text-align: center; border: none; font-weight: 600; }
.pl-desc-input { flex: 1; min-width: 0; width: 100%; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--bg); color: var(--text); font-size: var(--text-input); font-family: inherit; resize: vertical; min-height: 72px; }
.pl-desc-form { flex-direction: column; align-items: stretch; }
.pl-desc-form .sheet-act { width: 100%; margin-top: 8px; }
/* add-music sheet */
.sheet-body { display: flex; flex-direction: column; }
.add-opt { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%;
  text-align: start; padding: 12px 10px; border: none; background: none; cursor: pointer; border-radius: 12px; }
.add-opt:active { background: var(--bg); }
.add-opt .ao-t { color: var(--text); font-weight: 600; font-size: var(--text-base); }
.add-opt .ao-s { color: var(--muted); font-size: var(--text-sm); }
@media (min-width: 760px) {
  .sheet { align-items: center; justify-content: center; padding: 24px; }
  .sheet-panel { max-width: 420px; padding: 16px; border: 1px solid var(--line); border-radius: 20px; }
  .sheet-panel::before { display: none; }
}

.toast { position: fixed; left: 50%; bottom: calc(var(--nav-height) + var(--inset-bottom) + var(--player-height) + 20px); transform: translateX(-50%);
  z-index: 40; max-width: calc(100vw - 32px); background: var(--text); color: var(--bg);
  padding: 9px 16px; border-radius: 999px; font-size: 14px; font-weight: 600; text-align: center; }
.toast.with-action { display: flex; align-items: center; gap: 14px; padding-inline-end: 6px; }
.toast-undo { flex: 0 0 auto; background: none; border: none; color: var(--accent); font-weight: 700; font-size: 14px; cursor: pointer; padding: 4px 8px; }

/* ---- sources: rows with an independent silence toggle ---- */
.src-row { display: grid; grid-template-columns: minmax(0, 1fr) var(--hit); align-items: center;
  column-gap: var(--space-1); border-bottom: 1px solid var(--line); direction: ltr; }
.src-row:last-child { border-bottom: 0; }
/* reset native button surfaces so rows aren't grey UA blocks */
.src-row button { appearance: none; -webkit-appearance: none; margin: 0; border: 0; background: transparent;
  color: inherit; font: inherit; text-align: start; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.src-open { display: grid; grid-template-columns: 44px minmax(0, 1fr) 16px; align-items: center; gap: var(--space-3);
  min-width: 0; min-height: 64px; padding: var(--space-2); border-radius: var(--radius-control); }
.src-open:active { background: var(--hover); }
.src-art { display: grid; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-art);
  background: var(--selected); color: var(--accent); }
.src-art svg { width: 22px; height: 22px; }
.src-row[data-kind="upload"] .src-art { color: var(--accent-2); background: var(--hover); }
.src-row[data-kind="profile_import"] .src-art { color: var(--muted); background: var(--hover); }
.src-row[data-silenced="true"] .src-art { color: var(--muted); background: var(--hover); }
.src-copy { min-width: 0; }
.src-title { display: block; font-size: var(--text-base); font-weight: 600; line-height: 1.4;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.src-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--space-2); margin-top: 2px;
  color: var(--muted); font-size: var(--text-xs); }
.src-count { font-variant-numeric: tabular-nums; }
.src-status { display: inline-flex; align-items: center; gap: 5px; }
.src-status::before { content: ""; width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.src-status[data-indexing="true"] { color: var(--accent); }
.src-badge { padding: 1px 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--hover);
  color: var(--text); font-weight: 500; }
.src-chev { display: grid; place-items: center; color: var(--muted); }
.src-chev svg { width: 16px; height: 16px; }
.src-open[dir="rtl"] .src-chev { transform: scaleX(-1); }
.src-toggle { display: grid; place-items: center; width: var(--hit); height: var(--hit);
  border-radius: var(--radius-control); color: var(--muted); }
.src-toggle svg { width: 20px; height: 20px; }
.src-toggle[aria-pressed="true"] { background: var(--hover); color: var(--text); }
.src-toggle:active { background: var(--hover); }

/* the primary "Add music" row on the Sources screen */
.src-add { display: flex; align-items: center; justify-content: center; gap: var(--space-2); width: 100%;
  min-height: 48px; margin-bottom: var(--space-2); padding: 0 var(--space-4);
  border: 1px solid var(--line); border-radius: var(--radius-control);
  background: var(--selected); color: var(--accent); font-weight: 650; cursor: pointer; }
.src-add svg { width: 18px; height: 18px; }
.src-add:active { background: var(--hover); }

/* ---- browser sign-in ---- */
.signin { position: fixed; inset: 0; z-index: 50; background: var(--bg); overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch; }
.si-card { width: 100%; max-width: 360px; text-align: center; }
.si-logo { font-size: 26px; font-weight: 800; margin-bottom: 8px; }
.si-lead { color: var(--muted); margin: 0 0 22px; }
.si-btn { display: block; width: 100%; padding: 14px 18px; border-radius: 12px; border: none;
  background: var(--accent-gradient); color: #fff; font-size: var(--text-input); font-weight: 700;
  text-decoration: none; box-sizing: border-box; cursor: pointer; min-height: 48px; }
.si-btn[disabled] { opacity: .6; }
.si-state { margin-top: 16px; }
.si-wait { color: var(--muted); font-size: 14px; margin-top: 12px; }
.si-link { background: none; border: none; color: var(--accent); font: inherit; font-weight: 600; }
/* browser sign-in: the send-the-code panel (works where the deep link is censored) */
.si-code { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 10px; margin: 8px 0 14px; }
.si-code-val { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: clamp(26px, 8vw, 34px);
  font-weight: 800; letter-spacing: 3px; color: var(--text); user-select: all; -webkit-user-select: all;
  padding: 8px 12px; border-radius: 10px; background: rgb(127 127 127 / 12%); }
.si-copy { border: 1px solid var(--line); background: var(--card); color: var(--text); border-radius: 9px;
  padding: 9px 13px; font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap; min-height: 40px; }
.si-open { margin: 6px 0 2px; }
.si-warn, .si-help { color: var(--muted); font-size: 12.5px; line-height: 1.5; margin: 12px 0 0; }
.si-bot { color: var(--accent); font-weight: 700; text-decoration: none; white-space: nowrap; }

/* ---- pre-login landing page (responsive, desktop-capable) ---- */
.lp { max-width: 460px; margin: 0 auto; padding: 0 22px env(safe-area-inset-bottom, 24px); }
.lp-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 16px 0 6px; }
.lp-brand { display: flex; align-items: center; gap: 9px; font-size: 19px; font-weight: 800; }
.lp-logo { width: 30px; height: 30px; border-radius: 8px; }
.lp-controls { display: flex; align-items: center; gap: 8px; }
.lp-tbtn { display: inline-flex; align-items: center; justify-content: center; min-width: 40px; height: 40px;
  padding: 0 12px; border-radius: 11px; border: 1px solid rgb(127 127 127 / 22%); background: transparent;
  color: inherit; font-weight: 700; font-size: 14px; cursor: pointer; }
.lp-tbtn .lp-ic { width: 18px; height: 18px; }
.lp-hero { padding: 26px 0 8px; text-align: start; }
.lp-title { font-size: clamp(30px, 8vw, 40px); line-height: 1.08; font-weight: 800; letter-spacing: -.02em; margin: 0 0 14px; }
.lp-subhead { color: var(--muted); font-size: 17px; line-height: 1.5; margin: 0 0 26px; }
.lp-cta-wrap .lp-cta { max-width: 340px; }
.lp-note { color: var(--muted); font-size: 14px; margin: 12px 0 0; }
.lp-handshake { color: var(--muted); font-size: 13px; margin: 18px 0 0; opacity: .85; }
.lp-section { padding: 34px 0 6px; }
.lp-h { font-size: 22px; font-weight: 800; letter-spacing: -.01em; margin: 0 0 20px; }
.lp-feats, .lp-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 18px; }
.lp-feat, .lp-step { display: flex; align-items: flex-start; gap: 14px; }
.lp-feat h3, .lp-step h3 { font-size: 16px; font-weight: 700; margin: 0 0 3px; }
.lp-feat p, .lp-step p { color: var(--muted); font-size: 14.5px; line-height: 1.45; margin: 0; }
.lp-chip { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 11px; display: grid; place-items: center;
  background: var(--accent-gradient); color: #fff; }
.lp-ic { width: 20px; height: 20px; }
.lp-num { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-weight: 800; font-size: 15px; background: rgb(127 127 127 / 12%); color: var(--accent); margin-top: 1px; }
.lp-close { padding: 40px 0 30px; text-align: center; }
.lp-close .lp-cta-wrap { display: inline-block; width: 100%; max-width: 340px; }
.lp-footer { text-align: center; color: var(--muted); font-size: 13px; padding: 24px 0 40px; border-top: 1px solid rgb(127 127 127 / 15%); }
[dir="rtl"] .lp-hero { text-align: right; }

/* tablet: 2-up feature/step grids, roomier container */
@media (min-width: 680px) {
  .lp { max-width: 760px; padding-inline: 32px; }
  .lp-feats, .lp-steps { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px 30px; }
}

/* desktop-first: centered hero, 3-up grids, card-style feature tiles */
@media (min-width: 1000px) {
  .lp { max-width: 1080px; padding: 0 48px env(safe-area-inset-bottom, 40px); }
  .lp-top { padding: 22px 0 10px; }
  .lp-hero { text-align: center; padding: 64px 0 24px; }
  .lp-title { font-size: clamp(44px, 5vw, 60px); line-height: 1.04; max-width: 16ch; margin-inline: auto; }
  .lp-subhead { font-size: 19px; max-width: 620px; margin-inline: auto; margin-bottom: 30px; }
  .lp-cta-wrap { display: flex; flex-direction: column; align-items: center; }
  .lp-cta-wrap .lp-cta { width: auto; min-width: 300px; }
  .lp-section { padding: 56px 0 6px; text-align: center; }
  .lp-h { font-size: 28px; margin-bottom: 34px; }
  .lp-feats { grid-template-columns: repeat(3, 1fr); gap: 24px; }
  .lp-feat { flex-direction: column; align-items: flex-start; gap: 14px; text-align: start;
    padding: 26px 24px; border: 1px solid rgb(127 127 127 / 15%); border-radius: 16px; background: rgb(127 127 127 / 5%); }
  .lp-feat h3 { font-size: 17px; }
  .lp-feat p { font-size: 15px; }
  .lp-steps { grid-template-columns: repeat(3, 1fr); gap: 30px; max-width: 900px; margin-inline: auto; }
  .lp-step { text-align: start; }
  .lp-close { padding: 64px 0 36px; }
  .lp-footer { padding: 28px 0 48px; }
}

/* ---- responsive shell ---- */
@media (min-width: 600px) { :root { --gutter: 24px; } }
@media (min-width: 900px) {
  body > header { grid-template-columns: minmax(0, 1fr) minmax(280px, 360px); align-items: center; column-gap: 32px;
    padding-top: calc(var(--inset-top) + 12px); }
  #search { grid-column: 2; grid-row: 1; }
  #libseg { grid-column: 1 / -1; }
}

/* ===== first-run onboarding overlay ===== */
.onboarding { position: fixed; inset: 0; z-index: 60; background: var(--bg); color: var(--text); overflow-y: auto; }
.onb-wrap { display: flex; flex-direction: column; min-height: 100%; max-width: 34rem; margin-inline: auto;
  padding: calc(var(--inset-top) + var(--space-4)) var(--space-5) calc(var(--inset-bottom) + var(--space-5)); box-sizing: border-box; }
.onb-head { display: flex; align-items: center; gap: var(--space-2); min-height: 40px; color: var(--muted); }
.onb-back { flex: none; margin-inline-start: -8px; }
.onb-prog { font-size: var(--text-sm); }
.onb-body { flex: 1; padding-block: var(--space-5) var(--space-4); }
.onb-title { margin: 0 0 var(--space-2); font-size: 26px; font-weight: 800; line-height: 1.3; letter-spacing: .2px; outline: none; }
.onb-sub { margin: 0 0 var(--space-4); color: var(--muted); line-height: 1.5; }
.onb-opts { display: grid; gap: var(--space-3); margin-top: var(--space-4); }
.onb-opt, .onb-src { display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: start;
  padding: var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-panel); background: var(--card);
  color: var(--text); cursor: pointer; }
.onb-opt:active, .onb-src:active { background: var(--hover); }
.onb-opt.sel, .onb-src.sel { border-color: var(--accent); background: var(--selected); }
.onb-opt-copy, .onb-src-copy { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.onb-opt-t { font-weight: 700; font-size: var(--text-lg); }
.onb-opt-s { color: var(--muted); font-size: var(--text-sm); }
.onb-src-t { font-weight: 700; font-size: var(--text-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.onb-src-g { color: var(--text); font-size: var(--text-sm); opacity: .85; }
.onb-src-g:empty { display: none; }
.onb-src-m { color: var(--muted); font-size: var(--text-xs); }
.onb-check { flex: none; display: grid; place-items: center; width: 26px; height: 26px; border: 1.5px solid var(--muted);
  border-radius: 8px; color: transparent; }
.onb-check svg { width: 18px; height: 18px; }
.onb-opt.sel .onb-check, .onb-src.sel .onb-check { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.onb-tools { display: flex; gap: var(--space-2); margin-bottom: var(--space-3); }
.onb-tools button { min-height: 36px; padding: 0 var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-control);
  background: transparent; color: var(--muted); font: inherit; font-size: var(--text-sm); cursor: pointer; }
.onb-sources { display: grid; gap: var(--space-2); }
.onb-manage { margin: var(--space-4) 0 0; color: var(--muted); font-size: var(--text-sm); line-height: 1.5; }
.onb-foot { position: sticky; bottom: 0; display: grid; gap: var(--space-2); padding-top: var(--space-3);
  background: linear-gradient(to top, var(--bg) 70%, transparent); }
.onb-count { color: var(--muted); font-size: var(--text-sm); text-align: center; }
.onb-primary { min-height: 50px; border: none; border-radius: var(--radius-control); background: var(--accent-gradient);
  color: #fff; font-weight: 700; font-size: var(--text-base); cursor: pointer; }
.onb-primary:active { filter: brightness(.95); }
.onb-skip { min-height: 40px; border: none; background: transparent; color: var(--muted); font: inherit; cursor: pointer; }
[dir="rtl"] .onb-back svg { transform: scaleX(-1); }

/* ===== issue reporting ===== */
#report-issue { position: relative; }
.issue-badge { position: absolute; top: 2px; inset-inline-end: 2px; min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 999px; background: var(--danger); color: #fff; font-size: 10px; font-weight: 800; line-height: 15px;
  text-align: center; box-shadow: 0 0 0 2px var(--bg); }
.issues { display: flex; flex-direction: column; gap: var(--space-3); min-height: 0; }
.issue-head { display: flex; align-items: center; gap: var(--space-2); }
.issue-head .sheet-title { margin: 0; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.issue-back { flex: none; width: 34px; height: 34px; border: none; background: none; color: var(--text); border-radius: 999px; cursor: pointer; display: grid; place-items: center; }
.issue-back:active { background: var(--hover); }
.issue-back svg { width: 20px; height: 20px; }
[dir="rtl"] .issue-back svg { transform: scaleX(-1); }
.seg-mini-group { display: inline-flex; background: var(--card); border-radius: 999px; padding: 2px; gap: 2px; }
.seg-mini { border: none; background: none; color: var(--muted); font: inherit; font-size: var(--text-sm); font-weight: 600;
  padding: 5px 12px; border-radius: 999px; cursor: pointer; }
.seg-mini.active { background: var(--accent); color: var(--accent-text); }
.issue-newbtn { border: none; border-radius: var(--radius-control); background: var(--accent); color: var(--accent-text);
  font: inherit; font-weight: 700; padding: 12px; cursor: pointer; }
.issue-newbtn:active { filter: brightness(.95); }
.issue-empty { color: var(--muted); font-size: var(--text-sm); line-height: 1.6; text-align: center; padding: 24px 12px; }
.issue-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.issue-row { display: flex; align-items: center; gap: var(--space-3); padding: 12px 6px; cursor: pointer;
  border-top: 1px solid var(--line); }
.issue-row:active { background: var(--hover); }
.issue-row .ir-main { flex: 1; min-width: 0; }
.ir-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.issue-row.unread .ir-title { position: relative; }
.issue-row.unread .ir-title::after { content: ""; display: inline-block; width: 7px; height: 7px; margin-inline-start: 6px;
  border-radius: 999px; background: var(--danger); vertical-align: middle; }
.ir-prev { color: var(--muted); font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
.ir-status { flex: none; font-size: var(--text-xs); font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.st-open { background: color-mix(in srgb, var(--accent-2) 22%, transparent); color: var(--accent-2); }
.st-resolved { background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent); }
.st-not_an_issue { background: color-mix(in srgb, var(--muted) 20%, transparent); color: var(--muted); }
.issue-subject { border: 1px solid var(--line); border-radius: var(--radius-control); background: var(--bg); color: var(--text);
  font: inherit; font-size: var(--text-input); padding: 11px 12px; }
.issue-subject:focus { outline: none; border-color: var(--accent); }

/* composer */
.issue-composer { display: flex; flex-direction: column; gap: var(--space-2); margin-top: auto; padding-top: var(--space-2); }
.issue-thumbs { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.issue-thumb { position: relative; width: 64px; height: 64px; border-radius: 8px; overflow: hidden; background: var(--card); }
.issue-thumb img { width: 100%; height: 100%; object-fit: cover; }
.issue-thumb-x { position: absolute; top: 2px; inset-inline-end: 2px; width: 20px; height: 20px; border: none; border-radius: 999px;
  background: rgb(0 0 0 / 60%); color: #fff; font-size: 15px; line-height: 1; cursor: pointer; display: grid; place-items: center; }
.issue-inputrow { display: flex; align-items: flex-end; gap: var(--space-2); }
.issue-attach, .issue-send { flex: none; width: 40px; height: 40px; border: none; border-radius: 999px; cursor: pointer;
  display: grid; place-items: center; }
.issue-attach { background: var(--card); color: var(--muted); }
.issue-send { background: var(--accent); color: var(--accent-text); }
.issue-attach svg, .issue-send svg { width: 20px; height: 20px; }
.issue-text { flex: 1; min-width: 0; resize: none; border: 1px solid var(--line); border-radius: 18px; background: var(--bg);
  color: var(--text); font: inherit; font-size: var(--text-input); padding: 9px 14px; max-height: 120px; line-height: 1.4; }
.issue-text:focus { outline: none; border-color: var(--accent); }

/* thread */
.issue-detail { height: 70vh; }
.issue-admin { margin: 0 0 4px; }
.issue-thread { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-2) 0; }
.issue-msg { max-width: 82%; display: flex; flex-direction: column; gap: 4px; }
.issue-msg.user { align-self: flex-end; align-items: flex-end; }
.issue-msg.admin { align-self: flex-start; align-items: flex-start; }
.im-meta { font-size: var(--text-xs); color: var(--muted); font-weight: 700; padding: 0 4px; }
.im-body { padding: 9px 13px; border-radius: 16px; font-size: var(--text-base); line-height: 1.45; white-space: pre-wrap;
  overflow-wrap: anywhere; }
.issue-msg.user .im-body { background: var(--accent); color: var(--accent-text); border-bottom-right-radius: 5px; }
.issue-msg.admin .im-body { background: var(--card); color: var(--text); border-bottom-left-radius: 5px; }
.im-imgs { display: flex; flex-wrap: wrap; gap: 6px; }
.im-img { width: 120px; height: 120px; object-fit: cover; border-radius: 10px; cursor: pointer; background: var(--card); }
.img-lightbox { position: fixed; inset: 0; z-index: 100; background: rgb(0 0 0 / 88%); display: grid; place-items: center; padding: 20px; }
.img-lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 8px; }

/* ---- single-instance handoff: cover for a superseded browser/PWA instance ---- */
#instance-yield { position: fixed; inset: 0; z-index: 200; display: grid; place-content: center; justify-items: center;
  gap: 14px; padding: 24px; background: var(--bg); color: var(--text); text-align: center; font-size: 15px; }
#instance-yield p { margin: 0; color: var(--muted); }
#instance-yield button { background: var(--accent); color: var(--accent-text); border: none; border-radius: 12px;
  padding: 12px 22px; font: inherit; font-weight: 700; cursor: pointer; }

/* ===== guest mode (/t/<token>): the real app, player up, the rest blurred ===== */
body.guest .titlebar-heading, body.guest .tb-actions > :not(#theme-toggle):not(#lang-toggle),
body.guest #libseg, body.guest #home-top, body.guest #status, body.guest #list, body.guest #more, body.guest #nav {
  filter: blur(7px) saturate(0.9); opacity: 0.85; user-select: none; -webkit-user-select: none;
}
body.guest #search { filter: blur(5px); pointer-events: none; }
#guest-pill {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 14;
  bottom: calc(var(--inset-bottom) + var(--nav-height) + 84px);
  padding: 8px 14px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--card) 88%, var(--accent) 12%); color: var(--text); font: inherit; font-size: 13px; font-weight: 600;
  box-shadow: 0 8px 24px rgba(0,0,0,.25); cursor: pointer; white-space: nowrap; max-width: calc(100vw - 32px); overflow: hidden; text-overflow: ellipsis;
}
body.guest #now:not([hidden]) ~ #guest-pill { z-index: 21; bottom: calc(var(--inset-bottom) + 16px); }
.guest-sheet { display: flex; flex-direction: column; gap: 10px; padding: 6px 2px 2px; }
.guest-sheet h3 { margin: 0; font-size: 18px; }
.guest-sheet p { margin: 0 0 6px; color: var(--muted); line-height: 1.5; }
.guest-sheet .sheet-act { display: block; text-align: center; text-decoration: none; }
.guest-sheet .sheet-act.primary { background: var(--accent-gradient); color: var(--accent-text); }
