/* ---------------------------------------------------------------------------
   Theme tokens
   Light/dark comes from [data-theme] on <html>, restored from localStorage
   before first paint. The accent is a fixed part of the palette — change it
   here to restyle links, focus rings, and verse numbers site-wide.
--------------------------------------------------------------------------- */

:root {
  --accent: #c2410c;

  --bg: #faf7f2;
  --bg-raised: #ffffff;
  --bg-sunken: #f2ede4;
  --text: #1c1917;
  --text-muted: #6b625a;
  --border: #e2dace;
  --shadow: 0 1px 2px rgb(28 25 23 / 6%), 0 4px 12px rgb(28 25 23 / 4%);

  --font-body: "Roboto", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-indic: "Noto Sans Devanagari", "Nirmala UI", "Kohinoor Devanagari", var(--font-body);
  --font-serif: ui-serif, Georgia, "Times New Roman", serif;

  --measure: 68ch;
  --radius: 10px;
  --gap: 1.5rem;

  /* Reader mode's font-size multiplier. Applied only inside .reader-mode, so
     it never affects normal reading — see the Reader mode section below. */
  --reader-font-scale: 1;
}

[data-theme="dark"] {
  --bg: #16130f;
  --bg-raised: #211d18;
  --bg-sunken: #100e0b;
  --text: #f5f0e8;
  --text-muted: #a89e92;
  --border: #332c24;
  --shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 12px rgb(0 0 0 / 30%);
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover {
  text-decoration-thickness: 2px;
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--accent);
  color: #fff;
  padding: 0.6rem 1rem;
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

.wrap {
  max-width: 78rem;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

/* --------------------------------------------------------------- site chrome */

.site-header {
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  min-height: 4rem;
  flex-wrap: wrap;
}

.site-title {
  font-family: var(--font-serif);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
}

.site-title a {
  color: inherit;
  text-decoration: none;
}

.site-footer {
  border-top: 1px solid var(--border);
  margin-top: 4rem;
  padding-block: 2rem;
  color: var(--text-muted);
  font-size: 0.875rem;
}

/* ------------------------------------------------------------ theme controls */

.theme-controls {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--bg-sunken);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.7rem;
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
}

.theme-toggle:hover {
  border-color: var(--accent);
}

/* -------------------------------------------------------------- site search */

.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;
}

.site-search {
  position: relative;
  flex: 1 1 20rem;
  max-width: 24rem;
}

.site-search__input {
  width: 100%;
  font: inherit;
  font-size: 0.875rem;
  padding: 0.45rem 0.75rem;
  background: var(--bg-sunken);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.site-search__input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Safari/Chrome ship a built-in clear button on [type=search]; the default
   look clashes with the custom result list, so it is hidden and re-added via
   the input's own value instead of relying on the native widget. */
.site-search__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

.site-search__results {
  position: absolute;
  top: calc(100% + 0.375rem);
  left: 0;
  right: 0;
  z-index: 30;
  margin: 0;
  padding: 0.375rem;
  list-style: none;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  max-height: 22rem;
  overflow-y: auto;
}

.site-search__results[hidden] {
  display: none;
}

.site-search__result {
  border-radius: 6px;
}

.site-search__result a {
  display: block;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
}

.site-search__result a:hover,
.site-search__result a:focus-visible,
.site-search__result.is-active a {
  background: var(--bg-sunken);
}

.site-search__result-title {
  font-size: 0.875rem;
  font-weight: 600;
}

.site-search__result-title mark {
  background: color-mix(in srgb, var(--accent) 30%, transparent);
  color: inherit;
  border-radius: 3px;
}

.site-search__result-meta {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-top: 0.1rem;
}

.site-search__empty {
  padding: 0.6rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ------------------------------------------------------------------ homepage */

.page-intro {
  padding-block: 2.5rem 1.5rem;
  max-width: var(--measure);
}

.page-intro h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  line-height: 1.2;
  margin: 0 0 0.5rem;
}

.page-intro p {
  color: var(--text-muted);
  margin: 0;
}

.song-list {
  list-style: none;
  padding: 0;
  margin: 0 0 3rem;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
}

.song-card {
  display: block;
  height: 100%;
  padding: 1.25rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow);
  transition: border-color 120ms ease, transform 120ms ease;
}

.song-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}

