:root {
  --bg: #121212;
  --bg-2: #181818;
  --bg-3: #242424;
  --bg-4: #2e2e2e;
  --text: #ffffff;
  --muted: #a7a7a7;
  --accent: #1ed760;
  --accent-2: #fe2c55;   /* brand pink */
  --accent-3: #25f4ee;   /* brand cyan */
  /* Tikify's own mark: the app icon, the "All sounds" tile and the Add tab */
  --brand: linear-gradient(135deg, var(--accent-2), #7b2cbf 55%, var(--accent-3));
  --danger: #f15e6c;
  --radius: 8px;
  --tabbar-h: 64px;
  --mini-h: 60px;
  --update-h: 56px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  color-scheme: dark;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  overscroll-behavior: none;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
button:disabled { opacity: .5; cursor: default; }
svg { width: 24px; height: 24px; fill: currentColor; display: block; }
[hidden] { display: none !important; }

/* App, not web page: a long press on a control doesn't select its text or offer to save a cover,
   and a quick double tap (Next, Next) doesn't zoom. Text in messages and forms stays selectable. */
button, a, label, summary, .row, .tabbar, .mini-player, .player, .sheet-item, .sheet-handle { -webkit-user-select: none; user-select: none; }
img { -webkit-touch-callout: none; -webkit-user-drag: none; }
html, body, #view, .player, .sheet, button, a, label, summary, .row { touch-action: manipulation; }

/* Full width, so the page scrolls (and shows its scrollbar) wherever the mouse is; the content
   stays in a 720px column through the side padding. */
#app { height: 100%; display: flex; flex-direction: column; --gutter: max(16px, env(safe-area-inset-left), env(safe-area-inset-right), calc(50% - 344px)); }

/* ---------- top bar ---------- */
.topbar {
  display: flex; align-items: center; gap: 8px; flex: none;
  /* one height on every view (the 44px buttons fit exactly), so titles don't jump between tabs */
  height: calc(60px + var(--safe-t));
  padding: calc(8px + var(--safe-t)) var(--gutter) 8px;
}
.topbar h1 { font-size: 24px; font-weight: 800; margin: 0; flex: 1; letter-spacing: -.3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .15s; }
/* A playlist's name shows in the bar once its own heading has scrolled away. */
.topbar.scroll-title h1 { font-size: 18px; letter-spacing: -.2px; }
.topbar.title-hidden h1 { opacity: 0; }
.icon-btn { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 50%; color: var(--text); flex: none; position: relative; }
.icon-btn:active { background: var(--bg-3); }
.icon-btn.on { color: var(--accent); }
.icon-btn.on::after { content: ""; position: absolute; bottom: 2px; width: 4px; height: 4px; border-radius: 50%; background: var(--accent); }
.icon-btn.big { width: 56px; height: 56px; }
.icon-btn.big svg { width: 32px; height: 32px; }

main#view {
  flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 0 var(--gutter) calc(var(--tabbar-h) + var(--safe-b) + 24px);
  /* keeps keyboard focus from landing behind the fixed tab bar and mini player */
  scroll-padding-bottom: calc(var(--tabbar-h) + var(--safe-b) + 16px);
}
body.has-mini main#view {
  padding-bottom: calc(var(--tabbar-h) + var(--mini-h) + var(--safe-b) + 32px);
  scroll-padding-bottom: calc(var(--tabbar-h) + var(--mini-h) + var(--safe-b) + 24px);
}

/* visually hidden, still read by screen readers */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* headings and dialogs that receive focus from script, not from Tab */
[tabindex="-1"]:focus { outline: none; }

