/* Self-hosted fonts. A runtime fonts.googleapis.com request is render-blocking
   and on Indonesian mobile is the biggest delay before first paint.
   Generated by scripts/fetch_fonts.py (56 KB total, Latin subset).

   NOTE: Google splits each family into unicode-range chunks. Only the `latin`
   chunk contains full lowercase — `latin-ext` is a supplement without a-z, so
   taking it yields a font with no lowercase letters.
   `→` and `✓` are NOT in these files; render them as inline SVG. */
@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/GeistMono-300.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/GeistMono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/fonts/GeistMono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("/fonts/Geist-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("/fonts/Geist-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist";
  src: url("/fonts/Geist-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

/* chordbatak.com — v4 "instrument"
   Reference system: Vercel (from the popular-web-designs skill).

   Why this replaced the x.ai direction: x.ai is sharp-cornered brutalism, and
   the user asked for ROUNDED, simple, modern. Vercel supplies a real radius
   scale (6px buttons / 8px cards / 12px featured / pill for badges only) and a
   shadow-as-border technique (0 0 0 1px spread) instead of boxy frames.

   Why v3 "Buku Lagu" was dropped: cream paper + ink + one red accent +
   uppercase mono micro-labels is the exact house style an LLM produces when
   asked for "anti-AI-slop design" — anti-slop slop.

   Type: Geist Sans for UI and prose, Geist Mono for chords and lyrics.
   Monospace is STRUCTURAL here, not decorative — a chord must sit above the
   word it belongs to, so the chart needs fixed-width alignment.

   Colour: near-achromatic grays. One accent (--chord) survives on chord names
   only, because chords must read as distinct from lyrics at a glance; weight
   and opacity alone were not enough.

   Dark is default. Light is warm near-white (#faf9f7) so the inversion is not
   clinical.

   `→` and `✓` are NOT in the Latin subset — render them as inline SVG. */

:root {
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-pill: 9999px;

  /* shadow-as-border: Vercel replaces CSS borders with a 1px spread shadow so
     corners stay clean and transitions are smooth */
  --ring: 0 0 0 1px rgba(0, 0, 0, .08);
  --ring-hi: 0 0 0 1px rgba(0, 0, 0, .20);
  --lift: 0 0 0 1px rgba(0, 0, 0, .08), 0 2px 2px rgba(0, 0, 0, .04);

  --paper: #faf9f7;        /* warm near-white, not clinical #fff */
  --ink: #171717;
  --chord: #c2410c;        /* functional: chord names only */
  --ink-70: #4d4d4d;
  --ink-50: #666666;
  --ink-30: #808080;
  --ink-12: #ebebeb;
  --surface: #fafafa;
  --green: #1a7f4b;
  --amber: #8a5a00;

  --sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --pad: 24px;
  --maxw: 1180px;
}

[data-theme="dark"] {
  --ring: 0 0 0 1px rgba(255, 255, 255, .10);
  --ring-hi: 0 0 0 1px rgba(255, 255, 255, .22);
  --lift: 0 0 0 1px rgba(255, 255, 255, .10), 0 2px 2px rgba(0, 0, 0, .30);

  --paper: #111112;
  --ink: #ededed;
  --chord: #ff8a5c;
  --ink-70: #a1a1a1;
  --ink-50: #8f8f8f;
  --ink-30: #6b6b6b;
  --ink-12: #26262a;
  --surface: #1a1a1c;
  --green: #6fd39b;
  --amber: #e0b155;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; background: var(--paper); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; transition: opacity .12s; }
/* Inverted from convention: hover dims to 50% opacity rather than
   brightening or turning accent-colour. */
a:hover { color: var(--ink); opacity: .5; }
img, svg { max-width: 100%; }

/* ---------------------------------------------------------------- type */
/* Reference forbids 700: display weight is 300-400 only. Monospace carries the
   identity, so tracking is normal at small sizes and slightly loose at display
   sizes rather than the -0.02em of the old serif headings. */
/* Vercel's compression: negative tracking that relaxes as size drops, and
   weight 600 for headings. The old values (400 / normal tracking) came from the
   monospace system and read flat and mechanical. */
h1, h2, h3, h4 {
  font-family: var(--sans);
  font-weight: 600;
  letter-spacing: -.022em;
  line-height: 1.12;
  margin: 0;
}
h1 { font-size: 40px; letter-spacing: -.028em; }
h2 { font-size: 24px; letter-spacing: -.02em; }
h3 { font-size: 16px; letter-spacing: -.012em; font-weight: 500; }
h4 { font-size: 14px; letter-spacing: -.008em; font-weight: 500; }

/* Body stays proportional — monospace is for display and the chart, never for
   paragraphs, which would be unreadable. */
p, li, dd, dt, .lede, .side-hint, .detail-rows, .colophon p {
  font-family: var(--sans);
}
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/* Uppercase + wide letter-spacing + accent colour was the single strongest
   AI-slop signal in v3. A section label is now just small mono at 50% ink —
   the label is understood from position, not from screaming. */
.kicker {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-50);
  margin: 0 0 8px;
}
.mono {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--ink-70);
}
.lede {
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-70);
  max-width: 56ch;
}

