/* Engraving ink on manuscript paper above a row of ivory keys. The seven
   answers are the seven white keys, Do to Si, C to B; the felt strip, the
   ebony case and the brass highlight come from the instrument too.

   Layouts, by screen:
   - phone, portrait: header, staff, keyboard, stacked; keys run edge to edge.
   - 600 px and wider: the same stack, the keyboard set in its case.
   - short and wide (a phone on its side): staff on the left, a keyboard as
     tall as the screen on the right. */

@font-face {
  font-family: "Solfege Schola";
  src: url("fonts/schola-regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Solfege Schola";
  src: url("fonts/schola-bold.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}

:root {
  color-scheme: light;

  --paper: #eef1f3;
  --ink: #1d2433;
  --ink-soft: #5b6475;
  --rule: #c9cfd8;
  --ivory: #fffdf7;
  --ivory-pressed: #e8e2d4;
  --key-ink: #1d2433;
  --ebony: #22252b;
  --felt: #9b1c31;
  --felt-ink: #fffdf7;
  --brass: #c8932e;
  --brass-ink: #2e2106;
  --right: #2f7a5b;
  --right-ink: #f4fbf7;
  --focus: #2b63d9;
  --sheet: #f9fafb;
  --black-key: #1b1d22;
  --black-key-lit: #4a4e57;

  --track: color-mix(in srgb, var(--ink) 7%, var(--paper));
  --key-shade: color-mix(in srgb, var(--ivory) 80%, var(--ebony));

  --font: "Solfege Schola", "Century Schoolbook", "New Century Schoolbook", "TeX Gyre Schola", Georgia, serif;
  --gutter: clamp(16px, 4vw, 40px);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --paper: #171b24;
    --ink: #dce2ec;
    --ink-soft: #97a0b2;
    --rule: #333a48;
    --ivory: #e4dfd3;
    --ivory-pressed: #c7c0b0;
    --ebony: #0d0f13;
    --felt: #b8334a;
    --brass: #e0ac4a;
    --right: #3f9a74;
    --focus: #7fa8ff;
    --sheet: #1f2430;
    --black-key: #07080a;
    --black-key-lit: #2c3038;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --paper: #171b24;
  --ink: #dce2ec;
  --ink-soft: #97a0b2;
  --rule: #333a48;
  --ivory: #e4dfd3;
  --ivory-pressed: #c7c0b0;
  --ebony: #0d0f13;
  --felt: #b8334a;
  --brass: #e0ac4a;
  --right: #3f9a74;
  --focus: #7fa8ff;
  --sheet: #1f2430;
  --black-key: #07080a;
  --black-key-lit: #2c3038;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--paper);
}

body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "bar"
    "stage"
    "keys";
  height: 100vh;
  height: 100dvh;
  margin: 0;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.45;
  -webkit-tap-highlight-color: transparent;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

/* Header: the name, and what is being practised, which opens settings. */

.bar {
  grid-area: bar;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-self: center;
  width: 100%;
  max-width: 1200px;
  padding:
    calc(10px + var(--safe-top))
    calc(var(--gutter) + var(--safe-right))
    0
    calc(var(--gutter) + var(--safe-left));
}

.title {
  margin: 0 auto 0 0;
  font-size: clamp(1.375rem, 1.05rem + 1.2vw, 1.875rem);
  font-weight: 400;
  line-height: 1;
}

.offline {
  margin: 0;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--track);
  color: var(--ink-soft);
  font-size: 0.875rem;
  line-height: 1.2;
}

.mode {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin-right: -6px;
  padding: 0 10px 0 14px;
  border: 0;
  border-radius: 999px;
  background: var(--track);
  color: var(--ink);
  font: 400 0.9375rem/1 var(--font);
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.mode-clefs {
  display: inline-flex;
  align-items: center;
}

.mode-range {
  color: var(--ink-soft);
  white-space: nowrap;
}

.mode-accidentals {
  display: inline-flex;
  gap: 1px;
  margin-left: -2px;
  color: var(--ink-soft);
}

.mode-accidentals:empty {
  display: none;
}

.mode-gear {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
}

/* The clef glyphs, set at text size. The treble clef is drawn about twice as
   tall as the bass clef, as on the staff. */
.glyph {
  display: inline-flex;
}

.glyph svg {
  width: auto;
  fill: currentColor;
}

.glyph[data-glyph="trebleClef"] svg {
  height: 1.55em;
}

.glyph[data-glyph="bassClef"] svg {
  height: 0.9em;
}

.glyph + .glyph {
  margin-left: 1px;
}

.glyph[data-glyph="sharp"] svg,
.glyph[data-glyph="flat"] svg {
  height: 1.05em;
}

/* The staff is the page: it takes whatever height is left and scales down
   rather than pushing the keys off screen. */

.stage {
  grid-area: stage;
  position: relative;
  display: flex;
  min-height: 0;
  padding: 4px var(--safe-right) 8px var(--safe-left);
}

.staff {
  position: relative;
  flex: 1;
  min-height: 110px;
}

.staff svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.staff-line,
.barline {
  stroke: var(--ink);
  stroke-width: 1;
}

.ledger-line {
  stroke: var(--ink);
  stroke-width: 1.4;
}

.clef,
.brace,
.note {
  fill: var(--ink);
}

.accidental {
  fill: var(--ink);
}

.note.is-revealed,
.accidental.is-revealed {
  fill: var(--brass);
}

/* A new note slides in from the right, the direction music is read. */
.note-group.is-fresh {
  animation: note-in 260ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

@keyframes note-in {
  from {
    opacity: 0;
    translate: 12px 0;
  }
}

/* Shown only when something failed; the keys and the staff carry every
   other message. */
.notice {
  position: absolute;
  top: 8px;
  left: 50%;
  z-index: 1;
  width: max-content;
  max-width: calc(100% - 2 * var(--gutter));
  margin: 0;
  padding: 9px 16px;
  border-radius: 10px;
  background: var(--felt);
  color: var(--felt-ink);
  font-size: 0.9375rem;
  line-height: 1.35;
  text-align: center;
  translate: -50% 0;
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.18);
}

/* The keyboard: a felt strip, then seven white keys with ebony between and
   the five black keys of the octave over them. The top of each key sits in
   the felt's shadow. */

.keyboard {
  --key-height: clamp(116px, 27vh, 240px);
  --key-gap: 3px;
  --case: 3px;
  --black-lip: clamp(8px, 2vh, 16px);

  grid-area: keys;
  display: flex;
  flex-direction: column;
  justify-self: center;
  width: 100%;
  padding: 0 calc(var(--case) + var(--safe-right)) calc(var(--case) + var(--safe-bottom)) calc(var(--case) + var(--safe-left));
  background: var(--ebony);
}

.keyboard::before {
  content: "";
  flex: none;
  height: 8px;
  margin-inline: calc(-1 * var(--case));
  background:
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--felt) 80%, white) 0,
      var(--felt) 2px,
      color-mix(in srgb, var(--felt) 70%, black) 100%
    );
}

