/* =========================================================================
   styles.css - Chord Coach
   ITEC100 reference project G

   One stylesheet, no framework, no build step, no web fonts - a page that
   promises to send nothing anywhere should not quietly fetch a typeface from
   Google on the way in.

   The look is a church at night: a dark room, three washes of coloured light
   the way a window throws it on a floor, glass panels with a hairline of that
   light along the top edge, and gold saved for the one thing you are meant to
   be looking at, which here is always the chord under your fingers.
   ========================================================================= */

:root {
  --ink: #f4f1e9;
  --ink-dim: #99a2b8;
  --ink-faint: #6f7893;

  --ground: #0a0d15;
  --ground-2: #0e1220;
  --panel: rgba(22, 27, 43, .66);
  --panel-solid: #161b2b;
  --raise: rgba(255, 255, 255, .045);
  --line: rgba(255, 255, 255, .085);
  --line-strong: rgba(255, 255, 255, .16);

  --gold: #e8bc55;          /* candlelight: the current chord, and nothing else */
  --gold-deep: #a9761d;
  --violet: #8d7cf2;        /* the purple of the season of waiting */
  --teal: #59c9a8;
  --warn: #e3a172;

  --sans: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, ui-serif, serif;

  --radius: 18px;
  --radius-sm: 10px;
  --shadow: 0 30px 80px -34px rgba(0, 0, 0, .9);
  --width: 1120px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  background: var(--ground);
  overflow-x: hidden;
}

/* The coloured light. Fixed, behind everything, and inert to the pointer. */
.glass-light {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(760px 520px at 12% -6%, rgba(232, 188, 85, .17), transparent 64%),
    radial-gradient(700px 500px at 88% 2%, rgba(141, 124, 242, .16), transparent 62%),
    radial-gradient(900px 640px at 62% 108%, rgba(89, 201, 168, .10), transparent 66%),
    linear-gradient(180deg, var(--ground-2), var(--ground) 46%);
}

