/* ==========================================================================
   GUITAR COACH — app.css
   Owner: A6 (visual design). Last Edited: 07/30/2026 HST
   Pure CSS. No build step. No remote fonts. Works offline.

   DESIGN NOTE
   Same paper-warm family as Growth Hub, but its own instrument identity:
   spruce paper, rosewood, brass fret wire. Accent is brass/ochre, not
   terracotta and not a blue/purple SaaS gradient.

   TYPE CARRIES THE CONTRACT (§3 shape vs sounding):
   the SHAPE name is set in the display serif, big and heavy;
   the "sounds like" line is small mono grey. Different typeface, size,
   weight and colour — so the two can never be misread for each other.

   TABLE OF CONTENTS
     01  Tokens (light)
     02  Dark mode
     03  Reset + base
     04  Shell: app / header / nav / page / section / card
     05  Buttons
     06  Form controls
     07  Badge / pill / caveat
     08  Chord cards + chord row
     09  Fretboard
     10  Strum pattern + counting row
     11  Pitch: meter / readout / cents / range
     12  Voice page: measure flow, mic block, facts, takes, modal
     13  Page furniture: home, songs, song detail, chords, learn
     14  Video embeds
     15  Empty / spinner / toast
     16  Stage (performance) mode
     17  Desktop layout
     18  Reduced motion
     19  Print (chord chart for the music stand)

   OPTIONAL HELPERS I OWN (safe to use, safe to ignore):
     .gc-row .gc-col .gc-stack .gc-spread .gc-grow
     .gc-muted .gc-mono .gc-display .gc-hairline .gc-sr-only
     .gc-range-band .gc-range-mark .gc-range-ref

   CUSTOM PROPERTIES OTHER MODULES CAN SET INLINE:
     --gc-level   0..1     drives .gc-meter fill width
     --gc-cents  -50..50   drives .gc-cents-needle position
   ========================================================================== */


/* ==========================================================================
   01  TOKENS (light) — the whole palette is tunable from this one block
   ========================================================================== */

:root {
  /* --- paper + ink --- */
  --gc-bg:          #f4f0e6;   /* spruce paper */
  --gc-bg-sunk:     #ece7da;   /* recessed wells, scroll tracks */
  --gc-card:        #fffdf7;   /* bone */
  --gc-card-2:      #faf6ec;   /* second-level surface inside a card */
  --gc-ink:         #2b2520;   /* walnut ink */
  --gc-ink-soft:    #4a4139;
  --gc-muted:       #6f6558;
  --gc-faint:       #93897a;
  --gc-line:        #e3dbc9;
  --gc-line-strong: #cfc4ac;

  /* --- instrument --- */
  --gc-brass:       #a97c1e;   /* fret wire, tuner gears — primary accent */
  --gc-brass-deep:  #8a6414;
  --gc-brass-lit:   #d9ab4e;
  --gc-brass-wash:  #f6ecd4;   /* tinted background */
  --gc-rosewood:    #5d3226;   /* deep structural brown */
  --gc-walnut:      #3a2a20;
  --gc-neck-hi:     #56392c;   /* fretboard wood, light edge */
  --gc-neck-lo:     #2e1d15;   /* fretboard wood, deep centre */
  --gc-string:      #d9d2c2;   /* wound string, light */
  --gc-string-hi:   #fffaf0;   /* string highlight */
  --gc-wire:        #cfc7b2;   /* nickel fret wire */
  --gc-inlay:       #efe8d7;   /* mother of pearl */

  /* --- states --- */
  --gc-good:        #3f7d52;   /* in tune / verified — shared with Growth Hub */
  --gc-good-wash:   #e6efe4;
  --gc-warn:        #b06a1c;   /* our-recommendation caveats */
  --gc-warn-wash:   #f8eddb;
  --gc-bad:         #a8382a;   /* out of range / destructive */
  --gc-bad-wash:    #f7e4df;

  /* --- header --- */
  --gc-header-a:    #5d3226;
  --gc-header-b:    #33241c;
  --gc-header-ink:  #f7f0e2;
  --gc-header-dim:  #cbbba1;

  /* --- type --- */
  --gc-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
                  Roboto, Helvetica, Arial, sans-serif;
  --gc-font-display: "Iowan Old Style", "Palatino Linotype", Palatino,
                  "Book Antiqua", Georgia, "Times New Roman", serif;
  --gc-font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
                  "Courier New", monospace;

  --gc-fs-xs:   0.75rem;
  --gc-fs-sm:   0.875rem;
  --gc-fs-base: 1.0625rem;   /* 17px — readable on a music stand */
  --gc-fs-lg:   1.25rem;
  --gc-fs-xl:   1.5rem;
  --gc-fs-2xl:  2rem;

  /* --- metrics --- */
  --gc-tap:     44px;        /* never go below this on a touch target */
  --gc-r-sm:    6px;
  --gc-r:       12px;
  --gc-r-lg:    18px;
  --gc-gap:     14px;
  --gc-pad:     16px;
  --gc-navh:    62px;

  --gc-shadow:    0 1px 2px rgba(58, 42, 32, 0.07), 0 6px 18px rgba(58, 42, 32, 0.07);
  --gc-shadow-lg: 0 10px 34px rgba(46, 29, 21, 0.22);
  --gc-ring:      0 0 0 3px rgba(169, 124, 30, 0.38);

  color-scheme: light dark;
}


/* ==========================================================================
   02  DARK MODE — Kevin practices at night. No blazing white in a dim room.
       Follows the OS by default; [data-theme] wins if the app ever adds a
       manual switch.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --gc-bg:          #15120e;
    --gc-bg-sunk:     #0f0c09;
    --gc-card:        #1f1a15;
    --gc-card-2:      #272019;
    --gc-ink:         #efe7d8;
    --gc-ink-soft:    #d8cebc;
    --gc-muted:       #a2957f;
    --gc-faint:       #857a68;
    --gc-line:        #362e24;
    --gc-line-strong: #4b4034;

    --gc-brass:       #d9a83f;
    --gc-brass-deep:  #b98a26;
    --gc-brass-lit:   #f0cd7c;
    --gc-brass-wash:  #2c2416;
    --gc-rosewood:    #7a4232;
    --gc-walnut:      #2a1e17;
    --gc-neck-hi:     #4a3126;
    --gc-neck-lo:     #241610;
    --gc-string:      #b6ae9d;
    --gc-string-hi:   #e9e1cf;
    --gc-wire:        #9c9482;
    --gc-inlay:       #d9d0bb;

    --gc-good:        #6fb383;
    --gc-good-wash:   #17271b;
    --gc-warn:        #dda155;
    --gc-warn-wash:   #2e2213;
    --gc-bad:         #e0705c;
    --gc-bad-wash:    #2f1815;

    --gc-header-a:    #3d251c;
    --gc-header-b:    #1c1410;
    --gc-header-ink:  #f3e9d7;
    --gc-header-dim:  #b0a087;

    --gc-shadow:      0 1px 2px rgba(0, 0, 0, 0.5), 0 6px 18px rgba(0, 0, 0, 0.45);
    --gc-shadow-lg:   0 12px 38px rgba(0, 0, 0, 0.6);
    --gc-ring:        0 0 0 3px rgba(217, 168, 63, 0.42);
  }
}

/* Manual override (same values — kept in sync with the block above). */
:root[data-theme="dark"] {
  --gc-bg:          #15120e;
  --gc-bg-sunk:     #0f0c09;
  --gc-card:        #1f1a15;
  --gc-card-2:      #272019;
  --gc-ink:         #efe7d8;
  --gc-ink-soft:    #d8cebc;
  --gc-muted:       #a2957f;
  --gc-faint:       #857a68;
  --gc-line:        #362e24;
  --gc-line-strong: #4b4034;

  --gc-brass:       #d9a83f;
  --gc-brass-deep:  #b98a26;
  --gc-brass-lit:   #f0cd7c;
  --gc-brass-wash:  #2c2416;
  --gc-rosewood:    #7a4232;
  --gc-walnut:      #2a1e17;
  --gc-neck-hi:     #4a3126;
  --gc-neck-lo:     #241610;
  --gc-string:      #b6ae9d;
  --gc-string-hi:   #e9e1cf;
  --gc-wire:        #9c9482;
  --gc-inlay:       #d9d0bb;

  --gc-good:        #6fb383;
  --gc-good-wash:   #17271b;
  --gc-warn:        #dda155;
  --gc-warn-wash:   #2e2213;
  --gc-bad:         #e0705c;
  --gc-bad-wash:    #2f1815;

  --gc-header-a:    #3d251c;
  --gc-header-b:    #1c1410;
  --gc-header-ink:  #f3e9d7;
  --gc-header-dim:  #b0a087;

  --gc-shadow:      0 1px 2px rgba(0, 0, 0, 0.5), 0 6px 18px rgba(0, 0, 0, 0.45);
  --gc-shadow-lg:   0 12px 38px rgba(0, 0, 0, 0.6);
  --gc-ring:        0 0 0 3px rgba(217, 168, 63, 0.42);
}


/* ==========================================================================
   03  RESET + BASE
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;   /* stop iOS inflating text in landscape */
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--gc-bg);
  color: var(--gc-ink);
  font-family: var(--gc-font-body);
  font-size: var(--gc-fs-base);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;   /* no grey flash on tap */
  overscroll-behavior-y: none;
}

h1, h2, h3, h4 { margin: 0 0 0.4em; line-height: 1.2; font-weight: 700; }
h1 { font-family: var(--gc-font-display); font-size: var(--gc-fs-2xl); letter-spacing: -0.01em; }
h2 { font-family: var(--gc-font-display); font-size: var(--gc-fs-xl); letter-spacing: -0.005em; }
h3 { font-size: var(--gc-fs-lg); }
p  { margin: 0 0 0.75em; }
p:last-child { margin-bottom: 0; }

a { color: var(--gc-brass-deep); text-decoration-thickness: 1px; text-underline-offset: 2px; }
:root[data-theme="dark"] a { color: var(--gc-brass); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) a { color: var(--gc-brass); } }

button, input, select, textarea { font: inherit; color: inherit; }

/* Keyboard focus stays visible everywhere. */
:focus-visible {
  outline: 2px solid var(--gc-brass);
  outline-offset: 2px;
  border-radius: var(--gc-r-sm);
}

/* --- helpers --- */
.gc-row     { display: flex; align-items: center; gap: var(--gc-gap); flex-wrap: wrap; }
.gc-col     { display: flex; flex-direction: column; gap: var(--gc-gap); }
.gc-stack > * + * { margin-top: var(--gc-gap); }
.gc-spread  { display: flex; align-items: center; justify-content: space-between; gap: var(--gc-gap); }
.gc-grow    { flex: 1 1 auto; min-width: 0; }
.gc-muted   { color: var(--gc-muted); }
.gc-mono    { font-family: var(--gc-font-mono); font-variant-numeric: tabular-nums; }
.gc-display { font-family: var(--gc-font-display); }
.gc-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Signature divider: a fret wire, not a hairline. Nickel with a lit top edge. */
.gc-hairline {
  height: 2px;
  border: 0;
  margin: 22px 0;
  background: linear-gradient(180deg, var(--gc-line-strong) 0 1px, var(--gc-line) 1px 2px);
  border-radius: 2px;
}


/* ==========================================================================
   04  SHELL — app / header / nav / page / section / card
   ========================================================================== */

.gc-app {
  min-height: 100%;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--gc-bg);
}

/* --- header ------------------------------------------------------------- */
.gc-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px var(--gc-pad);
  padding-top: calc(12px + env(safe-area-inset-top));
  background: linear-gradient(135deg, var(--gc-header-a), var(--gc-header-b));
  color: var(--gc-header-ink);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), var(--gc-shadow);
}
.gc-header h1,
.gc-header .gc-header-title {
  font-family: var(--gc-font-display);
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  margin: 0;
  color: var(--gc-header-ink);
}
.gc-header small,
.gc-header .gc-header-sub {
  display: block;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gc-header-dim);
}
/* Brass string line under the header — the one bit of shine up top. */
.gc-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0, var(--gc-brass) 18%, var(--gc-brass-lit) 50%,
    var(--gc-brass) 82%, transparent 100%);
  opacity: 0.75;
}