/* ---------------------------------------------------------------- frame */
.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--pad);
}
.rule { border: 0; border-top: 1px solid var(--ink); margin: 0; }
.rule-2 { border: 0; border-top: 2px solid var(--ink); margin: 0; }
.hair { border: 0; border-top: 1px solid var(--ink-12); margin: 0; }

/* ---------------------------------------------------------------- masthead */
.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--paper);
  border-bottom: 1px solid var(--ink);
}

.masthead .bar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 13px 0;
  min-width: 0;
}
.brand {
  font-family: var(--mono);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
  white-space: nowrap;
  flex: 0 0 auto;
}
.brand b { color: var(--chord); }

.nav {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
  flex: 1;
}
.nav a {
  font-size: 14px;
  color: var(--ink-70);
  white-space: nowrap;
  padding-bottom: 2px;
  border-bottom: 1px solid transparent;
}
.nav a:hover { color: var(--ink); }
.nav a.is-active { color: var(--ink); border-bottom-color: var(--chord); }

.head-tools { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; }
.head-search {
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--ink-50);
  min-width: 0;
  width: 180px;
}
.head-search input {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  padding: 4px 0;
  width: 100%;
  min-width: 0;
}
.head-search input::placeholder { color: var(--ink-50); }
.head-search input:focus { outline: 0; }
.head-search button {
  border: 0;
  background: transparent;
  color: var(--ink-50);
  font-family: var(--mono);
  font-size: 12px;
  cursor: pointer;
  padding: 0 0 0 6px;
}
.head-search button:hover { color: var(--chord); }

/* Theme toggle is an icon: the moon shows in dark mode (switch to light), the
   sun shows in light mode (switch to dark). Both are in the DOM and CSS picks
   one from data-theme, so there is no icon swap in JS and no layout shift. */
.theme-toggle {
  border: 0;
  background: transparent;
  color: var(--ink-70);
  cursor: pointer;
  padding: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  border-radius: 0;
}
.theme-toggle:hover { color: var(--chord); }
.theme-toggle .ico-sun,
.theme-toggle .ico-moon { display: none; }
[data-theme="dark"] .theme-toggle .ico-sun { display: inline-flex; }
[data-theme="light"] .theme-toggle .ico-moon { display: inline-flex; }

.menu-toggle { display: none; }

/* mobile sheet */
.sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, .45);
  opacity: 0;
  transition: opacity .18s;
}
.sheet-scrim.show { opacity: 1; }
.sheet {
  position: fixed;
  z-index: 70;
  top: 0; left: 0; bottom: 0;
  width: min(80vw, 300px);
  background: var(--paper);
  border-right: 1px solid var(--ink);
  padding: 18px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-100%);
  transition: transform .2s ease;
  overflow-y: auto;
}
.sheet.show { transform: translateX(0); }
.sheet .sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-70);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--ink);
  margin-bottom: 6px;
}
.sheet .sheet-head button {
  border: 0; background: transparent; color: var(--ink-70);
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  cursor: pointer; text-transform: uppercase;
}
.sheet-search {
  display: flex;
  align-items: stretch;
  border-radius: var(--r-md);
  box-shadow: var(--ring);
  overflow: hidden;
  margin: 14px 0 4px;
  background: var(--paper);
}
.sheet-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  padding: 10px 12px;
  min-height: 42px;
}
.sheet-search input::placeholder { color: var(--ink-50); }
.sheet-search input:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--chord); }
.sheet-search button {
  border: 0;
  border-left: 1px solid var(--ink-12);
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  padding: 0 16px;
  min-height: 42px;
  cursor: pointer;
}
.sheet-search button:hover { color: var(--chord); }

