/* runTIME — dark athletic theme */
:root {
  --bg: #0b0e14;
  --panel: #121826;
  --panel-2: #182033;
  --line: #232d42;
  --text: #e8ecf5;
  --muted: #8a94ab;
  --accent: #ff6a2b;        /* start-gun orange */
  --accent-soft: #ff6a2b33;
  --run: #2dd4a7;           /* interval run */
  --walk: #ffd166;          /* interval walk */
  --marker: #4cc9f0;        /* distance markers */
  --hit: #2dd4a7;
  --near: #ffd166;
  --off: #4a5568;
  --radius: 10px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ------------------------------------------------------------- top bar */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 8px 18px 8px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #131a2a, #0f1523);
  position: relative;
  z-index: 40;
}
.btn-menu, .settings-close, .lib-collapse, .btn-search-mobile { display: none; }
.btn.settings-close {
  width: 100%;
  text-align: right;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 700;
  color: var(--accent);
  border-color: var(--accent);
}
.btn.settings-close:hover { background: var(--accent); color: #fff; }
/* tempo/BPM hidden until BPM can be auto-derived on add (Apple has no BPM API) */
#card-tempo, .bpm-chip { display: none; }

/* iTunes-esque center deck */
.deck {
  flex: 1; max-width: 620px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 4px;
  position: relative;
  min-width: 0;
}
.deck-info { display: flex; flex-direction: column; align-items: center; min-width: 0; }
#np-title {
  font-weight: 600; font-size: 13px; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#np-sub {
  font-size: 11px; color: var(--muted); max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.deck-controls { display: flex; align-items: center; justify-content: center; gap: 10px; }
.deck-btn { border: none; background: none; color: var(--muted); padding: 4px; display: flex; }
.deck-btn:hover { color: var(--text); }
.deck-btn svg { width: 13px; height: 13px; }
.btn-play-main svg { width: 14px; height: 14px; display: block; margin: 0 auto; }

/* scrub row — top of the playlist zone */
.scrub-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: baseline; gap: 6px; font-size: 24px; font-weight: 700; }
.brand-run { color: var(--text); letter-spacing: -0.5px; }
.brand-time {
  color: var(--accent);
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  letter-spacing: 1px;
}
.tagline { font-size: 12px; color: var(--muted); font-weight: 400; }
.topbar-actions { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.music-status { font-size: 12px; color: var(--run); }
.music-status.demo { color: var(--muted); }

/* -------------------------------------------------------------- layout */
.layout {
  flex: 1;
  display: grid;
  grid-template-columns: 288px 1fr 300px;
  gap: 14px;
  padding: 14px;
  min-height: 0;
}
.panel { display: flex; flex-direction: column; gap: 12px; overflow-y: auto; min-height: 0; }

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
}
.card.grow { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.card h2 { font-size: 13px; text-transform: uppercase; letter-spacing: 1px; color: var(--muted); margin-bottom: 10px; }
.h-toggle { cursor: pointer; display: flex; align-items: center; gap: 7px; }
.h-toggle input { accent-color: var(--accent); }

.field-row { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.field-row label { width: 82px; flex-shrink: 0; color: var(--muted); font-size: 12px; }
input[type="text"], input[type="number"], input[type="search"], select {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  padding: 6px 8px;
  font: inherit;
  width: 100%;
  min-width: 0;
}
input:focus, select:focus { outline: 1px solid var(--accent); border-color: var(--accent); }
input.tiny { width: 58px; text-align: center; }
.ratio-colon { color: var(--muted); font-weight: 700; }
.unit-suffix { color: var(--muted); font-size: 12px; }
input[type="range"] { width: 100%; accent-color: var(--accent); }

.seg { display: flex; background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
.seg button {
  background: none; border: none; color: var(--muted);
  padding: 5px 14px; cursor: pointer; font: inherit; font-size: 12px;
}
.seg button.active { background: var(--accent); color: #fff; font-weight: 600; }

.derived { font-size: 12px; color: var(--marker); margin-top: 2px; }
.slider-val {
  flex-shrink: 0; min-width: 52px; text-align: right;
  font-size: 12.5px; color: var(--marker); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.goal-finish { font-size: 14px; color: var(--muted); margin-top: 6px; }
.goal-finish strong { color: var(--accent); font-size: 16px; font-variant-numeric: tabular-nums; }
.hint { font-size: 11.5px; color: var(--muted); margin-top: 8px; }

.btn {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  font: inherit;
}
.btn:hover { border-color: var(--accent); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.btn-apple { background: #fa2d48; border-color: #fa2d48; color: #fff; font-weight: 600; }
.btn-apple:hover { filter: brightness(1.1); }
.btn:disabled { opacity: 0.6; cursor: default; }

/* --------------------------------------------------------------- stats */
.stats dl { display: flex; flex-direction: column; gap: 6px; }
.stats dl > div { display: flex; justify-content: space-between; font-size: 13px; }
.stats dt { color: var(--muted); }
.stats dd { font-variant-numeric: tabular-nums; }
.stats .good { color: var(--run); }
.stats .bad { color: var(--accent); }
.stats .warn { color: var(--walk); }

/* ------------------------------------------------------------ timeline */
.viz-wrap {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.viz-scroller { flex: 1; overflow-y: auto; padding: 0 10px; }
.viz {
  position: relative;
  display: grid;
  /* run-info rail (clock | distance | intervals), then the music */
  grid-template-columns: 48px 80px 20px 1fr;
  column-gap: 4px;
}
.col-ruler, .col-intervals, .col-markers { position: relative; }

/* ruler */
.ruler-tick {
  position: absolute; right: 0; left: 0;
  border-top: 1px solid var(--line);
}
.ruler-label {
  position: absolute; right: 4px; top: -8px;
  font-size: 10.5px; color: var(--muted);
  background: var(--panel); padding: 1px 3px;
  font-variant-numeric: tabular-nums;
}

/* intervals gutter */
.viz.no-intervals { grid-template-columns: 56px 104px 1fr; }
.viz.no-intervals .col-intervals { display: none; }
.seg-run, .seg-walk { position: absolute; left: 4px; right: 4px; border-radius: 3px; }
.seg-run {
  background: linear-gradient(180deg, #1d4a3d, #16382f);
  border: 1px solid #2dd4a744;
  display: flex; align-items: center; justify-content: center;
}
.seg-run span { font-size: 9px; color: var(--run); opacity: 0.85; }
.seg-walk { background: repeating-linear-gradient(45deg, var(--walk), var(--walk) 3px, #b98f3a 3px, #b98f3a 6px); }

.btn-play-main {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); border-color: var(--accent); color: #fff;
  line-height: 1; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.btn-play-main:hover { filter: brightness(1.12); }
.np-time { font-size: 11.5px; color: var(--marker); font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* scrub bar — whole run, one tick per song, draggable knob */
.scrub {
  position: relative; flex: 1; height: 13px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
  min-width: 120px;
  touch-action: none;
}
.scrub:hover { border-color: var(--marker); }
.scrub-fill {
  position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: linear-gradient(90deg, #1d6f8c, var(--marker));
  border-radius: 7px 0 0 7px;
  pointer-events: none;
}
.scrub-ticks { position: absolute; inset: 0; pointer-events: none; overflow: hidden ; border-radius: 7px; }
.scrub-ticks span {
  position: absolute; top: 0px; bottom: 0px; width: 1px;
  /* dark ticks read on both the empty track and the cyan fill background: #0b0e14b3;*/
  background: #e373407d;
}
.scrub-knob {
  position: absolute; top: 50%; left: 0;
  width: 13px; height: 13px; margin: -7px 0 0 -7px;
  background: #fff; border: 2px solid var(--marker); border-radius: 50%;
  box-shadow: 0 1px 5px #000a;
  cursor: grab; pointer-events: none;
  z-index: 2;
}
.scrub:active .scrub-knob { cursor: grabbing; transform: scale(1.15); }

.lib-head { display: flex; align-items: center; gap: 8px; }
.lib-head .btn-save { margin-left: auto; }
/* .btn-save is display:none pre-connect, which drops it out of flex flow
   entirely — its margin-left:auto stops pushing siblings right at that
   point. Anchor the push on Close too, so it stays pinned right regardless
   of which buttons before it are visible. */
.lib-head .lib-collapse { margin-left: auto; }
.btn-save, .btn-save-alt { flex-shrink: 0; font-size: 12px; padding: 3px 10px; }
.btn-save-alt { color: var(--muted); }
body:not(.connected) .btn-save,
body:not(.connected) .btn-save-alt { display: none; }

/* playhead — live position while playing */
.playhead {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 2px solid var(--marker);
  box-shadow: 0 0 10px #4cc9f066;
  z-index: 7; pointer-events: none;
}
.playhead-label {
  pointer-events: auto; cursor: grab; touch-action: none;
  position: absolute; right: 6px; top: -9px;
  background: var(--marker); color: #06202c;
  font-size: 10.5px; font-weight: 700;
  border-radius: 8px; padding: 1px 8px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* song blocks */
.col-blocks { display: flex; flex-direction: column; min-width: 0; }
.block {
  position: relative;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 0 10px;
  background: linear-gradient(180deg, var(--panel-2), #141b2c);
  border: 1px solid var(--line);
  border-top: none;
  border-left: 3px solid var(--off);
  overflow: hidden;
  cursor: grab;
  min-height: 7px;
  user-select: none;
}
.col-blocks .block:first-child { border-top: 1px solid var(--line); border-radius: 6px 6px 0 0; }
.block:hover { background: linear-gradient(180deg, #1e2740, #171f33); z-index: 2; }
.block.match-hit { border-left-color: var(--hit); }
.block.match-near { border-left-color: var(--near); }
.block.match-off { border-left-color: var(--off); }
.block.match-unknown { border-left-color: #2c3650; }
.block.finish-song { box-shadow: inset 0 0 0 1px var(--accent); }
.block.sortable-ghost { opacity: 0.35; }
.block.sortable-chosen { cursor: grabbing; }

.block-main { display: flex; flex-direction: column; min-width: 0; }
.block-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.block-artist { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.block-side { display: flex; align-items: center; gap: 7px; flex-shrink: 0; }
.block-dur { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.finish-badge { font-size: 14px; }

.bpm-chip {
  background: none; border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font-size: 11px; padding: 1px 7px; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.bpm-chip small { color: var(--muted); margin-left: 2px; font-size: 9px; }
.match-hit .bpm-chip { border-color: var(--hit); color: var(--hit); }
.match-near .bpm-chip { border-color: var(--near); color: var(--near); }
.bpm-chip:hover { border-color: var(--accent); }

.block-remove {
  background: none; border: none; color: var(--muted); font-size: 15px;
  cursor: pointer; padding: 0 2px; line-height: 1;
}
.block-remove:hover { color: var(--accent); }

.block-play {
  background: none; border: none; color: var(--marker); font-size: 12px;
  cursor: pointer; padding: 0 2px; line-height: 1;
  display: none;
}
body.connected .block:hover .block-play { display: inline; }
.block-play:hover { color: var(--accent); }

/* size tiers */
.block.compact { padding: 0 8px; }
.block.compact .block-title { font-size: 12px; }
.block.compact .block-artist { display: none; }
.block.micro { padding: 0 8px; }
.block.micro .block-main { flex-direction: row; gap: 6px; align-items: center; }
.block.micro .block-title { font-size: 10.5px; font-weight: 500; }
.block.micro .block-artist { display: none; }
.block.micro .block-dur, .block.micro .bpm-chip { font-size: 9.5px; }
.block.micro .bpm-chip { padding: 0 5px; }

/* silence zone */
.silence {
  display: flex; align-items: center; justify-content: center; text-align: center;
  border: 1px dashed var(--line); border-top: none; border-radius: 0 0 6px 6px;
  background: repeating-linear-gradient(45deg, transparent, transparent 8px, #ffffff05 8px, #ffffff05 16px);
  color: var(--muted); font-size: 12.5px;
  overflow: hidden;
}
.silence em { color: var(--accent); font-style: normal; }

/* distance markers — one readable line in the run-info rail */
.marker {
  position: absolute; left: 0; right: 0;
  display: flex; align-items: baseline; gap: 6px;
  border-top: 1px solid #4cc9f04d;
  padding: 1px 2px 0;
}
.marker-d { font-size: 12px; color: var(--marker); font-weight: 700; letter-spacing: 0.2px; }
.marker-t { font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.marker.finish { border-top: none; }
.marker.finish .marker-d { color: var(--accent); font-size: 12.5px; }
.marker.finish .marker-t { color: var(--text); }


/* finish line across everything */
.finish-line {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 2px solid var(--accent);
  box-shadow: 0 0 12px var(--accent-soft), 0 0 3px var(--accent);
  z-index: 6; pointer-events: none;
}
.finish-line::before {
  content: "";
  position: absolute; left: 0; right: 0; top: -1px; height: 6px;
  background: repeating-linear-gradient(90deg, #fff2, #fff2 6px, transparent 6px, transparent 12px);
}

/* -------------------------------------------------------------- library */
.lib-source { margin-bottom: 8px; width: 100%; }
.lib-source button { flex: 1; padding: 5px; font-size: 11.5px; }
.library .card input[type="search"] { margin-bottom: 10px; }
.library-results { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 5px; min-height: 0; }
.lib-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 7px 9px;
  cursor: grab;
}
.lib-item:hover { border-color: var(--marker); }
.lib-item.sortable-ghost { opacity: 0.4; }
.lib-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.lib-title { font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-artist { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-add {
  flex-shrink: 0;
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--run); background: none;
  color: var(--run); font-size: 17px; font-weight: 700; line-height: 1;
  cursor: pointer;
}
.lib-add:hover { background: var(--run); color: #06251c; }

.lib-preview, .lib-preview-spacer { width: 26px; height: 26px; flex-shrink: 0; }
.lib-preview {
  border-radius: 50%; border: 1px solid var(--line); background: none;
  color: var(--muted); font-size: 10px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.lib-preview:hover { border-color: var(--marker); color: var(--marker); }
.lib-preview.playing { border-color: var(--marker); color: var(--marker); background: #4cc9f01a; }

/* artwork */
.lib-art { width: 36px; height: 36px; border-radius: 5px; flex-shrink: 0; object-fit: cover; }
.lib-noart { display: inline-flex; align-items: center; justify-content: center; background: var(--panel-2); font-size: 15px; }

/* album / playlist card grid */
.lib-sect {
  font-size: 10.5px; color: var(--muted); text-transform: uppercase;
  letter-spacing: 1px; margin: 6px 0 2px 2px;
}
.lib-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
  gap: 10px; padding: 2px 0 6px;
}
.lib-card { position: relative; display: flex; flex-direction: column; gap: 3px; cursor: pointer; min-width: 0; }
.lib-edit {
  position: absolute; top: 4px; right: 4px;
  width: 22px; height: 22px; border-radius: 50%;
  background: #0b0e14cc; border: 1px solid var(--line);
  color: var(--text); font-size: 11px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.lib-edit:hover { border-color: var(--marker); color: var(--marker); }
.lib-cardart {
  width: 100%; aspect-ratio: 1; border-radius: 8px; object-fit: cover;
  border: 1px solid var(--line);
  background: var(--panel-2);
  display: flex; align-items: center; justify-content: center; font-size: 26px;
}
.lib-card:hover .lib-cardart { border-color: var(--marker); box-shadow: 0 3px 14px #0008; }
.lib-cardname {
  font-size: 11.5px; font-weight: 600; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lib-cardby { font-size: 10.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* drill-in header */
.lib-plhead {
  display: flex; align-items: center; gap: 9px;
  padding-bottom: 8px; margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--panel); z-index: 2;
}
.lib-back { padding: 2px 10px; font-size: 15px; line-height: 1.2; flex-shrink: 0; }
.lib-plmeta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.lib-plname { font-size: 12.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-plby { font-size: 10.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lib-addall { flex-shrink: 0; color: var(--run); font-size: 12px; font-weight: 700; }

/* expanded browser (desktop) */
.lib-expand { margin-left: 4px; padding: 3px 8px; font-size: 12px; }
.lib-collapse {
  margin-left: 4px; padding: 4px 11px; font-size: 12px; font-weight: 700;
  color: var(--accent); border-color: var(--accent);
}
.lib-collapse:hover { background: var(--accent); color: #fff; }
body.lib-max .layout { grid-template-columns: 288px 1fr 460px; }
#btn-save-m, #btn-save-alt-m { display: none; }

/* ---------------------------------------------------------- bpm popover */
.bpm-popover {
  position: fixed; z-index: 50;
  background: var(--panel-2);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 10px;
  width: 180px;
  box-shadow: 0 8px 24px #0009;
}
.bpm-popover-row { display: flex; gap: 6px; margin-bottom: 6px; }
.bpm-popover-row:last-child { margin-bottom: 0; }
.bpm-popover input { width: 80px; }

/* --------------------------------------------------------------- footer */
.footer {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 18px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
}
.footer a { color: var(--walk); text-decoration: none; }
.footer a:hover { text-decoration: underline; }
.coffee-wrap { display: flex; align-items: center; gap: 10px; }
.bmc-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--accent); color: #fff !important;
  border-radius: 8px; padding: 5px 14px;
  font-weight: 700; font-size: 13px;
  box-shadow: 0 2px 8px #ff6a2b44;
}
.bmc-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.bmc-btn:hover { text-decoration: none !important; filter: brightness(1.1); }
/* mobile-only copies live inside the settings/search panels since the real
   footer is hidden there; use combined selectors so display:none reliably
   beats .bmc-btn's own display:inline-flex regardless of source order */
.bmc-btn.settings-coffee, .bmc-btn.lib-coffee { display: none; }

/* ------------------------------------------------------------ responsive */
@media (max-width: 940px) {
  /* iOS Safari auto-zooms the page when a focused input's font-size is
     under 16px — that's the "funky zoom" on tapping +, not a bug in our
     layout. Match the base rule's selector specificity (attribute selectors
     beat a plain `input`) so this actually wins the cascade. */
  input[type="text"], input[type="number"], input[type="search"], select, textarea { font-size: 16px; }

  .btn-menu, .lib-collapse, .settings-close, .btn-search-mobile { display: inline-flex; }
  .tagline, .music-status { display: none; }
  .brand { font-size: 18px; }
  .topbar { gap: 10px; padding: 8px 10px; }

  /* cog (settings) + plus (search) sit together, both circular icon buttons */
  .btn-menu, .btn-search-mobile {
    width: 30px; height: 30px; padding: 0; flex-shrink: 0;
    border-radius: 50%; align-items: center; justify-content: center;
    color: var(--accent); border-color: var(--accent);
  }
  .btn-menu svg, .btn-search-mobile svg { width: 14px; height: 14px; }
  .btn-menu:hover, .btn-search-mobile:hover { background: var(--accent); color: #fff; }

  /* deck transport stays hidden until there's something to control */
  .deck-controls { display: none; }
  body.connected .deck-controls { display: flex; }
  /* the playlist zone's scrub bar already shows what's playing — the
     header's song/artist text is redundant on mobile, drop it for space */
  .deck-info { display: none; }

  /* the real footer is hidden on mobile — surface Buy Me a Coffee inside
     the settings and search panels instead */
  .bmc-btn.settings-coffee { display: inline-flex; align-self: center; margin-top: 14px; }
  #library-hint { display: none; }
  .bmc-btn.lib-coffee { display: inline-flex; align-self: center; margin-top: 10px; }

  /* Same 3-column model as desktop (settings | playlist | library), just
     paged instead of side-by-side: a horizontal strip you page between with
     the cog / + / Close buttons via native scroll-snap (panels.js#goToPanel
     calls scrollIntoView — letting the browser resolve real geometry avoids
     the vw/notch/dynamic-toolbar mismatches manual transform math gets
     wrong). Height comes from the existing `.layout{flex:1}` inside body's
     flex column — body/topbar/layout already do this sizing correctly, no
     need to re-measure it. Song blocks keep their own swipe gesture
     (touch-action:pan-y below) so it doesn't fight this native scroll. */
  .layout {
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    padding: 0;
    gap: 0;
    min-height: 0;
  }
  .layout::-webkit-scrollbar { display: none; }
  .layout > .settings, .layout > .viz-wrap, .layout > .library {
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
    min-height: 0;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  .settings, .library { padding: 12px; box-sizing: border-box; background: var(--bg); }
  .viz-wrap { border: none; border-radius: 0; }

  .viz { grid-template-columns: 48px 48px 18px 1fr; }
  .col-intervals { z-index: 0; left: -118px; }
  .col-blocks { margin-left: -24px; }
  .marker { flex-direction: column; }
  .marker-t { font-size: 9px; }
  .marker-d { font-size: 10.5px; }
  .seg-run span { font-size: 8px; }
  .ruler-label { right: 0px; }

  .lib-expand { display: none; }
  /* save lives at the bottom of the settings panel on mobile */
  .library .btn-save { display: none; }
  body.connected #btn-save-m { display: block; }
  body.connected #btn-save-alt-m:not([hidden]) { display: block; margin-top: -6px; }

  .library-results {
    padding-right: 30px; /* thumb lane so the list can be scrolled, not dragged */
    -webkit-overflow-scrolling: touch;
  }
  /* fixed 4-up grid on phone (auto-fill was landing on 3 depending on width) */
  .lib-grid { grid-template-columns: repeat(4, 1fr); gap: 7px; }
  .lib-cardname { font-size: 10px; -webkit-line-clamp: 2; }
  .lib-cardby { font-size: 9px; }
  .lib-art { width: 30px; height: 30px; }
  .footer { display: none; }

  /* song cards: title/artist two rows left, play + duration stacked right;
     swipe to remove */
  .block { touch-action: pan-y; }
  .block-remove { display: none; }
  .block.full .block-side { flex-direction: column; align-items: flex-end; gap: 2px; }
}

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 5px; }
::-webkit-scrollbar-track { background: transparent; }
