/* Noodle Pads: your own sampler. The casing is the current person's
   color, the pads sit in a dark bed tinted by it, and everything you press
   travels: a hard edge under each key that shrinks when it goes down.
   Flat fills and hard edges only (no blur, gradients or glass), so the
   Android version can copy it one to one. */

:root {
  --board: #1F3FA8;                                                /* casing, set per person by app.js */
  --board-deep: color-mix(in srgb, var(--board) 60%, black);        /* edges of casing-colored keys */
  --bed: color-mix(in srgb, var(--board) 24%, #141318);             /* the recessed pad bed */
  --bed-edge: color-mix(in srgb, var(--bed) 55%, black);
  --ink: #1C1740;
  --paper: #FFFFFF;
  --chalk: #ECEAF2;
  --chalk-edge: #A9A5BA;
  --line: #D6D3E0;
  --muted: #57527A;
  --record: #D8261F;
  --led: #FFE58A;
  --font-display: "Anybody", "Arial Narrow", system-ui, sans-serif;
  --font-ui: "Atkinson Hyperlegible Next", "Atkinson Hyperlegible", system-ui, sans-serif;
  --gutter: 16px;
  --max: 1040px;
  --toolbar-h: 76px;
  --deck: color-mix(in srgb, var(--bed) 62%, black);               /* the settings deck under a name bar */
  color-scheme: light;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  background: var(--board);
  transition: background-color 0.3s ease;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--board);
  color: #fff;
  font: 400 1rem/1.4 var(--font-ui);
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.3s ease;
}

button, input { font: inherit; color: inherit; }
/* Read by screen readers, not seen. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
button { cursor: pointer; }
:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

/* ── Header: nameplate, speaker grille, bank keys ───────────────────── */

.top {
  max-width: var(--max);
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + 18px) var(--gutter) 0;
}

.title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.title-tools { flex: none; display: flex; align-items: center; gap: 8px; }

/* Settings: small and up in the corner, away from where thumbs play. */
.settings-btn {
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: var(--bed);
  font-size: 1.3rem;
  line-height: 1;
}

h1 {
  margin: 0;
  font: 900 clamp(1.6rem, 8.4vw, 3.6rem)/1 var(--font-display);
  font-stretch: 78%;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* Speaker grille: lights up column by column with the sound level. */
.grille {
  flex: none;
  display: grid;
  grid-template-rows: repeat(3, 6px);
  grid-auto-flow: column;
  grid-auto-columns: 6px;
  gap: 4px;
  padding: 8px 9px;
  border-radius: 9px;
  background: var(--bed);
}
.grille span {
  border-radius: 50%;
  background: rgb(255 255 255 / 0.14);
  transition: background-color 60ms;
}
.grille span.lit { background: var(--led); }
/* On a phone the title, the grille, ❓ Help and ⚙️ Settings share one line:
   a slightly smaller title and a tighter grille let all four fit at 320 px.
   A very long name breaks rather than push the page sideways. */
h1 { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 420px) {
  .title-row { gap: 8px; }
  .title-tools { gap: 6px; }
  h1 { font-size: clamp(1.35rem, 7vw, 3.6rem); }
  .grille { grid-template-rows: repeat(3, 5px); grid-auto-columns: 5px; gap: 3px; padding: 7px; }
}
/* With the person's button in the corner too, the speaker grille makes room on a phone. */
@media (max-width: 420px) { .title-row:has(.people:not([hidden])) .grille { display: none; } }

/* Whose sounds: a round button in the top right corner, like an account
   picture: the person's first letter on their color. It opens a list of
   everyone, each in their color, and 👥 People. */
.people { flex: none; }
.person-menu { position: relative; }
.person-menu-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--c);
  color: #fff;
  font: 900 1.25rem/1 var(--font-display);
  box-shadow: 0 2px 0 rgb(0 0 0 / 0.35);
}
.person-menu-btn[aria-expanded="true"] { outline: 3px solid var(--led); outline-offset: 2px; }
.person-list {
  position: absolute;
  z-index: 20;
  top: calc(100% + 8px);
  right: 0;
  display: grid;
  gap: 6px;
  width: max-content;
  min-width: 200px;
  max-width: min(80vw, 320px);
  max-height: min(60dvh, 420px);
  margin: 0;
  padding: 8px;
  overflow-y: auto;
  border-radius: 14px;
  background: var(--bed);
  box-shadow: 0 10px 24px rgb(0 0 0 / 0.45);
  list-style: none;
}
.person-list[hidden] { display: none; }
.person-item {
  width: 100%;
  min-height: 48px;
  padding: 6px 14px;
  border: 0;
  border-radius: 10px;
  background: var(--c);
  color: #fff;
  font: 800 1.1rem/1 var(--font-display);
  font-stretch: 88%;
  text-align: left;
  overflow-wrap: anywhere;
}
.person-item[aria-current="true"] { outline: 3px solid #fff; outline-offset: -3px; }
.person-item[aria-current="true"]::after { content: " ✓"; }
.person-item.person-edit { margin-top: 4px; border: 2px solid rgb(255 255 255 / 0.5); background: transparent; font-family: var(--font-ui); }

/* ── Pad bed ────────────────────────────────────────────────────────── */

main {
  max-width: var(--max);
  margin: 0 auto;
  padding: 14px var(--gutter) calc(var(--toolbar-h) + env(safe-area-inset-bottom) + 24px);
}

.notice {
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--bed);
  max-width: 60ch;
}
/* Edit sounds lives on the pads screen, at the top right of the pads. */
.pads-bar { display: flex; justify-content: flex-end; }
.pads-bar[hidden] { display: none; }
/* ✏️ Edit sounds (✅ Done while editing) stays at the top as the sounds
   scroll under it, on a band of the page color as tall as the gap above a
   stuck group header (top: 60px), so no pad or ✕ badge shows between them. */
.pads-bar { position: sticky; top: 0; z-index: 7; margin: -8px 0 2px; padding: 8px 0; background: var(--board); transition: background-color 0.3s ease; }
.pads-edit {
  min-height: 44px;
  padding: 0 16px;
  border: 2px solid rgb(255 255 255 / 0.6);
  border-radius: 12px;
  background: var(--bed);   /* solid: pads scroll under it */
  color: #fff;
  font-weight: 800;
}
.pads-edit[aria-pressed="true"] { background: var(--chalk); border-color: var(--chalk); color: var(--ink); }

/* The version, small, in the bottom corner of the page. */
.version { margin: 0; text-align: right; font-size: 0.75rem; opacity: 0.8; font-variant-numeric: tabular-nums; }
/* Under the screen: its one-line how-to at the left, the version at the right. */
.page-foot { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin: 18px 0 0; }
/* The version keeps its one line; the how-to takes the rest and wraps beside it. */
.screen-hint { flex: 1 1 auto; min-width: 0; margin: 0; font-size: 0.85rem; font-weight: 700; opacity: 0.85; }
.page-foot .version { flex: none; margin-left: auto; white-space: nowrap; }
/* A how-to on two lines or more: the version stacks, date over commit, so
   the how-to gets the width. */
.page-foot.stacked { gap: 12px; }
.page-foot.stacked .version { display: flex; flex-direction: column; align-items: flex-end; }
.page-foot.stacked .ver-sep { display: none; }
.page-foot.stacked .ver-date { order: -1; }