.sheet a {
  display: block;
  /* 12px top + 12px bottom + 16px line = ~40px. The measured box was 14px
     because padding collapsed against the flex row; min-height guarantees the
     touch target regardless of the font's line box. */
  padding: 12px 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--ink-12);
  font-size: 16px;
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: -.01em;
}
.sheet a.is-active { color: var(--chord); }
body.nav-open { overflow: hidden; }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-sm);
  box-shadow: var(--ring);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  padding: 8px 16px;
  min-height: 36px;
  cursor: pointer;
  transition: box-shadow .15s, background .15s;
}
.btn:hover { box-shadow: var(--ring-hi); }
.btn-red { background: var(--ink); color: var(--paper); box-shadow: none; }
.btn-red:hover { opacity: .88; box-shadow: none; }
.btn.is-on { background: var(--ink); color: var(--paper); box-shadow: none; }

.seg {
  display: inline-flex;
  align-items: center;
  border-radius: var(--r-sm);
  box-shadow: var(--ring);
  overflow: hidden;
}
.seg > * {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  /* 24px minimum touch target; the container is rounded, the children must be
     tappable, not 15px slivers */
  min-height: 34px;
  min-width: 34px;
  padding: 7px 12px;
  cursor: pointer;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.seg > * + * { border-left: 1px solid var(--ink-12); }
.seg button:hover { color: var(--chord); }
/* autoscroll speed: a slider labelled in words */
.ctl-scroll { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.speed { display: inline-flex; align-items: center; gap: 8px; }
.speed input[type="range"] {
  width: 92px;
  height: 24px;
  accent-color: var(--chord);
}
.speed-val {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-70);
  white-space: nowrap;
  min-width: 74px;
}
@media (max-width: 600px) {
  .ctl-scroll { width: 100%; }
}
.seg .val {
  min-width: 46px;
  text-align: center;
  color: var(--chord);
  font-weight: 600;
  cursor: default;
}
.seg .lbl {
  color: var(--ink-70);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .1em;
  cursor: default;
}

/* ---------------------------------------------------------------- hero */
.hero { padding: 64px 0 48px; }
.hero h1 { max-width: 20ch; margin-bottom: 20px; }
.hero .lede { margin-bottom: 28px; }

.search-lg {
  display: flex;
  align-items: stretch;
  border: 0;
  border-radius: var(--r-md);
  box-shadow: var(--ring);
  overflow: hidden;
  max-width: 620px;
  min-width: 0;
  background: var(--paper);
}
.search-lg input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  padding: 13px 16px;
}
.search-lg input::placeholder { color: var(--ink-50); }
.search-lg input:focus { outline: 0; }
.search-lg button {
  border: 0;
  border-left: 1px solid var(--hair-hi);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 0 22px;
  cursor: pointer;
  flex: 0 0 auto;
  /* stretch, not baseline: the button must be exactly as tall as the field */
  align-self: stretch;
  display: flex;
  align-items: center;
}
.search-lg button:hover { opacity: .85; }

.try {
  margin-top: 16px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-70);
  letter-spacing: .02em;
}
.try a { color: var(--chord); border-bottom: 1px solid var(--chord); }
.try a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ---------------------------------------------------------------- sections */
.section { padding: 44px 0; }
.section + .section { border-top: 1px solid var(--ink-12); }
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;          /* a long label must not push past a 320px screen */
  padding-bottom: 12px;
  border-bottom: 1px solid var(--ink-12);
  margin-bottom: 4px;
}
.section-head h2 { font-size: 24px; }
.section-head .meta-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-70);
  white-space: nowrap;
}
@media (max-width: 600px) {
  .section-head .meta-label { white-space: normal; }
}
.section-foot { padding-top: 16px; font-family: var(--sans); font-size: 12px; }
.section-foot a { color: var(--chord); border-bottom: 1px solid var(--chord); }
.section-foot a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* ---------------------------------------------------------------- chart list */
.chart { list-style: none; margin: 0; padding: 0; }
.chart li {
  display: grid;
  grid-template-columns: 34px 58px minmax(0, 1fr) 46px 92px;
  align-items: baseline;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 1px solid var(--ink-12);
}
/* Columns exist only when they carry data — an empty column of em-dashes reads
   as broken, so the grid is rebuilt without it. */
