:root {
  --bg: #17130f;
  --panel: #201a15;
  --raised: #2a221c;
  --line: #3b3129;
  --text: #efe6d8;
  --soft: #b6a894;
  --home: #ffd66b;
  --land: #eaa53c;
  --wander: #33c7b5;
  --lean: #a87cff;
  --next: #ffffff;
  --why: 320px;
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--bg);
  color: var(--text);
  font:
    14px/1.45 system-ui,
    sans-serif;
}

#app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--why);
  grid-template-rows: auto auto auto minmax(0, 1fr) auto;
  height: 100vh;
  /* Without the browser's toolbars, which 100vh counts on a phone. */
  height: 100dvh;
}

body.why-closed #app {
  grid-template-columns: minmax(0, 1fr) 0;
}

body.why-closed #why {
  display: none;
}

#top {
  grid-column: 1 / -1;
  padding: 8px 14px 4px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}

#above {
  grid-column: 1;
  padding: 10px 14px 0;
}

#readout {
  grid-column: 1;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 6px 16px 0;
  min-height: 28px;
  font-size: 15px;
}

#now {
  color: var(--soft);
}

#holding {
  color: var(--home);
  font-weight: 600;
}

#stage {
  --overview: 0px;
  grid-column: 1;
  min-height: 0;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

#stage canvas {
  display: block;
  position: absolute;
  inset: var(--overview) 0 0;
  width: 100%;
  height: calc(100% - var(--overview));
  touch-action: none;
}

/* The strip that shows and moves the section of the instrument on the stage (view/overview.ts). */
#stage.windowed {
  --overview: 30px;
}

#stage #overview {
  display: none;
  inset: 5px 14px auto;
  width: calc(100% - 28px);
  height: calc(var(--overview) - 9px);
  border-radius: 3px;
  cursor: pointer;
}

#stage.windowed #overview {
  display: block;
}

#why {
  grid-column: 2;
  grid-row: 2 / 5;
  overflow-y: auto;
  padding: 12px 16px;
  border-left: 1px solid var(--line);
  background: var(--panel);
}

#legend {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  padding: 6px 14px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}

.row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 4px;
}

.spacer {
  flex: 1;
}

.quiet {
  color: var(--soft);
  font-size: 12.5px;
}

a.out {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--soft);
  font-size: 12.5px;
  text-decoration: none;
}

@media (hover: hover) {
  a.out:hover {
    color: var(--text);
  }
}

a.out svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.error {
  color: #ff8c7a;
}

label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--soft);
}

label.check {
  gap: 4px;
}

button,
select,
input {
  font: inherit;
  color: var(--text);
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 9px;
  touch-action: manipulation;
}

button {
  cursor: pointer;
}

/* Only where there's a real hover: a tap leaves a touch screen's hover stuck on. */
@media (hover: hover) {
  button:hover {
    border-color: #5a4a3d;
  }
}

button.icon {
  min-width: 2.1em;
  font-weight: 700;
}

button.primary {
  background: #3d2f1c;
  border-color: #7a5a2a;
}

button:disabled {
  opacity: 0.45;
  cursor: default;
}

input[type='number'] {
  width: 5.4em;
}

input[type='range'] {
  padding: 0;
  accent-color: var(--land);
}

input[type='checkbox'] {
  accent-color: var(--land);
}

#prog-text {
  flex: 1;
  min-width: 240px;
  font-family: ui-monospace, monospace;
}

code {
  font-family: ui-monospace, monospace;
  font-size: 0.92em;
  color: var(--text);
}

.seg {
  display: inline-flex;
}

.seg button {
  border-radius: 0;
}

.seg button:first-child {
  border-radius: 6px 0 0 6px;
}

.seg button:last-child {
  border-radius: 0 6px 6px 0;
  margin-left: -1px;
}

.seg button.on,
#try button.on {
  background: #4a3820;
  border-color: #8b6730;
}

body.mode-key #transport,
body.mode-key #lane,
body.mode-key #editor {
  display: none;
}

body.mode-progression #palette {
  display: none;
}

/* Chord cards: the lane and the palette */

#lane,
#palette {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.card {
  position: relative;
  min-width: 74px;
  padding: 6px 10px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--raised);
  text-align: left;
  color: var(--text);
}

.card .numeral {
  display: block;
  font-size: 19px;
  font-weight: 650;
  line-height: 1.2;
}

.card .name {
  display: block;
  color: var(--soft);
  font-size: 13px;
}

.card .tag {
  position: absolute;
  top: 5px;
  right: 7px;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--soft);
}

