/* Scrolls web reader — the reading column reproduces the iOS typesetter
   (fixed leading, the same paragraph indents, chapter/verse number treatment,
   footnote markers), while the chrome is the web's own: three floating glass
   clusters — header capsule, right stepper capsule, bottom dock — over the
   paper.

   The palette is paper and graphite: a neutral cream sheet, near-black ink,
   and an "accent" that is only a softer graphite. Nothing in the chrome
   carries a hue, so the seven highlight colors are the only color the reader
   ever sees, and the page reads as paper rather than as an interface. */

:root {
  --paper: #F4F2ED;
  --paper-2: #FBFAF7;
  --ink: #1E1D1B;
  --ink-soft: #6A665E;
  --accent: #4A4740;
  --line: rgba(30, 29, 27, .14);
  --shadow: rgba(30, 29, 27, .13);

  --serif: ui-serif, "New York", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Metrics: compact (<700px) 19pt body / 31pt leading; regular 25/41.
     --reader-scale (typography settings, set from JS) multiplies both, so
     every metric derived from them — indents, verse numbers, stanza space —
     scales with the text. */
  --body: calc(19px * var(--reader-scale, 1));
  --leading: calc(31px * var(--reader-scale, 1));
  /* The column's side inset. It lives on the paragraphs, not on the column,
     so each line's BOX reaches into the margin — see .bk. --gutter-wide is
     the narrow-stop inset; --reader-width-t (0–1, index / 11) lerps it to
     the chrome insets so the last stop is the page and every notch adds
     the same amount of measure. A discrete snap at stop 12 used to dump
     the whole leftover gutter in one jump. */
  --gutter-wide: clamp(22px, 10.5vw, 78px);
  --reader-width-t: 0.63636;   /* default index 7 / 11 on a wide viewport */
  /* The floating clusters' inset from the viewport. Full-width text uses
     these as its gutter so a line begins on the left buttons' outer edge
     and ends on the right stepper's outer edge. */
  --chrome-inset-left: 12px;
  --chrome-inset-right: 10px;
  --gutter: calc(var(--gutter-wide) * (1 - var(--reader-width-t))
    + var(--chrome-inset-left) * var(--reader-width-t));
  --gutter-end: calc(var(--gutter-wide) * (1 - var(--reader-width-t))
    + var(--chrome-inset-right) * var(--reader-width-t));
  /* Fallbacks until JS sizes these so verse 1 and the last verse can sit
     on the reading line (innerHeight / 3). See applyReadingInsets. */
  --top-inset: 84px;
  --bottom-inset: 160px;

  /* Materials: one glass recipe for every floating surface. */
  --glass: color-mix(in srgb, var(--paper-2) 72%, transparent);
  --glass-blur: blur(18px) saturate(140%);
  --hairline: color-mix(in srgb, var(--ink) 10%, transparent);
  --shadow-float: 0 1px 2px var(--shadow), 0 12px 32px -14px var(--shadow);
  --shadow-lift: 0 2px 4px var(--shadow), 0 18px 44px -14px var(--shadow);

  /* Motion: short and eased-out — surfaces settle, never drift. */
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --radius-pill: 999px;
  --radius-card: 18px;
}
@media (min-width: 700px) {
  :root {
    --body: calc(25px * var(--reader-scale, 1));
    --leading: calc(41px * var(--reader-scale, 1));
    --top-inset: 112px; --bottom-inset: 220px;
  }
}

/* Charcoal dark theme: fixed via html[data-theme=dark], or following the
   device unless the reader forced light. The accent inverts to a pale
   graphite, so every filled surface keeps paper-colored text on it. */
html[data-theme="dark"] { color-scheme: dark; }
html[data-theme="light"] { color-scheme: light; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) { color-scheme: dark; }
}
html[data-theme="dark"] {
  --paper: #1A1A18; --paper-2: #222220; --ink: #E8E6E0; --ink-soft: #A8A49B;
  --accent: #CAC5B9; --line: rgba(232, 230, 224, .16); --shadow: rgba(0, 0, 0, .45);
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) {
    --paper: #1A1A18; --paper-2: #222220; --ink: #E8E6E0; --ink-soft: #A8A49B;
    --accent: #CAC5B9; --line: rgba(232, 230, 224, .16); --shadow: rgba(0, 0, 0, .45);
  }
}

/* Reading faces, self-hosted (OFL — see fonts/README). Latin files carry a
   unicode-range so Greek falls through to Cardo instead of a .notdef. */
