/* Singing Coach — live view and recordings library.
   Visual system lifted from the Singing Coach AI brand screens in Figma (Levy Street Projects,
   page "Singing Coach AI Brand"): a flat #fbfbfb canvas, white cards with a light 2px border and
   12px corners, Paytone One for anything that carries weight and Epilogue Medium for the rest.
   Colour does the talking: brand blue for the primary action and every active state, red for the
   secondary action and low scores, green for good scores. There is no yellow anywhere. */

/* The ink outline plus a hard, blur-free shadow is the brand's ONE signature for "you can press
   this": full-width CTAs, round icon buttons, the active tab icon. Cards, tiles, chips, inputs and
   dividers all use the light border with no shadow, so the outline keeps meaning exactly one thing. */
:root {
  --ink:#0d0d0d; --shadow-ink:#171717;
  --canvas:#fbfbfb; --white:#fff; --surface:#f7f7f7;
  --border:#e7e7e7; --border-2:#dbdbdb; --divider:#e7e7e7;
  --text-2:#4c4c4c; --muted:#919191; --placeholder:#baadad; --disabled:#bdbdbd;

  --blue:#00b6fe; --blue-600:#008fc8; --blue-400:#7bd9ff; --blue-300:#bfedff;
  --blue-200:#dbf5ff; --blue-100:#e9f9ff; --blue-50:#f2fbff;
  --blue-ink:#005b7f; --blue-ink-2:#00425c;     /* text on the light and mid blue chips */
  --red:#fe3144; --red-400:#ff4a5b; --red-200:#ffb5bb;
  --green:#3bb44c; --green-400:#53bd62; --green-300:#8ec696;
  --orange:#ff6708; --orange-400:#ff904b;

  --r-card:12px; --r-ctl:8px; --r-pill:999px;
  --shadow:2px 4px 0 var(--shadow-ink);      /* primary pressables */
  --shadow-sm:1px 2px 0 var(--shadow-ink);   /* compact pressables: round icon buttons, small buttons */
  --stagepad-x:16px;   /* the singing pane's side padding; the dock bleeds exactly this far */
  --stagepad-b:16px;   /* the singing pane's own bottom padding, which the dock bleeds over */
  --display:"Paytone One", ui-rounded, system-ui, sans-serif;
  --sans:"Epilogue", ui-sans-serif, system-ui, -apple-system, sans-serif;
  /* the arrow every full-width CTA carries on its right, drawn in the button's own text colour */
  --arrow:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15M13 6l6 6-6 6'/%3E%3C/svg%3E");
  color-scheme: light;
}

* { box-sizing:border-box; }
[hidden] { display:none !important; }
html, body { height:100%; }
body {
  overflow-x:hidden;
  margin:0; background:var(--canvas); color:var(--ink);
  font-family:var(--sans); font-size:14px; font-weight:500; line-height:1.5;
  -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; overflow:hidden;
}
h1, h2, h3, h4 { margin:0; font-family:var(--display); font-weight:400; letter-spacing:0; }
p { margin:0; }
button { font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
input { font:inherit; color:inherit; }
img { max-width:100%; }
::placeholder { color:var(--placeholder); opacity:1; }

/* Small labels are sentence case in the brand, never tracked capitals. */
.card-label { font-size:14px; font-weight:500; color:var(--text-2); }

/* ------------------------------------------------------------ small parts */
.icon-btn {
  width:40px; height:40px; flex:none; display:grid; place-items:center;
  border:2px solid var(--ink); border-radius:50%; background:var(--white);
  box-shadow:var(--shadow-sm); transition:transform .1s, box-shadow .1s, background .12s;
}
.icon-btn svg { width:20px; height:20px; fill:none; stroke:var(--ink); stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round; }
.icon-btn:active { transform:translate(1px,2px); box-shadow:none; }
#del-take:hover { background:var(--red-200); }

/* --------------------------------------------------------------- buttons */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:44px; padding:8px 20px; border:2px solid var(--ink); border-radius:var(--r-ctl);
  font-family:var(--display); font-size:15px; line-height:1.2; color:var(--ink);
  background:var(--white); box-shadow:var(--shadow); transition:transform .1s, box-shadow .1s;
  white-space:nowrap;
}
.btn:active { transform:translate(2px,4px); box-shadow:none; }
.btn-blue { background:var(--blue); color:var(--white); }
.btn-danger { background:var(--red); color:var(--white); }
.btn-sm { min-height:36px; padding:6px 14px; font-size:14px; box-shadow:var(--shadow-sm); }
.btn-sm:active { transform:translate(1px,2px); }
.btn:disabled { opacity:.5; cursor:default; }
.btn-ico { width:20px; height:20px; flex:none; }

/* Segmented choices are a row of separate pills: the chosen one fills brand blue. */
.seg { display:inline-flex; flex-wrap:wrap; gap:6px; }
.seg button {
  min-height:32px; padding:4px 11px; border:2px solid var(--border); border-radius:var(--r-pill);
  background:var(--white); font-size:14px; font-weight:500; color:var(--ink);
  transition:background .12s, border-color .12s, color .12s;
}
.seg button.on { background:var(--blue); border-color:var(--blue); color:var(--white); }

/* Legend chips: off is an outlined pill, on fills with that series' own colour. */
.pill {
  display:inline-flex; align-items:center; gap:6px; min-height:32px; padding:4px 12px;
  border:2px solid var(--border); border-radius:var(--r-pill); background:var(--white);
  font-size:14px; font-weight:500; color:var(--text-2);
  transition:background .12s, border-color .12s, color .12s, transform .1s;
}
.pill:active { transform:translateY(1px); }
.pill .sw { width:8px; height:8px; border-radius:50%; background:var(--border-2); flex:none; }
.pill .sw-recent { background:var(--blue-400); }
.pill .sw-comb { background:var(--orange-400); }
.pill .sw-whole { background:var(--green-400); }
.pill.on { color:var(--ink); border-color:transparent; }
.pill.on .sw { background:var(--ink); opacity:.6; }
.pill.on[data-k="recent"] { background:var(--blue-400); color:var(--blue-ink-2); }
.pill.on[data-k="combined"] { background:var(--orange-400); }
.pill.on[data-k="whole"] { background:var(--green-400); color:var(--white); }
.pill.on[data-k="whole"] .sw { background:var(--white); opacity:.9; }

/* --------------------------------------------------------------- layout */
main {
  flex:1; min-height:0;
  display:grid; grid-template-columns:minmax(268px, 320px) 1fr;
}

/* -------------------------------------------------------------- library */
/* The brand's Recordings screen: a title, one full-width blue CTA, then a stack of white cards
   on the plain canvas. */
.library {
  display:flex; flex-direction:column; min-height:0;
  background:var(--canvas); border-right:2px solid var(--border);
}
.lib-head {
  flex:none; display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:12px;
  padding:16px 16px 8px;
}
.lib-head h2 { font-size:18px; line-height:22px; }
.lib-head .btn { flex-basis:100%; }
.lib-list { flex:1; min-height:0; overflow-y:auto; padding:8px 16px 16px; display:grid; gap:8px;
  align-content:start; }

/* The brand's recording card: a header (avatar, name, date, score badge with the take length under
   it), a divider, then a row of the take's own numbers coloured by band. */
.take {
  display:flex; flex-direction:column; gap:12px;
  width:100%; text-align:left; padding:16px;
  border:2px solid var(--border); border-radius:var(--r-card); background:var(--white);
  transition:background .12s, border-color .12s, transform .1s;
}
.take:hover { background:var(--surface); }
.take:active { transform:translateY(1px); }
.take[aria-current="true"] { background:var(--blue-50); border-color:var(--blue); }
.take-top { display:grid; grid-template-columns:40px 1fr auto; align-items:center; gap:12px; }
.take-bird { width:40px; height:40px; border-radius:50%; background:var(--blue-200); object-fit:cover; }
.take-who { min-width:0; }
.take-name { display:flex; align-items:center; gap:6px;
  font-family:var(--display); font-weight:400; font-size:14px; line-height:1.3; }