.chart.no-move li { grid-template-columns: 34px minmax(0, 1fr) 46px 92px; }
.chart.no-views li { grid-template-columns: 34px 58px minmax(0, 1fr) 46px; }
.chart.no-move.no-views li { grid-template-columns: 34px minmax(0, 1fr) 46px; }
.chart li:last-child { border-bottom: 0; }
.chart .rank {
  font-variant-numeric: tabular-nums;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-50);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.chart li:nth-child(-n+3) .rank { color: var(--chord); }
.chart .move {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-50);
  letter-spacing: .02em;
  white-space: nowrap;
}
.chart .move.up { color: var(--chord); }
.chart .move.down { color: var(--ink-70); }
.chart .song { min-width: 0; }
.chart .song a {
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chart .song .by {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-70);
  letter-spacing: .02em;
}
.chart .key {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--chord);
  font-weight: 600;
  text-align: center;
}
.chart .views {
  font-variant-numeric: tabular-nums;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-70);
  text-align: right;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- pick card */
.pick {
  border: 0;
  border-radius: var(--r-lg);
  box-shadow: var(--lift);
  padding: 28px 30px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 200px;
  gap: 32px;
  align-items: start;
}
.pick h3 { font-size: 34px; margin-bottom: 10px; }
.pick .facts {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--ink-70);
  margin-bottom: 16px;
}
.pick .facts b { color: var(--chord); font-weight: 600; }
.pick p { font-size: 15px; color: var(--ink-70); }
.pick .link-red {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--chord);
  border-bottom: 1px solid var(--chord);
  display: inline-block;
  margin-top: 16px;
}
.pick .link-red:hover { color: var(--ink); border-bottom-color: var(--ink); }
.pick .side {
  border-left: 1px solid var(--ink-12);
  border-radius: 0 var(--r-lg) var(--r-lg) 0;
  padding-left: 24px;
  font-family: var(--sans);
  font-size: 11px;
  color: var(--ink-70);
  letter-spacing: .02em;
}
.pick .side dt { text-transform: uppercase; letter-spacing: .12em; color: var(--ink-50); margin-bottom: 2px; }
.pick .side dd { margin: 0 0 14px; color: var(--ink); font-size: 13px; }

/* ---------------------------------------------------------------- index lists */
.index-cols {
  columns: 3;
  column-gap: 40px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.index-cols li {
  break-inside: avoid;
  padding: 7px 0;
  border-bottom: 1px solid var(--ink-12);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.index-cols a { font-size: 14px; }
.index-cols .n { font-family: var(--sans); font-size: 11px; color: var(--ink-50); }

.genre-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  font-family: var(--sans);
  font-size: 13px;
  padding: 0;
  margin: 0;
  list-style: none;
}
.genre-list a { color: var(--chord); border-bottom: 1px solid var(--chord); }
.genre-list a:hover { color: var(--ink); border-bottom-color: var(--ink); }
.genre-list .n { color: var(--ink-50); font-size: 11px; }

/* ---------------------------------------------------------------- chord page */
.crumb {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--ink-70);
  padding: 18px 0 0;
}
.crumb a { color: var(--ink-70); }
.crumb /* Inverted from convention: hover dims to 50% opacity rather than
   brightening or turning accent-colour. */
a:hover { color: var(--ink); opacity: .5; }
.crumb .sep { color: var(--ink-50); padding: 0 6px; }

.song-head { padding: 22px 0 26px; }
.song-head h1 { font-size: 40px; margin-bottom: 8px; }
.song-head .artist {
  font-family: var(--sans);
  font-size: 22px;
  font-weight: 700;
  color: var(--chord);
  letter-spacing: -.01em;
  /* inline-block so the tap target respects the full line box (was 23px tall) */
  display: inline-block;
  padding: 2px 0;
}
.song-head .artist:hover { text-decoration: underline; }

/* A single visible focus style for every interactive element. Previously only
   .chord-btn had one, so keyboard users lost their place on every other
   control. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--chord);
  outline-offset: 2px;
}
.song-head .facts {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-70);
  margin-top: 12px;
  letter-spacing: .02em;
}
.song-head .facts b { color: var(--chord); font-weight: 600; }
.song-head .facts .dot { color: var(--ink-50); padding: 0 8px; }

.controls {
  position: sticky;
  top: 96px;
  z-index: 30;
  background: var(--paper);
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--ink-12);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px 18px;
  padding: 12px 0;
}
.controls .spacer { flex: 1; }
.controls .ctl-label {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink-50);
  display: block;
  margin-bottom: 3px;
}

.song-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 52px;
  align-items: start;
  padding: 34px 0 56px;
}
.song-main { min-width: 0; }
/* Hand-written prose. Only present on rewritten songs, so it must not reserve
   space or look like part of the chart. Sits below the chords: the reader came
   for those, and this is a bonus rather than the point. */