.keybed {
  position: relative;
  height: var(--key-height);
}

.white-keys {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: var(--key-gap);
  height: 100%;
}

/* Black keys sit on the boundaries between white keys: after Do and Re
   (C#, D#), then after Fa, Sol and La (F#, G#, A#), each leaning a little
   away from the middle of its group, as on a piano. Without sharps or flats
   they are not answers: disabled, they still take the tap, so it never falls
   through to the white key below. */
.black-keys {
  position: absolute;
  inset: 0 0 auto;
  height: 60%;
  pointer-events: none;
}

.black-key {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  margin: 0;
  padding: 0 0 calc(var(--black-lip) + clamp(6px, 1.2vh, 12px));
  border: 0;
  color: #f1ede4;
  font: 700 clamp(0.72rem, 0.5rem + 1vw, 1.05rem)/1 var(--font);
  cursor: default;
  touch-action: manipulation;
  user-select: none;
  left: calc((100% + var(--key-gap)) * var(--after) / 7 - var(--key-gap) / 2);
  width: calc((100% + var(--key-gap)) / 7 * 0.58);
  translate: calc(-50% + var(--lean) * 12%) 0;
  border-radius: 0 0 4px 4px;
  background: linear-gradient(to bottom, var(--black-key) 0, var(--black-key) calc(100% - var(--black-lip)), var(--black-key-lit) calc(100% - var(--black-lip)), var(--black-key) 100%);
  box-shadow:
    inset 1px 0 0 var(--black-key-lit),
    inset -1px 0 0 var(--black-key-lit),
    0 3px 5px rgb(0 0 0 / 0.35);
  pointer-events: auto;
}

.black-key:not(:disabled) {
  cursor: pointer;
}

.black-key:active:not(:disabled) {
  translate: calc(-50% + var(--lean) * 12%) 2px;
  background: linear-gradient(to bottom, var(--black-key) 0, var(--black-key) calc(100% - var(--black-lip) / 2), var(--black-key-lit) calc(100% - var(--black-lip) / 2));
}