/* A faint grid of lead lines, like the cames holding glass together. */
.glass-light::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: .35;
  background-image:
    linear-gradient(rgba(255, 255, 255, .022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .022) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(120% 90% at 50% 0%, #000 30%, transparent 78%);
}

/* --- the hero ------------------------------------------------------------ */
.hero {
  position: relative;
  max-width: var(--width);
  margin: 0 auto;
  padding: 3rem 1.4rem 1.6rem;
}

/* Optional art. The page is finished without either picture - the rosette is
   drawn in the markup - so each one is simply tried, and worn if it is there.
   See docs/IMAGE_ORDERS.md for what was asked for. */
.has-rose .hero::after {
  content: "";
  position: absolute;
  top: -30%;
  right: -4%;
  width: min(440px, 44vw);
  aspect-ratio: 1;
  background: url("assets/art-rose-window.png") center / contain no-repeat;
  opacity: .3;
  pointer-events: none;
  z-index: -1;
}

.has-guitar .foot::after {
  content: "";
  position: absolute;
  left: -3%;
  bottom: 0;
  width: min(440px, 46vw);
  height: 62%;
  background: url("assets/art-guitar-glow.png") left bottom / contain no-repeat;
  opacity: .16;
  pointer-events: none;
}

.hero__inner {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.6rem;
  align-items: center;
}

.hero__words { min-width: 0; }

.eyebrow {
  margin: 0 0 .5rem;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.hero h1 {
  margin: 0 0 .5rem;
  font-family: var(--display);
  font-size: clamp(2.3rem, 6vw, 3.6rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.015em;
  background: linear-gradient(96deg, #fffaf0 4%, var(--gold) 58%, #c79a3f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lead {
  margin: 0;
  max-width: 62ch;
  color: var(--ink-dim);
  font-size: 1rem;
}

/* --- the rosette: a rose window and a soundhole are the same drawing ------ */
.rosette { width: clamp(88px, 13vw, 132px); height: auto; }

.rosette__ring {
  fill: none;
  stroke: rgba(232, 188, 85, .55);
  stroke-width: 1.1;
  transform-origin: 60px 60px;
  animation: turn 90s linear infinite;
}

.rosette__petals { fill: rgba(141, 124, 242, .12); stroke: rgba(232, 188, 85, .38); }
.rosette__hole { fill: rgba(6, 8, 14, .72); stroke: rgba(232, 188, 85, .7); stroke-width: 1.4; }

.rosette__cross {
  stroke: var(--gold);
  stroke-width: 2.2;
  stroke-linecap: round;
  animation: none;
}

.rosette__glow { animation: breathe 7s ease-in-out infinite; transform-origin: 60px 60px; }

@keyframes turn { to { transform: rotate(360deg); } }
@keyframes breathe { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

/* --- a verse, set the way a verse is set --------------------------------- */
.verse {
  margin: 1.1rem 0 0;
  padding-left: 1rem;
  border-left: 2px solid rgba(232, 188, 85, .45);
}

.verse p {
  margin: 0;
  font-family: var(--display);
  font-style: italic;
  font-size: 1.02rem;
  color: #e7e0cd;
}

.verse cite {
  display: block;
  margin-top: .2rem;
  font-style: normal;
  font-size: .74rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* --- panels -------------------------------------------------------------- */
main { max-width: var(--width); margin: 0 auto; padding: 0 1.4rem 2.5rem; }

/* The panels look like smoked glass but are not doing any blurring. A
   backdrop-filter over a panel this size is recomputed whenever anything
   inside it changes, and in this app something inside changes on every beat -
   the current cell lights up - so the blur would be re-rendered several times
   a second for a effect nobody would notice. A translucent fill over the
   coloured light behind gets the same look for nothing. */
.panel {
  position: relative;
  background: linear-gradient(180deg, rgba(28, 34, 52, .88), rgba(18, 22, 35, .92));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.5rem 1.6rem 1.7rem;
  margin-bottom: 1.3rem;
  box-shadow: var(--shadow);
  overflow: hidden;
}

/* The hairline of light along the top edge of every panel. */
.panel::before {
  content: "";
  position: absolute;
  top: 0;
  left: 8%;
  right: 8%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(232, 188, 85, .55), rgba(141, 124, 242, .35), transparent);
}

.panel__title {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: 0 0 .9rem;
  font-family: var(--display);
  font-size: 1.22rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

.panel__mark {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 2px;
  background: linear-gradient(135deg, var(--gold), var(--gold-deep));
  transform: rotate(45deg);
  box-shadow: 0 0 14px rgba(232, 188, 85, .55);
}

.sub { margin: .25rem 0; color: var(--ink-dim); font-size: .93rem; }
.tiny { font-size: .82rem; color: var(--ink-faint); }

.status {
  margin: .9rem 0 0;
  font-size: .9rem;
  color: var(--ink-dim);
}

.row { display: flex; flex-wrap: wrap; gap: .55rem; align-items: center; margin: 1rem 0 0; }

/* --- buttons ------------------------------------------------------------- */
.btn {
  font: inherit;
  font-weight: 600;
  font-size: .92rem;
  color: #1c1402;
  background: linear-gradient(180deg, #f5cf6e, var(--gold) 55%, #cf9f3a);
  border: 0;
  border-radius: 999px;
  padding: .62rem 1.25rem;
  cursor: pointer;
  transition: transform .14s ease, box-shadow .14s ease, filter .14s ease;
  box-shadow: 0 8px 22px -12px rgba(232, 188, 85, .9);
}

.btn:hover { transform: translateY(-1px); filter: brightness(1.05); }
.btn:active { transform: translateY(0); }

.btn--small { padding: .4rem .85rem; font-size: .84rem; }

.btn--quiet {
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line);
  box-shadow: none;
}

.btn--quiet:hover { border-color: rgba(232, 188, 85, .5); background: rgba(232, 188, 85, .08); }

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

/* --- the drop zone ------------------------------------------------------- */
.dropzone {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 9.5rem;
  padding: 1.4rem;
  text-align: center;
  color: var(--ink-dim);
  background:
    radial-gradient(420px 150px at 50% 0%, rgba(232, 188, 85, .08), transparent 70%),
    var(--raise);
  border: 1.5px dashed var(--line-strong);
  border-radius: 14px;
  transition: border-color .18s ease, background-color .18s ease, transform .18s ease;
}

.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.dropzone__prompt { display: grid; justify-items: center; gap: .55rem; pointer-events: none; }
.dropzone__prompt strong { color: var(--ink); font-weight: 600; }
.dropzone__prompt svg { color: var(--gold); opacity: .8; }
.dropzone__chosen { font-weight: 600; color: var(--gold); pointer-events: none; }

.dropzone:hover,
.dropzone:focus-within,
.dropzone--over {
  border-color: rgba(232, 188, 85, .7);
  background:
    radial-gradient(420px 170px at 50% 0%, rgba(232, 188, 85, .16), transparent 70%),
    rgba(255, 255, 255, .06);
}

.dropzone--over { transform: scale(1.005); }

.progress {
  height: 5px;
  margin-top: .8rem;
  background: var(--raise);
  border-radius: 999px;
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold), var(--violet));
  transition: width .2s ease;
}

/* --- the song's own details --------------------------------------------- */
.song {
  display: grid;
  /* Title, artist, CCLI, then the four the chart is built on: tempo, key,
     beats per bar, bar one - all on one line on a wide screen. */
  grid-template-columns: 2fr 1.3fr .9fr auto auto auto auto;
  gap: .7rem;
  margin-bottom: 1.2rem;
}

/* min-width: 0 or the title input's own minimum width pushes the row wider
   than the phone it is on. */
.song__field { display: grid; min-width: 0; gap: .3rem; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }

.song__field input,
.song__field select,
.control select,
.search {
  min-width: 0;
  width: 100%;
  font: inherit;
  font-size: .92rem;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  background: rgba(10, 13, 21, .6);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .5rem .65rem;
  transition: border-color .15s ease;
}

.song__field input:focus,
.song__field select:focus,
.search:focus { border-color: rgba(232, 188, 85, .6); }

.song__field--title input { font-family: var(--display); font-size: 1.05rem; font-weight: 600; }

/* --- player -------------------------------------------------------------- */
.player__top { display: grid; gap: 1rem; margin-bottom: 1.3rem; }
.player__top audio { width: 100%; height: 40px; border-radius: 999px; }

.player__controls { display: flex; flex-wrap: wrap; gap: .8rem 1.5rem; align-items: center; }

.control {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.control select { width: auto; padding: .34rem .5rem; font-size: .85rem; }
.control--buttons { gap: .4rem; }

/* --- the stage: what is playing, and the sheet it is playing from -------- */
.stage {
  display: grid;
  /* Narrower than it was: the diagrams are the smallest thing on the page
     that still has to be legible, and every millimetre they give up goes to
     the chart, which is the thing being read while playing. */
  grid-template-columns: minmax(200px, 16.5rem) 1fr;
  gap: 1.2rem;
  align-items: start;
}

.now { display: grid; gap: .8rem; position: sticky; top: 1rem; }

.now__chord {
  position: relative;
  background: linear-gradient(180deg, rgba(255, 255, 255, .06), rgba(255, 255, 255, .02));
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 1rem 1.1rem 1.2rem;
  text-align: center;
  overflow: hidden;
}

/* Light behind the chord you are playing, as if the window were right there. */
.now__chord::before {
  content: "";
  position: absolute;
  top: -40%;
  left: 50%;
  width: 130%;
  height: 100%;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(232, 188, 85, .22), transparent 70%);
  pointer-events: none;
}

.now__chord--next {
  background: rgba(255, 255, 255, .025);
}

.now__chord--next::before { background: radial-gradient(closest-side, rgba(141, 124, 242, .16), transparent 70%); }

.now__label {
  margin: 0;
  font-size: .66rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.now__name {
  position: relative;
  margin: .15rem 0 .5rem;
  font-family: var(--display);
  font-size: clamp(2.6rem, 7vw, 3.8rem);
  font-weight: 600;
  line-height: 1;
  color: var(--gold);
  text-shadow: 0 0 34px rgba(232, 188, 85, .35);
}

.now__chord--next .now__name {
  font-size: clamp(1.7rem, 5vw, 2.3rem);
  color: var(--ink);
  text-shadow: none;
}

.now__diagram { position: relative; }
.now__diagram svg { width: min(100%, 132px); height: auto; }
.now__hint { margin: .4rem 0 0; font-size: .82rem; }

/* The fretboard itself. */
.nut { fill: var(--ink); }
.fret { stroke: rgba(255, 255, 255, .22); stroke-width: 1.5; }
.string { stroke: rgba(255, 255, 255, .34); stroke-width: 1.4; }
.dot { fill: var(--gold); }
.barre { fill: var(--gold); }
.finger { fill: #1c1402; font-size: 11px; font-weight: 700; font-family: var(--sans); }
.open { fill: none; stroke: var(--ink); stroke-width: 2; }
.mark { fill: var(--ink-faint); font-size: 13px; font-family: var(--sans); }
.fret-number { fill: var(--ink-faint); font-size: 12px; font-family: var(--sans); }

/* --- the chart, bar by bar ----------------------------------------------- */
/* A chord sheet, not a timeline: bars wrap across the page the way they do on
   paper, and each bar is its own little grid of beats. */
.sheet {
  background: rgba(10, 13, 21, .45);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: .9rem 1rem 1rem;
}

/* Bars are all one width, four to a line, the way a chord sheet is printed.
   Left to wrap on their own they came out different widths from line to line
   - a bar of one chord narrower than a bar of four - and nothing about the
   page held still enough to read while playing. */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--bars-per-row, 3), minmax(0, 1fr));
  gap: .55rem;
  max-height: 52vh;
  overflow-y: auto;
  padding: .2rem .15rem .5rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .18) transparent;
  scroll-behavior: smooth;
}

.grid::-webkit-scrollbar { width: 8px; }
.grid::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .16); border-radius: 999px; }

