/* Office Hours: studio-dark Apple language.
   New York (ui-serif) display over the SF system stack, graphite surfaces,
   hairline separators, one keylight-gold tint, iOS-red record affordance. */

:root {
  color-scheme: light;

  /* color: warm parchment studio (owner-ratified 2026-07-31), indigo tint,
     orange trouble accent, dark charcoal wave tiles for contrast */
  --bg: #f4efe6;
  --surface: #fbf8f1;
  --surface-2: #efe9dc;
  --surface-3: #e5ddcc;
  --hairline: rgba(32, 29, 24, 0.14);
  --text: #201d18;
  --text-2: rgba(32, 29, 24, 0.72);
  --text-3: rgba(32, 29, 24, 0.68); /* clears 4.5:1 on bg, cards, and tinted lesson notices */
  /* PALETTE, revised 2026-08-02 (William delegated the choice).
     The old accent was #4f58d8, a high-chroma COOL indigo sitting on a warm,
     low-chroma parchment ground. Cool saturation on warm paper reads as foreign
     no matter how it is arranged, and it was the single loudest thing on every
     screen including pages about quiet study.

     The system is now three colours and a rule about the third:
       PAPER  warm parchment, unchanged, William ratified it 2026-07-31
       INK    a warm near-black that carries text AND primary actions
       RED    reserved EXCLUSIVELY for recording

     Making the primary action ink rather than a colour is the whole move. On
     paper, weight and contrast signal importance more honestly than hue, and it
     leaves exactly one saturated colour in the app. Red then means one thing,
     always: the mic is live. Give red a second job and it stops being a signal. */
  --tint: #2b2620;
  --tint-soft: rgba(43, 38, 32, 0.08);
  --tint-ink: #f7f3ea;
  --record: #e83c30;
  --ok: #177d43;
  --warn: #d96f24;
  --tile: #23222b;
  --tile-wave: #7d86ff;
  --tile-wave-warn: #f0954e;

  /* radius */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* spacing, 8-based */
  --s-1: 4px;
  --s0: 8px;
  --s1: 12px;
  --s2: 16px;
  --s3: 24px;
  --s4: 32px;
  --s5: 48px;

  /* elevation (dark UI: tone over shadow, shadow as whisper) */
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --elev-2: 0 6px 18px rgba(0, 0, 0, 0.45);
  --elev-3: 0 12px 40px rgba(0, 0, 0, 0.6);

  /* type */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", sans-serif;
  --font-display: ui-serif, "New York", Georgia, serif;
  --fs-display: clamp(28px, 7.5vw, 34px);
  --fs-title2: 21px;
  --fs-title: 17px;
  --fs-body: 15px;
  --fs-meta: 13px;
  --fs-label: 11px;

  /* motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: linear(0, 0.0117 0.98%, 0.0464 1.96%, 0.1846 4.03%, 0.7357 10.25%, 0.8935 12.62%, 1.0087 15.19%, 1.0521 16.71%, 1.0817 18.42%, 1.0952 20.24%, 1.0956 21.62%, 1.0831 24.03%, 1.0017 31.99%, 0.9827 36.16%, 0.9811 40.04%, 0.9997 55.16%, 1.0018 64.21%, 1 100%);
  --t-fast: 160ms;
  --t-med: 240ms;
  --t-slow: 320ms;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --gutter: max(var(--s2), var(--safe-left), var(--safe-right));
}

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

html { height: 100%; }

body {
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}

/* subtle studio atmosphere behind everything */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(79, 88, 216, 0.05), transparent 60%),
    radial-gradient(80% 50% at 80% 110%, rgba(217, 111, 36, 0.05), transparent 60%);
  pointer-events: none;
  display: none;
}

/* ---------- app frame ---------- */

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

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--s1);
  min-height: 52px;
  padding: calc(var(--safe-top) + var(--s0)) var(--gutter) var(--s0);
  background: var(--bg);
  border-bottom: 0.5px solid var(--hairline);
}