/* Which names a black key carries follows the session: Do♯ with sharps, Re♭
   with flats, both with both. While a correction is due, the revealed key
   shows only the name the note was written with. */
.black-key .key-name {
  display: none;
  white-space: nowrap;
}

.keyboard[data-accidentals="sharps"] .black-key .sharp-name,
.keyboard[data-accidentals="flats"] .black-key .flat-name,
.keyboard[data-accidentals="both"] .black-key .key-name {
  display: flex;
  align-items: center;
}

.keyboard .black-key.is-revealed .key-name {
  display: none;
}

.keyboard .black-key.is-revealed[data-revealed="sharp"] .sharp-name,
.keyboard .black-key.is-revealed[data-revealed="flat"] .flat-name {
  display: flex;
  visibility: visible;
}

.black-key .key-name .glyph svg {
  height: 1.1em;
}

.keyboard:not([data-accidentals="none"]) .black-key:disabled .key-name {
  opacity: 0.35;
}

:root[data-hints="off"] .black-key:not(.is-revealed) .key-name {
  visibility: hidden;
}

.black-key.is-right {
  animation: key-right 450ms ease-out;
}

.black-key.is-wrong {
  animation: key-wrong-black 450ms ease-out;
}

@keyframes key-wrong-black {
  0%,
  60% {
    background: var(--felt);
    color: var(--felt-ink);
  }

  15% {
    translate: calc(-50% + var(--lean) * 12% - 3px) 0;
  }

  30% {
    translate: calc(-50% + var(--lean) * 12% + 3px) 0;
  }
}

.black-key.is-revealed {
  background: var(--brass);
  color: var(--brass-ink);
  animation: key-call 1.4s ease-in-out infinite;
}

.black-key:focus-visible {
  outline-offset: -3px;
}

.black-key:nth-child(1) { --after: 1; --lean: -1; }
.black-key:nth-child(2) { --after: 2; --lean: 1; }
.black-key:nth-child(3) { --after: 4; --lean: -1; }
.black-key:nth-child(4) { --after: 5; --lean: 0; }
.black-key:nth-child(5) { --after: 6; --lean: 1; }

.key {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 100%;
  min-width: 0;
  margin: 0;
  padding: 0 0 clamp(12px, 2.4vh, 26px);
  border: 0;
  border-radius: 0 0 7px 7px;
  background: linear-gradient(to bottom, var(--key-shade), var(--ivory) 18px);
  box-shadow: inset 0 -6px 0 var(--ivory-pressed);
  color: var(--key-ink);
  font: 700 clamp(1.05rem, 0.75rem + 1.3vw, 1.6rem)/1 var(--font);
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  transition: color 150ms ease-out;
}

.key:active:not(:disabled) {
  translate: 0 2px;
  background: var(--ivory-pressed);
  box-shadow: inset 0 4px 8px rgb(0 0 0 / 0.2);
}

.key:focus-visible {
  outline-offset: -5px;
}

/* Names off: the keys are bare, except the one a wrong answer reveals. */
:root[data-hints="off"] .key:not(.is-revealed) .key-name {
  visibility: hidden;
}

/* While a correction is due the other keys stay ivory, only their names
   fade, so the keyboard still reads as a keyboard. */
.key:disabled {
  color: color-mix(in srgb, var(--key-ink) 28%, var(--ivory));
  cursor: default;
}

/* The key just pressed answers for a moment: green when right, felt red and
   a shake when wrong. */
.key.is-right {
  animation: key-right 450ms ease-out;
}

@keyframes key-right {
  0%,
  35% {
    background: var(--right);
    color: var(--right-ink);
  }
}

.key.is-wrong {
  animation: key-wrong 450ms ease-out;
}

@keyframes key-wrong {
  0%,
  60% {
    background: var(--felt);
    color: var(--felt-ink);
  }

  15% {
    translate: -3px 0;
  }

  30% {
    translate: 3px 0;
  }

  45% {
    translate: -2px 0;
  }
}

.key.is-revealed {
  background: var(--brass);
  box-shadow: inset 0 -6px 0 rgb(0 0 0 / 0.16);
  color: var(--brass-ink);
  animation: key-call 1.4s ease-in-out infinite;
}

@keyframes key-call {
  50% {
    box-shadow: inset 0 -6px 0 rgb(0 0 0 / 0.16), inset 0 0 0 4px rgb(255 255 255 / 0.55);
  }
}