.pads {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 12px;
  padding: 14px 12px 18px;
  border-radius: 22px;
  background: var(--bed);
  box-shadow: inset 0 4px 0 var(--bed-edge);
}
@media (min-width: 560px) { .pads { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Section headings across the pad grid: the person's own sounds, then Kit. */
.pad-section {
  grid-column: 1 / -1;
  margin: 4px 2px -6px;
  font: 800 1.05rem/1.2 var(--font-display);
  letter-spacing: 0.02em;
  color: #fff;
}
.pad-section:not(:first-child) { margin-top: 14px; }
/* A kit group's header: full width, tappable, opens or closes the group. */
.pad-group {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 14px;
  border: 0;
  border-radius: 12px;
  background: rgb(255 255 255 / 0.08);
  color: #fff;
  font: 800 1.05rem/1.2 var(--font-ui);
  text-align: left;
  /* Sticks under ✏️ Edit sounds while its pads scroll by; the next group's
     header slides over it. Solid, so pads never show through. */
  position: sticky;
  top: 60px;
  z-index: 5;
  /* The bed's color round its corners and out to the bed's edges, so no pad or badge shows beside it. */
  box-shadow: 0 0 0 4px var(--bed), 12px 0 0 var(--bed), -12px 0 0 var(--bed);
}
.pad-group { background: color-mix(in srgb, #fff 8%, var(--bed)); }
.pad-group[aria-expanded="true"] { background: color-mix(in srgb, #fff 14%, var(--bed)); }
.pad-group-caret { width: 1em; }
.pad-group-count { margin-left: auto; padding: 2px 10px; border-radius: 999px; background: rgb(255 255 255 / 0.15); font-size: 0.9rem; }
@media (min-width: 820px) {
  .pads { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 22px 18px; padding: 22px 20px 26px; }
  .pads .pad { padding: 16px 16px 16px 18px; }
  .pad .pad-label { font-size: 1.65rem; }
  .pad .pad-emoji { font-size: 2.4rem; }
  .top .grille { grid-template-rows: repeat(3, 9px); grid-auto-columns: 9px; gap: 6px; padding: 11px 12px; border-radius: 12px; }
}

/* A pad: picture top left, key number top right, legend bottom left,
   voice bottom right. */
.pad {
  --pad: #FFD60A;
  --pad-edge: color-mix(in srgb, var(--pad) 55%, black);
  position: relative;
  display: grid;
  grid-template:
    "emoji key" auto
    ".     .  " 1fr
    "label voice" auto / 1fr auto;
  column-gap: 6px;
  aspect-ratio: 1 / 0.82;
  padding: 12px 12px 12px 14px;
  border: 0;
  border-radius: 14px;
  background: var(--pad);
  color: var(--ink);
  box-shadow: 0 6px 0 var(--pad-edge);
  text-align: left;
  overflow: hidden;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  transition: transform 50ms, box-shadow 50ms;
}

/* Playback fills the pad left to right. */
.pad::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(255 255 255 / 0.45);
  transform-origin: left;
  transform: scaleX(var(--progress, 0));
  pointer-events: none;
}

.pad:not(.pad-add):active,
.pad.hit {
  transform: translateY(5px);
  box-shadow: 0 1px 0 var(--pad-edge);
}

.pad-emoji {
  grid-area: emoji;
  position: relative;
  align-self: start;
  font-size: clamp(1.6rem, 6.4vw, 2.1rem);
  line-height: 1;
}
.pad-label {
  grid-area: label;
  position: relative;
  align-self: end;
  font: 800 clamp(1rem, 4.9vw, 1.4rem)/1.02 var(--font-display);
  font-stretch: 84%;
  text-wrap: balance;
  overflow-wrap: break-word;
}
/* A pad's or key's name: a word too long for its line is hyphenated, not cut
   off; small ones (chooser, beat rows, DJ keys) take up to two lines. */
.pad-label, .dj-name { hyphens: auto; }
.pad.pad-mini .pad-label, .dj-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: break-word; white-space: normal; }
.pad-voice {
  grid-area: voice;
  position: relative;
  align-self: end;
  font-size: 1.3rem;
  line-height: 1;
  white-space: nowrap;   /* a chain of voices shows each emoji, in a row */
}
.pad-key {
  grid-area: key;
  position: relative;
  display: none;
  font: 800 0.95rem/1 var(--font-display);
}
@media (hover: hover) and (pointer: fine) { .pad-key { display: block; } }

/* Edit sounds: the corner badge (✕ delete, 🙈 hide, 👁 show), sitting on the
   pad's outside corner so it is easy to hit. */
.pad-x {
  position: absolute;
  top: -12px;
  right: -12px;
  z-index: 2;
  display: grid;
  place-items: center;
  min-width: 36px;
  height: 36px;
  padding: 0 8px;
  border: 3px solid #fff;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font: 800 1rem/1 var(--font-ui);
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.4);
  cursor: pointer;
  animation: none;
}
.pad-x::before { content: ""; position: absolute; inset: -6px; }   /* a 48px target */
.pad-x.asking { background: #D93A2B; }
body.editing .pad { position: relative; overflow: visible; }
.pad-badge {
  grid-area: key;
  position: relative;
  align-self: start;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--ink);
  color: #fff;
  font-size: 0.8rem;
  font-weight: 700;
}

/* Held down and repeating: the pad stays pressed and its edge pulses. */
.pad.looping {
  transform: translateY(5px);
  box-shadow: 0 1px 0 var(--pad-edge), 0 0 0 4px #fff;
  animation: loop-pulse 0.5s ease-in-out infinite alternate;
}
@keyframes loop-pulse { to { box-shadow: 0 1px 0 var(--pad-edge), 0 0 0 7px rgb(255 255 255 / 0.5); } }

/* The empty slot at the end of the bed. */
.pad-add {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: transparent;
  color: #fff;
  box-shadow: none;
  border: 2px dashed rgb(255 255 255 / 0.4);
  text-align: center;
}
.pad-add .pad-emoji { align-self: center; font: 400 2.6rem/1 var(--font-ui); }
.pad-add .pad-label { align-self: center; font: 700 1rem/1.2 var(--font-ui); }
.pad-add:hover { border-color: rgb(255 255 255 / 0.8); }

.pad.broken {
  --pad-edge: #8E89A3;
  background: repeating-linear-gradient(135deg, #D9D6E3 0 12px, #C9C5D6 12px 24px);
}

/* Edit mode: pads wobble so it is obvious a tap edits instead of plays. */
body.editing .pad:not(.pad-add) { animation: wobble 0.34s ease-in-out infinite alternate; }
body.editing .pad:nth-child(even):not(.pad-add) { animation-delay: -0.17s; }
body.editing .pad.hidden-clip { opacity: 0.45; }
/* Edit sounds: a kit group with every sound hidden, dimmed like its pads.
   Outside Edit sounds it has no heading at all. */
body.editing :is(.pad-group, .pad-section).all-hidden { opacity: 0.6; }
/* Tapped once in edit mode: held still and ringed, waiting for a swap. */
body.editing .pads .pad.selected {
  animation: none;
  outline: 4px solid #fff;
  outline-offset: 4px;
  scale: 1.04;
}

/* Dragging to reorder: the held pad lifts and follows the pointer. */
body.editing .pad:not(.pad-add) { cursor: grab; }
body.reordering, body.reordering .pad { cursor: grabbing; }
.pad.dragging {
  z-index: 2;
  animation: none !important;
  scale: 1.06;
  box-shadow: 0 14px 0 var(--pad-edge), 0 18px 30px rgb(0 0 0 / 0.35);
  pointer-events: none;
}
@keyframes wobble {
  from { transform: rotate(-1.2deg); }
  to { transform: rotate(1.2deg); }
}

/* ── Beat maker ─────────────────────────────────────────────────────── */

/* Same bed as the pads. Each row is a sound and its 16 pills (one bar),
   grouped four to a beat; on a phone the four beats wrap two and two. */
.seq {
  padding: 14px 12px 18px;
  border-radius: 22px;
  background: var(--bed);
  box-shadow: inset 0 4px 0 var(--bed-edge);
}

.seq-top { display: flex; align-items: center; gap: 12px; }
/* The click track as one emoji key, at the far right: lit while it ticks. */
.seq-go { display: flex; flex: none; align-items: center; gap: 8px; }
.seq-click { flex: none; width: 48px; min-height: 52px; padding: 0; border: 2px solid rgb(255 255 255 / 0.6); border-radius: 12px; background: transparent; font-size: 1.4rem; }
.seq-click[aria-pressed="true"] { background: var(--led); border-color: var(--led); }
/* On a phone or tablet, Play and the tempo stay at the top of the screen
   while the rows scroll under them; the name bar above and the bars below
   scroll away. */
@media (max-width: 899px) {
  .seq-top { position: sticky; top: 0; z-index: 6; }  /* over the playhead and a dragged row */
}
@media (max-width: 600px) {
  .seq-top .seq-play { flex: none; min-width: 0; width: 6.5rem; padding: 0 12px; }
  .seq-go { gap: 6px; }
}
/* The smallest phones: Play, ⏲️ and the number squeeze so the slider keeps room. */
@media (max-width: 400px) {
  .seq-top { gap: 8px; }
  .seq-top .seq-play { width: 4.6rem; padding: 0 6px; font-size: 1rem; }
  .seq-top .seq-click { width: 44px; font-size: 1.2rem; }
  .seq-top .seq-tempo { gap: 4px; }
  .seq-top .seq-bpm-num { font-size: 0.9rem; }
  .seq-top .seq-tempo { flex: 1 1 0; gap: 8px; }
  /* No room for the word; the slider is still named Tempo. */
  .seq-tempo-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
.seq-play {
  min-height: 52px;
  min-width: 120px;
  padding: 0 20px;
  border: 0;
  border-radius: 12px;
  background: var(--led);
  color: var(--ink);
  box-shadow: 0 5px 0 color-mix(in srgb, var(--led) 50%, black);
  font: 800 1.15rem/1 var(--font-ui);
  transition: transform 50ms, box-shadow 50ms;
}
/* Nothing to play yet (an empty song): the key goes dim and flat, so it doesn't invite a tap. */
.seq-play:disabled { opacity: 0.4; box-shadow: none; transform: translateY(4px); cursor: default; }
.seq-play:active, .seq-play[aria-pressed="true"] { transform: translateY(4px); box-shadow: 0 1px 0 color-mix(in srgb, var(--led) 50%, black); }
/* How many bars the beat is: 1, 2 or 4, as latching keys. */
.seq-barsel { display: inline-flex; border: 2px solid rgb(255 255 255 / 0.6); border-radius: 12px; overflow: hidden; }
.seq-barsel button { min-width: 44px; min-height: 48px; padding: 0 12px; border: 0; background: transparent; color: #fff; font-weight: 800; white-space: nowrap; }
.seq-barsel button[aria-pressed="true"] { background: var(--led); color: var(--ink); }
/* The keys sit inside a rounded frame that clips, so a focus ring goes
   inside the key, not around it (outside, only its sides showed). */
.seq-barsel button:focus-visible { outline: 3px solid currentColor; outline-offset: -6px; border-radius: 10px; }
/* On a phone, each line of controls fills the width instead of leaving a gap. */
@media (max-width: 600px) {
  .seq-foot > .seq-add { flex: 1 1 auto; }
}
/* The beat's shape: bars · time signature · swing, always on one line
   (lines.js). Under 900 px the groups share the line's width. As room runs
   out: the keys tighten, "1 bar 2 bars" becomes "1 2 4 bars", the time
   signature and swing turn into pickers ("4/4 ▾"), then the time signature
   drops out, then swing. The bars always stay. */
.seq-controls { display: flex; flex-wrap: nowrap; align-items: center; gap: 12px; }
.seq-shape { display: contents; }
/* A group never squeezes (its frame would clip its keys): the line overflows
   instead, which is what tells lines.js to take the next step. */
.seq-controls .seq-barsel, .dj-shape > .seq-barsel { flex-shrink: 0; }
@media (max-width: 899px) {
  .seq-controls > .seq-barsel, .seq-shape > .seq-barsel { display: flex; flex: 1 0 auto; }
  .seq-controls .seq-barsel button { flex: 1 0 auto; }   /* never narrower than its word */
}
.fit-tight { gap: 8px; }
.fit-tight .seq-barsel button { padding: 0 7px; }
.fit-short .bar-word { display: none; }
.seq-pick { display: none; }
.fit-pick :is(.seq-sigs, .seq-swing, .set-keys) > button { display: none; }
.fit-pick .seq-pick { display: block; }
.fit-nosig .seq-sigs, .fit-noswing .seq-swing { display: none; }
/* A picker looks like the pressed key, with a ▾ drawn at its right. */
.seq-pick {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 48px;
  padding: 0 30px 0 12px;
  border: 0;
  border-radius: 0;
  appearance: none;
  background:
    linear-gradient(45deg, transparent 50%, currentColor 50%) right 16px center / 6px 6px no-repeat,
    linear-gradient(135deg, currentColor 50%, transparent 50%) right 10px center / 6px 6px no-repeat,
    var(--led);
  color: var(--ink);
  font: 800 1rem/1 var(--font-ui);
  cursor: pointer;
}
.seq-pick:focus-visible { outline: 3px solid currentColor; outline-offset: -6px; }
.seq-tempo { flex: 1 1 220px; display: flex; align-items: center; gap: 12px; min-width: 0; font-weight: 800; }
.seq-tempo input[type="range"] { flex: 1 1 auto; width: auto; min-width: 0; min-height: 44px; accent-color: var(--led); }
.seq-tempo .seq-bpm-num, .seq-tempo .seq-bpm-type { flex: none; margin-left: auto; }
.seq-bpm-num {
  justify-self: end;
  min-width: 44px;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #fff;
  font: inherit;
  /* A dotted underline says it can be tapped to type. */
  text-decoration: underline dotted rgb(255 255 255 / 0.6) 2px;
  text-underline-offset: 5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.seq-bpm-type {
  justify-self: end;
  width: 4.5em;
  min-height: 44px;
  padding: 0 8px;
  border: 2px solid var(--led);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font: 800 1rem/1 var(--font-ui);
  text-align: right;
}
.seq-bpm-num[hidden], .seq-bpm-type[hidden] { display: none; }
.seq-empty { margin: 0 0 12px; font-weight: 700; }
/* An empty place says what to do in a callout: centered, in a dashed box
   like the add buttons it points at. */
.seq-empty, .song-empty, .lib-empty {
  padding: 16px; border: 2px dashed rgb(255 255 255 / 0.4); border-radius: 14px;
  background: rgb(255 255 255 / 0.07); color: #fff; font-size: 1.05rem; font-weight: 800; text-align: center; text-wrap: balance;
}
dialog .lib-empty { border-color: rgb(20 19 24 / 0.25); background: var(--chalk); color: var(--ink); }
/* Grooves: a new beat, or added to this one. */
#grooves .groove-how { display: flex; margin: 4px 0 8px; border-color: rgb(20 19 24 / 0.3); }
#grooves .groove-how button { flex: 1 1 0; min-width: auto; color: var(--ink); }   /* never narrower than its words, so lines.js sees the squeeze */
/* Segmented keys with an emoji: short of room (lines.js), emoji over word. */
.seq-barsel.fit-stack button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 6px; white-space: normal; line-height: 1.1; text-align: center; }
.seq-barsel.fit-stack .key-icon { font-size: 1.2rem; }
#grooves .groove-how button[aria-pressed="true"] { color: var(--ink); }

.seq-rows { position: relative; display: grid; gap: 14px; }
/* A light line between rows, so a row's 2 or 4 bars of pills read as one row. */
.seq-row + .seq-row { margin-top: 4px; padding-top: 18px; border-top: 2px solid rgb(255 255 255 / 0.5); }

/* The playhead bar, drawn over the rows at the step being played. */
.seq-playhead { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.seq-bar {
  position: absolute;
  width: 4px;
  margin-left: -2px;
  border-radius: 2px;
  background: #fff;
  /* The dark edge keeps it visible where it crosses the light sound pickers. */
  box-shadow: 0 0 0 1.5px var(--ink), 0 0 12px 2px rgb(255 255 255 / 0.45);
}
/* A row: its sound tile on the left, its buttons (Mute, and the advanced
   ones) at the far right, and the pills between them when wide enough, or
   underneath on a phone. */
.seq-row {
  --pill: var(--led);
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  grid-template-areas: "grip card tools" "steps steps steps";
  gap: 10px;
  align-items: center;
}
.seq-row > .seq-card { grid-area: card; flex: none; }
.seq-row > .seq-handle { grid-area: grip; }
.seq-row > .seq-steps { grid-area: steps; }
.seq-row > .seq-tools { grid-area: tools; justify-self: end; justify-items: end; }
@media (min-width: 720px) {
  /* Wide enough for one line per row: tile, pills, buttons. */
  .seq-row { grid-template-columns: auto auto minmax(0, 1fr) auto; grid-template-areas: "grip card steps tools"; }
}

/* A small pad: the same look as on the board, at a size that fits a row or a
   chooser cell. Beats the board's wide-screen pad font sizes. */
.pad.pad-mini {
  aspect-ratio: 1;
  padding: 7px 7px 7px 8px;
  border-radius: 11px;
  box-shadow: 0 4px 0 var(--pad-edge);
  column-gap: 3px;
}
.pad.pad-mini .pad-emoji { font-size: 1.35rem; }
.pad.pad-mini .pad-label { font-size: 0.78rem; font-stretch: 75%; line-height: 1; }
.pad.pad-mini .pad-voice { font-size: 0.95rem; }
.pad.pad-mini:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--pad-edge); }
.pad.pad-add.pad-mini { box-shadow: none; }
.pad.pad-add.pad-mini .pad-emoji { font-size: 1.6rem; }
.pad.pad-add.pad-mini .pad-label { font: 700 0.78rem/1.1 var(--font-ui); }
.seq-card { width: 88px; }  /* narrowest that fits a 17-character sound name without clipping */

/* On a phone the buttons sit beside the tile and wrap to a second line when
   a Remove? needs the room. Beside the pills on a wide screen they stack, in
   a column of fixed width so every row's pills line up. */
.seq-tools { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; min-width: 0; }
/* On a phone the keys share each line they land on: Mute and Clear, then
   Remove across the width under them, never one left hanging. */
@media (max-width: 719px) { .seq-tools > .seq-tool { flex: 1 1 auto; } }
@media (min-width: 720px) { .seq-tools { flex-direction: column; flex-wrap: nowrap; width: 7.5rem; } }
.seq-tool {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border: 2px solid rgb(255 255 255 / 0.5);
  border-radius: 10px;
  background: transparent;
  color: #fff;
  font: 800 0.9rem/1 var(--font-ui);
  white-space: nowrap;
}
.seq-tool[aria-pressed="true"] { background: var(--led); border-color: var(--led); color: var(--ink); }
.seq-tool:disabled { opacity: 0.35; }
/* A Clear? or Remove? waiting for its second tap. */
.seq-tool.armed { background: #D93A2B; border-color: #D93A2B; }
/* The handle column: the collapse button, and the grip under it. */
.seq-handle { display: grid; justify-items: center; gap: 4px; align-self: center; }
.seq-fold {
  width: 44px;
  min-height: 44px;
  margin: 0 -8px;   /* a 44 px target in the grip's 28 px column */
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: rgb(255 255 255 / 0.75);
  font: 800 1.1rem/1 var(--font-ui);
}
.seq-fold:hover { background: rgb(255 255 255 / 0.08); }
/* A collapsed row: handle and one slim line with the sound's emoji and name. */
.seq-row.collapsed { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "grip slim"; }
.seq-row.collapsed .seq-handle { grid-auto-flow: column; }
.seq-handle .seq-grip { min-height: 48px; padding: 8px 4px; }
.seq-row.collapsed .seq-grip { min-height: 44px; padding: 12px 4px; }
.seq-slim {
  grid-area: slim;
  justify-self: start;
  max-width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-left: 6px solid var(--pill);
  border-radius: 10px;
  background: rgb(255 255 255 / 0.08);
  color: #fff;
  font: 800 1rem/1 var(--font-ui);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seq-row.collapsed.muted .seq-slim { opacity: 0.55; }
/* The grip: a column of dots, a tall target that only starts a drag. */
.seq-grip {
  width: 28px;
  min-height: 64px;
  padding: 14px 4px;
  border: 0;
  border-radius: 8px;
  background: radial-gradient(circle, rgb(255 255 255 / 0.55) 2.2px, transparent 2.6px) content-box;
  background-size: 10px 10px;
  cursor: grab;
  touch-action: none;
}
.seq-grip[hidden] { display: none; }
.seq-grip:hover { background-color: rgb(255 255 255 / 0.08); }
.seq-row.dragging { position: relative; z-index: 5; opacity: 0.9; }
.seq-row.dragging .seq-grip { cursor: grabbing; }
/* A muted row keeps its pills, dimmed, so it's clear it is silent. */
.seq-row.muted .seq-steps, .seq-row.muted .seq-card { opacity: 0.4; }
/* Pills past a row's length (Pills tempo mode) are hidden, not just dimmed. */
.seq-beat[hidden], .pill[hidden] { display: none; }

/* One group per beat of the time signature. A group grows with its pill
   count (4 or 6) and needs ~30px a pill, so groups wrap onto more lines when
   the row is narrow: two 4-pill beats a line on a phone, all of 4/4 on one
   line when wide. */
/* Bars stack, one block each; in a block, beat groups wrap to fit. */
.seq-steps { display: grid; gap: 10px; }
.seq-measure { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px 10px; }   /* columns set by layoutMeasures */
.seq-measure[hidden] { display: none; }
.seq-measure + .seq-measure { padding-top: 10px; border-top: 2px dashed rgb(255 255 255 / 0.15); }
.seq-beat {
  --size: 4;
  /* About 26px a pill at least, so a bar of 4/4 fits on one line from ~490px;
     a group alone on a wrapped line doesn't stretch across the whole row. */
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(var(--size), minmax(0, 1fr));
  gap: 5px;
  padding: 5px;
  border-radius: 14px;
  background: rgb(255 255 255 / 0.06);
}

/* Vertical pills: dim when off, the sound's pad color when on. The playhead
   lights the column being played; a lit pill that is on flashes white. */
.pill {
  height: 64px;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.13);
  transition: background-color 60ms, transform 60ms;
}
.pill.beat-start { background: rgb(255 255 255 / 0.19); }
/* The "1" of every bar: brighter, with a small white dot while it is off. */
.pill.one { background: rgb(255 255 255 / 0.26) radial-gradient(circle, rgb(255 255 255 / 0.75) 3px, transparent 3.5px) center / 100% 100% no-repeat; }
.pill[aria-pressed="true"] { background: var(--pill); box-shadow: 0 3px 0 color-mix(in srgb, var(--pill) 55%, black); }
/* A loud hit: the same color with a white ring inside, so on and loud read apart. */
.pill.loud[aria-pressed="true"] { box-shadow: inset 0 0 0 4px rgb(255 255 255 / 0.9), 0 3px 0 color-mix(in srgb, var(--pill) 55%, black); }
.pill.now { outline: 2px solid rgb(255 255 255 / 0.7); outline-offset: 1px; }
.pill.now[aria-pressed="true"] { background: #fff; transform: translateY(2px); box-shadow: 0 1px 0 color-mix(in srgb, var(--pill) 55%, black); }

/* A melody row: per bar, 8 note lanes (highest on top) under the bar's pills. */
.seq-melody { display: grid; gap: 8px; }
.seq-roll { display: grid; grid-template-columns: 1.4rem repeat(var(--cols), minmax(0, 1fr)); gap: 2px; }
.seq-roll[hidden] { display: none; }
.note-name { font: 800 0.7rem/1 var(--font-ui); color: rgb(255 255 255 / 0.6); align-self: center; text-align: center; }
.note-cell { min-width: 0; height: 22px; padding: 0; border: 0; border-radius: 5px; background: rgb(255 255 255 / 0.1); }
.note-cell.beat-start { background: rgb(255 255 255 / 0.17); }
.note-cell[aria-pressed="true"] { background: var(--pill); box-shadow: 0 2px 0 color-mix(in srgb, var(--pill) 55%, black); }
.note-cell.now { outline: 2px solid rgb(255 255 255 / 0.7); outline-offset: 1px; }
@media (pointer: coarse) { .note-cell { height: 28px; } }
/* The open document's name bar: a beat on Beats and in Beat Builder, a song
   on 🎼 Song. It comes first on its screen, in a zone of its own a shade
   lighter than the panel. With room it is one line: icon, name (a text
   field: tap to rename), ✏️, 🆕 New, 📂 Open. Short of room, two balanced
   lines: icon, name and ✏️ over New and Open, which share the width; the
   icon and ✏️ columns are the same width, so the halves match. */
.seq, .dj, .song { container: panel / inline-size; }
.doc-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  padding: 8px;
  border-radius: 16px;
  background: rgb(255 255 255 / 0.08);
  box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.06);
}
.beat-bar-icon { flex: none; width: 44px; font-size: 1.3rem; text-align: center; }
.doc-bar .seq-tool { flex: none; }
.beat-name {
  flex: 1 1 9em;
  min-width: 0;
  min-height: 44px;
  padding: 0 10px;
  border: 2px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: #fff;
  font: 800 1.1rem/1 var(--font-ui);
  text-overflow: ellipsis;
}
.beat-name:hover, .beat-name:focus { border-color: rgb(255 255 255 / 0.5); background: rgb(0 0 0 / 0.2); }
/* The settings deck: what applies to the whole beat or song (Play, tempo,
   ⏲️, bars · time signature · swing; ● Record in Beat Builder; ▶ Play song),
   on a darker band across the panel under the name bar, ending in a bright
   rule, so its scope reads apart from the rows below. Every control on it
   is 52 px tall. Beats builds it from two lines (the transport sticks on a
   phone), so each line is a .deck and the last is also .deck-end. */
.deck { margin: 0 -12px; padding: 10px 12px; background: var(--deck); }
.deck + .deck { padding-top: 0; }
.deck-end { margin-bottom: 16px; padding-bottom: 14px; border-bottom: 3px solid rgb(255 255 255 / 0.3); }
.deck .seq-tool { min-height: 52px; padding: 0 14px; border-radius: 12px; font-size: 1rem; }
@container panel (max-width: 30rem) {
  .doc-bar {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) minmax(0, 1fr) 44px;
    grid-template-areas: "icon name name rename" "new new open open";
  }
  .doc-bar .beat-bar-icon { grid-area: icon; }
  .doc-bar .beat-name { grid-area: name; }
  .doc-bar .doc-rename { grid-area: rename; }
  .doc-bar .doc-new { grid-area: new; }
  .doc-bar .doc-open { grid-area: open; }
  /* Nothing open (ADR 0008): no name or ✏️, so one line: the icon, then
     🆕 New and 📂 Open sharing the width. */
  .doc-bar:has(.beat-name[hidden]) { grid-template-columns: 44px minmax(0, 1fr) minmax(0, 1fr); grid-template-areas: "icon new open"; }
}
.seq-undo { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding: 8px 8px 8px 16px; border-radius: 12px; background: rgb(255 255 255 / 0.12); font-weight: 800; }
.seq-undo[hidden] { display: none; }
.seq-foot { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 16px; }
.seq-add {
  min-height: 48px;
  padding: 0 18px;
  border: 2px dashed rgb(255 255 255 / 0.5);
  border-radius: 12px;
  background: transparent;
  color: #fff;
  font-weight: 800;
}

/* ── Song (Advanced): a row of beat slots under the grid ─────────────── */
/* 🎼 Song: a screen of its own (Advanced), a panel like Beats and DJ. */
.song { padding: 14px 12px 18px; border-radius: 22px; background: var(--bed); box-shadow: inset 0 4px 0 var(--bed-edge); color: #fff; }
.song[hidden] { display: none; }
.song-empty { margin: 0 0 10px; }
/* One slot per line on a phone; side by side when there is room. */
.song-slots { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 8px; margin: 0; padding: 0; list-style: none; }
.song-slot {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  padding: 6px 6px 6px 8px;
  border-radius: 12px;
  background: rgb(255 255 255 / 0.12);
}
.song-slot.now { box-shadow: inset 0 0 0 3px var(--led); }
.song-slot.gone { opacity: 0.5; }
.song-slot.gone .song-beat-name { font-style: italic; }
.song-letter { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; background: var(--led); color: var(--ink); font: 800 1rem/1 var(--font-ui); }
.song-text { display: grid; min-width: 0; }
.song-beat-name { font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.song-pass { font-size: 0.85rem; color: rgb(255 255 255 / 0.85); }
.song-times { min-width: 52px; }
/* Play song and Save as a sound on the deck; + Add a beat under the slots, like + Add a row. */
.song-deck { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.song-deck > * { flex: 1 1 auto; }
.song-foot { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 12px; }
.song-foot > * { min-height: 48px; }
.song-note { margin: 8px 0 0; font-weight: 700; }
.song-note:empty { display: none; }
@media (max-width: 600px) {
  .song-foot > * { flex: 1 1 auto; }
}
@media (min-width: 601px) { .song-deck > * { flex: none; } }

/* ── Toolbar ────────────────────────────────────────────────────────── */

.toolbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 10;  /* above everything that scrolls under it: the playhead, a dragged pad */
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 10px max(var(--gutter), calc((100% - var(--max)) / 2 + var(--gutter))) calc(14px + env(safe-area-inset-bottom));
  background: var(--board);
  box-shadow: 0 -2px 0 var(--board-deep);
  transition: background-color 0.3s ease;
}

.tool {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 20px;
  border: 0;
  border-radius: 12px;
  background: var(--bed);
  color: #fff;
  box-shadow: 0 5px 0 var(--bed-edge);
  font-weight: 800;
  font-size: 1.05rem;
  white-space: nowrap;  /* a label on two lines reads as two buttons */
  transition: transform 50ms, box-shadow 50ms;
}
/* On a phone the tools share the toolbar's width, so none sits alone at an edge. */
@media (max-width: 600px) {
  .tool { flex: 1 1 auto; justify-content: center; }
}
/* The toolbar stays one line (lines.js): short of room, the tools tighten,
   Stop all says Stop, then the screen buttons stack emoji over word. */
.toolbar.fit-tight { gap: 8px; }
.fit-tight .tool { padding: 0 10px; gap: 6px; font-size: 1rem; }
.fit-short .tool-more { display: none; }
.toolbar.fit-stack { gap: 6px; }
@media (max-width: 360px) { .toolbar { padding-left: 10px; padding-right: 10px; } }
.tool:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--bed-edge); }
/* The three screens, side by side as one switch. */
.screens { display: flex; gap: 8px; }
@media (max-width: 600px) { .screens { flex: 3 1 auto; } .screens .tool { flex: 1 1 0; } }
.fit-stack .screens { gap: 4px; }
.fit-stack .screens .tool { flex-direction: column; justify-content: center; gap: 1px; padding: 0 4px; font-size: 0.8rem; line-height: 1.1; }
.fit-stack .screens .tool span { font-size: 1.15rem; }
.tool[aria-pressed="true"] {
  background: var(--chalk);
  color: var(--ink);
  transform: translateY(4px);
  box-shadow: 0 1px 0 var(--chalk-edge);
}

.tool-stop::before {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 3px;
  background: var(--record);
}

/* ── Sheet (new / edit sound) ───────────────────────────────────────── */

dialog#sheet, dialog#chooser, dialog#library, dialog#grooves, dialog#takes, dialog#pictures, dialog#people-dialog, dialog#settings-dialog {
  width: min(560px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  border-radius: 24px;
  background: var(--paper);
  color: var(--ink);
}
dialog#sheet::backdrop, dialog#chooser::backdrop, dialog#library::backdrop, dialog#grooves::backdrop, dialog#takes::backdrop, dialog#pictures::backdrop, dialog#people-dialog::backdrop, dialog#settings-dialog::backdrop { background: rgb(20 19 24 / 0.62); }
dialog#sheet :focus-visible, dialog#chooser :focus-visible, dialog#library :focus-visible, dialog#grooves :focus-visible, dialog#takes :focus-visible, dialog#pictures :focus-visible, dialog#people-dialog :focus-visible, dialog#settings-dialog :focus-visible { outline-color: var(--board); }

@media (max-width: 600px) {
  dialog#sheet, dialog#chooser, dialog#library, dialog#grooves, dialog#takes, dialog#pictures, dialog#people-dialog, dialog#settings-dialog {
    width: 100%;
    max-width: 100%;
    margin: auto 0 0;
    border-radius: 24px 24px 0 0;
  }
}

#sheet-form, .chooser-body { padding: 20px 20px calc(20px + env(safe-area-inset-bottom)); }

/* The chooser shows the board's sounds on a piece of the pad bed. */
.chooser-groups { display: grid; gap: 12px; margin-bottom: 16px; }
/* Each section is one box in its color (the kit's dark, a person's own): the
   name along the top, its sounds underneath. A closed group is just its name. */
.chooser-group {
  border-radius: 18px;
  background: var(--c);
  color: #fff;
}
.chooser-group h3 {
  margin: 0;
  padding: 12px 16px 0;
  font: 800 1rem/1.2 var(--font-display);
}
.chooser-toggle {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 48px;
  padding: 0 16px;
  border: 0;
  border-radius: 18px;
  background: transparent;
  color: inherit;
  font: 800 1rem/1.2 var(--font-display);
  text-align: left;
}
.chooser-grid[hidden] { display: none; }
.chooser-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 14px 10px;
  padding: 12px 12px 18px;
}
.chooser-toggle + .chooser-grid { padding-top: 0; }
.chooser-grid :focus-visible { outline-color: #fff; }
.chooser-grid .pad[aria-pressed="true"] { outline: 4px solid #fff; outline-offset: 3px; }
.chooser-grid .pad.pad-mini { padding: 10px 10px 10px 12px; }
.chooser-grid .pad.pad-mini .pad-emoji { font-size: 1.7rem; }
.chooser-grid .pad.pad-mini .pad-label { font-size: 0.92rem; }   /* "Tambourine" fits a phone line; longer names wrap */
/* The bottom bar stays in view while the sounds scroll: the row's own
   buttons, then the one that uses the marked sound. */
#chooser .chooser-body { padding-bottom: 0; }   /* its pinned bar has its own; the other dialogs keep theirs */
.chooser-foot {
  position: sticky;
  bottom: 0;
  display: grid;
  gap: 12px;
  margin: 0 -20px;
  padding: 14px 20px calc(16px + env(safe-area-inset-bottom));
  background: var(--paper);
  box-shadow: 0 -8px 16px -10px rgb(20 19 24 / 0.35);
}
.chooser-tools { display: flex; flex-wrap: wrap; gap: 8px; }
.chooser-tools .seq-tool { border-color: rgb(20 19 24 / 0.25); color: var(--ink); }
.chooser-tools .seq-tool { flex: 1 1 auto; }
/* A row's speed: ½× 1× 2× keys after the word, like bars and time signature. */
.chooser-rate { display: flex; flex: 1 1 auto; align-items: center; gap: 8px; color: var(--ink); font-weight: 800; }
.chooser-rate .seq-barsel { flex: 1 0 auto; border-color: rgb(20 19 24 / 0.3); }
.chooser-rate .seq-barsel button { flex: 1 0 auto; color: var(--ink); }
.chooser-tools[hidden] { display: none; }
/* No sound: a real choice on the white sheet, not a ghost of the dark-screen button. */
.chooser-foot .chooser-none { min-height: 48px; border: 2px solid rgb(20 19 24 / 0.3); background: var(--chalk); color: var(--ink); }
#chooser-ok { width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#chooser-ok:disabled { opacity: 0.5; box-shadow: none; }

/* People editor: name, a row of deep colors, hide/delete. */
.pe-list { display: grid; gap: 12px; margin: 0 0 16px; padding: 0; list-style: none; }
.pe-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 10px;
  padding: 12px;
  border-radius: 14px;
  background: var(--c);
  color: #fff;
}
.pe-row.pe-hidden { opacity: 0.55; }
.pe-name {
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: 10px;
  background: rgb(255 255 255 / 0.92);
  color: var(--ink);
  font: 800 1.1rem/1 var(--font-ui);
}
.pe-row .quiet { color: #fff; }
.pe-row .quiet:disabled { opacity: 0.4; cursor: not-allowed; }
.pe-row .danger.armed { background: #fff; color: #B3261E; }
/* Deleted boards.json people, to bring back. */
.pe-gone { margin-top: 20px; padding-top: 14px; border-top: 2px solid var(--line); }
.pe-gone h3 { margin: 0 0 8px; font: 800 1.05rem/1.2 var(--font-ui); }
.pe-gone-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.pe-gone-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 4px 4px 4px 14px; border-left: 8px solid var(--c); border-radius: 10px; background: var(--chalk); font-weight: 800; }
.pe-colors { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.pe-colors button {
  width: 44px;
  height: 44px;
  border: 2px solid rgb(255 255 255 / 0.85);
  border-radius: 50%;
  background: var(--sw);
}
.pe-colors button[aria-pressed="true"] { outline: 3px solid #fff; outline-offset: 2px; }

/* Settings: one block per topic, with the Beats choice as big radio cards. */
.set-note { min-height: 1.4em; margin: -6px 0 6px; font-weight: 700; }
.set-section { margin: 0 0 22px; padding: 0; border: 0; min-width: 0; }
.set-section h3, .set-section legend { margin: 0 0 4px; padding: 0; font: 800 1.15rem/1.2 var(--font-ui); }
/* A pair of buttons shares the line in equal halves, or stacks full width when too narrow. */
.set-buttons { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); gap: 10px; }
.chip-dark { position: relative; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.chip-dark input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.chip-dark:focus-within { outline: 3px solid var(--board); outline-offset: 3px; }
.set-radio {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 44px;
  margin: 0 0 8px;
  padding: 10px 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  cursor: pointer;
}
.set-radio input { flex: none; width: 24px; height: 24px; margin: 0; accent-color: var(--board); }
.set-radio:has(input:checked) { border-color: var(--board); background: var(--chalk); }
.set-radio:has(input:focus-visible) { outline: 3px solid var(--board); outline-offset: 2px; }
.set-about { margin: 0; }
.set-group { margin: 12px 0 0; padding: 0; border: 0; min-width: 0; }
.set-group legend { margin: 0 0 6px; padding: 0; font-weight: 800; }
.set-switch input { border-radius: 6px; }
/* The device code is read aloud or typed, so it is spaced and fixed-width. */
.set-code { margin: 0 0 10px; }
.set-code b { font-family: ui-monospace, Menlo, Consolas, monospace; letter-spacing: 0.08em; }

/* Saved beats: a name field, then the library, newest first. */
.lib-note { min-height: 1.4em; margin: 8px 0 4px; font-weight: 700; }
.lib-sound-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 12px; }
.lib-bars { display: inline-flex; border: 2px solid var(--line); border-radius: 12px; overflow: hidden; }
.lib-bars button { min-height: 44px; padding: 0 12px; border: 0; background: #fff; font-weight: 700; }
.lib-bars button[aria-pressed="true"] { background: var(--board); color: #fff; }
.chip-dark:disabled { opacity: 0.5; }
/* A button waiting for its second press ("Tap again"). */
.chip-dark.armed, #lib-new.armed { padding: 0 16px; border-radius: 12px; background: #B3261E; color: #fff; text-decoration: none; }
.lib-empty { margin: 8px 0 0; color: var(--muted); }
.lib-list { display: grid; gap: 10px; margin: 8px 0 0; padding: 0; list-style: none; }
.lib-beat {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: 14px;
  background: var(--chalk);
}
.lib-beat.current { box-shadow: inset 0 0 0 3px var(--board); }
/* A beat's card: the whole card opens it; duplicate and delete at its end. */
.lib-beat { grid-template-columns: minmax(0, 1fr) auto auto auto; }
/* A phone: the beat's card keeps its whole name on top, the ⧉ ⬇️ 🗑️ keys on a line under it, at the right. */
@media (max-width: 520px) { .lib-beat:has(> .lib-open) .lib-open { grid-column: 1 / -1; } .lib-beat:has(> .lib-open) > [data-dup] { grid-column: 2; } }
.lib-open { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 10px; min-height: 52px; padding: 0; border: 0; background: transparent; color: var(--ink); font: inherit; text-align: left; }
.lib-beat .chip-dark { min-width: 48px; padding: 0 12px; }
/* A groove is a whole-card button: thumbnail, name, sounds and tempo. */
.groove { grid-template-columns: auto 1fr; width: 100%; min-height: 56px; border: 0; color: var(--ink); font: inherit; text-align: left; }
.groove.armed { box-shadow: inset 0 0 0 3px #B3261E; }
.lib-text { display: grid; min-width: 0; }
/* In every list (beats, grooves, songs), a long name wraps instead of hiding behind "…". */
.lib-name { font-weight: 800; overflow-wrap: break-word; hyphens: auto; }
.lib-info { color: var(--muted); font-size: 0.9rem; }
.lib-thumb { display: grid; gap: 3px; padding: 6px; border-radius: 8px; background: var(--bed); }
.lib-thumb div { --pill: var(--led); display: grid; grid-template-columns: repeat(16, 4px); gap: 2px; }
.lib-thumb span { height: 6px; border-radius: 2px; background: rgb(255 255 255 / 0.15); }
.lib-thumb span.on { background: var(--pill); }
.chip-dark {
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: 12px;
  background: var(--board);
  color: #fff;
  font-weight: 800;
}


.sheet-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.sheet-head h2 {
  margin: 4px 0 0;
  font: 900 1.75rem/1.02 var(--font-display);
  font-stretch: 80%;
  text-wrap: balance;
}

.close {
  flex: none;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: var(--chalk);
  font-size: 1.1rem;
}

/* The recorder: a piece of the pad bed, with a real REC button. */
.capture {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px;
  margin-bottom: 20px;
  border-radius: 18px;
  background: var(--bed);
  color: #fff;
}
dialog#sheet .capture :focus-visible { outline-color: #fff; }

.rec {
  --rec-edge: color-mix(in srgb, var(--record) 55%, black);
  flex: none;
  display: grid;
  place-items: center;
  align-content: center;
  gap: 6px;
  width: 96px;
  height: 96px;
  border: 0;
  border-radius: 50%;
  background: var(--record);
  color: #fff;
  font-weight: 800;
  box-shadow: 0 6px 0 var(--rec-edge);
  transition: transform 50ms, box-shadow 50ms;
}
.rec:active, .rec[aria-pressed="true"] { transform: translateY(5px); box-shadow: 0 1px 0 var(--rec-edge); }
.rec-cap { width: 20px; height: 20px; border-radius: 50%; background: #fff; }
.rec[aria-pressed="true"] .rec-cap { border-radius: 4px; animation: blink 1s steps(2) infinite; }
.rec:disabled { background: #6E6A80; --rec-edge: #45424F; color: #E6E4EE; cursor: not-allowed; }
@keyframes blink { 50% { opacity: 0.3; } }

.capture-body { flex: 1; min-width: 0; }
.grille-lg { margin: 0 0 12px; padding: 0; background: none; grid-template-rows: repeat(3, 8px); grid-auto-columns: 8px; gap: 5px; }
/* Too loud: the recorder's grille goes red while the sound hits the top. */
.grille.too-loud span.lit { background: #FF5A4E; }
.capture-status { margin: 0 0 12px; font-weight: 700; }

.capture-actions { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border: 2px solid rgb(255 255 255 / 0.75);
  border-radius: 12px;
  background: transparent;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
}
.chip:disabled { opacity: 0.45; cursor: default; }
.chip input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.chip:focus-within { outline: 3px solid #fff; outline-offset: 3px; }

/* ✨ Make one: starters on a piece of the pad bed, under the recorder. */
.make {
  margin: -8px 0 20px;
  padding: 14px 16px 16px;
  border-radius: 18px;
  background: var(--bed);
  color: #fff;
}
dialog#sheet .make :focus-visible { outline-color: #fff; }
.make-hint { margin: 0 0 10px; font-weight: 700; }
.make-starters { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }
.make-starter { gap: 8px; padding: 0 12px; }
#make-btn { gap: 6px; }
.make-starter span { font-size: 1.3rem; }
.make-starter[aria-pressed="true"] { background: #fff; color: var(--ink); border-color: #fff; }
.make-knobs { margin-top: 4px; }
.amount.make-amount { grid-template-columns: 1fr auto; grid-template-areas: "name out" "slider slider"; gap: 0 12px; margin: 8px 0 0; padding: 6px 12px; color: var(--ink); }
.make-amount span { grid-area: name; }
.make-amount output { grid-area: out; }
.make-amount input { grid-area: slider; }

/* The sound's wave: bars in the board color that light up behind the line
   sweeping across as it plays. */
.wave-box { margin: 0 0 20px; }
.wave {
  --wave-head: var(--ink);
  display: block;
  width: 100%;
  height: 72px;
  padding: 0;
  border-radius: 12px;
  background: var(--chalk);
  color: var(--board);
}

/* Hold: before. A key the width of the wave that stays down while held. */
.hold-before {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  margin-top: 10px;
  border: 0;
  border-radius: 12px;
  background: var(--chalk);
  box-shadow: 0 4px 0 var(--line);
  color: var(--ink);
  font-weight: 800;
  font-size: 1rem;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  transition: transform 50ms, box-shadow 50ms;
}
.hold-before:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--line); background: #fff; }
.hold-before:disabled { opacity: 0.45; cursor: default; }

/* Trim and chop (Advanced, chop.js): handles over the wave, 44 px wide to
   grab, each drawn as a line with a knob on top. The cut-off ends of a trim
   are drawn grey by wave.js in --wave-cut. */
.wave-box { position: relative; }
.wave { --wave-cut: var(--chalk-edge); }
.wave-marks {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 72px;
  touch-action: none;
  cursor: pointer;
}
.wave-handle {
  position: absolute;
  top: -6px;
  bottom: 0;
  left: calc(10px + var(--f) * (100% - 20px));   /* wave.js WAVE_PAD at each end */
  width: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  transform: translateX(-50%);
  cursor: ew-resize;
  touch-action: none;
}
.wave-handle::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 0;
  left: calc(50% - 1.5px);
  width: 3px;
  border-radius: 2px;
  background: var(--ink);
}
.wave-handle::after {
  content: "";
  position: absolute;
  top: 0;
  left: calc(50% - 8px);
  width: 16px;
  height: 16px;
  border: 3px solid var(--paper);
  border-radius: 50%;
  background: var(--ink);
}
.wave-handle[aria-pressed="true"]::before, .wave-handle[aria-pressed="true"]::after { background: var(--record); }
.cut-from { margin: 8px 0 0; }
.cut { margin-top: 10px; }
.cut-tools { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.cut-panel .cut-tools { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cut-tools .chain-tool { padding: 4px 8px; line-height: 1.15; }
.cut-make { grid-column: 1 / -1; }
.cut-make:not(:disabled), #cut-done { background: var(--ink); color: #fff; }
.cut-hint { margin: 0 0 8px; }

/* The wave editor (Advanced, chop.js): three views of the trim's wave and
   handles (Ends, Fades, Select part), and Select part's five changes in
   pairs, Keep only this across the width, so every line is full at 320 px.
   A fade handle's knob is a diamond, so it reads as a different handle. */
.cut-views { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin: 0 0 8px; }
.cut-views .chain-tool { padding: 4px 6px; line-height: 1.15; }
.cut-views .chain-tool[aria-pressed="true"] { background: #fff; border-color: var(--board); box-shadow: inset 0 0 0 1px var(--board); }
.cut-edits { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin: 0 0 8px; }
.cut-edits .chain-tool { padding: 4px 8px; line-height: 1.15; }
.cut-edits .cut-keep { grid-column: 1 / -1; }
.wave-handle[data-kind="fades"]::after { border-radius: 3px; transform: rotate(45deg); }

.field { display: block; margin: 0 0 20px; padding: 0; border: 0; min-width: 0; }
.field-name { display: block; margin: 0 0 8px; padding: 0; font-weight: 800; font-size: 1.05rem; }
.field input {
  width: 100%;
  min-height: 52px;
  padding: 0 14px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fff;
  font-size: 1.15rem;
}
.field input:focus-visible { outline: 3px solid var(--board); outline-offset: 0; border-color: transparent; }

.field-hint { margin: 0 0 10px; color: var(--muted); }

/* Voices: small keys that latch when chosen. */
.voices {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  gap: 12px 8px;
}
.voices button {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  padding: 6px 10px;
  border: 0;
  border-radius: 12px;
  background: var(--chalk);
  box-shadow: 0 4px 0 var(--line);
  font-weight: 800;
  font-size: 0.95rem;
  line-height: 1.1;
  text-align: left;
  transition: transform 50ms, box-shadow 50ms;
}
.voices button:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--line); }
.voices button[aria-pressed="true"] {
  background: var(--board);
  color: #fff;
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--board-deep);
}
.voices button:disabled { opacity: 0.45; cursor: default; }
.voice-emoji { font-size: 1.45rem; line-height: 1; }

/* The slider for voices with a setting (speed or pitch), under the voice keys. */
.amount {
  display: grid;
  grid-template-columns: auto 1fr minmax(7.5em, auto);
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--chalk);
  font-weight: 800;
}
.amount[hidden] { display: none; }
.amount input { width: 100%; min-height: 44px; accent-color: var(--board); }
.amount input:disabled { opacity: 0.45; }
.amount output { text-align: right; font-variant-numeric: tabular-nums; }
/* A setting with a few stops (Tone, Echoes, Loudness…) shows them as keys
   (lines.js keysForSlider), in the frame bars and time signature use. The
   slider and its words come back only when the keys don't fit (fit-slider). */
.amount .slider-keys { display: flex; border-color: rgb(20 19 24 / 0.3); background: #fff; }
.amount .slider-keys button { flex: 1 0 auto; color: var(--ink); }
.amount .slider-keys button[aria-pressed="true"] { color: var(--ink); }
.amount .slider-keys button:disabled { opacity: 0.45; }
dialog#sheet .amount .slider-keys button:focus-visible { outline-color: var(--ink); }
.amount.keyed:not(.fit-slider) > input, .amount.keyed:not(.fit-slider) > output { display: none; }
.amount.keyed:not(.fit-slider) { grid-template-columns: auto 1fr; }
.amount.fit-slider > .slider-keys { display: none; }
.make-amount .slider-keys, .shape-amount .slider-keys { grid-area: slider; }
.amount.keyed.make-amount:not(.fit-slider), .amount.keyed.shape-amount:not(.fit-slider) { grid-template-columns: 1fr auto; }
/* A voice's setting fallen back to its slider (no room for keys): the name
   and words on top, the slider full width under them, as in Make one. */
#amount-row.keyed:not(.fit-slider) { grid-template-columns: 1fr; gap: 6px; }   /* keys under the name, full width */
#amount-row.fit-slider { grid-template-columns: 1fr auto; grid-template-areas: "name out" "slider slider"; gap: 0 12px; }
#amount-row.fit-slider > span { grid-area: name; }
#amount-row.fit-slider > output { grid-area: out; }
#amount-row.fit-slider > input { grid-area: slider; }

/* The chain of voices: chips in play order with arrows between, then
   + Then add and 🎲 Surprise me. Wraps onto more lines on a phone. */
.chain { display: grid; gap: 8px; margin-top: 16px; }
.chain-links { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.chain-item { display: flex; gap: 8px; }
.chain-then { color: var(--muted); font-weight: 700; }
.chain-tools { display: flex; gap: 8px; }
.chain-link, .chain-remove, .chain-tool {
  min-height: 44px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  font-weight: 800;
  font-size: 0.95rem;
}
.chain-link { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 0 12px; text-align: left; }
.chain-link[aria-pressed="true"] { border-color: var(--board); box-shadow: inset 0 0 0 1px var(--board); }
.chain-remove { min-width: 44px; padding: 0; }
.chain-tool { flex: 1; padding: 0 10px; background: var(--chalk); border-color: transparent; }
.chain-link:disabled, .chain-remove:disabled, .chain-tool:disabled { opacity: 0.45; cursor: default; }
.chain-hint { margin: 8px 0 0; }

/* Shape it (Advanced): the chain as cards, top to bottom in play order. Each
   card: a grip to drag it, its name (tap to pick it for the voice keys), ⤢
   and ✕, then its sliders, each a label and value over a full-width slider. */
.shape-steps { display: grid; gap: 10px; margin: 0 0 10px; padding: 0; list-style: none; }
.shape-step { padding: 6px; border: 2px solid var(--line); border-radius: 14px; background: #fff; }
.shape-step.picked { border-color: var(--board); }
.shape-step.dragging { opacity: 0.6; }
.shape-step.drop-here { box-shadow: 0 -4px 0 var(--board); }
.shape-head { display: flex; align-items: center; gap: 4px; }
.shape-grip, .shape-open, .shape-remove {
  flex: none;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font-weight: 800;
  font-size: 1.2rem;
}
.shape-grip { cursor: grab; touch-action: none; }
.shape-grip:disabled { opacity: 0.35; cursor: default; }
.shape-pick {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink);
  font-weight: 800;
  text-align: left;
}
.shape-pick[aria-pressed="true"] { background: var(--chalk); }
.shape-name { min-width: 0; overflow-wrap: anywhere; }
.shape-open:disabled, .shape-remove:disabled, .shape-pick:disabled { opacity: 0.45; cursor: default; }
.amount.shape-amount { grid-template-columns: 1fr auto; grid-template-areas: "name out" "slider slider"; gap: 0 12px; margin: 6px 0 0; padding: 6px 10px; }
.shape-amount span { grid-area: name; }
.shape-amount output { grid-area: out; }
.shape-amount input { grid-area: slider; }
.shape-flag {
  min-height: 44px;
  margin: 6px 0 0;
  padding: 0 14px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fff;
  font-weight: 800;
}
.shape-flag[aria-pressed="true"] { border-color: var(--board); background: var(--board); color: #fff; }
.shape-flag::before { content: "○ "; }
.shape-flag[aria-pressed="true"]::before { content: "● "; }
.shape-palette { margin-top: 12px; }
/* 🎵 Find its note, what it heard, then Tune. */
.note-tools { display: grid; gap: 8px; margin-top: 12px; }
.note-out { margin: 0; font-weight: 700; }
.note-out:empty { display: none; }
/* ➕ Mix with another sound: which one, when it starts, the balance. */
.mix-open { width: 100%; margin-top: 12px; }
.mix { display: grid; gap: 8px; margin-top: 8px; }
.mix .amount { margin: 0; }
.mix-with { display: grid; gap: 4px; font-weight: 800; }
.mix-with select {
  width: 100%;
  min-height: 48px;
  padding: 0 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
}

/* Advanced on a wide screen: the sheet widens and Shape it gets its own column. */
@media (min-width: 900px) {
  dialog#sheet.wide { width: min(960px, calc(100vw - 2 * var(--gutter))); }
  dialog#sheet.wide #sheet-form { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 28px; align-items: start; }
  dialog#sheet.wide #sheet-form > * { grid-column: 1; }
  dialog#sheet.wide #sheet-form > .sheet-head,
  dialog#sheet.wide #sheet-form > .sheet-error,
  dialog#sheet.wide #sheet-form > .sheet-actions { grid-column: 1 / -1; }
  dialog#sheet.wide #shape { grid-column: 2; grid-row: 2 / span 7; }
  dialog#sheet.wide .swatches { grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); }
}

.emoji-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
  gap: 6px;
}
.emoji-grid button {
  aspect-ratio: 1;
  border: 0;
  border-radius: 10px;
  background: var(--chalk);
  font-size: 1.5rem;
}
.emoji-grid button[aria-pressed="true"] { background: #fff; box-shadow: inset 0 0 0 3px var(--board); }

/* Swatches are tiny pads in each color. */
.swatches { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px 10px; }
@media (min-width: 480px) { .swatches { grid-template-columns: repeat(8, minmax(0, 1fr)); } }
.swatches button {
  height: 44px;
  border: 0;
  border-radius: 10px;
  background: var(--c);
  box-shadow: 0 4px 0 color-mix(in srgb, var(--c) 55%, black);
  transition: transform 50ms, box-shadow 50ms;
}
.swatches button[aria-pressed="true"] {
  transform: translateY(3px);
  box-shadow: 0 1px 0 color-mix(in srgb, var(--c) 55%, black), 0 0 0 3px #fff, 0 0 0 6px var(--ink);
}

.sheet-error {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 12px;
  background: #FDE3E2;
  color: #8A1512;
  font-weight: 700;
}

.sheet-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
}
.primary {
  min-height: 56px;
  padding: 0 28px;
  border: 0;
  border-radius: 14px;
  background: var(--board);
  color: #fff;
  font-weight: 800;
  font-size: 1.1rem;
  box-shadow: 0 5px 0 var(--board-deep);
  transition: transform 50ms, box-shadow 50ms;
}
.primary:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--board-deep); }
.quiet {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  background: none;
  color: var(--ink);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}
#remove-btn { margin-right: auto; }
.danger { color: #B3261E; }
.danger.armed { padding: 0 16px; border-radius: 12px; background: #B3261E; color: #fff; text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  /* Nothing moves on its own; presses still show by changing shape. */
  *, ::before, ::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  html, body, .toolbar { transition: none; }
  body.editing .pad:not(.pad-add) { animation: none; outline: 3px dashed rgb(255 255 255 / 0.8); outline-offset: 4px; }
  .rec[aria-pressed="true"] .rec-cap { animation: none; }
  .pad.looping { animation: none; }
}

/* ── DJ mode: the keys, like the periodic table ───────────────────────── */

/* The count-in sits over the keys, so the panel is its frame. */
.dj { position: relative; }
.dj {
  --glow: #ffffff;
  --level: 0;
  padding: 14px 12px 18px;
  border-radius: 22px;
  background: var(--bed);
  /* The light show's glow: the color of the last hit, as bright as the sound. */
  box-shadow: inset 0 4px 0 var(--bed-edge), 0 0 calc(var(--level) * 60px) calc(var(--level) * 12px) var(--glow);
  transition: box-shadow 80ms linear;
}
.dj[hidden] { display: none; }
/* Settings' Keyboard: a key per layout on the white sheet; a picker when
   they don't fit (lines.js). */
.set-layout { display: flex; align-items: center; gap: 12px; color: var(--ink); font-weight: 800; }
.set-layout .set-keys { display: flex; flex: 1 0 auto; border-color: rgb(20 19 24 / 0.3); }
.set-layout .set-keys button { flex: 1 0 auto; color: var(--ink); }
/* How to record: Freestyle or Beat Builder. */
.dj-modes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.dj-modes .seq-tool { flex: 1 1 auto; }
/* Beat Builder's beat bar: the open beat's name, ✏️, New and Open. */
.dj-beatbar[hidden] { display: none; }
/* The beat's shape, set before Record: tempo, bars, time signature, on
   Record's line (the group is only for screen readers). Record, then the
   tempo, which gives way first (it shrinks, then turns into ⌄ ⌃); then the
   bars · time signature give way as on Beats (lines.js). On a phone the
   bars · time signature take a line of their own under Record and the tempo.
   While recording, what is happening sits in between. */
.dj-setup { display: contents; }
.dj-bar .dj-rec { flex: none; }
.dj-bar .dj-status { order: 1; }
.dj-bar .dj-status:empty { display: none; }   /* takes no room until there is something to say */
/* Its keys start at its left edge, so an overflow runs right, where lines.js measures it. */
.dj-bar .dj-shape { order: 2; display: flex; flex: 0 1 auto; flex-wrap: nowrap; gap: 12px; min-width: 0; margin-left: auto; }
@media (min-width: 601px) { .dj-bar.deck { flex-wrap: nowrap; } }   /* beats .dj-bar's wrap below */
@media (max-width: 900px) { .dj-bar .dj-rec { min-width: 0; padding: 0 16px; } }
.dj-bar #dj-takes-open { order: 3; flex: none; margin-left: auto; }
/* Tempo as a slider, like Beats and the click track, filling the room
   between Record and the bars. It gives way first: it shrinks, then turns
   into ⌄ ⌃ chevrons (see .tempo-box), before anything else wraps. */
.dj-tempo { display: flex; flex: 1 1 8.5rem; align-items: center; gap: 10px; min-width: 8.5rem; min-height: 52px; max-width: 26rem; }
.dj-tempo input { flex: 1 1 auto; min-width: 0; min-height: 44px; accent-color: var(--led); }
.dj-tempo input:disabled { opacity: 0.45; }
.dj-tempo output { flex: none; min-width: 4.6em; text-align: right; color: #fff; font-weight: 800; white-space: nowrap; font-variant-numeric: tabular-nums; }
.dj-setup button:disabled { opacity: 0.45; }
/* A phone: Record and the tempo share the first line, then the bars and
   time signature share the next, filling it. */
@media (max-width: 600px) {
  .dj-bar .dj-rec { min-width: 0; padding: 0 14px; }
  .dj-bar .dj-shape { flex: 1 1 100%; }
  .dj-bar .dj-shape > .seq-barsel { display: flex; flex: 1 0 auto; }
  .dj-bar .dj-shape .seq-barsel button { flex: 1 0 auto; }
}
/* The beat, small and still, while recording into it: pills fill as hits land. */
.dj-grid { display: grid; gap: 4px; margin: 0 0 12px; padding: 8px; border-radius: 12px; background: rgb(0 0 0 / 0.25); }
.dj-grid[hidden] { display: none; }
.dj-grid-note { margin: 4px 6px; color: rgb(255 255 255 / 0.8); font-weight: 700; }
.dj-grid-row { --c: var(--led); display: grid; grid-template-columns: auto 2.6rem minmax(0, 1fr); align-items: center; gap: 6px; }
.dj-grid-emoji { padding: 0; border: 0; background: transparent; color: inherit; font: 800 0.95rem/1 var(--font-ui); text-align: left; white-space: nowrap; cursor: pointer; }
.dj-grid-emoji:disabled { cursor: default; }
.dj-grid-pills { display: flex; gap: 2px; }
.dj-grid-pills i { cursor: pointer; flex: 1 1 0; min-width: 2px; height: 14px; border-radius: 3px; background: rgb(255 255 255 / 0.13); }
.dj-grid-pills i.beat-start { background: rgb(255 255 255 / 0.22); }
.dj-grid-pills i.on { background: var(--c); }
.dj-grid-pills i.loud { box-shadow: inset 0 0 0 2px #fff; }
.dj-grid-pills i.now { outline: 2px solid #fff; outline-offset: 0; }
/* The DJ bar: Record (Stop while recording), what is happening, Takes. */
.dj-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.dj-bar .dj-status { flex: 1 1 8em; }
.dj-rec {
  min-height: 52px;
  min-width: 120px;
  padding: 0 18px;
  border: 0;
  border-radius: 12px;
  background: var(--chalk);
  color: var(--ink);
  font: 800 1.1rem/1 var(--font-ui);
  box-shadow: 0 5px 0 var(--chalk-edge);
}
.dj-rec.recording { background: #D93A2B; color: #fff; box-shadow: 0 5px 0 #8A1512; }
.dj-status { flex: 1 1 auto; min-width: 0; font-weight: 800; font-variant-numeric: tabular-nums; }
.dj-done { margin: 0 0 12px; }
.dj-done { flex-wrap: wrap; }
.bar-close { flex: none; width: 44px; min-height: 44px; }
.dj-take-line { display: flex; flex: 1 1 auto; align-items: center; gap: 6px; min-width: 0; font-weight: 800; }
.dj-take-line[hidden] { display: none; }
.take-rename { flex: 0 1 auto; width: auto; min-width: 4ch; max-width: 14em; font-size: 1rem; field-sizing: content; }   /* as wide as the name (older browsers: dj.js fitTakeName sets size) */
.dj-done-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
/* A take's name is a text field, so tapping it renames the take. */
.take { grid-template-columns: 1fr auto auto auto; }
.take-name { min-height: 40px; min-width: 0; width: 100%; padding: 0 8px; border: 2px solid transparent; border-radius: 8px; background: transparent; color: var(--ink); font: 800 1rem/1 var(--font-ui); }
.take-name:focus, .take-name:hover { border-color: var(--board); background: #fff; }
.take .lib-info { padding-left: 10px; }
/* "Sound saved", fading in over a take's name and away again. */
.take .lib-text, .dj-take-line { position: relative; }
.saved-note {
  position: absolute; inset: 0; display: flex; align-items: center; padding: 0 10px;
  border-radius: 8px; background: #2E7D32; color: #fff; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none; animation: saved-note 2.6s ease forwards;
}
@keyframes saved-note { 0% { opacity: 0; } 10%, 70% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .saved-note { animation: none; } }   /* lines up with the name inside its field (2px border + 8px padding) */
.dj-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.dj-tabs button {
  flex: 1 1 0;
  min-height: 44px;
  border: 2px solid rgb(255 255 255 / 0.4);
  border-radius: 12px;
  background: transparent;
  color: #fff;
  font-size: 1.1rem;
}
.dj-tabs button[aria-pressed="true"] { background: var(--chalk); border-color: var(--chalk); }
.dj-keys { display: grid; gap: 8px; }
/* A phone shows one row of ten, as two lines of five big tiles. */
.dj-row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.dj-row:not(.shown) { display: none; }
@media (min-width: 560px) {
  .dj-tabs { display: none; }
  .dj-row, .dj-row:not(.shown) { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 6px; }
}
/* Wide enough for a keyboard's stagger: each row starts a little further in. */
@media (min-width: 900px) {
  .dj-keys { --key: calc((100% - 9 * 6px) / 10.75); }
  .dj-row { grid-template-columns: repeat(10, var(--key)); }
  .dj-row[data-row="1"] { padding-left: calc(var(--key) * 0.25); }
  .dj-row[data-row="2"] { padding-left: calc(var(--key) * 0.75); }
}
/* One key: an element tile. Letter top left (like a symbol), emoji top right,
   the sound's name, and its family small at the bottom. */
.dj-key {
  --c: #333040;
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto 1fr auto auto;
  grid-template-areas: "sym emoji" ". ." "name name" "fam fam";
  aspect-ratio: 1;
  min-width: 0;
  min-height: 44px;
  padding: 6px;
  border: 0;
  border-radius: 10px;
  background: var(--c);
  color: #fff;
  box-shadow: 0 4px 0 color-mix(in srgb, var(--c) 55%, black);
  text-align: left;
  transition: transform 50ms, box-shadow 50ms;
}
/* Lit: pressed, just hit, or looping. The whole tile brightens and glows. */
.dj-key.down, .dj-key.hit { filter: brightness(1.45) saturate(1.2); box-shadow: 0 0 18px 4px var(--c), 0 1px 0 color-mix(in srgb, var(--c) 55%, black); }
.dj-key.looping { animation: dj-pulse 0.9s ease-in-out infinite alternate; }
@keyframes dj-pulse { from { filter: brightness(1.1); box-shadow: 0 0 6px 1px var(--c); } to { filter: brightness(1.5); box-shadow: 0 0 20px 5px var(--c); } }
@media (prefers-reduced-motion: reduce) { .dj-key.looping { animation: none; filter: brightness(1.35); } }
.dj-key:active, .dj-key.hit { transform: translateY(3px); box-shadow: 0 1px 0 color-mix(in srgb, var(--c) 55%, black); }
.dj-key.empty { background: transparent; box-shadow: none; outline: 2px dashed rgb(255 255 255 / 0.3); outline-offset: -2px; }
.dj-sym { grid-area: sym; font: 800 1.35rem/1 var(--font-display); }
.dj-sym[hidden] { display: none; }
.dj-emoji { grid-area: emoji; font-size: 1.3rem; line-height: 1; }
.dj-name { grid-area: name; font: 800 0.8rem/1.1 var(--font-ui); }
/* On a phone or tablet (no keyboard in sight), the keys are a plain grid of
   pads that fits the screen; the kid picks the pad size. */
.dj-keys.pads-mode { --tile: 84px; grid-template-columns: repeat(auto-fill, minmax(var(--tile), 1fr)); gap: 8px; }
.dj-keys.pads-mode[data-size="s"] { --tile: 62px; }
.dj-keys.pads-mode[data-size="l"] { --tile: 112px; }
.dj-keys.pads-mode .dj-row, .dj-keys.pads-mode .dj-row:not(.shown) { display: contents; }
.dj-keys.pads-mode .dj-key { aspect-ratio: 1; min-height: 0; padding: 6px; }
.dj-keys.pads-mode[data-size="l"] .dj-emoji { font-size: 1.7rem; }
.dj-keys.pads-mode[data-size="l"] .dj-name { font-size: 0.95rem; }
.dj-tabs[hidden], .dj-size[hidden] { display: none; }
.dj-size button { min-width: 44px; }
/* A legend for the key colors, like the periodic table's. */
.dj-change-row { grid-area: change; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.dj-keys.changing .dj-key { animation: wobble 0.34s ease-in-out infinite alternate; }
.dj-keys.changing .dj-key:nth-child(even) { animation-delay: -0.17s; }
@media (prefers-reduced-motion: reduce) { .dj-keys.changing .dj-key { animation: none; outline: 3px dashed rgb(255 255 255 / 0.8); outline-offset: -3px; } }
/* The last line: the key colors, and the click opposite them. */
/* Under the keys: the pad size and ✏️ Change keys, then the key colors and
   ⏲️ Click track, in two columns (left and right). On a phone each gets a
   full line: the colors, then Change keys, then the click's tempo with
   Click track at its right (the tempo's room kept while the click is off). */
.dj-tail { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "size change" "legend click"; align-items: center; gap: 16px 20px; margin-top: 16px; }
.dj-foot, .dj-end { display: contents; }
.dj-size { grid-area: size; justify-self: start; }
.dj-legend { grid-area: legend; }
/* Right-aligned like ✏️ Change keys above it, with or without its tempo. */
.dj-clicktrack { grid-area: click; display: flex; align-items: center; justify-content: flex-end; gap: 12px; width: min(20rem, 45cqi); min-width: 0; }
.dj-clicktrack #dj-click { flex: none; }
.dj-click-tempo { display: flex; flex: 1 1 12rem; align-items: center; gap: 10px; min-width: 0; }
.dj-click-tempo.off { visibility: hidden; }
.dj-click-tempo input { flex: 1 1 auto; min-width: 0; min-height: 44px; accent-color: var(--led); }
.dj-click-tempo output { flex: none; min-width: 4.6em; text-align: right; color: #fff; font-weight: 800; line-height: 1; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* A tempo slider with its number (Beat Builder, the click track). Where its
   room gets too short for a useful slider, ⌄ ⌃ chevrons stand in for it and
   the number sits over BPM: decided by the box's own width, not the screen's. */
.tempo-box { container: tempo / inline-size; }
.tempo-step { display: none; flex: none; place-items: center; width: 44px; min-height: 44px; padding: 0; border: 2px solid rgb(255 255 255 / 0.6); border-radius: 10px; background: transparent; color: #fff; font-size: 0; }
/* Drawn, and pinned to the middle of the key, so it sits dead center
   whatever the font or a phone's minimum text size. The button has no text
   (its aria-label names it). The nudge centers the V's ink, not its box. */
.tempo-step { position: relative; }
.tempo-step::before { content: ""; position: absolute; inset: 0; width: 10px; height: 10px; margin: auto; border-right: 3px solid currentColor; border-bottom: 3px solid currentColor; box-sizing: content-box; transform: translateY(-4px) rotate(45deg); }
.tempo-step.up::before { transform: translateY(4px) rotate(-135deg); }
@container tempo (max-width: 15rem) {
  .tempo-box input[type="range"] { display: none; }
  .tempo-box .seq-tempo-word { display: none; }   /* the chevrons say it; the slider keeps its name */
  .tempo-step { display: grid; }
  /* ⌄ number ⌃ hug each other, the three together centered in the room. */
  /* Snug: 4 px from the number (a container query can't change the box's own gap). */
  .tempo-box .tempo-step.down { margin-left: auto; margin-right: -4px; }
  .tempo-box .tempo-step.up { margin-right: auto; margin-left: -4px; }
  .tempo-box output, .tempo-box .seq-bpm-num { flex: none; min-width: 44px; max-width: 3em; margin: 0; white-space: normal; line-height: 1.1; text-align: center; }
}
@container panel (max-width: 30rem) {
  .dj-tail { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "legend legend" "change change" "tempo click"; gap: 12px; }
  .dj-tail:has(> .dj-foot > .dj-size:not([hidden])) { grid-template-areas: "size size" "legend legend" "change change" "tempo click"; }
  .dj-clicktrack { display: contents; }
  .dj-clicktrack #dj-click { grid-area: click; }
  .dj-click-tempo { grid-area: tempo; }
  .dj-change-row > .seq-tool { flex: 1 1 auto; }
}
/* Too narrow for the four colors on one line: two and two, never three and one. */
@container panel (max-width: 21rem) {
  .dj-tail .dj-legend { display: grid; grid-template-columns: repeat(2, max-content); column-gap: 24px; }
}
.dj-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 0; padding: 0; list-style: none; font-size: 0.85rem; font-weight: 700; }
.dj-legend li { display: flex; align-items: center; gap: 6px; }
.dj-legend li::before { content: ""; width: 14px; height: 14px; border-radius: 4px; background: var(--c); }
@media (max-width: 559px) {
  .dj-fam { display: none; }
  .dj-key { aspect-ratio: auto; min-height: 66px; padding: 5px; }
  .dj-name { font-size: 0.76rem; font-stretch: 75%; line-height: 1.05; }
}
@media (max-width: 360px) { .dj-tabs button { font-size: 0.9rem; letter-spacing: -0.1em; } }
.dj-fam { grid-area: fam; overflow: hidden; font: 700 0.62rem/1.2 var(--font-ui); text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.8; white-space: nowrap; }
@media (min-width: 560px) and (max-width: 899px) { .dj-fam { display: none; } .dj-emoji { font-size: 1.05rem; } .dj-sym { font-size: 1.05rem; } .dj-name { font-size: 0.76rem; font-stretch: 75%; line-height: 1.05; } }

/* ── Help (❓): a picture reference, one tab per part of the app ────── */

/* The same paper sheet as the other dialogs: centred on wide screens, a
   bottom sheet on phones. The title and tabs stay put while it scrolls. */
dialog#help {
  width: min(600px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  border-radius: 24px;
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--paper);
  color: var(--ink);
}
dialog#help::backdrop { background: rgb(20 19 24 / 0.62); }
dialog#help :focus-visible { outline-color: var(--board); }
@media (max-width: 600px) {
  dialog#help { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: 24px 24px 0 0; }
}
.help-head { position: sticky; top: 0; z-index: 1; padding: 20px 20px 12px; background: var(--paper); box-shadow: 0 2px 0 var(--line); }
.help-head .sheet-head { margin-bottom: 12px; }
.help-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.help-tab {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 10px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font: 800 0.9rem/1 var(--font-ui);
  white-space: nowrap;
}
/* On a phone, emoji over word (like the toolbar), so all six tabs fit one line. */
@media (max-width: 480px) {
  .help-tabs { flex-wrap: nowrap; gap: 4px; }
  .help-tab { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 52px; padding: 4px 2px; font-size: 0.72rem; letter-spacing: -0.01em; }
  .help-tab span { font-size: 1.15rem; }
}
/* Six tabs at 320 px: a narrower margin keeps each tab 44 px wide. */
@media (max-width: 360px) {
  .help-head { padding-inline: 12px; }
}
.help-tab[aria-pressed="true"] { border-color: var(--board); background: var(--board); color: #fff; }
.help-body { padding: 16px 20px calc(20px + env(safe-area-inset-bottom)); }
.help-list { display: grid; gap: 14px; margin: 0; padding: 0; list-style: none; }
/* A drawing of the control on a piece of the pad bed, its sentence beside it
   (under it on a phone). */
.help-item { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); align-items: center; gap: 14px; }
/* On a phone a small drawing sits beside its sentence, a wide one above it. */
@media (max-width: 480px) {
  .help-item { display: flex; flex-wrap: wrap; gap: 6px 12px; }
  .help-text { flex: 1 1 9rem; }
  .pad.help-pad { width: 72px; }
}
.help-pic { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; justify-self: start; max-width: 100%; padding: 8px; border-radius: 12px; background: var(--bed); color: #fff; }
.help-text { margin: 0; font-weight: 600; line-height: 1.35; }
.help-adv { display: inline-block; margin-right: 6px; padding: 1px 8px; border-radius: 999px; background: var(--chalk); font-size: 0.8rem; font-weight: 800; white-space: nowrap; }
/* The app's own buttons, drawn a little smaller and not pressable. */
.help-btn { display: inline-flex; align-items: center; min-height: 34px; min-width: 0; max-width: 100%; padding: 0 10px; font-size: 0.85rem; white-space: nowrap; cursor: default; box-shadow: none; }
.help-lit { background: var(--led); border-color: var(--led); color: var(--ink); }
.seq-play.help-btn { min-width: 0; box-shadow: 0 3px 0 color-mix(in srgb, var(--led) 50%, black); }
.dj-rec.help-btn { min-width: 0; box-shadow: 0 3px 0 var(--chalk-edge); }
.help-toolbar-btn { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px; border-radius: 10px; background: var(--board); font-weight: 800; box-shadow: 0 3px 0 var(--board-deep); }
.help-toolbar-btn::before { content: ""; width: 12px; height: 12px; border-radius: 3px; background: var(--record); }
.help-mic { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px 0 8px; border-radius: 999px; background: var(--chalk); color: var(--ink); font-weight: 800; }
.help-mic-dot { width: 18px; height: 18px; border-radius: 50%; background: var(--record); }
.pad.help-pad { width: 88px; aspect-ratio: 1 / 0.82; padding: 8px; box-shadow: 0 3px 0 var(--pad-edge); cursor: default; }
.pad.help-pad .pad-emoji { font-size: 1.3rem; }
.pad.help-pad .pad-label { font-size: 0.85rem; }
.help-key { display: inline-grid; justify-items: center; width: 56px; padding: 4px 2px; border-radius: 10px; background: #C2410C; box-shadow: 0 3px 0 color-mix(in srgb, #C2410C 55%, black); line-height: 1.1; }
.help-key b { font: 900 1rem/1 var(--font-display); }
.help-key small { font-size: 0.7rem; font-weight: 800; }
.help-voice { display: inline-flex; align-items: center; min-height: 34px; padding: 0 10px; border-radius: 999px; background: #fff; color: var(--ink); font-size: 0.85rem; font-weight: 800; white-space: nowrap; }
.help-slider { display: inline-flex; align-items: center; gap: 8px; font-weight: 800; font-size: 0.85rem; }
.help-track { position: relative; width: 70px; height: 6px; border-radius: 3px; background: rgb(255 255 255 / 0.3); }
.help-track::after { content: ""; position: absolute; left: 55%; top: -6px; width: 18px; height: 18px; border-radius: 50%; background: var(--led); }
.help-seg { font-size: 0.85rem; font-weight: 800; }
.help-seg span { display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px; white-space: nowrap; }
.help-seg .help-seg-on { background: var(--led); color: var(--ink); }
.help-pills { --pill: #FFD60A; display: inline-grid; grid-auto-flow: column; grid-auto-columns: 18px; gap: 4px; padding: 4px; border-radius: 10px; background: rgb(255 255 255 / 0.06); }
.help-pill { height: 34px; border-radius: 999px; background: rgb(255 255 255 / 0.13); }
.help-pill.one { background: rgb(255 255 255 / 0.26) radial-gradient(circle, rgb(255 255 255 / 0.75) 3px, transparent 3.5px) center / 100% 100% no-repeat; }
.help-pill.on { background: var(--pill); box-shadow: 0 2px 0 color-mix(in srgb, var(--pill) 55%, black); }
.help-pill.loud { box-shadow: inset 0 0 0 3px rgb(255 255 255 / 0.9), 0 2px 0 color-mix(in srgb, var(--pill) 55%, black); }
.help-word { font-weight: 800; white-space: nowrap; }
.person-menu-btn.help-person { width: 40px; height: 40px; font-size: 1.1rem; }
.help-count { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--count); color: var(--ink); font: 900 1.4rem/1 var(--font-display); box-shadow: 0 0 0 3px rgb(0 0 0 / 0.25); }

/* Beat Builder's count-in: a big number on a disc of its color, over the
   keys, popping in on each beat; then a red GO!. Taps still reach the keys. */
.dj-count {
  position: absolute;
  z-index: 8;
  top: 46%;
  left: 50%;
  display: grid;
  place-items: center;
  width: min(42vw, 220px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--count, var(--led));
  color: var(--ink);
  font: 900 clamp(4rem, 18vw, 8rem)/1 var(--font-display);
  box-shadow: 0 0 0 8px rgb(0 0 0 / 0.25), 0 0 60px var(--count, var(--led));
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.dj-count[hidden] { display: none; }
.dj-count.go { color: #fff; font-size: clamp(2.6rem, 11vw, 5rem); }
.dj-count.pop { animation: count-pop 0.35s ease-out; }
@keyframes count-pop { from { transform: translate(-50%, -50%) scale(0.6); opacity: 0.4; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dj-count.pop { animation: none; } }

/* The narrowest phones: a slimmer ▶ Play, so ⌄ number ⌃ and ⏲️ fit beside it. */
@media (max-width: 340px) { .seq-top .seq-play { width: 4rem; padding: 0 4px; font-size: 0.95rem; } }

/* Pills answer the first tap on a phone (no double-tap zoom wait), and a
   hold makes a loud hit without the phone's text-select or callout menu. */
.pill, .dj-grid-pills i { touch-action: manipulation; -webkit-touch-callout: none; user-select: none; -webkit-user-select: none; }

/* Beat Builder: a row's ✕, beside its emoji and as small (Ben's call over the
   44 px rule); asked, it goes red and reads ✕?. */
.dj-grid-x { flex: none; padding: 0 4px; border: 0; border-radius: 6px; background: transparent; color: rgb(255 255 255 / 0.6); font: 800 0.95rem/1.2 var(--font-ui); cursor: pointer; }
.dj-grid-x:hover { color: #fff; }
.dj-grid-x.armed { background: #B3261E; color: #fff; }

/* A notice fading away by itself (ui.js fadeAway). */
.fading { opacity: 0; transition: opacity 0.6s ease; }
@media (prefers-reduced-motion: reduce) { .fading { transition: none; } }

/* The picture chooser: a grid of emoji keys; the sound's own is lit, one
   tapped while taken is red until tapped again. */
dialog#pictures { width: min(520px, calc(100vw - 24px)); }
.pictures-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(48px, 1fr)); gap: 6px; margin-top: 8px; }
.pictures-grid button { min-height: 48px; border: 2px solid transparent; border-radius: 10px; background: var(--chalk); font-size: 1.6rem; line-height: 1; cursor: pointer; }
.pictures-grid button[aria-pressed="true"] { border-color: var(--board); }
.pictures-grid button.armed { border-color: #B3261E; background: #fbe3e1; }

/* 🥁 Beat · 🎼 Song: Beats' two modes (Advanced), styled like DJ's, above the panel. */
.beats-modes { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.beats-modes .seq-tool { flex: 1 1 auto; }
.beats-modes[hidden] { display: none; }

/* ── Cloud profiles (cloud-ui.js): People rows, the ☁️ sheet, the list, the PIN pad ── */

dialog.np-dialog {
  width: min(560px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 0;
  border-radius: 24px;
  background: var(--paper);
  color: var(--ink);
}
dialog.np-dialog::backdrop { background: rgb(20 19 24 / 0.62); }
dialog.np-dialog :focus-visible { outline-color: var(--board); }
@media (max-width: 600px) {
  dialog.np-dialog { width: 100%; max-width: 100%; margin: auto 0 0; border-radius: 24px 24px 0 0; }
}

/* A People row: picture, made-up name, 🎲 and ☁️ on one line; colors; delete. */
.pe-top { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.pe-row .pe-name {
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: 0;
  background: none;
  color: #fff;
  font: 800 1.15rem/1.15 var(--font-ui);
  overflow-wrap: anywhere;
}
.pe-avatar, .pe-tool {
  flex: none;
  display: grid;
  place-items: center;
  min-width: 48px;
  min-height: 48px;
  padding: 0 6px;
  border: 2px solid rgb(255 255 255 / 0.85);
  border-radius: 14px;
  background: rgb(255 255 255 / 0.16);
  color: #fff;
  font-size: 1.3rem;
}
.pe-avatar { border-radius: 50%; padding: 0; }
.pe-badge, .cl-badge {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--c);
  color: #fff;
  font: 900 1.25rem/1 var(--font-display);
}
.pe-tool[hidden] { display: none; }

/* The ☁️ sheet and its lists. */
.cl-avatar { display: inline-block; vertical-align: middle; }
.cl-status { min-height: 1.4em; }
.cl-wide { width: 100%; }
.cl-head { margin: 18px 0 6px; font: 800 1.05rem/1.2 var(--font-ui); }
.cl-list { display: grid; gap: 8px; margin: 0 0 12px; padding: 0; list-style: none; }
.cl-item { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.cl-gift { padding: 8px 10px; border-radius: 12px; background: var(--chalk); }
.cl-text { flex: 1 1 10rem; min-width: 0; font-weight: 800; overflow-wrap: anywhere; }
.cl-pick {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 6px 12px;
  border: 2px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  color: var(--ink);
  font-weight: 800;
  text-align: left;
}
.cl-lock { margin-left: auto; }
.cl-what { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0 0 12px; }
.cl-what[hidden] { display: none; }
.cl-kind { min-height: 48px; padding: 0 8px; border: 2px solid var(--line); border-radius: 12px; background: var(--paper); color: var(--ink); font-weight: 800; }
.cl-kind[aria-pressed="true"] { border-color: var(--board); background: var(--board); color: #fff; }
dialog.np-dialog .set-buttons .quiet { justify-content: center; }

/* The PIN pad: four dots, then big number keys. */
.pin-body { max-width: 360px; margin: 0 auto; }
.pin-dots { display: flex; justify-content: center; gap: 16px; margin: 8px 0; }
.pin-dots span { width: 22px; height: 22px; border: 3px solid var(--ink); border-radius: 50%; }
.pin-dots span.on { background: var(--ink); }
.pin-note { text-align: center; }
.pin-keys { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.pin-key {
  min-height: 64px;
  border: 0;
  border-radius: 16px;
  background: var(--chalk);
  color: var(--ink);
  font: 900 1.6rem/1 var(--font-display);
}
.pin-key:active { background: var(--line); }
.pin-key[data-key="0"] { grid-column: 2; }

/* ⚙️ Settings → ☁️ Cloud. */
.set-private { margin: 0 0 12px; padding: 10px 14px; border: 2px solid var(--line); border-radius: 14px; background: var(--chalk); }
.set-private summary { min-height: 44px; display: flex; align-items: center; font-weight: 800; cursor: pointer; }
.set-private-list { margin: 4px 0 0; padding-left: 1.2em; }
.set-private-list li { margin: 0 0 6px; }
.set-sub { margin: 16px 0 4px; font: 800 1rem/1.2 var(--font-ui); }
.set-field {
  min-width: 0;
  min-height: 44px;
  padding: 0 12px;
  border: 2px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  font: 700 1rem/1 var(--font-ui);
}
.set-reveal { margin: 10px 0 0; padding: 10px 14px; border: 3px dashed var(--board); border-radius: 14px; }
.set-reveal p { margin: 0 0 6px; }
.set-big { font: 800 1.2rem/1.3 ui-monospace, Menlo, Consolas, monospace; letter-spacing: 0.06em; overflow-wrap: anywhere; }
