/*
 * music.gonglogic.com/theory — the Music Theory course.
 *
 * Built on the music site's tokens (music.css: --paper, --surface, --ink, --accent,
 * --ok, --bad, --staff …), so it follows the site's light and dark schemes without a
 * colour of its own. Every rule is scoped to [data-area="music"], as music.css's are.
 * Loaded only on the course's pages (MusicTheoryController).
 */

/* ── the course ─────────────────────────────────────────────────────────── */
[data-area="music"] .th-mast__actions { margin-top: 1.25rem; }

/* How far along: on the course, and through a run of notes. */
[data-area="music"] .th-meter { display: block; height: 0.3rem; border-radius: 0.3rem; background: var(--rule); overflow: hidden; }
[data-area="music"] .th-meter i { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--ok); transition: width 0.2s; }
@media (prefers-reduced-motion: reduce) { [data-area="music"] .th-meter i { transition: none; } }
[data-area="music"] .th-sofar { display: flex; align-items: center; gap: 0.75rem; margin-top: 1rem; max-width: 26rem; }
[data-area="music"] .th-sofar .th-meter { flex: 1; }
[data-area="music"] .th-sofar__text { flex: none; font-size: 0.88rem; color: var(--ink-2); }

[data-area="music"] .th-unit + .th-unit { margin-top: 2.25rem; }
[data-area="music"] .th-unit__title { margin: 0; font: 600 1.3rem/1.25 var(--display); }
[data-area="music"] .th-unit__blurb { margin: 0.15rem 0 0.8rem; font-size: 0.95rem; color: var(--ink-2); }

[data-area="music"] .th-course {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 0.6rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
  counter-reset: none;
}
[data-area="music"] .th-course__item { display: flex; }
[data-area="music"] .th-course__link {
  flex: 1;
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.85rem 1rem; min-height: 4.25rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r);
  text-decoration: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
[data-area="music"] .th-course__link:hover { border-color: var(--accent); box-shadow: var(--shadow-1); text-decoration: none; color: var(--ink); }
[data-area="music"] .th-course__num,
[data-area="music"] .th-part__num {
  flex: none; width: 2.1rem; height: 2.1rem; border-radius: 50%;
  display: grid; place-items: center;
  font: 600 0.95rem/1 var(--sans);
  background: var(--accent-wash); color: var(--accent-ink);
}
[data-area="music"] .th-course__item.is-complete .th-course__num { background: var(--ok); color: var(--surface); }
[data-area="music"] .th-course__body { display: flex; flex: 1; flex-direction: column; gap: 0.15rem; min-width: 0; }
[data-area="music"] .th-course__title { font: 600 1.02rem/1.25 var(--display); }
[data-area="music"] .th-course__sub { font-size: 0.86rem; color: var(--ink-2); }
/* The lesson to do next: the one thing on a page of 25 worth finding at a glance. */
[data-area="music"] .th-course__item.is-next .th-course__link { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
[data-area="music"] .th-course__item.is-next .th-course__num { background: var(--accent); color: var(--surface); }
[data-area="music"] .th-course__item.is-next .th-course__body::before {
  content: "Up next"; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent-ink);
}

/* Four dots: Learn, Play, Test, Quiz. */
[data-area="music"] .th-dots { display: flex; gap: 0.25rem; flex: none; }
[data-area="music"] .th-dots i {
  display: block; width: 0.5rem; height: 0.5rem; border-radius: 50%;
  border: 1.5px solid var(--rule-2); background: transparent;
}
[data-area="music"] .th-dots i.is-done { background: var(--ok); border-color: var(--ok); }

/* ── a lesson's head, contents and way on ──────────────────────────────── */
[data-area="music"] .th-head { margin: 0.6rem 0 1.4rem; }
[data-area="music"] .th-head--row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 0.5rem 1.5rem; }
[data-area="music"] .th-head__num {
  margin: 0; font-size: 0.74rem; font-weight: 600; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--accent-ink);
}
[data-area="music"] .th-head__title { margin: 0.25rem 0 0; font: 600 clamp(1.6rem, 4vw, 2.3rem)/1.15 var(--display); }
[data-area="music"] .th-head__sub { margin: 0.45rem 0 0; font-size: 1.05rem; color: var(--ink-2); }