@font-face {
  font-family: Literata;
  src: url("../fonts/literata-latin.woff2") format("woff2");
  font-weight: 200 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Literata;
  src: url("../fonts/literata-latin-italic.woff2") format("woff2");
  font-weight: 200 900; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "EB Garamond";
  src: url("../fonts/eb-garamond-latin.woff2") format("woff2");
  font-weight: 400 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "EB Garamond";
  src: url("../fonts/eb-garamond-latin-italic.woff2") format("woff2");
  font-weight: 400 800; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/source-serif-latin.woff2") format("woff2");
  font-weight: 200 900; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4";
  src: url("../fonts/source-serif-latin-italic.woff2") format("woff2");
  font-weight: 200 900; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Newsreader;
  src: url("../fonts/newsreader-latin.woff2") format("woff2");
  font-weight: 200 800; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Newsreader;
  src: url("../fonts/newsreader-latin-italic.woff2") format("woff2");
  font-weight: 200 800; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Cardo;
  src: url("../fonts/cardo-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Cardo;
  src: url("../fonts/cardo-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Cardo;
  src: url("../fonts/cardo-latin-bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Cardo;
  src: url("../fonts/cardo-greek.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: Cardo;
  src: url("../fonts/cardo-greek-bold.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Cascadia Mono";
  src: url("../fonts/cascadia-mono-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Cascadia Mono";
  src: url("../fonts/cascadia-mono-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Meslo LG Mono";
  src: url("../fonts/meslo-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Meslo LG Mono";
  src: url("../fonts/meslo-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fira Code";
  src: url("../fonts/fira-code-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Victor Mono";
  src: url("../fonts/victor-mono-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Victor Mono";
  src: url("../fonts/victor-mono-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Bitstream Vera Sans Mono";
  src: url("../fonts/vera-mono-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Bitstream Vera Sans Mono";
  src: url("../fonts/vera-mono-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Iosevka;
  src: url("../fonts/iosevka-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: Iosevka;
  src: url("../fonts/iosevka-latin-italic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* { box-sizing: border-box; }

::selection { background: color-mix(in srgb, var(--accent) 24%, transparent); }

/* Slim, unobtrusive scrollbars everywhere. */
* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--accent) 30%, transparent) transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--accent) 28%, transparent); border-radius: 3px; }
*::-webkit-scrollbar-track { background: transparent; }
/* Page bar only — sheets and other inner scrollers keep theirs. */
html.hide-scrollbar,
html.hide-scrollbar body { scrollbar-width: none; }
html.hide-scrollbar::-webkit-scrollbar,
html.hide-scrollbar body::-webkit-scrollbar { width: 0; height: 0; display: none; }

:focus-visible { outline: 2px solid color-mix(in srgb, var(--accent) 60%, transparent); outline-offset: 2px; }
button:focus,
button:focus-visible,
.bar-btn:focus,
.bar-btn:focus-visible,
.chip:focus,
.chip:focus-visible,
summary:focus,
summary:focus-visible {
  outline: none;
}
html {
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
@media (max-width: 899px) {
  :root { --reader-width-t: 1; }   /* 12 of 12 — the page, until JS applies prefs */
}
button { font-family: var(--sans); color: inherit; }

/* ---- chrome ---------------------------------------------------------------
   Three floating clusters over the page. The whole layer fades as one (tap
   the page to toggle); the scripture keeps its full contrast underneath —
   the glass capsules separate themselves without dimming the reading.
   The fade lives on the capsules, never on this container: opacity below 1
   on an ancestor of a backdrop-filter makes that ancestor the backdrop
   root, so for the whole transition the blur samples an empty layer and the
   scripture shows sharp through the glass, snapping blurry only once the
   opacity lands back on exactly 1. On the filtered element itself the blur
   keeps sampling the page, so every frame of the fade is real glass. */
.chrome {
  position: fixed;
  inset: 0;
  z-index: 20;
  pointer-events: none;         /* clusters re-enable on their own elements */
}
.chrome .bar, .chrome .dock-listen .bar-btn { transition: opacity .25s var(--ease-out); }
.chrome.hidden .bar, .chrome.hidden .chip,
.chrome.hidden .dock-listen .bar-btn { opacity: 0; }
.chrome.hidden * { pointer-events: none !important; }

/* Followed-link focus: only the exit-focus control, bottom-left. */
html.focus-mode .chrome-top,
html.focus-mode .chrome-right,
html.focus-mode .chrome-marks,
html.focus-mode .dock-listen,
html.focus-mode .chrome-help,
html.focus-mode .keynav,
html.focus-mode .wordbar,
html.focus-mode .dock > .bar-btn:not(#btn-focus) {
  display: none !important;
}
html.focus-mode .chrome.hidden .dock,
html.focus-mode .chrome.hidden #btn-focus {
  opacity: 1 !important;
  pointer-events: auto !important;
}
.chrome > div { position: fixed; pointer-events: none; }
.chrome .bar, .chrome .chip { pointer-events: auto; }
.bk { transition: opacity .25s var(--ease-out); }   /* the first-paint veil */

/* One capsule recipe for every button cluster. */
.bar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-float);
}
.bar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  min-width: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease;
}
@media (hover: hover) and (pointer: fine) {
  .bar-btn:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
}
/* Press the icon, not the button. Coarse pointers skip the scale —
   iOS leaves :active stuck, so the glyph sits shrunk with a hover-frame
   around it after a navigate tap. */
.bar-btn > * { transition: transform .12s ease; }
@media (hover: hover) and (pointer: fine) {
  .bar-btn:active > * { transform: scale(.94); }
}
/* display:inline-flex above beats the UA [hidden] rule, same as .note-row. */
.bar-btn[hidden] { display: none !important; }
.dock-listen[hidden],
html.no-listen .dock-listen { display: none !important; }
.bar-btn svg { width: 19px; height: 19px; }
.bar-btn svg[hidden] { display: none !important; }
.bar-btn.is-off { opacity: .35; pointer-events: none; }
.bar-btn.listening, .bar-btn.locked { color: var(--ink); }
#btn-listen { grid-area: 2 / 2; }
#btn-listen svg { flex: none; }
.listen-reference {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
}
.dock-listen {
  position: absolute;
  left: 0;
  bottom: calc(100% + 8px);
  display: grid;
  grid-template-columns: repeat(4, 40px);
  grid-template-rows: 42px 40px;
  gap: 8px;
  width: 184px;
}
.dock-listen .bar-btn {
  color: var(--accent);
  width: 40px;
  min-width: 40px;
  height: 40px;
  pointer-events: auto;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-float);
}
.chip.listen-location {
  grid-area: 1 / 1 / 2 / -1;
  justify-self: start;
  width: max-content;
  max-width: calc(100vw - var(--chrome-inset-left) - var(--chrome-inset-right));
  gap: 8px;
  padding: 0 12px;
  font: inherit;
}
.listen-location svg { flex: none; }
#btn-listen-prev { grid-area: 2 / 1; }
#btn-listen-next { grid-area: 2 / 3; }
#btn-listen-lock { grid-area: 2 / 4; }
.bar-btn, .chip { position: relative; }
/* Fixed widths so the capsule never resizes: the abbr fits "WLC", the
   reference fits the widest possible text ("Song of Solomon 8:14", 158px in
   SF Pro at 15px/600) with slack for wider platform fonts. */
.bar-btn.abbr { width: 60px; font-size: 13px; font-weight: 700; letter-spacing: .05em; }
.bar-btn.ref {
  padding: 0 14px;
  width: 192px;
  max-width: calc(100vw - 160px);   /* very narrow screens: ellipsis instead of overflow */
  color: var(--ink);
}
.bar-btn.ref #ref-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-sep { width: 1px; height: 18px; margin: 0 3px; background: var(--hairline); flex: none; }
.bar-sep.sep-h { width: 18px; height: 1px; margin: 3px 0; }

/* top row: the nav capsule sits far left; the location pill is its own
   capsule, dead-centered on wide screens and right-aligned on narrow ones
   (an absolute center would collide with the nav cluster there). */
.chrome-top {
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  /* The reference is absolutely positioned on wide screens and while locked.
     Keep its row when narration hides the navigation capsule. */
  min-height: 46px;
  left: var(--chrome-inset-left); right: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
@media (min-width: 560px) {
  .bar-ref { position: absolute; top: 0; left: 50%; transform: translateX(-50%); }
}

/* right column: the stepper capsule, vertically centered */
.chrome-right {
  top: 50svh;
  transform: translateY(-50%);
  right: var(--chrome-inset-right);
  width: max-content;   /* the capsule's own width, so its right edge IS this
                           column's — the keynav HUD aligns to the same 10px */
  display: flex;
  flex-direction: column;
  align-items: center;
}
.bar.bar-v { flex-direction: column; }

/* bottom-left dock, bookmark pins floating above it */
.chrome-bottom {
  min-height: 46px;
  left: var(--chrome-inset-left);
  right: var(--chrome-inset-right);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  display: flex;
  align-items: flex-end;
  gap: 8px;
  overflow: visible;   /* hover tips sit past play/lock, not clipped to a capsule */
}
.chrome-bottom > .dock:not(.dock-listen) { flex: none; }
.chrome-marks {
  left: var(--chrome-inset-left);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px + 46px + 8px + 90px + 8px);
  display: flex;
  flex-direction: column-reverse;   /* red sits nearest the dock, like the app */
  gap: 8px;
}
html.no-listen .chrome-marks {
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px + 46px + 8px);
}
@media (max-width: 699px) {
  .chrome-bottom > .dock:not(.dock-listen) { gap: 0; }
  .chrome-bottom > .dock:not(.dock-listen) .bar-btn { min-width: 32px; width: 32px; }
}

/* desktop-only keyboard shortcuts, same glass as the dock, bottom-right */
.chrome-help { display: none; }
@media (min-width: 700px) {
  .chrome-help {
    display: block;
    right: var(--chrome-inset-right);
    bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  }
  .chrome-help .bar-btn {
    font-size: 20px;
    font-weight: 500;
    line-height: 1;
  }
}

/* The floating chip: JS-made buttons outside the capsules (bookmark pin). */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-float);
  color: var(--accent);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: box-shadow .15s ease, opacity .25s var(--ease-out);   /* opacity: the chrome fade */
}
@media (hover: hover) and (pointer: fine) {
  .chip:hover { box-shadow: var(--shadow-lift); }
}
.chip > * { transition: transform .12s ease; }
@media (hover: hover) and (pointer: fine) {
  .chip:active > * { transform: scale(.94); }
}
.chip.icon svg { width: 20px; height: 20px; }

html.listen-locked { overscroll-behavior: none; }
/* Follow-lock owns the page — hide every control that would navigate or
   open a pane. Pause, unlock, and the location pill stay. The pill is
   not tappable (see `#btn-ref` below and `openBooks`). */
html.listen-locked .chrome-top .bar-nav,
html.listen-locked .chrome-right,
html.listen-locked .chrome-marks,
html.listen-locked .chrome-help,
html.listen-locked .dock:not(.dock-listen) {
  display: none !important;
}
html.listen-locked .chrome-top { justify-content: center; }
html.listen-locked .bar-ref {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
}
html.listen-locked #btn-ref { cursor: default; }
html.listen-locked #btn-ref:hover { background: transparent; }
@media (hover: hover) and (pointer: fine) {
  html.listen-locked #btn-ref:active > * { transform: none; }
}

/* ---- reading column ------------------------------------------------------ */
.bk {
  position: relative;       /* anchors the highlight band layer */
  isolation: isolate;       /* keeps the negative-z layer above the page bg */
  /* Twelve equal stops from min(480px, 60%) to the page. --reader-width-t
     is 0–1 (index / 11), set from JS; 3/11 ≈ today's 744px on a 1512 laptop.
     The gutter lerps on the same t (see :root), so the measure grows by
     one twelfth of (page − floor) at every notch. */
  --reader-width-min: min(480px, 60%);
  max-width: calc(var(--reader-width-min) + (100% - var(--reader-width-min)) * var(--reader-width-t));
  margin-inline: auto;
  /* No side padding here: the gutter belongs to the paragraphs (below). The
     text lands in exactly the same place either way, but a line's box then
     reaches the edge of the column, so a drag begun in the margin beside a
     line grabs that line's first or last word instead of missing the text
     entirely. Starting a selection at the outside edge is the fiddliest thing
     to do on a phone; this is what makes it forgiving. */
  padding: calc(var(--top-inset) + env(safe-area-inset-top, 0px)) 0
           calc(var(--bottom-inset) + env(safe-area-inset-bottom, 0px));
  font-family: var(--reader-font, var(--serif));   /* typography settings */
  font-size: var(--body);
  line-height: var(--leading);
  color: var(--ink);
  overflow-wrap: break-word;
  /* The reader does its own selecting (wordbar.js), so the browser's is off
     over the column: no iOS magnifier, no blue handles, no Copy/Look Up
     callout on top of the word bar, and no half-selection when a drag starts
     out in the margin. The gray band you see IS the selection. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
/* :where() keeps this at zero extra specificity, so the hanging-indent rules
   below (.vl, .s-q1…4) still win on the start side and only inherit the
   gutter on the end side. */
.bk > :where(p, .bk-title) {
  padding-inline-start: var(--gutter);
  padding-inline-end: var(--gutter-end, var(--gutter));
}
.bk[dir="rtl"] { text-align: right; }

.bk p { margin: 0; }
.bk > p:first-of-type { margin-top: 0 !important; }

/* The book's title page-head: big centered serif over a short accent rule.
   Same gap above the rule as below it, so the rule sits in the middle of
   the air between the name and the first verse. (Those used to be 0.45L
   and 1.1L; the sum is unchanged.) */
.bk-title {
  font-family: var(--reader-font, var(--serif));   /* follows the reading face */
  font-weight: 600;
  font-size: calc(var(--body) * 1.9);
  line-height: 1.2;
  text-align: center;
  color: var(--ink);
  letter-spacing: .01em;
  --rule-gap: calc(var(--leading) * 0.775);
  margin: 0 0 var(--rule-gap);
}
.bk-title::after {
  content: "";
  display: block;
  width: 44px;
  height: 2px;
  border-radius: 1px;
  margin: var(--rule-gap) auto 0;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
}

/* Paragraph styles (Typesetter.paragraph): prose indents each first line
   except the chapter's opener; poetry hangs deeper per level; m/d flush. */
.s-p { text-indent: calc(var(--body) * 1.2); }
.s-p.ch-open, .s-p.bk-open { text-indent: 0; }
.s-q1 { padding-inline-start: calc(var(--gutter) + var(--body) * 2.5);  text-indent: calc(var(--body) * -1.4); }
.s-q2 { padding-inline-start: calc(var(--gutter) + var(--body) * 3.4);  text-indent: calc(var(--body) * -1.4); }
.s-q3 { padding-inline-start: calc(var(--gutter) + var(--body) * 4.3);  text-indent: calc(var(--body) * -1.4); }
.s-q4 { padding-inline-start: calc(var(--gutter) + var(--body) * 5.2);  text-indent: calc(var(--body) * -1.4); }
.s-d { font-style: italic; color: color-mix(in srgb, var(--ink) 70%, transparent); }

/* Space above: chapter break .85 leading, poetry stanza .5 — book open none. */
.brk-ch { margin-top: calc(var(--leading) * .85); }
.brk-st { margin-top: calc(var(--leading) * .5); }

/* Verse-per-line layout: flush lines with a hanging indent, .15 leading
   between verses, .7 at a chapter break or before a heading. */
.vl { padding-inline-start: calc(var(--gutter) + var(--body) * 1.2); text-indent: calc(var(--body) * -1.2); margin-top: calc(var(--leading) * .15); }
.vl.brk-ch { margin-top: calc(var(--leading) * .7); }
.vl-h { margin-top: calc(var(--leading) * .7); font-style: italic; color: color-mix(in srgb, var(--ink) 70%, transparent); }

/* Chapter number: 1.35× bold accent leading the chapter's first verse.
   line-height: 1 keeps the inline-block's own box shorter than the body
   strut's rise, so the numeral overflows its box instead of growing the
   chapter's first line box (the same even-rhythm rule as .vn). */
.cn {
  font-weight: 700;
  font-size: calc(var(--body) * 1.35);
  line-height: 1;
  color: var(--accent);
  text-indent: 0;
  display: inline-block; /* keeps a prose first-line indent off the number */
}
/* Verse number: small raised accent semibold. line-height: 0 keeps it out of
   the line box — the leading is a fixed LENGTH, so a .62em run gets a bigger
   half-leading than the body strut and would hang 3.5px below it, growing
   every verse's first line and breaking the even row rhythm. The glyph keeps
   its baseline (and its raise), only its empty box goes. */
.vn {
  font-weight: 600;
  font-size: calc(var(--body) * .62);
  line-height: 0;
  color: color-mix(in srgb, var(--accent) 80%, transparent);
  position: relative;
  top: calc(var(--body) * -.34);
}
/* Footnote marker: raised accent ⓘ, glued to its word by a narrow NBSP. */
.fnm {
  font-family: var(--reader-font, var(--serif));   /* follows the reading face */
  font-weight: 700;
  font-size: calc(var(--body) * .7);
  color: var(--accent);
  position: relative;
  top: calc(var(--body) * -.34);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

.credit {
  text-align: center;
  font-style: italic;
  font-size: calc(var(--body) * .72);
  color: color-mix(in srgb, var(--accent) 50%, transparent);
  margin-top: calc(var(--leading) * 1.5);
}

/* ---- overlays / sheets ---------------------------------------------------
   Compact sheets (word lookup): mobile bottom sheet with a grab handle;
   700px+ a centered dialog. Panes (notes, chat, search, …): full page
   below 900px, right-edge dock above. Exits stay under panels.js's 260ms
   teardown. */
.scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(20, 14, 8, .3);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .22s ease;
  touch-action: none;            /* a pan on the dimmer must not move the page */
}
.scrim.show { opacity: 1; }

/* Covering sheets (mobile full-page pane, compact bottom sheet, centered
   dialog): the scripture must not move. html.covering is toggled from
   panels.js syncCovering. */
html.covering, html.covering body {
  overflow: hidden;
  overscroll-behavior: none;
}

.sheet {
  position: fixed; z-index: 41;
  left: 0; right: 0; bottom: 0;
  margin-inline: auto;
  max-width: 560px;
  max-height: min(80dvh, 640px);
  display: flex;
  flex-direction: column;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-bottom: 0;
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -18px 60px -14px var(--shadow);
  transform: translateY(102%);
  transition: transform .26s var(--ease-out);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* none, not translateY(0): a transform containing-block makes iOS draw the
   contenteditable caret below the glyphs in the note editor. */
.sheet.show { transform: none; }
.sheet::before {
  content: "";
  align-self: center;
  flex: none;
  width: 36px; height: 4px;
  margin: 8px 0 0;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
}
@media (min-width: 700px) {
  .sheet {
    left: 50%; right: auto; bottom: auto; top: 50%;
    width: min(560px, calc(100vw - 48px));
    max-height: min(76dvh, 660px);
    border-bottom: 1px solid var(--hairline);
    border-radius: 22px;
    box-shadow: 0 24px 80px -20px var(--shadow);
    transform: translate(-50%, -50%) scale(.97);
    opacity: 0;
    transition: transform .22s var(--ease-out), opacity .18s ease;
    padding-bottom: 0;
  }
  .sheet.show { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .sheet::before { display: none; }
}

/* Mobile panes are a normal full page, pinned to the visual viewport
   (`--vv-top` / `--vv-height`). That keeps Done on screen and the
   format bar / composer on the keys as the keyboard opens. Do not
   `inset: 0` (layout-sized) — iOS pans the visual viewport to the
   caret and the header disappears. Word lookup stays a compact sheet. */
@media (max-width: 899.98px) {
  html.page-pane {
    height: 100%;
    background: var(--paper-2);
  }
  html.page-pane body {
    position: relative;
    height: 100%;
    overflow: hidden;
    background: var(--paper-2);
  }
  html.page-pane #book,
  html.page-pane #chrome {
    visibility: hidden;
  }
  .sheet.pane {
    position: absolute;
    top: var(--vv-top, 0px);
    right: 0;
    bottom: auto;
    left: 0;
    width: 100%;
    max-width: none;
    height: var(--vv-height, 100%);
    max-height: none;
    margin: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: var(--paper-2);
    padding-top: env(safe-area-inset-top, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    transform: none;
    opacity: 0;
    transition: opacity .2s ease;
  }
  .sheet.pane.show { transform: none; opacity: 1; }
  .sheet.pane::before { display: none; }
  .sheet.pane .sheet-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--paper-2);
  }
}

.sheet-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 12px 18px 10px;
  border-bottom: 1px solid var(--line);
}
.sheet-title {
  flex: 1;
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sheet-btn {
  border: 0; background: none; cursor: pointer;
  color: var(--accent); font-size: 15px; font-weight: 600;
  padding: 6px 10px; border-radius: var(--radius-pill);
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease;
}
.sheet-btn:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.sheet-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  padding: 6px 18px 18px;
}
.sheet-body a { color: var(--accent); text-underline-offset: 2px; }
/* The note editor is the section: no inset card, just the writing surface
   from the head's hairline down to the format bar. Overflow lives on
   `.ne-scroll`, not the contenteditable — iOS will not pan overflow on
   the editable root, which is why a long note used to clip. */
.sheet-body:has(.ne) {
  position: relative;
  display: flex;
  flex-direction: column;
  padding-top: 0;
  padding-bottom: 0;
  overflow: hidden;
}
.ne-scroll {
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}
.sheet-body:has(.ne) > .ne,
.sheet-body:has(.ne) .ne {
  flex: none;
  min-height: 100%;
  overflow: visible;
  resize: none;
}

.section-label {
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin: 18px 2px 8px;
}

.settings-tabs {
  flex-wrap: nowrap;
  margin: 8px 18px 10px;
  flex: none;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.settings-tabs::-webkit-scrollbar { display: none; }
.settings-tabs button { flex: 0 0 auto; white-space: nowrap; }
/* Desktop side pane is 420–480px. Five nowrap labels (Text … Account)
   overflow that strip; the default flex min-width:auto then grows the
   tab bar past the pane and `.sheet { overflow: hidden }` shears the
   last glyphs. Constrain the row so overflow-x actually scrolls, and
   tighten the chips so they fit the 1280px pane (~435px) without
   cutting "Account". Phone keeps the rules above (Reed). */
@media (min-width: 900px) {
  .sheet.side .settings-tabs {
    min-width: 0;
    gap: 2px;
    padding-inline: 3px;
    scroll-padding-inline: 3px;
  }
  .sheet.side .settings-tabs button {
    padding-inline: 6px;
    font-size: 13px;
  }
}
.settings-panel[hidden] { display: none !important; }
.settings-panel > .section-label:first-child { margin-top: 8px; }
.settings-panel > .seg { margin: 4px 0 8px; }
.settings-panel > .type-slider-row:first-child { padding-top: 12px; }

/* Account fills the settings body so the version sits on that tab's floor —
   not a sheet footer on Text / Appearance / Narration / Translations. */
.sheet-body:has(#settings-account:not([hidden])) {
  display: flex;
  flex-direction: column;
}
#settings-account:not([hidden]) {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

/* Quiet About-style mark: centered `X.Y.Z (BUILD)`, system sans, muted ink. */
.settings-version {
  margin-top: auto;
  text-align: center;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 400;
  color: color-mix(in srgb, var(--ink) 42%, transparent);
  padding: 24px 8px 8px;
}

.credit-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 2px 14px;
}
.credit-card + .credit-card { border-top: 1px solid var(--line); }
.credit-title { font-size: 16px; color: var(--ink); }
.credit-detail {
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.4;
}
.credit-source {
  font-size: 12px;
  color: color-mix(in srgb, var(--ink-soft) 80%, transparent);
}
.credit-links { display: flex; flex-wrap: wrap; gap: 12px; }
.credit-links a {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
}
.credit-license {
  margin: 8px 2px 16px;
  font-size: 11px;
  color: color-mix(in srgb, var(--ink-soft) 70%, transparent);
  text-align: center;
  line-height: 1.45;
}

/* ---- shortcuts pane ------------------------------------------------------- */
.sc-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px;
  padding: 10px 2px;
}
.sc-row + .sc-row,
.sc-books + .sc-row,
.sc-row + .sc-books { border-top: 1px solid var(--line); }
.sc-label {
  font-family: var(--serif); font-size: 16px; color: var(--ink);
}
.sc-row.sc-prose .sc-label { white-space: normal; }
.sc-keys {
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: 6px; flex: none;
}
.sc-keys kbd {
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.sc-books { border-top: none; }
.sc-books > summary {
  list-style: none;
  cursor: pointer;
}
.sc-books > summary:focus,
.sc-books > summary:focus-visible { outline: none; }
.sc-books > summary::-webkit-details-marker { display: none; }
.sc-chevron {
  flex: none;
  width: 8px; height: 8px;
  margin-left: auto;
  border-right: 1.5px solid var(--ink-soft);
  border-bottom: 1.5px solid var(--ink-soft);
  transform: rotate(45deg) translateY(-2px);
}
.sc-books[open] > summary .sc-chevron {
  transform: rotate(225deg) translateY(-1px);
}
.sc-book-list { padding: 2px 0 6px; }
.sc-book-list .sc-book { padding-left: 8px; }

/* settings rows */
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 2px;
  color: var(--ink);
  font-size: 16px;
}
.row + .row { border-top: 1px solid var(--line); }
.row .grow { flex: 1; }
.row .sub { font-size: 13px; color: var(--ink-soft); }

/* toggle switch */
.tgl { position: relative; width: 50px; height: 30px; flex: none; }
.tgl input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.tgl .knob {
  position: absolute; inset: 0;
  border-radius: 15px;
  background: color-mix(in srgb, var(--ink) 14%, transparent);
  transition: background .18s ease;
  pointer-events: none;
}
.tgl .knob::after {
  content: "";
  position: absolute; top: 3px; left: 3px;
  width: 24px; height: 24px; border-radius: 12px;
  background: var(--paper-2);
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
  transition: transform .18s var(--ease-out);
}
.tgl input:checked + .knob { background: var(--accent); }
.tgl input:checked + .knob::after { transform: translateX(20px); }

/* segmented control (appearance) */
.seg {
  display: flex; gap: 4px;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  border-radius: var(--radius-pill); padding: 3px;
}
.seg button {
  flex: 1; border: 0; background: none; cursor: pointer;
  padding: 7px 10px; border-radius: var(--radius-pill);
  font-size: 14px; font-weight: 600; color: var(--ink-soft);
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease, color .15s ease;
}
.seg button.on { background: var(--paper-2); color: var(--ink); box-shadow: 0 1px 3px var(--shadow); }

/* navigator */
.nav-book {
  display: flex; align-items: baseline; gap: 10px;
  width: 100%; text-align: start;
  border: 0; background: none; cursor: pointer;
  padding: 11px 10px;
  font-family: var(--serif); font-size: 18px; color: var(--ink);
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
  border-radius: 12px;
}
/* Every row carries its own rule, the first of a testament included — the
   section label sits above the line, like a heading over a table. */
.nav-book { border-top: 1px solid var(--line); }
.nav-book:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.nav-book.open { color: var(--accent); }
/* Keyboard cursor — the same wash a hover uses, so a tap and an arrow
   land on one highlight. `.open` stays the expanded book's ink. */
.nav-book.selected {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
/* The keystrokes that reach this book, parked on the far right — the list is
   where the type-to-navigate mapping is learned. */
.nav-book .kbd {
  margin-inline-start: auto;
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--ink-soft) 70%, transparent);
}
.nav-book.open .kbd, .nav-book:hover .kbd, .nav-book.selected .kbd { color: var(--ink-soft); }

/* the in-place expansion under a book row: chapters, then verses below —
   the picked chapter stays lit while its verses are open */
.nav-expand { padding: 2px 0 16px; }
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 8px;
  padding-top: 10px;
}
.grid button {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--paper);
  border-radius: 12px;
  padding: 12px 0;
  font-size: 16px; font-weight: 600; color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease, border-color .12s ease, transform .1s ease;
}
/* Hover/focus/active must not paint a fill — that reads as a second,
   off-color selection next to .on / .selected. */
.grid button:hover,
.grid button:active {
  background: var(--paper);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.grid button:active { transform: scale(.96); }
@media (pointer: coarse) {
  .grid button:active { transform: none; }
}
.grid button.on,
.grid button.on:hover,
.grid button.on:active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

/* translation menu: drops from the nav capsule at the far left */
.menu {
  position: fixed; z-index: 41;
  top: calc(env(safe-area-inset-top, 0px) + 10px + 44px + 8px);
  left: 12px;
  min-width: 270px;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lift);
  padding: 6px;
  transform-origin: top left;
  transform: scale(.95); opacity: 0;
  transition: transform .16s var(--ease-out), opacity .14s ease;
}
.menu.show { transform: scale(1); opacity: 1; }
.menu button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: start;
  border: 0; background: none; cursor: pointer;
  padding: 11px 12px; border-radius: 12px;
  color: var(--ink); font-size: 15px;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
}
.menu button:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.menu .m-abbr { font-size: 12px; font-weight: 700; color: var(--accent); min-width: 52px; }
.menu .m-check { margin-inline-start: auto; color: var(--accent); font-weight: 700; }