.card .beats {
  display: flex;
  gap: 3px;
  margin-top: 5px;
}

.card .beats i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--line);
}

.card .beats i.done {
  background: var(--land);
}

.card.current {
  border-color: var(--home);
  box-shadow:
    0 0 0 1px var(--home) inset,
    0 0 18px #ffd66b2e;
}

.card.next {
  border-style: dashed;
  border-color: #d9d2c5;
}

.card.next .tag {
  color: var(--next);
}

.card.selected {
  border-color: var(--land);
}

.job-borrowed .numeral {
  color: var(--lean);
}

.card.job-home,
.chip.job-home {
  border-left: 3px solid var(--land);
}

.card.job-away,
.chip.job-away {
  border-left: 3px solid var(--wander);
}

.card.job-tension,
.chip.job-tension {
  border-left: 3px solid var(--lean);
}

.card.held {
  background: #3d2f1c;
  border-color: var(--home);
}

/* The progression editor (ui/editor.ts): the progression on one line, three boxes of chords to
   pick from, and one bar under them with the chord picked and Add. Sized by its own width, so the
   phone's side sheet gets one column; there the bar sticks to the bottom so Add is never a scroll
   away. Kept low because it sits above the keys, which show the chord picked. */

#editor {
  container-type: inline-size;
  display: grid;
  gap: 8px;
  margin-bottom: 6px;
}

#editor[hidden] {
  display: none;
}

.ed {
  padding: 8px 10px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
}

.ed-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  margin-bottom: 6px;
}

#ed-text .row {
  margin: 0;
}

#ed-text h3 {
  margin-right: 2px;
}

#ed-text p {
  margin: 5px 0 0;
}

.save {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ed-picks {
  display: grid;
  gap: 8px;
  align-items: start;
}

@container (min-width: 900px) {
  .ed-picks {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  #try {
    grid-column: 1 / -1;
  }
}

@container (min-width: 1500px) {
  .ed-picks {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 0.95fr) minmax(0, 1.2fr);
  }

  #try {
    grid-column: auto;
  }
}

.group {
  display: grid;
  grid-template-columns: 5.2em minmax(0, 1fr);
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}

.group .sub {
  color: var(--soft);
  font-size: 12px;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.chip {
  min-width: 3em;
  padding: 2px 7px 3px;
  text-align: left;
  line-height: 1.2;
}

.chip .numeral {
  display: block;
  font-weight: 650;
}

.chip .name,
.chip .tag {
  display: block;
  color: var(--soft);
  font-size: 11.5px;
}

.chip .tag {
  font-size: 10.5px;
}

/* The chord the suggestions follow: a card, not a button. */
.chip.after {
  border: 1px solid var(--home);
  border-radius: 6px;
  background: var(--raised);
}

.kind {
  padding: 3px 8px;
}

/* What comes next: the groups side by side, each with its name over it. */
.flow {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 6px 12px;
}

.flow .arrow {
  margin-bottom: 14px;
  color: var(--soft);
  font-size: 18px;
}

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

.tier .cap {
  color: var(--soft);
  font-size: 10.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.ed .edges {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 12px;
  margin: 4px 0 0;
  font-size: 12px;
}

.swatch.edge::before {
  width: 3px;
  height: 13px;
  border-radius: 1px;
}

.swatch.job-home {
  --c: var(--land);
}

.swatch.job-away {
  --c: var(--wander);
}

.swatch.job-tension {
  --c: var(--lean);
}

.swatch.job-borrowed::before {
  display: none;
}

/* The chord picked, wherever it was clicked, and the one Add. */
.chosen {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  min-height: 42px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--raised);
}

.chosen.empty {
  align-items: center;
  border-style: dashed;
}

.chosen .big,
.chosen .numeral {
  font-size: 17px;
  font-weight: 650;
}

.chosen .big {
  color: var(--home);
}

.chosen .from {
  color: var(--soft);
  font-size: 15px;
}

.chosen .notes {
  font-family: ui-monospace, monospace;
}

.chosen .words {
  color: var(--soft);
  font-size: 12.5px;
}

.chosen button {
  align-self: center;
}

/* Narrow, as in the side sheet: names above their rows, and the text boxes free to shrink. */
@container (max-width: 560px) {
  .ed {
    padding: 8px 9px 10px;
  }

  .group {
    grid-template-columns: minmax(0, 1fr);
    gap: 3px;
    margin-bottom: 7px;
  }

  #prog-text,
  #save-name {
    flex: 1;
    min-width: 0;
  }

  .save {
    flex-basis: 100%;
  }

  .chosen .spacer {
    display: none;
  }

  .chosen button {
    flex-basis: 100%;
  }
}