@media (hover: hover) {
  .black-key:not(:disabled):hover {
    background: linear-gradient(to bottom, var(--black-key-lit) 0, var(--black-key) 30%, var(--black-key) calc(100% - var(--black-lip)), var(--black-key-lit) calc(100% - var(--black-lip)));
  }

  .mode:hover {
    background: color-mix(in srgb, var(--ink) 12%, var(--paper));
  }

  .segmented input:not(:checked) + span:hover {
    color: var(--ink);
  }

  .key:not(:disabled):hover {
    background: linear-gradient(to bottom, var(--key-shade), var(--ivory-pressed) 18px);
  }
}

/* Settings: a sheet from the bottom on a phone, a panel in the middle on a
   wider screen. */

.settings {
  width: 100%;
  max-width: 100%;
  max-height: 92dvh;
  margin: auto 0 0;
  padding: 0;
  border: 0;
  border-radius: 18px 18px 0 0;
  background: var(--sheet);
  color: var(--ink);
  box-shadow: 0 -10px 40px rgb(0 0 0 / 0.2);
}

.settings[open] {
  animation: sheet-in 240ms cubic-bezier(0.2, 0.7, 0.2, 1);
}

.settings::backdrop {
  background: rgb(10 14 22 / 0.45);
}

@keyframes sheet-in {
  from {
    opacity: 0;
    translate: 0 32px;
  }
}

.sheet {
  display: grid;
  gap: 24px;
  max-width: 560px;
  margin: 0 auto;
  padding:
    18px
    calc(20px + var(--safe-right))
    calc(22px + var(--safe-bottom))
    calc(20px + var(--safe-left));
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sheet-title {
  margin: 0;
  font-size: 1.375rem;
  font-weight: 400;
}

.sheet-note {
  margin: -8px 0 0;
  color: var(--ink-soft);
  font-size: 0.875rem;
  line-height: 1.35;
}

.done {
  min-height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: 8px;
  background: var(--ink);
  color: var(--paper);
  font: 700 1rem/1 var(--font);
  cursor: pointer;
}

.setting {
  display: grid;
  gap: 10px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.setting-name {
  padding: 0;
  font-size: 1.0625rem;
  font-weight: 700;
}

.setting-note {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  line-height: 1.35;
}

/* A choice is a tinted track; the chosen option is set in ink. */
.segmented {
  display: flex;
  gap: 2px;
  margin: 0;
  padding: 3px;
  border-radius: 10px;
  background: var(--track);
}

.segmented label {
  position: relative;
  display: flex;
  flex: 1;
}

.segmented input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.segmented label > span {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 42px;
  padding: 0 8px;
  border-radius: 7px;
  color: var(--ink-soft);
  font-size: 1rem;
  user-select: none;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}

.segmented input:checked + span {
  background: var(--ink);
  color: var(--paper);
}

.segmented input:focus-visible + span {
  outline: 3px solid var(--focus);
  outline-offset: 1px;
}

.segmented-icons svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
}

.segmented-icons svg .fill {
  fill: currentColor;
  stroke: none;
}

/* Lines: a picture of the staff with its ledger lines, the chosen span
   shaded, beside the two ends that set it. The highest end sits above the
   lowest, as on the staff. */
.lines {
  display: grid;
  grid-template-columns: 136px minmax(0, 1fr);
  gap: 20px;
  align-items: center;
}

.lines-preview {
  width: 100%;
  height: auto;
}

.lines-preview .band {
  fill: color-mix(in srgb, var(--brass) 24%, transparent);
  stroke: color-mix(in srgb, var(--brass) 70%, transparent);
  stroke-width: 1;
}

.lines-preview .rule {
  stroke-width: 1.5;
  transition: stroke 150ms ease-out;
}

.lines-preview .rule.is-in {
  stroke: var(--ink);
}

.lines-preview .rule.is-out {
  stroke: var(--rule);
}

.lines-preview .rule.is-ledger.is-out {
  stroke-dasharray: 3 3;
}

.lines-preview .rule-label {
  fill: var(--ink-soft);
  font: 11px var(--font);
  text-anchor: middle;
}

.lines-preview .rule-label.is-in {
  fill: var(--ink);
  font-weight: 700;
}

.lines-ends {
  display: grid;
  gap: 16px;
}

.stepper {
  display: grid;
  gap: 6px;
}

.stepper-name {
  color: var(--ink-soft);
  font-size: 0.9375rem;
}

.stepper-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 3px;
  border-radius: 10px;
  background: var(--track);
}

.stepper button {
  width: 44px;
  height: 40px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ink);
  font: 700 1.375rem/1 var(--font);
  cursor: pointer;
}

