:root {
  --note-bg: #2b2b2b;
  --note-fg: #f5f0e6;
  --tonic-bg: #a03e2d;
  --tonic-fg: #f5f0e6;
  --root-bg: #0e6f86;
  --root-fg: #f5f0e6;
  --dim-opacity: 0.15;

  /* Shared board colors — the neck and the triad boxes both draw from these */
  --board-bg: #f5efe0;
  --fret-color: #b9b2a4;
  --string-color: #6b6b6b;
  --nut-color: #3a3a3a;
  --inlay-color: #cfc8b8;
  --label-color: #888;

  /* How far the board's left edge sits inside the page's content column: the
     string-name column (1.7rem chip + 0.6rem padding) plus the open-string
     gutter (1.9rem). Everything that wants to look centred *under the board*
     rather than under the content column offsets by this — the key picker, the
     chord strip and the triad grid all do. Derived from the three widths below,
     so changing any of them means changing this. */
  --neck-inset: 4.2rem;
}

.fretboard {
  --frets: 22;
  --nut-width: 8px;

  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: auto auto;
  margin: 0;
  min-width: 44rem;
}

.board-scroll {
  overflow-x: auto;
}

.board {
  grid-column: 3;
  grid-row: 1;
  display: grid;
  grid-template-columns: repeat(var(--frets), 1fr);
  grid-template-rows: repeat(6, 1fr);
  height: 13.5rem;
  background-color: var(--board-bg);
  /* One tile per fret gap; each tile paints a 2px wire on its right edge,
     so wires land at fret 1..22 and the last coincides with the board edge. */
  background-image: linear-gradient(to left, var(--fret-color) 2px, transparent 2px);
  background-size: calc(100% / var(--frets)) 100%;
  border-left: var(--nut-width) solid var(--nut-color);
}

.string {
  grid-column: 1 / -1;
  grid-row: var(--row);
  align-self: center;
  /* Thicker toward low E: row 1 (high e) = 1px ... row 6 (low E) = 3.5px */
  height: calc(0.5px * (var(--row) + 1));
  background-color: var(--string-color);
}

.inlay {
  grid-column: var(--fret);
  grid-row: 1 / -1;
  place-self: center;
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  background-color: var(--inlay-color);
}

/* Fret 12 double dots. Each spans two string rows so it centers on the line
   between them, landing in a gap the way a real neck's dots do: between the B
   and G strings above, between the D and A strings below. Spanning three rows
   (1/4 and 4/7) centers on rows 2 and 5 instead, putting each dot directly
   under a string. Strings run down row centers, so an even span is what puts a
   marker in a gap. The triad boxes place their pair to match. */
.inlay-upper {
  grid-row: 2 / 4;
}

.inlay-lower {
  grid-row: 4 / 6;
}

.string-names {
  grid-column: 1;
  grid-row: 1;
  display: grid;
  grid-template-rows: repeat(6, 1fr);
  padding-right: 0.6rem;
}

/* The names are checkbox chips that hide and show their string — see the
   visibility block at the foot of this file. `.chip` brings the shared chip
   look from site.css; these overrides shrink it to fit, because six rows share
   the board's 13.5rem and so get 2.25rem each, well under the tone chips'
   comfortable height. `justify-self: center` keeps the pill from stretching to
   the widest sibling, which would make "e" and "E" different widths. */
.string-names .chip {
  display: grid;
  place-items: center;
  justify-self: center;
  align-self: center;
  min-width: 1.7rem;
  padding: 0.1rem 0.35rem;
  font-size: 0.8rem;
}

/* Fret-0 (open string) gutter between the string names and the nut.
   Fixed width so toggling notes never shifts the board. */
.open-notes {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  grid-template-rows: repeat(6, 1fr);
  width: 1.9rem;
  padding-right: 0.3rem;
}

.open-notes .note {
  grid-column: 1;
}

.fret-numbers {
  grid-column: 3;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(var(--frets), 1fr);
  /* Transparent stand-in for the nut so number tiles align with fret gaps */
  border-left: var(--nut-width) solid transparent;
  padding-top: 0.4rem;
}

.fret-numbers span {
  text-align: center;
  font-size: 0.8rem;
  color: var(--label-color);
}

.note {
  display: none;
  grid-column: var(--fret);
  grid-row: var(--row);
  place-self: center;
  place-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background-color: var(--note-bg);
  color: var(--note-fg);
  font-size: 0.7rem;
  line-height: 1.05;
  text-align: center;
}

/* Flat spelling, stacked under the sharp name */
.note i {
  font-style: normal;
  font-size: 0.55rem;
  opacity: 0.75;
}

/* Sharp spelling wrapper — plain text look; a grid row like the <i> */
.note b {
  font-weight: normal;
}

/* Chord-degree mark. Generates no box until a chord rule sets content, so
   markers are untouched when no chord is selected. */
.note::after {
  font-size: 0.5rem;
  opacity: 0.85;
  line-height: 1;
}

/* The per-tone reveal rules that used to live here are gone with the "Show
   notes" chips: a note is now revealed only by a key selection, via the 672
   generated rules in keys.css. The `.tone-*` classes on every .note stay — they
   are exactly the pitch-class hooks those rules match on. */

/* ---------- String toggles.

   Each string name is a checked checkbox; unchecking it hides that string's
   notes. Spec: docs/superpowers/specs/2026-07-26-string-toggles-design.md

   These rules own `visibility`, and nothing else in the project sets it. That
   is the whole trick: `display` belongs to the reveal rules above and to the
   672 generated ones in keys.css, `opacity` and `content` to the chord rules,
   `background-color` and `color` to the tonic rules. Because the lanes are
   disjoint, a hidden string ANDs cleanly with whatever key, chord or tone is
   selected — no `!important`, no specificity contest, no ordering dependency.

   `visibility: hidden` also keeps the note's grid cell, which is what we want:
   .board's geometry is fixed by --frets and 6 rows regardless of its contents,
   so hiding a string cannot reflow the neck.

   The selector tests for the checkbox's ABSENCE, so all-six-on is the state no
   rule matches — the same reset-by-absence convention the chord strips use. */