.sheet__help { margin: .7rem 0 0; }

.bar-box {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--beats, 4), minmax(0, 1fr));
  gap: 2px;
  padding: .95rem .3rem .3rem;
  background: linear-gradient(180deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
  border: 1px solid var(--line);
  border-radius: 12px;
  min-width: 0;
  transition: border-color .2s ease, background-color .2s ease, box-shadow .2s ease;
}

/* The bar being played. The lit beat inside it says where in the bar you are;
   this says which bar to look at, which is the thing you lose first when you
   glance away. */
.bar-box--on {
  border-color: rgba(232, 188, 85, .55);
  background: linear-gradient(180deg, rgba(232, 188, 85, .10), rgba(232, 188, 85, .03));
  box-shadow: 0 0 0 1px rgba(232, 188, 85, .25), 0 10px 30px -18px rgba(232, 188, 85, .7);
}

/* The beats before the first full bar of a song that does not start on beat
   one. Drawn as empty slots so every bar on the page lines up. */
.cell--pad { visibility: hidden; }

.bar-box__number {
  position: absolute;
  top: .25rem;
  left: .55rem;
  font-size: .6rem;
  letter-spacing: .14em;
  color: var(--ink-faint);
}

/* A chord name is never abbreviated. "Fmaj7/E" cut to "D..." is not a
   shorter chord, it is a wrong one - so a long name gets smaller type
   instead, and the cell keeps whatever it was given. */
.cell {
  font: inherit;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  line-height: 1.15;
  color: var(--ink);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: .5rem .12rem;
  min-height: 2.7rem;
  cursor: text;
  overflow: hidden;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

/* Written with the class doubled so these beat .cell--first below, which
   raises the size of the first beat in a bar - and which was quietly
   cancelling this and cutting "Cmaj7" in half. */
.cell.cell--long { font-size: .84rem; letter-spacing: -.01em; }
.cell.cell--longer { font-size: .72rem; letter-spacing: -.02em; }

.cell:hover { border-color: var(--line-strong); background: rgba(255, 255, 255, .05); }
.cell--held { color: var(--ink-faint); font-weight: 400; }
.cell--edited { color: var(--teal); }
.cell--unsure { border-bottom: 2px dotted var(--warn); }

.cell--on {
  background: linear-gradient(180deg, rgba(232, 188, 85, .26), rgba(232, 188, 85, .12));
  border-color: rgba(232, 188, 85, .75);
  color: #fff3d6;
  box-shadow: 0 0 22px -4px rgba(232, 188, 85, .55);
}

.cell--editing {
  background: var(--ground);
  border-color: var(--gold);
  padding: .2rem;
}

.cell__input {
  width: 100%;
  font: inherit;
  font-weight: 700;
  text-align: center;
  color: var(--gold);
  background: transparent;
  border: 0;
  outline: none;
}

kbd {
  font: inherit;
  font-size: .78rem;
  padding: .05rem .34rem;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--raise);
  color: var(--ink);
}

code { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: .85em; color: var(--gold); }

/* --- the archive --------------------------------------------------------- */
.search { flex: 1 1 15rem; }

.archive__list { display: grid; gap: .45rem; margin-top: .8rem; }