/* footnote card */
.fn-card {
  position: fixed; z-index: 41;
  left: 12px; right: 12px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
  margin-inline: auto;
  max-width: 480px;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lift);
  padding: 14px 16px;
  transform: translateY(10px); opacity: 0;
  transition: transform .2s var(--ease-out), opacity .16s ease;
}
.fn-card.show { transform: none; opacity: 1; }
.fn-card .fn-anchor {
  font-family: var(--serif); font-style: italic; font-weight: 600;
  color: var(--accent); font-size: 15px; margin: 0 0 4px;
}
.fn-card .fn-note { font-family: var(--serif); color: var(--ink); font-size: 16px; line-height: 1.5; margin: 0; }

/* ---- highlights ----------------------------------------------------------
   The iOS tints: a light wash over cream paper, deeper muted tones over the
   sepia dark. ::highlight inherits custom properties from the text. */
:root {
  --hl-red: #F3B0A8; --hl-orange: #F7C99A; --hl-yellow: #F2DE7E;
  --hl-green: #B9DE9F; --hl-blue: #A6CBEE; --hl-indigo: #AEABE6; --hl-violet: #D7ADE6;
}
html[data-theme="dark"] {
  --hl-red: #6B3832; --hl-orange: #6E4828; --hl-yellow: #675824;
  --hl-green: #3C5731; --hl-blue: #304D6B; --hl-indigo: #3B3769; --hl-violet: #573761;
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme="light"]) {
    --hl-red: #6B3832; --hl-orange: #6E4828; --hl-yellow: #675824;
    --hl-green: #3C5731; --hl-blue: #304D6B; --hl-indigo: #3B3769; --hl-violet: #573761;
  }
}
/* The band layers sit behind the text inside the isolated reading column:
   one rect per highlighted line, every rect the same height (annotate.js).
   .sel-layer holds the gray selection preview, painted over .hl-layer. */