.song-note {
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--ink-12);
  max-width: 62ch;
}
.song-note h2 {
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-70);
  margin-bottom: 12px;
}
.song-note p {
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
  margin: 0 0 12px;
}
.song-note ul { margin: 0 0 12px; padding-left: 20px; }
.song-note li { font-size: 15px; line-height: 1.6; margin-bottom: 6px; }
.song-note h2 + h2 { margin-top: 18px; }
.song-note a { color: var(--chord); }
.song-note strong { color: var(--ink); font-weight: 600; }
.song-side { position: sticky; top: 176px; }

/* ---------------------------------------------------------------- lyrics
   Songbook format: the chord sits ABOVE the word it is played on. Each lyric
   line is a run of .seg boxes; the chord cell is stacked over the text cell, so
   the chord stays locked to its word when the line wraps or the font resizes. */
.lyrics {
  font-variant-numeric: tabular-nums;
  font-family: var(--mono);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
}
.lyric-block { margin-bottom: 26px; }
.lyric-block:last-child { margin-bottom: 0; }

.section-label {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-50);
  margin: 0 0 10px;
  padding-top: 2px;
}
.section-label.red { color: var(--chord); }

.lyric-line {
  margin: 0 0 2px;
  font-family: var(--mono);
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink);
  min-width: 0;
}
/* .ly is a LYRIC SEGMENT. It must not share a class with .seg (the segmented
   control), or every lyric chunk inherits that control's 1px border and the
   whole chart renders as a row of boxes. */
.lyric-line .ly {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  vertical-align: bottom;
  min-width: 0;
}
.lyric-line .ch {
  height: 1.4em;
  display: flex;
  align-items: flex-end;
  gap: .35em;
  padding-bottom: 1px;
}
.lyric-line .tx { white-space: pre-wrap; word-break: break-word; }
/* A chord+lyric pair should read as one unit: the space AFTER a line is larger
   than the space inside it. */
.lyrics > .lyric-line + .chord-row { margin-top: 14px; }
.lyrics > .chord-row + .lyric-line { margin-top: 0; }
.chord-row + .chord-row { margin-top: -4px; }

.chord-btn {
  border: 0;
  background: transparent;
  padding: 0;
  margin: 0;
  font-family: var(--mono);
  font-size: .82em;
  font-weight: 600;
  color: var(--chord);
  cursor: pointer;
  line-height: 1;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  /* Hit area, not visual size. A chord name renders ~7x13px on mobile, far
     below the 24px touch minimum — the primary interaction on the page was
     hard to tap. Padding would shift the glyph out of alignment with the word
     it belongs to, so the target is grown with a transparent overlay that
     extends past the box without affecting layout at all. */
  position: relative;
}
.chord-btn::before {
  content: "";
  position: absolute;
  /* Vertical reach is safe (2px between lyric lines, 21px chord cell), and gets
     the target to ~37px tall.
     Horizontal: adjacent chords can be as close as 5px apart, so 2px each side
     is the most that will not bridge the gap and cause mis-taps on the
     neighbour. That leaves the effective width at 18px for a single-letter
     chord — under 24px, but widening further would make the wrong chord
     easier to hit than the right one. Multi-letter chords (Am, F#m) clear 24px
     on their own. */
  left: -2px;
  right: -2px;
  top: -8px;
  bottom: -8px;
}
.chord-btn:hover { border-bottom-color: var(--chord); }
.chord-btn:focus-visible { outline: 1px solid var(--chord); outline-offset: 2px; }

.chord-row { display: flex; flex-wrap: wrap; gap: 10px; padding: 2px 0 10px; }

/* ---------------------------------------------------------------- sidebar */
.side-block {
  border: 0;
  border-radius: var(--r-md);
  background: var(--surface);
  padding: 16px 18px;
  margin-bottom: 12px;
}
.side-block:first-child { margin-top: 0; }
.side-block h3 {
  font-family: var(--sans);
  font-size: 12px;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-50);
  font-weight: 400;
  margin: 0 0 12px;
}
/* Sidebar chords have room to spare, so they get real padding rather than an
   overlay — a 24px-tall box that is visibly a button. */