.topbar .bar-title {
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar .bar-side { min-width: 64px; display: flex; }
.topbar .bar-side.right { justify-content: flex-end; }

.back-btn {
  appearance: none;
  border: 0;
  background: none;
  color: var(--tint);
  font: 600 var(--fs-body) var(--font-ui);
  padding: var(--s0) var(--s0) var(--s0) 0;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  cursor: pointer;
  min-height: 44px;
}
.back-btn::before { content: "‹"; font-size: 24px; line-height: 1; transform: translateY(-1px); }

.view {
  flex: 1;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: var(--s2) var(--gutter) calc(var(--s5) + var(--safe-bottom));
}

/* ---------- type ranks ---------- */

.display {
  font-family: var(--font-display);
  font-size: var(--fs-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.15;
}

.title2 { font-size: var(--fs-title2); font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; }
.title { font-size: var(--fs-title); font-weight: 600; letter-spacing: -0.01em; line-height: 1.25; }
.meta { font-size: var(--fs-meta); color: var(--text-2); }
.label {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* ---------- surfaces ---------- */

.card {
  background: var(--surface);
  border: 0.5px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--s2);
  box-shadow: var(--elev-1);
}

.card + .card { margin-top: var(--s1); }

.hero-card {
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 0.5px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: var(--s3) var(--s2);
  box-shadow: var(--elev-2);
}

.hr { border: 0; border-top: 0.5px solid var(--hairline); margin: var(--s2) 0; }

.row {
  display: flex;
  align-items: center;
  gap: var(--s1);
  min-height: 44px;
  /* Wrap, or a row of intrinsically-wide children pushes the whole page
     sideways on a phone. The count-in row was doing exactly that: segmented
     (189px) + tap-tempo chip (174px) + 12px gap = 375px of content in a 309px
     row, and the chip's nowrap text meant flex could not shrink it. Result was
     34px of horizontal scroll on a 375px iPhone. Found 2026-08-01. */
  flex-wrap: wrap;
}
.row .grow { flex: 1; min-width: 0; }

/* ---------- controls ---------- */

button { font-family: inherit; touch-action: manipulation; }

.btn {
  appearance: none;
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s0);
  min-height: 50px;
  padding: 0 var(--s3);
  border-radius: var(--r-pill);
  background: var(--tint);
  color: var(--tint-ink);
  font: 600 var(--fs-title) var(--font-ui);
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), opacity var(--t-fast) var(--ease-out);
}
.btn.block { width: 100%; }
.btn:disabled { opacity: 0.4; pointer-events: none; }

.btn-quiet {
  appearance: none;
  border: 0.5px solid var(--hairline);
  background: var(--surface-2);
  color: var(--text);
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-pill);
  font: 600 var(--fs-body) var(--font-ui);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s0);
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.btn-quiet.block { width: 100%; }

.btn-text {
  appearance: none;
  border: 0;
  background: none;
  color: var(--tint);
  font: 600 var(--fs-body) var(--font-ui);
  min-height: 44px;
  padding: 0 var(--s0);
  cursor: pointer;
}

.btn:active, .btn-quiet:active, .btn-text:active, .chip:active, .tap:active {
  transform: scale(0.97);
  opacity: 0.9;
}

:focus-visible {
  outline: 2px solid var(--tint);
  outline-offset: 2px;
  border-radius: 4px;
}

.chip {
  appearance: none;
  border: 0.5px solid var(--hairline);
  background: var(--surface-2);
  color: var(--text);
  white-space: nowrap;
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-pill);
  font: 500 var(--fs-body) var(--font-ui);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
.chip[aria-pressed="true"], .chip.on {
  background: var(--tint-soft);
  border-color: var(--tint);
  color: var(--tint);
}

.chip-row { display: flex; flex-wrap: wrap; gap: var(--s0); }

.selection-list {
  display: flex;
  flex-direction: column;
  border-top: 0.5px solid var(--hairline);
}

.selection-row {
  appearance: none;
  width: 100%;
  min-height: 60px;
  padding: var(--s1) var(--s0);
  border: 0;
  border-bottom: 0.5px solid var(--hairline);
  background: none;
  color: var(--text);
  text-align: left;
}

.selection-row[aria-checked="true"] {
  box-shadow: inset 3px 0 0 var(--tint);
  background: var(--tint-soft);
}