.hl-layer, .sel-layer, .spoken-layer {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.hl-band { position: absolute; border-radius: 4px; }

/* Selecting scripture previews the exact band a highlight would paint, in a
   neutral gray (annotate.js paintSelection). The native selection wash would
   notch around raised numbers underneath it, so the column suppresses it. */
#book ::selection { background: transparent; }
.hl-sel { background: color-mix(in srgb, var(--ink) 20%, transparent); }
/* Narrator: underline the spoken word, not a wash (washes fight highlights).
   Paint with a background-image, not inset box-shadow: iOS WebKit skips
   inset shadows on a transparent band, which made the underline vanish
   on phone while desktop still showed it. */
.hl-spoken {
  background-color: transparent;
  background-image: linear-gradient(var(--ink), var(--ink));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 2px;
  border-radius: 0;
  box-shadow: none;
}

/* ---- word-actions bar -----------------------------------------------------
   Same 46px capsule as the bottom-left dock (4px pad + 36px buttons + 1px
   borders), whether a side pane is open or not. Centered in the viewport
   with the reader; a pane parks it just left of the sheet instead. */
.wordbar {
  position: fixed; z-index: 35;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  display: flex; align-items: center; gap: 6px;
  height: 46px;
  box-sizing: border-box;
  padding: 4px 8px;
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-float);
  max-width: calc(100vw - 24px);
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.wordbar::-webkit-scrollbar { display: none; }
.hl-chip {
  width: 28px; height: 28px;
  border-radius: 14px;
  border: 1px solid rgba(0, 0, 0, .12);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .1s ease, box-shadow .12s ease;
}
.hl-chip:hover { transform: scale(1.12); box-shadow: 0 2px 6px var(--shadow); }
.hl-chip:active { transform: scale(.92); }
/* The pale band colors. Pickers and list dots override this from JS with the
   full-strength slot color (annotate.js slotColor) — a band has words on it,
   a dot has to be recognisable at 14px. */
.hl-red { background: var(--hl-red); } .hl-orange { background: var(--hl-orange); }
.hl-yellow { background: var(--hl-yellow); } .hl-green { background: var(--hl-green); }
.hl-blue { background: var(--hl-blue); } .hl-indigo { background: var(--hl-indigo); }
.hl-violet { background: var(--hl-violet); }
.wordbar-action {
  border: 0; background: none; cursor: pointer;
  color: var(--accent); font-size: 14px; font-weight: 600;
  height: 36px;
  padding: 0 10px;
  flex: none;
  white-space: nowrap;
  border-radius: var(--radius-pill);
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
}
.wordbar-action:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }

.def-pos { margin-top: 16px; }
.sheet-body > .def-pos:first-child { margin-top: 8px; }
.def-list { margin: 0 0 4px; padding-left: 1.35em; }
.def-list li {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 10px;
}
.def-example {
  display: block;
  font-style: italic;
  color: var(--ink-soft);
  margin-top: 4px;
}
.def-status, .def-empty {
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.5;
  margin: 12px 2px;
}
.def-status { color: var(--ink-soft); }
.def-empty { color: var(--ink); }
.def-source {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 16px 2px 4px;
}

