/* Typed so calc() can use them: an unregistered custom property is an opaque
 * token stream, which makes color-mix() with calc(var(--heat) * ...) fail and
 * silently fall back to the plain colour. */
@property --heat {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}
@property --impact {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}

:root {
  --bg: #07080c;
  --panel: #0d0f16;
  --panel2: #12151f;
  --line: #232838;
  --line-soft: #1a1e2b;
  --text: #e9edf6;
  --muted: #7f889d;
  --lime: #b6ff3d;
  --cyan: #4dd2ff;
  --magenta: #ff4dd2;
  --amber: #ffd45d;
  --r: 12px;
  --ctl-h: 34px;
  --label-col: 104px;
  /* Inset of the grid's content from the panel edge (border + padding), used to
     align the control row above with the grid's right edge. */
  --panel-inset: 11px;
}

* { box-sizing: border-box; }

/* Visually hidden, but present for screen readers and crawlers. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.noscript-note {
  max-width: 640px; margin: 40px auto; padding: 0 16px;
  color: var(--text); font-size: 16px; line-height: 1.6; text-align: center;
}

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(1100px 560px at 50% -14%, rgba(182, 255, 61, 0.06), transparent 62%),
    radial-gradient(900px 620px at 100% 112%, rgba(77, 210, 255, 0.045), transparent 60%),
    var(--bg);
}
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.22;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(circle at 50% 0%, #000 0%, transparent 78%);
}

.mono, .bpm, .price-amt, #bpm, .step-head, .order strong { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 18px;
  background: rgba(7, 8, 12, 0.72);
  backdrop-filter: blur(14px);
}
.brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.brand-mark {
  width: 34px; height: 34px; border-radius: 9px; flex: none;
  background: var(--lime); color: #05130a;
  display: grid; place-items: center;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.18);
}
.brand-mark svg { width: 100%; height: 100%; display: block; }
.brand-title { font-weight: 800; letter-spacing: 0.02em; font-size: 15px; }
/* "beats" wears a rainbow: a gradient clipped to the glyphs. The fallback color
   keeps the word legible if background-clip:text isn't supported. */