.song-card__seq {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.35rem;
}

.song-card__title {
  font-family: var(--font-serif);
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0 0 0.25rem;
}

.song-card__meta {
  font-size: 0.8125rem;
  color: var(--text-muted);
  margin: 0;
}

.empty-state {
  padding: 2rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--text-muted);
}

/* --------------------------------------------------------------- song header */

.song-header {
  padding-block: 2rem 1rem;
}

.song-header h1 {
  font-family: var(--font-serif);
  font-size: clamp(1.6rem, 3.5vw, 2.25rem);
  line-height: 1.2;
  margin: 0 0 0.35rem;
}

.song-header__subtitle {
  color: var(--text-muted);
  margin: 0 0 0.75rem;
}

.song-header__intro {
  max-width: var(--measure);
  color: var(--text-muted);
  font-size: 0.9375rem;
}

.breadcrumb {
  font-size: 0.875rem;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
}

.breadcrumb__seq {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
}

.song-header__controls {
  margin-top: 1rem;
}

.toggle-translation {
  font: inherit;
  font-size: 0.8125rem;
  padding: 0.35rem 0.75rem;
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}

.toggle-translation:hover {
  border-color: var(--accent);
}

.toggle-translation[aria-pressed="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

/* -------------------------------------------------------------------------
   Parallel verse grid

   One grid row per verse. Because the transliteration cell and the translation
   cell are
   siblings in the same row, the row height is driven by whichever is taller
   and the columns can never drift out of alignment — no scroll syncing.
------------------------------------------------------------------------- */

.verse-grid {
  display: grid;
  /* Reader mode can add extra transliteration columns at runtime (see
     reader-add-script); --verse-grid-cols lets JS repeat "1fr" as many times
     as there are visible columns without rewriting this whole rule. Normal
     view never sets the variable, so the fallback (the original fixed
     two-column layout) applies unchanged. */
  grid-template-columns: var(--verse-grid-cols, 1fr 1fr);
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-raised);
  box-shadow: var(--shadow);
}

/* Translation hidden: the translation cells leave the layout entirely.
 *
 * Normal view has exactly one transliteration column, so removing translation
 * always leaves exactly one column — grid-template-columns: 1fr is correct
 * and constant there. Reader mode is different: it can have 1-N
 * transliteration columns at once (see the "extra transliteration columns"
 * section below), so when reader mode AND translation-hidden are both
 * active, its column count is dynamic and set by JS (updateGridColumnCount)
 * via --verse-grid-cols instead — the plain selector below is overridden by
 * the more specific body.reader-mode rule later in the file, so the two
 * never actually conflict despite both targeting grid-template-columns.
 */
.verse-grid.translation-hidden {
  grid-template-columns: 1fr;
}

.verse-grid.translation-hidden .column-header--translation,
.verse-grid.translation-hidden .verse-cell--translation {
  display: none;
}

.verse-grid.translation-hidden .column-header--transliteration,
.verse-grid.translation-hidden .verse-cell--transliteration {
  border-right: none;
}

/* With the translation gone the lyric cell is the only one in its row, so it
   carries the row's bottom border again. */
.verse-grid.translation-hidden .verse-cell--transliteration {
  border-bottom: 1px solid var(--border);
}

.verse-grid.translation-hidden .verse-row:last-of-type .verse-cell--transliteration {
  border-bottom: none;
}

.column-headers {
  display: contents;
}

.column-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.75rem 1.25rem;
  background: var(--bg-sunken);
  border-bottom: 1px solid var(--border);
}

.column-header--transliteration {
  border-right: 1px solid var(--border);
}

.column-header__label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.verse-row {
  display: contents;
}

.verse-cell {
  padding: 1.25rem;
  border-bottom: 1px solid var(--border);
}

.verse-cell--transliteration {
  border-right: 1px solid var(--border);
}

.verse-row:last-of-type .verse-cell {
  border-bottom: none;
}

/* Zebra striping helps the eye track a row across the gutter. */
.verse-row:nth-of-type(even) .verse-cell {
  background: color-mix(in srgb, var(--bg-sunken) 45%, transparent);
}

.verse-number {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent);
  margin-bottom: 0.4rem;
  font-variant-numeric: tabular-nums;
}

.verse-text {
  margin: 0;
}