.archive__row {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.2fr;
  gap: .6rem;
  align-items: baseline;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: .7rem .9rem;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}

.archive__row:hover {
  border-color: rgba(232, 188, 85, .55);
  background: rgba(232, 188, 85, .07);
  transform: translateX(2px);
}

.archive__title { font-family: var(--display); font-weight: 600; font-size: 1.02rem; }
.archive__artist { color: var(--ink-dim); font-size: .85rem; }
.archive__meta { color: var(--ink-faint); font-size: .8rem; text-align: right; }

/* --- the editor ---------------------------------------------------------- */
.editor {
  position: absolute;
  z-index: 10;
  width: 244px;
  background: var(--panel-solid);
  border: 1px solid rgba(232, 188, 85, .6);
  border-radius: 14px;
  padding: .85rem .95rem 1rem;
  box-shadow: 0 30px 70px -20px rgba(0, 0, 0, .9);
}

.editor__title { margin: 0 0 .6rem; font-size: .9rem; font-weight: 600; }
.editor__grid { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.editor label { display: grid; gap: .25rem; font-size: .74rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }

.editor select {
  font: inherit;
  font-size: .88rem;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  background: rgba(10, 13, 21, .7);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .36rem .45rem;
}

/* --- the foot ------------------------------------------------------------ */
.foot {
  position: relative;
  overflow: hidden;
  max-width: var(--width);
  margin: 0 auto;
  padding: 2rem 1.4rem 3rem;
  border-top: 1px solid var(--line);
}

.foot__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; }

.foot__title {
  margin: 0 0 .45rem;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--gold);
}

.verse--foot {
  margin: 1.8rem auto 1.2rem;
  max-width: 34rem;
  padding: 0;
  border-left: 0;
  text-align: center;
}

.verse--foot p { font-size: 1.1rem; }
.verse--foot cite { margin-top: .35rem; }

.foot__credit { text-align: center; max-width: 60ch; margin: 0 auto; }

/* --- smaller screens ------------------------------------------------------ */
@media (max-width: 1240px) {
  .grid { --bars-per-row: 2; }
}

@media (max-width: 900px) {
  .stage { grid-template-columns: 1fr; }
  /* The sheet has the whole page now, so the bars can spread out again. */
  .grid { --bars-per-row: 4; }
  .now { position: static; grid-template-columns: 1.3fr 1fr; }
}

@media (max-width: 720px) {
  .hero { padding-top: 2rem; }
  .hero__inner { grid-template-columns: auto 1fr; gap: 1rem; align-items: start; }
  .panel { padding: 1.2rem 1.1rem 1.3rem; }
  .song { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .song__field--title { grid-column: 1 / -1; }
  .now__chord--next .now__hint { min-width: 0; }
  .archive__row { grid-template-columns: 1fr; gap: .15rem; }
  .archive__meta { text-align: left; }
  .now { grid-template-columns: 1fr; }
  .now__chord--next { display: flex; gap: 1rem; align-items: center; text-align: left; }
  .now__chord--next .now__diagram svg { width: 104px; }
  .grid { --bars-per-row: 2; }
  .foot__grid { grid-template-columns: 1fr; }
}

/* Someone who has asked for less movement gets none of it: the rosette holds
   still, and nothing slides. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- the chart, read the way a chord sheet is read ----------------------- */
/* A beat that carries on the chord before it is left blank, the way it is on
   paper; the beats are still there, marked by the lines between them, and
   every one of them is still clickable. */
.bar-box {
  background-image: linear-gradient(90deg, rgba(232, 188, 85, .38) 0 2px, transparent 2px);
  background-repeat: no-repeat;
}

.cell + .cell { box-shadow: inset 1px 0 0 rgba(255, 255, 255, .07); }
.cell--held { color: transparent; }
.cell--held:hover { color: var(--ink-faint); }
.cell--first { font-size: 1.15rem; }

/* --- sections ------------------------------------------------------------ */
.sheet__bar {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  align-items: center;
  margin-bottom: .7rem;
}

.section-input {
  flex: 0 1 12rem;
  min-width: 0;
  font: inherit;
  font-size: .88rem;
  color: var(--ink);
  background: rgba(10, 13, 21, .6);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .4rem .6rem;
}

.sheet__hint { font-size: .78rem; color: var(--ink-faint); }

/* Shown only while the chart is not following the music - because the reader
   scrolled away to look at what is coming. */
.follow {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font: inherit;
  font-size: .8rem;
  font-weight: 600;
  color: #1c1402;
  background: linear-gradient(180deg, #f5cf6e, var(--gold) 60%, #cf9f3a);
  border: 0;
  border-radius: 999px;
  padding: .35rem .8rem;
  cursor: pointer;
}

.follow[hidden] { display: none; }

.section-label {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: .5rem 0 -.1rem;
  font-family: var(--display);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--gold);
}

.section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(232, 188, 85, .45), transparent);
}

.section-label button {
  font: inherit;
  font-size: .9em;
  letter-spacing: normal;
  color: var(--ink-faint);
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0 .2rem;
}

.section-label button:hover { color: var(--warn); }

/* --- the chords used in this song ---------------------------------------- */
.overview {
  margin-top: 1.1rem;
  padding-top: .9rem;
  border-top: 1px solid var(--line);
}