/* --- pages -------------------------------------------------------------- */
.gc-page {
  display: none;
  flex: 1 1 auto;
  padding: var(--gc-pad);
  padding-bottom: calc(var(--gc-navh) + 28px + env(safe-area-inset-bottom));
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
}
.gc-page.active { display: block; }

.gc-section { margin: 0 0 26px; }
.gc-section:last-child { margin-bottom: 0; }
.gc-section > h2,
.gc-section > h3 { margin-bottom: 10px; }

/* Section eyebrow: small mono label above a heading. */
.gc-section > .gc-eyebrow {
  display: block;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gc-faint);
  margin-bottom: 4px;
}

/* --- cards -------------------------------------------------------------- */
.gc-card {
  background: var(--gc-card);
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  padding: var(--gc-pad);
  box-shadow: var(--gc-shadow);
}
.gc-card + .gc-card { margin-top: var(--gc-gap); }
.gc-card > h2:first-child,
.gc-card > h3:first-child { margin-top: 0; }

/* --- bottom tab bar ----------------------------------------------------- */
.gc-nav {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  align-items: stretch;
  justify-content: space-around;
  gap: 2px;
  padding: 4px 6px;
  padding-bottom: calc(4px + env(safe-area-inset-bottom));  /* clears the home indicator */
  background: var(--gc-card);                                /* fallback first */
  background: color-mix(in srgb, var(--gc-card) 92%, transparent);
  border-top: 1px solid var(--gc-line);
  box-shadow: 0 -6px 20px rgba(46, 29, 21, 0.08);
}
@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) {
  .gc-nav {
    -webkit-backdrop-filter: saturate(160%) blur(14px);
    backdrop-filter: saturate(160%) blur(14px);
  }
}

/* index.html ships <button class="gc-nav-btn"> — named explicitly so this
   doesn't rest on the element selector alone. */
.gc-nav button,
.gc-nav a,
.gc-nav-btn {
  flex: 1 1 0;
  min-width: 0;
  min-height: var(--gc-tap);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 6px 4px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--gc-muted);
  font-size: var(--gc-fs-xs);
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-nav button > span:first-child,
.gc-nav a > span:first-child { font-size: 1.25rem; line-height: 1; }

.gc-nav .active,
.gc-nav [aria-selected="true"],
.gc-nav [aria-current="page"] {
  color: var(--gc-brass-deep);
  background: var(--gc-brass-wash);
}
:root[data-theme="dark"] .gc-nav .active,
:root[data-theme="dark"] .gc-nav [aria-selected="true"],
:root[data-theme="dark"] .gc-nav [aria-current="page"] { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-nav .active,
  :root:not([data-theme="light"]) .gc-nav [aria-selected="true"],
  :root:not([data-theme="light"]) .gc-nav [aria-current="page"] { color: var(--gc-brass-lit); }
}


/* ==========================================================================
   05  BUTTONS
   ========================================================================== */

.gc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--gc-tap);
  padding: 11px 18px;
  border: 1px solid var(--gc-line-strong);
  border-radius: 10px;
  background: var(--gc-card);
  color: var(--gc-ink);
  font-size: var(--gc-fs-base);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.06s ease, background-color 0.15s ease, border-color 0.15s ease;
}
.gc-btn:active { transform: translateY(1px); }

.gc-btn.is-primary {
  background: linear-gradient(180deg, var(--gc-brass) 0%, var(--gc-brass-deep) 100%);
  border-color: var(--gc-brass-deep);
  color: #fffaf0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.28), var(--gc-shadow);
}
.gc-btn.is-primary:hover { filter: brightness(1.04); }

.gc-btn.is-ghost {
  background: transparent;
  border-color: var(--gc-line-strong);
  color: var(--gc-ink-soft);
}
.gc-btn.is-ghost:hover { background: var(--gc-card-2); }

.gc-btn.is-danger {
  background: transparent;
  border-color: var(--gc-bad);
  color: var(--gc-bad);
}
.gc-btn.is-danger:hover { background: var(--gc-bad-wash); }

.gc-btn:disabled,
.gc-btn[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
  filter: none;
  transform: none;
}

.gc-btn.gc-btn-block { display: flex; width: 100%; }
.gc-btn.gc-btn-big   { min-height: 58px; font-size: var(--gc-fs-lg); padding: 14px 22px; }


/* ==========================================================================
   06  FORM CONTROLS
   ========================================================================== */

.gc-input,
.gc-textarea,
.gc-select {
  width: 100%;
  min-height: var(--gc-tap);
  padding: 11px 13px;
  border: 1px solid var(--gc-line-strong);
  border-radius: 10px;
  background: var(--gc-card);
  color: var(--gc-ink);
  font-size: var(--gc-fs-base);   /* 16px+ keeps iOS from zooming on focus */
  -webkit-appearance: none;
  appearance: none;
}
.gc-input::placeholder,
.gc-textarea::placeholder { color: var(--gc-faint); }

.gc-input:focus,
.gc-textarea:focus,
.gc-select:focus {
  outline: none;
  border-color: var(--gc-brass);
  box-shadow: var(--gc-ring);
}

.gc-textarea { min-height: 120px; resize: vertical; line-height: 1.45; }

.gc-select {
  padding-right: 38px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gc-muted) 50%),
    linear-gradient(135deg, var(--gc-muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 13px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

.gc-input:disabled,
.gc-textarea:disabled,
.gc-select:disabled { opacity: 0.5; cursor: not-allowed; }


/* ==========================================================================
   07  BADGE / PILL / CAVEAT
   ========================================================================== */

.gc-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  color: var(--gc-muted);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.gc-badge.is-good { background: var(--gc-good-wash); color: var(--gc-good); }
.gc-badge.is-warn { background: var(--gc-warn-wash); color: var(--gc-warn); }
.gc-badge.is-bad  { background: var(--gc-bad-wash);  color: var(--gc-bad); }

/* Pill = a tappable filter/choice chip. Full tap height on purpose. */
.gc-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--gc-tap);
  padding: 8px 16px;
  border: 1px solid var(--gc-line-strong);
  border-radius: 999px;
  background: var(--gc-card);
  color: var(--gc-ink-soft);
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-pill.is-active,
.gc-pill[aria-pressed="true"] {
  background: var(--gc-brass-wash);
  border-color: var(--gc-brass);
  color: var(--gc-brass-deep);
}
:root[data-theme="dark"] .gc-pill.is-active,
:root[data-theme="dark"] .gc-pill[aria-pressed="true"] { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-pill.is-active,
  :root:not([data-theme="light"]) .gc-pill[aria-pressed="true"] { color: var(--gc-brass-lit); }
}

/* --- caveat -------------------------------------------------------------
   An honest heads-up, not an error. Amber, quiet, sits calmly in the page.
   Used for "this strumming pattern is our recommendation, not the artist's
   transcription" (contract §7.2). It should never read like a failure.      */
.gc-caveat {
  display: flex;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--gc-line);
  border-left: 3px solid var(--gc-warn);
  border-radius: var(--gc-r-sm);
  background: var(--gc-warn-wash);
  color: var(--gc-ink-soft);
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
}
.gc-caveat::before {
  content: "Heads up";
  flex: 0 0 auto;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gc-warn);
  padding-top: 1px;
}
/* If the markup supplies its own label, suppress ours. */
.gc-caveat[data-label="none"]::before { content: none; }
.gc-caveat strong { color: var(--gc-ink); }


/* ==========================================================================
   08  CHORD CARDS + CHORD ROW   (structure emitted by A2)
   .gc-chordcard        one diagram
   .gc-chordcard-title  the SHAPE name — big, display serif. This is what
                        Kevin fingers.
   .gc-chordcard-sub    "sounds like Db" — small mono grey, clearly secondary.
   .gc-chordrow         horizontal scroller with iOS momentum.
   ========================================================================== */

.gc-chordcard {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 132px;
  padding: 12px 12px 14px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: var(--gc-card);
  box-shadow: var(--gc-shadow);
  scroll-snap-align: start;
  text-align: center;
}
/* The svguitar host. Sits FIRST in the DOM; the caption is pulled above it
   with `order` below, so the shape name always reads first. */
.gc-chordcard-diagram {
  width: 100%;
  order: 0;
  margin-top: 2px;
  /* svguitar is built with fontFamily:'inherit' — this is what it inherits.
     Mono, because everything inside it is a number or a position marker. */
  font-family: var(--gc-font-mono);
}
.gc-chord-svg,
.gc-chordcard svg {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
}
/* svguitar draws near-black on transparent, which disappears on a dark
   background. The diagram is greyscale, so inverting it gives white strings
   and a white dot with a dark number inside — correct either way.
   Escape hatch: set data-color on the host if a coloured diagram is ever
   passed in, and this stops. */
:root[data-theme="dark"] .gc-chord-svg { filter: invert(1); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-chord-svg { filter: invert(1); }
}
.gc-chordcard-diagram[data-color] .gc-chord-svg { filter: none; }

.gc-chordcard-title {
  font-family: var(--gc-font-display);
  font-size: clamp(1.75rem, 8vw, 2.25rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--gc-ink);
  order: -1;                 /* the shape name reads first, always */
}

.gc-chordcard-sub {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.03em;
  color: var(--gc-faint);
  order: -1;                 /* sits directly under the title */
  max-width: 100%;
}

/* Scroller: momentum on iOS, scrollbar hidden, a fade + peek so Kevin can
   tell there's more to the right. */
.gc-chordrow {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  scroll-padding-left: var(--gc-pad);
  /* Bleed to the screen edges, then pad back in — the last card peeks. */
  margin: 0 calc(var(--gc-pad) * -1);
  padding: 4px var(--gc-pad) 10px;
  padding-right: calc(var(--gc-pad) + 14px);
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 34px), transparent 100%);
  mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 34px), transparent 100%);
}
.gc-chordrow::-webkit-scrollbar { display: none; width: 0; height: 0; }


/* ==========================================================================
   09  FRETBOARD   (built by chords.js -> createFretboard, ~line 1004)

   REAL GEOMETRY — VERTICAL, like every chord diagram ever printed.
   Verified against the source, not assumed:

     .gc-fb                  root. Holds the capo bar, the neck, the gutter.
       .gc-fb-capo           horizontal bar ACROSS the strings. Absolutely
                             positioned. Fret comes from --gc-fb-capo-fret
                             (integer, set inline by the JS).
         .gc-fb-capo-off     capo is 0 — hidden.
       .gc-fb-neck           flex row of six string columns.
         .gc-fb-string       ONE COLUMN PER STRING. :nth-of-type(1) is the
                             LOW E (the code builds low E first), so column 1
                             gets the thickest string. Each column holds:
           .gc-fb-label      the string name (E A D G B e)
           .gc-fb-mute       the ✕ toggle. .gc-fb-mute-on when muted.
           .gc-fb-dot        fret 0..5, stacked DOWNWARD, one button each.
             .gc-fb-dot-open fret 0 — sits ABOVE the nut, carries a ○ glyph.
             .gc-fb-dot-on   this fret is pressed.
       .gc-fb-frets          gutter to the right of the neck.
         .gc-fb-fretnum      one per row: "open", then absolute fret numbers.

   Rows line up because the geometry is fixed here, in one place. Change
   --gc-fb-row / --gc-fb-gap and the neck, the capo and the gutter all follow.

   The DOM has no fret-wire elements and no inlay elements, so both are
   painted as background layers on .gc-fb-neck.

   NOTE: the buttons carry data-string (0..5, low E = 0) and data-fret (0..5)
   for the JS. Styling keys off :nth-of-type and the state classes instead, so
   nothing here breaks if those attributes ever move.

   REMOVED from the first draft: .gc-fb-fret, .gc-fb-open and the
   .gc-fb-vertical modifier. None of them exist in the built DOM — fret wires
   are painted, the open marker is .gc-fb-dot-open, and vertical is now the
   only layout.
   ========================================================================== */