.brand-rainbow {
  color: var(--lime);
  background-image: linear-gradient(90deg,
    #ff4d4d 0%, #ff9f43 20%, #ffe14d 40%, #b6ff3d 55%, #4dd2ff 75%, #b06bff 100%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.eq { display: flex; align-items: flex-end; gap: 2px; height: 16px; margin-left: 4px; opacity: 0.9; }
.eq i { width: 3px; height: 4px; background: var(--lime); border-radius: 2px; }
body.playing .eq i { animation: bounce 0.6s infinite ease-in-out; }
body.playing .eq i:nth-child(2) { animation-delay: 0.1s; }
body.playing .eq i:nth-child(3) { animation-delay: 0.2s; }
body.playing .eq i:nth-child(4) { animation-delay: 0.3s; }
@keyframes bounce { 0%, 100% { height: 4px; } 50% { height: 16px; } }

.topbar-actions { display: flex; align-items: center; gap: 10px; }
.badge {
  font-size: 11px; font-weight: 800; letter-spacing: 0.12em;
  padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted);
}
.badge.pro { color: #06130a; background: var(--lime); border-color: transparent; }
.badge[role="button"] { cursor: pointer; }
.btn {
  appearance: none; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--line); background: var(--panel2);
  color: var(--text); font-size: 12px; font-weight: 700; letter-spacing: 0.03em;
  padding: 9px 14px; border-radius: 10px; cursor: pointer;
  transition: transform 0.08s ease, background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
  white-space: nowrap;
}
.btn[hidden] { display: none; }
.btn:hover { border-color: #3a4260; background: #171b27; transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn.primary { background: var(--lime); color: #06130a; border-color: transparent; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.14); }
.btn.primary:hover { background: #c4ff62; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.14), 0 8px 20px -12px rgba(182, 255, 61, 0.9); }
.btn.ghost { background: transparent; }
.btn.link { background: none; border: none; color: var(--muted); text-decoration: underline; padding: 4px; font-weight: 600; }
.btn.link:hover { color: var(--text); transform: none; }
.btn.locked { opacity: 0.5; }
.btn:disabled { opacity: 0.6; cursor: default; transform: none; }
/* Icon-only buttons: bare glyph at rest, and an outline that only appears on
   hover / focus / while toggled, so the toolbar stays quiet but stays usable. */
.btn.icon {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}
.btn.icon:hover,
.btn.icon:focus-visible {
  border-color: var(--line);
  background: rgba(255, 255, 255, 0.045);
  transform: none;
}
/* A disabled icon must not react to hover; it should read as inert. */
.btn.icon:disabled { cursor: default; opacity: 0.55; }
.btn.icon:disabled:hover { border-color: transparent; background: transparent; }
.btn.icon.active,
.btn.icon[aria-pressed="true"] {
  border-color: #3a4260;
  background: rgba(255, 255, 255, 0.08);
}
.wide-btn { width: 100%; justify-content: center; padding: 12px; font-size: 13px; }

/* ---------- settings marquee (embedded at the top of the grid) ---------- */
.seq-top {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  margin-bottom: 8px;
}
.marquee {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: stretch;
  height: var(--ctl-h);
  overflow: hidden;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: rgba(10, 12, 18, 0.6);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.marquee-viewport {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; overflow: hidden;
  padding: 0 12px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.marquee-track { display: inline-flex; white-space: nowrap; animation: marquee 22s linear infinite; will-change: transform; }
/* The status ticker only needs to move while the beat is running, so it doesn't
   keep a compositor animation alive the whole time the page is open. */
body:not(.playing) .marquee-track { animation-play-state: paused; }
.marquee-track > span { padding-right: 46px; }
.marquee-track b { font-weight: 600; color: var(--muted); }
.marquee-track b.on { color: var(--lime); }
.marquee-track i { font-style: normal; color: var(--line); padding: 0 12px; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(calc(-1 * var(--marquee-shift, 50%))); } }
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ---------- layout ---------- */
.wrap { width: 100%; max-width: none; margin: 0 auto; padding: 16px; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }

kbd {
  font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 11px;
  background: var(--panel2); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 6px; padding: 1px 6px; color: var(--text); white-space: nowrap;
}
.icon-btn { width: 36px; height: 36px; padding: 0; border-radius: 10px; font-size: 15px; font-weight: 800; line-height: 1; }
.btn-ico { width: 15px; height: 15px; flex: none; display: block; }

.help-list { list-style: none; margin: 8px 0 14px; padding: 0; display: flex; flex-direction: column; gap: 9px; font-size: 13px; color: #c6cddd; }
.help-list b { color: var(--text); }
.help-keys { display: flex; flex-wrap: wrap; gap: 10px 16px; font-size: 12px; color: var(--muted); padding: 10px 12px; background: rgba(8, 9, 14, 0.5); border: 1px solid var(--line-soft); border-radius: 10px; }

/* ---------- toolbar ---------- */
.wrap > .toolbar { display: none; }
.seq:empty { visibility: hidden; }
.toolbar {
  display: grid;
  grid-template-columns: 1.4fr 1.05fr 1.4fr 1fr;
  gap: 8px;
  margin-bottom: 10px;
}
@media (max-width: 1000px) {
  .toolbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .toolbar { grid-template-columns: 1fr; }
}
.cluster {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(18, 21, 31, 0.9), rgba(13, 15, 22, 0.9));
  border: 1px solid var(--line);
  border-radius: 12px;
}
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; align-items: end; }
.fields.cols-1 { grid-template-columns: 1fr; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* `hidden` must win over the display rule above, or the wake-lock field shows
   on desktop where the API is pointless. Same pattern as .btn[hidden]. */
.field[hidden] { display: none; }
.fields > .btn, .fields > .play-btn { width: 100%; }
.field > input[type="range"], .field > .select { width: 100%; }
.fx { min-width: 0; }
.fx input[type="range"] { width: 100%; }
.field .row-inline { width: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.field .row-inline .bpm { flex: 1 1 auto; width: auto; min-width: 0; }
.field .row-inline .btn { flex: 0 0 auto; }
.row-inline.seg .btn { flex: 1 1 0; }
.row-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* A control's label sits on the left with its live value (or input) on the
   right, so every slider reads the same way. */
.field-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.field-head .bpm { flex: none; }
.field-head .switch { align-self: center; }
/* Live value as a soft pill so it reads as data rather than as a label. */
.val {
  display: inline-flex; align-items: center; min-height: 20px; padding: 0 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--text); font-size: 11px; font-weight: 700;
  letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Collapsible section heading inside each control card. */
.cluster-title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; margin: 0; padding: 0; background: none; border: none; cursor: pointer;
  color: #c6cddd; font: inherit; font-size: 12.5px; font-weight: 700;
  letter-spacing: 0.01em; text-transform: none; text-align: left;
}
.cluster-title:hover { color: var(--text); }
.cluster-title .chev { width: 12px; height: 12px; flex: none; transition: transform 0.2s ease; }
.cluster.collapsed .cluster-title .chev { transform: rotate(-90deg); }
/* Collapse the body by animating a 1fr → 0fr grid row. */
.cluster-body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows 0.22s ease; }
.cluster-body > .fields { overflow: hidden; min-height: 0; }
.cluster.collapsed .cluster-body { grid-template-rows: 0fr; }
@media (prefers-reduced-motion: reduce) {
  .cluster-body, .cluster-title .chev { transition: none; }
}
/* Inline PRO badge so it never collides with a slider's value readout. */
/* Pro badge — one subtle gold chip used wherever a feature is Pro-only. */
.lock,
.fx.locked .fx-pro,
.preset-item.locked .preset-tag {
  display: inline-flex; align-items: center;
  font-size: 9px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  line-height: 1; padding: 2px 6px; border-radius: 999px;
  color: var(--amber);
  background: rgba(255, 212, 93, 0.13);
  border: 1px solid rgba(255, 212, 93, 0.3);
}
.fx-pro { display: none; }
/* The track-head lock sits in a flex column, so stop it stretching to the
   head's full width — it should hug its text like the other badges. */
.lock { align-self: flex-start; }

.ctl-icon {
  flex: none;
  width: var(--ctl-h);
  height: var(--ctl-h);
  padding: 0;
}
.ctl-icon svg { width: 17px; height: 17px; display: block; }
/* Open state: lime outline + glyph, no fill — the solid fill is Play's alone. */
.btn.icon.ctl-icon.active {
  color: var(--lime);
  background: rgba(182, 255, 61, 0.1);
  border-color: rgba(182, 255, 61, 0.55);
}
/* Undo lives in the grid header, beside the cells it affects. Borderless at
   rest, so the disabled state sits on the muted color rather than fading out. */
.undo-btn { flex: none; width: var(--ctl-h); height: var(--ctl-h); padding: 0; color: var(--muted); }
.undo-btn svg { width: 17px; height: 17px; display: block; }
.undo-btn:disabled { opacity: 0.65; }
.undo-btn.has-undo { color: var(--text); }
/* Play is the primary action, so it's a filled button rather than another ghost
   icon — same footprint as its neighbours now the beat row is busier. Stays lime
   when idle; shifts to a stop square in use. */
.play-btn {
  flex: none;
  width: var(--ctl-h);
  height: var(--ctl-h);
  padding: 0;
  color: #06130a;
  background: var(--lime);
  border-color: transparent;
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.14);
}
.play-btn:hover { background: #c4ff62; color: #06130a; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.14), 0 8px 20px -12px rgba(182, 255, 61, 0.9); }
.play-btn .ico { width: 18px; height: 18px; display: block; fill: currentColor; }
.play-btn .ico-stop { display: none; }
.play-btn.active { background: var(--lime); }
.play-btn.active .ico-play { display: none; }
.play-btn.active .ico-stop { display: block; }
/* A pair of friendly pulses after a beat is loaded, nudging the user to play it. */
@keyframes play-nudge {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(182, 255, 61, 0); }
  50% { transform: scale(1.13); box-shadow: 0 0 18px 2px rgba(182, 255, 61, 0.7); }
}
.play-btn.nudge { animation: play-nudge 0.8s ease-in-out 2; }
@media (prefers-reduced-motion: reduce) {
  .play-btn.nudge { animation: none; }
}

.bpm { width: 74px; padding: 0 10px; height: var(--ctl-h); text-align: center; font-size: 16px; font-weight: 700; }
.text-input, .select {
  appearance: none; background: var(--panel2); border: 1px solid var(--line); color: var(--text);
  border-radius: 10px; padding: 0 12px; height: var(--ctl-h); font-size: 13px; outline: none;
}
.select { padding-right: 30px; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.text-input:focus, .select:focus, .bpm:focus { border-color: var(--lime); box-shadow: 0 0 0 3px rgba(182, 255, 61, 0.14); }

.cluster .btn { display: inline-flex; align-items: center; justify-content: center; height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }

input[type="range"] { -webkit-appearance: none; appearance: none; width: 110px; height: var(--ctl-h); background: transparent; outline: none; cursor: pointer; margin: 0; }
input[type="range"]::-webkit-slider-runnable-track { height: 4px; border-radius: 999px; background: var(--line); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 15px; height: 15px; border-radius: 50%; background: #5c6577; margin-top: -5.5px; cursor: pointer; transition: background 0.15s ease, box-shadow 0.15s ease; }
input[type="range"]::-moz-range-track { height: 4px; border-radius: 999px; background: var(--line); }
input[type="range"]::-moz-range-thumb { width: 15px; height: 15px; border: none; border-radius: 50%; background: #5c6577; cursor: pointer; transition: background 0.15s ease, box-shadow 0.15s ease; }
input[type="range"].on::-webkit-slider-thumb { background: var(--lime); box-shadow: 0 0 12px rgba(182, 255, 61, 0.55); }
input[type="range"].on::-moz-range-thumb { background: var(--lime); box-shadow: 0 0 12px rgba(182, 255, 61, 0.55); }
/* BPM is always a live control, so its thumb stays neon rather than grey. */
#bpmSlider::-webkit-slider-thumb { background: var(--lime); box-shadow: 0 0 12px rgba(182, 255, 61, 0.55); }
#bpmSlider::-moz-range-thumb { background: var(--lime); box-shadow: 0 0 12px rgba(182, 255, 61, 0.55); }
.fx { display: flex; flex-direction: column; gap: 6px; position: relative; }
.fx.locked input[type="range"] { opacity: 0.45; }
.step-toggle { cursor: pointer; }
.step-toggle.active { border-color: var(--lime); color: var(--lime); background: rgba(182, 255, 61, 0.08); }
.step-toggle.locked { opacity: 0.55; }
/* ---------- switch ---------- */
.switch { position: relative; display: inline-flex; align-items: center; cursor: pointer; align-self: flex-start; }
.switch input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.switch-track {
  position: relative; width: 44px; height: 24px; border-radius: 999px;
  background: var(--panel2); border: 1px solid var(--line);
  transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
.switch-thumb {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #5c6577; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.18s ease;
}
.switch input:checked + .switch-track {
  background: rgba(182, 255, 61, 0.16);
  border-color: rgba(182, 255, 61, 0.5);
}
.switch input:checked + .switch-track .switch-thumb {
  transform: translateX(20px);
  background: var(--lime);
  box-shadow: 0 0 10px rgba(182, 255, 61, 0.55);
}
.switch:hover .switch-track { border-color: #3a4260; }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--lime); outline-offset: 2px; }

/* ---------- presets & beats ---------- */
/* One row: the picker flexes (and ellipsizes) and the actions stay pinned right.
   No insets: the picker lines up with the panel's outer left edge, and the play
   button sits flush with the panel/drawer right edge. */
.presets-head { display: block; margin-bottom: 8px; flex: none; }
.beat-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.actions-row { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.select-trigger {
  appearance: none; display: inline-flex; align-items: center; gap: 8px;
  background: var(--panel2); border: 1px solid var(--line); color: var(--text);
  border-radius: 10px; padding: 0 12px; height: var(--ctl-h); font-size: 13px; font-weight: 600;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
/* Fill the row but never grow past it, so a long beat name can't widen the
   layout; the label ellipsizes instead. */
button.select-trigger { flex: 1 1 auto; width: auto; min-width: 0; max-width: 100%; }
.select-trigger:hover { border-color: #3a4260; background: #171b27; }
.select-trigger > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.select-trigger .caret { flex: none; width: 7px; height: 7px; border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted); transform: rotate(45deg) translateY(-2px); }
.save-icon { width: var(--ctl-h); height: var(--ctl-h); padding: 0; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.save-icon svg { width: 17px; height: 17px; display: block; }
#clearBtn, #recordBtn, #surpriseBtn { width: var(--ctl-h); height: var(--ctl-h); padding: 0; display: inline-flex; align-items: center; justify-content: center; flex: none; }
#clearBtn svg, #surpriseBtn svg { width: 17px; height: 17px; display: block; }
#recordBtn { color: #ff5d73; }
#recordBtn svg { width: 15px; height: 15px; display: block; }
#recordBtn:hover { color: #ff8095; }
#recordBtn.recording {
  color: #ff5d73; border-color: rgba(255, 93, 115, 0.6);
  background: rgba(255, 93, 115, 0.12);
  animation: recpulse 1.1s ease-in-out infinite;
}
/* The recording red-lite is the one icon state that keeps a visible surface,
   so it reads even though the button is borderless at rest. */
.btn.icon#recordBtn.recording { background: rgba(255, 93, 115, 0.16); }
.rec-badge {
  position: fixed; top: 60px; left: 50%; transform: translateX(-50%); z-index: 210;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 13px; border-radius: 999px;
  background: rgba(24, 9, 13, 0.92); border: 1px solid rgba(255, 93, 115, 0.5);
  color: #ffd9df; font-size: 12px; font-weight: 800; letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}
.rec-badge[hidden] { display: none; }
.rec-dot { width: 8px; height: 8px; border-radius: 50%; background: #ff5d73; box-shadow: 0 0 8px #ff5d73; animation: recpulse 1.1s ease-in-out infinite; }
.rec-limit { color: var(--muted); font-weight: 700; }
@keyframes recpulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ---------- toasts ---------- */
.toast-root {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 220; display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none; width: max-content; max-width: calc(100vw - 28px);
}
.toast {
  display: flex; align-items: center; gap: 9px;
  max-width: 100%;
  padding: 9px 15px; border-radius: 999px;
  background: rgba(18, 21, 31, 0.96); border: 1px solid var(--line);
  color: var(--text); font-size: 13px; font-weight: 600; line-height: 1.35;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.5);
  opacity: 0; transform: translateY(-8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-text { min-width: 0; overflow-wrap: anywhere; }
.toast-ico { flex: none; width: 16px; height: 16px; display: block; color: var(--muted); }
.toast-ok .toast-ico { color: var(--lime); }
.toast-warn .toast-ico { color: var(--amber); }
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity 0.2s ease; transform: none; }
  .toast.show { transform: none; }
}
.beat-row .btn, .actions-row .btn { height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }
.beats-list { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.beat-item { display: flex; align-items: center; gap: 8px; }
.beat-item .beat-name { flex: 1 1 auto; min-width: 0; }
.beat-item .beat-load { flex: 1 1 auto; min-width: 0; }
.beat-item .beat-edit,
.beat-item .beat-del,
.beat-item .beat-save,
.beat-item .beat-cancel { flex: none; width: 40px; height: var(--ctl-h); padding: 0; color: var(--muted); }
.beat-item .beat-edit:hover { color: var(--text); border-color: #333b52; }
.beat-item .beat-del:hover { color: var(--magenta); border-color: var(--magenta); }
.beat-item .beat-save { color: var(--text); }
.beat-item svg { width: 17px; height: 17px; display: block; }
.beat-name-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.group-title { margin: 14px 0 8px; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.group-title .group-sub { font-size: 9px; letter-spacing: 0.08em; color: var(--line); text-transform: none; font-weight: 700; }
.preset-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  text-align: left; cursor: pointer; border: 1px solid var(--line); background: var(--panel2);
  color: var(--text); padding: 10px 12px; border-radius: 10px; font-size: 13px; font-weight: 600;
  transition: border-color 0.14s ease, background 0.14s ease;
}
.preset-item:hover { border-color: #3a4260; background: #171b27; }
.preset-item.active { border-color: var(--lime); color: var(--lime); }
.preset-item.locked { opacity: 0.7; }
.preset-tag { font-size: 10px; letter-spacing: 0.08em; color: var(--muted); font-weight: 800; }

/* ---------- info tooltips ---------- */
.lbl {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 20px; line-height: 20px; white-space: nowrap;
  font-size: 12px; letter-spacing: 0.01em; color: #9aa3b8;
  font-weight: 600; text-transform: none;
}
.info {
  appearance: none; flex: none; width: 13px; height: 13px; padding: 0;
  border-radius: 50%; border: 1px solid var(--line); background: transparent;
  color: var(--muted); font-size: 9px; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: help; transition: all 0.14s ease; font-family: inherit;
}
.info:hover, .info:focus-visible { color: #06130a; background: var(--lime); border-color: transparent; outline: none; }
h3 .info { transform: translateY(1px); }
.info, .lbl[data-tip], .switch[data-tip], .grid-corner[data-tip] { cursor: help; }

#tip {
  position: fixed; z-index: 200; max-width: 268px;
  background: #12151f; color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  padding: 9px 12px; font-size: 12px; line-height: 1.45; font-weight: 500;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.6);
  opacity: 0; transform: translateY(4px); pointer-events: none;
  transition: opacity 0.14s ease, transform 0.14s ease;
}
/* The richer tooltips (e.g. Surprise me) read as a sentence, so keep the copy
   on its natural text width instead of stretching to the max. */
#tip.multiline { max-width: 220px; text-wrap: pretty; }
#tip.show { opacity: 1; transform: translateY(0); }
#tip::after {
  content: ""; position: absolute; left: 50%; bottom: -5px; width: 9px; height: 9px;
  margin-left: -5px; background: #12151f; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  transform: rotate(45deg);
}
#tip.below::after { bottom: auto; top: -5px; border: none; border-left: 1px solid var(--line); border-top: 1px solid var(--line); }

/* ---------- guided tour ---------- */
#tour { position: fixed; inset: 0; z-index: 150; display: none; pointer-events: none; }
#tour.open { display: block; }
.tour-ring {
  position: absolute; border-radius: 14px; pointer-events: none;
  border: 2px solid var(--lime);
  box-shadow: 0 0 0 9999px rgba(3, 4, 7, 0.78), 0 0 20px rgba(182, 255, 61, 0.32);
  opacity: 0; transition: left 0.28s cubic-bezier(0.2, 0.8, 0.3, 1), top 0.28s cubic-bezier(0.2, 0.8, 0.3, 1), width 0.28s ease, height 0.28s ease, opacity 0.2s ease;
}
.tour-card {
  position: absolute; width: 310px; max-width: calc(100vw - 28px);
  background: linear-gradient(180deg, #161a26, #0e1016);
  border: 1px solid var(--line); border-radius: 16px; padding: 16px 16px 14px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.66);
  pointer-events: auto;
  opacity: 0; transition: opacity 0.2s ease, transform 0.2s ease; transform: translateY(6px);
}
.tour-card.show { opacity: 1; transform: none; }
.tour-skip { position: absolute; top: 10px; right: 12px; background: none; border: none; color: var(--muted); font-size: 11px; cursor: pointer; }
.tour-skip:hover { color: var(--text); }
.tour-step { font-size: 10px; letter-spacing: 0.14em; color: var(--lime); font-weight: 800; text-transform: uppercase; }
.tour-title { margin: 6px 0; font-size: 17px; }
.tour-text { margin: 0 0 14px; color: #c6cddd; font-size: 13px; line-height: 1.5; }
.tour-foot { display: flex; align-items: center; gap: 10px; }
.tour-dots { display: flex; gap: 5px; margin-right: auto; }
.tour-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--line); transition: background 0.2s ease; }
.tour-dots i.on { background: var(--lime); }
.tour-actions { display: flex; align-items: center; gap: 8px; }

/* ---------- sequencer ---------- */
.seq-wrap {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  display: flex;
  overflow: hidden;
}
.seq {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(9, 10, 15, 0.65);
  padding: calc(var(--panel-inset) - 1px); /* 1px goes to the border */
  display: flex;
  flex-direction: column;
}
.seq-grid {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.step-heads,
.track-row {
  display: flex;
  align-items: stretch;
  gap: 4px;
  min-width: 0;
}
.step-heads { flex: none; }
/* The scroll window sits after the fixed label column and clips the strip, so
   cells never paint over the track labels. The strip holds every step and is
   translated by --scroll; the whole grid glides together while playing. */
.head-window,
.cell-window {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}
.step-strip,
.cell-strip {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: stretch;
  gap: 4px;
  transform: translateX(calc(-1 * var(--scroll, 0px)));
}
/* In scroll mode every step keeps an equal, fixed width and the strip is sized
   to hold them all, so off-screen steps stay laid out for a uniform glide. */
.seq-grid.scrolling .step-strip,
.seq-grid.scrolling .cell-strip {
  flex: 0 0 auto;
  width: var(--strip-w, auto);
}
.seq-grid.scrolling .step-head,
.seq-grid.scrolling .cell {
  flex: 0 0 auto;
  width: var(--step-w, 40px);
}
.seq-body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
}
.playhead-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0;
  opacity: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  pointer-events: none;
  /* Position is set per step, so it never needs to move smoothly. */
  transition: opacity 0.12s ease;
  z-index: 2;
}
.playhead-line .ph-box {
  flex: 1 1 0;
  min-height: 0;
  border-radius: 5px;
  box-shadow: inset 0 0 0 1px rgba(233, 237, 246, 0.7);
}
.track-row { flex: 1 1 0; min-height: 0; }

.grid-corner {
  flex: 0 0 var(--label-col, 88px);
  font-size: 9px; letter-spacing: 0.12em; color: var(--muted); font-weight: 700;
  display: flex; align-items: flex-end; padding: 0 6px 2px;
}
.step-head {
  flex: 1 1 0; min-width: 0;
  font-size: 10px; color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  border-radius: 5px; transition: all 0.1s ease;
}
.step-head.beat { color: #aab3c8; font-weight: 700; }
.step-head.playing { color: #aab3c8; }
.step-head.hidden { display: none; }

.track-head {
  flex: 0 0 var(--label-col, 88px);
  display: flex; flex-direction: column; justify-content: center; gap: 3px;
  min-width: 0; padding: 1px 6px; border-radius: 8px;
}
.track-head .head-name { display: flex; align-items: center; gap: 4px; min-width: 0; }
.track-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--muted)); box-shadow: 0 0 8px var(--c, transparent); flex: none; }
.track-head.empty .dot { background: #2b3040; box-shadow: none; opacity: 0.6; }
.track-head .name { min-width: 0; overflow: hidden; }
.track-head .name-text { display: block; font-size: 10px; font-weight: 800; letter-spacing: 0.03em; color: #c6cddd; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.track-head .head-actions { display: flex; align-items: center; justify-content: center; gap: 10px; min-width: 0; width: 100%; }
/* Both buttons hug their content: the mute icon and the SOLO word fill the box. */
.track-head .mini { flex: none; min-width: 0; width: 26px; height: 24px; padding: 0; font-size: 11px; }
.track-head .mini svg { width: 18px; height: 18px; display: block; }
.track-head .mini[data-act="solo"] { width: auto; min-width: 0; height: 24px; padding: 0 3px; font-size: 11px; letter-spacing: 0; }
.track-head .note {
  appearance: none; -webkit-appearance: none;
  flex: none; width: auto; min-width: 0;
  background: transparent; border: none; border-radius: 5px;
  color: var(--lime); font: inherit; font-size: 12px; font-weight: 800;
  line-height: 1.2; padding: 1px 4px; text-align: center; text-align-last: center;
  cursor: pointer;
}
.track-head .note:hover { color: var(--lime); background: rgba(182, 255, 61, 0.12); }
.track-head .note:focus { outline: none; background: rgba(182, 255, 61, 0.16); }
/* The note picker only glows when the instrument actually has a step on. */
.track-head.empty .note { color: var(--muted); }
.track-head.empty .note:hover { color: var(--text); background: rgba(255, 255, 255, 0.07); }
.track-head.empty .note:focus { color: var(--text); background: rgba(255, 255, 255, 0.11); }
.track-head .lock { margin: 0; }
.track-head.muted .name, .track-head.muted .dot { opacity: 0.4; }
/* Muted rows get the same left accent as soloed ones, in the mute colour.
   The controls keep mute and solo mutually exclusive, so only one applies. */
.track-head.muted { box-shadow: inset 3px 0 0 var(--amber); }
.track-head.soloed { box-shadow: inset 3px 0 0 var(--cyan); }
.track-head.locked .head-actions { display: none; }
/* A Pro instrument on a locked row is inert, so its colour light dims to match
   the grid cells (which are dimmed the same way). */
.track-head.locked .dot { opacity: 0.42; }

.mini {
  display: inline-flex; align-items: center; justify-content: center;
  flex: none;
  width: 24px; height: 24px; border-radius: 7px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font-size: 11px; font-weight: 800;
  letter-spacing: 0; font-family: inherit; white-space: nowrap;
  cursor: pointer; touch-action: manipulation;
  transition: all 0.12s ease;
}
.mini[data-act="mute"] { color: #cbb66f; border-color: rgba(255, 212, 93, 0.26); }
.mini[data-act="solo"] { color: #86bdd6; border-color: rgba(77, 210, 255, 0.26); }
.mini:hover { color: var(--text); border-color: #333b52; background: rgba(255, 255, 255, 0.04); }
.mini:active { transform: scale(0.92); }
/* Nothing to mute or solo yet: grey the controls out and make them inert. */
.mini:disabled { opacity: 0.34; pointer-events: none; }
.mini.active { background: var(--cyan); color: #041018; border-color: transparent; }
.mini[data-act="mute"].active { background: var(--amber); color: #06130a; }
.mini[data-act="mute"]:not(.active):hover { color: var(--amber); border-color: rgba(255, 212, 93, 0.6); background: rgba(255, 212, 93, 0.08); }
.mini[data-act="solo"]:not(.active):hover { color: var(--cyan); border-color: rgba(77, 210, 255, 0.6); background: rgba(77, 210, 255, 0.08); }
.note { font-size: 10px; padding: 3px 6px; border-radius: 6px; background: var(--panel2); color: var(--text); border: 1px solid var(--line); }

.cell {
  appearance: none; border: 1px solid var(--line-soft); background: #10131c;
  border-radius: 5px; flex: 1 1 0; min-width: 0; min-height: 0; padding: 0; cursor: grab; touch-action: none;
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
  transition: background 0.08s ease, border-color 0.08s ease;
  position: relative;
  /* Impact animation drives these per frame from the audio clock. */
  --impact: 1;
  --heat: 0;
  transform: scale(var(--impact));
  transform-origin: center;
}
.cell.beat { border-left-color: #2f364b; }
.cell.hidden { display: none; }
.cell:hover { border-color: #3a4260; background: #151926; }
body.drawing, body.drawing * { cursor: grabbing !important; }
.cell.locked { opacity: 0.42; }
.cell.on {
  background: var(--c);
  border-color: var(--c);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}
.cell.accent { background: #fff; border-color: var(--c); box-shadow: inset 0 0 0 2px var(--c); }
.cell.playing { z-index: 1; }
/* The live cell lights up in layers: a tight core plus a wide, faint bloom.
   color-mix keeps each halo tied to the track's colour while the low-alpha
   stops stop bright hues (lime, pink) blooming harder than dark ones. */
.cell.playing.on {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--c) 70%, transparent),
    0 0 7px 0 color-mix(in srgb, var(--c) 62%, transparent),
    0 2px 18px 3px color-mix(in srgb, var(--c) 32%, transparent),
    inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
/* A cell that just made a sound. `--heat` decays 1 -> 0 from the moment the
 * sound was scheduled, so the cell starts white-hot and cools into its own
 * colour while the bloom fades and it settles back from the scale pop. */
.cell.impact {
  z-index: 2;
  will-change: transform;
  /* The per-frame clock ramp is the only timing here, so drop the transition
     that would otherwise smear the onset. */
  transition: none;
}
.cell.impact.on {
  background: color-mix(in srgb, #fff calc(var(--heat) * 72%), var(--c));
  border-color: color-mix(in srgb, #fff calc(var(--heat) * 45%), var(--c));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--c) 75%, transparent),
    0 0 calc(8px + var(--heat) * 12px) color-mix(in srgb, var(--c) 70%, transparent),
    0 2px calc(18px + var(--heat) * 16px) 3px color-mix(in srgb, var(--c) calc(24% + var(--heat) * 24%), transparent),
    inset 0 0 0 1px rgba(255, 255, 255, calc(0.3 + var(--heat) * 0.5));
}
.track-row.inactive .cell.on { box-shadow: none; }
.track-row.inactive .cell.playing.on { box-shadow: none; }

/* ---------- sequencer pager (small screens) ---------- */
.seq-pager {
  flex: none;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
  padding: 12px 0 4px;
}
.seq-pager[hidden] { display: none; }
.seq-dot {
  position: relative;
  width: 14px;
  height: 14px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--muted);
  background: transparent;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
/* Enlarge the tap target to ~28px without growing the visible dot. */
.seq-dot::before {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
}
.seq-dot::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  transition: background 0.15s ease;
}
.seq-dot:hover { border-color: var(--text); }
.seq-dot.active { border-color: var(--lime); box-shadow: 0 0 0 2px rgba(182, 255, 61, 0.18); }
.seq-dot.active::after { background: var(--lime); }

/* ---------- saved / footer ---------- */
/* Two fixed rows: the copyright, name and build metadata on top, the links
   centred beneath. A single wrapping line reflowed into a different ragged
   shape at nearly every width, and the app column is too narrow to seat three
   groups comfortably. */
footer {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  color: var(--muted); font-size: 12px;
  padding: 16px 22px max(24px, env(safe-area-inset-bottom));
  margin-top: auto;
}
footer .foot-id { font-weight: 700; letter-spacing: 0.02em; }
/* Secondary metadata (version, author) recedes so the name and the links are
   what the eye lands on. */
footer .by { opacity: 0.4; font-weight: 400; }
footer .ver { opacity: 0.4; font-weight: 400; font-variant-numeric: tabular-nums; }
footer .foot-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; }
footer a.foot-link { color: var(--muted); text-decoration: none; }
footer a.foot-link:hover { color: var(--text); }

/* ---------- modal ---------- */
#modal-root { position: fixed; inset: 0; z-index: 170; display: none; align-items: center; justify-content: center; padding: 18px; }
#modal-root.open { display: flex; }
/* On mobile the keyboard shrinks the visual viewport but leaves `position:
   fixed` pinned to the layout viewport, so the modal's bottom (its actions) can
   end up under the keyboard. Drive the height from the visual viewport instead,
   and shift the whole layer when the keyboard scrolls it. */
#modal-root {
  height: var(--vvh, 100dvh);
  transform: translateY(var(--vvt, 0px));
}
.modal-backdrop { position: absolute; inset: 0; background: rgba(3, 4, 7, 0.72); backdrop-filter: blur(6px); opacity: 0; transition: opacity 0.2s ease; }
#modal-root.open .modal-backdrop { opacity: 1; }
.modal {
  position: relative; z-index: 1; width: 100%; max-width: 440px; max-height: 90vh;
  max-height: calc(var(--vvh, 100dvh) - 36px);
  display: flex; flex-direction: column; overflow: hidden;
  background: linear-gradient(180deg, #141824, #0d0f16);
  border: 1px solid var(--line); border-radius: 18px; padding: 0;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  transform: translateY(14px) scale(0.98); opacity: 0; transition: all 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
#modal-root.open .modal { transform: none; opacity: 1; }
.modal.wide { max-width: 640px; }
.modal-body { padding: 22px; overflow-y: auto; min-height: 0; }
.modal h2 { margin: 0 0 10px; font-size: 20px; letter-spacing: -0.01em; }
.modal-x {
  position: absolute; top: 12px; right: 14px; z-index: 2;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  background: var(--panel); border: 1px solid var(--line-soft); border-radius: 50%;
  color: var(--muted); font-size: 18px; cursor: pointer; line-height: 1;
  transition: color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.modal-x:hover { color: var(--text); border-color: #333b52; background: var(--panel2); }
.muted { color: var(--muted); }
.fine { color: var(--muted); font-size: 11px; text-align: center; margin: 12px 0 0; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }

.price-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px; }
.price-card { border: 1px solid var(--line); border-radius: 14px; padding: 16px; position: relative; background: rgba(8, 9, 14, 0.5); }
.price-card.pro { border-color: var(--lime); box-shadow: 0 0 0 1px rgba(182, 255, 61, 0.2); }
.price-badge { position: absolute; top: -10px; right: 14px; font-size: 9px; font-weight: 800; letter-spacing: 0.1em; background: var(--lime); color: #06130a; padding: 3px 8px; border-radius: 999px; }
.price-name { font-weight: 800; letter-spacing: 0.1em; font-size: 12px; color: var(--muted); }
.price-amt { font-size: 30px; font-weight: 800; margin: 6px 0 12px; }
.price-amt span { font-size: 12px; color: var(--muted); font-weight: 600; margin-left: 4px; }
.price-card ul { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 7px; font-size: 12px; }
.price-card li { padding-left: 18px; position: relative; color: #c6cddd; }
.price-card li::before { content: "✓"; position: absolute; left: 0; color: var(--lime); font-weight: 800; }
.price-card .btn { width: 100%; justify-content: center; }
.price-card .btn.link { margin-top: 6px; }

.order { display: flex; justify-content: space-between; align-items: center; padding: 12px 14px; border: 1px dashed var(--line); border-radius: 10px; margin-bottom: 14px; }
.checkout .field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 10px; font-size: 11px; color: var(--muted); letter-spacing: 0.06em; text-transform: uppercase; font-weight: 700; }
.checkout .field .text-input { text-transform: none; letter-spacing: normal; font-weight: 400; color: var(--text); }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.share-row { display: flex; gap: 8px; margin: 8px 0; }
.share-row .text-input { flex: 1; min-width: 0; }

.confetti { position: fixed; top: -12px; width: 9px; height: 9px; border-radius: 2px; z-index: 300; animation-name: fall; animation-timing-function: linear; animation-fill-mode: forwards; }
@keyframes fall { to { transform: translateY(105vh) rotate(600deg); opacity: 0.9; } }

/* ---------- side drawer ---------- */
.app { display: flex; flex: 1 1 auto; min-height: 0; align-items: stretch; width: 100%; max-width: 1440px; margin: 0 auto; }
.drawer { position: fixed; inset: 0; z-index: 120; pointer-events: none; overflow: hidden; }
.drawer.open { pointer-events: auto; }
.drawer-backdrop { position: absolute; inset: 0; background: rgba(3, 4, 7, 0.62); backdrop-filter: blur(4px); opacity: 0; transition: opacity 0.22s ease; }
.drawer.open .drawer-backdrop { opacity: 1; }
.drawer-panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: min(380px, 92vw);
  background: linear-gradient(180deg, #141824, #0d0f16);
  border-left: 1px solid var(--line);
  box-shadow: -24px 0 60px rgba(0, 0, 0, 0.5);
  transform: translateX(105%);
  transition: transform 0.26s cubic-bezier(0.2, 0.8, 0.3, 1);
  display: flex; flex-direction: column;
  border-radius: var(--r);
  overflow: hidden;
}
.drawer.open .drawer-panel { transform: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--line-soft); font-size: 12px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.drawer-heading { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.drawer-sub { font-size: 10px; font-weight: 600; letter-spacing: 0.02em; text-transform: none; color: var(--muted); opacity: 0.8; }
.drawer-close { background: none; border: none; color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; }
.drawer-close:hover { color: var(--text); }
.drawer-body { padding: 12px; overflow-y: auto; flex: 1 1 auto; min-height: 0; scrollbar-width: thin; scrollbar-color: #2b3040 transparent; }
.drawer-body::-webkit-scrollbar { width: 8px; }
.drawer-body::-webkit-scrollbar-track { background: transparent; }
.drawer-body::-webkit-scrollbar-thumb { background: #2b3040; border-radius: 999px; }
.drawer-body::-webkit-scrollbar-thumb:hover { background: #3a4260; }
.drawer .toolbar { grid-template-columns: 1fr; margin-bottom: 0; gap: 10px; }
@media (min-width: 901px) {
  .drawer {
    position: relative; inset: auto; z-index: 1; pointer-events: auto;
    flex: 0 0 340px; width: 340px; height: 100%; overflow: hidden;
    transition: flex-basis 0.26s ease, width 0.26s ease, opacity 0.2s ease, margin-left 0.26s ease;
  }
  /* A touch of air between the grid and the drawer when it's open. */
  .drawer.open { margin-left: 10px; }
  .drawer:not(.open) { flex-basis: 0px; width: 0; pointer-events: none; opacity: 0; }
  .drawer-backdrop { display: none; }
  .drawer-panel { position: absolute; top: 0; right: 0; left: auto; bottom: auto; width: 340px; height: 100%; max-height: 100%; transform: none; box-shadow: none; }
}

:where(button, a, [role="button"]):focus-visible { outline: 2px solid var(--lime); outline-offset: 2px; }
::selection { background: rgba(182, 255, 61, 0.28); }

@media (max-width: 640px) {
  .presets-head { flex-direction: column; align-items: stretch; }
  .marquee { height: 34px; font-size: 11px; }
  .marquee-viewport { padding: 0 10px; }
  :root { --panel-inset: 9px; }
  .seq { padding: calc(var(--panel-inset) - 1px); }
  footer { padding: 10px 16px max(14px, env(safe-area-inset-bottom)); }
}
@media (max-width: 760px) {
  .wrap { padding: 14px; }
  .price-grid { grid-template-columns: 1fr; }
  .toolbar { gap: 8px; }
  .topbar { padding: 10px 14px; }
  :root { --label-col: 92px; }
}
@media (max-width: 520px) {
  :root { --label-col: 84px; }
  .track-head { padding: 1px 4px; }
  .track-head .name-text { font-size: 9px; }
  .track-head .mini { height: 22px; font-size: 10px; padding: 0; }
  .track-head .mini svg { width: 16px; height: 16px; }
  .track-head .mini[data-act="solo"] { width: auto; min-width: 0; height: 22px; padding: 0 3px; font-size: 10px; }
  .track-head .note { font-size: 11px; padding: 0 3px 1px; }
}
@media (max-width: 420px) {
  .badge { display: none; }
}
@media (pointer: coarse) {
  .step-heads, .track-row { gap: 5px; }
  :where(button, a, [role="button"], .text-input, .select) { touch-action: manipulation; }
}