.overview__title {
  margin: 0 0 .6rem;
  font-size: .7rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.overview__row {
  display: flex;
  gap: .9rem;
  overflow-x: auto;
  padding-bottom: .4rem;
  scrollbar-width: thin;
}

.overview__chord {
  flex: none;
  width: 74px;
  text-align: center;
}

.overview__chord svg { width: 100%; height: auto; }

.overview__name {
  margin: 0 0 .2rem;
  font-family: var(--display);
  font-weight: 600;
  font-size: .95rem;
  color: var(--ink);
}

/* A chord is printed with its quality raised and smaller - Amaj7, not AMAJ7 -
   which is how it appears in every songbook. */
.chord-quality { font-size: .62em; vertical-align: .42em; letter-spacing: .01em; }

.now__name .chord-quality { font-size: .44em; vertical-align: .62em; }

/* --- the arrows beside the key ------------------------------------------- */
.step {
  font: inherit;
  font-size: .8rem;
  line-height: 1;
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .3rem .45rem;
  cursor: pointer;
}

.step:hover { border-color: rgba(232, 188, 85, .5); }

/* --- a chord sheet used as a guide --------------------------------------- */
.guide {
  margin-bottom: .9rem;
  padding: .9rem 1rem 1rem;
  background: rgba(10, 13, 21, .5);
  border: 1px solid var(--line);
  border-radius: 14px;
}

.guide[hidden] { display: none; }

.guide__text {
  width: 100%;
  margin-top: .6rem;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink);
  background: rgba(6, 8, 14, .7);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .6rem .7rem;
  resize: vertical;
}

.guide__text:focus { border-color: rgba(232, 188, 85, .6); outline: none; }

/* --- reading a photograph of a chord sheet ------------------------------- */
.guide__ways { display: flex; gap: .8rem; align-items: stretch; margin-top: .7rem; }

.shot {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .7rem;
  min-height: 4.6rem;
  padding: .7rem 1rem;
  text-align: left;
  font-size: .85rem;
  color: var(--ink-dim);
  background: rgba(255, 255, 255, .035);
  border: 1.5px dashed var(--line-strong);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color .18s ease, background-color .18s ease;
}

.shot:hover, .shot:focus-within, .shot--over {
  border-color: rgba(232, 188, 85, .7);
  background: rgba(232, 188, 85, .08);
}

.shot svg { color: var(--gold); flex: none; }
.shot strong { color: var(--ink); font-weight: 600; }

.shot input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.guide__shot {
  flex: 0 0 auto;
  width: 96px;
  height: 4.6rem;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--line);
}

.guide__status {
  margin: .6rem 0 0;
  font-size: .85rem;
  color: var(--gold);
}

.guide__status[hidden] { display: none; }

@media (max-width: 720px) {
  .guide__ways { flex-direction: column; }
  .guide__shot { width: 100%; height: 7rem; }
}

/* --- charts kept in this browser ----------------------------------------- */
.saved { margin-bottom: 1.1rem; }
.saved[hidden] { display: none; }

.search--name { flex: 0 1 11rem; }

.archive__row--saved { grid-template-columns: 1.4fr 1fr auto auto; align-items: center; }

.archive__row .drop {
  font: inherit;
  font-size: .78rem;
  color: var(--ink-faint);
  background: none;
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .2rem .5rem;
  cursor: pointer;
}

.archive__row .drop:hover { color: var(--warn); border-color: var(--warn); }

/* A chord from outside the key. Marked, not corrected: most songs have one or
   two, they are usually the interesting bar, and a chart that quietly tidied
   them away would be telling the reader something untrue. */
.cell--outside::after {
  content: "";
  position: absolute;
  top: .3rem;
  right: .3rem;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--violet);
}

.cell { position: relative; }

/* --- a bar cut short by an odd bar ---------------------------------------- */
.bar-box--short {
  border-style: dashed;
}

.bar-box--short .bar-box__number::after {
  content: " \2022 short";
  opacity: .7;
}

/* --- the beat model, checking the beats in the background ------------------ */
.refine {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .6rem;
  margin: .4rem 0 0;
  font-size: .88rem;
  color: var(--ink-dim);
}

.refine__mark {
  color: var(--ink-faint);
  font-size: .6rem;
}

/* =========================================================================
   The draft. Chord Coach suggests; the reader decides. A suggestion is drawn
   faded and slanted - the way a pencilled guess looks next to ink - and it
   becomes ink when somebody has listened and confirmed it or typed the
   right one.
   ========================================================================= */
.cell--suggested { opacity: .5; font-style: italic; }
.cell--suggested:hover { opacity: .8; }
.cell--suggested.cell--on { opacity: .9; }
.cell--selected {
  opacity: 1;
  outline: 2px solid var(--violet);
  outline-offset: -2px;
  box-shadow: 0 0 18px -6px var(--violet);
}
.cell--selected.cell--held { color: var(--ink-faint); }

.draft,
.finished {
  display: grid;
  gap: .45rem;
  margin: 0 0 .8rem;
  padding: .75rem .9rem;
  border: 1px dashed rgba(141, 124, 242, .45);
  border-radius: var(--radius-sm);
  background: rgba(141, 124, 242, .07);
}
.draft[hidden],
.finished[hidden] { display: none; }

.draft__lead,
.finished p { margin: 0; font-size: .88rem; color: var(--ink-dim); }
.draft__lead strong,
.finished strong { color: var(--ink); }

.draft__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .45rem;
  margin: 0;
}

.draft__progress {
  font-size: .85rem;
  font-weight: 600;
  color: var(--violet);
  margin-right: .3rem;
}

.btn--finish { margin-left: auto; opacity: .6; }
.btn--finish.is-ready { opacity: 1; box-shadow: 0 0 0 1px var(--teal), 0 0 22px -6px var(--teal); }

.finished {
  grid-template-columns: 1fr auto;
  align-items: center;
  border-style: solid;
  border-color: rgba(89, 201, 168, .4);
  background: rgba(89, 201, 168, .07);
}

.draft kbd,
.finished kbd {
  font-size: .72rem;
  padding: 0 .3rem;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  margin-left: .2rem;
}

/* The song's settings, while they are still the app's guesses. */
.song__field--suggested > span::after { content: " \00b7 suggested"; color: var(--violet); letter-spacing: .06em; }
.song__field--suggested input,
.song__field--suggested select { border-style: dashed; font-style: italic; color: var(--ink-dim); }

