/* style.css — spec §8.
   Paper, not screen. No cards, no shadows, no gradients. Everything that
   separates is a hairline.

   Written mobile-first for iPhone 16 (393 × 852 pt, 59 pt top inset, 34 pt
   home indicator). There is one width breakpoint, and it only widens the
   reading column on a larger phone. */

/* ── Devanagari face ──────────────────────────────────────────────────────
   unicode-range confines Tiro to Devanagari, so Latin keeps falling through
   to ui-serif (New York on iOS) and the woff2 is never fetched on a screen
   with no Devanagari on it. */
@font-face {
  font-family: 'Tiro Devanagari Hindi';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/tiro-devanagari-hindi-devanagari-400-normal.woff2') format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0,
                 U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}

/* ── tokens ─────────────────────────────────────────────────────────────── */
:root {
  --paper:#faf8f3; --ink:#1c1a16; --muted:#6b6560; --rule:#e2ddd2;
  --mark:#f0e3c8;  --accent:#8c6d3f;
  --grain:0.015;

  --serif: 'Tiro Devanagari Hindi', ui-serif, 'New York', Georgia, serif;
  --ui: -apple-system, BlinkMacSystemFont, 'SF Pro Text', system-ui, sans-serif;

  /* fluid type, no per-size media queries */
  --fs-read: clamp(1.1875rem, 1.13rem + 0.28vw, 1.3rem);   /* 19 → 20.8 */
  --fs-ui: 0.875rem;
  --fs-meta: 0.78rem;

  /* Leading. Measured against Tiro's real outlines over this corpus: the
     worst ink spans 1.312 em — the tallest matra (ै, +0.964) over the deepest
     conjunct (द्ध, −0.348) — so collision begins below 1.312 and 1.5 does not
     in fact collide in this face. 1.85 is right for a better reason: it
     leaves 0.538 em of white between lines, which is what a Latin serif
     leaves at 1.5. It is the equivalent setting, not a generous one. */
  --lead: 1.85;

  --t: 200ms ease-out;        /* the one transition */
  --col: 40rem;
  --pad: 1.25rem;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --tap: 2.75rem;             /* 44 pt, the smallest thing worth aiming at */
}
@media (prefers-color-scheme: dark) {
  :root {
    --paper:#17150f; --ink:#e8e3d6; --muted:#8a837a; --rule:#2a2721;
    --mark:#3a3220;  --accent:#c9a063;
    --grain:0.04;
  }
}
@media (prefers-reduced-motion: reduce) { :root { --t: 0ms; } }

/* ── frame ──────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--paper); color: var(--ink);
  font: 1rem/1.5 var(--ui);
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: none;
}
body.sheet-open { overflow: hidden; }

/* paper grain — a fixed tile, mid-grey overlaid, so only the deviation shows.
   Above the sheet (z 50), not below it: at z 10 the sheet's opaque paper
   background covered it, so the one screen actually read on was the one
   screen with no paper on it. pointer-events: none, so sitting on top of the
   controls costs nothing. */
.grain {
  position: fixed; inset: 0; z-index: 100;
  pointer-events: none;
  background-image: url('textures/grain.png');
  background-size: 200px 200px;
  mix-blend-mode: overlay;
  opacity: var(--grain);
}

.wrap {
  max-width: var(--col); margin: 0 auto;
  padding: calc(var(--safe-t) + 1.25rem) var(--pad) 4rem;
}
body.has-player .wrap { padding-bottom: calc(6.5rem + var(--safe-b)); }