/* Why panel */

#why h3,
#editor h3 {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--soft);
}

#why h3 {
  margin: 14px 0 4px;
}

#why h3:first-child {
  margin-top: 0;
}

#why p {
  margin: 0 0 6px;
}

/* Three lines, the longest a note's sentence runs in the side panel, so hovering never moves
   what's below. */
#why .note {
  min-height: calc(3 * 1.45em);
}

/* Soft, but not .quiet: its smaller font would shrink the em the height is measured in. */
#why .note.empty {
  color: var(--soft);
}

#why .big {
  font-size: 17px;
  font-weight: 600;
}

#why .tip {
  border-left: 3px solid var(--land);
  padding-left: 9px;
  color: var(--text);
}

/* Legend swatches */

.swatch {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--soft);
}

.swatch::before {
  content: '';
  width: 14px;
  height: 6px;
  border-radius: 3px;
  background: var(--c);
}

.swatch.home {
  --c: var(--home);
}

.swatch.home::before {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: transparent;
  border: 2px solid var(--home);
}

.swatch.land {
  --c: var(--land);
}

.swatch.wander {
  --c: var(--wander);
}

.swatch.lean {
  --c: var(--lean);
}

.swatch.next {
  --c: var(--next);
}

.swatch.next::before {
  width: 13px;
  height: 13px;
  border-radius: 3px;
  background: radial-gradient(circle, #141210 0 30%, #f1ebdf 36%);
}

.swatch.star::before {
  content: '★';
  width: auto;
  height: auto;
  background: none;
  color: #fff1c4;
}

.swatch[hidden] {
  display: none;
}

/* Drawers and start overlay */

.panel {
  position: fixed;
  top: 54px;
  right: 14px;
  width: min(460px, calc(100vw - 28px));
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: 0 12px 40px #000a;
  z-index: 5;
}

.panel h2 {
  margin: 0;
  font-size: 16px;
}

.panel .grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  margin: 10px 0;
}

/* A select is as wide as its longest option; in a drawer it takes the room left instead, and
   the open list still shows each option in full. */
.panel .grid > label {
  min-width: 0;
}

.panel .grid > label:has(select) {
  white-space: nowrap;
}

.panel select {
  flex: 1;
  min-width: 0;
  text-overflow: ellipsis;
}

#clip-list {
  list-style: none;
  padding: 0;
  margin: 8px 0 0;
}

#clip-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 0;
  border-top: 1px solid var(--line);
}

#clip-list .what {
  flex: 1;
  min-width: 0;
}

#clip-list .what small {
  display: block;
  color: var(--soft);
}

#record.recording {
  border-color: #e5484d;
  color: #ff7a7a;
}

.panel h3 {
  margin: 14px 0 0;
  font-size: 14px;
}

.board-button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.board-button .what {
  flex: 1;
  min-width: 0;
}

.board-button small {
  display: block;
  color: var(--soft);
}

#record.flash,
#clip.flash {
  border-color: var(--home);
  color: var(--home);
}

#start {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: #0d0b09d9;
  z-index: 10;
}

#start[hidden] {
  display: none;
}

#start .card {
  max-width: 380px;
  padding: 22px 26px;
  text-align: left;
}

#start h1 {
  margin: 0 0 6px;
  font-size: 24px;
}

#start ul {
  list-style: none;
  padding: 0;
  margin: 12px 0 16px;
}

#start li {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 6px 0;
}

#start .swatch {
  gap: 0;
}

#start button {
  width: 100%;
  padding: 9px;
  font-size: 15px;
}

/* Guitar mode */

.badge {
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--wander);
  border: 1px solid #2c6f66;
  border-radius: 4px;
  padding: 0 4px;
  vertical-align: 1px;
}

body.instrument-piano #guitar-open,
body.instrument-guitar #fx-open,
body.instrument-guitar #range-row {
  display: none;
}

#guitar-open .light,
#fx-open .light {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--line);
}

#guitar-open.listening .light {
  background: var(--wander);
  box-shadow: 0 0 6px var(--wander);
}

#fx-open.active .light {
  background: var(--land);
  box-shadow: 0 0 6px var(--land);
}

#fx-open.on {
  background: #4a3820;
  border-color: #8b6730;
}

#guitar-status {
  margin: 8px 0;
}