.side-chords {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}
.side-chords .chord-btn {
  font-size: 16px;
  min-height: 32px;
  min-width: 32px;
  padding: 6px 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.side-hint { font-size: 13px; color: var(--ink-70); line-height: 1.55; }

.detail-rows { margin: 0; }
.detail-rows div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--ink-12);
  font-family: var(--mono);
  font-size: 12px;
}
.detail-rows div:last-child { border-bottom: 0; }
.detail-rows dt {
  color: var(--ink-50);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: 10px;
  padding-top: 2px;
}
.detail-rows dd {
  margin: 0;
  color: var(--ink);
  text-align: right;
  min-width: 0;
  padding-left: 10px;
  overflow-wrap: anywhere;
}

.side-actions { display: flex; flex-direction: column; gap: 8px; }

/* ---------------------------------------------------------------- modal */
.modal-scrim {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(20, 16, 11, .55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.modal-scrim.show { display: flex; }
.modal {
  background: var(--paper);
  border: 0;
  border-radius: var(--r-lg);
  box-shadow: var(--lift), 0 12px 32px rgba(0, 0, 0, .18);
  padding: 26px 28px 22px;
  width: 100%;
  max-width: 340px;
  position: relative;
}
.modal .close {
  position: absolute;
  top: 10px; right: 12px;
  border: 0; background: transparent;
  font-family: var(--mono); font-size: 18px;
  color: var(--ink-70); cursor: pointer; line-height: 1;
}
.modal .close:hover { color: var(--chord); }
.modal .m-kicker {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--ink-50);
  margin-bottom: 6px;
}
.modal .m-name {
  font-family: var(--mono);
  font-size: 40px;
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--chord);
  line-height: 1;
  margin-bottom: 18px;
}
.modal svg { display: block; width: 100%; height: auto; }
.modal .m-formula {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-70);
  letter-spacing: .06em;
  margin-top: 12px;
  text-align: center;
}
.modal .m-note {
  font-family: var(--mono);
  font-size: 10px;
  color: var(--ink-50);
  letter-spacing: .06em;
  text-align: center;
  margin-top: 4px;
}

/* ---------------------------------------------------------------- search page */
.page-head { padding: 44px 0 28px; }
.page-head h1 { font-size: 40px; margin-bottom: 12px; }

.search-grid {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 48px;
  align-items: start;
  padding: 30px 0 60px;
}
.filter-rail { position: sticky; top: 110px; }
.filter-group { margin-bottom: 26px; }
.filter-group .filter-label, .recent h2 {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--ink-50);
  font-weight: 500;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--ink-12);
}
.filter-group ul { list-style: none; margin: 0; padding: 0; }
.filter-group li { padding: 4px 0; }
.filter-group a {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-70);
  letter-spacing: .02em;
}
.filter-group /* Inverted from convention: hover dims to 50% opacity rather than
   brightening or turning accent-colour. */
a:hover { color: var(--ink); opacity: .5; }
.filter-group a.is-active { color: var(--chord); font-weight: 600; }
.filter-group .n { color: var(--ink-50); }

.results-label {
  font-family: var(--mono);
  font-size: 12px;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-50);
  padding-bottom: 10px;
  border-bottom: 2px solid var(--ink);
  margin-bottom: 2px;
}
.result {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 90px 44px;
  gap: 16px;
  align-items: baseline;
  padding: 14px 0;
  border-bottom: 1px solid var(--ink-12);
}
.result .t {
  font-family: var(--sans);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result .sub { font-family: var(--mono); font-size: 11px; color: var(--ink-70); letter-spacing: .02em; }
.result .diff { font-family: var(--mono); font-size: 11px; letter-spacing: .04em; text-align: right; }
.diff-pemula { color: var(--green); }
.diff-menengah { color: var(--amber); }
.diff-lanjutan { color: var(--chord); }
.result .key { font-family: var(--sans); font-size: 12px; color: var(--chord); font-weight: 600; text-align: center; }

.recent { margin-top: 34px; }
.recent .filter-label {
  font-family: var(--mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--ink-50);
  font-weight: 500;
  margin: 0 0 10px;
}
.recent a {
  border-bottom: 1px dotted var(--ink-50);
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-70);
  margin-right: 16px;
  line-height: 2;
}
.recent a:hover { color: var(--chord); border-bottom-color: var(--chord); }