.selection-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* segmented control: a real either-or, unlike chips */
.segmented {
  display: inline-flex;
  border: 0.5px solid var(--hairline);
  border-radius: var(--r-pill);
  background: var(--surface);
  padding: 3px;
  gap: 2px;
}
.segmented button {
  appearance: none;
  border: 0;
  background: none;
  color: var(--text-2);
  white-space: nowrap;
  font: 600 var(--fs-meta) var(--font-ui);
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.segmented button[aria-pressed="true"] {
  background: var(--surface-3);
  color: var(--text);
}
.chip[disabled], .chip[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }

/* reset for semantic buttons that look like text or cards */
.btn-reset {
  appearance: none;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  padding: 0;
  cursor: pointer;
}

input[type="text"], textarea, select {
  width: 100%;
  background: var(--surface-2);
  border: 0.5px solid var(--hairline);
  border-radius: var(--r-md);
  color: var(--text);
  font: 400 var(--fs-body) var(--font-ui);
  padding: 13px var(--s2);
  min-height: 44px;
}
textarea { resize: vertical; min-height: 88px; line-height: 1.5; }
input::placeholder, textarea::placeholder { color: var(--text-3); }

/* ---------- record button ---------- */

.record-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s2);
  padding: var(--s4) 0;
}

.record-btn {
  appearance: none;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  border: 3px solid rgba(32, 29, 24, 0.2);
  background: none;
  padding: 0;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.record-btn .dot {
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: var(--record);
  transition: border-radius var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-out);
}
.record-btn:active .dot { transform: scale(0.92); }
.record-btn.recording .dot {
  border-radius: 8px;
  transform: scale(0.42);
}

/* ---------- vertical song map ---------- */

.map { display: flex; flex-direction: column; gap: var(--s1); }

.map-row {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  width: 100%;
  padding: 0;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out);
}
.map-row:active { transform: scale(0.985); }

.map-row .map-label {
  display: flex;
  align-items: center;
  gap: var(--s0);
  margin-bottom: 4px;
}

.wave-tile {
  position: relative;
  height: 56px;
  border-radius: var(--r-md);
  background: var(--tile);
  box-shadow: var(--elev-1);
  overflow: hidden;
}
.wave-tile canvas { width: 100%; height: 100%; display: block; }

.map-row.trouble .wave-tile { box-shadow: 0 0 0 2px var(--warn), var(--elev-1); }

.map-row.empty .wave-tile {
  background: none;
  border: 1.5px dashed rgba(217, 111, 36, 0.55);
  display: grid;
  place-items: center;
  color: var(--warn);
  font: 600 var(--fs-body) var(--font-ui);
  animation: breathe-warm 2.8s var(--ease-out) infinite;
}
@keyframes breathe-warm {
  0%, 100% { border-color: rgba(217, 111, 36, 0.4); }
  50% { border-color: rgba(217, 111, 36, 0.85); }
}

.trouble-banner {
  display: flex;
  align-items: center;
  gap: var(--s0);
  background: rgba(217, 111, 36, 0.12);
  border: 0.5px solid rgba(217, 111, 36, 0.35);
  color: var(--warn);
  border-radius: var(--r-md);
  padding: var(--s1) var(--s2);
  font: 600 var(--fs-meta) var(--font-ui);
}

/* hero waveform art behind the Today card title */
.hero-card { position: relative; overflow: hidden; }
.hero-art {
  position: absolute;
  inset: 0;
  opacity: 0.1;
  pointer-events: none;
}
.hero-art canvas { width: 100%; height: 100%; display: block; }
.hero-card > :not(.hero-art) { position: relative; }

/* ---------- slot strip ---------- */