.gc-fb {
  /* --- geometry: the single source of truth for every row position --- */
  --gc-fb-gap:     4px;
  --gc-fb-row:     44px;   /* dot row height = the 44px tap target */
  --gc-fb-labelh:  18px;
  --gc-fb-muteh:   44px;
  --gc-fb-nutgap:  12px;   /* the air either side of the nut */
  --gc-fb-gutter:  42px;
  --gc-fb-pitch:   calc(var(--gc-fb-row) + var(--gc-fb-gap));
  /* everything above the fret rows: label + mute */
  --gc-fb-head:    calc(var(--gc-fb-labelh) + var(--gc-fb-muteh) + (var(--gc-fb-gap) * 2));
  --gc-fb-openbot: calc(var(--gc-fb-head) + var(--gc-fb-row));
  /* top of the fret-1 row = where the wood starts */
  --gc-fb-necktop: calc(var(--gc-fb-openbot) + var(--gc-fb-gap) + var(--gc-fb-nutgap));

  position: relative;
  display: flex;
  align-items: stretch;
  gap: var(--gc-fb-gap);
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

/* --- the neck ----------------------------------------------------------
   Wood, fret wires and inlays are all background layers, painted only from
   --gc-fb-necktop down. Above that line is open air (the head), where the
   label / mute / open-string row live on the page background.             */
.gc-fb-neck {
  position: relative;
  flex: 1 1 auto;
  display: flex;
  align-items: stretch;
  gap: var(--gc-fb-gap);
  min-width: 0;
  background-image:
    /* fret wire: one at the bottom of every fret row */
    repeating-linear-gradient(180deg,
      transparent 0 calc(var(--gc-fb-pitch) - 2px),
      var(--gc-wire) calc(var(--gc-fb-pitch) - 2px) var(--gc-fb-pitch)),
    /* the wood */
    linear-gradient(90deg, var(--gc-neck-hi), var(--gc-neck-lo) 45%, var(--gc-neck-hi));
  background-position:
    0 var(--gc-fb-necktop),
    0 var(--gc-fb-necktop);
  background-size:
    100% calc(100% - var(--gc-fb-necktop)),
    100% calc(100% - var(--gc-fb-necktop));
  background-repeat: repeat-y, no-repeat;
  border-radius: 0 0 8px 8px;
}

/* Wood grain + inner shading, over the wood only. */
.gc-fb-neck::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: var(--gc-fb-necktop);
  bottom: 0;
  pointer-events: none;
  border-radius: 0 0 8px 8px;
  background: repeating-linear-gradient(
    178deg,
    rgba(255, 235, 200, 0.05) 0 1px,
    transparent 1px 7px,
    rgba(0, 0, 0, 0.05) 7px 8px,
    transparent 8px 19px);
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.38),
    inset 0 -2px 6px rgba(0, 0, 0, 0.3);
  z-index: 1;
}

/* The nut — bone bar between the open row and fret 1. */
.gc-fb-neck::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--gc-fb-openbot) + 5px);
  height: 7px;
  border-radius: 2px;
  background: linear-gradient(180deg, #f3ead6, #c7bba0);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  z-index: 2;
}

/* Inlay dots at frets 3 and 5.
   ONLY when the capo is off. With a capo on, the rows are relative frets and
   the real 3rd/5th fret markers are somewhere else — a dot in the wrong place
   is worse than no dot, so it goes away. (.gc-fb-capo-off is the capo bar,
   which is the neck's previous sibling.) */
.gc-fb-capo-off + .gc-fb-neck {
  background-image:
    radial-gradient(circle, var(--gc-inlay) 0 45%, transparent 46%),
    radial-gradient(circle, var(--gc-inlay) 0 45%, transparent 46%),
    repeating-linear-gradient(180deg,
      transparent 0 calc(var(--gc-fb-pitch) - 2px),
      var(--gc-wire) calc(var(--gc-fb-pitch) - 2px) var(--gc-fb-pitch)),
    linear-gradient(90deg, var(--gc-neck-hi), var(--gc-neck-lo) 45%, var(--gc-neck-hi));
  background-position:
    50% calc(var(--gc-fb-necktop) + (var(--gc-fb-pitch) * 2) + (var(--gc-fb-row) / 2) - 7px),
    50% calc(var(--gc-fb-necktop) + (var(--gc-fb-pitch) * 4) + (var(--gc-fb-row) / 2) - 7px),
    0 var(--gc-fb-necktop),
    0 var(--gc-fb-necktop);
  background-size:
    14px 14px,
    14px 14px,
    100% calc(100% - var(--gc-fb-necktop)),
    100% calc(100% - var(--gc-fb-necktop));
  background-repeat: no-repeat, no-repeat, repeat-y, no-repeat;
}

/* --- one string column -------------------------------------------------- */
.gc-fb-string {
  position: relative;
  flex: 1 1 0;
  min-width: 40px;          /* keeps every button at a real tap size */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--gc-fb-gap);
}

/* The string itself: a line down the column, from the nut to the bottom.
   Low E is column 1 and thickest. */
.gc-fb-string::before {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(var(--gc-fb-openbot) + 5px);
  bottom: 0;
  width: var(--gc-sw, 2px);
  margin-left: calc(var(--gc-sw, 2px) / -2);
  border-radius: 2px;
  background: linear-gradient(90deg, var(--gc-string-hi), var(--gc-string) 55%, #8d8676);
  box-shadow: 1px 0 2px rgba(0, 0, 0, 0.5);
  z-index: 3;
  pointer-events: none;
}
.gc-fb-string:nth-of-type(1) { --gc-sw: 4.5px; }   /* low E */
.gc-fb-string:nth-of-type(2) { --gc-sw: 3.8px; }   /* A     */
.gc-fb-string:nth-of-type(3) { --gc-sw: 3.1px; }   /* D     */
.gc-fb-string:nth-of-type(4) { --gc-sw: 2.5px; }   /* G     */
.gc-fb-string:nth-of-type(5) { --gc-sw: 2px;   }   /* B     */
.gc-fb-string:nth-of-type(6) { --gc-sw: 1.5px; }   /* high e */
/* The bottom three are wound — faint winding texture. */
.gc-fb-string:nth-of-type(1)::before,
.gc-fb-string:nth-of-type(2)::before,
.gc-fb-string:nth-of-type(3)::before {
  background-image:
    repeating-linear-gradient(180deg, rgba(0, 0, 0, 0.24) 0 1px, transparent 1px 3px),
    linear-gradient(90deg, var(--gc-string-hi), var(--gc-string) 55%, #8d8676);
}

/* --- string name -------------------------------------------------------- */
.gc-fb-label {
  height: var(--gc-fb-labelh);
  line-height: var(--gc-fb-labelh);
  text-align: center;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--gc-muted);
}

/* --- buttons: shared reset ---------------------------------------------
   The JS sets min-width/min-height 40px inline. The column already
   guarantees the width, so we take the height up to a full 44px row.     */
.gc-fb-mute,
.gc-fb-dot {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0 !important;
  padding: 0;
  margin: 0;
  border: 0;
  background: transparent;
  font-family: var(--gc-font-mono);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.12s ease, background-color 0.12s ease;
}

/* --- mute toggle (above the nut, on page background) -------------------- */
.gc-fb-mute {
  height: var(--gc-fb-muteh);
  min-height: var(--gc-fb-muteh) !important;
  border-radius: 8px;
  color: var(--gc-faint);
  font-size: 1.1rem;
}
.gc-fb-mute:hover { color: var(--gc-muted); background: var(--gc-bg-sunk); }
.gc-fb-mute-on {
  color: var(--gc-bad);
  background: var(--gc-bad-wash);
}

/* --- fret dots ---------------------------------------------------------- */
.gc-fb-dot {
  height: var(--gc-fb-row);
  min-height: var(--gc-fb-row) !important;
  position: relative;
  z-index: 4;
  color: transparent;
  font-size: var(--gc-fs-sm);
}
/* The dot face. Faint until pressed, so the wood stays readable. */
.gc-fb-dot::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 28px;
  height: 28px;
  margin: -14px 0 0 -14px;
  border-radius: 50%;
  border: 2px dashed rgba(255, 250, 240, 0.22);
  background: rgba(255, 250, 240, 0.05);
  transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}
.gc-fb-dot:hover::before { border-color: rgba(255, 250, 240, 0.42); }

.gc-fb-dot-on::before {
  border: 2px solid rgba(255, 250, 240, 0.6);
  background: radial-gradient(circle at 35% 28%,
    var(--gc-brass-lit), var(--gc-brass) 60%, var(--gc-brass-deep));
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.4);
  transform: scale(1.06);
}

/* --- open-string row (fret 0) — above the nut, carries a ○ glyph -------- */
.gc-fb-dot-open {
  color: var(--gc-faint);
  font-size: 1.15rem;
  margin-bottom: var(--gc-fb-nutgap);   /* the air above the nut */
}
.gc-fb-dot-open::before { content: none; }   /* the glyph IS the marker */
.gc-fb-dot-open:hover { color: var(--gc-muted); }
.gc-fb-dot-open.gc-fb-dot-on {
  color: var(--gc-brass-deep);
  font-size: 1.3rem;
  text-shadow: 0 0 0 currentColor;
}
:root[data-theme="dark"] .gc-fb-dot-open.gc-fb-dot-on { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-fb-dot-open.gc-fb-dot-on { color: var(--gc-brass-lit); }
}

/* --- capo: a real bar clamped across the strings ------------------------
   Row position comes straight from --gc-fb-capo-fret (1..5), set inline by
   the JS. Fret 1 sits on the first row below the nut.                      */
.gc-fb-capo {
  position: absolute;
  left: 0;
  right: calc(var(--gc-fb-gutter) + var(--gc-fb-gap));
  top: calc(
    var(--gc-fb-necktop)
    + ((var(--gc-fb-capo-fret, 1) - 1) * var(--gc-fb-pitch))
    + (var(--gc-fb-row) / 2)
  );
  height: 15px;
  margin-top: -7.5px;
  border-radius: 7px;
  background: linear-gradient(180deg, #3a3a3a 0 3px, #1a1a1a 3px 100%);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.6),
    0 3px 8px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.2);
  z-index: 6;
  pointer-events: none;
  opacity: 1;
  transition: top 0.16s ease, opacity 0.16s ease;
}
/* Chrome screw head on the clamp. */
.gc-fb-capo::after {
  content: "";
  position: absolute;
  right: 7px;
  top: 50%;
  width: 9px;
  height: 9px;
  margin-top: -4.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f0ead8, #9a927f);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}
/* capo === 0: gone, but still animatable back in. */
.gc-fb-capo-off {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
}

/* --- fret-number gutter -------------------------------------------------
   Padded down by exactly the head height so every number lines up with its
   row, and the first one carries the same nut gap as .gc-fb-dot-open.      */
.gc-fb-frets {
  flex: 0 0 var(--gc-fb-gutter);
  display: flex;
  flex-direction: column;
  gap: var(--gc-fb-gap);
  padding-top: var(--gc-fb-head);
  text-align: center;
}
.gc-fb-fretnum {
  height: var(--gc-fb-row);
  line-height: var(--gc-fb-row);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-variant-numeric: tabular-nums;
  color: var(--gc-faint);
}
.gc-fb-fretnum:first-child {
  margin-bottom: var(--gc-fb-nutgap);
  font-size: 10px;
  letter-spacing: 0.04em;
}

/* Six 40px columns + gaps + gutter needs 306px, which overflows a 320px
   iPhone SE. Tighten the gutter and gaps rather than the tap targets. */
@media (max-width: 360px) {
  .gc-fb {
    --gc-fb-gap: 3px;
    --gc-fb-gutter: 32px;
  }
  .gc-fb-string { min-width: 36px; }
  .gc-fb-dot::before { width: 26px; height: 26px; margin: -13px 0 0 -13px; }
}

/* ==========================================================================
   10  STRUM PATTERN + COUNTING ROW
   .gc-strum        the row of tokens
   .gc-strum-token  one hit: .is-down ↓  .is-up ↑  .is-rest  .is-mute ✕
                    .is-active = the one sounding right now
   .gc-count        the out-loud counting row, .is-accent on stressed counts
   ========================================================================== */

.gc-strum {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 10px 2px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.gc-strum::-webkit-scrollbar { display: none; height: 0; }

.gc-strum-token {
  flex: 1 0 auto;
  min-width: 46px;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--gc-line);
  border-radius: 10px;
  background: var(--gc-card);
  color: var(--gc-ink-soft);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
  user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.09s linear, color 0.09s linear,
              border-color 0.09s linear, transform 0.09s ease;
}

.gc-strum-token.is-down { color: var(--gc-ink); }
.gc-strum-token.is-up   { color: var(--gc-muted); font-size: 1.4rem; }
.gc-strum-token.is-rest {
  color: var(--gc-faint);
  background: var(--gc-bg-sunk);
  border-style: dashed;
  font-size: 1.1rem;
}
.gc-strum-token.is-mute {
  color: var(--gc-rosewood);
  background: var(--gc-card-2);
  border-color: var(--gc-line-strong);
}
:root[data-theme="dark"] .gc-strum-token.is-mute { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-strum-token.is-mute { color: var(--gc-brass-lit); }
}

/* Active token: unmistakable at arm's length — filled brass, lifted, ringed. */
.gc-strum-token.is-active {
  background: linear-gradient(180deg, var(--gc-brass-lit), var(--gc-brass));
  border-color: var(--gc-brass-deep);
  color: #2b2013;
  transform: translateY(-4px) scale(1.06);
  box-shadow: 0 0 0 3px var(--gc-brass-wash), 0 6px 14px rgba(0, 0, 0, 0.22);
  animation: gc-pulse 0.42s ease-out;
}

@keyframes gc-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(169, 124, 30, 0.55), 0 6px 14px rgba(0, 0, 0, 0.22); }
  100% { box-shadow: 0 0 0 12px rgba(169, 124, 30, 0), 0 6px 14px rgba(0, 0, 0, 0.22); }
}