/* A run of 22 notes for one string. `display: contents` is load-bearing: the
   wrapper must not become a grid item, or the notes inside it would be laid
   out against the wrapper instead of .board and lose their --fret/--row cells.
   Generating no box is also what lets `visibility` inherit straight through. */
.string-notes {
  display: contents;
}

main:not(:has(#string-1:checked)) .str-1,
main:not(:has(#string-2:checked)) .str-2,
main:not(:has(#string-3:checked)) .str-3,
main:not(:has(#string-4:checked)) .str-4,
main:not(:has(#string-5:checked)) .str-5,
main:not(:has(#string-6:checked)) .str-6 {
  visibility: hidden;
}

/* Vertical orientation (chord-chart convention) below 44rem: nut on top,
   frets descending, low E leftmost. Same markup — the --row/--fret
   placements are reinterpreted against a transposed grid. */
@media (max-width: 44rem) {
  .fretboard {
    /* Widest the vertical neck is allowed to get, and the fret-number gutter
       beside it — two digits at 0.8rem plus 0.6rem of padding, which measures
       ~1.45rem, so 1.8rem clears it on any platform's metrics. */
    --vneck-w: 20rem;
    --vneck-gutter: 1.8rem;

    min-width: 0;
    /* Fixed gutters rather than `auto`, so the cap below is exact: the board
       track is then always (container - 2 * gutter). The third track is empty and
       exists only to balance the fret numbers on the left — without it the board
       sits half a gutter right of the neck's own centre, which is 14px off the
       axis the key and chord panels centre on. */
    grid-template-columns: var(--vneck-gutter) 1fr var(--vneck-gutter);
    grid-template-rows: auto auto 1fr;
    /* Cap the whole neck — gutters included — and centre it. Capping the board
       alone left every pixel of surplus on one side: at a 700px viewport the
       neck sat hard left with 309px of dead space to its right. The children
       below are plain `width: 100%` for the same reason; they must not carry
       their own cap, or the grid and the board would disagree about where the
       spare width belongs. */
    max-width: calc(var(--vneck-w) + 2 * var(--vneck-gutter));
    margin-inline: auto;
  }

  .board {
    grid-column: 2;
    grid-row: 3;
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(var(--frets), 1fr);
    width: 100%;
    height: calc(var(--frets) * 2.75rem);
    /* One tile per fret gap; each tile paints a 2px wire on its bottom
       edge, so wires land at frets 1..22 with the last at the board's
       bottom edge. */
    background-image: linear-gradient(to top, var(--fret-color) 2px, transparent 2px);
    background-size: 100% calc(100% / var(--frets));
    border-left: 0;
    border-top: var(--nut-width) solid var(--nut-color);
  }

  .string {
    /* Row 6 (low E) lands in column 1: leftmost, chord-chart order */
    grid-column: calc(7 - var(--row));
    grid-row: 1 / -1;
    align-self: stretch;
    justify-self: center;
    height: auto;
    width: calc(0.5px * (var(--row) + 1));
  }

  .inlay {
    grid-column: 1 / -1;
    grid-row: var(--fret);
  }

  /* Fret 12 double dots become a symmetric left/right pair, each still spanning
     two strings so it centers in the gap between them rather than under one. */
  .inlay-upper { grid-column: 2 / 4; grid-row: var(--fret); }
  .inlay-lower { grid-column: 4 / 6; grid-row: var(--fret); }

  .note {
    grid-column: calc(7 - var(--row));
    grid-row: var(--fret);
  }

  /* Open-notes gutter becomes a row between the string names and the nut */
  .open-notes {
    grid-column: 2;
    grid-row: 2;
    grid-template-rows: none;
    grid-template-columns: repeat(6, 1fr);
    width: 100%;
    height: 1.9rem;
    padding-right: 0;
    padding-bottom: 0.3rem;
  }

  .open-notes .note {
    grid-column: calc(7 - var(--row));
    grid-row: 1;
  }

  .string-names {
    grid-column: 2;
    grid-row: 1;
    grid-template-rows: none;
    grid-template-columns: repeat(6, 1fr);
    /* Same width formula as .board so header columns align with strings */
    width: 100%;
    padding-right: 0;
    padding-bottom: 0.6rem;
  }

  .string-names .chip {
    grid-row: 1;
  }

  /* Reverse display order so the header reads E A D G B e */
  .string-names .chip:nth-child(1) { grid-column: 6; }
  .string-names .chip:nth-child(2) { grid-column: 5; }
  .string-names .chip:nth-child(3) { grid-column: 4; }
  .string-names .chip:nth-child(4) { grid-column: 3; }
  .string-names .chip:nth-child(5) { grid-column: 2; }
  .string-names .chip:nth-child(6) { grid-column: 1; }

  .fret-numbers {
    grid-column: 1;
    grid-row: 3;
    grid-template-columns: none;
    grid-template-rows: repeat(var(--frets), 1fr);
    /* Transparent stand-in for the nut so number rows align with fret
       gaps — same trick as horizontal, transposed */
    border-left: 0;
    border-top: var(--nut-width) solid transparent;
    padding-top: 0;
    padding-right: 0.6rem;
  }

  .fret-numbers span {
    display: grid;
    place-items: center;
  }
}