.slot-strip {
  display: flex;
  gap: var(--s1);
  overflow-x: auto;
  padding: var(--s0) var(--gutter) var(--s2);
  margin: 0 calc(-1 * var(--gutter));
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.slot-strip::-webkit-scrollbar { display: none; }

.slot {
  appearance: none;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  scroll-snap-align: start;
  flex: 0 0 132px;
  min-height: 148px;
  border-radius: var(--r-md);
  border: 0.5px solid var(--hairline);
  background: var(--surface);
  padding: var(--s1);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
  position: relative;
}
.slot:active { transform: scale(0.97); }

.slot.empty {
  border-style: dashed;
  border-color: rgba(217, 166, 72, 0.45);
  background: rgba(217, 166, 72, 0.05);
  align-items: center;
  justify-content: center;
}
.slot.empty .plus { font-size: 28px; color: var(--tint); font-weight: 300; }
.slot.empty { animation: breathe 2.8s var(--ease-out) infinite; }

@keyframes breathe {
  0%, 100% { border-color: rgba(217, 166, 72, 0.35); }
  50% { border-color: rgba(217, 166, 72, 0.75); }
}

.slot.settled { border-color: rgba(48, 209, 88, 0.4); }
.slot .trouble {
  position: absolute;
  top: var(--s0);
  right: var(--s0);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warn);
}

.wave {
  width: 100%;
  height: 36px;
  display: block;
}

/* ---------- lists, badges ---------- */

.list { display: flex; flex-direction: column; }
.list > * + * { border-top: 0.5px solid var(--hairline); }
.list-item { padding: var(--s1) 0; display: flex; gap: var(--s1); align-items: center; min-height: 52px; }

.badge {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 1px 9px;
  border-radius: var(--r-pill);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.05em;
  background: var(--surface-3);
  color: var(--text-2);
}
.badge.gold { background: var(--tint-soft); color: #3f47bd; }
.badge.green { background: rgba(48, 209, 88, 0.14); color: var(--ok); }

/* ---------- lessons ---------- */

.lesson-stage { overflow: hidden; }
.lesson-card-head { align-items: flex-start; }
.lesson-profile-head { flex-direction: column; align-items: stretch; }
.lesson-profile-head .segmented { align-self: flex-start; }

.lesson-stage-summary {
  cursor: pointer;
  list-style: none;
  margin: calc(-1 * var(--s0));
  padding: var(--s0);
  border-radius: var(--r-sm);
}
.lesson-stage-summary::-webkit-details-marker { display: none; }
.lesson-stage-summary:active { background: var(--surface-2); }
.lesson-stage-toggle {
  color: var(--text-3);
  font-size: 24px;
  line-height: 1;
  transform: rotate(90deg);
  transition: transform var(--t-fast) var(--ease-out);
}
.lesson-stage:not([open]) .lesson-stage-toggle { transform: rotate(0); }

.lesson-list {
  display: flex;
  flex-direction: column;
  margin-top: var(--s0);
}

.lesson-row {
  width: 100%;
  min-height: 76px;
  padding: var(--s1) 0;
  display: flex;
  align-items: center;
  gap: var(--s1);
  border-radius: var(--r-sm);
  transition: transform var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.lesson-row + .lesson-row { border-top: 0.5px solid var(--hairline); }
.lesson-row:active { transform: scale(0.985); background: var(--surface-2); }

.lesson-number {
  flex: 0 0 34px;
  color: var(--tint);
  font-size: var(--fs-meta);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.lesson-row-copy {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-width: 0;
}
.lesson-row-copy .title,
.lesson-row-copy .meta { overflow-wrap: anywhere; }
.lesson-row > .badge { flex: 0 0 auto; align-self: flex-start; margin-top: var(--s-1); }

/* ---------- song document ---------- */

.document-history {
  display: flex;
  align-items: center;
  gap: var(--s0);
  flex-wrap: wrap;
}
.document-history .btn-quiet { min-width: 84px; }
.document-history .meta { min-width: 160px; }
.document-summary { align-items: flex-start; }

.document-track { overflow: hidden; padding: var(--s1) var(--s2); }
.document-track-summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--s0);
  min-height: 52px;
  margin: calc(-1 * var(--s0));
  padding: var(--s0);
  border-radius: var(--r-sm);
}
.document-track-summary::-webkit-details-marker { display: none; }
.document-track-summary:active { background: var(--surface-2); }
.document-track:not([open]) .lesson-stage-toggle { transform: rotate(0); }

.document-items { margin-top: var(--s0); border-top: 0.5px solid var(--hairline); }
.document-item {
  appearance: none;
  width: 100%;
  min-height: 72px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  display: flex;
  align-items: center;
  gap: var(--s1);
  padding: var(--s1) 0;
}
.document-item + .document-item { border-top: 0.5px solid var(--hairline); }
button.document-item { cursor: pointer; transition: transform var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out); }
button.document-item:active { transform: scale(0.985); background: var(--surface-2); }
.document-item-copy { min-width: 0; }
.document-item-copy .title,
.document-item-copy .meta { overflow-wrap: anywhere; }
.document-item > .badge { flex: 0 0 auto; align-self: flex-start; margin-top: var(--s-1); }
.document-badge-trouble { background: rgba(217, 111, 36, 0.14); color: var(--warn); }
.document-empty-track { padding: var(--s1) 0 var(--s0); }