/* ---------------------------------------------------------------- artist page */
.artist-head { padding: 34px 0 30px; }
.artist-head h1 { font-size: 64px; margin-bottom: 14px; }
.artist-head .bio { font-size: 17px; color: var(--ink-70); max-width: 60ch; margin-bottom: 18px; }
.artist-head .stats {
  font-family: var(--sans);
  font-size: 12px;
  color: var(--ink-70);
  letter-spacing: .02em;
  margin-bottom: 20px;
}
.artist-head .stats .dot { color: var(--ink-50); padding: 0 8px; }

.alpha-index { columns: 2; column-gap: 44px; margin: 0; padding: 0; list-style: none; }
.alpha-index li {
  break-inside: avoid;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 34px;
  gap: 10px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid var(--ink-12);
}
.alpha-index .letter {
  font-family: var(--sans);
  font-size: 11px;
  color: var(--chord);
  font-weight: 600;
}
.alpha-index a {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.alpha-index .key { font-family: var(--sans); font-size: 11px; color: var(--chord); text-align: right; }

/* ---------------------------------------------------------------- footer */
.colophon {
  border-top: 2px solid var(--ink);
  margin-top: 20px;
  padding: 36px 0 28px;
}
.colophon .cols {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 40px;
}
.colophon .fbrand {
  font-family: var(--sans);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.02em;
  margin-bottom: 10px;
}
.colophon .fbrand b { color: var(--chord); }
.colophon p { font-size: 13px; color: var(--ink-70); max-width: 34ch; line-height: 1.6; }
/* Footer column labels are labels, not document headings — an <h4> here would
   skip a level in the page outline (h2 -> h4). */
.colophon .fcol-label {
  font-family: var(--sans);
  font-size: 13px;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-70);
  font-weight: 500;
  margin: 0 0 10px;
}
.colophon ul { list-style: none; margin: 0; padding: 0; }
.colophon li { padding: 3px 0; }
.colophon ul a { font-size: 13px; color: var(--ink-70); }
.colophon ul /* Inverted from convention: hover dims to 50% opacity rather than
   brightening or turning accent-colour. */
a:hover { color: var(--ink); opacity: .5; }
.fineprint {
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 30px;
  padding-top: 14px;
  border-top: 1px solid var(--ink-12);
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-50);
  letter-spacing: .04em;
}

/* ---------------------------------------------------------------- utility */
.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;
}
[hidden] { display: none !important; }