::selection { background: var(--mark); color: var(--ink); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
:focus:not(:focus-visible) { outline: none; }

h1 {
  font: 400 1.3rem/1.4 var(--serif);
  margin: 0 0 1.5rem; letter-spacing: .01em;
}
h2 {
  font: 400 .75rem/1.4 var(--ui);
  text-transform: lowercase; letter-spacing: .08em; color: var(--muted);
  margin: 2rem 0 .75rem; padding-bottom: .4rem;
  border-bottom: 1px solid var(--rule);
}
.dev { font-variant-numeric: normal; }

nav { display: flex; flex-wrap: wrap; gap: .5rem 1rem; margin-bottom: 1.5rem; font-size: var(--fs-ui); }
nav a {
  color: var(--muted); text-decoration: none;
  padding-bottom: 2px; border-bottom: 1px solid transparent;
  transition: color var(--t), border-color var(--t);
}
nav a.on { color: var(--ink); border-bottom-color: var(--accent); }

/* ── notices ────────────────────────────────────────────────────────────── */
.notice {
  font-size: .8rem; line-height: 1.6; color: var(--muted);
  border-left: 1px solid var(--accent);
  padding: .1rem 0 .1rem .75rem; margin: 0 0 1.25rem;
}
.notice b { font-weight: 400; color: var(--ink); }

/* the first-run line: said once, then never again. No border, no icon, no
   dismiss control — it is a whisper under the list, not a banner. */
.firstrun {
  margin: 2rem 0 0; text-align: center;
  font-size: .78rem; line-height: 1.7; color: var(--muted);
}

/* ── discourse rows ─────────────────────────────────────────────────────── */
.row {
  display: flex; align-items: baseline; gap: .75rem;
  width: 100%; min-height: var(--tap);
  padding: .7rem 0; border: 0; border-bottom: 1px solid var(--rule);
  background: none; color: inherit; font: inherit; text-align: left;
  transition: background var(--t);
}
.row:active { background: var(--rule); transition: none; }   /* down is instant, up eases */
.row .n { font: 400 1.05rem/1.4 var(--serif); min-width: 2.2rem; }
.row .mid { display: block; flex: 1; min-width: 0; }
.row .kind { display: block; font-size: .72rem; color: var(--muted); letter-spacing: .04em; }
.row .bar { display: block; height: 1px; background: var(--rule); margin-top: .45rem; width: 100%; }
.row .bar i { display: block; height: 100%; background: var(--accent); transition: width var(--t); }
.row .meta {
  margin-left: auto; font-size: var(--fs-meta); color: var(--muted);
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.row .on-disk { color: var(--accent); }
.row.is-current .n { color: var(--accent); }

/* ── the mini bar ───────────────────────────────────────────────────────── */
.mini {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; align-items: center; gap: .5rem;
  background: var(--paper);
  padding: .55rem var(--pad) calc(.55rem + var(--safe-b));
}
.mini[hidden] { display: none; }

/* the top hairline IS the progress indicator */
.mini__track {
  position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: var(--rule);
}
.mini__track i {
  display: block; height: 100%; width: 0; background: var(--accent);
  transition: background var(--t);
}
.mini__track i.loading { background: var(--muted); }

.mini__open {
  flex: 1; display: flex; align-items: baseline; gap: .6rem;
  min-height: var(--tap);
  border: 0; background: none; color: inherit; font: inherit; text-align: left;
  padding: 0;
}
.mini__n { font: 400 1.1rem/1 var(--serif); }
.mini__time {
  font-size: var(--fs-meta); color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ── the sheet ──────────────────────────────────────────────────────────── */
.sheet {
  position: fixed; inset: 0; z-index: 50;
  display: flex; flex-direction: column;
  background: var(--paper);
  padding-top: var(--safe-t);
  transform: translateY(100%);
  visibility: hidden;
  transition: transform var(--t), visibility var(--t);
}
.sheet.on { transform: translateY(0); visibility: visible; }
/* while a thumb is on it the sheet tracks the thumb; easing a drag reads as lag */
.sheet.is-dragging { transition: none; }

.sheet__grip {
  flex: none; align-self: center;
  width: 100%; height: 2rem; border: 0; background: none; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.sheet__grip::before {
  content: ''; width: 2.25rem; height: 2px; border-radius: 1px;
  background: var(--rule);
  transition: background var(--t);
}
.sheet__grip:active::before { background: var(--muted); transition: none; }

.sheet__head {
  flex: none; display: flex; align-items: baseline; gap: .7rem;
  padding: 0 var(--pad) .6rem;
  margin: 0 var(--pad); padding-left: 0; padding-right: 0;
  border-bottom: 1px solid var(--rule);
}
.sheet__n { font: 400 1.15rem/1 var(--serif); }
.sheet__kind { font-size: .72rem; letter-spacing: .04em; color: var(--muted); }

.sheet__read {
  flex: 1; min-height: 0; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 1.25rem var(--pad) 2rem;
  font-family: var(--serif);
  font-size: var(--fs-read); line-height: var(--lead);
  text-align: left;
}

/* ── blocks ───────────────────────────────────────────────────────────────
   Spacing is expressed as top margins on adjacent siblings rather than a
   bottom margin on every block, so the exceptions below can simply say what
   the gap is instead of cancelling one with a negative number. */
.sheet__read .blk { margin: 0; }
.sheet__read .blk + .blk { margin-top: 1.15em; }
.sheet__read .t { white-space: pre-line; }   /* newlines are real characters in `plain` */

/* the trailing `।। 6।।`, and the same marker inside a bookmarked sutra.
   Still in the DOM — and so in textContent, and so in every bookmark offset —
   just not painted. */
.off { display: none; }

/* ── sutras ───────────────────────────────────────────────────────────────
   `pre`, never `pre-line`: a pada is a metrical line and wrapping one invents
   a break the verse does not have. Because sutras are centred, a wrapped
   remnant sits centred on its own line and reads as another pada — which is
   what two of the eight shlokas in discourse 1 were doing. views.js measures
   the widest pada per discourse and sets --sutra-fit so nothing has to wrap.

   Leading 1.9 rather than 2.0: at 2.0 the padas sat 0.69 em apart while the
   verse numeral sat 0.55 em below them, so the numeral was closer to the verse
   than the verse's own lines were to each other. */
.sheet__read .blk-sutra { text-align: center; }
.sheet__read .blk + .blk-sutra { margin-top: 2.4em; }
.sheet__read .blk-sutra + .blk { margin-top: 2.4em; }
.sheet__read .blk-sutra .t {
  font-size: calc(1.08em * var(--sutra-fit, 1));
  line-height: 1.9;
  white-space: pre;
}
/* the floor: below 0.84 a wrap is the lesser evil */
.sheet__read.sutra-wraps .blk-sutra .t { white-space: pre-line; }

.sheet__read .verse {
  display: block; margin-top: 1em;
  font-size: .68em; line-height: 1; color: var(--muted);
}

/* ── questions ────────────────────────────────────────────────────────────
   The audience's voice: set back, not set apart, so the answer stays primary.
   Three spacings, all structural — no block's content is inspected:
     within a group   `पहला प्रश्न:` and the question it introduces are one
                      thing, so they are set tight;
     into a group     the rule opens a session, so it takes more space above
                      than below;
     out of a group   the handover from question to answer is a change of
                      voice and gets more than a paragraph break. */
.sheet__read .blk-question .t { font-size: .94em; color: var(--muted); }
.sheet__read .blk-question + .blk-question { margin-top: .45em; }
.sheet__read .blk + .blk-q-open {
  margin-top: 3.4em; padding-top: 1.8em;
  border-top: 1px solid var(--rule);
}
.sheet__read .blk + .blk-answer { margin-top: 2.2em; }

.sheet__read mark {
  background: var(--mark); color: inherit;
  border-radius: 2px; padding: 1px 0;
}
.sheet__read mark.flash { outline: 1px solid var(--accent); }

.sheet__empty {
  color: var(--muted); text-align: center; font-family: var(--ui);
  font-size: .9rem; line-height: 1.9; padding: 4rem 1rem; white-space: pre-line;
}

/* ── transport ──────────────────────────────────────────────────────────── */
.transport {
  flex: none;
  border-top: 1px solid var(--rule);
  padding: 1rem var(--pad) calc(.75rem + var(--safe-b));
}

/* a hairline and a dot — not a system control */
.seek {
  position: relative; height: var(--tap); margin: -0.9rem 0 -0.55rem;
  display: flex; align-items: center; touch-action: none;
}
.seek__track { position: relative; width: 100%; height: 1px; background: var(--rule); }
.seek__track i { display: block; height: 100%; width: 0; background: var(--accent); }
.seek__dot {
  position: absolute; top: 50%; left: 0;
  width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px;
  border-radius: 50%; background: var(--accent);
  transition: transform var(--t);
}
.seek.is-dragging .seek__dot { transform: scale(1.6); }
/* the fill and the dot follow the finger directly; easing them would put the
   scrubber behind the thumb, which reads as the control being broken */
.seek.is-dragging .seek__dot,
.seek.is-dragging .seek__track i { transition: none; }

.times {
  display: flex; justify-content: space-between;
  font-size: var(--fs-meta); color: var(--muted);
  font-variant-numeric: tabular-nums;
  margin-top: .55rem;
}

.ctrls {
  display: flex; align-items: center; justify-content: center;
  gap: 2.25rem; margin-top: .35rem;
}
.ctrl, .pp {
  display: flex; align-items: center; justify-content: center;
  border: 0; background: none; color: var(--ink); padding: 0;
  width: var(--tap); height: var(--tap);
}
.pp { width: 3.5rem; height: 3.5rem; }
.pp--mini { width: var(--tap); height: var(--tap); flex: none; }

.ctrl svg, .pp svg {
  width: 1.55rem; height: 1.55rem;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
  transition: stroke var(--t);
}
.pp svg { width: 1.8rem; height: 1.8rem; }
.pp--mini svg { width: 1.5rem; height: 1.5rem; }
.ctrl svg text {
  font: 7px/1 var(--serif); fill: currentColor; stroke: none;
}
.ctrl:active svg, .pp:active svg { stroke: var(--accent); transition: none; }

/* one control shows at a time */
.i--pause { display: none; }
body.is-playing .i--play { display: none; }
body.is-playing .i--pause { display: block; }

.pstatus {
  margin: .5rem 0 0; min-height: 1rem;
  font-size: .72rem; color: var(--muted); text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ── bookmarks ──────────────────────────────────────────────────────────── */
.bmcount { font: 400 1.05rem/1.6 var(--serif); color: var(--ink); }
.sorts { display: flex; gap: 1rem; font-size: var(--fs-meta); margin: .25rem 0 .5rem; }
.sorts button {
  border: 0; background: none; padding: .4rem 0; color: var(--muted); font: inherit;
  border-bottom: 1px solid transparent;
  transition: color var(--t), border-color var(--t);
}
.sorts button.on { color: var(--ink); border-bottom-color: var(--accent); }

.bm { padding: 1.75rem 0; border-bottom: 1px solid var(--rule); }
.bm .txt {
  font-family: var(--serif);
  font-size: var(--fs-read); line-height: var(--lead);
  white-space: pre-line;                /* never truncated, however long */
}
.bm .src { margin-top: .9rem; font-size: .75rem; color: var(--muted); }
.bm .when { font-size: .75rem; color: var(--muted); }
.bm .note { margin-top: .5rem; font-size: .8rem; color: var(--muted); font-style: italic; }
/* sutras keep their sutra treatment here too (spec §7). No fitter on this
   page: a bookmark is a fragment, not necessarily whole padas, so it wraps. */
.bm.is-sutra .txt { text-align: center; font-size: 1.08em; line-height: 1.9; }

/* ── buttons, states ────────────────────────────────────────────────────── */
button {
  font: inherit; font-size: var(--fs-ui); background: none; color: var(--ink);
  border: 1px solid var(--rule); border-radius: 2px;
  padding: .6rem .85rem; min-height: var(--tap);
  transition: background var(--t);
}
button:active { background: var(--rule); transition: none; }
button.wide { width: 100%; margin-top: .5rem; }

.empty {
  color: var(--muted); text-align: center;
  padding: 3rem 1rem; font-size: .9rem; line-height: 1.9; white-space: pre-line;
}
.hint { color: var(--muted); font-size: .78rem; line-height: 1.7; margin: .75rem 0 0; }
.diag {
  font: 12px/1.7 ui-monospace, Menlo, monospace;
  color: var(--muted); white-space: pre-wrap; word-break: break-all;
}

/* ── selection → bookmark ───────────────────────────────────────────────── */
/* visibility rather than display, so the fade actually runs — a display
   change gives the transition no frame to start from. Fixed position, so
   staying in the layout costs nothing, and a hidden element takes no taps. */
.selbtn {
  position: fixed; z-index: 80;
  background: var(--ink); color: var(--paper);
  border: 0; border-radius: 4px; padding: .5rem .9rem;
  font-size: .82rem; min-height: 0;
  visibility: hidden; opacity: 0;
  transition: opacity var(--t), visibility var(--t);
}
.selbtn.on { visibility: visible; opacity: 1; }

/* ── adjust panel ───────────────────────────────────────────────────────── */
.adj {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  background: var(--paper); border-top: 1px solid var(--rule);
  padding: 1rem var(--pad) calc(1rem + var(--safe-b));
  visibility: hidden;
  transform: translateY(100%);
  transition: transform var(--t), visibility var(--t);
}
.adj.on { visibility: visible; transform: translateY(0); }
.adj__inner { max-width: var(--col); margin: 0 auto; }
.adj__text {
  font-family: var(--serif); font-size: .95rem; line-height: 1.7;
  max-height: 7rem; overflow: auto; white-space: pre-line;
  background: var(--mark); padding: .6rem; border-radius: 2px; margin-bottom: .75rem;
}
.adj__row { display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; font-size: .8rem; }
.adj__lab { color: var(--muted); min-width: 3rem; }
.adj__lab--gap { margin-left: 1rem; }
.adj__row button { min-width: 2.75rem; text-align: center; }
.adj__done { margin-left: auto; }