[data-area="music"] .th-parts { list-style: none; margin: 0 0 1.4rem; padding: 0; display: grid; gap: 0.6rem; }
[data-area="music"] .th-part__link {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.9rem 1rem; background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule); border-radius: var(--r); text-decoration: none;
}
[data-area="music"] .th-part__link:hover { border-color: var(--accent); box-shadow: var(--shadow-1); color: var(--ink); text-decoration: none; }
[data-area="music"] .th-part__body { display: flex; flex: 1; flex-direction: column; min-width: 0; }
[data-area="music"] .th-part__name { font: 600 1.1rem/1.25 var(--display); }
[data-area="music"] .th-part__blurb { font-size: 0.88rem; color: var(--ink-2); }
[data-area="music"] .th-part__count { flex: none; font-size: 0.85rem; color: var(--ink-3); }
[data-area="music"] .th-part__tick,
[data-area="music"] .th-tabs__tick { flex: none; width: 1.1rem; height: 1.1rem; border-radius: 50%; border: 1.5px solid var(--rule-2); }
[data-area="music"] .is-done .th-part__tick,
[data-area="music"] .is-done .th-tabs__tick { background: var(--ok); border-color: var(--ok); display: grid; place-items: stretch; }
/* A check mark, as a shape cut out of the surface colour, so it holds in either scheme.
   It was two crossed gradients, which read as an X: the mark for "right" looked like the
   mark for "wrong". */
[data-area="music"] .is-done .th-part__tick::after,
[data-area="music"] .is-done .th-tabs__tick::after {
  content: ""; background: var(--surface);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.4l3 3 6-6.6' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.4l3 3 6-6.6' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
@media (max-width: 599px) {
  [data-area="music"] .th-part__blurb { display: none; }
}

[data-area="music"] .th-onward { margin: 1.5rem 0 0; display: flex; flex-wrap: wrap; gap: 0.6rem; }
[data-area="music"] .th-pager { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--rule); display: flex; justify-content: space-between; gap: 1rem; font-size: 0.92rem; }
[data-area="music"] .th-pager__link--next { margin-left: auto; text-align: right; }

/* The parts, on every part page. The margin leaves the tabs clear of the screen's edge
   when a phone opens a Play or Test page scrolled to them (theory.js). */
[data-area="music"] .th-tabs,
[data-area="music"] .th-stage { scroll-margin-top: 0.5rem; }
[data-area="music"] .th-tabs {
  display: flex; gap: 0.35rem; margin: 0.4rem 0 1rem; padding: 0.3rem;
  background: var(--paper-2); border-radius: var(--r);
}
[data-area="music"] .th-tabs__tab {
  flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 0.35rem;
  padding: 0.5rem 0.25rem; border: 1px solid transparent; border-radius: var(--r-s);
  font-size: 0.92rem; font-weight: 600; color: var(--ink-2); text-decoration: none; white-space: nowrap;
}
[data-area="music"] .th-tabs__tab:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
/* The edge is what says which part this is in the dark scheme, where the surface is barely
   lighter than the strip behind it. */
[data-area="music"] .th-tabs__tab.is-current { background: var(--surface); color: var(--ink); border-color: var(--rule-2); box-shadow: var(--shadow-1); }
[data-area="music"] .th-tabs__tick { width: 0.85rem; height: 0.85rem; }

/* ── Learn ─────────────────────────────────────────────────────────────── */
[data-area="music"] .th-learn { display: grid; gap: 1.5rem; }
[data-area="music"] .th-learn__heading { margin: 0 0 0.4rem; font: 600 1.3rem/1.25 var(--display); }
[data-area="music"] .th-learn__body { margin: 0; font-size: 1.08rem; line-height: 1.7; max-width: 62ch; }
[data-area="music"] .th-hear {
  margin-top: 1.75rem; padding: 0.9rem 1rem 1rem;
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-l); box-shadow: var(--shadow-1);
}
[data-area="music"] .th-hear__head { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
[data-area="music"] .th-hear__title { margin: 0; font: 600 1.15rem/1.25 var(--display); }
[data-area="music"] .th-hear__note { margin: 0.25rem 0 0.7rem; font-size: 0.9rem; color: var(--ink-2); }

/* ── Play and Test ─────────────────────────────────────────────────────── */
[data-area="music"] .th-instruction { margin: 0; max-width: 46ch; font-size: 1.02rem; color: var(--ink-2); }
[data-area="music"] .th-stage {
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r-l);
  padding: 0.9rem; box-shadow: var(--shadow-1);
}
[data-area="music"] .th-staff { position: relative; }
[data-area="music"] .th-staff__frame {
  display: block; width: 100%; height: 170px; border: 0; border-radius: var(--r-s);
  /* Paper in either scheme, as the site's scores are. A frame whose colour scheme differs
     from its page is painted opaque white by the browser, so a light-on-dark staff was
     pale grey on white and all but invisible. */
  background: #fff;
}
@media (max-width: 599px) { [data-area="music"] .th-staff__frame { height: 140px; } }
[data-area="music"] .th-status { min-height: 1.6rem; margin: 0.25rem 0.2rem 0.4rem; font-size: 0.98rem; font-weight: 600; color: var(--ink); }
[data-area="music"] .th-stage > .th-meter { margin: 0 0.2rem 0.7rem; }
[data-area="music"] .th-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0.75rem 0 0; }
/* The instrument pages are held to a width where the staff can be read at a glance: stretched
   across a wide screen, the eye crossed a metre of paper between one note and the next. */