/* ---- original-text sheet ------------------------------------------------- */
.orig-summary {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-radius: 10px;
  padding: 14px;
  margin: 8px 0 16px;
}
.orig-cap {
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin: 12px 0 4px;
}
.orig-cap:first-child { margin-top: 0; }
.orig-selected {
  font-family: var(--serif); font-size: 18px; color: var(--ink); line-height: 1.4;
}
.orig-script {
  font-family: Cardo, var(--serif);
  font-size: 26px; color: var(--ink); line-height: 1.35;
}
.orig-script.rtl, .orig-word-surface.rtl { direction: rtl; unicode-bidi: isolate; }
.orig-translit {
  font-family: var(--serif); font-style: italic; font-size: 15px;
  color: color-mix(in srgb, var(--ink) 60%, transparent); line-height: 1.4;
}
.orig-word {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border-radius: 10px;
  padding: 12px 14px;
  margin: 10px 0;
}
.orig-word-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.orig-word-surface { font-family: Cardo, var(--serif); font-size: 23px; color: var(--ink); }
.orig-word-translit {
  font-family: var(--serif); font-style: italic; font-size: 14px;
  color: color-mix(in srgb, var(--ink) 55%, transparent);
}
.orig-word-meaning {
  font-family: var(--serif); font-size: 15px; color: var(--ink);
  margin-top: 8px; line-height: 1.45;
}
.orig-word-root { font-family: var(--serif); font-size: 13px; color: var(--accent); margin-top: 5px; }
.orig-word.orig-uses {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.orig-word.orig-uses:hover { background: color-mix(in srgb, var(--accent) 11%, transparent); }
.orig-selected.orig-uses, .orig-script.orig-uses { cursor: pointer; }
.orig-selected.orig-uses:hover, .orig-script.orig-uses:hover,
.orig-word.orig-uses:hover .orig-word-surface { color: var(--accent); }
.orig-uses-hint {
  font-family: var(--serif); font-size: 12px; font-weight: 600;
  color: var(--accent); margin-left: 4px;
}
.uses-head { margin: 4px 2px 12px; }
.uses-sub {
  font-family: var(--serif); font-size: 14px;
  color: color-mix(in srgb, var(--ink) 55%, transparent); margin-bottom: 4px;
}
.uses-count {
  font-family: var(--serif); font-size: 15px; color: var(--ink); margin-bottom: 6px;
}
.uses-def {
  font-family: var(--serif); font-size: 14px; color: var(--ink-soft);
  line-height: 1.45; margin: 0 0 4px;
}
.uses-foot { margin-top: 8px; }
.uses-more {
  font-family: var(--serif);
  font-style: italic;
  font-size: 13px;
  color: var(--ink-soft);
  text-align: center;
  margin: 12px 8px 4px;
  min-height: 1px;
}
.uses-more.is-loading { min-height: 2.4em; }
.orig-note {
  font-family: var(--serif); font-style: italic; font-size: 13px;
  color: var(--ink-soft); line-height: 1.45; margin: 12px 2px;
}
.orig-status {
  font-family: var(--serif); font-size: 16px; color: var(--ink-soft);
  text-align: center; line-height: 1.5; margin: 18px 8px;
}
.uses-searching {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.uses-wave {
  display: block;
  width: 88px;
  height: 22px;
  overflow: hidden;
  color: var(--ink-soft);
}
.uses-wave svg {
  display: block;
  width: 176px;
  height: 22px;
  animation: uses-wave-shift 1.15s linear infinite;
}
.uses-search-label { font-family: var(--serif); }
.uses-dots span {
  display: inline-block;
  animation: uses-dot 1.2s ease-in-out infinite;
  opacity: .2;
}
.uses-dots span:nth-child(2) { animation-delay: .2s; }
.uses-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes uses-wave-shift {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@keyframes uses-dot {
  0%, 80%, 100% { opacity: .2; }
  40% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .uses-wave svg, .uses-dots span { animation: none; }
  .uses-dots span { opacity: 1; }
}
.sheet-body > .orig-status + .gate-submit { margin-top: 14px; width: 100%; }

/* ---- inline note markers -------------------------------------------------- */
.notem {
  border: 0; background: none; cursor: pointer;   /* padding below, shared with .bkm */
  color: var(--accent);
  vertical-align: baseline;
  -webkit-tap-highlight-color: transparent;
}
/* Markers and the live drop placeholder share one box so the stand-in
   is the pin the drop will become. */
.notem, .bkm, .drop-gap {
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  vertical-align: baseline;
  -webkit-appearance: none;
  appearance: none;
}
.notem svg, .bkm svg, .drop-gap svg {
  width: 1.1em; height: 1.1em;
  vertical-align: -0.18em;
}
.notem svg, .bkm svg { transition: transform .12s ease; }
.notem:hover svg, .bkm:hover svg { transform: scale(1.15); }
.mk-air {
  font-family: inherit;
  font-size: inherit;
  white-space: pre;
}
.drop-gap {
  color: var(--ink-soft);
  pointer-events: none;
}
.drop-gap svg { opacity: .55; }
.mk-keep { white-space: nowrap; }
.mk-glue { font-size: 0; line-height: 0; }
.lifting { display: none; }

/* ---- notes / highlights list rows ----------------------------------------- */
.sheet-note { color: var(--ink-soft); font-size: 15px; padding: 16px 2px; }
.note-row {
  display: flex; align-items: center; gap: 4px;
  padding: 10px 0;
}
.note-row + .note-row { border-top: 1px solid var(--line); }
.note-main {
  flex: 1; min-width: 0;
  border: 0; background: none; cursor: pointer;
  text-align: start; padding: 0;
  -webkit-tap-highlight-color: transparent;
}
.note-title {
  font-family: var(--serif); font-size: 17px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: flex; align-items: center; gap: 8px;
}
.note-sub {
  font-size: 13px; color: var(--ink-soft); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.note-date {
  font-size: 12px; color: var(--ink-soft); margin-top: 2px;
  opacity: 0.85;
}
.note-icon {
  flex: none;
  width: 34px; height: 34px;
  border: 0; background: none; cursor: pointer;
  color: var(--accent); font-size: 16px;
  border-radius: var(--radius-pill);
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
}
.note-icon:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.hl-swatch {
  display: inline-block; flex: none;
  width: 14px; height: 14px; border-radius: 7px;
  border: 1px solid rgba(0, 0, 0, .12);
}
.note-area {
  width: 100%;
  min-height: 40dvh;
  resize: vertical;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
  padding: 12px 0;
  outline: none;
  box-sizing: border-box;
}
.note-delete { color: #B4443C; }
.sheet-btn.note-delete:hover { background: color-mix(in srgb, #B4443C 10%, transparent); }
/* Delete confirmation: a card in the middle of the writing surface, not
   a Delete / Cancel swap in the sheet head. */
.note-del-mask {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: color-mix(in srgb, var(--paper) 48%, transparent);
}
.note-del-card {
  width: min(260px, 100%);
  padding: 20px 18px 16px;
  text-align: center;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lift);
}
.note-del-copy {
  margin: 0 0 16px;
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}
.note-del-actions { display: flex; justify-content: center; gap: 8px; }

/* ---- bookmark pins --------------------------------------------------------- */
.bk-btn svg { width: 20px; height: 20px; }
.bkm {
  border: 0; background: none; cursor: grab;   /* padding is the shared marker box */
  vertical-align: baseline;
  -webkit-tap-highlight-color: transparent;
}
.bk-dot {
  width: 14px; height: 14px; border-radius: 7px; flex: none;
  display: inline-block;
}

/* ---- drag ghosts / the delete target ---------------------------------------- */
/* The ghost rides exactly at the pointer — it IS the cursor while dragging. */
.drag-ghost {
  position: fixed; z-index: 70;
  transform: translate(-50%, -50%);
  pointer-events: none;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, .3));
  transition: opacity .15s ease, transform .15s var(--ease-out);
}
.drag-ghost svg { width: 26px; height: 26px; display: block; }   /* the icons carry no size of their own */
/* Over the target the ghost shrinks into it — the marker is going away. */
.drag-ghost.over-remove { opacity: .5; transform: translate(-50%, -50%) scale(.62); }
body.dragging, body.dragging * { cursor: none !important; }
.note-ghost { color: var(--accent); }

/* The delete target: an X circle beside the marker's button in the left
   column. It arrives with a small pop, and ARMS when the ghost reaches it —
   it presses in and its fill turns red, the same press the chips give — so
   the release is never a guess. */
.remove-x {
  position: fixed; z-index: 69;
  width: 42px; height: 42px;   /* a chip's size — see .chip */
  display: grid; place-items: center;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-float);
  color: var(--ink-soft);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%) scale(.5);
  transition: opacity .16s var(--ease-out), transform .18s var(--ease-out),
              background-color .15s ease, color .15s ease, box-shadow .18s var(--ease-out);
}
.remove-x.in { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.remove-x.armed {
  transform: translate(-50%, -50%) scale(.9);   /* the chips' own press */
  background: #B4443C;
  color: #fff;
  box-shadow: var(--shadow-float);
}
.remove-x svg { width: 20px; height: 20px; display: block; }   /* as .bk-btn svg */

/* Chrome down, no chip to sit beside: the X takes the dock's own corner. Same
   12px inset, and anchored from the bottom so the safe area is respected —
   which is why this case is placed here and not from JS. */
.remove-x.corner {
  left: calc(12px + 21px);   /* the dock's inset + half a chip */
  top: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  transform: translate(-50%, 0) scale(.5);
}
.remove-x.corner.in { transform: translate(-50%, 0) scale(1); }
.remove-x.corner.armed { transform: translate(-50%, 0) scale(.9); }

/* ---- chat ------------------------------------------------------------------ */
.sheet-chat:not(.pane) {
  max-height: min(92dvh, 760px);
  height: min(92dvh, 760px);
}
@media (min-width: 700px) {
  .sheet-chat:not(.pane) { max-height: min(84dvh, 760px); height: min(84dvh, 760px); }
}
.chat-scroll {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bubble {
  max-width: 88%;
  border-radius: 18px;
  padding: 10px 14px;
  font-size: 15.5px;
  line-height: 1.5;
  position: relative;
}
.bubble-copy {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  display: grid;
  place-items: center;
  cursor: pointer;
  background: color-mix(in srgb, var(--paper) 72%, transparent);
  color: var(--ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}
.bubble-copy svg { width: 14px; height: 14px; display: block; }
.bubble.user .bubble-copy {
  background: color-mix(in srgb, var(--paper) 22%, transparent);
  color: var(--paper);
}
.bubble:hover .bubble-copy {
  opacity: 1;
  pointer-events: auto;
}
.bubble.user {
  align-self: flex-end;
  border-bottom-right-radius: 6px;
  background: var(--accent);
  color: var(--paper);
  white-space: pre-wrap;
}
.bubble.assistant {
  align-self: flex-start;
  border-bottom-left-radius: 6px;
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--ink);
}
.bubble.thinking {
  background: transparent;
  padding: 4px 2px;
  border-radius: 0;
  box-shadow: none;
}
.chat-thinking {
  opacity: .55;
  font-style: italic;
  letter-spacing: 0;
  white-space: pre;
}
.chat-context {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 12.5px; font-weight: 600;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-radius: var(--radius-pill);
  padding: 5px 6px 5px 12px;
}
.chat-context-clear {
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: 16px;
  line-height: 1;
  padding: 0 6px;
  cursor: pointer;
  opacity: .7;
}
.chat-context-clear:hover { opacity: 1; }
.chat-chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 16px 8px;
  scrollbar-width: none;
}
.chat-chips::-webkit-scrollbar { display: none; }
.chat-chip {
  flex: none;
  max-width: 260px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--accent);
  border-radius: 14px;
  padding: 8px 12px;
  font-size: 13.5px;
  text-align: start;
  cursor: pointer;
  white-space: normal;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease, border-color .12s ease;
}
.chat-chip:hover { border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.chat-composer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  flex: none;
  /* Safe-area / keyboard inset lives on `.sheet-page` (`--kb`). Do not
     add a second safe-area or keyboard pad here. */
  padding: 8px 16px 12px;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.chat-input {
  flex: 1; min-width: 0;
  resize: none;
  max-height: 120px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15.5px;
  line-height: 1.4;
  padding: 10px 14px;
  outline: none;
  transition: border-color .15s ease;
}
.chat-input:focus { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.chat-send {
  width: 40px; height: 40px; flex: none;
  border: 0; border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--paper);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, opacity .15s ease;
}
.chat-send:hover { opacity: .9; }
.chat-send:active { transform: scale(.94); }
.chat-send:disabled,
.chat-send:disabled:hover {
  opacity: .35;
  cursor: default;
}
.chat-send:disabled:active { transform: none; }
.chat-send svg { width: 20px; height: 20px; }
.chat-chip:disabled {
  opacity: .45;
  cursor: default;
}
.ref-link {
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* markdown inside assistant bubbles */
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md p, .md ul, .md ol, .md blockquote, .md pre, .md .md-table { margin: 8px 0; }
.md h3, .md h4, .md h5, .md h6 { margin: 12px 0 6px; font-family: var(--serif); }
.md blockquote {
  border-inline-start: 3px solid color-mix(in srgb, var(--accent) 45%, transparent);
  padding-inline-start: 10px;
  font-family: var(--serif);
  font-style: italic;
  color: color-mix(in srgb, var(--ink) 82%, transparent);
}
.md pre {
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  border-radius: 8px;
  padding: 10px;
  overflow-x: auto;
  font-size: 13px;
}
.md code {
  font-family: ui-monospace, "Fira Code", Menlo, monospace;
  font-size: .9em;
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  border-radius: 4px;
  padding: .12em .38em;
}
.md pre code { background: none; padding: 0; font-size: inherit; }
.md ul, .md ol { padding-inline-start: 22px; }
.md li { margin: 3px 0; }
.md li.task { list-style: none; margin-inline-start: -18px; display: flex; gap: 7px; align-items: baseline; }
.md li.task input { accent-color: var(--accent); }
.md .md-table { overflow-x: auto; }
.md table { border-collapse: collapse; font-size: 14px; }
.md th, .md td { border: 1px solid var(--line); padding: 5px 9px; text-align: start; }
.md hr { border: 0; border-top: 1px solid var(--line); }
.md a { color: var(--accent); }

/* ---- account gate ---------------------------------------------------------- */
.gate {
  position: fixed; inset: 0; z-index: 60;
  background:
    radial-gradient(120% 90% at 50% 0%,
      color-mix(in srgb, var(--accent) 7%, transparent), transparent 60%),
    var(--paper);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.gate-card {
  width: 100%; max-width: 400px;
  text-align: center;
}
.gate-icon {
  width: 76px; height: 76px; border-radius: 18px;
  margin: 0 auto 18px; display: block;
  box-shadow: 0 14px 34px -12px var(--shadow);
}
.gate-title {
  font-family: var(--serif); font-size: 34px; font-weight: 600;
  color: var(--ink); margin: 0 0 8px;
}
.gate-blurb { color: var(--ink-soft); font-size: 15px; line-height: 1.5; margin: 0 0 22px; }
.gate-form { display: flex; gap: 8px; }
.gate-form[hidden] { display: none !important; }
#gate-form { flex-direction: column; width: 100%; }
.gate-input {
  flex: 1; min-width: 0;
  height: 48px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--paper-2);
  color: var(--ink);
  font-size: 16px;
  padding: 0 18px;
  outline: none;
  transition: border-color .15s ease;
}
.gate-input:focus { border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.gate-submit {
  height: 48px;
  border: 0; border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--paper);
  font-size: 15px; font-weight: 600;
  padding: 0 20px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s ease, opacity .15s ease;
}
.gate-submit:hover { opacity: .92; }
.gate-submit:active { transform: scale(.97); }
.gate-submit:disabled { opacity: .6; }
.gate-error { color: #B4443C; font-size: 14px; margin: 14px 0 0; }
.gate-error[hidden] { display: none !important; }
.gate-skip {
  margin-top: 22px;
  background: none; border: 0;
  padding: 8px 14px; border-radius: var(--radius-pill);
  color: var(--accent); font-size: 15px; font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .15s ease;
}
.gate-skip:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); }
.gate-note {
  color: var(--ink-soft); opacity: .75;
  font-size: 13px; line-height: 1.5; margin: 10px 0 0;
}

/* the account nudge reuses the footnote card + the gate's button */
.fn-card .gate-submit { margin-top: 14px; width: 100%; }

/* loading veil for the first paint */
.bk.loading { opacity: 0; }

/* Focus mode: a followed verse link keeps its ink; everything else holds
   a quarter of its alpha (ReaderViewController.focusDimFactor). Highlight
   bands sit in their own layer, so they dim with the same factor. */
.bk.focused :is(.vs, .vn, .cn, .vl-h, .bk-title, .credit) { opacity: .25; }
.bk.focused .focus-bright { opacity: 1; }
.bk.focused .hl-layer { opacity: .25; }

/* ---- type-to-navigate HUD: keystrokes echo in a floating glass pill ------ */

.keynav {
  position: fixed;
  /* bottom-right, level with the dock; its right edge lines up with the
     chapter/verse stepper capsule above it (.chrome-right) */
  bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
  right: 10px;
  z-index: 42;   /* above the sheet (41): the navigator borrows this HUD */
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 16px;
  border-radius: var(--radius-pill);
  background: var(--glass);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: var(--shadow-float), inset 0 0 0 1px var(--hairline);
  font-family: var(--sans);
  pointer-events: none;
  opacity: 0;
  transform: translateY(6px);   /* rises out of the dock corner */
  transition: opacity .25s var(--ease-out), transform .25s var(--ease-out),
              right .26s var(--ease-out);
}
.keynav.show { opacity: 1; transform: translateY(0); }
.kn-buf {
  font-size: 17px; font-weight: 700; letter-spacing: .08em;
  color: var(--ink);
  text-transform: uppercase;
}
.kn-hint { font-size: 14px; font-weight: 500; color: var(--ink-soft); }
/* Narrow screens: the dock fills the bottom row, so the HUD rides above it,
   level with the bookmark pins on the other side. */
@media (max-width: 559px) {
  .keynav { bottom: calc(env(safe-area-inset-bottom, 0px) + 12px + 46px + 8px + 90px + 8px); }
  html.no-listen .keynav { bottom: calc(env(safe-area-inset-bottom, 0px) + 12px + 46px + 8px); }
}
@media (min-width: 700px) {
  .keynav {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
    right: calc(var(--chrome-inset-right) + 46px + 8px);
  }
}
.keynav.kn-commit .kn-hint { color: var(--accent); }
.keynav.kn-miss .kn-hint { color: #B4443C; }

@media (prefers-reduced-motion: reduce) {
  .chrome .bar, .sheet, .menu, .fn-card, .bk, .keynav,
  .bar-btn, .chip,
  .drop-gap, .tgl .knob::after { transition: none; }
}

/* ==== list animations (owner: lists agent) ================================ */
/* A deleted .note-row folds shut: listfx.js pins its height inline, adds
   .row-leaving, then zeroes the height, so the rows below ride the collapse
   up instead of the whole list re-rendering. Reorders (pin/unpin) are FLIP
   transforms driven entirely from listfx.js and need no CSS here. */
.note-row.row-leaving {
  overflow: hidden;
  opacity: 0;
  transform: translateX(-16px);
  padding-top: 0; padding-bottom: 0;
  border-top-color: transparent;
  pointer-events: none;
  transition: height .24s ease, padding .24s ease, transform .24s ease,
              opacity .18s ease, border-top-color .24s ease;
}
@media (prefers-reduced-motion: reduce) {
  .note-row.row-leaving { transition: none; }
}

/* Inline delete confirmation (listfx.js confirmDelete): the ✕ swaps for a
   Delete / Cancel pair in the row itself — no browser confirm() dialog. */
.del-confirm { display: inline-flex; align-items: center; gap: 2px; }
.del-confirm button {
  border: 0; background: none; font: inherit; font-size: 13px;
  font-weight: 600; padding: 6px 8px; border-radius: 8px; cursor: pointer;
}
.del-confirm .del-yes { color: #B4443C; }
.del-confirm .del-yes:hover { background: rgba(180, 68, 60, .1); }
.del-confirm .del-no { color: var(--ink-soft); }
.del-confirm .del-no:hover { background: rgba(127, 127, 127, .12); }

/* ==== search (owner: search agent) ======================================== */
/* Search lives in the bottom-left dock with Settings / Highlights / Notes /
   Chats. Overlay: field pinned between the head and the scrolling results.
   Committed ✕-chips and the bare input share a horizontally scrolling row
   (the web's ChipBarTextField) — with few chips the input stretches, with
   many the row outgrows the box and scrolls. */
.search-field { padding: 10px 18px 4px; flex: none; }
.search-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--paper);
  padding: 5px 14px;
  cursor: text;
  transition: border-color .15s ease;
}
.search-bar::-webkit-scrollbar { display: none; }
.search-bar:focus-within {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.search-bar input {
  flex: 1;
  min-width: 80px;
  border: 0;
  outline: none;
  background: none;
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  padding: 4px 0;
}
/* One committed parameter: the term and an ✕ in a capsule. The whole chip is
   the delete button — the ✕ is the signpost, the target is generous. */
.search-chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 0;
  cursor: pointer;
  padding: 5px 9px 5px 11px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--ink);
  font-size: 14px;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.search-chip .search-chip-x {
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
}
.search-hint { padding-top: 4px; margin-top: 0; }
.search-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  margin: 8px 18px 6px;
  flex: none;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.search-tabs::-webkit-scrollbar { display: none; }
.search-tabs button {
  flex: 0 0 auto;
  border: 0;
  cursor: pointer;
  white-space: nowrap;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 7px 12px;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--ink-soft);
  font-size: 14px;
  font-weight: 600;
  -webkit-tap-highlight-color: transparent;
}
.search-tabs button.on {
  background: var(--paper-2);
  color: var(--ink);
}
.search-tabs button[hidden] { display: none !important; }
.search-tab-n {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
}
.search-tabs button.on .search-tab-n { color: var(--ink); }
.search-panel[hidden] { display: none !important; }
.search-lazy { height: 1px; pointer-events: none; }
/* A matched term inside a snippet: the selection wash, not a new color. */
.search-hit {
  font-style: normal;
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 3px;
}
/* Search rows inset their title and snippet so the keyboard-selection
   frame (.selected) sits around the text instead of sharing its edge.
   Horizontal only — .note-row already gives 10px above and below. */
.search-row { padding-inline: 12px; }
.search-row.selected {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-radius: 12px;
}

/* ==== desktop side panes (owner: panes agent) ============================= */
/* In-surface navigation: a sheet's content rides a .sheet-page, so list ↔
   detail moves swap the page (panels.js replacePage) and never the sheet —
   the docked pane stays docked, the bottom sheet stays up. The flex chain
   mirrors what the sheet gave its children directly: the page fills the
   sheet, min-height lets the body inside keep scrolling. */
.sheet-page { display: flex; flex-direction: column; flex: 1; min-height: 0; }
/* Clip children to the rounded edge. hidden, not clip: WebKit has been
   known to refuse a descendant overflow:auto the touch-scroll when an
   ancestor uses overflow:clip, so the pan falls through to the scripture. */
.sheet { overflow: hidden; }
/* The note editor's verse anchor, worn like chat's "Discussing …" pill
   (it borrows .chat-context for the look; this centers the button in the
   sheet body's block flow and strips the button chrome). */
.note-context { display: block; margin: 10px auto 4px; border: 0; cursor: pointer; padding: 5px 12px; }

/* On a wide viewport the conversational surfaces — the chat, its history
   list, the notes list, and the note editor — dock to the right edge as a
   full-height pane instead of covering, so the reading column stays open
   beside them. JS adds .side at present time (matchMedia, the same 900px);
   no scrim comes with a docked pane, so the reader stays fully live.
   Below 900px those surfaces are `.pane` full-page covers (above). Entry
   and exit slide from the right, under panels.js's 260ms teardown. */
@media (min-width: 900px) {
  :root { --pane-w: clamp(420px, 34vw, 480px); }
  .sheet.side {
    left: auto; right: 0; top: 0; bottom: 0;
    width: var(--pane-w);
    max-width: none;
    height: auto;                    /* the pinned edges size it */
    max-height: none;
    margin-inline: 0;
    border: 0;
    border-left: 1px solid var(--hairline);
    border-radius: 22px 0 0 22px;
    box-shadow: none;
    padding-top: env(safe-area-inset-top, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    opacity: 1;
    transform: translateX(102%);
    transition: transform .26s var(--ease-out);
  }
  .sheet.side.show { transform: none; }

  /* The push: while a pane is up (body.paned, kept by the same JS that adds
     .side) the reader shares the viewport with it instead of sitting under
     it. Padding on the body narrows the column's containing block, so the
     margin-inline:auto column re-centers itself in the space that remains;
     the right-anchored chrome — the stepper capsule and the header row
     whose 50% centers the reference pill — jumps by the same
     pane width. The width change is instant: interpolating it would rewrap
     the scripture every frame. The pane still slides into the vacated strip,
     and JS re-anchors the active verse (scrolls:reflow). */
  body.paned { padding-right: var(--pane-w); }
  body.paned .chrome-right { right: calc(var(--chrome-inset-right) + var(--pane-w)); }
  body.paned .chrome-top { right: calc(12px + var(--pane-w)); }
  /* Same inset as the stepper: the type-to-navigate HUD sits just left of
     the pane so "H · Highlights" never paints on top of the sheet. */
  body.paned .keynav { right: calc(var(--chrome-inset-right) + var(--pane-w)); }
  /* Same 46px capsule, parked just left of the pane so it never covers
     the dock. Six icon buttons is the widest the dock gets (search + focus). */
  body.paned .wordbar {
    left: auto;
    right: calc(var(--pane-w) + var(--chrome-inset-right));
    transform: none;
    max-width: calc(100% - var(--pane-w) - var(--chrome-inset-right)
      - var(--chrome-inset-left) - 234px - 10px);
  }
}

/* Mirrors the global reduced-motion block: these selectors outweigh it. */
@media (prefers-reduced-motion: reduce) {
  .sheet.side, .sheet.pane { transition: none; }
}

/* ==== typography settings (owner: typography agent) ======================= */
/* The settings sheet's Text section. The reading column itself consumes
   --reader-width-t / --reader-scale / --reader-font (set on :root from
   main.js's applyTypography; the reading-column rules carry the no-JS
   fallbacks), so everything here is just the sheet's controls: dotted
   sliders for width and size, and the font rows — each button is set in
   its own face, so the choice shows itself. */
.type-slider-row { flex-wrap: wrap; align-items: center; gap: 2px 12px; --thumb: 22px; --notch: 7px; }
.type-slider-label {
  flex: none; width: auto;
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.type-slider {
  --thumb: 22px;
  --notch: 7px;
  position: relative; flex: 1 1 100%; height: 36px;
}
.type-slider.has-names { height: 54px; }
.type-slider.has-captions { height: 78px; }
.type-slider.has-names input { bottom: auto; height: 36px; }
.type-slider.has-names .type-notches { top: 18px; }
.type-slider input {
  -webkit-appearance: none; appearance: none;
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; background: transparent; accent-color: transparent;
  cursor: pointer; overflow: visible;
}
.type-slider input::-webkit-slider-runnable-track {
  height: 36px; background: transparent; border: none;
}
.type-slider input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--thumb); height: var(--thumb); border-radius: 50%;
  background: color-mix(in srgb, var(--paper-2) 55%, #fff); border: none;
  box-shadow: 0 1px 3px var(--shadow), 0 4px 12px var(--shadow);
  margin-top: calc((36px - var(--thumb)) / 2);
}
.type-slider input::-moz-range-track {
  height: 36px; background: transparent; border: none;
}
.type-slider input::-moz-range-progress { background: transparent; }
.type-slider input::-moz-range-thumb {
  width: var(--thumb); height: var(--thumb); border-radius: 50%;
  background: color-mix(in srgb, var(--paper-2) 55%, #fff); border: none;
  box-shadow: 0 1px 3px var(--shadow), 0 4px 12px var(--shadow);
}
/* Dots are the track. Inset so each dot's center is where the thumb sits. */
.type-notches {
  position: absolute;
  left: calc((var(--thumb) - var(--notch)) / 2);
  right: calc((var(--thumb) - var(--notch)) / 2);
  top: 50%; transform: translateY(-50%);
  display: flex; justify-content: space-between;
  pointer-events: none;
}
.type-notch {
  width: var(--notch); height: var(--notch); border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 32%, transparent);
}
.type-slider-names {
  position: absolute;
  left: calc(var(--thumb) / 2);
  right: calc(var(--thumb) / 2);
  top: 36px;
  display: flex;
  justify-content: space-between;
  pointer-events: none;
}
.type-slider-stop {
  width: 0;
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 2px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink-soft);
}
.type-slider-name { white-space: nowrap; }
.type-slider-caption {
  font-size: 10px;
  font-weight: 500;
  text-align: center;
  white-space: normal;
  max-width: 76px;
  line-height: 1.25;
  color: inherit;
  opacity: .8;
}
.type-slider-stop.on { color: var(--ink); }
button.font-row {
  width: 100%; border: 0; background: none; cursor: pointer;
  text-align: start; font-size: 22px; font-weight: 400; line-height: 1.35;
  -webkit-tap-highlight-color: transparent;
}
button.font-row .grow { font-family: inherit; }
button.font-row:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.font-row .f-check { font-family: var(--sans); color: var(--accent); font-weight: 700; flex: none; }


/* ==== note editor (owner: editor agent) =================================== */

/* The live rich-markdown surface (noteedit.js). The contenteditable root
   is the section itself — no card, no frame — from the sheet head's
   hairline to the format bar. Everything below derives presentation
   from each line's kind + indent + inline flags, the way
   NoteMarkdown.normalize does on iOS: serif body, three heading sizes, mono
   code on a soft ground, struck-and-receded done tasks, italic quotes with
   a lead bar, full-width rule dividers, and gutter glyphs (•, numbers, task
   boxes) drawn in the lead before the text. */
.ne {
  font-family: var(--serif);
  font-size: 17px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  cursor: text;
  position: relative;
  caret-color: var(--ink);
}
.ne:focus { outline: none; }
.ne[data-empty="1"]::before {
  content: attr(data-placeholder);
  position: absolute;
  color: var(--ink-soft);
  opacity: .8;
  pointer-events: none;
}

/* Lines: one block per paragraph; depth rides a variable (18px per level,
   iOS's indentStep). */
.ne-line { position: relative; --ind: 0px; min-height: 1lh; }
.ne-line[data-indent="1"] { --ind: 18px; }
.ne-line[data-indent="2"] { --ind: 36px; }
.ne-line[data-indent="3"] { --ind: 54px; }
.ne-line[data-indent="4"] { --ind: 72px; }

.ne-line[data-kind="heading1"] { font-size: 23px; font-weight: 700; line-height: 1.35; padding: .45em 0 .1em; }
.ne-line[data-kind="heading2"] { font-size: 20px; font-weight: 600; line-height: 1.35; padding: .4em 0 .08em; }
.ne-line[data-kind="heading3"] { font-size: 18px; font-weight: 600; line-height: 1.4; padding: .35em 0 .06em; }

.ne-line[data-kind="body"] { padding-left: var(--ind); }
.ne-line[data-kind="bullet"], .ne-line[data-kind="numbered"],
.ne-line[data-kind="task"], .ne-line[data-kind="taskDone"] {
  --lead: 36px;                            /* shared text start */
  --mark-w: 28px;                          /* centered gutter; fits "10." */
  padding-left: calc(var(--lead) + var(--ind));
  text-align: start;
}
.ne-line[data-kind="quote"] {
  padding-left: calc(18px + var(--ind));   /* quoteLead */
  font-style: italic;
}

/* Gutter glyphs: one centered column so •, 1., 10., and the checkbox
   share a midpoint. The words all start at --lead — never under a
   wide number, never centered with the marker. */
.ne-line[data-kind="bullet"]::before,
.ne-line[data-kind="numbered"]::before {
  position: absolute;
  left: var(--ind);
  width: var(--mark-w);
  text-align: center;
  box-sizing: border-box;
  color: var(--accent);
}
.ne-line[data-kind="bullet"]::before { content: "•"; }
.ne-line[data-kind="numbered"]::before {
  content: attr(data-ord) ".";
  top: .14em;
  font-variant-numeric: tabular-nums;
  font-size: .85em;
}
.ne-line[data-kind="task"]::before, .ne-line[data-kind="taskDone"]::before {
  content: "";
  position: absolute;
  left: calc(var(--ind) + (var(--mark-w) - 14px) / 2);
  /* Same type as the line, so 1lh is the first line of text — not this
     glyph's own size. A smaller font here is what sat the box too high. */
  font: inherit;
  line-height: inherit;
  top: calc((1lh - 14px) / 2);
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  border: 1.5px solid var(--accent);
  border-radius: 3.5px;
  background: none;
  cursor: pointer;
}
.ne-line[data-kind="taskDone"]::before {
  background: var(--accent);
}
.ne-line[data-kind="taskDone"]::after {
  content: "";
  position: absolute;
  left: calc(var(--ind) + (var(--mark-w) - 14px) / 2);
  font: inherit;
  line-height: inherit;
  top: calc((1lh - 14px) / 2);
  width: 14px;
  height: 14px;
  background: var(--paper-2);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.8 8.2 6.6 11 12.2 4.8' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px 12px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.8 8.2 6.6 11 12.2 4.8' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px 12px no-repeat;
  pointer-events: none;
}
.ne-line[data-kind="taskDone"] {
  color: color-mix(in srgb, var(--ink) 38%, transparent);   /* marker ink */
  text-decoration: line-through;
}
.ne-line[data-kind="quote"]::before {
  content: "";
  position: absolute;
  left: calc(var(--ind) + 6px);
  top: .18em;
  bottom: .18em;
  width: 3px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 20%, transparent);
}

/* Rules: the line holds no caret (contenteditable=false) and draws itself
   as a full-width divider. */
.ne-line[data-kind="rule"] { padding: 12px 0; cursor: default; }
.ne-line[data-kind="rule"] br { display: none; }
.ne-line[data-kind="rule"]::before {
  content: "";
  display: block;
  border-top: 1px solid color-mix(in srgb, var(--ink) 28%, transparent);
}

/* Code blocks: mono on the soft ground; contiguous lines read as one block
   (rounding and breathing room only at a run's edges). */
.ne-line[data-kind="code"] {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15.5px;
  line-height: 1.5;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  padding: 0 10px;
}
.ne-line[data-kind="code"]:not(.ne-line[data-kind="code"] + .ne-line) {
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  padding-top: 6px;
  margin-top: 4px;
}
.ne-line[data-kind="code"]:not(:has(+ .ne-line[data-kind="code"])) {
  border-bottom-left-radius: 8px;
  border-bottom-right-radius: 8px;
  padding-bottom: 6px;
  margin-bottom: 4px;
}

/* Inline formatting: semantic elements only — the serializer reads these. */
.ne strong { font-weight: 700; }
.ne mark {
  background: var(--hl-yellow);   /* ::highlight:: rides the reader's yellow */
  color: inherit;
  border-radius: 3px;
  padding: 0 1px;
}
.ne .ne-u { text-decoration: underline; text-underline-offset: 2px; }
.ne code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .85em;
  background: color-mix(in srgb, var(--ink) 7%, transparent);
  border-radius: 5px;
  padding: 1px 4px;
}
.ne-line[data-kind="code"] code { background: none; padding: 0; font-size: inherit; }
.ne-link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* The [[ picker: Scripture / Note, then the same book list and chapter/verse
   grid the navigator uses. Sits above the format bar — not on the note's
   bottom hairline — so the writing surface keeps its last line clear. */
.ne-wiki {
  flex: none;
  display: flex;
  flex-direction: column;
  max-height: 260px;
  margin: 8px 0 14px;
  background: var(--paper-2);
  border: 1px solid var(--hairline);
  border-radius: 16px;
  box-shadow: var(--shadow-float);
  overflow: hidden;
}
.ne-wiki[hidden] { display: none !important; }
.ne-wiki-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--line);
}
.ne-wiki-caption {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ne-wiki-head button {
  border: 0;
  background: none;
  color: var(--accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 10px;
  border-radius: var(--radius-pill);
  -webkit-tap-highlight-color: transparent;
}
.ne-wiki-head button:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.ne-wiki-done { font-weight: 700; }
.ne-wiki-list { overflow-y: auto; overscroll-behavior: contain; padding: 0 6px 8px; }
.ne-wiki-list.grid { padding: 10px 12px 12px; }
.ne-wiki .section-label { margin: 12px 10px 4px; }
.ne-wiki .nav-book { padding: 11px 10px; }
.ne-wiki .nav-book.selected {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.ne-wiki-list.grid button.selected,
.ne-wiki-list.grid button.selected:hover,
.ne-wiki-list.grid button.selected:active,
.ne-wiki-list.grid button.selected:focus {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--paper);
}

/* The format bar — iOS's above-the-keyboard strip, worn in-pane: pinned
   under the writing surface (sticky keeps it in view while the bottom
   sheet's body scrolls; the desktop pane's flex column pins it anyway),
   scrolling horizontally where the row outgrows the width. Paper ground,
   hairline top, accent glyphs; an active tool fills, iOS-style. */
.ne-bar {
  position: sticky;
  bottom: 0;
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 0 -18px;                  /* full-bleed; the note meets this line */
  padding: 6px 12px;
  background: var(--paper-2);
  border-top: 1px solid color-mix(in srgb, var(--accent) 12%, transparent);
  overflow-x: auto;
  scrollbar-width: none;
}
.ne-bar::-webkit-scrollbar { display: none; }
.ne-tool {
  flex: none;
  width: 38px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--accent);
  border-radius: 9px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
}
.ne-tool:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.ne-tool:disabled { opacity: .35; pointer-events: none; }
.ne-tool:disabled:hover { background: none; }
.ne-tool.on { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.ne-tool svg { width: 17px; height: 17px; }
/* H1/H2/H3 wear their heading's relative size, so the row previews the
   sizes it sets. */
.ne-hbtn { font-weight: 600; font-family: var(--sans); }
.ne-hbtn1 { font-size: 15px; }
.ne-hbtn2 { font-size: 13px; }
.ne-hbtn3 { font-size: 11px; }