.settle {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin: .2rem 0 .8rem;
  font-size: .85rem;
  color: var(--ink-dim);
}
.settle[hidden] { display: none; }
.settle strong { color: var(--violet); font-weight: 600; }

/* Practice belongs to a finished chart. */
.practice {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem 1.5rem;
  align-items: center;
}
.practice[hidden] { display: none; }
.practice__locked { margin: 0; }
.practice__locked[hidden] { display: none; }
#detail-control[hidden] { display: none; }

/* Tempo markings, written over the bar where the tempo changes. */
.tempo-mark {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: .35rem;
  margin: .45rem 0 -.15rem;
  font-family: var(--display);
  font-size: .95rem;
  color: var(--ink);
}
.tempo-mark__note { font-size: 1.05rem; }
.tempo-mark__value {
  font: inherit;
  font-weight: 700;
  color: inherit;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--line-strong);
  padding: 0 .1rem;
  cursor: pointer;
}
.tempo-mark__when { font-family: var(--sans); font-size: .72rem; color: var(--ink-faint); }
.tempo-mark__act {
  font: inherit;
  font-family: var(--sans);
  font-size: .8rem;
  color: var(--ink-faint);
  background: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0 .45rem;
  cursor: pointer;
}
.tempo-mark__act:hover { color: var(--ink); border-color: var(--line-strong); }
.tempo-mark--suggested { opacity: .6; font-style: italic; }
.tempo-mark--suggested .tempo-mark__value { border-bottom-style: dashed; }
.tempo-mark__input {
  width: 4.5rem;
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  background: var(--ground);
  border: 1px solid var(--violet);
  border-radius: 6px;
  padding: 0 .3rem;
}

/* =========================================================================
   Finding your way. Three steps, said once at the top and shown again at
   the top of the song: open, check, practise.
   ========================================================================= */
.refine[hidden] { display: none; }

.steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .8rem;
  margin: 1.1rem 0 1.2rem;
  padding: 0;
  max-width: 44rem;
}
.steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: .55rem;
  align-items: baseline;
  font-size: .85rem;
  color: var(--ink-dim);
}
.steps li span:last-child { grid-column: 2; font-size: .8rem; color: var(--ink-faint); }
.steps strong { color: var(--ink); font-weight: 600; }
.steps__n {
  display: inline-grid;
  place-items: center;
  width: 1.45rem;
  height: 1.45rem;
  border-radius: 50%;
  font-size: .75rem;
  font-weight: 700;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  background: var(--raise);
}

.stepper {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1.4rem;
  margin: 0 0 1.1rem;
  padding: 0 0 .8rem;
  border-bottom: 1px solid var(--line);
  font-size: .85rem;
  color: var(--ink-faint);
}
.stepper li { display: flex; align-items: center; gap: .45rem; }
.stepper li.is-done .steps__n { background: rgba(89, 201, 168, .18); border-color: var(--teal); color: var(--teal); }
.stepper li.is-done .steps__n::before { content: "\2713"; }
.stepper li.is-done .steps__n { font-size: 0; }
.stepper li.is-done .steps__n::before { font-size: .75rem; }
.stepper li.is-now { color: var(--ink); font-weight: 600; }
.stepper li.is-now .steps__n { background: var(--violet); border-color: var(--violet); color: #fff; }

/* Where to start: one thing to press, and the rest as plain links. */
.ways {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .7rem;
  margin: .7rem 0 0;
  font-size: .85rem;
  color: var(--ink-faint);
}
.ways__gap { margin-left: .8rem; }
.link {
  font: inherit;
  color: var(--ink-dim);
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 3px;
  cursor: pointer;
}
.link:hover { color: var(--ink); text-decoration-color: var(--gold); }

/* The draft toolbar: compact, and pinned while the chart scrolls under it. */
.draft {
  position: sticky;
  top: .5rem;
  z-index: 4;
  gap: .35rem;
  padding: .6rem .75rem;
  background: rgba(24, 22, 44, .94);
  backdrop-filter: blur(6px);
}
.draft__lead { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .9rem; font-size: .84rem; }
.legend { display: inline-flex; align-items: center; gap: .35rem; color: var(--ink-faint); }
.chip {
  display: inline-grid;
  place-items: center;
  min-width: 1.6rem;
  padding: .05rem .35rem;
  font-family: var(--display);
  font-weight: 600;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
}
.chip--suggested { opacity: .5; font-style: italic; border-style: dashed; }
.keys-hint { font-size: .78rem; color: var(--ink-faint); margin-left: auto; }

.more { position: relative; }
.more > summary { list-style: none; }
.more > summary::-webkit-details-marker { display: none; }
.more > summary::after { content: " \25BE"; }
.more__menu {
  position: absolute;
  z-index: 5;
  top: calc(100% + .35rem);
  left: 0;
  display: grid;
  min-width: 15rem;
  padding: .35rem;
  background: var(--panel-solid);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}
.more__menu button {
  font: inherit;
  font-size: .86rem;
  text-align: left;
  color: var(--ink);
  background: none;
  border: 0;
  border-radius: 6px;
  padding: .5rem .6rem;
  cursor: pointer;
}
.more__menu button:hover { background: var(--raise); }

.sheet__follow { display: flex; justify-content: flex-end; min-height: 0; }
.sheet__follow .follow { margin: 0 0 .4rem; }

/* Sections, bar lines and the chord sheet: there when wanted, folded away
   when not, below the chart they change. */
.tools {
  margin-top: .8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .02);
}
.tools > summary {
  padding: .55rem .8rem;
  font-size: .86rem;
  font-weight: 600;
  color: var(--ink-dim);
  cursor: pointer;
}
.tools[open] > summary { border-bottom: 1px solid var(--line); }
.tools > .sheet__bar,
.tools > .sheet__hint,
.tools > .guide { margin: .7rem .8rem; }