/* Lyrics are verse: every source line break is meaningful, so preserve it.
   This holds for the original script and its romanization alike.
   font-size is in em (not rem) so it scales with an ancestor's font-size —
   specifically .verse-grid in reader mode, via --reader-font-scale. */
.verse-cell--transliteration .verse-text {
  white-space: pre-line;
  font-size: 1.0625em;
  line-height: 1.9;
}

/* Translations are prose: they must reflow to the column, ignoring however
   the source file happened to be hard-wrapped. */
.verse-cell--translation .verse-text {
  color: var(--text-muted);
}

/* Script-specific typography for Indic text. */
[data-script="devanagari"],
[data-script="bengali"],
[data-script="gujarati"],
[data-script="gurmukhi"],
[data-script="tamil"],
[data-script="telugu"],
[data-script="kannada"],
[data-script="malayalam"],
[data-script="odia"] {
  font-family: var(--font-indic);
}

.verse-missing {
  font-style: italic;
  color: var(--text-muted);
  opacity: 0.7;
  margin: 0;
  font-size: 0.875rem;
}

/* -------------------------------------------------------------------------
   Language switching

   Every language variant is present in the HTML (good for SEO and for
   no-JS readers); the active one is chosen by CSS attribute match.
------------------------------------------------------------------------- */

.lang-variant {
  display: none;
}

.lang-variant.is-active {
  display: block;
}

/* Without JS, show the first variant of each cell so the page still reads. */
.no-js .lang-variant:first-child {
  display: block;
}