.stepper button:disabled {
  color: color-mix(in srgb, var(--ink) 25%, var(--sheet));
  cursor: default;
}

.stepper output {
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.setting-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
}

.setting-row label {
  display: grid;
  gap: 4px;
  cursor: pointer;
}

.setting-row .setting-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 1.0625rem;
}

.setting-option .glyph svg {
  height: 1.2em;
}

.switch {
  position: relative;
  width: 50px;
  height: 30px;
  margin: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 22%, var(--sheet));
  appearance: none;
  cursor: pointer;
  transition: background-color 150ms ease-out;
}

.switch::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.3);
  transition: translate 150ms ease-out;
}

.switch:checked {
  background: var(--ink);
}

.switch:checked::before {
  translate: 20px 0;
  background: var(--paper);
}

@media (hover: hover) {
  .stepper button:not(:disabled):hover {
    background: color-mix(in srgb, var(--ink) 8%, transparent);
  }
}

/* Narrow phones (320–359 px): the range says itself in settings, not in the
   header, and the keys keep every pixel. */
@media (max-width: 359px) {
  .mode-range {
    display: none;
  }

  .keyboard {
    --key-gap: 2px;
    --case: 2px;
  }

  .lines {
    grid-template-columns: 104px minmax(0, 1fr);
    gap: 12px;
  }
}

/* 600 px and wider: the keyboard sits in its ebony case, centred. */
@media (min-width: 600px) {
  .bar {
    padding-top: calc(20px + var(--safe-top));
  }

  .stage {
    padding-block: 8px 16px;
  }

  .keyboard {
    --key-height: clamp(150px, 27vh, 260px);
    --key-gap: 4px;
    --case: 12px;

    width: min(calc(100% - 2 * var(--gutter)), 980px);
    padding-top: var(--case);
    border-radius: 18px 18px 0 0;
    box-shadow:
      inset 0 1px 0 rgb(255 255 255 / 0.08),
      0 -14px 40px rgb(0 0 0 / 0.12);
  }

  .keyboard::before {
    margin-inline: 0;
    border-radius: 3px 3px 0 0;
  }

  .settings {
    width: min(520px, calc(100% - 32px));
    margin: auto;
    border-radius: 16px;
    box-shadow: 0 20px 60px rgb(0 0 0 / 0.25);
  }

  .sheet {
    padding: 22px 26px 26px;
  }
}

/* Short and wide, a phone on its side: the staff on the left, a keyboard as
   tall as the screen on the right, so the keys are long enough to hit. */
@media (orientation: landscape) and (max-height: 560px) {
  body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
      "bar keys"
      "stage keys";
  }

  .bar {
    padding: calc(8px + var(--safe-top)) 12px 0 calc(16px + var(--safe-left));
  }

  .stage {
    padding: 0 0 calc(8px + var(--safe-bottom)) var(--safe-left);
  }

  .keyboard {
    --key-gap: 3px;
    --case: 8px;

    width: 100%;
    height: 100%;
    padding:
      calc(var(--case) + var(--safe-top))
      calc(var(--case) + var(--safe-right))
      calc(var(--case) + var(--safe-bottom))
      var(--case);
    border-radius: 0;
    box-shadow: none;
  }

  .keyboard::before {
    margin-inline: 0;
    border-radius: 3px 3px 0 0;
  }

  .keybed {
    flex: 1;
    height: auto;
  }

  .key {
    font-size: 1.125rem;
  }

  /* Settings in two columns, so the panel fits the short screen: what to
     practise on the left, the lines picker on the right. */
  .settings {
    width: min(860px, calc(100% - 24px));
    max-height: calc(100dvh - 16px);
  }

  .sheet {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-auto-flow: row dense;
    gap: 14px 28px;
    max-width: none;
    padding: 14px 22px 16px;
  }

  .sheet-head,
  .sheet-note {
    grid-column: 1 / -1;
  }

  .setting-lines {
    grid-column: 2;
    grid-row: span 4;
  }
}

@media (prefers-reduced-motion: reduce) {
  .settings[open],
  .note-group.is-fresh,
  .key.is-revealed,
  .key.is-right,
  .key.is-wrong,
  .black-key.is-revealed,
  .black-key.is-right,
  .black-key.is-wrong {
    animation: none;
  }

  .key.is-wrong,
  .black-key.is-wrong {
    background: var(--felt);
    color: var(--felt-ink);
  }

  .mode,
  .segmented label > span,
  .lines-preview .rule,
  .switch,
  .switch::before,
  .key {
    transition: none;
  }
}