/* --- counting row ------------------------------------------------------- */
.gc-count {
  display: flex;
  gap: 6px;
  padding: 0 2px 8px;
  overflow-x: auto;
  scrollbar-width: none;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  color: var(--gc-faint);
  letter-spacing: 0.02em;
}
.gc-count::-webkit-scrollbar { display: none; height: 0; }
.gc-count > * {
  flex: 1 0 auto;
  min-width: 46px;
  text-align: center;
  text-transform: lowercase;
}
.gc-count .is-accent,
.gc-count > .is-accent {
  color: var(--gc-brass-deep);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
:root[data-theme="dark"] .gc-count .is-accent { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-count .is-accent { color: var(--gc-brass-lit); }
}


/* ==========================================================================
   11  PITCH: METER / READOUT / CENTS / RANGE
   ========================================================================== */

/* --- input level -------------------------------------------------------- */
.gc-meter {
  position: relative;
  width: 100%;
  height: 12px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  border: 1px solid var(--gc-line);
  overflow: hidden;
}
/* Two ways to drive it: set --gc-level (0..1) on .gc-meter, or size a child. */
.gc-meter::after {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: calc(var(--gc-level, 0) * 100%);
  background: linear-gradient(90deg, var(--gc-good), var(--gc-brass) 78%, var(--gc-bad));
  transition: width 0.07s linear;
}
.gc-meter > *:first-child {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gc-good), var(--gc-brass) 78%, var(--gc-bad));
  transition: width 0.07s linear;
}
.gc-meter.is-good::after { background: var(--gc-good); }
.gc-meter.is-warn::after { background: var(--gc-warn); }
.gc-meter.is-bad::after  { background: var(--gc-bad); }

/* --- big note readout --------------------------------------------------- */
.gc-pitch-readout {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 14px 10px;
  border-radius: var(--gc-r);
  background: var(--gc-card-2);
  border: 1px solid var(--gc-line);
  font-family: var(--gc-font-display);
  font-size: clamp(3rem, 20vw, 5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gc-ink);
  font-variant-numeric: tabular-nums;
}
/* The Hz line — mono, small, quiet. */
.gc-pitch-readout small,
.gc-pitch-readout .gc-hz {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--gc-faint);
}
.gc-pitch-readout.is-good { color: var(--gc-good); }
.gc-pitch-readout.is-warn { color: var(--gc-warn); }
.gc-pitch-readout.is-bad  { color: var(--gc-bad); }

/* --- sharp / flat needle ------------------------------------------------ */
.gc-cents {
  position: relative;
  width: 100%;
  height: 46px;
  border-radius: var(--gc-r-sm);
  background: var(--gc-bg-sunk);
  border: 1px solid var(--gc-line);
  overflow: hidden;
}
/* Tick marks across the strip. */
.gc-cents::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg,
      var(--gc-line-strong) 0 1px, transparent 1px 10%);
  opacity: 0.55;
}
/* The centre line ("in tune") is a REAL element in the markup —
   index.html:104 ships <div class="gc-cents-center">. It is styled in
   section 13.7. Nothing is drawn here, or the two would stack up. */

.gc-cents-needle {
  position: absolute;
  top: 2px;
  bottom: 2px;
  width: 5px;
  /* Drive with --gc-cents (-50 flat .. 0 in tune .. +50 sharp). */
  left: calc(50% + (var(--gc-cents, 0) * 1%));
  transform: translateX(-50%);
  border-radius: 3px;
  background: var(--gc-brass);
  box-shadow: 0 0 0 3px var(--gc-brass-wash), 0 2px 6px rgba(0, 0, 0, 0.25);
  transition: left 0.09s linear, background-color 0.15s linear;
}
.gc-cents.is-good .gc-cents-needle,
.gc-cents-needle.is-good { background: var(--gc-good); box-shadow: 0 0 0 4px var(--gc-good-wash); }
.gc-cents.is-warn .gc-cents-needle,
.gc-cents-needle.is-warn { background: var(--gc-warn); box-shadow: 0 0 0 3px var(--gc-warn-wash); }
.gc-cents.is-bad .gc-cents-needle,
.gc-cents-needle.is-bad  { background: var(--gc-bad);  box-shadow: 0 0 0 3px var(--gc-bad-wash); }

/* --- range strip --------------------------------------------------------
   A piano-ish keyboard band. Black-key stripes are painted in, so a plain
   empty .gc-range-viz still looks like a keyboard.
   Helpers (mine, optional): .gc-range-band = Kevin's measured range,
   .gc-range-mark = a single note marker, .gc-range-ref = a reference
   voice-type bracket.                                                       */
.gc-range-viz {
  position: relative;
  width: 100%;
  height: 62px;
  border-radius: var(--gc-r-sm);
  border: 1px solid var(--gc-line-strong);
  background:
    repeating-linear-gradient(90deg,
      transparent 0 3.9%,
      rgba(43, 37, 32, 0.75) 3.9% 5.4%,
      transparent 5.4% 7.1%),
    linear-gradient(180deg, #fffdf7, #ece5d5);
  overflow: hidden;
}
/* Dark: the "keys" go bone-grey so the strip still reads as a keyboard
   without glowing white in a dim room. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-range-viz {
    background:
      repeating-linear-gradient(90deg,
        transparent 0 3.9%,
        rgba(0, 0, 0, 0.8) 3.9% 5.4%,
        transparent 5.4% 7.1%),
      linear-gradient(180deg, #cfc5b1, #a89e8c);
  }
}
:root[data-theme="dark"] .gc-range-viz {
  background:
    repeating-linear-gradient(90deg,
      transparent 0 3.9%,
      rgba(0, 0, 0, 0.8) 3.9% 5.4%,
      transparent 5.4% 7.1%),
    linear-gradient(180deg, #cfc5b1, #a89e8c);
}

.gc-range-band {
  position: absolute;
  top: 0; bottom: 0;
  background: rgba(169, 124, 30, 0.38);
  border-left: 2px solid var(--gc-brass-deep);
  border-right: 2px solid var(--gc-brass-deep);
}
.gc-range-band.is-good { background: rgba(63, 125, 82, 0.32); border-color: var(--gc-good); }
.gc-range-band.is-warn { background: rgba(176, 106, 28, 0.32); border-color: var(--gc-warn); }
.gc-range-band.is-bad  { background: rgba(168, 56, 42, 0.30);  border-color: var(--gc-bad); }

.gc-range-mark {
  position: absolute;
  top: 0; bottom: 0;
  width: 3px;
  margin-left: -1.5px;
  background: var(--gc-rosewood);
}
.gc-range-ref {
  position: absolute;
  bottom: 3px;
  height: 16px;
  border: 1px solid var(--gc-muted);
  border-top: 0;
  border-radius: 0 0 4px 4px;
  font-family: var(--gc-font-mono);
  font-size: 10px;
  line-height: 14px;
  text-align: center;
  color: var(--gc-muted);
  background: rgba(255, 253, 247, 0.72);
  white-space: nowrap;
  overflow: hidden;
}

/* --- shared state colours ----------------------------------------------- */
.is-good { --gc-state: var(--gc-good); }
.is-warn { --gc-state: var(--gc-warn); }
.is-bad  { --gc-state: var(--gc-bad); }


/* ==========================================================================
   12  VOICE PAGE — measure flow, mic block, and the shared rows

   Verified against the real markup, not a description:
     index.html:90-96          the mic block + the #rangeSteps host
     main.js setStepCard()     :372-386   builds .gc-measure
     main.js setStepProgress() :388-393   writes .gc-measure-live text and
                                          .gc-progress-fill inline width
     main.js showMicDiagnostics() :396-430  .gc-factrow in the modal
     main.js buildTake()       :1287-1319  the playback rows

   .gc-progress-fill and .gc-meter-fill both get their WIDTH from inline
   style set by the JS. Nothing here sets width on either — only how they
   look. Same rule as the fretboard capo: JS owns position, CSS owns paint.
   ========================================================================== */

/* --- mic block (static markup, index.html:90) ---------------------------
   Extends section 11: .gc-meter and .gc-pitch-readout are defined there,
   these are the pieces that turn them into the live panel.               */
.gc-mic-block {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 16px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: var(--gc-card);
  box-shadow: var(--gc-shadow);
  text-align: center;
}

/* The level bar's fill. Width is inline, from P.getLevel() every 100ms. */
.gc-meter-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gc-good), var(--gc-brass) 78%, var(--gc-bad));
  transition: width 0.08s linear;
}

/* Inside the block the readout is the panel's centrepiece, so it drops its
   own box and lets .gc-mic-block be the card. */
.gc-mic-block .gc-pitch-readout {
  padding: 4px 0 0;
  border: 0;
  background: transparent;
}

/* Hz + cents, under the big note. Mono so the digits stop jittering. */
.gc-pitch-hz {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  color: var(--gc-faint);
  min-height: 1.4em;      /* holds its line so the panel never jumps */
}

/* --- the measure flow --------------------------------------------------- */
.gc-rangesteps { margin-top: var(--gc-gap); }
.gc-rangesteps:empty { display: none; }

.gc-measure {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px 18px;
  border: 1px solid var(--gc-brass);
  border-radius: var(--gc-r);
  background: var(--gc-card);
  box-shadow: var(--gc-shadow);
}
/* Buttons appended on failure (main.js:355, :366) shouldn't stretch full
   width in a column — keep them their own size, left aligned. */
.gc-measure > .gc-btn { align-self: flex-start; }

/* The instruction. He is holding a guitar and looking from arm's length,
   so this is the biggest thing on the screen. */
.gc-measure-title {
  font-family: var(--gc-font-display);
  font-size: clamp(1.5rem, 6.5vw, 2.1rem);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--gc-ink);
}

.gc-measure-copy {
  font-size: var(--gc-fs-base);
  line-height: 1.45;
  color: var(--gc-ink-soft);
  max-width: 46ch;
}