/* ---------- lists ---------- */
.list { display: flex; flex-direction: column; }
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 0; text-align: left; width: 100%; border-radius: 6px;
}
/* List rows reach 8px past the column on both sides, so their highlight doesn't end flush with the cover. */
.list > .row { padding: 8px; margin: 0 -8px; width: calc(100% + 16px); }
.row.track { cursor: pointer; }
.row:active { background: var(--bg-2); }
.row .meta { flex: 1; min-width: 0; }
.row .t { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .s { color: var(--muted); font-size: 13px; margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; text-align: left; border-radius: 4px; }
.row.track.playing .t { color: var(--accent); }
/* an equalizer mark, so the playing row doesn't rely on color alone */
.row.track.playing .t::before {
  content: ""; display: inline-block; width: 12px; height: 11px; margin-right: 6px;
  background:
    linear-gradient(currentColor, currentColor) 0 100% / 3px 55% no-repeat,
    linear-gradient(currentColor, currentColor) 4.5px 100% / 3px 100% no-repeat,
    linear-gradient(currentColor, currentColor) 9px 100% / 3px 75% no-repeat;
}
.row .more { color: var(--muted); }

.cover {
  width: 56px; height: 56px; border-radius: 4px; object-fit: cover; flex: none;
  background: var(--bg-3); display: block;
}
.cover.empty { display: grid; place-items: center; color: var(--muted); }
/* Four equal quarters, whatever the covers' own shapes (TikTok thumbnails are portrait). */
.cover.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); overflow: hidden; }
.cover.grid img { width: 100%; height: 100%; min-width: 0; min-height: 0; object-fit: cover; display: block; }
.cover.all-sounds { display: grid; place-items: center; background: var(--brand); }
.cover.lg { width: 200px; height: 200px; border-radius: 6px; }
.cover.xl { width: 200px; height: 200px; border-radius: 4px; box-shadow: 0 8px 40px rgba(0,0,0,.6); }
.cover.xl svg, .cover.lg svg { width: 72px; height: 72px; }
.track .cover { width: 48px; height: 48px; }

.lib-actions { display: flex; gap: 8px; margin: 4px 0 12px; }
.backup-nudge { background: var(--bg-2); border: 1px solid var(--bg-4); border-radius: 12px; padding: 14px 16px; margin: 4px 0 14px; }
.backup-nudge p { color: var(--muted); font-size: 14px; line-height: 1.45; margin: 4px 0 0; }
.backup-nudge .row-btns { margin-top: 12px; }
.backup-nudge .btn { min-height: 44px; padding: 8px 18px; font-size: 14px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 7px 14px 7px 10px; border-radius: 999px;
  background: var(--bg-3); font-size: 14px; font-weight: 600;
}
.chip svg { width: 18px; height: 18px; }
.chip:active { background: var(--bg-4); }

/* ---------- playlist header ---------- */
.pl-header { display: flex; flex-direction: column; align-items: center; padding-top: 4px; }
.pl-header h1 {
  align-self: stretch; font-size: 26px; margin: 20px 0 4px; font-weight: 800; letter-spacing: -.4px; word-break: break-word;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
}
.pl-header .s { align-self: stretch; color: var(--muted); font-size: 13px; }
.pl-actions { align-self: stretch; display: flex; align-items: center; gap: 8px; margin: 12px 0 8px; }
.pl-actions .grow { flex: 1; }

.play-btn {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--text); color: #000; display: grid; place-items: center; flex: none;
  transition: transform .1s;
}
.play-btn svg { width: 28px; height: 28px; }
.play-btn:active { transform: scale(.94); }
.play-btn.green { background: var(--accent); }