/* A touch screen has no Enter or Tab key; the buttons say it all. */
@media (hover: none) {
  .keys-hint { display: none; }
}

@media (max-width: 900px) {
  /* While checking a draft, the chart comes first; the shapes follow. */
  .panel--song.is-draft .stage > .sheet { order: -1; }
}

@media (max-width: 720px) {
  .steps { grid-template-columns: 1fr; gap: .55rem; }
  .sheet { padding: .6rem .5rem .7rem; }
  .draft { top: .25rem; }
  .draft__row .btn--small { padding: .45rem .7rem; }
  /* The two diagrams side by side, smaller, so the page is not two screens
     of pictures before the chart. */
  .now { grid-template-columns: 1fr 1fr; gap: .5rem; }
  .now__chord { padding: .6rem .5rem .7rem; }
  .now__chord--next { display: block; text-align: center; }
  .now__name { font-size: 2rem; }
  .now__diagram svg, .now__chord--next .now__diagram svg { width: 92px; }
}

@media (max-width: 720px) {
  /* Title across the top, then the small fields three to a row. */
  .song { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; }
  .song__field--title { grid-column: 1 / -1; }
  .song__field--suggested > span::after { content: " \00b7 ?"; }
  .settle { font-size: .8rem; margin-bottom: .6rem; }
  .stepper { gap: .3rem .9rem; font-size: .78rem; }

  /* The toolbar pinned over the chart has to stay small on a phone. */
  .draft { padding: .45rem .5rem; gap: .25rem; }
  .draft__lead { font-size: .74rem; gap: .2rem .6rem; }
  .draft__lead > strong { display: none; }
  .draft__progress { width: 100%; font-size: .8rem; }
  .draft__row { gap: .3rem; }
  .draft__row .btn--small { padding: .38rem .6rem; font-size: .8rem; }
  .btn--finish { margin-left: 0; }
}

/* An empty message line takes no room. */
.sheet__hint:empty { display: none; }

/* Help for the hands in use: keys where there is a keyboard, taps where
   there is only a screen. */
.help--touch { display: none; }
@media (hover: none) {
  .help--touch { display: block; }
  .help--keys { display: none; }
}

@media (max-width: 720px) {
  /* A chord name is never cut short. On a phone the beats are narrow, so the
     name is set a little smaller and allowed to run on over the blank beats
     that follow it - the way it is written on paper. */
  .cell { overflow: visible; white-space: nowrap; position: relative; z-index: 1; font-size: .9rem; }
  .cell--first { font-size: .98rem; }
  .cell.cell--long { font-size: .78rem; }
  .cell.cell--longer { font-size: .68rem; }
}