/* --- the progress bar --------------------------------------------------
   This is the thing that tells him it's hearing him. It is deliberately
   chunky — the failure copy says "hold it until the bar fills all the way
   up", so the bar has to be impossible to miss.                          */
.gc-progress {
  position: relative;
  width: 100%;
  height: 22px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  border: 1px solid var(--gc-line-strong);
  overflow: hidden;
  box-shadow: inset 0 2px 4px rgba(46, 29, 21, 0.14);
}
.gc-progress-fill {
  display: block;
  height: 100%;
  /* NO width here — main.js:381/:392 sets it inline. */
  min-width: 0;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gc-brass-lit), var(--gc-brass) 60%, var(--gc-brass-deep));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
  transition: width 0.22s ease-out;
}

/* --- the live status line ----------------------------------------------
   "I hear A2 — keep holding" lands here. The dot is what makes it read as
   live rather than as a caption that happens to be sitting there.        */
.gc-measure-live {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gc-brass-deep);
}
.gc-measure-live::before {
  content: "";
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
  animation: gc-live 1.2s ease-in-out infinite;
}
@keyframes gc-live {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(0.78); }
}
:root[data-theme="dark"] .gc-measure-live { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-measure-live { color: var(--gc-brass-lit); }
}

/* --- quiet positive -----------------------------------------------------
   "✓ Every shape here is an open chord. No barres." Good news, said once,
   without shouting. Deliberately lighter than .gc-caveat.                 */
.gc-good-note {
  display: flex;
  gap: 8px;
  padding: 8px 12px;
  border-left: 3px solid var(--gc-good);
  border-radius: 0 var(--gc-r-sm) var(--gc-r-sm) 0;
  background: var(--gc-good-wash);
  color: var(--gc-good);
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  line-height: 1.4;
}

/* --- fact rows (also used inside the diagnostics modal) ----------------- */
.gc-factrow {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  overflow: hidden;
  background: var(--gc-card);
}
.gc-fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 12px;
  font-size: var(--gc-fs-sm);
}
.gc-fact + .gc-fact { border-top: 1px solid var(--gc-line); }
.gc-fact:nth-child(even) { background: var(--gc-card-2); }
.gc-fact-lbl { color: var(--gc-muted); }
.gc-fact-val {
  font-family: var(--gc-font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--gc-ink);
  text-align: right;
}

/* --- recording takes ----------------------------------------------------
   buildTake() emits: label span, a native <audio controls>, a download
   link, and a Delete button. The audio element gets its own full-width
   line — at 375px it cannot share a row with two buttons.                */
.gc-takes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.gc-take {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  background: var(--gc-card-2);
}
.gc-take-lbl {
  flex: 1 1 100%;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  letter-spacing: 0.02em;
  color: var(--gc-muted);
}
.gc-take audio {
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;          /* Safari gives audio a wide intrinsic width */
  max-width: 100%;
  height: 40px;
  display: block;
}
.gc-take .gc-btn {
  flex: 0 1 auto;
  padding: 10px 14px;      /* min-height stays 44px — Delete is destructive */
  font-size: var(--gc-fs-sm);
}

/* --- modal (index.html:226) --------------------------------------------
   The diagnostics panel lives in here. Driven by the `hidden` attribute
   (main.js showModal sets m.hidden = false), so [hidden] must win.       */
.gc-modal {
  position: fixed;
  inset: 0;
  z-index: 70;                       /* above the nav (40) and toast (60) */
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 16px;
  background: rgba(28, 20, 15, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.gc-modal[hidden] { display: none; }

.gc-modal-box {
  position: relative;
  width: 100%;
  max-width: 560px;
  max-height: 86dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-lg) var(--gc-r-lg) 0 0;
  background: var(--gc-card);
  box-shadow: var(--gc-shadow-lg);
}
.gc-modal-box > h3:first-child { margin-top: 0; padding-right: 44px; }

.gc-modal-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: var(--gc-tap);
  height: var(--gc-tap);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gc-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-modal-close:hover { background: var(--gc-bg-sunk); color: var(--gc-ink); }

@media (min-width: 620px) {
  .gc-modal { align-items: center; }
  .gc-modal-box {
    border-radius: var(--gc-r-lg);
    padding-bottom: 20px;
  }
}

/* --- small print utility (main.js pairs it with .gc-muted, 18 times) ---- */
.gc-small {
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
}


/* ==========================================================================
   13  PAGE FURNITURE — home, songs, song detail, chords, learn

   Read from the source, not from a list:
     main.js bigCapo()            :852-863
     main.js renderSongList()     :573-599
     main.js renderSongDetail()   :628-843
     main.js buildStrumCard()     :916-1036
     main.js buildSectionsCard()  :1039-1081
     main.js renderHome()         :98-167
     main.js runIdentify()        :1383-1407
     main.js renderBeginnerChords() :1409-1427
     main.js renderLearn/tipItem()  :1432-1507
     index.html                   the static shell for all five pages

   Three things that are buttons and need the native chrome taken off, or
   iOS/Windows draw them as grey system buttons: .gc-songrow, .gc-tipsec-head,
   .gc-video-thumb.
   ========================================================================== */


/* --------------------------------------------------------------------------
   13.1  THE CAPO ANSWER — the most important output in the app

   bigCapo() emits .gc-bigcapo-word and .gc-bigcapo-num as adjacent inline
   spans with NO whitespace between them, which is why it read "Capo7". The
   gap on the flex row is the fix — never add a text space, the JS owns the
   text. "No capo" ships the word with no number, so the word carries the
   whole panel on its own: :only-child handles that case.
   -------------------------------------------------------------------------- */

.gc-bigcapo {
  display: block;
  margin: 4px 0 14px;
  padding: 18px 16px;
  border: 2px solid var(--gc-brass);
  border-radius: var(--gc-r);
  background: var(--gc-brass-wash);
  text-align: center;
}

.gc-bigcapo-capo {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 12px;                 /* the "Capo7" fix */
  flex-wrap: wrap;
}

.gc-bigcapo-word {
  font-family: var(--gc-font-display);
  font-size: clamp(1.15rem, 5vw, 1.6rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--gc-ink-soft);
}
/* "No capo" — no number follows, so the words carry the panel. */
.gc-bigcapo-word:only-child {
  font-size: clamp(2rem, 10vw, 3rem);
  font-weight: 700;
  color: var(--gc-brass-deep);
  letter-spacing: -0.02em;
}

/* The fret number he clamps to. Biggest type in the app, on purpose. */
.gc-bigcapo-num {
  font-family: var(--gc-font-display);
  font-size: clamp(3.5rem, 22vw, 6rem);
  font-weight: 700;
  line-height: 0.85;
  letter-spacing: -0.04em;
  color: var(--gc-brass-deep);
  font-variant-numeric: lining-nums;
}

.gc-bigcapo-chords {
  display: block;
  margin-top: 14px;
  padding-top: 12px;
  /* fret wire, same device as .gc-hairline */
  border-top: 2px solid var(--gc-brass);
  border-image: linear-gradient(90deg, transparent, var(--gc-brass) 25%, var(--gc-brass) 75%, transparent) 1;
}
.gc-bigcapo-lbl {
  display: block;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gc-muted);
  margin-bottom: 4px;
}
/* SHAPE names (contract §3) — display serif, like the diagram captions. */
.gc-bigcapo-names {
  display: block;
  font-family: var(--gc-font-display);
  font-size: clamp(1.35rem, 6.5vw, 2rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--gc-ink);
}

:root[data-theme="dark"] .gc-bigcapo-num,
:root[data-theme="dark"] .gc-bigcapo-word:only-child { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-bigcapo-num,
  :root:not([data-theme="light"]) .gc-bigcapo-word:only-child { color: var(--gc-brass-lit); }
}


/* --------------------------------------------------------------------------
   13.2  SONGS LIST — .gc-songrow is a <button>, so the native chrome has to
   come off completely or it renders as a grey OS button.
   -------------------------------------------------------------------------- */

.gc-songlist {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: var(--gc-gap);
}

.gc-songrow {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: var(--gc-tap);
  margin: 0;
  padding: 13px 14px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r);
  background: var(--gc-card);
  color: var(--gc-ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  box-shadow: var(--gc-shadow);
  transition: border-color 0.14s ease, transform 0.06s ease;
}
.gc-songrow:hover  { border-color: var(--gc-brass); }
.gc-songrow:active { transform: translateY(1px); }
/* A chevron so it reads as "this goes somewhere". */
.gc-songrow::after {
  content: "›";
  flex: 0 0 auto;
  margin-left: 2px;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--gc-faint);
}

.gc-songrow-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gc-songrow-title {
  font-family: var(--gc-font-display);
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--gc-ink);
}
.gc-songrow-sub {
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
}
.gc-songrow-tags {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 4px;
  max-width: 40%;
}

/* .gc-pill is a 44px tap target by default. In these four places it is a
   STATIC label, not something to press — shrink it back to a chip. */
.gc-songrow-tags .gc-pill,
.gc-section-head .gc-pill,
.gc-idalts .gc-pill,
.gc-tip-meta .gc-pill {
  min-height: 0;
  padding: 3px 10px;
  font-size: var(--gc-fs-xs);
  font-weight: 600;
  cursor: default;
}


/* --------------------------------------------------------------------------
   13.3  SONG DETAIL
   -------------------------------------------------------------------------- */

.gc-back { margin-bottom: var(--gc-gap); }

/* The answer card carries the capo panel — mark it as the important one. */
.gc-answer { border-color: var(--gc-line-strong); }

.gc-why {
  margin: 12px 0 0;
  padding: 11px 13px;
  border-radius: var(--gc-r-sm);
  background: var(--gc-card-2);
  font-size: var(--gc-fs-sm);
  line-height: 1.5;
  color: var(--gc-ink-soft);
}
.gc-why strong { color: var(--gc-ink); }

/* --- section-by-section map --- */
.gc-section-block {
  padding: 12px 0;
  border-bottom: 1px solid var(--gc-line);
}
.gc-section-block:last-child { border-bottom: 0; padding-bottom: 0; }

.gc-section-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}
.gc-section-label {
  font-family: var(--gc-font-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--gc-ink);
}

.gc-chordseq {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* Shape names again (contract §3) — mono and solid, so a chord sequence
   scans as a row of things to play rather than as prose. */
.gc-chordchip {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 5px 11px;
  border: 1px solid var(--gc-line-strong);
  border-radius: var(--gc-r-sm);
  background: var(--gc-card-2);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-base);
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--gc-ink);
}

/* --- chord flow: which strums belong to which chord (contract §12) ---
   One cell per chord, its own bar of strums directly underneath, arrows
   between. Reading left to right IS the chord change. Scrolls sideways
   inside its own box rather than pushing the page wide. */
.gc-chordflow-wrap { margin-bottom: 4px; }

.gc-chordflow {
  display: flex;
  align-items: stretch;
  gap: 6px;
  padding: 4px 2px 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.gc-chordflow::-webkit-scrollbar { display: none; height: 0; }

.gc-chordflow-cell {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 8px 10px;
  border: 1px solid var(--gc-line-strong);
  border-radius: var(--gc-r-sm);
  background: var(--gc-card-2);
}
/* Same treatment the chord chips had — mono and solid, so a chord reads as
   a thing to play rather than as prose. */
.gc-chordflow-chord {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-base);
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--gc-ink);
  line-height: 1;
}
.gc-chordflow-strum {
  display: flex;
  gap: 3px;
}
.gc-chordflow-strum .gc-strum-token {
  flex: 0 0 auto;
  min-width: 18px;
  min-height: 22px;
  border-radius: 5px;
  font-size: 0.78rem;
  font-weight: 700;
}
.gc-chordflow-strum .gc-strum-token.is-up { font-size: 0.68rem; }
.gc-chordflow-strum .gc-strum-token.is-rest { font-size: 0.58rem; }

.gc-chordflow-arrow {
  flex: 0 0 auto;
  align-self: center;
  color: var(--gc-faint);
  font-size: 1rem;
  line-height: 1;
  user-select: none;
}
.gc-chordflow-arrow.is-loop { color: var(--gc-brass); }