/* ---------- empty state ---------- */
.empty-state { text-align: center; padding: 48px 16px; color: var(--muted); }
.empty-state.small { padding: 24px 16px; }
.empty-state h2 { color: var(--text); margin: 16px 0 8px; }
.empty-state p { margin: 0 0 20px; line-height: 1.5; }
.big-icon { width: 72px; height: 72px; border-radius: 50%; background: var(--bg-3); display: grid; place-items: center; margin: 0 auto; color: var(--text); font-size: 34px; }
.big-icon svg { width: 36px; height: 36px; }
.big-icon.ok { background: var(--accent); color: #000; font-weight: 800; }

/* ---------- buttons / inputs ---------- */
.btn {
  padding: 12px 22px; border-radius: 999px; font-weight: 700; font-size: 15px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.btn.primary { background: var(--text); color: #000; }
.btn.ghost { background: transparent; border: 1px solid #727272; }
.btn.danger { background: var(--danger); color: #000; }
.btn.wide { width: 100%; margin-top: 12px; }
.btn:active { transform: scale(.98); }
.link-btn { color: var(--accent); font-size: 13px; text-align: left; padding: 10px 0; }

.input {
  width: 100%; padding: 13px 14px; border-radius: 6px; border: 1px solid #7a7a7a;
  background: var(--bg-3); color: var(--text); font: inherit; font-size: 16px; outline: none;
}
.input:focus { border-color: #fff; box-shadow: 0 0 0 1px #fff; background: var(--bg-4); }
.input::placeholder { color: var(--muted); opacity: 1; }
.lbl { display: block; font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; margin: 16px 0 6px; }

/* ---------- add view ---------- */
.add-wrap { padding-top: 4px; }
.hint { color: var(--muted); line-height: 1.5; margin: 0 0 14px; }
.hint.center { text-align: center; margin-top: 32px; }
.lookup { position: relative; }
.lookup .input { padding-right: 52px; }
.lookup .paste { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.loading { display: flex; align-items: center; gap: 12px; color: var(--muted); padding: 28px 0; justify-content: center; }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--bg-4); border-top-color: var(--accent); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.error { background: #f15e6c22; border: 1px solid #f15e6c55; color: #ffb3ba; padding: 14px; border-radius: var(--radius); margin-top: 16px; line-height: 1.5; }
.error .btn { display: block; margin-top: 12px; color: var(--text); }
.note { background: var(--bg-3); color: var(--muted); padding: 10px 12px; border-radius: 6px; margin-top: 12px; font-size: 13px; }
.note.warn { background: #4a3a1a; color: #eee; line-height: 1.45; margin: 4px 0 12px; font-size: 14px; }
.empty-state .from-safari { margin: 28px 0 12px; font-size: 14px; }
.preview { position: relative; margin-top: 20px; padding: 16px; background: var(--bg-2); border-radius: 12px; }
.preview-top { position: relative; display: flex; justify-content: center; }
.preview-top .play-btn { position: absolute; bottom: -12px; right: calc(50% - 112px); box-shadow: 0 4px 16px rgba(0,0,0,.5); }
/* clear of the play button, which hangs 12px below the cover */
.preview-top + .note { margin-top: 24px; }
.pl-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
/* floated so the legend lays out like the other .lbl captions instead of sitting in the border */
.pl-fieldset legend { float: left; width: 100%; padding: 0; }
.pl-fieldset .pl-checks { clear: both; }
.pl-checks { display: flex; flex-wrap: wrap; gap: 8px; }
.pl-check { position: relative; }
.pl-check input { position: absolute; opacity: 0; pointer-events: none; }
.pl-check span { display: inline-flex; align-items: center; min-height: 40px; padding: 8px 14px; border-radius: 999px; background: var(--bg-3); font-size: 14px; font-weight: 600; cursor: pointer; border: 1px solid transparent; }
.pl-check input:checked + span { background: var(--accent); color: #000; }
.pl-check input:focus-visible + span { border-color: #fff; }
.saved { text-align: center; padding: 28px 0; display: flex; flex-direction: column; gap: 14px; align-items: center; }
.tips { margin-top: 16px; color: var(--muted); font-size: 14px; }
.tips summary { cursor: pointer; font-weight: 600; padding: 12px 0; }
.tips li { margin: 8px 0; line-height: 1.45; }
.tips code { background: var(--bg-3); padding: 1px 5px; border-radius: 4px; }

.search-wrap .input.search { margin-bottom: 12px; }

/* ---------- mini player ---------- */
.mini-player {
  position: fixed; left: 8px; right: 8px;
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 6px);
  max-width: 704px; margin: 0 auto;
  height: var(--mini-h); border-radius: 8px;
  background: #3a2a3a; background: linear-gradient(90deg, #2b2b3d, #3a2533);
  display: flex; align-items: center; gap: 10px; padding: 0 6px 0 8px;
  overflow: hidden; cursor: pointer; z-index: 10;
  box-shadow: 0 6px 20px rgba(0,0,0,.5);
}
.mini-open { flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: 10px; text-align: left; }
.mini-player img { width: 44px; height: 44px; border-radius: 4px; object-fit: cover; background: var(--bg-3); }
.mini-meta { flex: 1; min-width: 0; }
.mini-title { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-artist { color: #ccc; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.mini-progress { position: absolute; left: 8px; right: 8px; bottom: 0; height: 2px; background: #ffffff33; border-radius: 2px; }
.mini-progress div { height: 100%; width: 0; background: #fff; border-radius: 2px; }

/* ---------- tab bar ---------- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 9;
  height: calc(var(--tabbar-h) + var(--safe-b));
  /* the tabs sit under the content column on a wide screen */
  padding: 0 max(0px, calc(50% - 360px)) var(--safe-b);
  display: flex; justify-content: space-around; align-items: center;
  /* opaque, so list text doesn't run behind the icons; the fade above it eases the edge */
  background: #000;
}
/* Black behind the bars floating above it too (mini player, update bar), so no list text shows in the
   gaps between them; --above: how much of them there is. */
.tabbar { --above: 0px; }
body.has-mini .tabbar { --above: calc(var(--mini-h) + 6px); }
body.has-update .tabbar { --above: calc(var(--update-h) + 6px); }
body.has-update.has-mini .tabbar { --above: calc(var(--mini-h) + var(--update-h) + 12px); }
.tabbar::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: calc(var(--above) + 24px); background: linear-gradient(to top, #000 var(--above), #0000); pointer-events: none; }
.tabbar button { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); padding: 6px 18px; }
.tabbar button.active { color: var(--text); font-weight: 700; }
.tabbar button.active::after { content: ""; position: absolute; bottom: 0; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: currentColor; }
.tabbar .add-tab svg { background: var(--brand); color: #fff; border-radius: 8px; width: 40px; padding: 1px 9px; }

/* ---------- iPhone Home Screen app on iOS 26 ---------- */
/* There the page ends one status bar short of the screen's bottom, and nothing can be drawn below
   that line (WebKit bug 301108). iOS fills the strip, where the home indicator sits, with the app's
   background colour (#121212, manifest.webmanifest). app.js sets .short-bottom when it measures that
   layout: the page then needs no bottom inset, the tab bar takes the strip's colour so the two read
   as one bar down to the screen's edge, and sheets float as cards instead of looking cut off. */
html.short-bottom { --safe-b: 0px; }
html.short-bottom .tabbar { background: var(--bg); box-shadow: inset 0 1px #ffffff17; }
html.short-bottom .tabbar::before { background: linear-gradient(to top, var(--bg) var(--above), #12121200); }
html.short-bottom .sheet { width: calc(100% - 16px); margin-bottom: 8px; border-radius: 14px; transform: translateY(calc(100% + 16px)); }

/* ---------- full screen player ---------- */
.player {
  position: fixed; inset: 0; z-index: 20; background: var(--bg);
  transform: translateY(100%); transition: transform .25s ease;
  overflow: hidden;
}
.player.open { transform: none; }
.player-bg {
  position: absolute; inset: -60px; background-size: cover; background-position: center;
  filter: blur(50px) saturate(1.4) brightness(.45); transform: scale(1.2);
}
.player-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, transparent, var(--bg) 85%); }
.player-inner {
  position: relative; height: 100%; max-width: 480px; margin: 0 auto;
  display: flex; flex-direction: column;
  padding: calc(12px + var(--safe-t)) 24px calc(24px + var(--safe-b));
}
.player-top { display: flex; align-items: center; justify-content: space-between; }
.player-context { font-size: 12px; font-weight: 700; text-align: center; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 8px; }
.player-inner > * { flex: none; }
/* Square, and only as big as the height leaves room for (--rest: the rest of the player), so a short
   screen doesn't push the controls off the bottom. svh: the height while Safari shows its toolbars. */
.player-inner { --rest: 340px; }
.player-cover {
  width: max(120px, min(100%, calc(100vh - var(--rest) - var(--safe-t) - var(--safe-b))));
  height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 8px;
  align-self: center; margin: auto 0; box-shadow: 0 16px 60px rgba(0,0,0,.6); background: var(--bg-3);
}
@supports (height: 100svh) {
  .player-cover { width: max(120px, min(100%, calc(100svh - var(--rest) - var(--safe-t) - var(--safe-b)))); }
}
.player-meta { margin-top: 24px; }
.player-title { font-size: 22px; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.player-artist { color: var(--muted); margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* A 44px tall touch target around the 4px track; the negative bottom margin keeps the layout as it
   was, and z-index keeps the time labels from taking taps on its lower part. */
#seek {
  -webkit-appearance: none; appearance: none; width: 100%; height: 44px; margin: 6px 0 -12px; background: transparent; cursor: pointer;
  position: relative; z-index: 1;
  --fill: 0%;
}
#seek::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: linear-gradient(to right, #fff var(--fill), #ffffff44 var(--fill)); }
#seek::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%; background: #fff; margin-top: -5px; transition: transform .1s; }
#seek:active::-webkit-slider-thumb { transform: scale(1.3); }
#seek::-moz-range-track { height: 4px; border-radius: 2px; background: #ffffff44; }
#seek::-moz-range-progress { height: 4px; border-radius: 2px; background: #fff; }
#seek::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: #fff; }
/* Keyboard focus rings the thumb: an outline would frame the whole 44px box and cut through the times. */
#seek:focus-visible { outline: none; }
#seek:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 2px #000, 0 0 0 4px #fff; }
#seek:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 2px #000, 0 0 0 4px #fff; }
.times { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; margin-top: 2px; font-variant-numeric: tabular-nums; }
.controls { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; }
.controls .play-btn { width: 66px; height: 66px; }
.controls .play-btn svg { width: 32px; height: 32px; }
.repeat-one { position: absolute; top: 8px; right: 6px; font-size: 9px; font-weight: 800; background: var(--accent); color: #000; border-radius: 50%; width: 13px; height: 13px; display: grid; place-items: center; }
.open-tiktok { display: block; align-self: center; padding: 14px 16px; text-align: center; color: var(--muted); font-size: 13px; margin-top: 10px; text-decoration: none; }
.open-tiktok:active { color: var(--text); }
/* A small phone, or Safari's toolbars: tighter spacing leaves more room for the cover. */
@media (max-height: 640px) {
  .player-inner { --rest: 310px; padding-bottom: calc(16px + var(--safe-b)); }
  .player-meta { margin-top: 16px; }
  .controls { margin-top: 8px; }
  .open-tiktok { margin-top: 2px; padding: 10px 16px; }
}
/* A phone on its side (iOS ignores the manifest's orientation): cover on the left, controls on the right. */
@media (orientation: landscape) and (max-height: 520px) {
  .player-inner {
    max-width: 820px; display: grid; grid-template-columns: auto 1fr; column-gap: 32px; align-content: center;
    grid-template-areas: "top top" "cover meta" "cover seek" "cover times" "cover controls" "cover link";
    padding-left: max(24px, env(safe-area-inset-left)); padding-right: max(24px, env(safe-area-inset-right));
  }
  .player-top { grid-area: top; }
  .player-cover { grid-area: cover; width: auto; height: min(62vh, 280px); max-height: none; margin: 0; align-self: center; }
  .player-meta { grid-area: meta; margin-top: 0; align-self: end; min-width: 0; }
  #seek { grid-area: seek; }
  .times { grid-area: times; }
  .controls { grid-area: controls; margin-top: 4px; }
  .open-tiktok { grid-area: link; margin-top: 0; padding: 8px 16px; }
}

/* ---------- sheet ---------- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 30; background: rgba(0,0,0,0);
  display: flex; align-items: flex-end; justify-content: center; transition: background .2s;
}
.sheet-backdrop.open { background: rgba(0,0,0,.6); }
.sheet {
  width: 100%; max-width: 560px; max-height: 85vh; max-height: 85dvh; overflow-y: auto;
  background: #282828; border-radius: 14px 14px 0 0;
  padding: 8px 16px calc(16px + var(--safe-b));
  transform: translateY(100%); transition: transform .2s ease;
}
.sheet-backdrop.open .sheet { transform: none; }
/* being dragged down by its handle (or anywhere, once scrolled to the top) */
.sheet-backdrop.open .sheet.dragging { transition: none; }
.sheet-handle { width: 36px; height: 4px; border-radius: 2px; background: #555; margin: 4px auto 12px; }
.sheet-title { font-weight: 800; font-size: 17px; margin-bottom: 4px; word-break: break-word; }
.sheet-sub { color: var(--muted); font-size: 14px; margin-bottom: 8px; line-height: 1.45; }
.sheet-list { display: flex; flex-direction: column; margin-top: 8px; }
.sheet-item { display: flex; align-items: center; gap: 14px; padding: 14px 8px; text-align: left; font-size: 16px; border-radius: 6px; }
.sheet-item:active { background: #3a3a3a; }
.sheet-item.danger { color: var(--danger); }
.sheet-item.sheet-cancel { justify-content: center; color: var(--muted); font-weight: 600; margin-top: 4px; }
/* every item has one, so the labels line up */
.sheet-ic { width: 22px; height: 22px; flex: none; color: var(--muted); }
.sheet-item.danger .sheet-ic { color: inherit; }
.sheet-item svg { width: 22px; height: 22px; }
/* a toggle item that is on (a playlist that already holds the sound) */
.sheet-check { margin-left: auto; color: var(--accent); flex: none; }
.sheet-form .input { margin-top: 8px; }
.row-btns { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; }
.saved .row-btns { justify-content: center; }
.pick { max-height: 55vh; max-height: 55dvh; overflow-y: auto; }
.pick-row { position: relative; cursor: pointer; padding: 8px 4px; }
.pick-row .cover { width: 44px; height: 44px; }
/* the hidden checkbox covers the row, so a screen reader's focus outline frames the whole row */
.pick-row input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.pick-row:has(input:focus-visible) { outline: 2px solid #fff; outline-offset: -2px; }
.pick-row input:focus-visible + .check { box-shadow: 0 0 0 2px #fff; }
.pick-row .check { width: 24px; height: 24px; border-radius: 50%; border: 2px solid #777; flex: none; }
.pick-row input:checked + .check { background: var(--accent); border-color: var(--accent); box-shadow: inset 0 0 0 4px #282828; }

.about p { color: #ddd; line-height: 1.5; margin: 10px 0; font-size: 14px; }
.about b { color: #fff; }

/* ---------- update bar ---------- */
.update-bar {
  position: fixed; left: 8px; right: 8px; z-index: 11; max-width: 704px; margin: 0 auto;
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 6px);
  display: flex; align-items: center; gap: 6px; padding: 6px 4px 6px 14px; min-height: var(--update-h);
  background: #3e3e3e; border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,.5); font-size: 14px; font-weight: 600;
}
body.has-mini .update-bar { bottom: calc(var(--tabbar-h) + var(--mini-h) + var(--safe-b) + 12px); }
.update-bar span { flex: 1; min-width: 0; }
.update-bar .btn { padding: 8px 16px; min-height: 40px; font-size: 14px; }
body.has-update .toast { bottom: calc(var(--tabbar-h) + var(--safe-b) + 66px); }
body.has-update.has-mini .toast { bottom: calc(var(--tabbar-h) + var(--mini-h) + var(--safe-b) + 76px); }

/* ---------- toast ---------- */
.toast {
  /* centred by its margins, not left: 50%, which would cap its width at half the screen */
  position: fixed; left: 16px; right: 16px; margin: 0 auto; z-index: 40;
  width: -webkit-fit-content; width: fit-content; max-width: 480px;
  bottom: calc(var(--tabbar-h) + var(--safe-b) + 16px);
  background: #fff; color: #000; padding: 10px 16px; border-radius: 8px; font-weight: 600; font-size: 14px;
  box-shadow: 0 6px 20px rgba(0,0,0,.4); text-align: center;
  pointer-events: none; opacity: 0; transition: opacity .2s;
}
/* Clear of whatever sits above the tab bar; in the full player, at the top, off the controls. */
body.has-mini .toast { bottom: calc(var(--tabbar-h) + var(--mini-h) + var(--safe-b) + 18px); }
body.player-open .toast, body.player-open.has-update.has-mini .toast { top: calc(var(--safe-t) + 64px); bottom: auto; }
/* A phone on its side centres the player's content, so its top row isn't at the top: below it instead. */
@media (orientation: landscape) and (max-height: 520px) {
  body.player-open .toast, body.player-open.has-update.has-mini .toast { top: auto; bottom: calc(8px + var(--safe-b)); }
}
/* An open sheet covers the bottom of the screen (and the player's top bar): the toast goes above it. */
body.sheet-open .toast, body.sheet-open.has-update.has-mini .toast { top: calc(var(--safe-t) + 12px); bottom: auto; }
.toast.show { opacity: 1; }
.toast.error { box-shadow: inset 4px 0 0 var(--danger), 0 6px 20px rgba(0,0,0,.4); }

@media (min-width: 760px) {
  .cover.xl { width: 232px; height: 232px; }
}
/* a phone on its side: the playlist cover mustn't fill the whole screen */
@media (max-height: 520px) {
  .cover.xl { width: 140px; height: 140px; }
}
/* A wide screen: sheets open as dialogs in the middle instead of hanging off the bottom edge. */
@media (min-width: 760px) and (min-height: 560px) {
  .sheet-backdrop { align-items: center; padding: 24px; }
  .sheet { border-radius: 14px; padding-top: 20px; opacity: 0; transform: translateY(24px); transition: transform .2s ease, opacity .2s ease; }
  .sheet-backdrop.open .sheet { opacity: 1; }
  .sheet-handle { display: none; }
}

/* ---------- mouse ---------- */
/* Hover only where there is a real pointer: on a touch screen it would stick after a tap. */
@media (hover: hover) {
  .row:hover, .pick-row:hover { background: #ffffff0d; }
  .icon-btn:hover { background: #ffffff17; }
  .chip:hover, .pl-check span:hover { background: var(--bg-4); }
  .pl-check input:checked + span:hover { background: #3be477; }
  .sheet-item:hover { background: #333; }
  .tabbar button:hover { color: var(--text); }
  .btn.primary:not(:disabled):hover { background: #f0f0f0; }
  .btn.ghost:not(:disabled):hover { border-color: #fff; }
  .btn.danger:not(:disabled):hover { filter: brightness(1.1); }
  .play-btn:not(:disabled):hover { transform: scale(1.05); }
  .play-btn.green:not(:disabled):hover { background: #3be477; }
  .link-btn:hover, .open-tiktok:hover { color: var(--text); text-decoration: underline; }
  .tips summary:hover { color: var(--text); }
  .mini-open:hover .mini-title { text-decoration: underline; }
}

/* ---------- install prompt ---------- */
.install { display: flex; flex-direction: column; align-items: center; text-align: center; padding-top: 4px; }
.install-icon { width: 76px; height: 76px; border-radius: 18px; box-shadow: 0 6px 24px rgba(0,0,0,.5); }
.install-badge { margin: 12px 0 8px; padding: 3px 10px; border-radius: 999px; background: var(--accent); color: #000; font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; }
.sheet-title.center { text-align: center; font-size: 20px; }
.install-perks { list-style: none; padding: 0; margin: 12px 0 4px; align-self: stretch; text-align: left; }
.install-perks li { position: relative; padding: 7px 0 7px 30px; color: #ddd; }
.install-perks li::before { content: "✓"; position: absolute; left: 4px; color: var(--accent); font-weight: 800; }
.install-steps { align-self: stretch; text-align: left; background: var(--bg-3); border-radius: 10px; margin: 12px 0 0; padding: 12px 14px 12px 34px; line-height: 1.5; }
.install-steps li { margin: 6px 0; }
.inline-ic { display: inline-block; width: 18px; height: 18px; vertical-align: -3px; color: #4ea1ff; }
.install .btn.wide { margin-top: 12px; }
.install .btn.ghost.wide { border: 0; color: var(--muted); }
.install-none { color: var(--muted); line-height: 1.5; margin: 12px 0 0; }
.install-warn { align-self: stretch; text-align: left; margin: 12px 0 0; padding: 12px 14px; border-radius: 10px; line-height: 1.45; font-size: 14px; color: #ddd; background: #4a3a1a; border: 1px solid #8a6a2a; }
.install-warn b { color: #fff; }
.install-warn .btn { display: flex; margin-top: 10px; min-height: 44px; padding: 8px 18px; font-size: 14px; }
/* The buttons stay in view while the rest scrolls on a short screen (iPhone SE, Safari's toolbars). */
.install-actions {
  align-self: stretch; position: sticky; bottom: calc(-16px - var(--safe-b)); z-index: 1;
  margin: 4px -16px calc(-16px - var(--safe-b)); padding: 0 16px calc(12px + var(--safe-b));
  background: linear-gradient(to bottom, #28282800, #282828 16px);
}
@media (max-height: 700px) {
  .install-icon { width: 56px; height: 56px; border-radius: 14px; }
  .install-badge { display: none; }
  .install .sheet-title.center { margin-top: 10px; font-size: 18px; }
  .install-perks { margin-top: 6px; }
  .install-perks li { padding: 4px 0 4px 30px; font-size: 14px; }
  .install-perks li:nth-child(n+3) { display: none; }
}
@media (max-height: 600px) {
  .install-perks { display: none; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .player, .sheet, .sheet-backdrop, .play-btn, .btn, .toast, .topbar h1 { transition: none !important; }
  .play-btn:active, .btn:active, .play-btn:not(:disabled):hover { transform: none; }
  .spinner { animation-duration: 1.6s; }
}

.about-tech { color: var(--muted); font-size: 12px; margin-top: 16px; font-variant-numeric: tabular-nums; }