@media (max-width: 1100px) and (min-width: 721px) {
  .song { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .song__field--title { grid-column: span 2; }
}

/* --- the mini player -------------------------------------------------------- */
.mini {
  position: fixed;
  z-index: 50;
  left: 50%;
  bottom: calc(.8rem + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: .7rem;
  max-width: calc(100vw - 1.5rem);
  padding: .45rem .9rem .45rem .5rem;
  background: rgba(22, 27, 43, .92);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  box-shadow: 0 18px 40px -16px rgba(0, 0, 0, .9);
}
.mini[hidden] { display: none; }
.mini__btn {
  display: inline-grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  flex: none;
  font: inherit;
  font-size: 1.05rem;
  line-height: 1;
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
}
.mini__btn small { font-size: .55rem; margin-top: -.35rem; }
.mini__play {
  width: 2.8rem;
  height: 2.8rem;
  color: #1c1402;
  background: linear-gradient(180deg, #f5cf6e, var(--gold) 55%, #cf9f3a);
  border: 0;
  font-size: .95rem;
}
.mini__time { font-variant-numeric: tabular-nums; font-size: .85rem; color: var(--ink-dim); }
.mini__chord { font-family: var(--display); font-weight: 700; font-size: 1.25rem; color: var(--gold); min-width: 2.5rem; }
.mini__bar { font-size: .78rem; color: var(--ink-faint); white-space: nowrap; }
body.has-mini { padding-bottom: 5rem; }

/* =========================================================================
   The setup: which song, then how sensitive - then the main screen.
   ========================================================================= */
.setup__steps { display: grid; gap: 1.3rem; }
.setup__steps[hidden] { display: none; }
.setup__step { display: grid; gap: .6rem; }
.setup__label {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin: 0;
  font-weight: 600;
  color: var(--ink);
}
.setup__go { margin-top: .2rem; }

.setup__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .8rem;
  margin: 0;
  font-size: .92rem;
}
.setup__summary[hidden] { display: none; }
.setup__song { font-family: var(--display); font-weight: 600; color: var(--ink); }
.setup__level { color: var(--ink-faint); font-size: .85rem; }

/* Five steps along one line, named underneath. */
.sense { max-width: 34rem; }
.sense__slider { width: 100%; accent-color: var(--violet); cursor: pointer; }
.sense__marks {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  margin-top: .15rem;
  font-size: .74rem;
  color: var(--ink-faint);
  text-align: center;
}
.sense__marks span:first-child { text-align: left; }
.sense__marks span:last-child { text-align: right; }
.sense__words { margin: 0; font-size: .9rem; color: var(--ink-dim); max-width: 40rem; }

.control--sense { display: inline-flex; align-items: center; gap: .5rem; }
.control--sense label { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.sense__slider--small { width: 7.5rem; }
.control--sense output { font-size: .85rem; color: var(--violet); min-width: 5.5rem; }

/* Suggestion sets, and the other candidates for one beat. */
.candidates {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem .5rem;
  margin: 0;
  font-size: .8rem;
  color: var(--ink-faint);
}
.candidates[hidden] { display: none; }
.candidates__list { display: inline-flex; flex-wrap: wrap; gap: .35rem; }
.candidate {
  display: inline-flex;
  align-items: baseline;
  gap: .35rem;
  font: inherit;
  font-size: .8rem;
  color: var(--ink-dim);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .2rem .65rem;
  cursor: pointer;
}
.candidate:hover { border-color: var(--violet); color: var(--ink); }
.candidate.is-on { border-color: var(--violet); color: var(--ink); background: rgba(141, 124, 242, .16); }
.candidate--chord strong { font-family: var(--display); font-size: .98rem; color: var(--ink); }
.candidate--chord small { font-size: .68rem; color: var(--ink-faint); }

@media (max-width: 720px) {
  .control--sense { flex-wrap: wrap; }
  .sense__slider--small { width: 100%; }
  .sense__marks { font-size: .66rem; }
}

/* A button that cannot be pressed yet looks it. */
.btn:disabled,
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; filter: none; box-shadow: none; }

/* The names sit under the slider's five stops, not in five equal boxes. */
.sense__marks { position: relative; display: block; height: 1.1rem; }
.sense__marks span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.sense__marks span:nth-child(1) { left: 0; transform: none; }
.sense__marks span:nth-child(2) { left: 25%; }
.sense__marks span:nth-child(3) { left: 50%; }
.sense__marks span:nth-child(4) { left: 75%; }
.sense__marks span:nth-child(5) { left: auto; right: 0; transform: none; }

/* =========================================================================
   Tips: a speech bubble pointing at one part of the page, the rest shaded.
   The shade is the hole's own shadow, spread to the edges of the screen, so
   the part being explained stays lit and in place.
   ========================================================================= */
.tour { position: fixed; inset: 0; z-index: 100; }
.tour[hidden] { display: none; }
.tour__hole {
  position: fixed;
  border-radius: 14px;
  box-shadow: 0 0 0 9999px rgba(4, 6, 12, .74), 0 0 0 2px rgba(141, 124, 242, .9);
  transition: top .25s ease, left .25s ease, width .25s ease, height .25s ease;
  pointer-events: auto;
}
.tour__bubble {
  position: fixed;
  z-index: 1;
  padding: 1rem 1.1rem .9rem;
  background: var(--panel-solid);
  border: 1px solid rgba(141, 124, 242, .55);
  border-radius: 14px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .9);
  color: var(--ink);
  transition: top .25s ease, left .25s ease;
}
/* The point of the bubble, towards what it is about. */
.tour__bubble::before {
  content: "";
  position: absolute;
  left: calc(var(--arrow, 50%) - 8px);
  width: 16px;
  height: 16px;
  background: var(--panel-solid);
  border: 1px solid rgba(141, 124, 242, .55);
  transform: rotate(45deg);
}
.tour__bubble[data-side="below"]::before { top: -9px; border-right: 0; border-bottom: 0; }
.tour__bubble[data-side="above"]::before { bottom: -9px; border-left: 0; border-top: 0; }
.tour__count { margin: 0 0 .2rem; font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--violet); }
.tour__title { margin: 0 0 .35rem; font-family: var(--display); font-size: 1.1rem; }
.tour__text { margin: 0; font-size: .88rem; line-height: 1.5; color: var(--ink-dim); }
.tour__actions { display: flex; align-items: center; justify-content: space-between; gap: .6rem; margin-top: .85rem; }
.tour__nav { display: inline-flex; gap: .4rem; }
.tour__nav [hidden] { display: none; }
.tour__never {
  font: inherit;
  font-size: .76rem;
  color: var(--ink-faint);
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.tour__never:hover { color: var(--ink); }
.tour__close {
  position: absolute;
  top: .35rem;
  right: .45rem;
  font: inherit;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--ink-faint);
  background: none;
  border: 0;
  padding: .2rem .35rem;
  cursor: pointer;
}
.tour__close:hover { color: var(--ink); }

.stepper-row { display: flex; align-items: flex-start; gap: 1rem; }
.stepper-row .stepper { flex: 1; }
.tips-button {
  font: inherit;
  font-size: .8rem;
  color: var(--ink-dim);
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .25rem .7rem;
  cursor: pointer;
  white-space: nowrap;
}
.tips-button:hover { color: var(--ink); border-color: var(--violet); }

@media (prefers-reduced-motion: reduce) {
  .tour__hole, .tour__bubble { transition: none; }
}

/* =========================================================================
   The palette: the key's chords as buttons, the song's own first, each with
   the number that is also its key on the keyboard.
   ========================================================================= */
.palette { display: grid; gap: .35rem; }
.palette[hidden], .palette__row[hidden] { display: none; }
.palette__row { display: flex; align-items: center; gap: .5rem; min-width: 0; }
.palette__label { flex: none; font-size: .78rem; color: var(--ink-faint); }
.palette__chords {
  display: flex;
  gap: .35rem;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: .1rem;
}
.palette__chord {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: baseline;
  gap: .3rem;
  font: inherit;
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  padding: .32rem .62rem;
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.palette__chord strong { font-family: var(--display); font-size: 1rem; font-weight: 700; }
.palette__chord small { font-size: .66rem; color: var(--ink-faint); }
.palette__chord:hover { border-color: var(--violet); background: rgba(141, 124, 242, .14); }
.palette__chord:active { transform: translateY(1px); }
.palette__chord--outside { border-style: dashed; }
.palette__chord--variant strong { font-size: .9rem; font-weight: 600; }

@media (max-width: 720px) {
  .palette__label { display: none; }
  .palette__chord { padding: .4rem .7rem; }
}