.take-name .txt { min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* A real per-take status, standing in for the brand card's chip row. */
.take-flag { flex:none; padding:2px 8px; border-radius:var(--r-pill);
  background:var(--blue-300); color:var(--blue-ink);
  font-family:var(--sans); font-weight:600; font-size:14px; }
.take-sub { display:block; font-size:14px; color:var(--text-2); line-height:1.4; margin-top:2px; }
.take-side { display:flex; flex-direction:column; align-items:center; gap:3px; }
/* The score is a round badge coloured by band, as on the brand's recording cards. */
.take-score {
  width:40px; height:40px; display:grid; place-items:center;
  border-radius:50%; background:var(--blue); color:var(--white);
  font-family:var(--display); font-size:14px; line-height:1; font-variant-numeric:tabular-nums;
}
.take-score.band-low { background:var(--red-400); }
.take-score.band-mid { background:var(--blue-400); color:var(--blue-ink-2); }
.take-score.band-good { background:var(--blue); }
.take-score.band-high { background:var(--green); }
.take-score.band-none { background:var(--surface); color:var(--muted); }
.take-dur { font-size:14px; font-weight:500; color:var(--text-2); font-variant-numeric:tabular-nums; }
/* Lower tier: the divider, then the chip row and the take's own numbers, as on the brand card. */
.take-body { display:flex; flex-direction:column; gap:12px; padding-top:12px; border-top:1px solid var(--border); }
.take-tags { display:flex; flex-wrap:wrap; gap:6px; }
.take-tag {
  padding:3px 12px; border-radius:var(--r-pill);
  background:var(--blue-300); color:var(--blue-ink);
  font-family:var(--sans); font-weight:500; font-size:14px; line-height:1.3;
}
.take-tag:nth-child(2n) { background:var(--blue-400); color:var(--blue-ink-2); }
.take-metrics { display:grid; grid-template-columns:repeat(3, 1fr); gap:8px; }
.take-metric { display:flex; flex-direction:column; gap:3px; }
.take-metric small { font-size:14px; font-weight:500; color:var(--text-2); }
.take-metric b { font-family:var(--display); font-weight:400; font-size:15px; color:var(--ink);
  font-variant-numeric:tabular-nums; }
.take-metric b.band-low { color:var(--red); }
.take-metric b.band-mid { color:var(--blue-600); }
.take-metric b.band-good { color:var(--blue); }
.take-metric b.band-high { color:var(--green); }

.lib-empty { padding:24px 20px; text-align:center; color:var(--text-2); display:none; }
.lib-empty.on { display:block; }
.lib-empty img { width:104px; height:104px; margin-bottom:8px; }
.lib-empty p { font-family:var(--display); font-size:16px; color:var(--ink); }
.lib-empty .sub { font-family:var(--sans); font-weight:500; font-size:14px; color:var(--text-2); margin-top:4px; }

/* ---------------------------------------------------------------- stage */
.stage {
  min-height:0; min-width:0; display:flex; flex-direction:column; gap:8px;
  padding:16px var(--stagepad-x) var(--stagepad-b);
  overflow-y:auto;
}

.stage-head { flex:none; display:flex; align-items:center; gap:12px; }
.stage-title { min-width:0; flex:1; }
/* Had no rule at all, so the two buttons were block-flowing and stacking on top of each other.
   One row, pinned to the end, sized to its contents. */
.stage-actions { flex:none; display:flex; align-items:center; gap:8px; margin-left:auto; }
.stage-actions .icon-btn { width:44px; height:44px; flex:none; }
/* Share is the primary action on a take: the brand's blue round icon button. Delete stays white. */
#share-open { background:var(--blue); box-shadow:var(--shadow); }
#share-open svg { stroke:var(--white); }
#share-open:active { transform:translate(2px,4px); box-shadow:none; }
#share-open[aria-expanded="true"] { background:var(--blue-600); }
.stage-bird {
  width:48px; height:48px; flex:none; border-radius:50%;
  background:var(--blue-100); object-fit:cover;
}
/* The take name edits in place under a blue underline, like the brand's title field. */
.title-input {
  display:block; width:100%; max-width:520px; padding:2px 0; margin:0;
  font-family:var(--display); font-size:18px; line-height:22px; color:var(--ink);
  background:transparent; border:0; border-bottom:2px solid transparent; border-radius:0;
  overflow:hidden; text-overflow:ellipsis; transition:border-color .12s;
}
.title-input:not(:disabled):hover { border-bottom-color:var(--border); }
.title-input:focus { border-bottom-color:var(--blue); outline:none; }
.title-input:disabled { color:var(--ink); opacity:1; }
.stage-meta { font-size:14px; color:var(--muted); font-weight:500; }

/* readout ---------------------------------------------------------------- */
.readout { flex:none; display:grid; grid-template-columns:minmax(200px,240px) 1fr; gap:8px; }
.card {
  border:2px solid var(--border); border-radius:var(--r-card); background:var(--white);
}
.score-card { padding:16px; }
/* The band colours the number, not the card: white cards, coloured figures, as in the brand. */
.score-big {
  font-family:var(--display); font-size:44px; line-height:1; letter-spacing:-.02em;
  margin:4px 0 2px; color:var(--ink); font-variant-numeric:tabular-nums;
}
.score-card.band-low .score-big { color:var(--red); }
.score-card.band-mid .score-big { color:var(--blue-600); }
.score-card.band-good .score-big { color:var(--blue); }
.score-card.band-high .score-big { color:var(--green); }
.score-big.waiting { color:var(--disabled); font-size:34px; }
.card-sub { font-size:14px; color:var(--text-2); font-weight:500; }

.tiles { display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:8px; }
.tile {
  padding:12px; border:2px solid var(--border); border-radius:var(--r-ctl); background:var(--white);
  display:flex; flex-direction:column; justify-content:center;
}
.tile-val { font-family:var(--display); font-size:20px; line-height:1.1; margin-top:4px;
  font-variant-numeric:tabular-nums; }
.tile-at { font-size:14px; color:var(--text-2); font-weight:500; }
.tile.best .tile-val { color:var(--green); }
.tile.worst .tile-val { color:var(--red); }

/* chart ------------------------------------------------------------------ */
.chart-card {
  align-self:stretch; width:100%;   /* never shrink-to-fit; it is a full-width panel */
  flex:1; min-height:170px; display:flex; flex-direction:column; padding:12px 16px 8px;
  overflow:hidden;
}
.chart-top { flex:none; display:flex; align-items:center; justify-content:space-between;
  gap:8px; flex-wrap:wrap; margin-bottom:8px; }
.series { display:flex; gap:6px; flex-wrap:wrap; }
.chart { flex:1; min-height:0; }
.chart svg { display:block; width:100%; height:100%; touch-action:pan-y; cursor:crosshair; }

/* Light grid, no heavy axis, thin coloured lines: the brand's performance chart. */
.gridline { stroke:var(--border); stroke-width:1; }
.axis-line { stroke:var(--border-2); stroke-width:2; }
.tick { font-family:var(--sans); font-size:14px; font-weight:500; fill:var(--text-2); }
.curve { fill:none; stroke:var(--blue); stroke-width:2.5; stroke-linejoin:round; stroke-linecap:round; }
.curve-ramp { fill:none; stroke:var(--blue-400); stroke-width:2; stroke-dasharray:5 4;
  stroke-linejoin:round; stroke-linecap:round; }
.curve-noisy { fill:none; stroke:var(--blue-400); stroke-width:1.5; stroke-dasharray:2 4;
  opacity:.8; stroke-linecap:round; }
.curve-raw { fill:none; stroke:var(--blue-300); stroke-width:1.5; stroke-linejoin:round; }
.curve-comb { fill:none; stroke:var(--orange-400); stroke-width:2.5; stroke-linejoin:round; stroke-linecap:round; }
.curve-whole { fill:none; stroke:var(--green-400); stroke-width:2; stroke-dasharray:6 4;
  stroke-linejoin:round; stroke-linecap:round; }
.area { fill:url(#areaGrad); }
.ramp-zone { fill:var(--ink); opacity:.04; }
.meanline { stroke:var(--text-2); stroke-width:1.5; stroke-dasharray:5 5; opacity:.5; }
.meanchip { font-size:14px; font-weight:600; fill:var(--text-2); }
.chip-plate { fill:var(--white); opacity:.9; }

.dot-live { fill:var(--blue); stroke:var(--white); stroke-width:2.5; }
.dot-live.pulsing { animation:pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { r:6; } 50% { r:8.5; } }
.dot-comb { fill:var(--orange-400); stroke:var(--white); stroke-width:2.5; }
.ph-line { stroke:var(--ink); stroke-width:2; }
.ph-dot { fill:var(--orange-400); stroke:var(--white); stroke-width:2.5; }
.hv-line { stroke:var(--muted); stroke-width:1.5; stroke-dasharray:3 3; opacity:.7; }
.hv-dot { fill:var(--white); stroke:var(--ink); stroke-width:2; }
.tip-box { fill:var(--ink); }
.tip-text { font-family:var(--sans); font-size:14px; font-weight:600; fill:var(--white); }
.hit { fill:transparent; }
.empty-note { font-family:var(--sans); font-size:14px; font-weight:500; fill:var(--muted); }

/* transport -------------------------------------------------------------- */
.state { font-size:14px; color:var(--text-2); font-weight:500; }
.state.bad { color:var(--red); font-weight:600; }

.transport { display:flex; align-items:center; gap:12px; margin-bottom:5px; }
.play {
  width:44px; height:44px; flex:none; border-radius:50%; display:grid; place-items:center;
  border:2px solid var(--ink); background:var(--blue); box-shadow:var(--shadow-sm);
  transition:transform .1s, box-shadow .1s;
}
.play:active { transform:translate(1px,2px); box-shadow:none; }
.play svg { width:22px; height:22px; fill:var(--white); }
/* The brand's slider: a thin white track with a light border and a blue fill. */
.track {
  flex:1; height:10px; border-radius:var(--r-pill); background:var(--white); cursor:pointer;
  border:1px solid var(--border-2); overflow:hidden;
}
.track-fill { height:100%; width:0; background:var(--blue); border-radius:var(--r-pill); }
.times { font-size:14px; font-weight:500; font-variant-numeric:tabular-nums; white-space:nowrap;
  color:var(--text-2); }

/* ---------------------------------------------------------------- dialog */
.sheet { border:0; padding:0; background:none; max-width:min(520px, calc(100vw - 32px)); }
.sheet::backdrop { background:rgba(13,13,13,.45); }
.sheet-in {
  border:2px solid var(--border); border-radius:var(--r-card); background:var(--white);
  padding:20px 16px 16px;
}
.sheet h3 { font-size:16px; line-height:22px; margin-bottom:8px; }
.sheet h3 + p, .sheet ul { font-size:14px; font-weight:400; color:var(--ink); line-height:1.6; }
.sheet ul { list-style:none; margin:0 0 16px; padding:0; display:grid; gap:8px; }
/* Bullets are 8px blue dots, as on the brand's "Areas for improvement" card. */
.sheet li { position:relative; padding-left:18px; }
.sheet li::before { content:""; position:absolute; left:0; top:.5em; width:8px; height:8px;
  border-radius:50%; background:var(--blue); }
.sheet p { margin-bottom:16px; }
.sheet b { color:var(--ink); font-weight:600; }

/* ============================================================ full-width CTAs
   Blue fill, ink outline, hard shadow, Paytone label, icon on the left and an arrow pinned to the
   right: every primary action in the brand looks like this. */
.rec, .sh-play, #new-take, #share-toggle, .gate-go, .sheet-in > .btn {
  display:flex; align-items:center; justify-content:flex-start; gap:16px;
  width:100%; min-height:50px; padding:8px 24px; text-align:left;
  border:2px solid var(--ink); border-radius:var(--r-ctl); box-shadow:var(--shadow);
  font-family:var(--display); font-size:18px; line-height:1.2;
}
.rec::after, .sh-play::after, #new-take::after, #share-toggle::after, .gate-go::after,
.sheet-in > .btn::after {
  content:""; width:20px; height:20px; flex:none; margin-left:auto; background:currentColor;
  -webkit-mask:var(--arrow) center / contain no-repeat; mask:var(--arrow) center / contain no-repeat;
}
.sheet-in > .btn { margin-top:16px; }

/* ------------------------------------------------------------ responsive */
@media (max-width: 900px) {
  body { overflow:auto; }
  .topbar { padding:max(12px, env(safe-area-inset-top)) 16px 8px; }

  main { display:block; }
  main[data-view="stage"] .library { display:none; }
  main[data-view="library"] .stage { display:none; }
  /* fill what is left under the header and tab row, so the canvas never stops mid-screen */
  .library { border-right:0; min-height:calc(100vh - 128px); min-height:calc(100dvh - 128px); }
  .lib-list { overflow:visible; }

  .stage { --stagepad-x:16px; --stagepad-b:16px; padding:16px; gap:8px; }
  .stage-bird { width:44px; height:44px; }
  .readout { grid-template-columns:1fr; }
  .score-card { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; padding:12px 16px; }
  .score-card .card-label { order:1; }
  .score-big { order:0; font-size:40px; margin:0; }
  .score-card .card-sub { order:2; flex-basis:100%; }
  .tiles { grid-template-columns:repeat(2, minmax(0,1fr)); gap:8px; }
  .tile-val { font-size:18px; }
  .chart-card { min-height:260px; height:44vh; }
}

@media (max-width: 420px) {
  .chart-card { height:38vh; }
  .transport .times { display:none; }
}

/* A phone on its side has about 390px of height to spend. The chart's 260px floor ate all of it
   and pushed the dock two screens down, so the one control that matters was never in view. */
@media (orientation:landscape) and (max-height:560px) {
  .stage { gap:8px; }
  .chart-card { min-height:150px; height:52vh; }
  .tiles { grid-template-columns:repeat(4, minmax(0,1fr)); }
  .stage-bird { width:38px; height:38px; }
  .title-input { font-size:16px; }
  .lib-empty img { width:76px; height:76px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation:none !important; transition:none !important; }
}

/* ============================================================ performance view
   Shown only while recording. Everything answers to one number, so the whole screen has to read at
   arm's length from somebody who is mid-phrase and can spare a glance.

   Colour comes from the brand's score bands rather than a hue ramp: JS sets --tone-lo, --tone and
   --tone-dark to three mixes of ONE brand colour picked from the score (red struggling, light blue
   warming up, brand blue normal, green good) and the background cross-fades between them. */
.perform {
  position:fixed; inset:0; z-index:60; display:flex; flex-direction:column;
  gap:clamp(6px, 1.6vh, 16px);
  padding:max(12px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
          max(14px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background:radial-gradient(125% 85% at 50% 4%, var(--tone-lo) 0%, var(--tone) 58%, var(--tone-dark) 100%);
  transition:background 1.2s ease;
  color:var(--ink); overflow:hidden; touch-action:manipulation;
  --tone-lo:#dbf5ff; --tone:#00b6fe; --tone-dark:#008fc8;
}
.perform[hidden] { display:none; }

.perf-bloom { position:absolute; inset:0; pointer-events:none; opacity:0;
  background:radial-gradient(58% 42% at 50% 38%, #fff 0%, transparent 70%); }
.perf-bloom.on { animation:bloom .9s ease-out; }
@keyframes bloom { 0%{opacity:0} 20%{opacity:.6} 100%{opacity:0} }

/* Burst particles are real elements so they can carry the app's own star and gem art rather than
   being abstract dots. They are removed as soon as the animation ends. */
.perf-burst { position:absolute; inset:0; pointer-events:none; overflow:hidden; }
.perf-burst img { position:absolute; width:30px; height:30px; will-change:transform, opacity;
  animation:fly 1.15s cubic-bezier(.15,.75,.35,1) forwards; }
@keyframes fly {
  0%   { transform:translate(0,0) scale(.35) rotate(0deg); opacity:0; }
  18%  { opacity:1; }
  100% { transform:translate(var(--dx), var(--dy)) scale(1.05) rotate(var(--rot)); opacity:0; }
}

.perf-top { display:flex; align-items:center; gap:10px; flex:none; min-height:38px; }
.perf-elapsed { margin-left:auto; font-family:var(--display); font-size:14px;
  color:var(--ink); background:var(--white); padding:4px 14px;
  border:2px solid var(--ink); border-radius:var(--r-pill); font-variant-numeric:tabular-nums; }
.perf-streak {
  display:inline-flex; align-items:center; gap:6px; padding:4px 14px 4px 10px;
  border:2px solid var(--ink); border-radius:var(--r-pill); background:var(--white);
  font-family:var(--display); font-size:14px; color:var(--orange);
}
.perf-streak img { width:20px; height:20px; }
.perf-streak.pop { animation:streak-pop .45s cubic-bezier(.2,1.6,.4,1); }
@keyframes streak-pop { 0%{transform:scale(1)} 38%{transform:scale(1.22) rotate(-4deg)} 100%{transform:scale(1)} }

.perf-scorebox { flex:none; text-align:center; }
.perf-num {
  font-family:var(--display); line-height:.9; letter-spacing:-.025em;
  font-size:clamp(76px, 22vh, 176px); color:var(--white);
  text-shadow:3px 4px 0 var(--shadow-ink); font-variant-numeric:tabular-nums;
}
.perf-num.up { animation:num-up .5s cubic-bezier(.2,1.7,.35,1); }
.perf-num.down { animation:num-down .5s ease-out; }
@keyframes num-up { 0%{transform:scale(1)} 32%{transform:scale(1.11)} 100%{transform:scale(1)} }
@keyframes num-down { 0%{transform:translateY(0)} 40%{transform:translateY(4px)} 100%{transform:translateY(0)} }
.perf-caption {
  margin:10px 0 0; font-family:var(--display); font-size:clamp(14px,2.1vh,18px);
  color:var(--ink); background:var(--white); display:inline-block;
  padding:5px 16px; border:2px solid var(--ink); border-radius:var(--r-pill);
}
.perf-caption.swap { animation:cap-swap .4s cubic-bezier(.2,1.5,.4,1); }
@keyframes cap-swap { 0%{transform:translateY(6px) scale(.94);opacity:0} 100%{transform:none;opacity:1} }

/* The bird sits low, just above the ribbon, so the eye travels number -> bird -> shape. */
.perf-birdwrap { flex:1; min-height:0;
  display:flex; align-items:flex-end; justify-content:center; padding-bottom:2px; }
/* The bubble anchors to the BIRD, not to this column. Anchoring it to the column was the bug that
   floated it near the top of the screen: the column is flex:1 and therefore tall, so `bottom:100%`
   measured from the top of all that empty space rather than from the bird's head. */
.perf-bird-anchor { position:relative; display:inline-block; line-height:0; }
.perf-bird {
  width:clamp(92px, 19vh, 168px); height:auto; display:block;
  animation:bird-breathe 2.8s ease-in-out infinite;
}
.perf-bird.talk { animation:bird-talk .5s cubic-bezier(.2,1.6,.4,1); }
@keyframes bird-breathe { 0%,100%{transform:translateY(0) rotate(-1.5deg)} 50%{transform:translateY(-8px) rotate(1.5deg)} }
@keyframes bird-talk { 0%{transform:scale(1)} 35%{transform:scale(1.1) rotate(-3deg)} 100%{transform:scale(1)} }

/* width:max-content is doing real work. An absolutely positioned box with only `left` set gets
   shrink-to-fit against the space from that edge to the containing block's edge - about half the
   bird's width here - which wrapped every single word onto its own line. */
.perf-bubble {
  position:absolute; bottom:calc(100% + 9px); left:50%;
  transform:translateX(-50%);
  width:max-content; max-width:min(420px, calc(100vw - 44px));
  padding:10px 16px; text-align:center;
  border:2px solid var(--ink); border-radius:var(--r-card); background:var(--white);
  font-family:var(--display);
  font-size:clamp(15px, 2.15vh, 18px); line-height:1.3;
  animation:bubble-pop .26s cubic-bezier(.2,1.5,.4,1);
}
.perf-bubble::before, .perf-bubble::after {
  content:""; position:absolute; left:50%; top:100%; width:0; height:0;
  border:10px solid transparent; border-bottom:0; transform:translateX(-50%);
}
.perf-bubble::before { border-top-color:var(--ink); }
.perf-bubble::after  { border-width:8px; border-bottom:0; margin-top:-3px; border-top-color:var(--white); }
.perf-bubble.praise { background:var(--blue-200); }
.perf-bubble.praise::after { border-top-color:var(--blue-200); }
.perf-bubble.fix    { background:var(--surface); }
.perf-bubble.fix::after { border-top-color:var(--surface); }
@keyframes bubble-pop { 0%{opacity:0;transform:translateX(-50%) translateY(9px) scale(.92)}
                        100%{opacity:1;transform:translateX(-50%) none} }

.perf-foot { flex:none; display:flex; flex-direction:column; gap:8px; }
.perf-canvas {
  display:block; width:100%; height:clamp(52px, 11vh, 96px);
  border:2px solid var(--border); border-radius:var(--r-card); background:var(--white);
}
.perf-meta { display:flex; justify-content:center; font-family:var(--display);
  font-size:14px; color:var(--ink); opacity:.85; margin-top:-2px; }

/* The one call to action on the screen: centred, full width, unmistakable. */
.perf-stop {
  display:flex; align-items:center; justify-content:center; gap:12px;
  width:min(420px, 100%); margin:0 auto; padding:12px 24px; min-height:50px; cursor:pointer;
  border:2px solid var(--ink); border-radius:var(--r-ctl); background:var(--white);
  box-shadow:var(--shadow); font-family:var(--display); font-size:18px; color:var(--ink);
  transition:transform .1s, box-shadow .1s;
}
.perf-stop-sq { width:16px; height:16px; flex:none; background:var(--red); border-radius:3px; }
.perf-stop:active { transform:translate(2px,4px); box-shadow:none; }

/* A phone in landscape is ~350px tall: the column has nowhere to put a 170px number. Two columns,
   with the call to action spanning the foot so it stays the obvious thing to press. */
@media (orientation:landscape) and (max-height:560px) {
  .perform { display:grid; gap:4px 18px;
             grid-template-columns:1fr 1fr; grid-template-rows:auto auto 1fr auto; }
  .perf-top      { grid-column:1 / -1; }
  .perf-scorebox { grid-column:1; grid-row:2 / 4; align-self:center; }
  .perf-birdwrap { grid-column:2; grid-row:2 / 4; align-items:center; }
  .perf-foot     { grid-column:1 / -1; grid-row:4; flex-direction:row; align-items:center; gap:12px; }
  .perf-num      { font-size:clamp(58px, 26vh, 128px); }
  .perf-caption  { margin-top:6px; }
  .perf-canvas   { flex:1; height:clamp(44px, 15vh, 72px); }
  .perf-meta     { display:none; }
  .perf-stop     { width:auto; flex:none; padding:12px 22px; font-size:16px; }
  .perf-bird     { width:clamp(70px, 21vh, 128px); }
  .perf-bubble   { max-width:min(360px, 46vw); font-size:clamp(13px, 3.4vh, 17px); }
}

/* Nobody is singing. The screen goes quiet rather than dark: colour drains towards the canvas
   grey, the number holds its last value at low contrast instead of falling to zero (a plunging
   score for a silent room is a lie), and the bird visibly dozes. */
.perform.idle { --tone-lo:#f7f7f7; --tone:#dbdbdb; --tone-dark:#c4c4c4; }
.perform.idle .perf-num { visibility:hidden; }
.perform.idle .perf-bird { animation:bird-doze 3.6s ease-in-out infinite; }
.perform.idle .perf-caption { background:var(--surface); }
@keyframes bird-doze { 0%,100%{transform:translateY(0) rotate(0deg)} 50%{transform:translateY(-3px) rotate(2deg)} }

/* A soft pulsing ring while the app is listening but hearing nothing, so "quiet" reads as
   attentive rather than broken or frozen. */
.perf-listen { position:absolute; left:50%; bottom:0; width:132px; height:132px;
  margin-left:-66px; border:2px solid rgba(13,13,13,.30); border-radius:50%;
  pointer-events:none; opacity:0; }
.perform.idle .perf-listen { animation:listen 2.4s ease-out infinite; }
@keyframes listen { 0%{transform:scale(.55);opacity:.55} 100%{transform:scale(1.35);opacity:0} }

@media (prefers-reduced-motion:reduce) {
  .perform, .perf-bloom, .perf-bird, .perf-num, .perf-bubble, .perf-streak,
  .perf-caption, .perf-burst img, .perf-listen { transition:none; animation:none; }
}

/* ================================================================= accounts */
/* Both of these are full-screen takeovers rather than modals: signing in is the whole task, and a
   shared link should open to the take and nothing else. Shadows stay off everything that is not a
   control, per the rule at the top. */
.field { display:flex; flex-direction:column; gap:6px; }
.field span { font-size:14px; font-weight:500; color:var(--text-2); }
/* Inputs are white fields with the light border; focus turns the border brand blue. */
.field input {
  width:100%; min-height:50px; padding:8px 16px; font:inherit; font-size:16px; font-weight:500;
  color:var(--ink); background:var(--white);
  border:2px solid var(--border); border-radius:var(--r-ctl);
  transition:border-color .12s;
}
.field input:focus { border-color:var(--blue); outline:none; }
.field-hint { font-size:14px; font-weight:500; color:var(--muted); margin-top:1px; }
.linkish { background:none; border:0; padding:0 0 0 4px; font:inherit; font-weight:600;
  color:var(--blue-600); cursor:pointer; text-decoration:underline; text-underline-offset:2px; }

/* -- share panel ---------------------------------------------------------- */
/* A tinted information panel, like the brand's "Tip of the day" card. */
.share-panel {
  margin-top:8px; padding:16px; border:2px solid var(--border); border-radius:var(--r-card);
  background:var(--blue-50); display:flex; flex-direction:column; gap:14px;
}
.share-panel.on { background:var(--white); }
.share-row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.share-state { font-family:var(--display); font-size:16px; }
.share-panel.on .share-state { color:var(--green); }
.share-why { margin:0; font-size:14px; color:var(--text-2); line-height:1.5; }
.share-link {
  display:flex; gap:8px; margin-top:0; align-items:center;
}
.share-link input {
  flex:1; min-width:0; min-height:44px; padding:8px 14px; font:inherit; font-size:14px; font-weight:500;
  border:2px solid var(--border); border-radius:var(--r-ctl); background:var(--white); color:var(--ink);
  transition:border-color .12s;
}
.share-link input:focus { border-color:var(--blue); outline:none; }
.share-link .btn { min-height:44px; }


/* =================================================================== dialogs */
.modal {
  position:fixed; inset:0; z-index:90; display:flex; align-items:center; justify-content:center;
  padding:20px; background:rgba(13,13,13,.42); backdrop-filter:blur(2px);
  animation:fade .14s ease-out;
}
.modal[hidden] { display:none; }
@keyframes fade { from { opacity:0 } to { opacity:1 } }
.modal-card {
  width:min(380px,100%); background:var(--white); border:2px solid var(--border);
  border-radius:var(--r-card); padding:24px 16px 16px; text-align:center;
  animation:modal-in .2s cubic-bezier(.2,1.4,.4,1);
}
@keyframes modal-in { from { transform:translateY(14px) scale(.96); opacity:0 } to { transform:none; opacity:1 } }
.modal-bird { width:72px; height:72px; display:block; margin:0 auto 10px; }
.modal-title { font-family:var(--display); font-size:18px; line-height:1.25; margin:0 0 6px; }
.modal-body { margin:0; color:var(--text-2); font-size:14px; font-weight:400; line-height:1.55; }
.modal-actions { display:flex; gap:8px; margin-top:20px; }
.modal-actions .btn { flex:1; justify-content:center; }
.modal-actions .btn[hidden] { display:none; }

/* Three dots rather than a spinning ring: it reads as "working" at 20px on a phone, where a thin
   rotating arc mostly reads as a rendering artefact. */
.modal-spin { display:flex; gap:7px; justify-content:center; margin-top:18px; }
.modal-spin[hidden] { display:none; }
.modal-spin i {
  width:10px; height:10px; border-radius:50%; background:var(--blue);
  animation:dot 1s ease-in-out infinite;
}
.modal-spin i:nth-child(2) { animation-delay:.16s; }
.modal-spin i:nth-child(3) { animation-delay:.32s; }
@keyframes dot { 0%,100% { transform:translateY(0); opacity:.55 } 40% { transform:translateY(-7px); opacity:1 } }

.toast {
  position:fixed; left:50%; z-index:95; transform:translate(-50%, 20px);
  bottom:calc(112px + env(safe-area-inset-bottom));  /* clears the sticky dock */
  max-width:min(340px, calc(100vw - 32px));
  padding:12px 20px; border-radius:var(--r-pill);
  background:var(--ink); color:var(--white);
  font-family:var(--display); font-size:14px; text-align:center;
  opacity:0; pointer-events:none; transition:opacity .18s ease, transform .18s ease;
}
.toast.on { opacity:1; transform:translate(-50%, 0); }
.toast.bad { background:var(--red); }
@media (prefers-reduced-motion:reduce) {
  .modal, .modal-card, .modal-spin i, .toast { animation:none; transition:none; }
}


/* ================================================================== top bar */
/* Header and tabs are one sticky block on the plain canvas: identity and account on top, the
   view switch as a row of pills underneath, one light rule under the lot. Sticking them together
   means the tab row never has to know how tall the header is on a device with a notch. */
.chrome { position:sticky; top:0; z-index:10; background:var(--canvas); border-bottom:2px solid var(--border); }
.topbar {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:max(12px, env(safe-area-inset-top)) 16px 8px;
}
.brand { display:flex; align-items:center; gap:10px; min-width:0; }
.brand-bird { width:40px; height:40px; flex:none; }
.brand-name { font-family:var(--display); font-size:18px; line-height:22px; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.avatar {
  width:40px; height:40px; flex:none; padding:0; overflow:hidden; cursor:pointer;
  border:2px solid var(--ink); border-radius:50%; background:var(--blue-200);
  box-shadow:var(--shadow-sm); transition:transform .1s, box-shadow .1s;
}
.avatar:active { transform:translate(1px,2px); box-shadow:none; }
.avatar img { width:100%; height:100%; object-fit:cover; display:block; }

/* The brand's segmented control: outlined pills, the chosen one filled blue with white text. */
.tabs {
  display:flex; gap:8px;
  padding:8px 16px 12px;
}
.tabs button {
  flex:1; min-width:0; min-height:40px; padding:6px 16px; border:2px solid var(--border);
  border-radius:var(--r-pill); background:var(--white);
  font-family:var(--sans); font-weight:600; font-size:14px; color:var(--text-2); cursor:pointer;
  transition:background .12s, color .12s, border-color .12s;
}
.tabs button.on { background:var(--blue); border-color:var(--blue); color:var(--white); }
.tab-count {
  display:inline-block; min-width:20px; padding:1px 6px; margin-left:6px; border-radius:var(--r-pill);
  background:var(--surface); color:var(--text-2); font-family:var(--sans); font-size:14px;
  font-weight:600; line-height:1.5; vertical-align:1px;
}
.tabs button.on .tab-count { background:var(--white); color:var(--blue-600); }
.tab-count[data-n="0"] { display:none; }

/* The explanation, under the numbers it explains rather than behind a "?" in the corner. It
   spans the whole readout: as an ordinary grid item it took the second column and pushed the
   tiles onto a row of their own at half width. */
.explain {
  grid-column:1 / -1; justify-self:start; display:block; margin:0; padding:4px 2px;
  border:0; background:none;
  font:inherit; font-size:14px; font-weight:600; color:var(--blue-600);
  text-decoration:underline; text-underline-offset:2px; cursor:pointer;
}

/* ============================================================= record dock */
/* Sticky at the foot of the singing pane: the transport and the one way to start a new take are
   both always reachable without scrolling for them. It bleeds to the pane edges so the rule above
   it reads as an edge rather than a floating card, and keeps its own inner padding so nothing
   touches the sides. */
.account { position:relative; flex:none; }
.menu {
  position:absolute; right:0; top:calc(100% + 8px); z-index:20; min-width:200px;
  padding:8px; border:2px solid var(--ink); border-radius:var(--r-card); background:var(--white);
  box-shadow:var(--shadow);
}
.menu-who { margin:4px 8px 8px; font-size:14px; color:var(--text-2); }
.menu-who b { color:var(--ink); font-weight:600; }
.menu-item {
  display:block; width:100%; padding:10px 12px; text-align:left; cursor:pointer;
  border:0; border-radius:var(--r-ctl); background:transparent;
  font-family:var(--sans); font-weight:600; font-size:14px; color:var(--ink);
  transition:background .12s;
}
.menu-item:hover { background:var(--surface); }
#signout:hover { background:var(--red-200); }

/* Trimmed down: the transport and the one button, nothing else. The status line only takes up
   room when it actually has something to say. */
.dock {
  position:sticky; bottom:0; z-index:11;
  margin:8px calc(-1 * var(--stagepad-x)) calc(-1 * var(--stagepad-b));
  padding:12px var(--stagepad-x) calc(12px + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; gap:10px;
  background:var(--white); border-top:2px solid var(--border); border-radius:0;
}
.dock-body { width:100%; text-align:center; }
.dock .state:empty { display:none; }
.state { margin:0; }
.transport { display:flex; align-items:center; gap:12px; justify-content:center; margin-bottom:0; }

/* A labelled full-width button rather than a circle: it is the primary action on the screen and
   an icon alone made somebody guess at it. Blue while idle, red while recording. */
.rec {
  cursor:pointer; background:var(--blue); color:var(--white);
  transition:transform .1s, box-shadow .1s, background .15s;
}
.rec:active { transform:translate(2px,4px); box-shadow:none; }
.rec.recording { background:var(--red); color:var(--white); }
.rec:disabled { opacity:.5; cursor:not-allowed; box-shadow:var(--shadow); }
.rec:disabled:active { transform:none; box-shadow:var(--shadow); }
.rec-ico { width:24px; height:24px; flex:none; }


@media (max-width:420px) {
  .tabs { padding-left:12px; padding-right:12px; }
  .tabs button { font-size:14px; padding:6px 10px; }
  .topbar { padding-left:12px; padding-right:12px; }
  .modal-actions { flex-direction:column-reverse; }
}

/* ============================================================== shared take */
/* Whoever follows a share link has no account and no context, so this IS the page rather than a
   card floating over the app. One column, the score at the top where the eye lands, the shape of
   the take in the middle to scrub through, and the only two things worth doing pinned to the
   bottom where a thumb already is. */
.shared {
  position:fixed; inset:0; z-index:80;
  display:flex; flex-direction:column; gap:12px;
  padding:max(16px, env(safe-area-inset-top)) 16px max(14px, env(safe-area-inset-bottom));
  background:var(--canvas);
  /* scrolls rather than clips: the fixed-height children add up to ~607px, so on a 568px phone
     hiding the overflow cut off the play button and the link out with no way to reach them */
  overflow-y:auto; -webkit-overflow-scrolling:touch;
}
.shared[hidden] { display:none; }

.sh-top { display:flex; align-items:flex-start; gap:12px; flex:none; }
.sh-who { min-width:0; flex:1; }
.sh-owner { margin:0; font-size:14px; font-weight:500; color:var(--text-2); }
.sh-title { font-family:var(--display); font-size:clamp(18px,5vw,22px); line-height:1.2;
  margin:3px 0 0; overflow-wrap:anywhere; }
.sh-medal { width:44px; height:44px; flex:none;
  animation:medal-in .55s cubic-bezier(.2,1.6,.4,1) .45s backwards; }
@keyframes medal-in { from { transform:scale(0) rotate(-40deg); opacity:0 } to { transform:none; opacity:1 } }

/* The graph is the interactive element here: a white card whose border turns blue while you drag. */
.sh-graph { position:relative; flex:1; min-height:104px; display:flex; flex-direction:column; }
.sh-canvas {
  flex:1; min-height:0; width:100%; display:block; touch-action:none; cursor:ew-resize;
  border:2px solid var(--border); border-radius:var(--r-card); background:var(--white);
  transition:border-color .12s;
}
.sh-graph.scrubbing .sh-canvas { border-color:var(--blue); }
.sh-scrub { position:absolute; inset:0; }        /* keyboard target only; pointer events pass through */
.sh-scrub:focus-visible { outline:3px solid var(--ink); outline-offset:3px; border-radius:var(--r-card); }
.sh-times { display:flex; justify-content:space-between; margin:6px 2px 0;
  font-size:14px; font-weight:500; color:var(--text-2);
  font-variant-numeric:tabular-nums; }

.sh-tiles { flex:none; display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.sh-tile { padding:12px 8px; text-align:center; border:2px solid var(--border); border-radius:var(--r-ctl);
  background:var(--white); }
.sh-tile span { display:block; font-family:var(--display); font-size:18px; line-height:1.1;
  font-variant-numeric:tabular-nums; }
.sh-tile small { display:block; margin-top:4px; font-size:14px; font-weight:500; color:var(--text-2); }

.sh-foot { flex:none; display:flex; flex-direction:column; align-items:center; gap:10px; }
.sh-play {
  width:min(360px,100%); cursor:pointer; background:var(--blue); color:var(--white);
  transition:transform .1s, box-shadow .1s;
}
.sh-play:active { transform:translate(2px,4px); box-shadow:none; }
.sh-play:disabled { opacity:.5; cursor:default; }
.sh-play svg { width:22px; height:22px; fill:var(--white); flex:none; }
.sh-cta { font-family:var(--sans); font-weight:600; font-size:14px; color:var(--blue-600);
  text-decoration:underline; text-underline-offset:2px; padding:4px; }
.shared-err { margin:0; text-align:center; color:var(--red); font-weight:600; font-size:14px; }
#shared-audio { display:none; }

/* One focus ring for the whole app: the browser's default sat a pale halo outside an already
   outlined button, which read as a rendering fault rather than as focus. No border-radius here --
   setting one reshaped whatever had focus, so the round avatar turned into a rounded square while
   it was focused. Outlines already follow the element's own corners. */
:focus-visible { outline:3px solid var(--ink); outline-offset:2px; }

/* Reuse the live view's colours and bird art, with a media-clock-driven performance. The panel is
   tinted with a pale mix of the band colour; blue until a score arrives. */
.replay {
  --replay-tone:var(--blue-200); --replay-accent:var(--blue);
  flex:none; padding:16px; border:2px solid var(--border); border-radius:var(--r-card);
  background:var(--replay-tone); transition:background .4s cubic-bezier(.25,1,.5,1);
}
.replay-heading { display:flex; justify-content:space-between; gap:12px; font-size:14px; font-weight:500; color:var(--text-2); }
.replay-state { font-weight:500; }
.replay-stage { display:grid; grid-template-columns:1fr 1fr; align-items:center; gap:16px; min-height:208px; }
.replay-scorebox { display:flex; flex-direction:column; align-items:center; gap:8px; text-align:center; }
.replay-number { font:64px/1 var(--display); font-variant-numeric:tabular-nums; }
.replay-caption { font:16px/1.3 var(--display); }
.replay-scorebox small { max-width:18ch; font-size:14px; line-height:1.5; color:var(--text-2); }
.replay-coach { display:flex; flex-direction:column; align-items:center; justify-content:flex-end; }
.replay-bird { width:108px; height:108px; object-fit:contain; transform-origin:50% 85%; }
.replay-bubble { position:relative; margin:12px 0 0; max-width:30ch; padding:10px 12px;
  background:var(--white); border:2px solid var(--ink); border-radius:var(--r-card);
  font:14px/1.4 var(--display); text-align:center; }
.replay-bubble.say { animation:replay-say .24s cubic-bezier(.25,1,.5,1); }
.replay.is-playing .replay-bird { animation:replay-breathe 2s ease-in-out infinite; }
.replay.is-playing.is-talking .replay-bird { animation:replay-talk .6s ease-in-out infinite; }
@keyframes replay-say { from { opacity:0; transform:translateY(5px); } to { opacity:1; transform:none; } }
@keyframes replay-breathe { 50% { transform:translateY(-4px) rotate(2deg); } }
@keyframes replay-talk { 50% { transform:rotate(-3deg) scale(1.035); } }
.enhance { width:100%; padding:12px 0; }
.enhance-top { display:flex; align-items:center; flex-wrap:wrap; gap:10px 14px; }
.enhance-toggle { min-height:44px; font-size:14px; }
.enhance-toggle[aria-pressed="true"] { background:var(--blue); color:var(--white); }
.enhance-status { flex:1; min-width:100px; font-size:14px; line-height:1.5; color:var(--text-2); }
.enhance-options { padding-top:14px; display:grid; gap:12px; }
.enhance-options label { display:flex; align-items:center; gap:10px; font-size:14px; font-weight:600; }
.enhance-options input { flex:1; min-width:40px; height:28px; accent-color:var(--blue); }
.enhance-options output { min-width:4ch; text-align:right; font-variant-numeric:tabular-nums; }
.enhance-options p { margin:0; max-width:65ch; font-size:14px; line-height:1.6; color:var(--text-2); }
.shared { background:var(--replay-tone, var(--canvas)); transition:background .4s cubic-bezier(.25,1,.5,1); }
.shared > * { width:100%; max-width:680px; margin-left:auto; margin-right:auto; }
.shared .replay { background:transparent; border:0; padding:0; }
.shared .replay-stage { min-height:230px; }
.shared .replay-number { font-size:80px; }
.shared .replay-bird { width:140px; height:140px; }
.sh-summary { margin-top:0; margin-bottom:0; font-size:14px; text-align:center; color:var(--text-2); }
.sh-summary b { font-family:var(--display); font-weight:400; font-size:16px; color:var(--ink); }
.sh-scrub { pointer-events:none; }
.sh-foot { position:sticky; bottom:calc(-1 * max(14px, env(safe-area-inset-bottom)));
  padding:10px 0 max(14px, env(safe-area-inset-bottom)); background:var(--replay-tone, var(--canvas)); }
.sh-foot .enhance { padding:0 0 6px; }
.shared-err:empty { display:none; }
.sh-medal { animation:replay-say .3s cubic-bezier(.25,1,.5,1); }
@media (max-width:380px) {
  .replay { padding:12px; }
  .replay-stage { gap:8px; }
  .replay-number, .shared .replay-number { font-size:60px; }
  .replay-bubble { font-size:14px; padding:8px; }
  .replay-bird, .shared .replay-bird { width:104px; height:104px; }
  .enhance-options label { font-size:14px; }
}
@media (prefers-reduced-motion:reduce) {
  .replay, .shared, .sh-medal, .replay-bubble.say,
  .replay.is-playing .replay-bird, .replay.is-playing.is-talking .replay-bird { animation:none; transition:none; }
}
.stage { overflow-y:auto; }
.stage > .enhance { flex:none; }
.shared > .enhance { flex:none; }

@media (orientation:landscape) and (max-height:560px) {
  .shared .replay-stage { min-height:160px; }
  .shared .replay-bird { width:100px; height:100px; }
  .shared .replay-number { font-size:60px; }
  .sh-foot { flex-direction:row; justify-content:center; }
  .sh-play { width:auto; min-width:220px; padding:12px 22px; }
}

/* The owner auditions a finish before publishing; the listener hears that exact master. */
#share-panel:not([hidden]) ~ .dock { display:none; }
.share-studio { padding:4px 0; }
.share-studio fieldset { min-width:0; margin:0; padding:0; border:0; }
.share-studio legend { padding:0; font:18px/1.3 var(--display); }
.studio-intro { margin:6px 0 14px; font-size:14px; color:var(--text-2); }
/* One sound per row: the mobile layout that ships to the game. Desktop's wide stage pane can
   afford two. Mobile-first so the base rule can't be overridden by later source order. */
.preset-list { display:grid; grid-template-columns:1fr; gap:12px; }
@media (min-width:901px) { .preset-list { grid-template-columns:repeat(2,minmax(0,1fr)); } }
/* one pressable per sound; the note only appears on the chosen one, descriptions live by the play button */
.preset-choice { position:relative; display:flex; align-items:center; justify-content:center; gap:10px; min-height:56px; padding:12px 20px; cursor:pointer;
  border:2px solid var(--ink); border-radius:var(--r-ctl); background:var(--white); box-shadow:var(--shadow);
  font:16px/1.2 var(--display); color:var(--ink); user-select:none; transition:background .12s, color .12s, transform .1s, box-shadow .1s; }
.preset-choice:active { transform:translate(2px,4px); box-shadow:none; }
.preset-choice:has(input:checked) { background:var(--blue); color:var(--white); }
.preset-choice:has(input:focus-visible) { outline:3px solid var(--ink); outline-offset:3px; }
.preset-choice input { position:absolute; opacity:0; width:1px; height:1px; margin:0; pointer-events:none; }
.preset-note { display:none; flex:none; width:18px; height:18px; }
.preset-note svg { display:block; width:100%; height:100%; fill:currentColor; }
.preset-choice:has(input:checked) .preset-note { display:block; }
.studio-description { margin:12px 0 0; font-size:14px; line-height:1.5; color:var(--text-2); }
.studio-description b { font-weight:600; color:var(--ink); }
.studio-description[hidden] { display:none; }
.studio-audition { border-top:2px solid var(--border); margin-top:20px; padding-top:16px; }
.studio-player-heading { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:12px; }
.studio-player-heading h3 { margin:0; font:16px/1.3 var(--display); }
.studio-elapsed { font-size:14px; white-space:nowrap; font-variant-numeric:tabular-nums; color:var(--text-2); }
.studio-preparing { position:relative; display:flex; align-items:center; gap:14px; padding:16px 16px 20px;
  margin-bottom:16px; border:2px solid var(--border); border-radius:var(--r-ctl); background:var(--white); overflow:hidden; }
.studio-preparing strong { font:15px/1.4 var(--display); font-weight:400; }
.studio-preparing p { margin:4px 0 0; max-width:52ch; font-size:14px; line-height:1.5; color:var(--text-2); }
.studio-loading-bars { display:flex; flex:none; align-items:center; gap:3px; height:36px; }
.studio-loading-bars i { width:5px; height:28px; border-radius:3px; background:var(--blue); animation:studio-pulse 1s ease-in-out infinite alternate; }
.studio-loading-bars i:nth-child(2) { animation-delay:-.2s; }
.studio-loading-bars i:nth-child(3) { animation-delay:-.4s; }
.studio-loading-bars i:nth-child(4) { animation-delay:-.6s; }
.studio-loading-bars i:nth-child(5) { animation-delay:-.8s; }
.studio-progress { position:absolute; inset:auto 0 0; height:5px; background:var(--blue-100); }
.studio-progress span { display:block; height:100%; width:35%; background:var(--blue); animation:studio-progress 1.6s ease-in-out infinite; }
/* Version switch = the same pill segmented control as everywhere else. */
.studio-versions { display:inline-flex; flex-wrap:wrap; max-width:100%; gap:6px; padding:0; border:0; background:transparent; }
.studio-versions button { min-height:36px; min-width:96px; padding:6px 16px; border:2px solid var(--border); border-radius:var(--r-pill);
  background:var(--white); color:var(--ink); font:500 14px/1.3 var(--sans); cursor:pointer; transition:background .12s, border-color .12s, color .12s; }
.studio-versions button[aria-pressed=true] { background:var(--blue); border-color:var(--blue); color:var(--white); }
.studio-versions button:disabled { opacity:.5; cursor:default; }
.studio-transport { display:flex; align-items:center; gap:16px; margin-top:16px; }
.studio-play { display:grid; place-items:center; flex:none; width:52px; height:52px; padding:0; border:2px solid var(--ink);
  border-radius:50%; background:var(--blue); color:var(--white); box-shadow:var(--shadow); cursor:pointer;
  transition:transform .1s, box-shadow .1s; }
.studio-play:active:not(:disabled) { transform:translate(2px,4px); box-shadow:none; }
.studio-play:disabled { opacity:.4; cursor:default; }
.studio-play svg { width:25px; height:25px; fill:currentColor; }
.studio-timeline { flex:1; min-width:0; }
.studio-seek { display:block; width:100%; height:32px; margin:0; padding:0; cursor:pointer; accent-color:var(--blue); }
.studio-seek:disabled { opacity:.4; cursor:default; }
.studio-clock { display:flex; justify-content:space-between; gap:12px; font-size:14px; font-variant-numeric:tabular-nums; color:var(--text-2); }
.studio-status { margin:12px 0 0; font-size:14px; min-height:1.5em; line-height:1.5; color:var(--text-2); }
.studio-play:focus-visible, .studio-versions button:focus-visible, .studio-seek:focus-visible { outline:3px solid var(--ink); outline-offset:3px; }
.studio-retry { margin-top:8px; min-height:36px; }
.studio-note { margin-top:8px; font-size:14px; line-height:1.5; max-width:65ch; color:var(--text-2); }
#share-toggle { align-self:stretch; }
#share-toggle:disabled, #share-copy:disabled { opacity:.5; cursor:default; }
.sh-sound { font-size:14px; text-align:center; color:var(--text-2); }
@keyframes studio-pulse { from { transform:scaleY(.3); } to { transform:scaleY(1); } }
@keyframes studio-progress { from { transform:translateX(-100%); } to { transform:translateX(390%); } }
@media (prefers-reduced-motion:reduce) {
  .studio-loading-bars i, .studio-progress span { animation:none; }
  .studio-loading-bars i:nth-child(even) { transform:scaleY(.5); }
  .studio-progress span { width:100%; opacity:.5; }
}
@media (max-width:380px) {
  .preset-list { grid-template-columns:1fr; }
  .preset-choice { padding:10px; }
}
/* Compact desktop navigation belongs inside the header; phones retain the second row. */
.topbar { display:grid; grid-template-columns:1fr auto 1fr; }
.topbar .tabs { grid-template-columns:repeat(3,auto); padding:0; border:0; background:transparent; gap:8px; }
.topbar .tabs button { min-width:104px; font-size:14px; padding:8px 16px; }
.topbar .account { justify-self:end; }
@media(max-width:700px) { .topbar { display:flex; flex-wrap:wrap; gap:9px 12px; }.topbar .brand { flex:1; }.topbar .account { order:2; }.topbar .tabs { order:3; width:100%; grid-template-columns:repeat(3,minmax(0,1fr)); padding-top:4px; }.topbar .tabs button { min-width:0; padding:10px 6px; font-size:14px; } }
/* Center only the two creation modes; the personal library sits beside the account. */
.topbar { position:relative; display:flex; justify-content:space-between; }
.topbar .tabs { position:absolute; inset:0; display:block; pointer-events:none; }
.topbar .tabs-primary { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); display:flex; gap:8px; }
.topbar .tabs button { pointer-events:auto; }
.topbar .tabs>button[data-view="library"] { position:absolute; right:76px; top:50%; transform:translateY(-50%); }
@media(max-width:900px) { .topbar { flex-wrap:wrap; }.topbar .brand { flex:1; }.topbar .account { order:2; }.topbar .tabs { position:static; order:3; display:grid; width:100%; grid-template-columns:repeat(3,minmax(0,1fr)); padding-top:4px; gap:8px; }.topbar .tabs-primary { display:contents; }.topbar .tabs button { min-width:0; padding:10px 6px; font-size:14px; }.topbar .tabs>button[data-view="library"] { position:static; transform:none; } }
/* My recordings is a complete library page; detail reuses the saved-take player and Share. */
main[data-view="library"],main[data-view="recording"] { display:block; overflow-y:auto; }
main[data-view="library"] .stage,main[data-view="recording"] .library { display:none; }
main[data-view="library"] .library { display:flex; width:100%; max-width:1200px; min-height:100%; margin:0 auto; padding:28px 28px 40px; border:0; background:var(--canvas); }
main[data-view="library"] .lib-head { padding:0 0 24px; }
main[data-view="library"] .lib-head h2 { font-size:30px; }
main[data-view="library"] .lib-list { flex:none; overflow:visible; padding:0; gap:14px; grid-template-columns:repeat(auto-fit,minmax(310px,1fr)); }
main[data-view="library"] .take { min-height:92px; padding:18px; }
main[data-view="library"] .take-who { display:flex; flex-direction:column; gap:7px; }
main[data-view="library"] .lib-empty { padding:64px 20px; }
main[data-view="library"] .lib-empty img { width:144px; height:144px; margin-bottom:18px; }
main[data-view="recording"] .stage { display:flex; max-width:1200px; height:100%; margin:0 auto; }
.recordings-back { align-self:flex-start; margin:0 0 8px; }
.recordings-back[hidden],.rec[hidden] { display:none; }
@media(max-width:700px) { main[data-view="library"] .library { padding:24px 16px; }main[data-view="library"] .lib-head h2 { font-size:24px; }main[data-view="library"] .lib-list { grid-template-columns:1fr; }main[data-view="library"] .take { min-height:84px; padding:14px; } }

/* Flat account rows retain one menu boundary and a visible keyboard focus state. */
.menu { padding:6px; background:#fff; }
.menu .menu-item { min-height:44px; border:0; border-radius:7px; box-shadow:none; background:transparent; transform:none; text-decoration:none; }
.menu .menu-item:hover,.menu .menu-item:focus-visible { background:#e8f6fd; }
.menu .menu-item[hidden] { display:none; }
/* Recording cards retain the new nested header while long titles shrink safely. */
.take { min-width:0; }
.take-top { grid-template-columns:40px minmax(0,1fr) auto; min-width:0; }
.take-who { overflow:hidden; }
.take-name .txt { display:block; }
.take-sub { max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