.gc-chordflow-hint {
  margin: 0 0 6px;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--gc-muted);
}

/* ==========================================================================
   CAMPFIRE MODE (contract §16)
   Phone propped up a few feet away, at night, guitar in hand. Everything
   here serves reading distance: no chrome, no nav, one scale knob driving
   every size, and generous line spacing so a chord line and its words stay
   visually paired even at 3x.
   z-index 80 — above the modal (70), nav (40) and toast (60), because this
   is a full takeover and nothing should ever float over it.
   ========================================================================== */
.gc-campfire {
  --gc-campfire-scale: 1.6;
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  flex-direction: column;
  background: var(--gc-bg);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* Stop the page underneath from scrolling behind the overlay. */
body.gc-campfire-open { overflow: hidden; }

.gc-campfire-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(10px + env(safe-area-inset-top, 0px)) 12px 10px;
  border-bottom: 1px solid var(--gc-line);
  background: var(--gc-card);
}
.gc-campfire-title {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--gc-font-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--gc-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gc-campfire-controls { flex: 0 0 auto; display: flex; gap: 6px; }
.gc-campfire-btn {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--gc-line-strong);
  border-radius: var(--gc-r-sm);
  background: var(--gc-bg-sunk);
  color: var(--gc-ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-campfire-btn.is-close { color: var(--gc-brass); }

/* The capo fret must be right before the first strum, so it never scrolls
   away — pinned under the bar for the whole song. */
.gc-campfire-capo {
  flex: 0 0 auto;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--gc-line);
  background: var(--gc-card-2);
}
.gc-campfire-capo-fret {
  font-family: var(--gc-font-display);
  font-size: calc(1rem * var(--gc-campfire-scale));
  font-weight: 700;
  color: var(--gc-brass);
  line-height: 1.1;
}
.gc-campfire-capo-chords {
  font-family: var(--gc-font-mono);
  font-size: calc(0.8rem * var(--gc-campfire-scale));
  font-weight: 700;
  color: var(--gc-ink);
  white-space: pre-wrap;
}

.gc-campfire-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 12px calc(28px + env(safe-area-inset-bottom, 0px));
}

/* The pasted sheet, scaled. Monospace + pre is non-negotiable here for the
   same reason as the card: the column alignment IS the information.
   SCOPED UNDER .gc-campfire on purpose — this element also carries .gc-lyrics,
   which sets a fixed 0.86rem at the SAME specificity and is defined later in
   this file, so an unscoped rule loses the cascade and the size buttons do
   nothing at all. Caught in a live browser 08/08/2026. */
.gc-campfire .gc-campfire-lyrics {
  border: 0;
  background: transparent;
  padding: 0;
  font-size: calc(0.86rem * var(--gc-campfire-scale));
  line-height: 1.6;
}
/* The same cascade trap, one level down: section headers inside that <pre>
   carry .gc-lyrics-section, which pins 0.95rem. Scaling the <pre> alone left
   "Verse 1" and "Chorus" fixed while the body text grew — at scale 3.2 the
   labels ended up ~3x SMALLER than the words, so the only structural cue on
   the screen vanished at exactly the distance the mode exists for. */
.gc-campfire .gc-campfire-lyrics .gc-lyrics-section {
  font-size: calc(0.95rem * var(--gc-campfire-scale));
}
.gc-campfire-hint {
  margin: 0 0 14px;
  font-size: calc(0.8rem * var(--gc-campfire-scale));
  color: var(--gc-muted);
  line-height: 1.5;
}
.gc-campfire-section { margin-bottom: 18px; }
.gc-campfire-section-label {
  font-family: var(--gc-font-display);
  font-size: calc(0.85rem * var(--gc-campfire-scale));
  font-weight: 700;
  color: var(--gc-muted);
  margin-bottom: 6px;
}
.gc-campfire-chords { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.gc-campfire-chord {
  font-family: var(--gc-font-mono);
  font-size: calc(1rem * var(--gc-campfire-scale));
  font-weight: 700;
  color: var(--gc-ink);
  line-height: 1.2;
}

.gc-campfire-launch { align-items: center; }

/* --- lyrics + chords, local only (contract §15) ---
   A chords-over-lyrics sheet only reads correctly in a MONOSPACE font with
   whitespace preserved — the alignment IS the information. Scrolls sideways
   inside its own box so a long line never widens the page. */
.gc-lyrics-card { display: flex; flex-direction: column; gap: 10px; }

.gc-lyrics {
  margin: 0;
  padding: 12px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  background: var(--gc-bg-sunk);
  font-family: var(--gc-font-mono);
  font-size: 0.86rem;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  tab-size: 4;
}
.gc-lyrics-chords {
  color: var(--gc-brass);
  font-weight: 700;
}
.gc-lyrics-words { color: var(--gc-ink); }
.gc-lyrics-section {
  color: var(--gc-ink);
  font-family: var(--gc-font-display);
  font-weight: 700;
  font-size: 0.95rem;
}
.gc-lyrics-blank { display: inline; }

/* --- song progress, 0-5 stars (contract §14) --- */
.gc-progress-card { display: flex; flex-direction: column; gap: 10px; }

.gc-stars {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}
.gc-stars-glyphs {
  font-size: 1.6rem;
  line-height: 1;
  letter-spacing: 0.06em;
  color: var(--gc-brass);
}
.gc-stars.is-gold .gc-stars-glyphs {
  color: var(--gc-brass-lit);
  text-shadow: 0 0 10px rgba(217, 168, 63, 0.45);
}
.gc-stars-label {
  font-family: var(--gc-font-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--gc-ink);
}
.gc-stars-blurb { margin: 0; }

.gc-progress-options { display: flex; flex-direction: column; gap: 6px; }

.gc-progress-opt {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 9px 11px;
  text-align: left;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  background: var(--gc-bg-sunk);
  color: var(--gc-ink);
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-progress-opt.is-current {
  border-color: var(--gc-brass);
  background: var(--gc-card-2);
  box-shadow: inset 0 0 0 1px var(--gc-brass);
}
.gc-progress-opt.is-goal .gc-progress-opt-label { color: var(--gc-brass); }
.gc-progress-opt-stars {
  flex: 0 0 auto;
  color: var(--gc-brass);
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  line-height: 1.4;
}
.gc-progress-opt-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.gc-progress-opt-label { font-weight: 700; font-size: 0.95rem; }
.gc-progress-opt-blurb { font-size: 0.82rem; color: var(--gc-muted); line-height: 1.4; }

/* stars on the song list row */
.gc-songrow-progress {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin-top: 3px;
}
.gc-songrow-stars {
  color: var(--gc-brass);
  font-size: 0.82rem;
  letter-spacing: 0.03em;
  line-height: 1;
}
.gc-songrow-progress.is-gold .gc-songrow-stars { color: var(--gc-brass-lit); }
.gc-songrow-stage { font-size: 0.78rem; color: var(--gc-muted); }

/* the campfire counter is the goal, so it reads warmer than its neighbours */
.gc-stat.is-goal .gc-stat-num { color: var(--gc-brass); }

/* --- per-section strum row (contract §12) ---
   Sits right under a section's chord row: a tiny read-only preview of that
   section's pattern (.gc-strum.is-mini reuses the real token classes at a
   fraction of the size) + a select to change it + a hint/reset. */
.gc-section-strum {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--gc-line);
}
.gc-strum.is-mini {
  padding: 0;
  gap: 3px;
  flex: 0 0 auto;
}
.gc-strum.is-mini .gc-strum-token {
  min-width: 20px;
  min-height: 24px;
  border-radius: 5px;
  font-size: 0.8rem;
  font-weight: 700;
}
.gc-strum.is-mini .gc-strum-token.is-up { font-size: 0.7rem; }
.gc-strum.is-mini .gc-strum-token.is-rest { font-size: 0.6rem; }
.gc-section-strum-select {
  min-height: 36px;
  padding: 4px 8px;
  font-size: 0.85rem;
}
.gc-section-strum .gc-muted.gc-small { margin: 0; }
.gc-section-strum-reset {
  min-height: 30px;
  padding: 4px 10px;
  font-size: 0.8rem;
}

/* --- song notes (contract §12) ---
   A small local rich-text-lite editor: plain lines, bullet/numbered lists
   via native contenteditable list behavior, and a hand-rolled checklist
   (no execCommand equivalent exists for checkboxes). */
.gc-notes-card { display: flex; flex-direction: column; gap: 10px; }
.gc-notes-toolbar { display: flex; gap: 8px; flex-wrap: wrap; }
.gc-notes-tool {
  min-height: 38px;
  padding: 6px 12px;
  font-size: 0.85rem;
}
.gc-notes-editor {
  min-height: 110px;
  padding: 14px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  background: var(--gc-bg-sunk);
  color: var(--gc-ink);
  font-size: 1rem;
  line-height: 1.55;
  outline: none;
  -webkit-user-select: text;
  user-select: text;
}
.gc-notes-editor:focus {
  border-color: var(--gc-brass);
  box-shadow: 0 0 0 3px rgba(217, 168, 63, 0.18);
}
.gc-notes-editor:empty::before {
  content: attr(data-placeholder);
  color: var(--gc-faint);
}
.gc-notes-editor ul, .gc-notes-editor ol {
  margin: 4px 0 4px 1.3em;
  padding: 0;
}
.gc-notes-editor li { margin: 2px 0; }

.gc-check-item {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 4px 0;
}
.gc-check-item input[type="checkbox"] {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--gc-brass);
  cursor: pointer;
}
.gc-check-item .gc-check-text {
  flex: 1 1 auto;
  min-width: 0;
  outline: none;
}
.gc-check-item.is-checked .gc-check-text {
  color: var(--gc-faint);
  text-decoration: line-through;
}

/* --- strumming --- */
.gc-pattern-name {
  margin: 6px 0 2px;
  font-family: var(--gc-font-display);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--gc-ink);
}

.gc-bpmrow { align-items: center; }
.gc-bpmval {
  font-family: var(--gc-font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: var(--gc-fs-sm);
  color: var(--gc-brass-deep);
  min-width: 7ch;            /* stops the row jittering as the number changes */
  text-align: right;
}
:root[data-theme="dark"] .gc-bpmval { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-bpmval { color: var(--gc-brass-lit); }
}

/* Tempo slider. Native range inputs are unusable on iOS without this. */
.gc-range {
  -webkit-appearance: none;
  appearance: none;
  flex: 1 1 120px;
  min-width: 120px;
  height: var(--gc-tap);       /* full-height tap strip; the track is drawn */
  margin: 0;
  padding: 0;
  background: transparent;
  touch-action: manipulation;
}
.gc-range::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  border: 1px solid var(--gc-line-strong);
}
.gc-range::-moz-range-track {
  height: 8px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  border: 1px solid var(--gc-line-strong);
}
.gc-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 28px;
  height: 28px;
  margin-top: -11px;           /* centres the thumb on the 8px track */
  border-radius: 50%;
  border: 2px solid var(--gc-brass-deep);
  background: radial-gradient(circle at 35% 30%, var(--gc-brass-lit), var(--gc-brass) 65%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.gc-range::-moz-range-thumb {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--gc-brass-deep);
  background: var(--gc-brass);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.gc-range:focus-visible::-webkit-slider-thumb { box-shadow: var(--gc-ring); }

/* --- recorder status --- */
.gc-rec-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  color: var(--gc-muted);
}
.gc-rec-status::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--gc-line-strong);
}
.gc-rec-status.is-live { color: var(--gc-bad); }
.gc-rec-status.is-live::before {
  background: var(--gc-bad);
  animation: gc-rec 1.1s ease-in-out infinite;
}
@keyframes gc-rec {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.3; transform: scale(0.75); }
}

/* --- notes + sources --- */
.gc-note {
  margin: 0 0 8px;
  color: var(--gc-ink-soft);
  line-height: 1.5;
}
.gc-sources {
  margin: 4px 0 10px;
  padding-left: 18px;
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
}
.gc-sources li { margin-bottom: 3px; overflow-wrap: anywhere; }  /* long URLs */