.lang-switcher {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.lang-switcher label {
  font-size: 0.75rem;
  color: var(--text-muted);
}

.lang-select {
  font: inherit;
  font-size: 0.8125rem;
  padding: 0.3rem 0.5rem;
  background: var(--bg-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  /* Fixed rather than content-sized, so the script and language dropdowns
     match each other regardless of how long their longest option is
     ("Sanskrit (Roman)" would otherwise be far wider than "English"). */
  width: 11rem;
}

.lang-select:hover {
  border-color: var(--accent);
}

/* ------------------------------------------------------------------- mobile */

@media (max-width: 48rem) {
  /* Collapse to one column: each verse's translation follows its lyrics directly,
     which is the natural reading order on a narrow screen. */
  .verse-grid {
    grid-template-columns: 1fr;
  }

  .column-header--transliteration,
  .verse-cell--transliteration {
    border-right: none;
  }

  .column-header {
    position: static;
  }

  .column-header--translation {
    border-top: 1px solid var(--border);
  }

  .verse-cell--transliteration {
    border-bottom: none;
    padding-bottom: 0.5rem;
  }

  .verse-cell--translation {
    padding-top: 0.5rem;
  }

  .verse-cell--translation .verse-number {
    display: none;
  }

  /* Nothing follows the lyric cell once the translation is hidden, so restore
     the separator and padding the stacked layout had removed. */
  .verse-grid.translation-hidden .verse-cell--transliteration {
    padding-bottom: 1.25rem;
  }

  .site-header__inner {
    padding-block: 0.75rem;
  }

  /* Full width on its own wrapped row rather than the desktop-sized column. */
  .site-search {
    flex-basis: 100%;
    max-width: none;
    order: 3;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

@media print {
  .site-header,
  .site-footer,
  .lang-switcher,
  .theme-controls,
  .site-search {
    display: none;
  }

  .verse-grid {
    box-shadow: none;
  }
}

/* -------------------------------------------------------------------------
   Reader mode

   A distraction-free, full-screen presentation of the same .verse-grid
   already on the page — no separate template or duplicated markup. Toggling
   .reader-mode on <body> hides the site chrome, promotes the verse grid to a
   fixed full-viewport layer, and shows the reader toolbar in its place.

   Deliberately NOT persisted across a reload — only the font-size and
   scroll-speed *preferences* are remembered; whether reader mode itself is
   open is not, so every page load starts in the normal view.
------------------------------------------------------------------------- */

.reader-open {
  cursor: pointer;
}

.reader-toolbar {
  display: none;
}

body.reader-mode {
  /* The verse grid becomes the only scrollable surface; scrolling the body
     itself would fight the auto-scroll animation and double-scroll on touch. */
  overflow: hidden;
}

body.reader-mode .site-header,
body.reader-mode .song-header,
body.reader-mode .site-footer {
  display: none;
}

body.reader-mode main.wrap {
  /* The verse grid inside is what actually goes full-screen (see below); the
     wrapper itself just needs to stop constraining width/centering it. */
  all: unset;
  display: block;
}

body.reader-mode .reader-toolbar {
  display: flex;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding: 0.75rem 1.25rem;
  background: var(--bg-raised);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.reader-toolbar__btn {
  font: inherit;
  font-size: 0.8125rem;
  padding: 0.4rem 0.7rem;
  background: var(--bg-sunken);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  line-height: 1;
}

.reader-toolbar__btn:hover {
  border-color: var(--accent);
}

.reader-toolbar__close {
  color: var(--accent);
  border-color: var(--accent);
}

.reader-toolbar__group {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.reader-toolbar__label {
  font-size: 0.75rem;
  color: var(--text-muted);
  margin-right: 0.15rem;
}

.reader-toolbar__speed {
  display: inline-block;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  /* Fixed, not min-width: the longest possible label ("0.25×") must not grow
     the element beyond this, or the +/- buttons shift as the value changes. */
  width: 5ch;
  text-align: center;
}

/* Hotkey hints — subtle by design: small, muted, and tucked beside the
   control they belong to rather than called out as their own element. */
.reader-toolbar__kbd {
  display: inline-block;
  margin-left: 0.3rem;
  padding: 0.05rem 0.35rem;
  font: inherit;
  font-size: 0.6875rem;
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  color: var(--text-muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  line-height: 1.4;
  opacity: 0.75;
}

.reader-toolbar__hint {
  font-size: 0.75rem;
  color: var(--text-muted);
  opacity: 0.75;
}

/* Higher specificity than plain .verse-grid.translation-hidden (line ~433),
   so reader mode's dynamic --verse-grid-cols always wins here regardless of
   the two rules' order in the file — hiding translation while multiple
   transliteration columns are open must reflow to that many columns, not
   collapse to a hardcoded single one. */
body.reader-mode .verse-grid.translation-hidden {
  grid-template-columns: var(--verse-grid-cols, 1fr);
}

body.reader-mode .verse-grid {
  position: fixed;
  inset: 0;
  top: 3.25rem; /* below the fixed toolbar */
  z-index: 50;
  overflow-y: auto;
  border: none;
  border-radius: 0;
  box-shadow: none;
  max-width: none;
  /* Independent scaling from the rest of the site — see --reader-font-scale
     on :root, adjusted by the toolbar's A+/A- buttons. */
  font-size: calc(1rem * var(--reader-font-scale));
}

body.reader-mode .column-header {
  top: 0;
}

/* No extra font-size rule needed here: .verse-grid above sets font-size in
   rem from --reader-font-scale, and every descendant (.verse-text, headings,
   labels) already uses em/relative sizing, so they scale via normal CSS
   inheritance. A+/A- only ever has to touch the one variable. */

/* -------------------------------------------------------------------------
   Reader mode: extra transliteration columns

   Reader mode can add more transliteration columns at runtime — each one a
   full clone of the original transliteration cell/header, with its own
   independent script selector. Because the column count is dynamic, the
   fixed --transliteration/--translation border rules above don't generalize;
   these :not(:last-child) rules give every column a right-hand divider
   except whichever one currently happens to be last, no matter how many
   there are.
------------------------------------------------------------------------- */

body.reader-mode .column-header,
body.reader-mode .verse-cell {
  border-right: 1px solid var(--border);
}

body.reader-mode .column-header:last-child,
body.reader-mode .verse-cell:last-child {
  border-right: none;
}

/* An added column's header carries its own remove button beside the script
   selector. */
.column-header__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.375rem;
  height: 1.375rem;
  margin-left: 0.25rem;
  font-size: 0.75rem;
  line-height: 1;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 5px;
  cursor: pointer;
}

.column-header__remove:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.reader-toolbar__btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.reader-toolbar__btn:disabled:hover {
  border-color: var(--border);
}

@media (max-width: 48rem) {
  body.reader-mode .reader-toolbar {
    gap: 0.75rem 1rem;
  }

  body.reader-mode .verse-grid {
    top: 5.5rem; /* toolbar wraps to two rows on narrow screens */
  }
}

@media print {
  .reader-toolbar {
    display: none;
  }
}