#guitar-device-row[hidden],
#guitar-meter-row[hidden],
#guitar-record-row[hidden] {
  display: none;
}

#guitar-record.recording {
  border-color: #e5484d;
  color: #ff7a7a;
}

.live {
  display: flex;
  align-items: center;
  gap: 10px;
}

#guitar-heard {
  min-width: 11em;
  color: var(--home);
  font-weight: 600;
}

.meter {
  position: relative;
  flex: 1;
  min-width: 120px;
  height: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg);
}

.meter i {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--wander);
  transition: width 60ms linear;
}

/* Too quiet, good, loud, clipping; the stops are set from the setup's thresholds. */
.meter.zones {
  height: 18px;
  background: linear-gradient(
    to right,
    #2a221c 0 var(--good),
    #24453b var(--good) var(--loud),
    #4a3320 var(--loud) var(--clip),
    #6a2424 var(--clip)
  );
}

.meter.zones i {
  background: #efe6d88c;
}

/* Knobs in the middle are the sound as voiced. */
.knobs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 14px;
  margin: 8px 0;
}

.knobs label {
  justify-content: space-between;
}

.knobs input[type='range'] {
  width: 60%;
}

.knobs button {
  justify-self: start;
}

.strings {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px 10px;
  margin: 6px 0;
}

.strings label {
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  font-size: 12px;
}

/* The effects panel (ui/effects.ts): the explanations' column while it's open, so the keys keep
   their room. The media queries below put it under the keys on a phone held upright and over
   their right end on one on its side. Its blocks go side by side where it's wide enough. */

#fx {
  grid-column: 2;
  grid-row: 2 / 5;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 16px;
  border-left: 1px solid var(--line);
  background: var(--panel);
}

#fx[hidden],
body.fx-open #why {
  display: none;
}

body.fx-open #app {
  grid-template-columns: minmax(0, 1fr) var(--why);
}

#fx h2 {
  margin: 0;
  font-size: 16px;
}

#fx > p {
  margin: 6px 0 10px;
}

.fx-top {
  display: grid;
  gap: 6px;
  margin: 8px 0 0;
}

.fx-top label,
.fx-choice {
  min-width: 0;
}

.fx-top select,
.fx-top input[type='range'],
.fx-choice select {
  flex: 1;
  min-width: 0;
  text-overflow: ellipsis;
}

#fx-blocks {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  align-items: start;
  gap: 8px;
}

.fx-block {
  padding: 7px 10px 9px;
  border: 1px solid var(--line);
  border-radius: 10px;
}

.fx-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
}

.fx-title {
  color: var(--text);
  font-weight: 600;
}

.fx-knobs {
  display: grid;
  gap: 4px;
  margin-top: 6px;
}

.fx-knob {
  display: grid;
  grid-template-columns: 5.2em minmax(0, 1fr) 4.6em;
  gap: 8px;
}

.fx-knob input[type='range'] {
  width: 100%;
  min-width: 0;
}

.fx-knob output {
  text-align: right;
  color: var(--text);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

.fx-curve {
  display: block;
  width: 100%;
  height: 84px;
  margin-top: 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--bg);
}

/* Off, an effect's controls are still there to set, but quieter. */
.fx-block.off .fx-knobs,
.fx-block.off .fx-curve,
#fx.bypassed #fx-blocks {
  opacity: 0.55;
}

/* The guitar setup */

#setup {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: #0d0b09d9;
  z-index: 8;
}

#setup[hidden] {
  display: none;
}

#setup .card {
  width: min(520px, calc(100vw - 32px));
  padding: 18px 24px;
}

#setup h2 {
  margin: 2px 0 8px;
  font-size: 20px;
}

#setup-text p {
  margin: 0 0 8px;
}

#setup-show {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 12px 0;
}

#setup .channel {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--soft);
}

#setup .channel[hidden] {
  display: none;
}

#setup .say {
  min-height: 2.9em;
  font-size: 15px;
}

#setup .say.good {
  color: var(--wander);
}

#setup .say.warn {
  color: var(--land);
}

.tuner {
  position: relative;
  height: 46px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
}

.tuner b {
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: calc(50% - 1px);
  width: 2px;
  background: var(--soft);
}

.tuner i {
  position: absolute;
  top: 4px;
  bottom: 4px;
  width: 4px;
  margin-left: -2px;
  border-radius: 2px;
  background: var(--land);
  transition: left 80ms linear;
}

.tuner.in-tune {
  border-color: var(--wander);
}

.tuner.in-tune i {
  background: var(--wander);
}