/* --- video thumbnails (tap to load the iframe) --- */
.gc-video-thumb {
  -webkit-appearance: none;
  appearance: none;
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 16px;
  border: 0;
  border-radius: inherit;
  background: linear-gradient(160deg, var(--gc-rosewood), var(--gc-walnut));
  color: #f7f0e2;
  font: inherit;
  text-align: center;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.gc-video-play {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--gc-brass);
  color: #2b2013;
  font-size: 1.35rem;
  line-height: 1;
  padding-left: 4px;          /* optically centres the ▶ glyph */
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);
}
.gc-video-title {
  font-weight: 700;
  font-size: var(--gc-fs-sm);
  line-height: 1.25;
}
.gc-video-chan {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  color: var(--gc-header-dim);
}


/* --------------------------------------------------------------------------
   13.4  HOME
   -------------------------------------------------------------------------- */

.gc-hero {
  background: linear-gradient(165deg, var(--gc-card), var(--gc-brass-wash));
  border-color: var(--gc-line-strong);
}
.gc-hero h2 {
  font-size: clamp(1.5rem, 7vw, 2rem);
}

.gc-lead {
  font-size: 1.1rem;
  line-height: 1.5;
  color: var(--gc-ink-soft);
  max-width: 54ch;
}

/* The three steps ARE a sequence — do them in order — so the numbering
   carries real information rather than decoration. */
.gc-steps {
  counter-reset: gcstep;
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}
.gc-step {
  counter-increment: gcstep;
  display: grid;
  grid-template-columns: 32px 1fr auto;
  grid-template-areas:
    "num title go"
    "num desc  go";
  align-items: center;
  gap: 2px 12px;
  padding: 12px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-step:first-child { border-top: 0; }
.gc-step::before {
  content: counter(gcstep);
  grid-area: num;
  align-self: start;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1.5px solid var(--gc-line-strong);
  background: var(--gc-card);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  font-weight: 700;
  color: var(--gc-muted);
}
.gc-step.is-done::before {
  content: "✓";
  border-color: var(--gc-good);
  background: var(--gc-good-wash);
  color: var(--gc-good);
}
.gc-step-title {
  grid-area: title;
  font-weight: 700;
  color: var(--gc-ink);
}
.gc-step.is-done .gc-step-title { color: var(--gc-muted); }
.gc-step-desc {
  grid-area: desc;
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
}
.gc-step-go { grid-area: go; align-self: center; }

/* --- practice stats --- */
.gc-statrow {
  display: flex;
  gap: var(--gc-gap);
  margin-bottom: var(--gc-gap);
}
.gc-stat {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 12px 8px;
  border: 1px solid var(--gc-line);
  border-radius: var(--gc-r-sm);
  background: var(--gc-card-2);
}
.gc-stat-num {
  font-family: var(--gc-font-display);
  font-size: clamp(1.8rem, 9vw, 2.4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gc-brass-deep);
  font-variant-numeric: tabular-nums lining-nums;
}
.gc-stat-lbl {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gc-muted);
  text-align: center;
}
:root[data-theme="dark"] .gc-stat-num { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-stat-num { color: var(--gc-brass-lit); }
}

/* --- today's 15 minutes --- */
.gc-plan {
  list-style: none;
  margin: 0;
  padding: 0;
}
.gc-planitem {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "min what"
    "min detail";
  gap: 2px 12px;
  padding: 10px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-planitem:first-child { border-top: 0; }
.gc-plan-min {
  grid-area: min;
  align-self: start;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--gc-brass-wash);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  color: var(--gc-brass-deep);
  white-space: nowrap;
}
.gc-plan-what   { grid-area: what; font-weight: 600; color: var(--gc-ink); }
.gc-plan-detail { grid-area: detail; font-size: var(--gc-fs-sm); color: var(--gc-muted); }

.gc-about { color: var(--gc-muted); font-size: var(--gc-fs-sm); }
.gc-about h2, .gc-about h3 { color: var(--gc-ink); }

.gc-rangetext { font-size: 1.1rem; line-height: 1.45; color: var(--gc-ink); }

/* A finished-successfully card (range saved, sheet parsed). */
.gc-result { border-color: var(--gc-good); }
.gc-result > h3:first-child { color: var(--gc-good); }

.gc-reqrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--gc-line);
  font-size: var(--gc-fs-sm);
}
.gc-reqrow:last-child { border-bottom: 0; }
.gc-reqrow .gc-btn { min-height: 36px; padding: 6px 12px; }


/* --------------------------------------------------------------------------
   13.5  CHORDS PAGE
   -------------------------------------------------------------------------- */

.gc-idresult {
  padding: 14px;
  border: 1px solid var(--gc-line-strong);
  border-radius: var(--gc-r);
  background: var(--gc-card-2);
  text-align: center;
}
.gc-idresult.is-good { border-color: var(--gc-good); background: var(--gc-good-wash); }
.gc-idresult.is-warn { border-color: var(--gc-warn); background: var(--gc-warn-wash); }

.gc-idname {
  font-family: var(--gc-font-display);
  font-size: clamp(2.2rem, 12vw, 3.2rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--gc-ink);
}
.gc-idsub {
  margin-top: 4px;
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
}
.gc-idresult.is-good .gc-idsub { color: var(--gc-good); }
.gc-idresult.is-warn .gc-idsub { color: var(--gc-warn); }

.gc-idalts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.gc-capo-row { align-items: center; }

/* --- the beginner chord list --- */
.gc-beginner {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-beginner:first-child { border-top: 0; }
.gc-beginner > .gc-chordcard {
  flex: 0 0 auto;
  min-width: 118px;
  max-width: 40%;
}
.gc-beginner-text { flex: 1 1 auto; min-width: 0; }
.gc-beginner-order {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gc-brass-deep);
  margin-bottom: 4px;
}
.gc-beginner-why {
  margin: 0 0 6px;
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
  color: var(--gc-ink-soft);
}
.gc-beginner-tip {
  margin: 0;
  padding: 7px 10px;
  border-left: 3px solid var(--gc-brass);
  border-radius: 0 var(--gc-r-sm) var(--gc-r-sm) 0;
  background: var(--gc-brass-wash);
  font-size: var(--gc-fs-sm);
  line-height: 1.4;
  color: var(--gc-ink-soft);
}
:root[data-theme="dark"] .gc-beginner-order { color: var(--gc-brass-lit); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .gc-beginner-order { color: var(--gc-brass-lit); }
}


/* --------------------------------------------------------------------------
   13.6  LEARN
   -------------------------------------------------------------------------- */

.gc-tipsec { padding-bottom: 8px; }

/* Accordion header — a <button>, so the native chrome comes off. */
.gc-tipsec-head {
  -webkit-appearance: none;
  appearance: none;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--gc-tap);
  margin: 0;
  padding: 8px 0;
  border: 0;
  background: transparent;
  color: var(--gc-ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
/* Chevron. Rotates when the section is open. */
.gc-tipsec-head::after {
  content: "›";
  margin-left: auto;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--gc-faint);
  transform: rotate(90deg);
  transition: transform 0.18s ease;
}
.gc-tipsec-head.is-open::after { transform: rotate(-90deg); }

.gc-tipsec-icon { font-size: 1.25rem; line-height: 1; }
.gc-tipsec-title {
  font-family: var(--gc-font-display);
  font-size: 1.15rem;
  font-weight: 700;
}
.gc-tipsec-count {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--gc-bg-sunk);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  color: var(--gc-muted);
}
/* JS toggles style.display inline — don't fight it, just space the contents. */
.gc-tipsec-body > .gc-tip:first-child { margin-top: 6px; }

.gc-tip {
  padding: 12px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-tip-title {
  font-weight: 700;
  color: var(--gc-ink);
  margin-bottom: 3px;
}
.gc-tip-body {
  margin: 0 0 6px;
  font-size: var(--gc-fs-sm);
  line-height: 1.5;
  color: var(--gc-ink-soft);
}
.gc-tip-why {
  margin: 0;
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
  color: var(--gc-muted);
  border-left: 2px solid var(--gc-line-strong);
  padding-left: 10px;
}
.gc-tip-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

/* --- first week --- */
.gc-day {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "num what"
    "num detail";
  gap: 2px 12px;
  padding: 11px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-day:first-child { border-top: 0; }
.gc-day-num {
  grid-area: num;
  align-self: start;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--gc-brass-wash);
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-xs);
  font-weight: 700;
  color: var(--gc-brass-deep);
  white-space: nowrap;
}
.gc-day-what { grid-area: what; font-weight: 600; color: var(--gc-ink); }
.gc-day-detail {
  grid-area: detail;
  margin: 0;
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
  color: var(--gc-muted);
}

/* --- glossary --- */
.gc-gloss {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px 14px;
  padding: 9px 0;
  border-top: 1px solid var(--gc-line);
}
.gc-gloss:first-child { border-top: 0; }
.gc-gloss-term {
  font-family: var(--gc-font-mono);
  font-weight: 700;
  color: var(--gc-ink);
}
.gc-gloss-plain {
  font-size: var(--gc-fs-sm);
  line-height: 1.45;
  color: var(--gc-muted);
}
@media (min-width: 520px) {
  .gc-gloss { grid-template-columns: 12rem 1fr; align-items: baseline; }
}


/* --------------------------------------------------------------------------
   13.7  SHELL BITS THAT WERE MISSING
   -------------------------------------------------------------------------- */

/* index.html wraps every .gc-page in <main class="gc-main"> — the desktop
   grid in section 16 targets this, NOT .gc-page (which is a grandchild). */
.gc-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.gc-header-inner {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.gc-btnrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: var(--gc-gap);
}
.gc-label {
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  color: var(--gc-muted);
}

/* --- tuner (index.html:100-130) --- */
.gc-tuner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
}
.gc-tuner-string {
  font-family: var(--gc-font-display);
  font-size: clamp(2.5rem, 15vw, 4rem);
  font-weight: 700;
  line-height: 1;
  color: var(--gc-ink);
}
.gc-tuner-hint {
  font-family: var(--gc-font-mono);
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
  text-align: center;
}
/* The real centre-line element. .gc-cents draws its own via ::after only when
   this element is absent — see section 11. */
.gc-cents-center {
  position: absolute;
  left: 50%;
  top: 4px;
  bottom: 4px;
  width: 2px;
  margin-left: -1px;
  border-radius: 2px;
  background: var(--gc-good);
  opacity: 0.85;
  pointer-events: none;
}


/* ==========================================================================
   14  VIDEO EMBEDS — 16:9, never overflows a phone
   ========================================================================== */

.gc-video-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gc-gap);
}

.gc-video {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--gc-r);
  overflow: hidden;
  background: var(--gc-walnut);
  border: 1px solid var(--gc-line);
}
/* Fallback for engines without aspect-ratio. */
@supports not (aspect-ratio: 16 / 9) {
  .gc-video { height: 0; padding-bottom: 56.25%; }
}
.gc-video iframe,
.gc-video video,
.gc-video img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  object-fit: cover;
}
.gc-video figcaption,
.gc-video + .gc-video-caption {
  font-size: var(--gc-fs-sm);
  color: var(--gc-muted);
}

@media (min-width: 620px) {
  .gc-video-grid { grid-template-columns: repeat(2, 1fr); }
}


/* ==========================================================================
   15  EMPTY / SPINNER / TOAST
   ========================================================================== */

.gc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 34px 20px;
  border: 1px dashed var(--gc-line-strong);
  border-radius: var(--gc-r);
  background: var(--gc-card-2);
  color: var(--gc-muted);
  text-align: center;
}
.gc-empty strong {
  font-family: var(--gc-font-display);
  font-size: var(--gc-fs-lg);
  font-weight: 700;
  color: var(--gc-ink);
}
.gc-empty p { font-size: var(--gc-fs-sm); max-width: 34ch; }

.gc-spinner {
  display: inline-block;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 3px solid var(--gc-line-strong);
  border-top-color: var(--gc-brass);
  animation: gc-spin 0.75s linear infinite;
  vertical-align: middle;
}
@keyframes gc-spin { to { transform: rotate(360deg); } }