[data-area="music"] .th-instrument > .lib-wrap { max-width: 64rem; }
/* Title and instruction side by side where there is room: a long instruction under the title
   pushed the keyboard below a laptop's screen. */
@media (min-width: 760px) {
  [data-area="music"] .th-instrument .th-head--row { flex-wrap: nowrap; align-items: flex-start; margin-bottom: 1rem; }
  [data-area="music"] .th-instrument .th-head--row > div { flex: 1 1 42%; min-width: 0; }
  [data-area="music"] .th-instrument .th-instruction { flex: 1 1 58%; max-width: none; line-height: 1.4; }
}
/* A phone on its side: the page opens at the staff (theory.js), so these two and the status
   line have to share about 340px. */
@media (max-height: 480px) and (min-width: 600px) {
  [data-area="music"] .th-stage { padding: 0.35rem 0.5rem 0.5rem; }
  [data-area="music"] .th-staff__frame { height: 118px; }
  [data-area="music"] .th-status { min-height: 1.3rem; margin: 0.1rem 0.2rem 0.2rem; font-size: 0.9rem; }
  [data-area="music"] .th-stage > .th-meter { margin-bottom: 0.35rem; }
  [data-area="music"] .th-keys:not(.th-keys--mini) .th-keys__row { height: 7rem; }
  [data-area="music"] .th-keys:not(.th-keys--mini) .th-keys__blacks { height: 4.4rem; }
}
/* On a phone the keyboard and the staff must share the first screen, or every note means a
   scroll. The tabs already say which lesson and which part, so the rest makes way. */