.tuner span {
  position: absolute;
  bottom: 2px;
  font-size: 11px;
  color: var(--soft);
}

.tuner .flat {
  left: 8px;
}

.tuner .sharp {
  right: 8px;
}

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

.beats i {
  width: 16px;
  height: 16px;
  border: 2px solid var(--line);
  border-radius: 50%;
}

.beats i.play {
  border-color: var(--land);
}

.beats i.past {
  background: var(--soft);
}

.beats i.play.past {
  background: var(--land);
}

.choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.choice {
  padding: 10px 12px;
  font-size: 15px;
  text-align: left;
}

.summary {
  margin: 0;
  padding-left: 18px;
}

@media (prefers-reduced-motion: reduce) {
  .meter i,
  .tuner i {
    transition: none;
  }
}

#start button + button {
  margin-top: 8px;
}

/* First-run tour. The ring's shadow dims everything but its target; clicks pass through it. */

.tour-ring {
  position: fixed;
  z-index: 8;
  pointer-events: none;
  border: 2px solid var(--home);
  border-radius: 10px;
  box-shadow: 0 0 0 100vmax #0d0b0999;
  transition:
    left 0.25s,
    top 0.25s,
    width 0.25s,
    height 0.25s;
}

.tour-card {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 9;
  width: min(300px, calc(100vw - 20px));
  padding: 12px 14px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  box-shadow: 0 12px 40px #000a;
}

.tour-card.done {
  border-color: var(--wander);
}

.tour-card h2 {
  margin: 2px 0 6px;
  font-size: 16px;
}

.tour-card p {
  margin: 0 0 8px;
}

.tour-card .row {
  margin: 4px 0 0;
}

/* The menu: ☰ in the compact bar, and the drawer the rest of the controls move into (ui/menu.ts). */

#menu-open,
.in-menu,
.touch-only {
  display: none;
}

#menu-open {
  position: relative;
}

#menu-open svg {
  display: block;
  width: 18px;
  height: 18px;
}

/* While recording, so it can be seen with Record out of sight in the drawer. */
body:has(#record.recording) #menu-open::after {
  content: '';
  position: absolute;
  top: 3px;
  right: 3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #e5484d;
}

#menu {
  position: fixed;
  inset: 0;
  z-index: 7;
  background: #0d0b0999;
}

#menu .sheet {
  position: absolute;
  inset: 0 auto 0 0;
  width: min(340px, 88vw);
  overflow-y: auto;
  padding: 10px 14px 18px;
  border-right: 1px solid var(--line);
  background: var(--panel);
  box-shadow: 12px 0 40px #000a;
}

#menu h2 {
  margin: 0;
  font-size: 16px;
}

#menu section {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
}

#menu section:empty,
body.mode-key #menu [data-section='progression'] {
  display: none;
}

#menu h3 {
  flex-basis: 100%;
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--soft);
}

#menu label:has(select),
#menu label:has(input[type='range']) {
  flex-basis: 100%;
  min-width: 0;
}

#menu label select,
#menu label input[type='range'] {
  flex: 1;
  min-width: 0;
  text-overflow: ellipsis;
}

#menu .in-menu {
  display: inline;
}

#menu #midi {
  flex-basis: 100%;
}

#menu #midi:empty {
  display: none;
}

/* The chords and the explanations: a sheet on a short screen, and nothing of its own elsewhere. */
#side {
  display: contents;
}

/* Small screens: the compact bar. The query is COMPACT in src/tuning.ts; keep the two equal. */
@media (max-width: 900px), (max-height: 520px) {
  #top {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    padding: 6px 10px;
  }

  #top > .row {
    display: contents;
  }

  #top [data-menu],
  #legend [data-menu] {
    display: none;
  }

  #menu-open {
    display: inline-block;
  }

  #why-open {
    order: 1;
  }

  /* Floats under the bar while it has something to say, so it never moves the keys. */
  #tuning {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    z-index: 4;
    transform: translateX(-50%);
    padding: 3px 10px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--raised);
    white-space: nowrap;
    pointer-events: none;
  }

  #tuning:empty {
    display: none;
  }

  #above {
    padding: 8px 10px 0;
  }

  #readout {
    flex-wrap: wrap;
    gap: 0 12px;
    min-height: 24px;
    padding: 4px 12px 0;
    font-size: 14px;
  }

  #legend {
    gap: 4px 12px;
    padding: 5px 12px;
    font-size: 12.5px;
  }

  /* One row the lane scrolls along, following the chord playing (ui/lane.ts). */
  #lane {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  #lane::-webkit-scrollbar {
    display: none;
  }

  #lane .card {
    flex: none;
  }

  #palette {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(46px, 1fr));
    gap: 5px;
  }

  #palette .card {
    min-width: 0;
    padding: 5px 4px 6px;
    text-align: center;
  }

  #palette .card .numeral {
    font-size: 16px;
  }

  #palette .card .name {
    font-size: 12px;
  }

  #palette .card .tag {
    display: none;
  }

  .panel {
    top: 8px;
    left: 8px;
    right: 8px;
    width: auto;
    max-height: calc(100dvh - 16px);
  }
}