.lesson-lock,
.lesson-safety {
  border-radius: var(--r-lg);
  padding: var(--s2);
}
.lesson-lock {
  background: var(--tint-soft);
  border: 0.5px solid rgba(79, 88, 216, 0.3);
}
.lesson-safety {
  background: rgba(217, 111, 36, 0.1);
  border: 0.5px solid rgba(217, 111, 36, 0.35);
}

.lesson-evidence-list { display: flex; flex-direction: column; }
.lesson-evidence { padding: var(--s1) 0; overflow-wrap: anywhere; }
.lesson-evidence + .lesson-evidence { border-top: 0.5px solid var(--hairline); }
.lesson-evidence > * + * { margin-top: var(--s0); }

@media (max-width: 360px) {
  .lesson-row { align-items: flex-start; flex-wrap: wrap; }
  .lesson-row > .badge { margin-left: 46px; }
  .lesson-card-head .segmented { width: 100%; }
  .lesson-card-head .segmented button { flex: 1; padding-inline: var(--s0); }
}

@media (forced-colors: active) {
  .lesson-lock,
  .lesson-safety { border: 1px solid CanvasText; }
}

/* ---------- skeleton shimmer ---------- */

.skel {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
  min-height: 16px;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* ---------- empty states ---------- */

.empty-state {
  text-align: center;
  padding: var(--s5) var(--s3);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s1);
}
.empty-state .title2 { color: var(--text); }
.empty-state .meta { max-width: 34ch; }

/* ---------- sheet ---------- */

.sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity var(--t-med) var(--ease-out);
}
.sheet-scrim.open { opacity: 1; }

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 61;
  background: var(--surface-2);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  border-top: 0.5px solid var(--hairline);
  padding: var(--s1) var(--gutter) calc(var(--s3) + var(--safe-bottom));
  box-shadow: var(--elev-3);
  transform: translateY(100%);
  transition: transform var(--t-slow) var(--ease-spring);
  max-height: 86dvh;
  overflow-y: auto;
}
.sheet.open { transform: translateY(0); }
.sheet .grabber {
  width: 36px;
  height: 5px;
  border-radius: var(--r-pill);
  background: var(--text-3);
  margin: 0 auto var(--s2);
}

/* ---------- toast ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--s4) + var(--safe-bottom));
  transform: translate(-50%, 16px);
  z-index: 80;
  background: var(--surface-3);
  border: 0.5px solid var(--hairline);
  color: var(--text);
  padding: 11px 18px;
  border-radius: var(--r-pill);
  font-size: var(--fs-meta);
  font-weight: 500;
  box-shadow: var(--elev-2);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-med) var(--ease-out), transform var(--t-med) var(--ease-out);
  max-width: calc(100vw - 2 * var(--gutter));
  text-align: center;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- staggered entrances ---------- */

.enter > * {
  animation: rise var(--t-slow) var(--ease-out) both;
}
.enter > *:nth-child(2) { animation-delay: 40ms; }
.enter > *:nth-child(3) { animation-delay: 80ms; }
.enter > *:nth-child(4) { animation-delay: 120ms; }
.enter > *:nth-child(5) { animation-delay: 160ms; }
.enter > *:nth-child(n + 6) { animation-delay: 200ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* view transitions */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: fade-out 140ms var(--ease-out) both; }
  ::view-transition-new(root) { animation: rise 220ms var(--ease-out) both; }
}
@keyframes fade-out { to { opacity: 0; } }

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .slot.empty {
    animation: none;
    border-color: var(--tint);
    box-shadow: inset 0 0 0 1px rgba(217, 166, 72, 0.4);
  }
  .enter > * { animation: none; }
}