@media (max-width: 599px) {
  [data-area="music"] .th-page { padding-top: 0.5rem; }
  [data-area="music"] .th-page .sm-crumbs__item:first-child,
  [data-area="music"] .th-page .sm-crumbs__item:last-child:not(:nth-child(2)) { display: none; }
  [data-area="music"] .th-page .sm-crumbs__item:nth-child(2)::before { content: none; display: none; }
  [data-area="music"] .th-tabs ~ .th-head + .th-learn { margin-top: 1.1rem; }
  [data-area="music"] .th-tabs ~ .th-head .th-head__num { display: none; }
  [data-area="music"] .th-tabs ~ .th-head { margin: 0 0 0.7rem; }
  [data-area="music"] .th-instrument .th-head__title { font-size: 1.35rem; }
  [data-area="music"] .th-instrument .th-instruction { font-size: 0.92rem; line-height: 1.4; }
  [data-area="music"] .th-stage { padding: 0.5rem 0.6rem 0.7rem; }
}
[data-area="music"] .th-controls__hint { margin-left: auto; font-size: 0.8rem; color: var(--ink-3); }
[data-area="music"] .th-btn {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.45rem 0.85rem; min-height: 2.4rem;
  font: 600 0.9rem/1 var(--sans); color: var(--ink);
  background: var(--paper); border: 1px solid var(--rule); border-radius: var(--r-s); cursor: pointer;
}
[data-area="music"] .th-btn:hover:not(:disabled) { border-color: var(--accent); }
[data-area="music"] .th-btn:disabled { opacity: 0.6; cursor: default; }
/* Offered, not pressed on anyone: most readers have no MIDI keyboard. */
[data-area="music"] .th-btn--quiet { background: transparent; border-color: transparent; color: var(--ink-2); font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
[data-area="music"] .th-toggle { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.9rem; color: var(--ink-2); }

/* The keyboard. White keys share the row; black keys sit in a layer above, each
   placed by theory.js between the two whites it belongs to. On a narrow screen the
   keyboard keeps a playable key width and scrolls inside its own box — the page never
   scrolls sideways — and theory.js brings the next key into view. */
[data-area="music"] .th-keys {
  --white-min: 2.1rem; --black-w: 1.35rem;
  position: relative; overflow-x: auto; overflow-y: hidden;
  border-radius: var(--r-s); background: #16161a;
  padding: 4px 4px 6px; touch-action: manipulation;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
[data-area="music"] .th-keys--hold { touch-action: none; }
[data-area="music"] .th-keys__row {
  display: flex; height: 9.5rem;
  min-width: calc(var(--whites, 14) * var(--white-min));
}
[data-area="music"] .th-keys__blacks {
  position: absolute; inset: 4px 4px auto 4px; height: 5.9rem; pointer-events: none;
  min-width: calc(var(--whites, 14) * var(--white-min));
}
[data-area="music"] .th-key { margin: 0; padding: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
[data-area="music"] .th-key:focus-visible { outline: 3px solid #ff9f0a; outline-offset: -3px; }
[data-area="music"] .th-key--white {
  flex: 1; position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  margin-right: 2px; background: #fbfaf6; color: #1c1c22; border: 0; border-radius: 0 0 5px 5px;
  box-shadow: inset 0 -5px 0 rgba(0,0,0,0.08);
}
[data-area="music"] .th-key--white:last-child { margin-right: 0; }
[data-area="music"] .th-key--black {
  position: absolute; top: 0; width: var(--black-w); height: 100%;
  background: #1c1c22; color: #f2f2ee; border: 0; border-radius: 0 0 4px 4px; pointer-events: auto;
  box-shadow: inset 0 -4px 0 rgba(255,255,255,0.08);
}
[data-area="music"] .th-key__name { margin-bottom: 0.5rem; font: 600 0.68rem/1 var(--sans); color: #66665f; }
/* Which computer key plays it, when asked: a key marked "A" that is a C is the wrong thing
   to put in front of someone learning the keys' names, so these are off by default. */
[data-area="music"] .th-key__kbd { display: none; margin-bottom: 0.4rem; font: 500 0.68rem/1 var(--sans); color: #8d8d86; }
[data-area="music"] .th-key--black .th-key__kbd { position: absolute; left: 0; right: 0; bottom: 0.15rem; margin: 0; text-align: center; color: #a3a3ad; }
[data-area="music"] .th-kbd-on .th-key__kbd { display: block; }
[data-area="music"] .th-key--white:active { background: #ecebe4; }
[data-area="music"] .th-key--black:active { background: #34343c; }
/* Play only: the key to press glows; a chord's tones already down stay lit.
   THE STAFF'S OWN COLOURS — vexstaff.html marks the target note #007AFF, a right note
   #34C759, a wrong one #FF3B30 — so the key and the note it stands for are one colour.
   Solid, not a wash: the keyboard's frame is near-black, and a translucent tint over a
   white key let it through, so the lit key read as a dark, pressed one. */
[data-area="music"] .th-key--white.is-target { background: linear-gradient(#eaf3ff, #a8cdff); box-shadow: inset 0 0 0 2px #007aff; }
[data-area="music"] .th-key--black.is-target { background: linear-gradient(#3f9bff, #0062d6); box-shadow: inset 0 0 0 1.5px #fff; }
[data-area="music"] .th-key--white.is-held { background: linear-gradient(#e6f9ec, #a4e6b8); box-shadow: inset 0 0 0 2px #34c759; }
[data-area="music"] .th-key--black.is-held { background: linear-gradient(#57d67b, #24a047); }
/* The lit key says its own name, so a beginner need not map the staff's letter to the
   keyboard by counting. "Note names" turns it off with the names on the staff. */
[data-area="music"] .th-key.is-target::after,
[data-area="music"] .th-key.is-held::after {
  content: attr(data-name); position: absolute; left: 0; right: 0; text-align: center;
  font: 700 0.92rem/1 var(--sans); pointer-events: none;
}
[data-area="music"] .th-key--white.is-target::after,
[data-area="music"] .th-key--white.is-held::after { top: 66%; color: #06366f; }
[data-area="music"] .th-key--white.is-held::after { color: #0d4a22; }
[data-area="music"] .th-key--black.is-target::after,
[data-area="music"] .th-key--black.is-held::after { bottom: 1.1rem; font-size: 0.7rem; color: #fff; }
[data-area="music"] .th-key--black.is-held::after { color: #06230f; }
[data-area="music"] .th-names-off .th-key::after { content: none !important; }
/* Learn's keyboard: a dot on each key the lesson uses. */
[data-area="music"] .th-keys--mini .th-keys__row { height: 6.5rem; }
[data-area="music"] .th-keys--mini .th-keys__blacks { height: 4rem; }
[data-area="music"] .th-key.is-lesson:not(.is-target)::after {
  content: ""; position: absolute; left: 50%; bottom: 1.6rem; width: 0.55rem; height: 0.55rem; margin-left: -0.275rem;
  border-radius: 50%; background: #007aff; pointer-events: none;
}
[data-area="music"] .th-key--black.is-lesson:not(.is-target)::after { background: #7ab8ff; bottom: 0.4rem; }
[data-area="music"] .th-key.is-right { background: #34c759 !important; }
[data-area="music"] .th-key.is-wrong { background: #ff3b30 !important; }
[data-area="music"] .th-instrument.is-restarting .th-stage { animation: th-shake 0.35s; }
@keyframes th-shake { 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
@media (prefers-reduced-motion: reduce) { [data-area="music"] .th-instrument.is-restarting .th-stage { animation: none; } }
@media (max-width: 599px) {
  [data-area="music"] .th-keys { --white-min: 2.35rem; }
  [data-area="music"] .th-keys:not(.th-keys--mini) .th-keys__row { height: 8rem; }
  [data-area="music"] .th-keys:not(.th-keys--mini) .th-keys__blacks { height: 5rem; }
}

/* ── done: the result of a run, or a quiz ─────────────────────────────── */
[data-area="music"] .th-done:focus,
[data-area="music"] .th-q__why:focus { outline: none; }
[data-area="music"] .th-done {
  margin-top: 1.2rem; padding: 1.2rem 1.25rem;
  background: var(--ok-wash); border: 1px solid var(--ok); border-radius: var(--r-l);
}
[data-area="music"] .th-done__stars { margin: 0; font-size: 1.6rem; letter-spacing: 0.15em; color: #c8962f; }
[data-area="music"] .th-done__stars:empty { display: none; }
[data-area="music"] .th-done__title { margin: 0.2rem 0 0.25rem; font: 600 1.35rem/1.2 var(--display); }
[data-area="music"] .th-done__detail { margin: 0; color: var(--ink-2); }
[data-area="music"] .th-done__actions { margin: 1rem 0 0; display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }
[data-area="music"] .th-done__actions .th-onward { margin: 0; }
[data-area="music"] .th-done__actions .button:not(.button--primary) { background: var(--surface); color: var(--ink); border: 1px solid var(--rule-2); }

/* ── Quiz ──────────────────────────────────────────────────────────────── */
[data-area="music"] .th-quiz { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.4rem; }
[data-area="music"] .th-q { padding: 1rem 1.1rem; background: var(--surface); border: 1px solid var(--rule); border-radius: var(--r); }
[data-area="music"] .th-q__num { margin: 0 0 0.2rem; font-size: 0.74rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
[data-area="music"] .th-q__prompt { margin: 0 0 0.75rem; font: 600 1.1rem/1.4 var(--display); }
[data-area="music"] .th-q__options { display: grid; gap: 0.45rem; }
[data-area="music"] .th-q__option {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  text-align: left; padding: 0.7rem 0.9rem; min-height: 2.75rem;
  font: 500 1rem/1.35 var(--sans); color: var(--ink);
  background: var(--paper); border: 1.5px solid var(--rule); border-radius: var(--r-s); cursor: pointer;
}
[data-area="music"] .th-q__option:hover:not(:disabled) { border-color: var(--accent); }
/* A browser greys a disabled button, and these stay to be read beside the explanation. */
[data-area="music"] .th-q__option:disabled { cursor: default; color: var(--ink); opacity: 1; }
[data-area="music"] .th-q__text { display: block; min-width: 0; }
[data-area="music"] .th-q__option.is-right { border-color: var(--ok); background: var(--ok-wash); }
[data-area="music"] .th-q__option.is-wrong { border-color: var(--bad); background: var(--bad-wash); }
/* Marked in shape as well as colour: red and green are the pair many people cannot tell apart. */
[data-area="music"] .th-q__option.is-right::after { content: "\2713"; flex: none; font-weight: 700; color: var(--ok); }
[data-area="music"] .th-q__option.is-wrong::after { content: "\2717"; flex: none; font-weight: 700; color: var(--bad); }
[data-area="music"] .th-q__why { margin: 0.7rem 0 0; font-size: 0.95rem; color: var(--ink-2); }
[data-area="music"] .th-q__verdict { color: var(--ink); }