/* The narrowest: Play and Pause by their icons alone. */
@media (max-width: 480px) {
  #transport .word {
    display: none;
  }
}

/* Narrow and tall, like a phone held upright: one column, the explanations under the keys. */
@media (max-width: 900px) and (min-height: 521px) {
  #app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr) auto auto;
  }

  /* Open above the keys, it would push them off the screen: it scrolls in half the height. */
  #editor {
    max-height: 50dvh;
    overflow-y: auto;
  }

  #why {
    grid-column: 1;
    grid-row: 5;
    max-height: 24vh;
    border-left: none;
    border-top: 1px solid var(--line);
  }

  /* Taller than the explanations, since its sliders are for using while you play. */
  #fx {
    grid-column: 1;
    grid-row: 5;
    max-height: 42vh;
    border-left: none;
    border-top: 1px solid var(--line);
  }

  body.fx-open #app {
    grid-template-columns: minmax(0, 1fr);
  }

  #legend {
    grid-row: 6;
  }
}

/* Short, like a phone on its side: the keys get the whole width and height. The chords and the
   explanations are a sheet over the keys' right end that ? pulls out, and the readout sits in the
   middle of the bar, clear of the buttons either side. */
@media (max-height: 520px) {
  #app,
  body.why-closed #app,
  body.fx-open #app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  #top {
    grid-row: 1;
  }

  #stage {
    grid-row: 2;
  }

  #readout {
    grid-row: 1;
    grid-column: 1;
    z-index: 1;
    justify-self: center;
    align-self: center;
    flex-direction: column;
    align-items: center;
    gap: 0;
    max-width: calc(100% - 470px);
    min-height: 0;
    padding: 0;
    font-size: 13px;
    line-height: 1.3;
    pointer-events: none;
  }

  #readout span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  #readout span:empty {
    display: none;
  }

  #side {
    display: flex;
    flex-direction: column;
    grid-row: 2;
    grid-column: 1;
    justify-self: end;
    z-index: 3;
    width: min(320px, 45vw);
    min-height: 0;
    overflow-y: auto;
    border-left: 1px solid var(--line);
    background: var(--panel);
    box-shadow: -12px 0 32px #000a;
  }

  body.why-closed #side,
  body.fx-open #side {
    display: none;
  }

  /* A sheet over the keys' right end, in the explanations' place. */
  #fx {
    grid-row: 2;
    grid-column: 1;
    justify-self: end;
    z-index: 3;
    width: min(340px, 50vw);
    padding: 10px 12px;
    box-shadow: -12px 0 32px #000a;
  }

  #side #lane {
    flex-wrap: wrap;
    overflow: visible;
  }

  #why {
    overflow: visible;
    border-left: none;
  }

  #legend {
    display: none;
  }
}

/* Touch: room for a finger, and no zooming in on a field when it's tapped (iOS does below 16px). */
@media (pointer: coarse) {
  button,
  select,
  input[type='number'],
  input[type='text'] {
    min-height: 36px;
  }

  select,
  input[type='number'],
  input[type='text'] {
    font-size: 16px;
  }

  input[type='checkbox'] {
    width: 18px;
    height: 18px;
  }

  #stage.windowed {
    --overview: 34px;
  }

  /* The panel's sliders are dragged while playing, so give the thumb a finger's height. */
  #fx input[type='range'] {
    min-height: 30px;
  }

  #octave,
  .keys-only {
    display: none;
  }

  .touch-only {
    display: block;
  }
}

/* On a short screen the card often has to sit over the keys: wider is shorter, and covers less. */
@media (max-height: 520px) {
  .tour-card {
    width: min(420px, calc(100vw - 20px));
  }
}

@media (prefers-reduced-motion: reduce) {
  .tour-ring {
    transition: none;
  }

  .card.current {
    box-shadow: 0 0 0 1px var(--home) inset;
  }
}