/* ---------- utility ---------- */

.stack { display: flex; flex-direction: column; gap: var(--s2); }
.stack-tight { display: flex; flex-direction: column; gap: var(--s0); }
.center { text-align: center; }
.gold { color: var(--tint); }
.dim { color: var(--text-2); }
.mt1 { margin-top: var(--s1); }
.mt2 { margin-top: var(--s2); }
.mt3 { margin-top: var(--s3); }
.hidden { display: none !important; }

/* Visually hidden but still a real, laid-out, clickable element. Used for the
   import file input: a display:none input is one of the ways iOS Safari
   refuses to open the file picker on a programmatic .click(). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* "Coming from Voice Memos?" disclosure under the import button. */
.help { margin-top: var(--s1); }
.help > summary {
  cursor: pointer;
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 2px;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.help > summary::-webkit-details-marker { display: none; }
.help > div { margin-top: var(--s1); text-align: left; }

/* ---------- Today: the daybook layout (2026-08-02) ----------
   The home screen failed on affordance, not on colour. Six elements sat in
   three visual styles, all of them tappable except one stat, and the phrase
   "Resume the active song" was inert text that read as a command. The fix is
   structural: exactly one primary action, facts that can never be mistaken for
   controls, and navigation grouped into chrome pinned to the bottom instead of
   three loose words floating mid-page. */

.today {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

/* Masthead: dated standfirst, title, key line, ruled off like a page heading. */
.masthead {
  padding-bottom: var(--s2);
  border-bottom: 0.5px solid var(--hairline);
}

/* Facts live below a divider inside the card. They carry no border, no colour
   and no padding box, so nothing about them suggests a target. */
.hero-facts {
  margin-top: var(--s2);
  padding-top: var(--s1);
  border-top: 0.5px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.fact {
  font-size: var(--fs-meta);
  color: var(--text-2);
  /* An explicit non-target. If this ever starts looking pressable, that is the
     regression this whole section exists to prevent. */
  cursor: default;
}

/* The shelf: grouped navigation, pushed to the bottom of the view, separated
   from content by a rule so it reads as chrome. */
.shelf {
  /* Follows the content rather than being pushed to the floor. Pinning it to
     the bottom of the viewport looked deliberate on a full screen and opened a
     dead zone on a sparse one, which is the failure this screen already had. */
  margin-top: var(--s3);
  padding-top: var(--s2);
  border-top: 0.5px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s0);
}

.shelf-link {
  appearance: none;
  border: 0.5px solid var(--hairline);
  background: var(--surface);
  color: var(--text);
  font: 600 var(--fs-meta) var(--font-ui);
  min-height: 44px;
  padding: 0 var(--s2);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease-out);
}

.shelf-link:active { background: var(--surface-2); }

/* The empty state was a 444px block with a hole in the middle. Let it sit at a
   natural reading position instead of centring into a void. */
.empty-state {
  padding-top: var(--s4);
  max-width: 34ch;
}

/* ---------- Focused workspace (2026-08-03) ----------
   A song is a working document, not a dashboard. The primary screens use
   rules, compact rows, and one strong action. Cards remain available to the
   deeper lesson and document tools where grouping is genuinely useful. */

.bar-action {
  appearance: none;
  border: 0;
  background: none;
  color: var(--text);
  min-height: 44px;
  padding: 0;
  font: 600 var(--fs-meta) var(--font-ui);
  white-space: nowrap;
}

.song-workspace {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.session-strip {
  min-height: 36px;
  display: flex;
  align-items: center;
  padding: 0 var(--s1);
  border: 0.5px solid var(--hairline);
  border-radius: var(--r-sm);
  background: rgba(251, 248, 241, 0.55);
}

.song-meta-strip {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s1);
  border-bottom: 0.5px solid var(--hairline);
}

.song-meta-button {
  appearance: none;
  border: 0;
  background: none;
  color: var(--text-2);
  min-height: 44px;
  min-width: 44px;
  padding: 0;
  text-align: left;
  font: 500 var(--fs-meta) var(--font-ui);
}

.work-block {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  padding: var(--s3) 0;
  border-top: 1px solid var(--text);
  border-bottom: 0.5px solid var(--hairline);
}

.work-title {
  max-width: 28ch;
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.18;
}

.work-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-1);
  margin-top: var(--s0);
}