/* ---------------------------------------------------------------- responsive */
@media (max-width: 900px) {
  :root { --pad: 24px; }
  h1 { font-size: 40px; }
  .hero { padding: 40px 0 34px; }
  .hero h1 { font-size: 40px; }
  .nav { display: none; }
  /* Mobile bar is three zones: hamburger | search | theme. The brand is the
     one thing that can go — the sheet carries it — so it drops instead of
     competing with the search field for the middle of the bar. */
  .masthead .bar {
    gap: 10px;
    flex-wrap: nowrap;
    padding: 10px 0;
  }
  /* Brand stays on mobile — it is the only thing that tells a first-time
     visitor what site this is. At 13px it costs 109px, leaving ~170px for
     search at 390px wide. The fixed controls (burger 36 + theme 36 + gaps 20)
     are what actually constrain the bar, not the brand. */
  .brand {
    display: block;
    font-size: 13px;
    flex: 0 0 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: clip;
  }
  .menu-toggle {
    border: 0;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    padding: 6px;
    /* 24px minimum touch target — this was 33x15px, under the WCAG floor. */
    min-height: 36px;
    min-width: 36px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
    flex: 0 0 auto;
    margin-left: -6px;   /* optical alignment with the page edge */
  }
  .menu-toggle:hover { color: var(--chord); }
  .head-tools { flex: 1 1 auto; justify-content: flex-end; gap: 8px; min-width: 0; }
  .head-search {
    flex: 1 1 auto;
    width: auto;
    max-width: none;
    min-width: 0;
  }
  .head-search input { min-height: 34px; font-size: 14px; padding: 4px 0; }
  .head-search button { min-height: 34px; padding: 0 10px; font-size: 13px; }
  .theme-toggle { min-height: 36px; min-width: 36px; flex: 0 0 auto; }
  .nav { flex: 1; }

  .pick { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .pick .side { border-left: 0; border-top: 1px solid var(--ink-12); padding-left: 0; padding-top: 16px; }

  .index-cols { columns: 2; }

  .song-grid { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 24px 0 44px; }
  .song-side { position: static; }
  .song-head h1 { font-size: 40px; }
  /* Sticky offset tracks the real masthead height. It was 88px when the mobile
     bar wrapped onto two rows; the single-row bar measures 52px. */
  .controls { top: 52px; }

  .search-grid { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 24px 0 44px; }
  .filter-rail { position: static; margin-bottom: 28px; }
  .filter-rail .filter-group { margin-bottom: 18px; }

  .artist-head h1 { font-size: 44px; }
  .colophon .cols { grid-template-columns: minmax(0, 1fr); gap: 26px; }

  .chart li { grid-template-columns: 42px 52px minmax(0, 1fr) 40px; }
  .chart .views {
  font-variant-numeric: tabular-nums; display: none; }
}

@media (max-width: 600px) {
  :root { --pad: 20px; }
  h1 { font-size: 32px; }
  .hero { padding: 30px 0 26px; }
  .hero h1 { font-size: 32px; }
  .lede { font-size: 15px; }
  .section { padding: 30px 0; }
  .section-head h2 { font-size: 20px; }
  .song-head h1 { font-size: 32px; }
  .song-head .artist { font-size: 18px; }
  .page-head h1 { font-size: 34px; }
  .artist-head h1 { font-size: 34px; }
  .pick { padding: 20px 18px; }
  .pick h3 { font-size: 26px; }
  .lyrics, .lyric-line { font-size: 15px; }
  .index-cols { columns: 1; }
  .alpha-index { columns: 1; }

  /* chart rows: drop movement and view columns, keep rank + title + key */
  .chart li { grid-template-columns: 34px minmax(0, 1fr) 36px; gap: 10px; }
  .chart .move { display: none; }
  .chart .rank {
  font-variant-numeric: tabular-nums; font-size: 17px; }
  .chart .song a { font-size: 15px; }

  .result { grid-template-columns: minmax(0, 1fr) 40px; }
  .result .diff { display: none; }

  .masthead .bar { padding: 8px 0; gap: 8px; }
  /* Four control groups stacked on mobile ate 27% of the screen. Keep them on
     one horizontally scrollable row instead — the chord text is what matters. */
  .controls {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 8px;
    padding: 8px 0;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .controls::-webkit-scrollbar { display: none; }
  .controls > * { flex: 0 0 auto; }
  .ctl-scroll { width: auto; flex-wrap: nowrap; }
  .speed input[type="range"] { width: 74px; }
  .speed-val { min-width: 0; }
  .controls .ctl-label { display: none; }
}

@media (max-width: 375px) {
  /* Only on the narrowest phones: the full wordmark would squeeze the search
     field under ~100px. "chordbatak" still identifies the site. */
  .brand .tld { display: none; }
}

/* ---------------------------------------------------------------- tool pages
   Chord reference cards. Square, hairline-framed, mono fingering — same
   grammar as the rest of the book. */
.chordgrid {
  display: grid;
  gap: 0;
  /* Fixed track count: auto-fill leaves empty bordered cells at the end of a
     row, which reads as an unfinished table rather than a grid. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
}
@media (max-width: 900px) {
  .chordgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
}
@media (max-width: 600px) {
  .chordgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; }
}
.chordcard {
  border: 0;
  border-radius: var(--r-md);
  box-shadow: var(--ring);
  margin: 6px;
  padding: 18px 18px 16px;
}
.chordcard h3 {
  font-family: var(--mono);
  font-size: 30px;
  color: var(--chord);
  letter-spacing: -.02em;
  margin-bottom: 6px;
}
.chordcard code {
  display: block;
  font-family: var(--mono);
  font-size: 14px;
  letter-spacing: .12em;
  color: var(--ink);
  margin-bottom: 8px;
}
.chordcard p {
  font-size: 13px;
  color: var(--ink-70);
  margin: 0;
  line-height: 1.5;
}

/* prose block on tool pages */
.section .lede { max-width: 62ch; }
.section .lede a { color: var(--chord); border-bottom: 1px solid var(--chord); }
.section .lede a:hover { color: var(--ink); border-bottom-color: var(--ink); }
