:root {
  --bg: #120f0c;
  --bg2: #1a1511;
  --panel: #221c16;
  --ink: #f3ece3;
  --muted: #b7a894;
  --line: rgba(243, 236, 227, 0.1);
  --copper: #c9854a;
  --copper2: #e2b07a;
  --ivory: #f7f1e6;
  --ivory2: #e7dccb;
  --ebony: #161310;
  --felt: #7a2430;
  --good: #d7c4a3;
  --shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { height: 100%; font-size: 16px; } /* K-19: rem base; touch devices rescale it from iOS Larger Text (js/app.js applyTextScale) */
body {
  min-height: 100%;
  color: var(--ink);
  font-family: var(--sans);
  background:
    radial-gradient(1200px 500px at 50% -10%, #3a2a1c 0%, transparent 55%),
    linear-gradient(180deg, var(--bg2), var(--bg));
  /* 2.1.10: html is one screen tall, so a repeating gradient drew a hard line 720 px down. */
  background-color: var(--bg);
  background-repeat: no-repeat;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  width: min(760px, calc(100% - 32px));
  margin: 0 auto;
  padding: 36px 0 48px;
}
.wrap.intro {
  padding-bottom: 8px;
}
.wrap:not(.intro) {
  padding-top: 10px;
}

header {
  text-align: center;
  margin-bottom: 28px;
}
.brand {
  font-family: var(--serif);
  font-size: 0.8125rem;
  letter-spacing: 0.38em;
  text-transform: uppercase;
  color: var(--copper2);
  margin: 0 0 6px;
}
.build {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}
h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.25rem, 6vw, 3.375rem);
  letter-spacing: -0.03em;
  margin: 0 0 8px;
}
.lede {
  margin: 0;
  color: var(--muted);
  font-size: 1.0625rem;
}
/* 2.1.21: the top is one slim line (Keysong + version). Tap Keysong to open the welcome words. */
header { margin-bottom: 8px; }
.top-line { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: nowrap; min-width: 0; }
.top-line .build { margin: 0; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.intro-toggle { background: none; border: 0; padding: 4px 6px; cursor: pointer; margin: 0; min-height: 32px; flex: none; }
html.touch .intro-toggle { min-height: 44px; }
.intro-toggle:hover, .intro-toggle:focus-visible { color: var(--copper); }
.intro-caret { display: inline-block; letter-spacing: 0; transition: transform 0.15s; }
.intro-toggle[aria-expanded="true"] .intro-caret { transform: rotate(180deg); }
.intro-more { margin-top: 6px; }
.intro-more[hidden] { display: none !important; }

.piano-shell {
  position: relative;
  width: calc(100% - 24px);
  max-width: 2400px;
  margin: 8px auto 18px;
  background: linear-gradient(180deg, #4a3424 0%, #2a1c14 100%);
  border-radius: 16px;
  padding: 16px 12px 14px;
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,.14);
}
.midi-lamp, .midi-pair {
  position: absolute;
  top: 8px;
  z-index: 5;
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 999px;
  font: 600 0.8125rem/1.2 var(--sans);
}
.midi-lamp {
  right: 12px;
  margin: 0;
  padding: 3px 8px;
  color: #1a110a;
  background: rgba(226, 176, 122, 0.92);
  pointer-events: none;
}
.midi-pair {
  left: 12px;
  padding: 3px 8px;
  border: 1px solid rgba(226, 176, 122, 0.55);
  background: rgba(18, 15, 12, 0.55);
  color: var(--ivory);
}
.midi-lamp[hidden], .midi-pair[hidden] { display: none !important; }
.felt {
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(90deg, #5c1b24, var(--felt), #5c1b24);
  margin: 0 6px 10px;
}
.piano-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  scrollbar-color: rgba(201,133,74,.55) transparent;
  -webkit-overflow-scrolling: touch;
}
.piano {
  --ww: 44px;
  --bw: 28px;
  position: relative;
  height: 188px;
  user-select: none;
}
.whites {
  display: flex;
  height: 100%;
}
.white {
  position: relative;
  flex: 0 0 var(--ww);
  width: var(--ww);
  border: 0;
  border-radius: 0 0 7px 7px;
  background: linear-gradient(180deg, var(--ivory) 0%, var(--ivory2) 100%);
  color: #3a220c;
  font: 800 14px/1 var(--sans);
  padding-top: 148px;
  /* 2.1.24: clearer keys. Darker dividers between white keys and dark note names (Pete 2026-11-08 "keys more visible"). */
  box-shadow: inset -2px 0 0 rgba(60, 35, 12, 0.45), inset 0 -10px 16px rgba(80, 50, 20, 0.14), 0 8px 0 #a8946f;
  cursor: pointer;
}
.white .letter {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 32px;
  text-align: center;
  font-size: var(--ls, 13px);
  font-weight: 900;
  letter-spacing: 0;
  color: #2a1608;
}
.white.octave { color: #5a3a18; font-weight: 700; }
.white:hover { filter: brightness(1.03); }
.white.home {
  box-shadow: inset -1px 0 0 rgba(80, 50, 20, 0.12), inset 0 0 0 2px rgba(201, 133, 74, 0.45), 0 8px 0 #c4b49a;
}
.white.selected {
  background: linear-gradient(180deg, #fff8ee, #f0d8b0);
  color: #5a3a18;
  box-shadow: inset 0 0 0 2px var(--copper), 0 6px 0 #c4b49a;
}
.white.on {
  background: linear-gradient(180deg, #ffe2b0, #e09a48);
  color: #3a220c;
  box-shadow: inset 0 0 0 2px #c9854a, 0 6px 0 #b07d3c;
}
.white.under {
  background: linear-gradient(180deg, #f3e6cf, #dfc9a4);
  box-shadow: inset -1px 0 0 rgba(80, 50, 20, 0.12), inset 0 0 0 1px rgba(201, 133, 74, 0.35), 0 8px 0 #c4b49a;
}
.black.under {
  background: linear-gradient(180deg, #5a4a3a, #2a2018);
  box-shadow: inset 0 0 0 1px rgba(226, 176, 122, 0.4), 0 8px 10px rgba(0,0,0,.35);
}
.white:active { transform: translateY(2px); box-shadow: 0 4px 0 #c4b49a; }
.white.next {
  background: linear-gradient(180deg, #f0b56a, #d98a3a) !important;
  color: #2a1606;
  box-shadow: inset 0 0 0 3px var(--copper2), 0 0 0 4px rgba(232, 162, 74, 0.55), 0 6px 0 #8a5a2a;
}
.white.next-legacy {
  background: linear-gradient(180deg, #fff3dc, #f3c98a);
  color: #3a220c;
  box-shadow: inset 0 0 0 3px var(--copper), 0 0 0 3px rgba(226, 176, 122, 0.45), 0 6px 0 #b07d3c;
  animation: nextPulse 1.1s ease-in-out infinite;
}
.white.wrong, .black.wrong {
  animation: wrongShake 0.3s ease;
  box-shadow: inset 0 0 0 3px #b23b3b !important;
}
@keyframes nextPulse {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.16); }
}
@keyframes wrongShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}
.blacks { position: absolute; inset: 0 0 38% 0; pointer-events: none; }
.black {
  pointer-events: auto;
  position: absolute;
  top: 0;
  width: var(--bw);
  height: 100%;
  border: 0;
  border-radius: 0 0 5px 5px;
  background: linear-gradient(180deg, #3a342e, var(--ebony));
  color: transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 0 0 1.5px #000, 0 8px 10px rgba(0,0,0,.5);
  cursor: pointer;
}
.black .letter {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10px;
  text-align: center;
  color: #ffe2b0;
  font: 800 var(--ls, 12px)/1 var(--sans);
  letter-spacing: 0;
}
.black.home { box-shadow: inset 0 0 0 2px rgba(226, 176, 122, 0.55); }
.black.selected {
  background: linear-gradient(180deg, #6a4a2a, #2a1a10);
  box-shadow: inset 0 0 0 2px var(--copper2);
}
.black.on {
  background: linear-gradient(180deg, #c9854a, #5a3010);
  box-shadow: inset 0 0 0 2px var(--copper2);
}
.black:active { transform: translateY(1px); }
.black.next {
  background: linear-gradient(180deg, #e2b07a, #8a5a2a);
  box-shadow: inset 0 0 0 3px var(--copper2), 0 0 0 4px rgba(232, 162, 74, 0.55), 0 8px 10px rgba(0,0,0,.35);
  animation: nextPulse 1.1s ease-in-out infinite;
}
.white.mapped .letter, .black.mapped .letter { opacity: 1; }

.key-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 12px;
  padding: 2px 4px 0;
}
.octave-btns {
  display: flex;
  align-items: center;
  gap: 10px;
}
.auto-chords {
  display: flex;
  align-items: center;
  gap: 10px;
}
.auto-chords .opt-label { margin: 0; color: var(--ivory); }
.auto-chords .seg { min-width: 150px; }
.octave-btns p {
  margin: 0;
  color: var(--ivory);
  font-size: 0.875rem;
}
.octave-btns strong {
  font-family: var(--serif);
  font-size: 1.125rem;
  font-weight: 400;
}
.octave-btns button {
  border: 1px solid rgba(243, 236, 227, 0.18);
  background: rgba(0, 0, 0, 0.28);
  color: var(--ink);
  border-radius: 10px;
  padding: 8px 12px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.octave-btns button:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.comp-shell {
  width: min(calc(100% - 24px), 1100px);
  margin: 8px auto 22px;
  background: linear-gradient(180deg, #2a231c, var(--panel));
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px 18px 16px;
}
.comp-ask {
  text-align: center;
  margin-bottom: 14px;
}
.comp-ask-q {
  font-family: var(--serif);
  font-size: 1.375rem;
  margin: 0 0 10px;
}
.comp-ask .seg {
  max-width: 420px;
  margin: 0 auto;
}
.seg.big button {
  font-size: 0.9375rem;
  padding: 12px 10px;
}
.comp-ask-h {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 0.875rem;
}
.comp-lede {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.9375rem;
  text-align: center;
  line-height: 1.45;
}
.comp-scroll {
  overflow-x: auto;
  padding-bottom: 6px;
  scrollbar-width: thin;
}
.comp-board {
  min-width: 760px;
  background: #161310;
  border-radius: 14px;
  padding: 16px 14px 14px;
}
.ckey-row {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-bottom: 6px;
}
.ckey {
  box-sizing: border-box;
  min-width: 54px;
  height: 70px;
  margin: 0;
  border: 1px solid rgba(243, 236, 227, 0.12);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding: 6px 7px 8px;
  cursor: pointer;
  user-select: none;
  text-align: left;
  color: var(--ink);
  background: #2a241c;
}
.comp-board.mac .ckey { border-radius: 10px; }
.comp-board.pc .ckey { border-radius: 5px; }
.ckey-letter {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  opacity: 0.72;
}
.ckey-note {
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 400;
  line-height: 1;
  align-self: flex-end;
}
.ckey-shift {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  opacity: 0.8;
  align-self: flex-end;
}
.ckey.natural {
  background: linear-gradient(180deg, #f7f1e6, #e7dccb);
  color: #1a110a;
  border-color: rgba(80, 50, 20, 0.18);
}
.ckey.sharp {
  background: linear-gradient(180deg, #3a342e, #161310);
  color: #f0d8b0;
}
.ckey.action {
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  border: 0;
}
.ckey.dim {
  opacity: 0.42;
  cursor: default;
  min-width: 46px;
  height: 52px;
  align-self: flex-end;
}
.ckey.wide { min-width: 280px; align-items: center; }
.ckey.wide .ckey-note { align-self: center; }
.ckey.enter { min-width: 92px; }
.ckey.hit {
  box-shadow: 0 0 0 2px var(--copper2);
  filter: brightness(1.08);
}
.ckey.next {
  box-shadow: 0 0 0 3px var(--copper2), 0 0 18px rgba(226, 176, 122, 0.55);
  animation: nextPulse 1.1s ease-in-out infinite;
}
.ckey-spacer { width: 28px; flex: 0 0 28px; }
.ckey-spacer.lg { width: 44px; flex: 0 0 44px; }
.letter-layout {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.letter-layout .seg { min-width: 240px; }

.home-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 6px 2px 22px;
  color: var(--muted);
  font-size: 0.875rem;
}
.home-row strong {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.375rem;
  font-weight: 400;
}

.songs-wrap { padding-top: 4px; padding-bottom: 8px; }
.songs { margin: 0 2px 14px; }
.song-opts {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 14px;
  margin: 0 2px 4px;
  align-items: end;
}
.song-speed .seg { max-width: 520px; }
/* 2.1.22: How fast slider, 50%..100%. Big thumb so a child can drag it. */
.speed-slider { display: flex; align-items: center; gap: 10px; min-height: 44px; max-width: 520px; padding: 0 12px; border-radius: 999px; background: var(--panel, rgba(255,255,255,0.04)); border: 1px solid rgba(255,255,255,0.08); }
.speed-end { font-size: 0.8125rem; color: var(--muted); flex: none; }
.speed-slider input[type="range"] { flex: 1; min-width: 0; height: 44px; margin: 0; cursor: pointer; background: transparent; -webkit-appearance: none; appearance: none; touch-action: pan-y; }
.speed-slider input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: linear-gradient(90deg, var(--copper) 0 var(--fill, 100%), rgba(255,255,255,0.18) var(--fill, 100%) 100%); }
.speed-slider input[type="range"]::-moz-range-track { height: 6px; border-radius: 3px; background: rgba(255,255,255,0.18); }
.speed-slider input[type="range"]::-moz-range-progress { height: 6px; border-radius: 3px; background: var(--copper); }
.speed-slider input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 26px; height: 26px; margin-top: -10px; border-radius: 50%; background: linear-gradient(180deg, var(--copper2), var(--copper)); border: 2px solid #1a110a; box-shadow: 0 1px 4px rgba(0,0,0,0.5); }
.speed-slider input[type="range"]::-moz-range-thumb { width: 26px; height: 26px; border-radius: 50%; background: var(--copper2); border: 2px solid #1a110a; }
.speed-slider input[type="range"]:focus-visible { outline: 2px solid var(--copper2); outline-offset: 2px; border-radius: 8px; }
.song-spunk .seg button { white-space: nowrap; }
.speed-slider output { flex: none; min-width: 4.2em; text-align: right; font: 700 0.8125rem/1 var(--sans); color: var(--copper2); }
.learn-btn {
  width: 100%;
  border: 0;
  border-radius: 999px;
  padding: 10px 12px;
  font: 700 0.8125rem/1 var(--sans);
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  cursor: pointer;
}
.learn-btn:disabled { opacity: 1; cursor: not-allowed; background: rgba(201, 133, 74, 0.22); color: var(--copper2); border: 1px solid rgba(226, 176, 122, 0.5); }
.learn-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  margin: 12px 2px 0;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(226, 176, 122, 0.55);
  background: rgba(201, 133, 74, 0.12);
}
.learn-bar[hidden] { display: none; }
.learn-bar.done {
  border-color: rgba(215, 196, 163, 0.7);
  background: rgba(215, 196, 163, 0.12);
}
.learn-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.learn-text strong { font-family: var(--serif); font-weight: 400; font-size: 1.125rem; }
.learn-text span { color: var(--ink); font-size: 0.875rem; line-height: 1.4; }
.learn-actions { display: flex; gap: 8px; }
.learn-actions button {
  border: 1px solid var(--line);
  background: rgba(255,255,255,.06);
  color: var(--ink);
  border-radius: 8px;
  padding: 8px 12px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.learn-actions button:hover { border-color: rgba(201, 133, 74, .55); }
/* 2.1.28: a song played to the end gets a tick; the Done card offers the next song. */
.songs-count { margin: 0 2px 2px; color: var(--muted); font-size: 0.875rem; }
.songs-count[hidden] { display: none; }
.song-chip.learned::before { content: "\2713\00a0"; color: var(--copper2); font-weight: 800; }
.song-chip.on.learned::before { color: #1a110a; }
.learn-more { display: none; width: 100%; gap: 8px; flex-wrap: wrap; }
.learn-bar.done .learn-more { display: flex; }
.learn-more[hidden], .learn-more button[hidden] { display: none !important; }
.learn-more button {
  flex: 1 1 auto;
  border: 1px solid var(--line);
  background: rgba(255,255,255,.06);
  color: var(--ink);
  border-radius: 8px;
  padding: 10px 12px;
  font: 600 0.8125rem/1.1 var(--sans);
  cursor: pointer;
}
.learn-more button:hover { border-color: rgba(201, 133, 74, .55); }
.learn-more .next-song {
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  border-color: transparent;
  font-weight: 700;
}
html.touch .learn-more button { min-height: 48px; font-size: 0.9375rem; }
.songs-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}
.song-chip {
  border: 1px solid var(--line);
  background: rgba(255,255,255,.05);
  color: var(--ink);
  border-radius: 999px;
  padding: 8px 12px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.song-chip:hover { border-color: rgba(201, 133, 74, .55); }
.song-chip.on {
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  border-color: transparent;
}

.opts {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 14px;
  margin-bottom: 18px;
}
.opt-label {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.seg {
  display: flex;
  background: rgba(0,0,0,.28);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 3px;
}
.seg button {
  flex: 1;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: 600 0.8125rem/1 var(--sans);
  padding: 9px 6px;
  border-radius: 999px;
  cursor: pointer;
}
.seg button.on {
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
}

.vol-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 2px 16px;
  color: var(--muted);
  font-size: 0.8125rem;
}
.vol-row label { letter-spacing: 0.12em; text-transform: uppercase; font-size: 0.8125rem; }
.vol-row input[type="range"] {
  flex: 1;
  accent-color: var(--copper);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 22px;
}
.actions button {
  border: 0;
  cursor: pointer;
  border-radius: 12px;
  font: 700 0.9375rem/1 var(--sans);
  padding: 14px 14px;
}
.actions button:disabled {
  opacity: 0.38;
  cursor: not-allowed;
}
#btnWrite {
  flex: 1.6 1 140px;
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  box-shadow: 0 10px 24px rgba(201, 133, 74, 0.28);
}
#btnWrite.busy { filter: saturate(0.7); }
#btnPlay, #btnSaveWav, #btnSaveMid, #btnCopy, #btnLoop, #btnRec {
  flex: 1 1 110px;
  background: rgba(255,255,255,.06);
  color: var(--ink);
  border: 1px solid var(--line);
}
#btnLoop, #btnRec { flex: 0 1 96px; }
#btnLoop.on {
  background: rgba(201, 133, 74, 0.22);
  border-color: rgba(226, 176, 122, 0.7);
  color: var(--copper2);
}
#btnRec::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #c9503f;
  margin-right: 7px;
  vertical-align: -1px;
}
#btnRec.rec {
  background: rgba(178, 59, 59, 0.22);
  border-color: rgba(226, 120, 110, 0.7);
  color: #ffd9d2;
}
#btnRec.rec::before { animation: recBlink 1s steps(1) infinite; }
@keyframes recBlink { 50% { opacity: 0.25; } }
.kind-learn { color: #ffe2b0; }
.kind-record { color: #ffb8ad; }
.chord { cursor: pointer; }
.chord:hover { border-color: rgba(201, 133, 74, .45); }

.recents { margin-top: 16px; }
.activity {
  margin-top: 28px;
  background: linear-gradient(180deg, #2a231c, var(--panel));
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px;
}
.log-toggle {
  display: inline-block;
  margin: 2px 0 0;
  border: 1px solid rgba(243, 236, 227, 0.18);
  background: rgba(0, 0, 0, 0.22);
  color: var(--ink);
  border-radius: 10px;
  padding: 9px 14px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.log-toggle:hover { border-color: rgba(201, 133, 74, .55); }
.log-toggle[aria-expanded="true"] { margin-bottom: 12px; }
.activity-body[hidden] { display: none; }
.activity h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.375rem;
  margin: 0 0 4px;
}
.activity-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 14px;
}
.activity-lede {
  margin: 0;
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.45;
}
#logCount {
  color: var(--muted);
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  padding-top: 6px;
}
.keymap {
  margin: 0 0 14px;
  padding: 12px;
  background: rgba(0,0,0,.22);
  border-radius: 12px;
}
.keymap-grid {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 6px;
  margin-top: 8px;
}
.kpair {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 8px;
  font-size: 0.8125rem;
  background: rgba(255,255,255,.04);
}
.kpair .note {
  font-family: var(--serif);
  color: var(--ink);
}
.kpair.sharp {
  background: #161310;
}
.kpair.sharp .note { color: var(--copper2); }
.keymap-help {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.45;
}
.log-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}
.log-actions button {
  border: 1px solid var(--line);
  background: rgba(255,255,255,.06);
  color: var(--ink);
  border-radius: 8px;
  padding: 8px 12px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.log-actions button:hover { border-color: rgba(201, 133, 74, .55); }
.activity-log {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.8125rem;
  line-height: 1.55;
  max-height: 280px;
  overflow: auto;
  background: #100d0b;
  border-radius: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  min-height: 88px;
  scrollbar-width: thin;
}
.log-row {
  color: var(--good);
  white-space: pre-wrap;
  word-break: break-word;
}
.kind-key { color: var(--copper2); }
.kind-piano { color: var(--ink); }
.kind-write, .kind-play { color: #f0d8b0; }
.kind-button { color: #e2b07a; }
.kind-session, .kind-log { color: var(--muted); }
.kind-option, .kind-volume { color: #c9b89a; }
.kind-chord, .kind-recent { color: #d7c4a3; }
.recents-label {
  margin: 0 0 8px;
  font-size: 0.8125rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.recents-row {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: thin;
}
.recent {
  flex: 0 0 auto;
  border: 1px solid var(--line);
  background: rgba(255,255,255,.04);
  color: var(--ink);
  border-radius: 999px;
  padding: 8px 12px;
  font: 600 0.8125rem/1 var(--sans);
  cursor: pointer;
}
.recent:hover { border-color: rgba(201, 133, 74, .55); }

.sheet {
  background: linear-gradient(180deg, #2a231c, var(--panel));
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px 18px 16px;
  min-height: 148px;
}
#status {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1.45;
}
.progress {
  height: 3px;
  background: rgba(255,255,255,.08);
  border-radius: 99px;
  overflow: hidden;
  margin-bottom: 14px;
}
#progressFill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--copper), var(--copper2));
}
.chords {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
}
.chords.empty { display: none; }
/* 2.1.12: says whether the cards are notes or chords. */
.chords-label { margin: 10px 0 8px; font-size: 0.8125rem; color: var(--muted); }
.chord {
  flex: 0 0 calc((100% - 56px) / 8);
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 12px 6px;
  text-align: center;
  scroll-snap-align: center;
  transition: transform .18s ease, border-color .18s ease, background .18s ease;
}
.chord.now {
  transform: translateY(-2px);
  border-color: rgba(201, 133, 74, .7);
  background: rgba(201, 133, 74, .14);
}
.chords.melody .chord {
  flex: 0 0 56px;
  padding: 10px 4px;
}
.chords.melody .sym { font-size: 1.125rem; }
.sym {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 4vw, 1.75rem);
  line-height: 1.1;
}
.sub {
  margin-top: 4px;
  color: var(--muted);
  font-size: 0.8125rem;
}
#sentence { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
#saveHint {
  margin: 12px 0 0;
  color: var(--muted);
  font-size: 0.8125rem;
}

footer {
  margin-top: 26px;
  text-align: center;
  color: var(--muted);
  font-size: 0.8125rem;
  line-height: 1.55;
}
kbd {
  font: 600 0.8125rem var(--sans);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--good);
}

@media (max-width: 620px) {
  .wrap { width: min(100% - 20px, 760px); padding-top: 22px; }
  .piano-shell { width: calc(100% - 16px); padding: 12px 8px 10px; }
  .piano { height: 150px; }
  .white { padding-top: 114px; font-size: 11px; }
  .white .letter { bottom: 26px; }
  .black .letter { font-size: 11px; }
  .opts { grid-template-columns: 1fr; }
  .song-opts { grid-template-columns: 1fr; }
  .actions { flex-direction: column; }
  .chord { flex-basis: calc((100% - 8px) / 2); }
  .activity-head { flex-direction: column; }
  .keymap-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .key-bar { flex-direction: column; align-items: stretch; }
  .octave-btns { justify-content: space-between; }
  .comp-shell { width: calc(100% - 16px); padding: 14px 12px; }
  .ckey { min-width: 50px; height: 58px; }
  .ckey-note { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .chord, .white, .black { transition: none; }
  .white.next, .black.next, .ckey.next, .white.wrong, .black.wrong { animation: none; }
  #btnRec.rec::before { animation: none; }
}

/* ===== Touch devices (iPhone / iPad / Android). Desktop is untouched: everything is under html.touch / html.phone. ===== */
.touch-only { display: none; }
html.touch .kb-only { display: none !important; }
html.touch .touch-only { display: block; }
html.touch .octave-btns .touch-only { margin: 0; color: var(--ivory); font-size: 0.8125rem; }
html.touch .comp-shell { display: none; }
html.touch body { -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; }
html.touch button, html.touch .seg, html.touch .song-chip, html.touch .chord, html.touch .recent { touch-action: manipulation; }
/* 2.1.11: a double-tap on words no longer zooms the page; pinch zoom still works. */
html.touch body { touch-action: manipulation; }
/* 2.1.10: the recent-song chips were 31 px tall on iPad (fit check); 44 px is a finger. */
html.touch .recent { min-height: 44px; }
/* 2.1.13: sideways on the keys plays them (slide); up/down still scrolls the page. Lower / Higher move the strip. */
html.touch .piano { touch-action: pan-y; }
html.touch .piano-scroll { scrollbar-width: none; }
html.touch .piano-scroll::-webkit-scrollbar { display: none; }
html.touch .white, html.touch .black { -webkit-user-select: none; user-select: none; }
html.touch .white:hover { filter: none; }
html.touch .white .n { font-size: 12px; color: #4a3220; font-weight: 800; }
/* 2.1.30: the letter on the lit (orange) key was 4.32:1; the key's own dark ink is above 6:1 (tests/contrast.mjs). */
html.touch .white.next .n, .white.next .n { color: #2a1606; }
html.touch .white.octave .n { color: #2a1608; font-weight: 900; }
html.touch .seg button { min-height: 44px; }
html.touch .octave-btns button { min-height: 40px; padding: 8px 16px; }
html.touch .actions button { min-height: 46px; }
html.touch .song-chip { min-height: 40px; }
html.touch .white:active { transform: none; }
html.touch .white.on, html.touch .white.selected { transform: none; }

/* ----- Phone (narrow touch screen) ----- */
html.phone body { padding-bottom: env(safe-area-inset-bottom); }
html.phone .wrap.intro { padding-top: calc(4px + env(safe-area-inset-top)); padding-bottom: 0; width: calc(100% - 24px); }
html.phone header { margin-bottom: 2px; }
html.phone .top-line { justify-content: space-between; gap: 8px; }
html.phone .intro-toggle { letter-spacing: 0.2em; padding: 0 4px 0 0; }
html.phone .brand { font-size: 0.8125rem; margin-bottom: 4px; }
/* 2.1.15 (K-17): one short version line at the top on iPhone, with the TestFlight build inside the app. */
html.phone .build { display: block; font-size: 0.8125rem; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.phone h1 { font-size: 1.6875rem; margin: 0 0 4px; letter-spacing: -0.02em; }
html.phone .lede { font-size: 0.8438rem; line-height: 1.35; }
html.phone .piano-shell { width: calc(100% - 12px); margin: 6px auto 12px; padding: 10px 6px 8px; border-radius: 14px; }
html.phone .felt { margin: 0 4px 8px; height: 5px; }
html.phone .piano { height: 168px; }
html.phone .white { padding-top: 132px; font-size: 11px; border-radius: 0 0 6px 6px; box-shadow: inset -1px 0 0 rgba(80, 50, 20, 0.12), inset 0 -10px 16px rgba(80, 50, 20, 0.1), 0 6px 0 #c4b49a; }
html.phone .white .letter { display: none; }
html.phone .black .letter { display: none; }
html.phone .key-bar { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding: 0 2px; }
html.phone .octave-btns { gap: 6px; }
html.phone .octave-btns .touch-only { display: none; }
html.phone .octave-btns button { padding: 8px 12px; font-size: 0.8125rem; min-height: 38px; }
html.phone .auto-chords { gap: 6px; }
/* 2.1.28: no text under 11px (Apple refused another app on 2026-11-11 for hard-to-read type; Store's gate now measures it). */
html.phone .auto-chords .opt-label { font-size: 0.8125rem; letter-spacing: 0.06em; white-space: nowrap; }
html.phone .auto-chords .seg { min-width: 96px; }
.phone-only { display: none; }
html.phone .phone-only { display: inline; }
html.phone .phone-hide { display: none; }
html.phone .auto-chords .seg button { min-height: 44px; padding: 6px 8px; font-size: 0.8125rem; }
@media (orientation: landscape) {
  html.phone .wrap.intro { padding-top: 6px; }
  html.phone header { display: none; }
  html.phone .piano { height: 150px; }
  html.phone .white { padding-top: 116px; }
}
html.phone .wrap:not(.intro) { width: calc(100% - 24px); padding-top: 6px; }
html.phone .songs-wrap { padding-top: 0; }
html.phone .song-chip { font-size: 0.8125rem; padding: 8px 12px; }
html.phone .opts { gap: 10px; }
html.phone .opt-label { font-size: 0.8125rem; }
html.phone .seg button { font-size: 0.8125rem; padding: 8px 6px; }
html.phone .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
html.phone .actions #btnWrite { grid-column: 1 / -1; min-height: 52px; font-size: 1.0625rem; }
html.phone .actions button { flex: none; width: auto; }
html.phone .learn-bar { flex-direction: column; align-items: stretch; gap: 10px; }
html.phone .learn-actions button { flex: 1; min-height: 44px; }
html.phone .activity-log { max-height: 180px; }
html.phone footer { font-size: 0.8125rem; line-height: 1.5; }

html.phone body { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }

/* ===== Debut panel (2026-08-23): status mirror, action row under the piano, phone bar, focus, targets ===== */
.shell-status {
  margin: 10px 6px 0;
  color: var(--ivory);
  font-size: 0.8125rem;
  line-height: 1.3;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 17px;
  opacity: 0.92;
}
.shell-status:empty { display: none; }
.actions-wrap { padding-top: 0; padding-bottom: 4px; }
.actions-wrap .actions { margin-top: 0; }
:focus-visible { outline: 3px solid var(--copper2); outline-offset: 2px; }
.white:focus-visible, .black:focus-visible { outline-offset: -3px; }
html:not(.phone) .seg button.on::before { content: "✓ "; font-weight: 700; }
#btnWrite.busy { opacity: 0.8; }
.touch-only.inline { display: none; }
html.touch .touch-only.inline { display: inline; }
html.touch .kb-only.inline { display: none !important; }
html.touch #learnHelp[hidden] { display: none; }
html.native .chrome-only, html.native:not(.phone) .build, html.native #compAsk { display: none; }
html.touch .learn-btn, html.touch .log-toggle, html.touch .learn-actions button { min-height: 48px; font-size: 0.9375rem; }
html.touch .song-chip, html.touch .octave-btns button, html.touch .auto-chords .seg button { min-height: 44px; }
html.touch .white .n { font-size: 17px; }
html.touch .black::after { content: ""; position: absolute; inset: 0 -5px; }
.phone-bar { display: none; }
html.phone .piano-shell { position: sticky; top: env(safe-area-inset-top); z-index: 6; box-shadow: var(--shadow), 0 10px 30px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.14); }
html.phone { scroll-padding-top: 280px; }
/* The phone bar has Write / Play / Record; the row keeps Save sound, Save MIDI, Loop and Copy chords (App Review note step 3). */
html.phone .actions #btnWrite, html.phone .actions #btnPlay, html.phone .actions #btnRec { display: none; }
html.phone .actions button { min-height: 44px; }
html.phone .phone-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 7;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  background: var(--panel, #1d1610);
  border-top: 1px solid rgba(226, 176, 122, 0.35);
}
html.phone .phone-bar button {
  min-height: 44px; border: 1px solid rgba(243, 236, 227, 0.18); border-radius: 999px;
  background: rgba(0, 0, 0, 0.28); color: var(--ink); font: 700 0.875rem/1 var(--sans);
}
html.phone .phone-bar button[data-proxy="btnWrite"] { background: linear-gradient(180deg, var(--copper2), var(--copper)); color: #1a110a; border: 0; }
html.phone .phone-bar button.active { background: rgba(201, 133, 74, 0.35); border-color: var(--copper2); }
html.phone .phone-bar button:disabled { opacity: 0.4; }
html.phone body { padding-bottom: calc(70px + env(safe-area-inset-bottom)); }
html.phone .shell-status { font-size: 0.8125rem; margin-top: 8px; }
@media (orientation: landscape) {
  html.phone .piano { height: 110px; }
  html.phone .white { padding-top: 78px; }
  html.phone .key-bar { margin-top: 6px; }
}
@media (orientation: landscape) and (max-height: 900px) {
  html.touch:not(.phone) header { display: none; }
  html.touch:not(.phone) .wrap.intro { padding-top: 6px; }
}
@media (orientation: portrait) {
  html.touch:not(.phone) .piano-shell { position: sticky; top: 0; z-index: 6; }
}

/* ===== Mode bar: who plays ===== */
.mode-wrap { padding-top: 0; padding-bottom: 6px; }
.mode-seg { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; padding: 4px; }
.mode-seg button { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 9px 6px; min-height: 54px; line-height: 1.1; }
.mode-seg button strong { font-size: 0.875rem; font-weight: 700; }
.mode-seg button small { font-size: 0.8125rem; opacity: 0.75; font-weight: 500; }
.mode-seg button.on small { opacity: 0.9; }
html:not(.phone) .mode-seg button.on::before { content: none; }
.mode-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin-top: 8px; }
.mode-hint { margin: 0; color: var(--muted); font-size: 0.875rem; line-height: 1.4; flex: 1 1 280px; }
.accomp-row { display: flex; align-items: center; gap: 10px; }
.accomp-row .opt-label { margin: 0; white-space: nowrap; }
.accomp-row .seg { min-width: 220px; }
html.phone .mode-wrap { width: calc(100% - 24px); padding-top: 8px; }
html.phone .mode-seg button { min-height: 56px; padding: 8px 2px; }
html.phone .mode-seg button strong { font-size: 0.8125rem; }
html.phone .mode-seg button small { font-size: 0.8125rem; }
html.phone .mode-hint { font-size: 0.8125rem; }
html.phone .accomp-row { width: 100%; justify-content: space-between; }
html.phone .accomp-row .seg { min-width: 0; flex: 1; }
html.touch .mode-seg button { min-height: 58px; }

html.phone .mode-seg button small { display: none; }
html.phone .mode-seg button { min-height: 46px; }
html.phone .mode-seg button strong { font-size: 0.8438rem; }

/* Finishing a song: a light sweep across the piano (skipped under reduced motion). */
@keyframes doneSweep {
  0% { box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,.14); }
  40% { box-shadow: var(--shadow), 0 0 0 3px rgba(232,162,74,.55), inset 0 1px 0 rgba(255,255,255,.35); }
  100% { box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,.14); }
}
.piano-shell.done-flash { animation: doneSweep 0.7s ease-out 1; }
@media (prefers-reduced-motion: reduce) { .piano-shell.done-flash { animation: none; } }
/* Long songs: show every chord card instead of clipping at 8 (phones keep the swipe row). */
.chords.many { flex-wrap: wrap; }
html.phone .chords.many { flex-wrap: nowrap; }

/* Beginner tips, MIDI import, share, and a larger iPad piano. */
.beginner-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 6px; }
.beginner-row button {
  min-height: 48px;
  padding: 10px 16px;
  border-radius: 999px;
  font: 700 0.9375rem/1 var(--sans);
}
#btnImport {
  background: transparent;
  color: var(--ink);
  border: 1px solid rgba(243, 236, 227, 0.35);
}
#btnShare {
  background: linear-gradient(180deg, var(--copper2), var(--copper));
  color: #1a110a;
  border: 0;
}
#btnShare:disabled { opacity: 0.4; }
.beginner-note { margin: 0 0 8px; color: var(--muted); font-size: 0.875rem; line-height: 1.4; }
.tips-btn {
  margin-top: 10px;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(243, 236, 227, 0.28);
  background: transparent;
  color: var(--ink);
  font: 700 0.875rem/1 var(--sans);
}
.coach {
  position: fixed;
  z-index: 30;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  width: min(460px, calc(100% - 24px));
  padding: 16px 16px 14px;
  border-radius: 18px;
  background: #2a2118;
  color: var(--ink);
  border: 1px solid rgba(226, 176, 122, 0.5);
  box-shadow: var(--shadow);
}
.coach[hidden] { display: none; }
/* The card never blocks the page: only its own buttons take clicks (2.1.8). */
.coach { pointer-events: none; }
.coach-actions button { pointer-events: auto; }
.coach-kicker {
  margin: 0 0 4px;
  color: var(--copper2);
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.coach h2 {
  margin: 0 0 8px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.875rem;
  letter-spacing: -0.02em;
}
.coach #coachBody { margin: 0 0 8px; font-size: 1rem; line-height: 1.45; }
.coach-count { margin: 0 0 12px; color: var(--muted); font-size: 0.8125rem; }
.coach-actions { display: flex; gap: 8px; }
.coach-actions button { flex: 1; min-height: 48px; border-radius: 999px; font: 700 1rem/1 var(--sans); }
#coachSkip { background: transparent; color: var(--ink); border: 1px solid rgba(243, 236, 227, 0.28); }
#coachNext { background: linear-gradient(180deg, var(--copper2), var(--copper)); color: #1a110a; border: 0; }
html.phone .coach { bottom: calc(78px + env(safe-area-inset-bottom)); }
html.coach-piano .piano-shell,
html.coach-songs .songs-wrap,
html.coach-beginner .beginner-row,
html.coach-tabs .tab-seg {
  outline: 3px solid var(--copper2);
  outline-offset: 3px;
  border-radius: 14px;
}
html.pad .wrap { width: min(1040px, calc(100% - 48px)); }
html.pad .piano { height: 280px; --ww: 58px; --bw: 36px; }
html.pad .white { padding-top: 232px; font-size: 16px; }
html.pad .white .n { font-size: 18px; }
html.pad .piano-shell {
  position: sticky;
  top: env(safe-area-inset-top);
  z-index: 6;
}
html.pad .song-chip { min-height: 48px; font-size: 1.0625rem; padding: 10px 16px; }
html.pad .mode-seg button { min-height: 64px; }
html.pad .mode-seg button small { display: block; font-size: 0.8125rem; }
html.pad .beginner-row button, html.pad .actions button { min-height: 52px; font-size: 1.0625rem; }
@media (orientation: landscape) {
  html.pad .wrap.intro { padding-top: 8px; padding-bottom: 0; }
  html.pad header { display: none; }
  html.pad .piano { height: 230px; }
  html.pad .white { padding-top: 182px; }
}


/* Tap targets: every control is at least 44 px tall (Apple's minimum for a finger).
   Last in the file so it wins over the phone and orientation rules above. The piano keys are
   excluded on purpose: they sit in #piano, marked data-qa-skip for the UI smoke harness. */
.octave-btns button,
.song-chip,
.seg button,
.learn-btn,
.learn-actions button,
.log-toggle,
.tips-btn,
.actions button {
  min-height: 44px;
}
.vol-row input[type="range"] { height: 44px; margin: 0; }
footer a {
  display: inline-block;
  color: var(--copper2);   /* was browser-default blue, unreadable on the dark footer */
  min-height: 44px;
  line-height: 44px;
  padding: 0 6px;
}

/* App Review points at Bluetooth MIDI / MIDI keyboard: a full finger target (Store, 2026-10-24). */
.midi-pair { min-height: 44px; padding: 8px 14px; font-size: 0.875rem; }
/* Under the tabs, not on the piano: a 44 px button covered the top of the first few keys. */
.midi-pair { position: static; flex: none; max-width: 100%; margin: 8px 0 0; }
.mode-wrap { display: flex; flex-wrap: wrap; align-items: center; column-gap: 12px; }
.mode-wrap .tab-seg { flex: 1 0 100%; }
.mode-wrap .mode-hint { flex: 1 1 240px; }

/* Off the phone there is no bottom bar, so the tab's main buttons hold the bottom of the screen
   when the page is taller than the window, as Write does on a phone. Only with room for it, or the
   strip would sit on the tabs. On Learn it waits for a song, or it would sit on the song list; a
   browser without :has() just leaves the row where it is. */
@media (min-width: 621px) and (min-height: 560px) {
  html:not(.phone):not(.tab-learn) .actions-wrap {
    position: sticky;
    bottom: 0;
    z-index: 4;
    padding-top: 8px;
    padding-bottom: calc(8px + env(safe-area-inset-bottom));
    background: #120f0c;
    box-shadow: 0 -10px 14px -6px #120f0c;
  }
  html:not(.phone):not(.tab-learn) .actions-wrap .actions { margin-bottom: 0; }
  html:not(.phone).tab-learn #songsWrap:has(#learnBar[hidden]) .song-opts:has(#btnLearn:not(:disabled)) {
    position: sticky;
    bottom: 0;
    z-index: 4;
    padding-top: 8px;
    padding-bottom: calc(8px + env(safe-area-inset-bottom));
    background: #120f0c;
    box-shadow: 0 -10px 14px -6px #120f0c;
  }
  /* While learning, the bar takes the strip's place so the lit key and its controls share the screen. */
  html:not(.phone).tab-learn .learn-bar {
    position: sticky;
    bottom: calc(8px + env(safe-area-inset-bottom));
    z-index: 4;
    background: #1c1510;
    box-shadow: 0 -10px 14px -6px #120f0c;
  }
}
/* A narrow desktop window: two neat columns, not a tall stack of stretched buttons. */
@media (max-width: 620px) {
  html:not(.phone) .actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  html:not(.phone) .actions button { flex: none; width: auto; }
  html:not(.phone) .song-opts { grid-template-columns: auto 1fr; gap: 8px; }
  html:not(.phone) header { margin-bottom: 4px; }
  html:not(.phone) .piano-shell { margin-bottom: 8px; }
}

/* A laptop screen: the words above the piano pushed Write off the bottom. */
@media (max-height: 860px) {
  html:not(.touch) .wrap.intro { padding-top: 14px; }
  html:not(.touch) header { margin-bottom: 8px; }
  html:not(.touch) .build { margin-bottom: 4px; }
  html:not(.touch) h1 { font-size: 2rem; margin-bottom: 0; }
  html:not(.touch) .lede { display: none; }
  /* The buttons say what they do, and a slimmer strip leaves songs showing above it. */
  html:not(.touch) .song-opts .opt-label { display: none; }
  html:not(.touch) .song-opts { align-items: center; }
}
@media (max-height: 640px) {
  html:not(.touch) h1 { display: none; }
  html:not(.touch) .piano { height: 150px; }
  html:not(.touch) .white { padding-top: 114px; }
  html:not(.touch) .piano-shell { margin-bottom: 8px; }
  html:not(.touch) .tab-seg button { min-height: 40px; }
  html:not(.touch) .songs { margin-bottom: 4px; }
  html:not(.touch) .mode-wrap .mode-hint { margin: 4px 0 0; }
  html:not(.touch) .midi-pair { margin-top: 4px; }
}

/* A sideways phone is only ~340 px tall: a pinned piano plus the bottom bar left a 55 px strip, and
   the tabs sat under the bar. There the piano scrolls with the page; a song brings it back (2.1.8). */
@media (orientation: landscape) and (max-height: 500px) {
  html.phone .piano-shell { position: relative; top: auto; }
  html.phone { scroll-padding-top: 0; }
}

/* ---------- 2.1.9: three tabs + one More drawer (Pete: "no one knows what all the tabs do") ---------- */
.tab-seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; }
.tab-seg button { min-height: 50px; font: 700 1rem/1.1 var(--sans); padding: 8px 6px; }
html:not(.phone) .tab-seg button.on::before { content: none; }
.mode-wrap .mode-hint { margin-top: 8px; }
html:not(.tab-learn) .tab-learn-only { display: none; }
html:not(.tab-play) .tab-play-only { display: none; }
/* What each tab shows in the button row. */
html.tab-play #btnRec, html.tab-play #btnShare { display: none; }
/* 2.1.11: Save sound / Save MIDI show on Learn a song too; leaving the tab clears the song. */
html.tab-learn #btnWrite, html.tab-learn #btnRec, html.tab-learn #btnShare { display: none; }
html.tab-record #btnWrite { display: none; }
#btnShare { border-radius: 999px; }
html.phone .tab-seg button { min-height: 3rem; font-size: 0.9375rem; }
html.pad .tab-seg button { min-height: 3.75rem; font-size: 1.125rem; }
/* 2.1.26 (Pete 11-09): Learn a song is the first and biggest button */
.tab-seg { grid-template-columns: 1.6fr 1fr 1fr; }
.tab-seg button.tab-learn { font-weight: 800; font-size: 1.125rem; }
.tab-seg button.tab-learn:not(.on) { color: var(--copper2); }
html.phone .tab-seg button.tab-learn { font-size: 1.0625rem; }
html.pad .tab-seg button.tab-learn { font-size: 1.3125rem; }
.more { margin: 18px 0 8px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); }
.more > summary {
  list-style: none; cursor: pointer; min-height: 48px; display: flex; align-items: center; justify-content: space-between;
  padding: 0 16px; font: 700 1rem/1 var(--sans); color: var(--ink);
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary::after { content: "Show"; font-size: 0.8125rem; font-weight: 600; color: var(--muted); }
.more[open] > summary::after { content: "Hide"; }
.more-body { padding: 4px 16px 16px; }
.more-h { margin: 16px 0 8px; font: 700 0.8125rem/1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.more-songs { display: grid; gap: 12px; }
.more-songs .accomp-row { display: flex; flex-wrap: wrap; }
.more .comp-shell { margin: 0; padding: 0; width: auto; background: none; border: 0; box-shadow: none; }
.more .comp-ask { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 8px; padding: 0; background: none; border: 0; }
.more .comp-ask-q { margin: 0; font-size: 0.875rem; }
.more .comp-ask-h:empty { display: none; }
html.touch .more .comp-shell { display: none; }
/* Phone bottom bar follows the tab: two big buttons, never a second copy of the tabs. */
html.phone .phone-bar { grid-template-columns: 1fr 1fr; }
html.phone.tab-play .phone-bar [data-proxy="btnLearn"], html.phone.tab-play .phone-bar [data-proxy="btnRec"],
html.phone.tab-learn .phone-bar [data-proxy="btnWrite"], html.phone.tab-learn .phone-bar [data-proxy="btnRec"],
html.phone.tab-record .phone-bar [data-proxy="btnWrite"], html.phone.tab-record .phone-bar [data-proxy="btnLearn"] { display: none; }
html.phone.tab-learn .phone-bar [data-proxy="btnLearn"] { order: 2; }
html.phone.tab-record .phone-bar [data-proxy="btnRec"] { order: -1; background: linear-gradient(180deg, var(--copper2), var(--copper)); color: #1a110a; border: 0; }

/* 2.1.18: on a phone, Piano | Organ sits beside Lower / Higher (no label: the words say it),
   so the Chords row stays clear of the bottom bar on an iPhone SE. */
html.phone .sound-pick .opt-label { display: none; }
html.phone .sound-pick .seg { min-width: 0; }
html.phone .sound-pick .seg button { padding: 6px 10px; }
/* 2.1.18: Spunk's Off | On means nothing without its name, so keep the label on desktop too. */
html:not(.touch) .song-opts .song-spunk .opt-label { display: inline; margin-right: 6px; }
.song-spunk { display: flex; align-items: center; gap: 6px; }
/* Band only plays on the Play tab, so it takes no room on Learn / Record. */
html.tab-learn .band-pick, html.tab-record .band-pick { display: none; }

/* 2.1.30: "More from Analog Arcade" (apps only). Text stays at 13px or more. */
.moreapps { margin-top: 18px; }
.moreapps-list { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 8px; }
.moreapps-list a {
  display: block; min-height: 44px; padding: 10px 14px; border-radius: 12px;
  border: 1px solid rgba(243, 236, 227, 0.28); color: var(--ink); text-decoration: none;
}
.moreapps-list a b { display: block; font: 700 0.9375rem/1.25 var(--sans); }
.moreapps-list a span { display: block; margin-top: 2px; font: 400 0.8125rem/1.3 var(--sans); opacity: 0.8; }
.ma-ask { display: flex; align-items: center; gap: 10px; min-height: 44px; margin-top: 8px; font: 400 0.875rem/1.3 var(--sans); }
.ma-ask input { width: 22px; height: 22px; }