/* main.js toast() shows this by ADDING .is-show and hides it by removing the
   class (main.js:40-46) — so the resting state has to be invisible, or the
   bubble sits on screen forever. Not display:none: it still needs to be able
   to fade. */
.gc-toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--gc-navh) + 16px + env(safe-area-inset-bottom));
  z-index: 60;
  max-width: min(92vw, 460px);
  padding: 12px 16px;
  border-radius: 999px;
  background: var(--gc-walnut);
  color: #f7f0e2;
  font-size: var(--gc-fs-sm);
  font-weight: 600;
  text-align: center;
  box-shadow: var(--gc-shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, 12px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s linear 0.2s;
}
.gc-toast.is-show {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s;
}
.gc-toast.is-good { background: var(--gc-good); color: #fff; }
.gc-toast.is-warn { background: var(--gc-warn); color: #fff; }
.gc-toast.is-bad  { background: var(--gc-bad);  color: #fff; }
.gc-toast[hidden] { display: none; }


/* ==========================================================================
   16  STAGE MODE — phone on a stand, a few feet away, guitar in hands.
       Chrome drops away, chord names go huge. Apply .gc-stage to the app
       root or to a single page; both work.
   ========================================================================== */

.gc-stage,
.gc-app.gc-stage { background: var(--gc-bg); }

.gc-stage .gc-nav,
.gc-app.gc-stage .gc-nav { display: none; }

.gc-stage .gc-header,
.gc-app.gc-stage .gc-header {
  padding-top: calc(6px + env(safe-area-inset-top));
  padding-bottom: 6px;
}
.gc-stage .gc-header small,
.gc-stage .gc-header .gc-header-sub { display: none; }

.gc-stage .gc-page,
.gc-app.gc-stage .gc-page {
  padding: 10px;
  padding-bottom: calc(24px + env(safe-area-inset-bottom));
  max-width: 100%;
}

.gc-stage .gc-card {
  border: 0;
  background: transparent;
  box-shadow: none;
  padding: 6px 0;
}

.gc-stage .gc-chordcard {
  border: 0;
  background: transparent;
  box-shadow: none;
  min-width: 44vw;
  padding: 6px;
}
.gc-stage .gc-chordcard-title {
  font-size: clamp(3rem, 15vw, 6rem);
  letter-spacing: -0.03em;
}
.gc-stage .gc-chordcard-sub {
  font-size: var(--gc-fs-sm);
  letter-spacing: 0.05em;
}

.gc-stage .gc-strum-token {
  min-width: 62px;
  min-height: 78px;
  font-size: 2.4rem;
  border-radius: 14px;
}
.gc-stage .gc-strum-token.is-up { font-size: 2.1rem; }
.gc-stage .gc-count { font-size: var(--gc-fs-base); }
.gc-stage .gc-count > * { min-width: 62px; }

/* Bigger rows and a wider neck when the phone is on a stand. The geometry
   vars do all the work — nothing else needs to move. */
.gc-stage .gc-fb {
  --gc-fb-row: 56px;
  --gc-fb-muteh: 52px;
  --gc-fb-gutter: 48px;
  --gc-fb-nutgap: 16px;
  max-width: 100%;
}
.gc-stage .gc-fb-dot::before { width: 36px; height: 36px; margin: -18px 0 0 -18px; }
.gc-stage .gc-fb-dot-open { font-size: 1.45rem; }
.gc-stage .gc-fb-fretnum { font-size: var(--gc-fs-base); }

/* Anything explicitly marked as chrome disappears on stage. */
.gc-stage [data-stage-hide],
.gc-stage .gc-stage-hide { display: none !important; }


/* ==========================================================================
   17  DESKTOP — side rail instead of a bottom bar
   ========================================================================== */

@media (min-width: 900px) {
  :root { --gc-pad: 24px; }

  .gc-app {
    display: grid;
    grid-template-columns: 232px 1fr;
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "header header"
      "nav    main";
    min-height: 100dvh;
  }
  .gc-header { grid-area: header; }

  .gc-nav {
    grid-area: nav;
    position: sticky;
    top: 74px;
    align-self: start;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    height: auto;
    max-height: calc(100dvh - 74px);
    overflow-y: auto;
    padding: 16px 12px;
    border-top: 0;
    border-right: 1px solid var(--gc-line);
    background: transparent;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .gc-nav button,
  .gc-nav a {
    flex: 0 0 auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 10px;
    width: 100%;
    padding: 10px 14px;
    font-size: var(--gc-fs-sm);
    text-align: left;
  }
  .gc-nav button > span:first-child,
  .gc-nav a > span:first-child { font-size: 1.1rem; }

  /* The grid child is <main class="gc-main"> (index.html:25), NOT .gc-page —
     the pages are grandchildren, so giving THEM the grid area put them
     outside the layout entirely. */
  .gc-main { grid-area: main; min-width: 0; }

  .gc-page {
    padding-bottom: 48px;
    max-width: 860px;
    margin: 0;
  }
  .gc-page.active { display: block; }

  .gc-toast { bottom: 24px; }

  /* Stage mode on a laptop: full width, no rail. */
  .gc-stage.gc-app,
  .gc-app.gc-stage {
    grid-template-columns: 1fr;
    grid-template-areas: "header" "main";
  }
  .gc-stage .gc-page { max-width: 100%; }
}


/* ==========================================================================
   18  REDUCED MOTION — honour the OS setting. States stay readable without
       any animation; only the movement goes away.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  /* The spinner still needs to say "working" — slow it right down. */
  .gc-spinner {
    animation: gc-spin 1.6s linear infinite !important;
    animation-duration: 1.6s !important;
  }
  /* Active strum token keeps the colour, ring and lift. Just no pulse. */
  .gc-strum-token.is-active {
    animation: none !important;
    transform: none;
    box-shadow: 0 0 0 4px var(--gc-brass-wash);
    outline: 2px solid var(--gc-brass-deep);
  }
  /* Pressed fret keeps its brass fill and ring — it just stops growing. */
  .gc-fb-dot-on::before { transform: none; }
}


/* ==========================================================================
   19  PRINT — a chord chart for the music stand.
       Black on white, no nav, no buttons, diagrams intact.
   ========================================================================== */

@media print {
  :root {
    --gc-bg: #fff;
    --gc-card: #fff;
    --gc-card-2: #fff;
    --gc-bg-sunk: #fff;
    --gc-ink: #000;
    --gc-ink-soft: #000;
    --gc-muted: #444;
    --gc-faint: #555;
    --gc-line: #999;
    --gc-line-strong: #666;
  }

  body { background: #fff; color: #000; font-size: 12pt; }

  .gc-nav,
  .gc-btn,
  .gc-toast,
  .gc-spinner,
  .gc-meter,
  .gc-cents,
  .gc-pitch-readout,
  .gc-video,
  .gc-video-grid,
  .gc-pill,
  .gc-input,
  .gc-textarea,
  .gc-select,
  .gc-range,
  .gc-bpmrow,
  .gc-btnrow,
  .gc-rec-status,
  .gc-takes,
  .gc-statrow,
  .gc-modal,
  .gc-mic-block,
  .gc-progress,
  .gc-measure-live,
  .gc-header::after { display: none !important; }

  .gc-header {
    position: static;
    background: none !important;
    color: #000;
    padding: 0 0 8pt;
    border-bottom: 1pt solid #000;
    box-shadow: none;
  }
  .gc-header h1,
  .gc-header .gc-header-title { color: #000; }

  .gc-app { display: block; }

  /* Print every page, not just the active one — he may print the song sheet
     while sitting on the tuner tab. */
  .gc-page {
    display: block !important;
    max-width: 100%;
    padding: 0;
    margin: 0;
  }

  .gc-card {
    border: 1pt solid #999;
    box-shadow: none;
    break-inside: avoid;
    page-break-inside: avoid;
    padding: 8pt;
  }

  .gc-section { break-inside: avoid; page-break-inside: avoid; }

  /* Chord cards: wrap onto the page instead of scrolling off it. */
  .gc-chordrow {
    display: flex;
    flex-wrap: wrap;
    overflow: visible;
    margin: 0;
    padding: 0;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .gc-chordcard {
    border: 1pt solid #999;
    box-shadow: none;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .gc-chordcard-title { color: #000; }
  .gc-chordcard-sub   { color: #444; }

  /* Fretboard prints as a clean line drawing, not a slab of dark wood.
     Geometry is unchanged — only the ink is. */
  .gc-fb {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .gc-fb-neck {
    background-image:
      repeating-linear-gradient(180deg,
        transparent 0 calc(var(--gc-fb-pitch) - 1px),
        #000 calc(var(--gc-fb-pitch) - 1px) var(--gc-fb-pitch)),
      none !important;
    background-color: #fff;
    border: 0.75pt solid #000;
    border-top: 0;
    box-shadow: none;
  }
  .gc-fb-neck::before { display: none; }          /* grain + inner shadow */
  .gc-fb-neck::after  { background: #000 !important; box-shadow: none; }  /* nut */

  .gc-fb-string::before {
    background: #000 !important;
    background-image: none !important;
    box-shadow: none;
  }
  .gc-fb-dot::before {
    background: #fff !important;
    border: 1pt solid #666;
    box-shadow: none;
    transform: none;
  }
  .gc-fb-dot-on::before {
    background: #000 !important;
    border-color: #000;
  }
  .gc-fb-dot-open { color: #000 !important; }
  .gc-fb-mute { color: #999 !important; background: none !important; }
  .gc-fb-mute-on { color: #000 !important; }
  .gc-fb-label,
  .gc-fb-fretnum { color: #000 !important; text-shadow: none; }
  .gc-fb-capo {
    background: #000 !important;
    box-shadow: none;
  }
  .gc-fb-capo::after { background: #fff !important; box-shadow: none; }

  /* Strum + counting stay readable in black and white. */
  .gc-strum, .gc-count { overflow: visible; flex-wrap: wrap; }
  .gc-strum-token {
    border: 1pt solid #666;
    background: #fff !important;
    color: #000 !important;
    animation: none !important;
    transform: none !important;
    box-shadow: none !important;
  }
  .gc-strum-token.is-active { outline: 2pt solid #000; }
  .gc-count .is-accent { color: #000; }

  /* The capo answer is the reason he prints anything. Keep it big and black
     — it has to be readable on a stand from a few feet away. */
  .gc-bigcapo {
    border: 2pt solid #000;
    background: #fff;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .gc-bigcapo-word,
  .gc-bigcapo-num,
  .gc-bigcapo-names,
  .gc-bigcapo-word:only-child { color: #000 !important; }
  .gc-bigcapo-chords { border-top: 1pt solid #000; border-image: none; }
  .gc-bigcapo-lbl { color: #444 !important; }

  .gc-chordchip {
    border: 1pt solid #666;
    background: #fff;
    color: #000;
  }
  .gc-section-block { break-inside: avoid; page-break-inside: avoid; }
  .gc-section-label, .gc-pattern-name, .gc-songrow-title { color: #000; }
  .gc-songrow { border: 1pt solid #999; box-shadow: none; background: #fff; }
  .gc-songrow::after { content: none; }
  .gc-tipsec-head::after { content: none; }
  .gc-tipsec-body { display: block !important; }   /* print the whole guide */

  .gc-caveat {
    background: #fff;
    border: 1pt solid #666;
    border-left: 3pt solid #000;
    color: #000;
  }
  .gc-badge { border: 0.75pt solid #666; background: #fff; color: #000; }

  a { color: #000; text-decoration: underline; }
  .gc-empty { display: none; }

  /* The dark-mode invert must never reach paper — a printer set to dark mode
     would otherwise hand him a white-on-white diagram. */
  .gc-chord-svg { filter: none !important; }

  /* Keep the ink swaps the browser would otherwise strip. */
  .gc-fb-neck,
  .gc-fb-neck::after,
  .gc-fb-string::before,
  .gc-fb-dot::before,
  .gc-fb-capo {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}