.section-group,
.tool-group {
  display: flex;
  flex-direction: column;
  gap: var(--s0);
  margin-top: var(--s3);
}

.map {
  gap: 0;
  border-top: 0.5px solid var(--hairline);
}

.map-row,
.map-row.empty {
  min-height: 72px;
  padding: var(--s1) 0;
  border-bottom: 0.5px solid var(--hairline);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  animation: none;
}

.map-row.trouble {
  box-shadow: inset 3px 0 0 var(--warn);
  padding-left: var(--s1);
}

.section-copy {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.section-copy > .title,
.section-copy > .meta {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.section-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1);
  margin-top: var(--s-1);
}

.section-action {
  flex: 0 0 auto;
  color: var(--text);
  font-size: var(--fs-meta);
  font-weight: 700;
}

.record-action,
.record-again {
  color: var(--record);
}

.tool-group {
  padding-top: var(--s2);
  border-top: 0.5px solid var(--hairline);
}

.utility-group {
  display: flex;
  flex-direction: column;
  margin-top: var(--s3);
  border-top: 0.5px solid var(--hairline);
}

.compact-tools {
  margin-top: 0;
}

.compact-tools .utility-row {
  min-height: 56px;
}

.utility-row {
  appearance: none;
  width: 100%;
  min-height: 64px;
  padding: var(--s1) 0;
  border: 0;
  border-bottom: 0.5px solid var(--hairline);
  background: none;
  color: var(--text);
  display: flex;
  align-items: center;
  gap: var(--s2);
  text-align: left;
}

.utility-copy {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.utility-arrow {
  color: var(--text-3);
  font-size: 24px;
  line-height: 1;
}

.today-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s0);
  max-width: 34ch;
  padding: var(--s3) 0;
}

.today-work { margin-top: var(--s0); }

.secondary-action {
  appearance: none;
  width: 100%;
  min-height: 52px;
  border: 0;
  border-bottom: 0.5px solid var(--hairline);
  background: none;
  font: 700 var(--fs-body) var(--font-ui);
  text-align: center;
}

/* ---------- audio transport ---------- */

.transport {
  display: flex;
  flex-direction: column;
  gap: var(--s0);
  padding: var(--s1) 0;
}

.transport-times {
  display: flex;
  justify-content: space-between;
  color: var(--text-2);
  font-size: var(--fs-meta);
  font-variant-numeric: tabular-nums;
}

.transport-range {
  width: 100%;
  min-height: 44px;
  margin: 0;
  accent-color: var(--tint);
}

.transport-button { margin-top: var(--s-1); }
.transport[data-playback-state="playing"] .transport-button.btn-quiet { background: var(--surface-3); color: var(--text); }
.transport-compact { width: 100%; padding: var(--s0) 0 0; }
.transport-compact .transport-times,
.transport-compact .transport-range { display: none; }
.transport-compact .transport-button { min-height: 44px; }

.sheet-action-list {
  display: flex;
  flex-direction: column;
  border-top: 0.5px solid var(--hairline);
}

.sheet-action-row {
  appearance: none;
  min-height: 56px;
  border: 0;
  border-bottom: 0.5px solid var(--hairline);
  background: none;
  color: var(--text);
  font: 600 var(--fs-body) var(--font-ui);
  text-align: left;
  padding: 0;
}

.sheet-action-row.record-again { color: var(--record); }

@media (max-width: 360px) {
  .topbar .bar-side { min-width: 58px; }
  .work-title { font-size: 23px; }
  .section-copy > .meta { max-width: 210px; }
}
