/* ───────────────────────────────────────────────────────
   Crate — a personal DJ crate.
   Dark, quiet, typographic. Optimised for iPhone.
   ─────────────────────────────────────────────────────── */

:root {
  --bg:        #08080a;
  --bg-raised: #131316;
  --bg-field:  #1a1a1e;
  --hairline:  rgba(255,255,255,.075);
  --text:      #f4f4f6;
  --text-2:    #9a9aa4;
  --text-3:    #62626c;
  --accent:    #ff3b5c;

  /* Harmonic lights. Two colours only: a standard mix, or an energy move.
     Anything with no relationship stays neutral and uncoloured. */
  --std-bg:    rgba(56, 214, 138, .15);
  --std-fg:    #45d68f;
  --energy-bg: rgba(255, 176, 74, .15);
  --energy-fg: #ffb04a;

  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;

  --pad: 20px;
  --top: env(safe-area-inset-top, 0px);
  --bottom: env(safe-area-inset-bottom, 0px);

  --ease: cubic-bezier(.32,.72,0,1);

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
          system-ui, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Any class that sets `display` outranks the browser's own [hidden] rule,
   which quietly leaves elements on screen. Settle it once, here. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.35;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, textarea {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  margin: 0;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
}
button { cursor: pointer; touch-action: manipulation; }
input:focus, textarea:focus { outline: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
      stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

/* ── Library shell ─────────────────────────────────── */

.app { display: flex; flex-direction: column; height: 100%; }

.topbar {
  padding: calc(var(--top) + 10px) var(--pad) 0;
  background: var(--bg);
  flex: none;
  position: relative;
  z-index: 2;
}

.topbar-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; height: 40px;
}

h1 {
  margin: 0;
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -.022em;
}

.topbar-actions { display: flex; gap: 10px; }

.icon-btn {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--bg-raised);
  color: var(--text);
  display: grid; place-items: center;
  transition: transform .16s var(--ease), background .16s ease;
}
.icon-btn svg { width: 20px; height: 20px; }
.icon-btn:active { transform: scale(.9); background: #202026; }
.icon-btn.accent { background: var(--accent); color: #fff; }
.icon-btn.accent:active { background: #e02c4c; }

/* Search */
.searchbar {
  margin-top: 14px;
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-field);
  border-radius: 12px;
  padding: 0 10px;
  height: 40px;
}
.search-icon { width: 17px; height: 17px; color: var(--text-3); flex: none; }
.searchbar input {
  flex: 1; min-width: 0;
  font-size: 17px;                 /* ≥16px: stops iOS zooming on focus */
  letter-spacing: -.01em;
  background: none;
  height: 100%;
}
.searchbar input::placeholder { color: var(--text-3); }
.searchbar input::-webkit-search-cancel-button { display: none; }
.clear-btn { width: 22px; height: 22px; flex: none; color: var(--text-3); }
.clear-btn .fill { fill: currentColor; stroke: none; }
.clear-btn .x { stroke: var(--bg-field); stroke-width: 2.2; }

/* Now playing */
.nowplaying {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  margin-top: 12px;
  padding: 8px 12px 8px 8px;
  background: var(--bg-raised);
  border-radius: 14px;
  text-align: left;
  transition: transform .16s var(--ease), opacity .14s ease;
}
.nowplaying:active { transform: scale(.985); opacity: .75; }
.np-art {
  width: 42px; height: 42px; flex: none;
  border-radius: 8px; overflow: hidden; background: #1c1c21;
}
.np-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.np-meta { flex: 1; min-width: 0; }
.np-eyebrow {
  display: flex; align-items: center; gap: 5px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent);
}
.np-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent); display: block;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.np-title {
  display: block; margin-top: 2px;
  font-size: 15px; font-weight: 600; letter-spacing: -.014em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.np-sub {
  display: block;
  font-size: 12.5px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Key pill — the harmonic light */
.key-pill {
  flex: none;
  padding: 4px 7px;
  border-radius: 7px;
  background: rgba(255,255,255,.07);
  color: var(--text-2);
  font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  white-space: nowrap;
}
.key-pill.standard { background: var(--std-bg);    color: var(--std-fg); }
.key-pill.energy   { background: var(--energy-bg); color: var(--energy-fg); }
.key-pill.current  { background: rgba(255,255,255,.13); color: var(--text); }

/* Filter chips */
.filters { display: flex; gap: 8px; padding-top: 12px; }
.chip {
  padding: 8px 14px;
  border-radius: 100px;
  background: var(--bg-raised);
  color: var(--text-2);
  font-size: 13px; letter-spacing: -.005em;
  transition: background .14s ease, color .14s ease, transform .14s var(--ease);
}
.chip:active { transform: scale(.94); }
.chip.on { background: #f2f2f5; color: #08080a; font-weight: 600; }

/* Sort / count */
.sortbar {
  display: flex; align-items: center; gap: 5px;
  padding: 12px 2px 10px;
  font-size: 13px;
  color: var(--text-3);
  letter-spacing: -.005em;
}
.sortbar .sort-name { color: var(--text-2); }
/* One tap flips the direction, so there is no menu and nothing to point at
   with a chevron — the arrow in the label is the whole affordance. */
.sortbar { gap: 6px; }

.sortbar .chev { width: 13px; height: 13px; margin-left: -2px; color: var(--text-3); }
.sortbar:active { opacity: .55; }

/* ── Track list ────────────────────────────────────── */

.list {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: 0 var(--pad) calc(var(--bottom) + 28px);
}

.row {
  display: flex; align-items: center; gap: 13px;
  width: 100%;
  padding: 7px 0;
  text-align: left;
  position: relative;
  transition: opacity .12s ease, transform .12s ease;
}
.row:active { opacity: .5; transform: scale(.985); }
.row + .row::before, .swipe + .swipe .row::before {
  content: ""; position: absolute; left: 73px; right: 0; top: 0;
  height: 1px; background: var(--hairline);
}

.art {
  width: 60px; height: 60px; flex: none;
  border-radius: var(--r-sm);
  background: #1c1c21;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
}
.art img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  opacity: 0;
  transition: opacity .32s ease;
}
.art img.in { opacity: 1; }

.meta { flex: 1; min-width: 0; }
.meta .t, .meta .a, .bpm .n, .bpm .u { display: block; }
.meta .t {
  font-size: 16.5px; font-weight: 600; letter-spacing: -.015em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.meta .a {
  margin-top: 2px;
  font-size: 14px; color: var(--text-2); letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.bpm {
  flex: none; padding-left: 8px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
}
.bpm .n {
  font-size: 21px; font-weight: 600;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.bpm .u {
  font-size: 9px; font-weight: 600; letter-spacing: .1em;
  color: var(--text-3); text-transform: uppercase;
}

/* Played tracks recede but stay legible and tappable. */
.row.played .art, .row.played .meta, .row.played .bpm { opacity: .38; }
.row .tick {
  display: none;
  width: 11px; height: 11px;
  margin-right: 5px;
  vertical-align: -1px;
  color: var(--text-2);
}
.row.played .tick { display: inline-block; }

.empty {
  margin: 0; padding: 64px var(--pad);
  text-align: center; color: var(--text-3);
  font-size: 15px; line-height: 1.5;
}

/* ── Sheets ────────────────────────────────────────── */

.sheet {
  position: fixed; inset: 0;
  background: var(--bg);
  display: flex; flex-direction: column;
  z-index: 20;
  transform: translate3d(0, 100%, 0);
  visibility: hidden;
  transition: transform .4s var(--ease), visibility 0s linear .4s;
}
.sheet.open {
  transform: translate3d(0,0,0);
  visibility: visible;
  transition: transform .4s var(--ease), visibility 0s linear 0s;
}

.sheet-head {
  flex: none;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
  padding: calc(var(--top) + 12px) 14px 12px;
  border-bottom: 1px solid var(--hairline);
  background: var(--bg);
}
.sheet-title {
  font-size: 16px; font-weight: 600; letter-spacing: -.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  text-align: center;
}
.txt-btn {
  font-size: 16px; color: var(--text-2);
  padding: 6px; letter-spacing: -.01em;
  justify-self: start;
}
.sheet-head .txt-btn:last-child { justify-self: end; }
.txt-btn.strong { color: var(--accent); font-weight: 600; }
.txt-btn.ghost { visibility: hidden; }
.txt-btn:active { opacity: .5; }

.sheet-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  padding: 24px var(--pad) calc(var(--bottom) + 40px);
}

/* ── Detail ────────────────────────────────────────── */

/* The detail sheet is a glance, not a page — everything about a record
   should be in front of you without a scroll, on the shortest phone and
   with Safari's toolbars showing. So the pieces that can give ground do:
   the sleeve shrinks to whatever height is left, and the vertical rhythm
   tightens on short screens. The numbers never shrink; they are the point. */
.detail-body {
  text-align: center;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.hero-art {
  /* Sized by the height left over, not the width — dvh so Safari's
     collapsing toolbar is counted rather than guessed at. */
  height: clamp(120px, 30dvh, 300px);
  min-height: 120px;   /* it gives up height to fit, but never to nothing */
  width: auto;
  aspect-ratio: 1 / 1;
  flex: 0 1 auto;
  margin: 2px auto 18px;
  border-radius: 18px;
  overflow: hidden;
  background: #1c1c21;
  box-shadow: 0 24px 60px -18px rgba(0,0,0,.9), 0 2px 10px rgba(0,0,0,.5);
}
.hero-art img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0; transition: opacity .35s ease;
}
.hero-art img.in { opacity: 1; }

.detail-title {
  margin: 0;
  font-size: 25px; font-weight: 700; letter-spacing: -.024em; line-height: 1.15;
}
.detail-artist {
  margin: 7px 0 0;
  font-size: 16px; color: var(--text-2); letter-spacing: -.008em;
}

.detail-state {
  margin: 0 0 10px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--accent);
}
.detail-state.played { color: var(--text-3); }

.detail-record {
  margin: 10px 0 0;
  font-size: 13px; color: var(--text-3); letter-spacing: -.003em;
}

.stat-row {
  display: flex; align-items: flex-start; justify-content: center;
  gap: 14px;
  margin: 20px 0 16px;
}
.stat-cell { flex: 1; max-width: 160px; }
.bpm-num, .key-big {
  font-size: 62px; font-weight: 700;
  letter-spacing: -.045em; line-height: .95;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.key-big.standard { color: var(--std-fg); }
.key-big.energy { color: var(--energy-fg); }
.stat-label.key-name { text-transform: none; letter-spacing: .06em; font-size: 12px; }
.stat-label {
  margin-top: 8px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .16em;
  color: var(--text-3); text-transform: uppercase;
}

.relation {
  margin: 0 auto 16px;
  display: inline-block;
  padding: 6px 12px;
  border-radius: 100px;
  background: rgba(255,255,255,.06);
  font-size: 13px; color: var(--text-2); letter-spacing: -.005em;
}
.relation.standard { background: var(--std-bg);    color: var(--std-fg); }
.relation.energy { background: var(--energy-bg); color: var(--energy-fg); }

.chips-line {
  margin: 0; font-size: 15px; color: var(--text-2); letter-spacing: -.005em;
}
.chips-line:empty { display: none; }

.energy-block {
  margin-top: 20px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  font-size: 13px; color: var(--text-3);
}
.energy-label { letter-spacing: -.005em; }
.energy-meter { display: flex; gap: 3px; }
.energy-meter i {
  width: 5px; height: 14px; border-radius: 2.5px;
  background: rgba(255,255,255,.13); display: block;
}
.energy-meter i.on { background: var(--accent); }
.energy-value { font-variant-numeric: tabular-nums; color: var(--text-2); }

.notes {
  margin: 28px auto 0;
  max-width: 34ch;
  font-size: 15.5px; line-height: 1.5;
  color: var(--text-2);
  letter-spacing: -.005em;
}

.sample-tag {
  margin: 26px 0 0;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-3);
}

.wide-btn {
  display: block; width: 100%;
  margin: 12px 0 0;
  padding: 15px;
  border-radius: var(--r-md);
  background: var(--bg-raised);
  font-size: 16px; font-weight: 600; letter-spacing: -.01em;
  transition: opacity .14s ease, transform .14s var(--ease);
}
.wide-btn:first-of-type { margin-top: 22px; }
.wide-btn:active { opacity: .6; transform: scale(.985); }
.wide-btn.primary { background: var(--accent); color: #fff; }
.wide-btn.danger { color: #ff4f4f; }
/* Deleting a record is not something you reach for as often as playing it,
   and a full-height red slab said otherwise. Same tap target, less weight,
   and the ~60px it gives back is what lets a fully filled-in record fit. */
.text-danger {
  display: block; width: 100%;
  margin: 16px 0 0;
  padding: 10px;
  background: none;
  font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  color: #ff4f4f;
  transition: opacity .14s ease;
}
.text-danger:active { opacity: .55; }
.btn-hint {
  margin: 10px 4px 0;
  font-size: 12.5px; line-height: 1.45; color: var(--text-3);
  text-align: center;
}

/* ── Form ──────────────────────────────────────────── */

.art-picker { text-align: center; margin-bottom: 28px; }

.art-drop {
  width: min(58vw, 220px);
  aspect-ratio: 1 / 1;
  border-radius: 16px;
  background: var(--bg-raised);
  display: grid; place-items: center;
  overflow: hidden;
  position: relative;
  transition: transform .16s var(--ease);
  box-shadow: inset 0 0 0 1px var(--hairline);
}
.art-drop:active { transform: scale(.97); }
.art-drop img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.art-hint {
  display: grid; justify-items: center; gap: 8px;
  font-size: 13.5px; color: var(--text-3); letter-spacing: -.005em;
}
.art-hint svg { width: 26px; height: 26px; stroke-width: 1.6; }
.art-drop.has-art .art-hint { display: none; }

.mini-btn {
  margin-top: 14px;
  font-size: 14px; color: var(--text-2);
  padding: 6px 10px;
}
.mini-btn:active { opacity: .5; }

.group {
  background: var(--bg-raised);
  border-radius: var(--r-md);
  overflow: hidden;
  margin-bottom: 18px;
}

.field {
  display: flex; align-items: center; gap: 12px;
  min-height: 50px;
  padding: 0 15px;
  position: relative;
  width: 100%;
  text-align: left;
}
.field + .field::before {
  content: ""; position: absolute; left: 15px; right: 0; top: 0;
  height: 1px; background: var(--hairline);
}
.field .lbl {
  flex: none; width: 74px;
  font-size: 15px; color: var(--text-2); letter-spacing: -.008em;
}
.field input, .field textarea {
  flex: 1; min-width: 0;
  font-size: 17px;                 /* ≥16px: stops iOS zooming on focus */
  letter-spacing: -.012em;
  padding: 14px 0;
  background: none;
  resize: none;
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-3); }
.field-notes { align-items: flex-start; }
.field-notes .lbl { padding-top: 15px; }
.field-notes textarea { line-height: 1.4; }
.field-energy { padding-top: 13px; padding-bottom: 13px; }

.field .lbl.wide { width: auto; flex: 1; }
.field .chev { width: 16px; height: 16px; flex: none; color: var(--text-3); margin-left: 4px; }
#fKeyVal.set { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }

.format-pick { display: flex; gap: 6px; flex: 1; flex-wrap: wrap; }
.format-pick button {
  padding: 7px 11px;
  border-radius: 8px;
  background: rgba(255,255,255,.07);
  font-size: 13.5px; letter-spacing: -.005em; color: var(--text-2);
  transition: background .12s ease, color .12s ease, transform .12s var(--ease);
}
.format-pick button.on { background: #f2f2f5; color: #08080a; font-weight: 600; }
.format-pick button:active { transform: scale(.93); }
.field-format { padding-top: 11px; padding-bottom: 11px; }

.energy-pick { display: flex; gap: 6px; flex: 1; }
.energy-pick button {
  flex: 1; height: 30px;
  border-radius: 7px;
  background: rgba(255,255,255,.07);
  transition: background .12s ease, transform .12s var(--ease);
}
.energy-pick button.on { background: var(--accent); }
.energy-pick button:active { transform: scale(.9); }

.kb-spacer { height: 30vh; }

/* ── Settings ──────────────────────────────────────── */

.settings-body { padding-top: 20px; }
.stat {
  margin: 0 0 26px;
  font-size: 14px; color: var(--text-3); letter-spacing: -.005em;
}
.section-label {
  margin: 0 0 8px 15px;
  font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3);
}
.group.tappable .row-btn { transition: background .12s ease; }
.group.tappable .row-btn:active { background: #202026; }
.row-btn { justify-content: space-between; }
.row-btn .lbl { width: auto; flex: 1; color: var(--text); font-size: 16px; }
.row-btn .val { font-size: 14px; color: var(--text-3); }
.danger-row .lbl { color: #ff4f4f; }
.footnote {
  margin: 22px 4px 0;
  font-size: 12.5px; line-height: 1.5; color: var(--text-3);
}

/* ── Action sheet ──────────────────────────────────── */

.scrim {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(0,0,0,.55);
  opacity: 0; transition: opacity .3s ease;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.scrim.in { opacity: 1; }

.actionsheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 31;
  padding: 0 8px calc(var(--bottom) + 8px);
  transform: translate3d(0, 110%, 0);
  transition: transform .4s var(--ease);
}
.actionsheet.in { transform: translate3d(0,0,0); }

.as-panel, .as-cancel {
  background: #1c1c20;
  border-radius: var(--r-lg);
  overflow: hidden;
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
}
.as-panel button, .as-title {
  display: block; width: 100%;
  padding: 16px;
  font-size: 17px; letter-spacing: -.01em;
  text-align: center;
  position: relative;
}
.as-title { font-size: 13px; color: var(--text-3); padding: 14px 20px; line-height: 1.4; }
.as-panel > *:not(:first-child)::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: rgba(255,255,255,.09);
}
.as-panel button:active { background: #26262b; }
.as-panel button.sel { color: var(--accent); font-weight: 600; }
.as-panel button.destructive { color: #ff4f4f; }
/* Camelot picker */
.as-scroll { max-height: 62vh; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.key-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 10px;
}
.key-head {
  font-size: 10.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--text-3);
  text-align: center; padding: 4px 0 2px;
}
.as-panel .key-cell {
  padding: 9px 4px;
  width: auto;
  font-size: inherit;
  text-align: center;
  border-radius: 10px;
  background: rgba(255,255,255,.05);
  display: grid; gap: 1px;
  transition: background .12s ease, transform .12s var(--ease);
}
.key-cell b {
  font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.key-cell i {
  font-style: normal;
  font-size: 11px; color: var(--text-3);
}
.key-cell:active { transform: scale(.94); }
.key-cell.on { background: var(--accent); }
.key-cell.on i { color: rgba(255,255,255,.75); }
.as-scroll + button::before { display: none; }

.as-cancel {
  margin-top: 8px;
  padding: 16px;
  width: 100%;
  font-size: 17px; font-weight: 600; letter-spacing: -.01em;
}
.as-cancel:active { background: #26262b; }

/* ── Toast ─────────────────────────────────────────── */

.toast {
  position: fixed; z-index: 40;
  left: 50%; bottom: calc(var(--bottom) + 30px);
  transform: translate(-50%, 14px);
  background: rgba(38,38,44,.96);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  color: var(--text);
  padding: 11px 18px;
  border-radius: 100px;
  font-size: 14.5px; font-weight: 500; letter-spacing: -.008em;
  box-shadow: 0 10px 30px rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transition: opacity .22s ease, transform .32s var(--ease);
  max-width: calc(100vw - 40px);
  text-align: center;
}
.toast.in { opacity: 1; transform: translate(-50%, 0); }

/* ── Motion / accessibility ────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ── Listening ─────────────────────────────────────── */

.listenbar {
  display: flex; align-items: center; gap: 10px;
  margin-top: 12px;
  padding: 9px 10px 9px 12px;
  background: var(--bg-raised);
  border-radius: 14px;
}
.level { display: flex; align-items: flex-end; gap: 2px; height: 15px; flex: none; }
.level i {
  width: 3px; height: 5px;
  border-radius: 2px;
  background: rgba(255,255,255,.18);
  display: block;
  transition: height .12s ease, background .12s ease;
}
.level i.lit { background: var(--accent); }
.listen-text {
  flex: 1; min-width: 0;
  font-size: 13.5px; color: var(--text-2); letter-spacing: -.006em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.listen-stop {
  flex: none;
  font-size: 13px; font-weight: 600; color: var(--text-2);
  padding: 8px 13px;
  border-radius: 100px;
  background: rgba(255,255,255,.08);
}
.listen-stop:active { opacity: .5; }
.icon-btn.listening { background: var(--accent); color: #fff; }

.ear-tag {
  margin: 26px 0 0;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--text-3);
}
/* It looks like a status line, but it is the way in to forget or relearn
   this record, so it has to invite a tap. */
.ear-tag { cursor: pointer; }
.ear-tag::after {
  content: '';
  width: 6px; height: 6px;
  margin-left: 2px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(-45deg);
  opacity: .55;
}
.ear-tag:active { opacity: .55; }
.ear-tag.learning { color: var(--accent); }

/* The bar goes accent while Crate still needs the record playing. */
.listenbar.learning .listen-text { color: var(--accent); }

.ear-tag svg { width: 13px; height: 13px; flex: none; }

/* ── Identify sheet ────────────────────────────────── */

.identify-body { padding-top: 18px; }
.identify-hint {
  margin: 0 2px 16px;
  font-size: 13.5px; line-height: 1.5; color: var(--text-3);
}
.identify-body .searchbar { margin-top: 0; }
.identify-list { margin-top: 6px; }
.identify-list .row { padding: 8px 0; }
.identify-list .row + .row::before { left: 61px; }
.identify-list .art { width: 48px; height: 48px; }

/* ── Swipe to set now playing ──────────────────────── */

.swipe {
  position: relative;
  overflow: hidden;
  border-radius: 12px;
}
.swipe-behind {
  position: absolute; inset: 0;
  display: flex; align-items: center;
  padding-left: 16px;
  gap: 7px;
  background: var(--accent);
  color: #fff;
  font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  opacity: 0;
  pointer-events: none;
}
.swipe-behind svg { width: 15px; height: 15px; }
/* Right reveals Now playing, left reveals Favourite. Both panels sit in the
   same box, so arming has to pick one — otherwise the second one in the DOM
   paints over the first and a right swipe reads as "Favourite". */
.swipe.armed .swipe-behind { opacity: 0; }
.swipe.armed:not(.left) > .swipe-behind:not(.fav) { opacity: 1; }
.swipe.armed.left > .swipe-behind.fav { opacity: 1; }
.swipe .row {
  background: var(--bg);
  position: relative;
  padding-left: 0;
  will-change: transform;
}
.swipe.sliding .row { transition: none; }
.swipe .row { transition: transform .32s var(--ease); }

/* ── Filters row ───────────────────────────────────── */

.filters {
  display: flex; gap: 8px;
  padding-top: 12px;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  margin: 0 calc(var(--pad) * -1);
  padding-left: var(--pad);
  padding-right: var(--pad);
}
.filters::-webkit-scrollbar { display: none; }
.chip { flex: none; }
.chip.drop { display: inline-flex; align-items: center; gap: 3px; }
.chip.drop svg { width: 13px; height: 13px; margin-right: -3px; opacity: .55; }

/* ── Live tempo readout ────────────────────────────── */

.bpm-live {
  flex: none;
  display: flex; align-items: baseline; gap: 3px;
  padding: 4px 9px;
  border-radius: 8px;
  background: rgba(255,255,255,.07);
  transition: transform .14s var(--ease);
}
.bpm-live:active { transform: scale(.92); }
.bpm-live-n {
  font-size: 15px; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.bpm-live-u {
  font-size: 8.5px; font-weight: 700; letter-spacing: .1em;
  color: var(--text-3);
}
.bpm-live.steady .bpm-live-n { color: var(--std-fg); }

/* ── Tap tempo ─────────────────────────────────────── */

.tap-body { text-align: center; display: flex; flex-direction: column; }
.tap-readout { margin: 10px 0 26px; }
.tap-pad {
  width: 100%;
  aspect-ratio: 1 / 1;
  max-height: 46vh;
  border-radius: 28px;
  background: var(--bg-raised);
  display: grid; place-content: center; gap: 10px;
  transition: transform .09s var(--ease), background .09s ease;
}
.tap-pad:active { transform: scale(.97); background: var(--accent); }
.tap-pad-label {
  font-size: 32px; font-weight: 700; letter-spacing: .18em;
}
.tap-count { font-size: 13px; color: var(--text-3); letter-spacing: -.005em; }
.tap-pad:active .tap-count { color: rgba(255,255,255,.8); }

/* ── Tag picker ────────────────────────────────────── */

.picker-add {
  display: flex; gap: 8px; align-items: center;
  padding: 10px;
}
.picker-add input {
  flex: 1; min-width: 0;
  font-size: 16px;
  background: rgba(255,255,255,.07);
  border-radius: 9px;
  padding: 9px 11px;
}
.picker-add button {
  flex: none;
  font-size: 14px; font-weight: 600; color: var(--accent);
  padding: 9px 12px;
}
.as-panel .pick-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  text-align: left;
  padding: 14px 16px;
  width: 100%;
  font-size: 16px;
}
.as-panel .pick-row .tick { width: 17px; height: 17px; flex: none; color: var(--accent); opacity: 0; }
.as-panel .pick-row.on .tick { opacity: 1; }
.as-panel .pick-row.on { font-weight: 600; }

/* ── Favourites ────────────────────────────────────── */

.sortrow { display: flex; align-items: center; gap: 10px; }
.sortrow .countbar { padding: 12px 0 10px; }
.sortrow .sortbar { flex: 1; min-width: 0; padding-left: 0; }

.star-toggle {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  color: var(--text-3);
  transition: transform .16s var(--ease), color .16s ease;
}
.star-toggle svg { width: 19px; height: 19px; stroke-width: 1.6; }
.star-toggle:active { transform: scale(.85); }
.star-toggle.on { color: var(--text); }
.star-toggle.on svg { fill: currentColor; }
.star-toggle.inline { width: 26px; height: 26px; margin-right: -4px; }

.row .star {
  display: none;
  width: 11px; height: 11px;
  margin-right: 5px;
  vertical-align: -1px;
  color: var(--text);
  fill: currentColor;
  stroke-width: 1.4;
}
.row.fav .star { display: inline-block; }

.detail-fav {
  margin: 0 0 10px;
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--text-2);
}
.detail-fav .star { width: 12px; height: 12px; fill: currentColor; stroke-width: 1.4; }

/* ── Unverified values ─────────────────────────────── */

.unsure {
  font-size: .58em;
  font-weight: 700;
  color: var(--text-3);
  vertical-align: super;
  margin-left: 1px;
  letter-spacing: 0;
}

/* ── The now-playing key pill is the harmonic toggle ── */

.np-main {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 11px;
  text-align: left;
  transition: opacity .14s ease;
}
.np-main:active { opacity: .6; }
.np-stat { align-items: flex-end; }
#npKey {
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.10);
  transition: transform .14s var(--ease), background .14s ease, color .14s ease;
}
#npKey:active { transform: scale(.9); }
#npKey.on {
  background: var(--std-bg);
  color: var(--std-fg);
  box-shadow: inset 0 0 0 1px var(--std-fg);
}

/* swipe left to favourite */
.swipe-behind.fav {
  justify-content: flex-end;
  padding-left: 0; padding-right: 16px;
  background: #2a2a31;
  color: var(--text);
}
.swipe-behind.fav svg { fill: currentColor; stroke-width: 1.4; }


/* ── Album view ─────────────────────────────────────
   A card per record. Same sleeve, same tempo column and same left-to-right
   reading order as a track row, so switching views doesn't move your eye. */
.countbar {
  color: var(--text-2);
  font-size: 13.5px;
  letter-spacing: -.005em;
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--text-3) 55%, transparent);
  text-underline-offset: 3px;
}
.countbar:active { opacity: .55; }
.sortrow > .dot { color: var(--text-3); margin: 0 -4px; font-size: 13px; }

.album {
  border-radius: 12px;
  background: var(--bg-raised);
  margin-bottom: 8px;
  overflow: hidden;
}
.album.played .album-head .art,
.album.played .album-head .meta,
.album.played .album-head .bpm { opacity: .38; }
.album.on-deck { box-shadow: inset 0 0 0 1.5px var(--accent); }

.album-head {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
}
.album-head:active { opacity: .6; }
.album-head .art {
  width: 52px; height: 52px; flex: none;
  border-radius: 8px; overflow: hidden; background: #1c1c21;
}
.album-head .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.album-head .bpm { padding-left: 6px; }
 /* A range is twice the width of a single number, so it takes the smaller
    size to leave the artist and track count room to breathe. */
.album-head .bpm .n { font-size: 15px; letter-spacing: -.01em; }

/* The tracks sit inside the card, indented under their sleeve. */
.album-tracks {
  padding: 0 12px 6px 12px;
  border-top: 1px solid rgba(255,255,255,.06);
}
.album-tracks .row { padding-left: 0; padding-right: 0; gap: 0; }
.album-tracks .meta .a { font-size: 12px; color: var(--text-3); letter-spacing: .04em; }
.album-tracks .swipe:first-child .row::before { display: none; }


/* Short screens: take it out of the gaps, never out of the figures. */
.sheet-body.detail-body { padding-bottom: calc(var(--bottom) + 16px); }
@media (max-height: 800px) {
  .sheet-body.detail-body { padding-top: 14px; }
  .hero-art { margin-bottom: 12px; }
  .detail-title { font-size: 23px; }
  .detail-artist { margin-top: 5px; }
  .detail-record { margin-top: 6px; }
  .stat-row { margin: 14px 0 12px; }
  .bpm-num, .key-big { font-size: 56px; }
  .stat-label { margin-top: 5px; }
  .chips-line { margin-top: 8px; }
  /* The optional lines — key relation, crates, energy, notes, the ear tag —
     stack up on a fully filled-in record. Their gaps are what gives. */
  .relation { margin-bottom: 9px; }
  .energy-block { margin-top: 11px; }
  .notes { margin-top: 14px; }
  .ear-tag { margin-top: 14px; }
  .sample-tag { margin-top: 12px; }
  .wide-btn { margin-top: 9px; padding: 14px; }
  .wide-btn:first-of-type { margin-top: 16px; }
  .text-danger { margin-top: 11px; padding: 9px; }
}

/* Smallest phones (SE-sized), where a record carrying every optional line —
   now-playing state, key relation, energy, notes, ear tag, crates — still
   has to land inside one screen. Only the artwork and gaps give; the BPM
   and key figures stay the size they are everywhere else. */
@media (max-height: 700px) {
  .hero-art { height: clamp(104px, 24dvh, 300px); min-height: 104px; margin-bottom: 10px; }
  .sheet-body.detail-body { padding-top: 10px; }
  .stat-row { margin: 11px 0 10px; }
  .relation { margin-bottom: 7px; }
  .notes, .energy-block, .ear-tag, .sample-tag { margin-top: 9px; }
  .wide-btn { margin-top: 7px; padding: 13px; }
  .wide-btn:first-of-type { margin-top: 12px; }
  .text-danger { margin-top: 8px; padding: 8px; }
}

/* ── Record editor ───────────────────────────────────────
   The same sheet as the track form, with the per-track rows hidden. */
#sheetForm [data-scope="record"] { display: none; }
#sheetForm.record-mode [data-scope="track"] { display: none; }
#sheetForm.record-mode [data-scope="record"] { display: block; }
#sheetForm.record-mode .form-body > .group:first-of-type { margin-top: 18px; }

.album-edit {
  display: block;
  margin: 6px 0 2px auto;
  padding: 8px 2px;
  background: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
}
.album-edit:active { opacity: .5; }

/* ── Side badge ─────────────────────────────────────────
   Where to drop the needle, at the front of the title line. Outlined so it
   reads as a different thing from the filled key pill; fixed minimum width
   so the sides line up as a column down the list. */
.side {
  display: inline-block;
  min-width: 34px;
  margin-right: 8px;
  padding: 2px 6px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.55);
  color: var(--text);
  font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
  text-align: center;
  vertical-align: 2px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* ── Add record ────────────────────────────────────── */

.add-body { padding-top: 18px; }
.add-body .searchbar { margin-top: 0; }
.add-body .searchbar input {
  flex: 1; min-width: 0; height: 100%;
  background: none; font-size: 16px; letter-spacing: -.01em;
}
.wide-btn.snap-btn {
  margin-top: 12px;
  display: flex; align-items: center; justify-content: center; gap: 9px;
}
.snap-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.add-status {
  margin: 16px 2px 4px;
  font-size: 13.5px; line-height: 1.5; color: var(--text-3);
  min-height: 1.5em;
}
.add-status.busy { color: var(--text-2); }
.add-status.busy::after {
  content: ""; display: inline-block; width: 10px; height: 10px; margin-left: 8px;
  border: 1.6px solid var(--text-3); border-top-color: transparent; border-radius: 50%;
  vertical-align: -1px; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.add-results .row { padding: 8px 0; }
.add-results .row + .row::before { left: 61px; }
.add-results .art { width: 48px; height: 48px; }
.add-results .meta .t { font-size: 15.5px; }
.add-results .meta .a { font-size: 13px; }
.add-results .meta .a.c { color: var(--text-3); font-size: 12.5px; margin-top: 1px; }
.txt-link {
  display: block; margin: 22px auto 0; padding: 8px 10px;
  font-size: 14.5px; color: var(--text-2);
}
.txt-link:active { opacity: .5; }

.review-body { padding-top: 22px; }
.review-body .art-picker { margin-bottom: 18px; }
.review-meta { margin: 12px 0 0; font-size: 13px; color: var(--text-3); letter-spacing: -.005em; }
.review-warn {
  margin: 0 0 16px; padding: 10px 14px;
  border-radius: var(--r-sm);
  background: var(--energy-bg); color: var(--energy-fg);
  font-size: 13.5px; line-height: 1.45;
}
.review-tracks-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 6px;
}
.review-tracks-head .section-label { margin-bottom: 0; }
.review-tracks-head .mini-btn { margin-top: 0; color: var(--accent); font-weight: 600; }
.review-tracks-head .mini-btn:disabled { color: var(--text-3); }
.review-tracks { margin-top: 8px; }

.rtrack {
  display: flex; align-items: center; gap: 10px;
  min-height: 52px; padding: 0 12px 0 6px;
  position: relative;
}
.rtrack + .rtrack::before {
  content: ""; position: absolute; left: 46px; right: 0; top: 0;
  height: 1px; background: var(--hairline);
}
.rtick {
  width: 32px; height: 32px; flex: none;
  display: grid; place-items: center;
}
.rtick .tick {
  width: 20px; height: 20px; padding: 3px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--text-3);
  fill: none; stroke: transparent; stroke-width: 2.4;
}
.rtick.on .tick { background: var(--accent); box-shadow: none; stroke: #fff; }
.rmain { flex: 1; min-width: 0; padding: 8px 0; }
.rt, .ra { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rt { font-size: 15px; font-weight: 600; letter-spacing: -.012em; }
.rt .side { min-width: 30px; font-size: 11.5px; padding: 1px 5px; margin-right: 7px; }
.ra { margin-top: 2px; font-size: 12.5px; color: var(--text-2); }
.rkey { flex: none; font-size: 12.5px; font-weight: 600; color: var(--text-2); font-variant-numeric: tabular-nums; }
.rkey:empty { display: none; }
.rbpm {
  flex: none; width: 62px;
  padding: 7px 8px;
  border-radius: 8px;
  background: var(--bg-field);
  font-size: 16px; font-weight: 600; text-align: center;
  font-variant-numeric: tabular-nums;
}
.rbpm::placeholder { color: var(--text-3); font-weight: 400; font-size: 14px; }
.rtrack.off .rmain, .rtrack.off .rbpm, .rtrack.off .rkey { opacity: .35; }
.wide-btn:disabled { opacity: .4; }
.txt-btn:disabled { opacity: .35; }
.review-body .art-drop { margin: 0 auto; width: min(52vw, 200px); }

/* The record that's on, in track view too. The row paints its own
   background (it slides over the swipe panels), which hid an inset shadow
   on the wrapper — so the outline is drawn on a layer above it instead. */
.swipe.on-deck .row { padding-left: 8px; padding-right: 10px; }
.swipe.on-deck::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  border-radius: 12px; pointer-events: none;
  box-shadow: inset 0 0 0 1.5px var(--accent);
}
.swipe.on-deck + .swipe .row::before, .swipe.on-deck .row::before { display: none; }

/* Hold for the menu: no iOS text selection or link callout in the way. */
.swipe .row { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.swipe .row.held { background: #17171b; }

/* ── Tab bar and pages ─────────────────────────────── */

:root { --tabh: calc(56px + var(--bottom)); }
.app { padding-bottom: var(--tabh); }

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  height: var(--tabh);
  padding: 6px 6px var(--bottom);
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: rgba(12,12,15,.94);
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
  border-top: 1px solid var(--hairline);
  z-index: 15;
}
.tab {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 3px; padding-top: 3px;
  color: var(--text-3);
  font-size: 10.5px; font-weight: 600; letter-spacing: .01em;
  transition: color .12s ease;
}
.tab svg { width: 25px; height: 25px; stroke-width: 1.7; }
.tab.on { color: var(--text); }
.tab.on svg { color: var(--accent); }
.tab:active { opacity: .6; }
.tab-badge {
  position: absolute; top: 0; left: calc(50% + 7px);
  min-width: 17px; height: 17px; padding: 0 5px;
  border-radius: 9px; background: var(--accent); color: #fff;
  font-size: 10.5px; font-style: normal; font-weight: 700; line-height: 17px; text-align: center;
}

.page {
  position: fixed; left: 0; right: 0; top: 0; bottom: var(--tabh);
  display: flex; flex-direction: column;
  background: var(--bg);
  z-index: 5;
}
.page-head {
  flex: none;
  padding: calc(var(--top) + 10px) var(--pad) 8px;
}
.page-head h1 { line-height: 40px; }
.page-body {
  flex: 1; overflow-y: auto;
  -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain;
  padding: 10px var(--pad) 40px;
}
.footnote.version { margin-top: 10px; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; }

/* ── Teach bar (under the listen bar) ──────────────── */

.teachbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 8px;
}
.teach-q { font-size: 12.5px; color: var(--text-3); }
.teach-chip {
  max-width: 100%;
  padding: 7px 12px;
  border-radius: 100px;
  background: rgba(255,59,92,.14); color: var(--accent);
  font-size: 13px; font-weight: 600; letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.teach-chip.next { background: rgba(255,255,255,.08); color: var(--text); }
.teach-chip:active { opacity: .6; }

/* ── Detail actions ────────────────────────────────── */

.detail-actions { display: flex; gap: 10px; margin-top: 22px; }
.detail-actions .wide-btn { margin: 0; }
.detail-actions .primary { flex: 1; }
.detail-actions .queue-btn { flex: none; width: 104px; }
.detail-actions .queue-btn.on { color: var(--accent); }
.preview-tag { display: flex; margin-top: 10px; }

/* ── Queue ─────────────────────────────────────────── */

.queue-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 18px;
}
.queue-head .section-label { margin-bottom: 0; }
.queue-head .mini-btn { margin-top: 0; }
.queue-head #endSetBtn { color: var(--accent); font-weight: 600; }
.queue-list { margin-top: 6px; }
.queue-empty { margin: 8px 2px 0; font-size: 13.5px; line-height: 1.5; color: var(--text-3); }
.qrow {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; position: relative;
  background: var(--bg);
  touch-action: pan-y;
}
.qrow + .qrow::before {
  content: ""; position: absolute; left: 62px; right: 0; top: 0;
  height: 1px; background: var(--hairline);
}
.qrow .art { width: 50px; height: 50px; }
.qrow .meta { flex: 1; min-width: 0; }
.qrow .meta .t { font-size: 15.5px; }
.qrow .meta .a { font-size: 13px; }
.qrow .bpm .n { font-size: 18px; }
.qrow .num { width: 16px; flex: none; font-size: 12px; color: var(--text-3); text-align: right; font-variant-numeric: tabular-nums; }
.qbtn {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center; color: var(--text-3);
  border-radius: 50%;
}
.qbtn svg { width: 18px; height: 18px; }
.qbtn:active { background: rgba(255,255,255,.08); }
.qbtn.play { color: var(--accent); }
.qhandle { cursor: grab; touch-action: none; }
.qrow.dragging { z-index: 3; box-shadow: 0 8px 24px rgba(0,0,0,.6); border-radius: 12px; opacity: .96; }
.played-list .qrow { opacity: .6; }
.queue-now { margin-top: 4px; }
.queue-now .qrow { padding: 10px 12px; border-radius: 14px; box-shadow: inset 0 0 0 1.5px var(--accent); }
.queue-now .eyebrow { display: block; font-size: 10.5px; font-weight: 700; letter-spacing: .14em; color: var(--accent); text-transform: uppercase; margin-bottom: 2px; }

/* ── Listen page ───────────────────────────────────── */

.listen-body { display: flex; flex-direction: column; }
.seg {
  display: grid; grid-template-columns: 1fr 1fr;
  padding: 3px; border-radius: 11px; background: var(--bg-raised);
}
.seg button {
  padding: 8px; border-radius: 8px;
  font-size: 14px; font-weight: 600; color: var(--text-2);
  transition: background .15s ease, color .15s ease;
}
.seg button.on { background: #f2f2f5; color: #08080a; }
.tempo-dial {
  margin: 18px 0 0;
  min-height: min(44vh, 330px);
  border-radius: 26px;
  background: var(--bg-raised);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  transition: transform .1s var(--ease), background .12s ease;
  user-select: none; -webkit-user-select: none;
}
.bpm-num.huge { font-size: clamp(84px, 27vw, 128px); }
.tempo-dial .stat-label { margin-top: 2px; }
.tempo-dial .tap-count { margin-top: 18px; font-size: 13.5px; color: var(--text-3); }
.tempo-dial.steady .bpm-num { color: var(--std-fg); }
.tempo-dial.tap { background: #1d1d22; }
.tempo-dial.tap:active { transform: scale(.985); background: var(--accent); }
.tempo-dial.tap:active .tap-count, .tempo-dial.tap:active .stat-label { color: rgba(255,255,255,.85); }
.listen-actions { display: flex; gap: 10px; }
.listen-actions .wide-btn { flex: 1; margin-top: 14px; }
.listen-actions .wide-btn.stop { background: var(--bg-raised); color: var(--text); }
.lp-toggles { margin-top: 18px; margin-bottom: 0; }
.lp-heard {
  margin-top: 14px; padding: 10px 12px;
  border-radius: 14px; background: var(--bg-raised);
}
.lp-heard .row { padding: 0; }
.lp-heard .lp-line { display: block; font-size: 12.5px; color: var(--text-3); margin-top: 6px; }
.lp-heard .teachbar { margin-top: 10px; }

/* ── Add page ──────────────────────────────────────── */

.add-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 6px; }
.add-tile {
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  gap: 6px; padding: 16px 14px 16px;
  min-height: 150px;
  border-radius: 18px; background: var(--bg-raised);
  box-shadow: inset 0 0 0 1px var(--hairline);
  transition: transform .14s var(--ease), background .12s ease;
}
.add-tile:active { transform: scale(.97); background: #1d1d22; }
.add-tile svg { width: 30px; height: 30px; color: var(--accent); stroke-width: 1.6; margin-bottom: auto; }
.tile-t { font-size: 16.5px; font-weight: 700; letter-spacing: -.015em; margin-top: 18px; }
.tile-s { font-size: 12.5px; line-height: 1.35; color: var(--text-3); }

/* ── Import ────────────────────────────────────────── */

.import-body { padding-top: 16px; }
.import-tools { display: flex; justify-content: space-between; }
.import-tools .mini-btn { margin-top: 0; }
.import-list .row { gap: 11px; }
.import-list .rtick { margin-left: -4px; }
.import-list .row.have .meta, .import-list .row.have .art { opacity: .45; }
.import-list .have-tag { font-size: 11px; font-weight: 700; letter-spacing: .08em; color: var(--text-3); text-transform: uppercase; flex: none; }
.import-progress { margin-top: 20px; }
.import-progress .bar { height: 6px; border-radius: 3px; background: var(--bg-raised); overflow: hidden; }
.import-progress .bar i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .3s ease; }
.toast { bottom: calc(var(--tabh) + 14px); max-width: calc(100vw - 40px); text-align: center; }
.footnote + .section-label { margin-top: 26px; }
.tempo-dial.empty .bpm-num { color: var(--text-3); }
.qrow { gap: 8px; }
.qrow .qbtn { width: 30px; height: 30px; }
.qrow + .qrow::before { left: 58px; }
