/* ============================================================================
   LEMMA — STYLESHEET TABLE OF CONTENTS
   ----------------------------------------------------------------------------
   One served, service-worker-cached file (CSP forbids inline styles). Each
   section below is fronted by a matching `=== NN. TITLE ===` banner — grep the
   number or the title to jump. Sections are in document order.

    1.  FILE OVERVIEW
    2.  GLOBAL RESET HOOKS (hidden attribute + view transitions)
    3.  WEBFONTS (@font-face)
    4.  DESIGN TOKENS (:root)
    5.  BASE RESET + BODY
    6.  TYPOGRAPHY ROLE MAPPING
    7.  APP LAYOUT CONTAINER (.app)
    8.  SITE HEADER (brand, nav, OT toggle)
    9.  DATA WARNING BANNER
   10.  SEARCH FORM + EXAMPLE CHIPS
   11.  CONTENT GRID LAYOUT
   12.  RESULTS PANEL + VERSE HERO (results head, verse stats)
   13.  PUBLIC-DOMAIN ENGLISH TRANSLATION BLOCK
   14.  READING-SETTINGS DIALOG + HEADER GEAR
   15.  VERSE "ABOUT" TAB — CORPUS INSIGHTS
   16.  CROSS-REFERENCES PANEL
   17.  COMMENTARY PANEL
   18.  WORD GRID
   19.  VERSE PAGER
   20.  WORD CARD
   21.  KEYBOARD FOCUS RING
   22.  STATUS / ERRORS
   23.  LEXICON PANEL (home / verse)
   24.  ABOUT / FAQ STATIC CONTENT
   25.  SITE FOOTER
   26.  RESPONSIVE — HOME / GLOBAL @MEDIA
   27.  SSR VERSE PAGE (/v/:slug/:ch/:v) — breadcrumbs, pager, word-by-word, tabs
   28.  SSR STRONG'S PAGE (/w/:strongs) — hero, gloss history, occurrences, about
   29.  SSR CHAPTER + BOOK INDEX (/v/:slug/:ch and /v/:slug)
   30.  FOOTER ADDITIONS (builder credit + secondary links)
   31.  ABOUT / FAQ / SUPPORT CONTENT PAGES
   32.  SUPPORT PAGE (/support)
   33.  404 NOT-FOUND PAGE (/totally-bogus, unknown verses/words)
   34.  COMPARE BASKET (#197) — per-row mark toggle + cross-page tray
   ============================================================================ */

/* ============================================================================
   1. FILE OVERVIEW
   ============================================================================ */
/**
 * Lemma — styles
 * Dark scholarly theme. Original-language text uses a serif stack; UI uses
 * a system sans stack. Navy + warm gold palette matched to the brand banner
 * (public/img/og-banner.jpg — gold Λ on navy).
 */

/* ============================================================================
   2. GLOBAL RESET HOOKS (hidden attribute + view transitions)
   ============================================================================ */

/* Make the HTML `hidden` attribute always win.
   The UA stylesheet's `[hidden] { display: none }` is overridden by any author
   rule that sets `display` (e.g. `.pager { display: flex }`), so without this
   line `hide(el.pager)` from app.js would set the attribute but the element
   would stay visible — the bug that left a stale "John 1:1 · 1 of 3" pager
   visible after navigating to a single-verse search. `!important` is correct
   here: the HTML spec's `hidden` semantic should always mean "not rendered". */
[hidden] { display: none !important; }

/* View Transitions API — used ONLY for same-document content swaps fired
   from app.js (`document.startViewTransition` in `softTransition()`): the
   home-page SPA verse pager and the lexicon-body update. Cross-document
   navigation (the prev/next anchors on /v/* and /w/* pages) deliberately
   does NOT opt in — the browser-driven crossfade snapshots the old page and
   then paints white while it waits on the next document, which reads as a
   flash. The duration override below still applies to the programmatic
   transitions. Browsers without support silently fall back to instant. */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: 200ms; }
}

/* ============================================================================
   3. WEBFONTS (@font-face)
   ============================================================================ */

/* ---- Webfonts ----
   Self-hosted SIL OFL fonts in /public/fonts/. Same-origin only (the CSP
   blocks third-party font CDNs). `font-display: swap` so original-language
   text renders immediately in the system serif fallback and re-renders once
   the file arrives — never blocks first paint. See /about#sources for
   per-font attribution; the full SIL Open Font License text ships at
   /fonts/OFL.txt. */
/* Gentium — full weight ladder (400/500/600/700/800 + italic pairs). The
   family was renamed from "Gentium Book Plus" in SIL's recent release; the
   font-family string here must stay "Gentium" to match the file's internal
   name. */
@font-face {
  font-family: 'Gentium';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Gentium-Regular.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Gentium-Italic.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/Gentium-Medium.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/Gentium-MediumItalic.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/Gentium-SemiBold.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: italic;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/Gentium-SemiBoldItalic.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/Gentium-Bold.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/Gentium-BoldItalic.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/fonts/Gentium-ExtraBold.ttf') format('truetype');
}
@font-face {
  font-family: 'Gentium';
  font-style: italic;
  font-weight: 800;
  font-display: swap;
  src: url('/fonts/Gentium-ExtraBoldItalic.ttf') format('truetype');
}
/* Ezra SIL — single regular weight (the standard for biblical Hebrew display).
   SILEOTSR.ttf (SBL-reading variant with subtly different glyph forms) also
   ships in /fonts/; uncomment a second @font-face to make it available under
   a different family name if needed. */
@font-face {
  font-family: 'Ezra SIL';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/SILEOT.ttf') format('truetype');
}

/* Source Sans 3 — variable font for UI chrome (nav, headings, labels,
   buttons). `font-weight: 100 900` declares the supported weight axis range
   so CSS `font-weight: 600` resolves to a real interpolated weight. */
@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/SourceSans3-VariableFont_wght.ttf') format('truetype');
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/SourceSans3-Italic-VariableFont_wght.ttf') format('truetype');
}

/* Source Code Pro — variable monospace for Strong's numbers (H####/G####),
   URLs, and other code-like fragments. */
@font-face {
  font-family: 'Source Code Pro';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/SourceCodePro-VariableFont_wght.ttf') format('truetype');
}
@font-face {
  font-family: 'Source Code Pro';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/SourceCodePro-Italic-VariableFont_wght.ttf') format('truetype');
}

/* ============================================================================
   4. DESIGN TOKENS (:root)
   ============================================================================ */
:root {
  /* Sticky full-width app-bar height — the SINGLE source of truth for every
     sticky offset. The remaining in-page strip (.faq-pills) pins at
     top: var(--header-h), and deep-linked sections add it into their
     scroll-margin-top, so a jumped-to section clears the bar instead of hiding
     under it. (The verse page's section nav is no longer a separate strip — it
     rides inside the header band; see --subnav-h below.) Overridden smaller on
     mobile (the 760px media block). */
  --header-h: 64px;
  /* Height of the in-header section-nav SECOND ROW (.site-subnav), which exists
     only on the verse page. 0 everywhere by default; body.v-page sets the real
     row height (desktop here / mobile in the 760px block) so the combined
     header+subnav band reconciles every sticky offset:
       scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 8px).
     Compaction shrinks --header-h only; --subnav-h holds, so the offset stays
     correct without any is-scrolled override here. */
  --subnav-h: 0px;
  /* Content column width. .app defaults to the reading width; .app--wide bumps
     it for multi-panel surfaces (verse study grid, concordance / index tile
     grids) WITHOUT touching the prose measure caps (those stay 70-74ch). */
  --content-max: 1100px;
  --bg: #0a1530;
  --bg-raised: #131e3d;
  --bg-card: #1a2547;
  --border: #2a3559;
  --border-soft: #232c4d;
  --text: #e6edf3;
  --text-dim: #9aa7c4;
  /* Lightened to keep WCAG AA on every surface: 4.5:1+ on --bg-card and --bg.
     #909dbe → ~9.5:1 on --bg-card, ~12:1 on --bg. */
  --text-faint: #909dbe;
  --accent: #c8a13b;
  --accent-soft: rgba(200, 161, 59, 0.12);
  --accent-border: rgba(200, 161, 59, 0.35);
  /* Text colour placed ON a solid-gold fill (primary buttons, active tabs,
     hovered soft-gold buttons, numbered-sense markers). The single source of
     truth for the dark-on-gold inversion rule — keeps the gold accent legible
     (dark navy on gold) and lets a sibling theme retint gold in one place. */
  --on-accent: #0a1530;
  /* Patreon sign-in control (docs/patreon-login-button-spec.md §5-§6).
     These are BRAND values, deliberately outside the gold/navy token family — the
     control must read as a third-party sign-in, not as Lemma chrome. --patreon-surface
     is Patreon's current near-black CTA treatment, NOT the legacy coral: white-on-coral
     measures 3.42:1 and fails AA, and the coral would need a per-theme label swap.
     --patreon-coral is DECORATIVE ONLY (the panel's accent rule). Never put text on it. */
  --patreon-surface: #0e0e10;
  --patreon-surface-hover: #232327;
  --patreon-on-surface: #ffffff;
  --patreon-edge: #6a7080;
  --patreon-edge-hover: #8c93a3;
  --patreon-coral: #ff424d;
  /* Positive-signal tones for "Strong's 1890 agrees" confirmation badges
     and related agreement indicators. Mint green stays readable on the
     dark backgrounds and is visually distinct from the gold accent so the
     two signals don't get conflated. */
  --success: #6dba72;
  --success-soft: rgba(109, 186, 114, 0.12);
  --success-border: rgba(109, 186, 114, 0.42);
  /* Status tones. Warn (amber) + error (red) mirror the accent's
     soft-fill (10%) + 35%-alpha-border idiom so banners theme consistently;
     only the hue is non-gold. Text tones are AA on the soft fill over --bg. */
  --warn: #fde68a;
  --warn-soft: rgba(234, 179, 8, 0.1);
  --warn-border: rgba(234, 179, 8, 0.35);
  --error: #fca5a5;
  --error-soft: rgba(239, 68, 68, 0.1);
  --error-border: rgba(239, 68, 68, 0.35);
  /* Four typefaces, each scoped to a role:
       --hebrew-font  Ezra SIL — every Hebrew word (MT corpus).
       --greek-font   Gentium — every Greek word (NT + LXX). Older
                      Gentium Plus / Gentium Book Plus stay as fallbacks
                      for users with the older families installed locally.
       --reading-font Gentium — long-form English reading text (article
                      bodies, lexicon entries, verse prose). Body inherits
                      this by default; UI primitives override to --ui-font.
       --ui-font      Source Sans 3 — interface chrome (nav, headings,
                      labels, buttons, form controls).
       --mono-font    Source Code Pro — Strong's numbers (H####/G####),
                      URLs, pronunciations, morphology badges.
     All four self-hosted typefaces ship under the SIL OFL (see /about#sources). */
  --hebrew-font: 'Ezra SIL', 'SBL Hebrew', 'Times New Roman', 'Cardo', serif;
  --greek-font: 'Gentium', 'SBL Greek', 'Gentium Book Plus', 'Gentium Plus', 'Cardo', 'Times New Roman', serif;
  --reading-font: 'Gentium', 'Cardo', 'Times New Roman', Georgia, serif;
  --ui-font: 'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono-font: 'Source Code Pro', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --radius: 10px;
  --shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
}

/* ============================================================================
   5. BASE RESET + BODY
   ============================================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  /* Default to the reading typeface (Gentium). UI chrome below overrides
     to var(--ui-font); original-language word displays override per-lang. */
  font-family: var(--reading-font);
  background: radial-gradient(1200px 600px at 70% -10%, #1a3568 0%, var(--bg) 55%);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ============================================================================
   6. TYPOGRAPHY ROLE MAPPING
   ============================================================================ */

/* ---- Typography role mapping ----
   Interface chrome uses --ui-font (Source Sans 3): nav, headings, labels,
   buttons, form controls. Everything else inherits --reading-font from body
   (Gentium) so long-form English prose reads as serif throughout. */
.site-header, .site-header *,
.site-footer, .site-footer *,
.site-nav, .site-nav *,
h1, h2, h3, h4, h5, h6,
button, input, select, textarea, optgroup,
.btn, .cta, .pill, .chip, .tab, .tabbtn,
.license-tag, .pager, .pager *,
.tabbar, .tabbar *,
[role="tab"], [role="tablist"],
label, legend, fieldset,
/* /w/ Strong's-page labels + action links. These are class-based spans/anchors
   (not <label>/<button> elements), so they need explicit enrollment here to get
   the UI typeface instead of falling through to the serif reading font. */
.strongs-stat-label, .strongs-stat-usage-head,
.strongs-hero-def-label, .strongs-hero-def-more, .strongs-hero-def-share,
.lex-source-head, .lex-card-label {
  font-family: var(--ui-font);
}

/* ============================================================================
   7. APP LAYOUT CONTAINER (.app)
   ============================================================================ */
/* The full-bleed sticky header breaks out of .app via a 50vw negative margin.
   When a vertical scrollbar is present, 100vw is ~scrollbar-width wider than the
   content box, so the band overflows by that sliver. overflow-x: clip absorbs it
   so no horizontal scrollbar appears. It must be on the ROOT (html) — the
   overflow registers on the document element, so clipping body alone leaves an
   8px sliver on html. clip (unlike hidden/auto) creates no scroll container, so
   overflow-y stays auto and the viewport-relative position:sticky of the header
   and the in-page jump strips keeps working. */
html, body { overflow-x: clip; }

.app {
  max-width: var(--content-max);
  margin: 0 auto;
  /* Pad past the notch / home indicator now that viewport-fit=cover is set. */
  padding:
    0
    calc(20px + env(safe-area-inset-right))
    calc(60px + env(safe-area-inset-bottom))
    calc(20px + env(safe-area-inset-left));
}
/* Multi-panel surfaces (verse study grid, concordance / Appearances / index
   tile grids) widen the column to fill desktop space. Prose blocks inside keep
   their own ch-based caps, so only the panels/grids actually use the extra room. */
.app--wide { --content-max: 1280px; }

/* ============================================================================
   8. SITE HEADER (brand, nav, OT toggle)
   ============================================================================ */

/* ---- Header ---- */
/* Header is a 2-row layout on mobile (brand row + nav row) and one row on
   wider screens. Brand-link is an anchor so the whole brand area is clickable. */
/* Full-bleed sticky app bar. The band spans the viewport (breaks out of .app's
   max-width via the 50vw negative margins); .site-header-inner re-aligns the
   contents to the content column. On the verse page a second row (.site-subnav)
   rides INSIDE this band. z-index 25 sits ABOVE the remaining in-page strip
   (.faq-pills 5) so it tucks under the header when both pin, but BELOW popover
   menus (30) so dropdowns still cover the bar. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 25;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  margin-bottom: 8px;
  background: var(--bg);
  border-bottom: 1px solid var(--border-soft);
}
.site-header-inner {
  max-width: var(--content-max);
  min-height: var(--header-h);
  margin: 0 auto;
  /* Match .app's horizontal gutters so the bar's contents line up with the page
     content below it. No vertical padding — min-height + align-items center it. */
  padding:
    0
    calc(20px + env(safe-area-inset-right))
    0
    calc(20px + env(safe-area-inset-left));
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
}
/* The brand is the single shrinkable element; the controls stay flex-none so a
   tight width ellipsizes the wordmark instead of clipping the toggle/gear/nav. */
.site-header-inner > .brand-link { min-width: 0; }
.site-header-inner > .header-end { flex: none; }

.brand-link {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: inherit;
}
.brand-link:hover .brand-text .brand-name { color: var(--accent); }

/* New brand mark: an actual logo image (gold Λ on navy with book detail).
   Sized to match the prior CSS-rendered mark so headers don't reflow. */
.brand-mark-img {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: block;
  /* The source PNG is square with the existing gold-frame design; no extra
     border/background needed. Subtle shadow lifts it off dark backgrounds. */
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

.brand-text { min-width: 0; }
/* The wordmark. A SPAN since 2026-08-21, not an <h1>: the brand was the only
   heading on ~52,000 pages, so it is no longer a heading at all and each page
   view owns its own <h1> (views/_header.ejs carries the full reasoning).
   `display: block` is the one declaration the tag swap made load-bearing —
   overflow/text-overflow below do nothing to an inline box, and the ellipsis
   they produce is what pins the sticky bar to --header-h. Every font-size below
   is explicit at every width, so nothing here ever depended on the UA h1 size. */
.brand-text .brand-name {
  display: block;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 120ms;
}

/* NOTHING IN THE STICKY BAR MAY WRAP. --header-h is the single source of truth for
   every sticky offset in the app (the .faq-pills top, every deep-linked section's
   scroll-margin-top, the verse page's combined header+subnav band), and the bar's
   real height is `min-height: var(--header-h)` — a MINIMUM. So a child that wraps
   silently makes the bar taller than the token every one of those offsets is
   computed from, and jumped-to headings land under it.
   The tagline was the one child that could: the h1 above has carried
   nowrap/overflow/ellipsis since it was written, this <p> did not, and the brand
   column is the flex row's only shrinkable item. MEASURED on master before this
   rule existed: /  at 1024px rendered a 75.5px bar (token 64) and at 800px a
   222.5px one — the tagline on nine lines — for the whole 761-1024px band, where
   the ≤760px rule that display:none's it has not yet applied. Giving it the
   wordmark's own treatment pins the bar at exactly --header-h at every width.
   Do not "restore" the wrap to keep the full sentence legible; it is decorative
   copy, and the wordmark beside it is the brand, not a heading.

   WHAT THE ELLIPSIS COSTS, AND WHO CAUSED IT. Do not read the above as "≥1025px
   was unaffected" — it was not, and the cause is not the wrap bug. .header-end is
   `flex: none` and the page-share control grew it 657.3 -> 703.3px (a 32px toggle
   plus one 14px gap), while .site-header-inner caps at --content-max, a 1060px
   content box. The tagline needs 305px, the brand lockup 40 + 14 around it = 359,
   so `359 + column-gap + .header-end` had to come in under 1060 and at 24 + 703.3
   it was 1086 — over at EVERY width from 1024 to 1920. Measured before the reclaim
   below: 1920/1440/1280 all rendered `…with Strong's …`, the word "lexicon" gone,
   where master rendered the sentence in full on one line.
   So the ellipsis here is LOAD-BEARING from 761 to 1024px (master wrapped to 2-3
   lines in that band and inflated the bar; there is no width where the whole
   sentence fits), and the `@media (min-width: 761px)` reclaim in §8 exists
   SPECIFICALLY to buy back the ~26px the control took, so that ≥1025px reads in
   full again. Loosen that block and the truncation comes straight back at 1920px,
   silently — an ellipsis is not an error. */
.brand-text p {
  color: var(--text-dim);
  font-size: 14px;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Compact-on-scroll header (header-compact.js toggles html.is-scrolled) ----
   The sentinel is a zero-visual 1px box pinned to the document top, ABOVE the
   sticky header. It's absolutely positioned so it adds no flow height (which
   would offset the header and desync the sticky strips). It scrolls out of view
   as the user scrolls; an IntersectionObserver reads that and flips is-scrolled. */
[data-header-sentinel] {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
/* Shrink the bar when scrolled. Lowering --header-h here reconciles every sticky
   offset (.faq-pills top, deep-link scroll-margin-top) automatically — that's why
   compaction is just "smaller bar + smaller token". The verse page's in-header
   section nav (.site-subnav / --subnav-h) is NOT shrunk here: it stays visible and
   its height holds, so the combined header+subnav offset still reconciles (the
   header part gets shorter, the subnav part is unchanged). The token change is
   instant (no transition); only the visual height/logo ease. */
html.is-scrolled { --header-h: 52px; }
html.is-scrolled .brand-mark-img { width: 30px; height: 30px; }
html.is-scrolled .brand-text p { display: none; }
html.is-scrolled .brand-text .brand-name { font-size: 18px; }
/* Gentle shrink so the compaction isn't abrupt. Only the visual height/logo are
   transitioned — never the sticky-offset math (--header-h flips instantly). */
.site-header-inner { transition: min-height 140ms ease; }
.brand-mark-img { transition: width 140ms ease, height 140ms ease; }

/* Primary top nav: About / FAQ / Support. Gold underline on the active page. */
.header-end {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: nowrap;
}

/* OT-edition toggle (MT ↔ LXX) — a small segmented switch in the header.
   Pressed state borrows the accent palette already used by .site-nav
   [aria-current], so the two affordances feel like one family. */
.ot-toggle {
  display: inline-flex;
  border: 1px solid var(--border);
  background: var(--bg-card);
  border-radius: 10px;
  padding: 2px;
  gap: 0;
}
.ot-toggle-btn {
  appearance: none;
  background: none;
  border: none;
  color: var(--text-dim);
  font: 600 12px/1 var(--ui-font);
  letter-spacing: 0.04em;
  padding: 8px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: color 120ms, background 120ms;
}
.ot-toggle-btn:hover:not([aria-pressed="true"]):not(:disabled) {
  color: var(--accent);
  background: var(--accent-soft);
}
.ot-toggle-btn[aria-pressed="true"] {
  color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 0 -2px 0 var(--accent);
}
.ot-toggle-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ot-toggle-btn:disabled { cursor: progress; opacity: 0.6; }

.site-nav {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.site-nav a,
.nav-dropdown-toggle {
  display: inline-block;
  padding: 8px 14px;
  color: var(--text-dim);
  text-decoration: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  transition: color 120ms, background 120ms;
}
.site-nav a:hover,
.site-nav a:focus,
.nav-dropdown-toggle:hover,
.nav-dropdown-toggle:focus,
.nav-dropdown[open] > .nav-dropdown-toggle {
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.site-nav a[aria-current="page"] {
  color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* ---- Tools dropdown (#155) ----
   A native <details>/<summary> disclosure that lives in the primary nav. The
   baseline works with JavaScript OFF; header-compact.js only adds Escape /
   outside-click close. The summary reuses the .nav-primary / .site-nav a
   appearance (shared selectors above); the rules here add the summary-specific
   bits (no disclosure triangle, a caret hint) and the absolutely-positioned
   panel. All colours come from theme custom properties — no hard-coded values,
   so a future light theme inherits cleanly. */
.nav-dropdown {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.nav-dropdown-toggle {
  cursor: pointer;
  list-style: none;          /* remove the default disclosure triangle (standard) */
  user-select: none;
}
.nav-dropdown-toggle::-webkit-details-marker { display: none; } /* …and WebKit */
/* Caret drawn from currentColor so it tracks the summary's text colour in every
   state and theme; rotates when the menu is open. */
.nav-dropdown-toggle::after {
  content: "";
  display: inline-block;
  margin-left: 6px;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  vertical-align: middle;
  transition: transform 120ms ease;
}
.nav-dropdown[open] > .nav-dropdown-toggle::after { transform: rotate(180deg); }

/* The panel. A native <details> hides every non-summary child when closed, so
   this only paints when [open] — no display toggling needed. Right-anchored to
   the toggle so it never overflows the right edge of the header; z-index 30 sits
   above the sticky header band (z-index 25). */
.nav-dropdown-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  min-width: 224px;
  max-width: calc(100vw - 24px);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
}
.nav-dd-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  color: var(--text-dim);
  text-decoration: none;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: color 120ms, background 120ms;
}
a.nav-dd-item:hover,
a.nav-dd-item:focus {
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.nav-dd-ico {
  flex: none;
  display: inline-flex;
  color: var(--accent);
}
.nav-dd-ico svg { width: 20px; height: 20px; display: block; }
/* Current page: greyed + non-interactive. A gold left bar marks "you are here"
   while the muted text, default cursor, and absence of hover make it clearly
   not clickable. */
.nav-dd-item.is-current {
  color: var(--text-faint);
  cursor: default;
  box-shadow: inset 2px 0 0 var(--accent);
  opacity: 0.7;
}
.nav-dd-item.is-current .nav-dd-ico { color: var(--text-faint); }
/* "All tools" hub link — a footer row set off by a hairline divider. */
.nav-dd-all {
  margin-top: 4px;
  padding-top: 11px;
  border-top: 1px solid var(--border-soft);
  border-radius: 0 0 8px 8px;
}

/* Comfortable ≥44px tap targets on coarse pointers (mirrors the .chip rule). */
@media (hover: none), (pointer: coarse) {
  .nav-dropdown-toggle,
  .nav-dd-item { min-height: 44px; }
}

/* ---- Page-share / permalink control (views/_share.ejs) ----
   Lemma installs as a standalone PWA, which has NO URL BAR, so this disclosure is
   the only way an installed reader can obtain the address of the page they are on.
   Kept here in §8 beside .header-end's gaps, html.is-scrolled and the two
   header-packing media blocks, for the same reason the Patreon control below is.

   THE TOGGLE IS DELIBERATELY SMALLER THAN ITS NEIGHBOURS (32px, against 44px for
   the gear and the auth button). The header row is a fixed-height sticky band whose
   rendered height is a load-bearing number — verse.ejs's --subnav-h, every jump
   target's scroll-margin-top and header-compact.js's compact state all derive from
   it — and this control is a FIFTH child of an already-packed .header-end. 32px
   clears WCAG 2.5.8 Target Size (Minimum, AA, 24px); it does not reach 2.5.5's
   AAA 44px, which is the price of adding a control to this row without re-opening
   the ≤400px packing negotiation in docs/patreon-login-button-spec.md §9.3. */
.header-share {
  position: relative;
  display: inline-flex;
  align-items: center;
  /* Never shrink: at 320px .header-end is already over-subscribed and the flex
     algorithm would otherwise take the width out of the smallest box here. */
  flex: none;
}

.header-share-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-inline-size: 32px;
  min-block-size: 32px;
  padding: 6px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text-dim);
  cursor: pointer;
  /* Kill the native disclosure triangle: the standard property, the WebKit
     pseudo-element, and ::marker — a summary that grew a triangle would blow the
     32px box the header height depends on. */
  list-style: none;
  user-select: none;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.header-share-toggle::-webkit-details-marker { display: none; }
.header-share-toggle::marker { content: ''; }
.header-share-toggle svg { display: block; }
.header-share-toggle:hover,
.header-share[open] > .header-share-toggle {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.header-share-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* The panel. ABSOLUTELY POSITIONED, always — that is what keeps the control from
   growing the header row in its open state, which would move every sticky offset
   on the page the moment a reader tapped it. A native <details> paints its
   non-summary children only when [open], so nothing here needs toggling.
   z-index 30 matches .nav-dropdown-menu / .verse-share-menu: above the sticky
   header band (25), including the verse page's second row, which follows this
   element in source order and would otherwise paint over it.
   Right-anchored to the toggle for the same reason .verse-share-menu is — a
   left-anchored panel runs off the right edge as the toggle moves rightward. */
.header-share-panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 30;
  box-sizing: border-box;
  inline-size: min(320px, calc(100vw - 32px));
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.header-share-label {
  margin: 0 0 6px;
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
}
/* The address itself: real, selectable link text, which IS the no-JS story. A
   long query string must wrap rather than widen the panel, and `anywhere` is
   correct where `break-word` is not — these are unbroken runs with no spaces. */
.header-share-url {
  display: block;
  font-family: var(--mono-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.header-share-url:hover,
.header-share-url:focus-visible { color: var(--accent); text-decoration: underline; }

.header-share-actions { margin: 10px 0 0; }
/* NO `display` declaration on this class, on purpose — see the [hidden] rule
   below. The button is SSR-hidden and revealed by header-compact.js only once a
   clipboard path exists. */
.header-share-copy {
  appearance: none;
  -webkit-appearance: none;
  padding: 8px 12px;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 13px/1.2 var(--ui-font);
  cursor: pointer;
  transition: color 120ms, background 120ms, border-color 120ms;
}
.header-share-copy:hover { background: var(--accent); color: var(--on-accent); }
.header-share-copy:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* NOT REDUNDANT BY CONSTRUCTION, only by today's §2. The UA's own
   `[hidden] { display: none }` carries no !important, so ANY author `display` on
   this class beats it and a no-JS reader is shown a Copy button that cannot copy —
   laid out, focusable, and silent when pressed. §2's global
   `[hidden] { display: none !important }` currently covers that for every element
   in the app; this line is the local guarantee for the one button whose entire
   SSR contract is "hidden until JS says otherwise", so narrowing or scoping that
   global cannot resurrect it. */
.header-share-copy[hidden] { display: none; }
/* Copy feedback: a SHAPE-ONLY mark, no hue change — the state must not be carried
   by colour alone, and the live region announces it in words regardless. Cleared
   by header-compact.js after ~2s. */
.header-share-copy.is-copied::after { content: ' \2713'; }
.header-share-copy.is-copy-failed::after { content: ' \2715'; }

/* Narrow viewports: RE-ANCHOR, don't clamp narrower. A panel hung off the toggle —
   at any width wide enough to read a URL in — runs off one edge or the other once
   the toggle has moved far enough away from that edge; GEBible measured 94px of
   horizontal scroll at 320px doing exactly that, on the device the installed PWA
   actually runs on. Making .header-share `static` hands the containing block to
   the sticky .site-header (the nearest positioned ancestor), so the panel spans
   the viewport gutter-to-gutter and `top: 100%` now clears the WHOLE band —
   including the verse page's second row.

   900, NOT 560, AND THAT CORRECTION IS THE POINT OF THIS COMMENT. The number here
   used to be 560 on the strength of "measured, the toggle-anchored panel still
   fits at 560 and does not at 520" — a real measurement of the WRONG BAND. Below
   760px `.site-nav a.nav-secondary` is `display: none` and .header-end is packed,
   so the toggle sits near the right gutter and a 320px panel does fit. ABOVE 760px
   the FULL desktop nav is rendered, which pushes the toggle left, and the panel is
   right-anchored TO THE TOGGLE — so it hangs off the LEFT edge instead, and
   `html, body { overflow-x: clip }` means there is no scrollbar and
   scrollWidth === clientWidth: the content is simply gone, silently.
   MEASURED with the disclosure forced open, panel.left, / and /v/genesis/1/1
   alike: 761px -81.1 · 780px -68.4 · 800px -48.4 · 850px +1.6 · 900px +51.6 —
   i.e. the Copy button's own left edge was off-screen from 761 to ~800. That band
   is iPad portrait (768), iPad 10.2 (810), iPad Air (820) and every half-screen
   split on a 1600/1680 laptop.
   900 is the first round number clear of the last failing sample with real margin.
   The SEPARATE header-packing block below stays at 560: different concern (row
   width, not panel overhang), and 560 is correct for it. */
@media (max-width: 900px) {
  .header-share { position: static; }
  /* Two declarations, not four. `min-inline-size: 0` and `max-inline-size: none`
     were both inert — the base rule sets `inline-size` alone, and those are the
     initial values for an absolutely-positioned box. */
  .header-share-panel {
    inset-inline: 1rem;
    inline-size: auto;
  }
}

/* ---- Header packing, 401-560px: PAY FOR THE FIFTH CONTROL ----
   The share control is a fifth child of .header-end, and the bar was already
   over-subscribed here: .header-end is `flex: none`, so the brand column is the
   only thing that can absorb a shortfall, and past its collapse the row overflows
   into the root's `overflow-x: clip`. MEASURED on master, /  at 414px: the brand
   link was already squeezed 40px -> 15.9px with the mark overhanging it. Adding
   32px + one 14px gap took the row 30px past the viewport, which clipped the RIGHT
   EDGE OFF THE PATREON BUTTON — the failure this block exists to prevent, because
   `overflow-x: clip` means it reports as neither a scrollbar nor an error.

   THESE ARE NOT NEW VALUES. Every declaration here is the ≤400px header-packing
   block's OWN value (docs/patreon-login-button-spec.md §9.3), applied from 560px
   down instead of 400px down — the same reclaim, in the band where a fifth control
   makes it necessary. That block stays authoritative below 400px: it repeats each
   of these at equal specificity and sits ~2,700 lines LOWER, so it wins on source
   order, and its own values are tighter still. Nothing here can loosen it.

   Measured after: the brand mark clears the first control at every width from 401px
   up, and no control is clipped. 560 rather than 600 because the bar still fits at
   561 unaided (brand 116.9px). It USED to be justified as "the width the panel above
   re-anchors at — one number, not two", and that half is now wrong: the panel
   re-anchors at 900, because it fails on a different axis (a right-anchored panel
   overhanging the LEFT edge while the desktop nav pushes the toggle inward) that has
   nothing to do with this block's axis (the row's own width). Two numbers, two
   reasons — see the panel block above. */
@media (max-width: 560px) {
  .site-header-inner { column-gap: 10px; }
  .header-end { gap: 8px; }
  .site-nav { gap: 2px; }
  /* Tightened, NOT removed — both segments keep their labels, their height and
     their behaviour. Horizontal padding only, exactly as at ≤400px. */
  .ot-toggle-btn { padding: 8px 8px; }
}

/* ---- Header packing, >=761px: PAY FOR THE FIFTH CONTROL, THE OTHER END ----
   THIS BLOCK EXISTS BECAUSE OF THE SHARE CONTROL, and it is the second half of the
   .brand-text p note in §Header above. The band ≥761px is the OTHER crowded one:
   the full desktop nav is rendered (three .nav-secondary links the ≤760px query
   hides) AND the tagline is visible AND .header-end now carries five controls, all
   inside a 1060px content box that does not grow past --content-max however wide
   the viewport gets. That is why 1920px and 1024px fail identically — the constraint
   is the content box, not the screen.

   THE ARITHMETIC, measured on / with the webfont loaded:
     tagline           305px (p.scrollWidth)
     brand lockup      40 (mark) + 14 (.brand-link gap) = 54  -> brand needs 359
     .header-end       703.3 = 647.3 of controls + 4 x 14px gap   (was 657.3)
     column-gap         24
     359 + 24 + 703.3 = 1086.3 > 1060  ->  26.3px short, at EVERY width >= 1024.
   The three reclaims below give back 32px (8 + 4x4 + 4x2), landing at 1054.0 with
   ~6px of slack — deliberately not zero, since text metrics differ by engine and a
   failed webfont re-measures this string.

   NONE OF THEM REMOVES, HIDES OR SHRINKS A CONTROL — same contract as the two
   narrow blocks. And note the progression is not monotonic, on purpose: ≥761 is
   packed (everything visible at once), 561-760 runs the loose base values (the
   secondary nav is gone, the tagline is gone — there is room to spare), ≤560 and
   ≤400 pack again for width. Two crowded bands with a comfortable middle.

   RANGE, not a bare min-width bump: 761 rather than 1025 because the reclaim is
   worth having across the whole band the desktop nav is rendered in. It also clears
   two pre-existing defects at the bottom of that band as a side effect — the row
   spilling past .site-header-inner's padding edge at 761, and the 40px brand mark
   overlapping .header-end's first control from 761 to ~783.
   Every value is LOOSER than the ≤560 block's, so nothing here can be read as
   contradicting it, and the ranges are disjoint in any case. */
@media (min-width: 761px) {
  .site-header-inner { column-gap: 16px; }
  .header-end { gap: 10px; }
  /* The invisible one: each .site-nav link already carries 14px of horizontal
     padding, so 6 -> 4 changes the gap between two labels from 34px to 32px and
     buys 8px across the four gaps. */
  .site-nav { gap: 4px; }
}

/* ---- Persistent Patreon sign-in control (docs/patreon-login-button-spec.md §3, §6) ----
   Last child of .header-end. Kept here in §8, beside every rule it must coordinate
   with (.header-end's gaps, html.is-scrolled, the header-packing media blocks), rather
   than beside the gear in §14. Sized 44x44 minimum so it clears WCAG 2.5.5; the
   .settings-gear is bumped 40 -> 44 in §14 in the same change so the two icon controls
   align. Colour comes from the --patreon-* tokens, never from --accent: this is a
   third-party affordance and should not look like Lemma chrome. */
.header-auth { display: inline-flex; align-items: center; flex: none; }

.auth-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 10px;
  background: var(--patreon-surface);
  color: var(--patreon-on-surface);
  border: 1px solid var(--patreon-edge);
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background 120ms, border-color 120ms;
}
.auth-btn:hover,
.auth-btn:focus {
  background: var(--patreon-surface-hover);
  border-color: var(--patreon-edge-hover);
  color: var(--patreon-on-surface);
  text-decoration: none;
}
/* Same ring as .settings-gear / .ot-toggle-btn, so keyboard focus is one idiom
   across the whole bar. Gold on the navy band measures 7.4:1. */
.auth-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.auth-btn:active { background: var(--patreon-surface); }

/* The mark is an <img> of a local SVG (spec §7). It cannot inherit currentColor —
   that is the point: it makes recolouring the brand mark impossible by construction. */
.auth-btn-mark { width: 16px; height: 16px; display: block; flex: none; }

/* ---- Signed-in account menu (S2) ----
   Reuses .nav-dropdown / .nav-dropdown-menu / .nav-dd-item wholesale; only the
   summary chip and the two menu-only rows are new.

   EVERY selector here is descendant-qualified with .header-auth, giving (0,2,0).
   That is deliberate: the summary also carries .nav-dropdown-toggle (for the
   marker removal and the caret), and `.site-nav a, .nav-dropdown-toggle` sets
   display/padding/color/font-size at (0,1,0). A bare .auth-menu-toggle would tie
   and be decided by source order alone, so moving this block would silently
   restyle the chip. See spec §9.2. */
.header-auth .auth-menu-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
}
.header-auth .auth-menu-toggle:hover,
.header-auth .auth-menu[open] > .auth-menu-toggle { background: var(--accent); color: var(--on-accent); }
.header-auth .auth-menu-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.header-auth .auth-menu-star { font-size: 13px; line-height: 1; }
/* Narrower than the Tools menu's 224px — fewer, shorter rows. Right-anchored and
   viewport-clamped by the inherited .nav-dropdown-menu rules, so it contributes no
   width to the header row at any breakpoint (spec §9.4). */
.header-auth .auth-menu-panel { min-width: 200px; }

.auth-menu-tier {
  padding: 8px 10px 10px;
  margin: 0;
  color: var(--text-dim);
  font-family: var(--ui-font);
  font-size: 13px;
  border-bottom: 1px solid var(--border-soft);
}
/* No `.auth-menu-tier strong` rule: the line is a fixed "Signed in — ad-free
   supporter" with nothing emphasised in it. The named tier that used to sit here in
   a <strong> was removed on privacy grounds (views/_auth_control.ejs explains why),
   so a rule for it would be dead CSS asserting markup that is not emitted. */

.auth-logout { margin: 2px 0 0; padding: 0; }
.auth-logout-btn {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 9px 10px;
  text-align: left;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text-dim);
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: color 120ms, background 120ms;
}
.auth-logout-btn:hover { color: var(--accent); background: var(--accent-soft); }
.auth-logout-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* html.is-scrolled: NO new rules, deliberately. The auth control is unchanged by
   compaction, exactly like .settings-gear and .ot-toggle. The bar shrinks 64->52
   (desktop) / 56->50 (mobile) and a 44px control still fits inside 50px with 3px of
   breathing room; the 12px of compaction comes entirely from the brand block.
   Shrinking or un-labelling the control mid-scroll would reflow the bar for no
   benefit. Do not "complete" this later. */

/* Icon-only below 760px. Scoped to .header-auth so it cannot reach the inline
   panel's copy of the button, which keeps its visible label at every width (§10.4). */
@media (max-width: 760px) {
  /* NOT display:none — the label is the control's own name, and collapsing it out of
     the a11y tree would leave the accessible name resting entirely on the aria-label.
     Keeping both means the name is correct even if the aria-label is ever dropped, and
     it keeps WCAG 2.5.3 Label in Name satisfiable by inspection. */
  .header-auth .auth-btn-label,
  .header-auth .auth-menu-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .header-auth .auth-btn,
  .header-auth .auth-menu-toggle {
    width: 44px;
    padding: 0;
    justify-content: center;
    gap: 0;
  }
}

/* Forced colours (Windows High Contrast). The button is a brand-mark container whose
   colour carries meaning, and the mark is a white <img> that would vanish onto a forced
   light ButtonFace. Pin it, but keep a UA-painted boundary so it stays identifiable as
   a control. forced-color-adjust:none is used here deliberately and narrowly — a logo
   is the canonical case the property exists for. Do NOT extend it to .auth-menu-toggle,
   .auth-panel, or .auth-notice; those must keep system colours. */
@media (forced-colors: active) {
  .auth-btn {
    forced-color-adjust: none;
    background: #0e0e10;
    color: #ffffff;
    border: 1px solid ButtonBorder;
  }
  .auth-btn:focus-visible { outline: 2px solid Highlight; outline-offset: 2px; }
}

/* ============================================================================
   9. DATA WARNING BANNER
   ============================================================================ */

/* ---- Data warning ---- */
.data-warning {
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  color: var(--warn);
  padding: 12px 16px;
  border-radius: var(--radius);
  margin-bottom: 20px;
  font-size: 14px;
}
.data-warning code {
  background: rgba(0, 0, 0, 0.3);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 13px;
}

/* ============================================================================
   10. SEARCH FORM + EXAMPLE CHIPS
   ============================================================================ */

/* ---- Search ---- */
.search-form {
  display: flex;
  gap: 10px;
  position: relative; /* anchor for the absolute autocomplete listbox (app.js) */
}

.search-input {
  flex: 1;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 16px;
  padding: 14px 16px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.search-input::placeholder { color: var(--text-faint); }
.search-input:focus {
  outline: none;
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.search-btn {
  background: linear-gradient(135deg, #d4a839 0%, #b8852a 100%);
  border: none;
  border-radius: var(--radius);
  color: var(--on-accent);
  font-size: 15px;
  font-weight: 700;
  padding: 0 26px;
  min-height: 48px; /* guarantees a comfortable touch target even when not flex-stretched */
  cursor: pointer;
  transition: transform 0.1s, box-shadow 0.15s;
}
.search-btn:hover { box-shadow: 0 6px 18px rgba(200, 161, 59, 0.3); }
.search-btn:active { transform: translateY(1px); }
.search-btn:disabled { opacity: 0.6; cursor: progress; }

/* ---- Search autocomplete (type-ahead combobox; DOM built by app.js) ----
   The listbox is created and toggled in JS so the box degrades to a plain text
   input with no JS. Absolutely positioned under the form; the global
   [hidden] !important rule keeps it out of the flex row until revealed. */
.ac-list {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 40;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
  max-height: 62vh;
  overflow-y: auto;
}
.ac-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.ac-item.is-active,
.ac-item:hover { background: var(--accent-soft); }
.ac-badge {
  flex: none;
  min-width: 56px;
  text-align: center;
  padding: 3px 7px;
  border-radius: 999px;
  font: 700 10.5px/1 var(--ui-font);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid transparent;
}
.ac-badge--ref     { color: var(--accent); border-color: var(--accent-border); }
.ac-badge--strongs { color: #8fb3ff; border-color: rgba(143, 179, 255, 0.4); }
.ac-badge--lxx     { color: #b58cff; border-color: rgba(181, 140, 255, 0.4); }
.ac-text { min-width: 0; display: flex; flex-direction: column; gap: 1px; }
/* Originals-capable stack: Ezra SIL covers Hebrew, Gentium covers Greek/Latin,
   so a Strong's lemma or LXX display form renders whatever its script. */
.ac-pri {
  font-family: 'Ezra SIL', var(--reading-font), var(--ui-font);
  font-size: 16px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ac-sec {
  font-family: 'Ezra SIL', var(--reading-font), var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.examples {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.examples-label { color: var(--text-faint); font-size: 13px; }
.chip {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s;
  min-height: 36px; /* roomy chip; widened to 44px on touch screens below */
}
.chip:hover { color: var(--accent); border-color: var(--accent-border); }
/* #57: a small, subordinate gloss after a cryptic Strong's-code chip (e.g.
   H7225 "beginning") so a newcomer knows what the code means. The full
   word + meaning is in the chip's title tooltip. */
.chip-gloss { color: var(--text-faint); font-size: 12px; margin-left: 3px; }

/* ============================================================================
   11. CONTENT GRID LAYOUT
   ============================================================================ */

/* ---- Content layout ---- */
.content {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* grid-blowout guard: a 1fr (auto-min) column lets a wide min-content child expand the page column past the viewport at 390px; minmax(0,1fr) caps it at available width — #199 residual */
  gap: 20px;
  margin-top: 28px;
}

/* ============================================================================
   12. RESULTS PANEL + VERSE HERO (results head, verse stats)
   ============================================================================ */

/* ---- Results ---- */
/* Results panel: filled card that visually owns the center of the page.
   Without it the empty-state placeholder reads as a narrow island; with it
   the word-study area is the page's primary surface from first paint. */
.results {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 28px 28px;
  min-height: 280px;
}
.placeholder {
  text-align: center;
  color: var(--text-dim);
  padding: 40px 20px;
}
.placeholder-original {
  font-family: var(--greek-font);
  font-size: 30px;
  color: var(--text);
  margin-bottom: 14px;
}

.results-head {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-bottom: 18px;
  margin-bottom: 22px;
  /* Gold hairline under the verse title (demo look) rather than the neutral
     border used elsewhere — frames the verse as the hero of the page. */
  border-bottom: 1px solid var(--accent-border);
}
.results-head-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 14px;
}
/* An <h1> since 2026-08-21 — the verse reference is the page heading on /v/ and
   /compare. display:inline-flex was already explicit and survives the tag swap;
   font-size, weight AND FAMILY are all pinned to inherit, so nothing the UA or
   this stylesheet hands an h1 can reach this row.

   FAMILY IS NOT DEFENSIVE — it is a repair, and it was found by measurement
   rather than by reading. The h1..h6 selector at the top of this file enrolls
   every heading in --ui-font, and `.results-head .ref` sets no family of its
   own, so the promotion silently moved the verse reference out of Gentium and
   into Source Sans 3: measured in Chrome against the pre-promotion tree,
   138.77px -> 144px at every width from 320 to 1920. Nothing would have
   reported it. The visible type is `.results-head .ref` below, unchanged. */
.ref-group {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  font-size: inherit;
  font-weight: inherit;
  font-family: inherit;
}
.ref-book-icon { flex: none; color: var(--accent); }
.results-head .ref { font-size: 30px; font-weight: 700; letter-spacing: -0.015em; color: var(--text); }
.results-head .lang-badge { color: var(--accent); font-weight: 600; font-size: 14px; }

/* Language badge + source-info affordance. The ⓘ reveals a hover/focus card with
   the text's provenance (CSP-safe pure-CSS disclosure — same pattern as the
   Strong's .gloss-info tooltip; tap-to-reveal on touch via :focus-within). */
.verse-lang { display: inline-flex; align-items: center; gap: 8px; }
/* Right-side header group: the version/language badge + source ⓘ and the Share
   control, folded onto the same top row so the word grid is the first substantial
   element under a single-row head. Stays at the row's right edge (the parent
   .results-head-top is justify-content:space-between with .ref-group on the left);
   wraps as a unit on narrow widths. Deliberately NOT position:relative — the
   share dropdown's containing block must remain its own .verse-share, not this
   wrapper, so the menu's right:0 anchors to the trigger and stays on-screen. */
.results-head-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.verse-source {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  color: var(--text-dim);
  cursor: help;
  flex: none;
}
.verse-source svg { width: 14px; height: 14px; }
.verse-source:hover,
.verse-source:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.verse-source-pop {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: max-content;
  max-width: min(360px, 80vw);
  padding: 14px 16px;
  font-size: 13px;
  line-height: 1.6;
  font-weight: 400;
  text-align: left;
  color: var(--text-dim);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.7);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 140ms, transform 140ms, visibility 140ms;
  z-index: 6;
}
.verse-source-pop strong { color: var(--text); font-weight: 600; }
/* Arrow pointing up at the icon. */
.verse-source-pop::after {
  content: "";
  position: absolute;
  bottom: 100%;
  right: 9px;
  border: 6px solid transparent;
  border-bottom-color: var(--bg-card);
}
.verse-source:hover .verse-source-pop,
.verse-source:focus-within .verse-source-pop {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
/* Legacy single-line meta (older render path) — kept so any caller still
   emitting it stays styled. */
.results-head .meta { color: var(--text-dim); font-size: 13px; }
.results-head .meta .lang-badge { color: var(--accent); font-weight: 600; }

/* Verse hero stat band — icon-badged metric chips that mirror the Strong's
   page's stat grid (same token palette: bg-card chip, gold accent-soft icon
   badge). Auto-fits 1–4 across by available width and collapses on phones. */
.verse-stats {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
  gap: 12px;
}
.verse-stat {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
}
.verse-stat-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.verse-stat-icon svg { width: 20px; height: 20px; }
.verse-stat-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.verse-stat-value {
  margin: 0;
  font: 700 22px/1.05 var(--ui-font);
  color: var(--text);
  letter-spacing: -0.01em;
}
.verse-stat-of { font-size: 14px; font-weight: 400; color: var(--text-dim); }
/* Textual value (e.g. the corpus section name) reads as gold reading-type
   rather than a big tabular number. */
.verse-stat-value.is-text { font: 600 16px/1.2 var(--reading-font); color: var(--accent); }
.verse-stat-label {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

/* ============================================================================
   13. PUBLIC-DOMAIN ENGLISH TRANSLATION BLOCK
   ============================================================================ */

/* ---- Public-domain English rendering (under the interlinear word grid) ----
   Shown on the SSR verse page (_translation.ejs) and the SPA range view
   (app.js renderTranslation), same markup either way. The gold left rule
   signals "translated reading" without competing with the gold word chips. */
.verse-translation-host[hidden] { display: none; }
.verse-translation {
  margin: 22px 0 4px;
  padding: 18px 20px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}
.vt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.vt-label {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.01em;
}
.vt-icon { flex: none; color: var(--text-faint); }
/* The real version control + the dialog's MT/LXX live in _settings_dialog. The
   native arrow is kept (no appearance:none) so no data-URI caret is needed —
   the strict CSP's img-src falls back to 'self' and would block one. */
.translation-select,
.lxx-translation-select {
  font: 600 14px/1 var(--ui-font);
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 9px 12px;
  cursor: pointer;
  transition: border-color 120ms, box-shadow 120ms;
}
.translation-select:hover,
.lxx-translation-select:hover { border-color: var(--accent-border); }
.translation-select:focus-visible,
.lxx-translation-select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.translation-select:disabled,
.lxx-translation-select:disabled { cursor: progress; opacity: 0.6; }
.vt-text {
  margin: 0;
  font-family: var(--reading-font);
  font-size: 20px;
  line-height: 1.55;
  color: var(--text);
  /* Hold a comfortable reading measure even when the verse card spans a wide
     (.app--wide) study page — the 45-75ch legibility norm. */
  max-width: 70ch;
}
.vt-attr {
  margin-top: 10px;
  font-family: var(--ui-font);
  font-size: 12px;
  color: var(--text-faint);
  letter-spacing: 0.02em;
}

/* ---- #115 honest English->original on-ramp (linked reading line) ---------
   When the active reading version carries its OWN published word alignment
   (today: the ULT), each English word links to its Strong's lexicon page. A
   RESTRAINED affordance by design: the word keeps the reading-line text color so
   the verse is not a wall of blue, with a faint dotted underline to signal it is
   a link; the gold accent + a solid underline only appear on hover/focus. */
.vt-word {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--text-faint);
  /* keep the dotted rule clear of descenders so the line stays readable */
  padding-bottom: 1px;
  transition: color 0.12s ease, border-color 0.12s ease;
}
.vt-word:hover,
.vt-word:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
  border-bottom-style: solid;
}
.vt-word:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}
/* The alignment disclosure caption — sits between the linked line and the
   version attribution. Honest, quiet, and unmissable: it states the links rest
   on the version's OWN published alignment (CC BY-SA 4.0), not Lemma's analysis. */
.vt-align-note {
  margin: 8px 0 0;
  font-family: var(--ui-font);
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-faint);
  max-width: 70ch;
}
.vt-align-note strong { color: var(--text-muted, var(--text-faint)); font-weight: 600; }

/* ---- Parallel-version compare -------------------------------------------
   The in-page <details> panel (verse/_compare.ejs) + the dedicated /compare
   view (compare.ejs). Stacked ROWS beneath the interlinear spine; the picker
   is a no-JS form enhanced by compare.js. Reuses the card visual language so
   no new tokens are needed. */
.verse-compare { margin: 14px 0 4px; }
.cmp-details {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  overflow: hidden;
}
.cmp-summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  cursor: pointer;
  list-style: none;
  font-family: var(--ui-font);
  color: var(--text-dim);
}
.cmp-summary::-webkit-details-marker { display: none; }
.cmp-summary:hover { color: var(--text); }
/* Panel-header parity with .cross-refs-head / .commentary-head (2026-06): a gold
   icon chip + a bold near-white heading + a gold count pill, so the collapsed
   compare teaser reads as a first-class study panel, not a faint toggle. */
.cmp-summary-icon {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 11px;
  background: var(--accent-soft); color: var(--accent);
}
.cmp-summary-text { display: inline-flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; }
.cmp-summary-title { margin: 0; min-width: 0; font: 700 19px/1.15 var(--ui-font); color: var(--text); }
.cmp-summary-count {
  flex: none; margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  font: 600 12px/1 var(--ui-font); color: var(--accent);
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  border-radius: 999px; padding: 5px 10px;
}
.cmp-summary-chevron { flex: none; color: var(--text-faint); transition: transform 160ms; }
.cmp-details[open] .cmp-summary-chevron { transform: rotate(180deg); }
.cmp-body { padding: 4px 18px 18px; }
.cmp-intro {
  margin: 0 0 14px; font-family: var(--ui-font); font-size: 13px;
  line-height: 1.5; color: var(--text-dim);
}
.cmp-intro strong { color: var(--text); font-weight: 700; }
/* Honesty disclosure caption (shared by the panel + the /compare page): the
   interlinear is co-present, NOT word-aligned to the English rows. Muted, but on
   its own line so a reader actually sees it. */
.cmp-nonalign {
  display: block;
  margin-top: 7px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-faint);
}
.cmp-nonalign strong { color: var(--text-dim); font-weight: 600; }
/* PROMOTED standalone caption: directly under the spine on /compare and above the
   rows in the /v/ panel. Renders with AND without a spine, in both hero layouts. */
.cmp-nonalign--caption {
  margin: 0 0 16px;
  padding-left: 11px;
  border-left: 2px solid var(--border);
  font-family: var(--ui-font);
}

/* ───────────────────────────────────────────────────────────────────────────
   MT ↔ LXX edition comparison panel (verse/_compare_editions.ejs). A collapsed
   <details> like .verse-compare, holding two READ BLOCKS side by side — the
   Masoretic Hebrew and the Greek Septuagint of the same verse, each with its
   original-language line + an English rendering. NOT word-grids (no MT↔LXX
   word-alignment exists). Stacks below 720px. Palette tokens only.
   ─────────────────────────────────────────────────────────────────────────── */
.verse-mtlxx { margin: 14px 0 4px; }
.mtlxx-details {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  overflow: hidden;
}
.mtlxx-summary {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; cursor: pointer; list-style: none;
  font-family: var(--ui-font); color: var(--text-dim);
}
.mtlxx-summary::-webkit-details-marker { display: none; }
/* Panel-header parity with .cross-refs-head / .commentary-head (2026-06): gold
   icon chip + bold near-white heading, with the "Masoretic Hebrew ↔ Greek
   Septuagint" line stacked beneath as a subtitle (mirrors commentary's h2 + intro). */
.mtlxx-summary-icon {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 11px;
  background: var(--accent-soft); color: var(--accent);
}
.mtlxx-summary-text {
  display: flex; flex-direction: column; gap: 2px;
  align-items: flex-start; flex: 1 1 auto; min-width: 0;
}
.mtlxx-summary-title { margin: 0; min-width: 0; font: 700 19px/1.15 var(--ui-font); color: var(--text); }
.mtlxx-summary-sub { font-size: 13px; line-height: 1.4; color: var(--text-dim); }
.mtlxx-summary-chevron { flex: none; color: var(--text-faint); transition: transform 160ms; }
.mtlxx-details[open] .mtlxx-summary-chevron { transform: rotate(180deg); }

.mtlxx-body { padding: 4px 18px 18px; }
.mtlxx-intro {
  margin: 0 0 12px; font-family: var(--ui-font); font-size: 13px;
  line-height: 1.5; color: var(--text-dim);
}
.mtlxx-intro strong { color: var(--text); font-weight: 700; }
/* PROMOTED non-alignment caption — its own line directly above the two columns,
   mirroring .cmp-nonalign--caption on the parallel-compare panel. Muted but
   conspicuous, so the "not word-aligned / lemma form" caveat is seen even when the
   panel opens by default on desktop. */
.mtlxx-nonalign {
  margin: 0 0 14px;
  padding-left: 11px;
  border-left: 2px solid var(--border);
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-faint);
}
.mtlxx-nonalign strong { color: var(--text-dim); font-weight: 600; }
.mtlxx-disclose {
  display: flex; gap: 8px; align-items: flex-start;
  margin: 0 0 14px; padding: 10px 12px;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  border-radius: 10px;
  font-family: var(--ui-font); font-size: 12.5px; line-height: 1.45; color: var(--text-dim);
}
.mtlxx-disclose svg { flex: none; margin-top: 1px; color: var(--accent); }

.mtlxx-cols { display: grid; grid-template-columns: 1fr; gap: 12px; }
@media (min-width: 720px) { .mtlxx-cols { grid-template-columns: 1fr 1fr; } }

.mtlxx-col {
  display: flex; flex-direction: column;
  padding: 13px 15px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--border);
  border-radius: 10px;
}
.mtlxx-col--mt { border-left-color: var(--accent); }
.mtlxx-col--note { border-left-color: var(--warn-border); background: var(--warn-soft); }

.mtlxx-col-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 9px; }
.mtlxx-col-badge {
  font: 700 10.5px/1 var(--ui-font); letter-spacing: 0.04em; text-transform: uppercase;
  padding: 4px 7px; border-radius: 6px; white-space: nowrap;
}
.mtlxx-badge--mt, .mtlxx-badge--lxx { color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-border); }
.mtlxx-col-ref { font: 600 13px/1.2 var(--ui-font); color: var(--text); }
.mtlxx-col-source { font: 500 11px/1.3 var(--ui-font); color: var(--text-faint); flex-basis: 100%; }

.mtlxx-orig { margin: 0 0 10px; line-height: 1.7; color: var(--text); }
.mtlxx-orig--he { font-family: var(--hebrew-font); font-size: 22px; }
.mtlxx-orig--grc { font-family: var(--greek-font); font-size: 19px; }
.mtlxx-eng { margin: 0; font-family: var(--reading-font); font-size: 16px; line-height: 1.5; color: var(--text); }
.mtlxx-attr { margin: 8px 0 0; font: 500 11.5px/1.4 var(--ui-font); color: var(--text-faint); }
.mtlxx-empty { margin: 0; font-family: var(--ui-font); font-size: 13px; font-style: italic; line-height: 1.5; color: var(--text-faint); }
.mtlxx-softnote {
  margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--border-soft);
  font: 500 12px/1.45 var(--ui-font); color: var(--text-faint);
}
.mtlxx-note-text { margin: 0 0 9px; font-family: var(--reading-font); font-size: 15px; line-height: 1.5; color: var(--text); }
.mtlxx-note-hedge { margin: 0; font: 500 12.5px/1.45 var(--ui-font); color: var(--text-dim); }
.mtlxx-note-hedge strong { color: var(--accent); }
.mtlxx-foot {
  margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--border-soft);
  font: 500 11.5px/1.5 var(--ui-font); color: var(--text-faint);
}
.mtlxx-foot-link { display: inline-block; margin-top: 4px; color: var(--accent); text-decoration: none; font-weight: 600; }
.mtlxx-foot-link:hover { text-decoration: underline; }

/* R3 — length-divergence headline inside the compare panel. */
.mtlxx-diverge {
  display: flex; gap: 9px; align-items: flex-start;
  margin: 0 0 14px; padding: 10px 13px;
  border: 1px solid var(--accent-border); border-radius: 10px;
  background: var(--accent-soft);
  font: 500 13.5px/1.55 var(--ui-font); color: var(--text);
}
.mtlxx-diverge svg { flex: none; margin-top: 2px; color: var(--accent); }
.mtlxx-diverge strong { color: var(--text); font-weight: 700; }
.mtlxx-diverge-hedge { display: block; margin-top: 3px; font-size: 12px; color: var(--text-dim); font-weight: 500; }

/* Stacked version rows (shared by the panel + the /compare page). */
.cmp-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
/* In-page /v/ panel only: on the wide study column the version rows go multi-
   across (the critic's open + columnar desktop treatment, 2026-06). Scoped to
   .verse-compare so the dedicated /compare page keeps its stacked default and its
   own JS-driven row↔column toggle (.cmp-page-rows.is-columns). auto-fit + minmax
   keeps the columns BALANCED at every version count (1-4): 3 versions sit as 3
   even columns with no lonely orphan cell, and it reflows to fewer columns (down
   to a single column on narrow widths) as the container shrinks. min(100%, 280px)
   so a column never overflows when only one fits. Mirrors the /compare page's
   .cmp-page-rows.is-columns grid. */
@media (min-width: 1080px) {
  .verse-compare .cmp-rows {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
    align-items: start;
  }
}
.cmp-row {
  padding: 12px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
}
.cmp-row.is-empty { border-left-color: var(--border); opacity: 0.85; }
/* FLIP reorder animation — same pattern as .cmp-chip.is-flipping above. */
.cmp-row.is-flipping { transition: transform 260ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
@media (prefers-reduced-motion: reduce) { .cmp-row.is-flipping { transition: none; } }
.cmp-row-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px 12px; flex-wrap: wrap; margin-bottom: 7px;
}
.cmp-version-name { font: 600 13px/1.2 var(--ui-font); color: var(--text); }
.cmp-license-chip {
  font: 600 10.5px/1 var(--ui-font); letter-spacing: 0.03em;
  color: var(--text-faint); background: var(--bg-card);
  border: 1px solid var(--border-soft); border-radius: 6px;
  padding: 4px 7px; white-space: nowrap;
}
.cmp-license-chip.is-cc { color: var(--accent); border-color: var(--accent-border); }
.cmp-text {
  margin: 0; font-family: var(--reading-font); font-size: 17px;
  line-height: 1.5; color: var(--text); max-width: 70ch;
}
/* #107 — whole-verse English↔English diff highlight. Marks tokens where the
   stacked versions differ (server-computed `diffHtml`, echoed by SSR + JS). NOT
   color-alone (a11y): a subtle gold tint AND an inset underline, so the delta
   reads even without color perception. Inherits text color so the prose stays
   legible; the marks wrap normally on a 390px phone. */
.cmp-text mark.cmp-diff {
  background: var(--accent-soft);
  color: inherit;
  border-radius: 2px;
  box-shadow: inset 0 -2px 0 var(--accent-border);
  padding: 0 1px;
}
/* #107 — short legend explaining the highlight (gated on >= 2 versions). Mirrors
   .cmp-nonalign caption styling: small, muted, on its own line above the rows. */
.cmp-difflegend {
  display: block;
  margin: 0 0 12px;
  padding-left: 11px;
  border-left: 2px solid var(--border);
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-faint);
}
.cmp-empty-reason {
  margin: 0; font-family: var(--ui-font); font-size: 13px;
  font-style: italic; color: var(--text-faint);
}
.cmp-attr {
  display: flex; align-items: flex-start; gap: 7px; margin: 14px 0 0;
  font-family: var(--ui-font); font-size: 11.5px; line-height: 1.45;
  color: var(--text-faint);
}
.cmp-attr-icon { flex: none; margin-top: 1px; color: var(--text-faint); }

/* Version picker (panel + dialog + /compare page). The single de-triplicated
   partial views/verse/_compare_picker.ejs renders this on all three surfaces. */
.cmp-picker { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-soft); }
.cmp-picker-set { margin: 0; padding: 0; border: 0; }
.cmp-picker-legend { padding: 0; margin-bottom: 9px; font: 600 12px/1 var(--ui-font); color: var(--text-dim); letter-spacing: 0.02em; }
.cmp-picker-grid { display: flex; flex-wrap: wrap; gap: 8px; }

/* PILLS — a CSS-styled NATIVE checkbox. The <input> is VISUALLY CLIPPED via the
   .visually-hidden technique (NOT display:none — that kills focus + SR semantics),
   so the no-JS form submit + keyboard/screen-reader behaviour stay native. The
   visible pill face is the adjacent sibling .cmp-pill-face, driven entirely by the
   checkbox's :checked / :disabled / :focus-visible state. The label keeps the
   .cmp-picker-opt hook (compare.js's .is-disabled toggle) alongside .cmp-pill. */
.cmp-pill { display: inline-flex; margin: 0; cursor: pointer; }
.cmp-pill-face {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px;
  font: 500 13px/1.1 var(--ui-font); color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  transition: background 120ms, border-color 120ms, color 120ms;
  user-select: none; white-space: nowrap;
}
.cmp-pill:hover .cmp-pill-face { color: var(--text); border-color: var(--border); }
.cmp-picker-check:checked + .cmp-pill-face {
  color: var(--accent); font-weight: 600;
  background: var(--accent-soft); border-color: var(--accent-border);
}
.cmp-picker-check:checked + .cmp-pill-face::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); flex: none;
}
.cmp-picker-check:disabled + .cmp-pill-face {
  opacity: 0.4; cursor: default; color: var(--text-faint);
}
/* At the 4-version cap, unchecked catalog pills are hidden (not greyed). */
.cmp-pill.is-disabled { display: none; }
/* Focus ring follows the (clipped) input onto the visible face. */
.cmp-picker-check:focus-visible + .cmp-pill-face {
  outline: none; box-shadow: 0 0 0 3px var(--accent-soft); border-color: var(--accent-border);
}
.cmp-pill-name { min-width: 0; }

/* "N of 4 selected" counter (SSR'd; compare.js keeps [data-compare-count] live). */
.cmp-picker-count { margin: 12px 0 0; font: 500 12px/1.3 var(--ui-font); color: var(--text-faint); }
.cmp-picker-count [data-compare-count] { color: var(--accent); font-weight: 700; }

/* Removable selected-set chip row (P2/P3). SSR-inert + hidden; compare.js
   un-hides, populates, and wires removal/reorder. Pure enhancement. */
.cmp-selected { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; margin: 0 0 12px; }
.cmp-selected[hidden] { display: none; }
.cmp-chip {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px 4px 3px 8px; border-radius: 999px;
  font: 600 12px/1.1 var(--ui-font); color: var(--accent);
  background: var(--accent-soft); border: 1px solid var(--accent-border);
}
.cmp-chip.is-dragging { opacity: 0.5; }
/* FLIP reorder animation — JS sets style.transform to the inverse delta, then
   adds .is-flipping one rAF later so this transition slides it to transform:none. */
.cmp-chip.is-flipping { transition: transform 220ms cubic-bezier(0.25, 0.46, 0.45, 0.94); }
@media (prefers-reduced-motion: reduce) { .cmp-chip.is-flipping { transition: none; } }
.cmp-chip-name { padding: 0 2px; }
.cmp-chip-move, .cmp-chip-x {
  appearance: none; -webkit-appearance: none; border: 0; background: transparent;
  color: var(--accent); cursor: pointer; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; padding: 0;
  font-size: 14px; flex: none;
}
.cmp-chip-move:hover, .cmp-chip-x:hover { background: var(--accent-border); }
.cmp-chip-move:focus-visible, .cmp-chip-x:focus-visible {
  outline: none; box-shadow: 0 0 0 2px var(--accent);
}
.cmp-chip-x { font-size: 16px; }

.cmp-picker-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; }
.cmp-picker-apply {
  appearance: none; -webkit-appearance: none;
  font: 600 13px/1 var(--ui-font); color: var(--bg);
  background: var(--accent); border: 0; border-radius: 9px;
  padding: 9px 16px; cursor: pointer; transition: filter 120ms;
}
.cmp-picker-apply:hover { filter: brightness(1.08); }
.cmp-picker-apply:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }
.cmp-picker-full, .cmp-picker--page .cmp-picker-full {
  font: 600 13px/1 var(--ui-font); color: var(--accent); text-decoration: none;
}
.cmp-picker-full:hover { text-decoration: underline; }
.cmp-picker-hint { margin: 10px 0 0; font: 500 12px/1.4 var(--ui-font); color: var(--text-faint); }

/* Dedicated /compare page extras. */
.cmp-page-intro {
  margin: 0 0 18px; font-family: var(--ui-font); font-size: 14px;
  line-height: 1.55; color: var(--text-dim); max-width: 70ch;
}
.cmp-page-intro strong { color: var(--text); }
.cmp-page-back, .cmp-page-intro .cmp-page-back { color: var(--accent); text-decoration: none; font-weight: 600; white-space: nowrap; }
.cmp-page-back:hover { text-decoration: underline; }
.cmp-spine { margin: 0 0 18px; }
.cmp-spine-note { margin: 0 0 10px; font: italic 500 12.5px/1.4 var(--ui-font); color: var(--text-faint); }
.cmp-page-rows { display: flex; flex-direction: column; gap: 22px; }
.cmp-verse-block { }
.cmp-verse-label { margin: 0 0 10px; font: 700 15px/1.2 var(--ui-font); color: var(--text-dim); }
.cmp-verse-label a { color: inherit; text-decoration: none; }
.cmp-verse-label a:hover { color: var(--accent); }
.cmp-picker--page { margin-top: 24px; }

/* P2 two-column hero (/compare only). Stacked by default (the safe baseline);
   only the wide .app--wide column at ≥1080px lays intro + spine side by side, and
   ONLY when the server didn't force the stack (.cmp-hero--stack — set for no
   spine, RTL Hebrew, or a >12-word verse). The class is the single source of
   truth; there is no inline style (CSP). */
.cmp-hero { display: block; margin: 0 0 18px; }
.cmp-hero .cmp-page-intro { margin-bottom: 14px; }
.cmp-hero .cmp-spine { margin: 0; }
@media (min-width: 1080px) {
  .app--wide .cmp-hero:not(.cmp-hero--stack) {
    display: grid;
    grid-template-columns: minmax(240px, 280px) 1fr;
    gap: 28px;
    align-items: start;
  }
  .app--wide .cmp-hero:not(.cmp-hero--stack) .cmp-page-intro { margin-bottom: 0; }
}

/* P3 row→column layout toggle (≥1080 .app--wide; compare.js un-hides it). */
.cmp-layout-toggle {
  display: flex; align-items: center; gap: 8px; margin: 0 0 16px;
  font: 600 12px/1 var(--ui-font);
}
.cmp-layout-toggle[hidden] { display: none; }
.cmp-layout-toggle-label { color: var(--text-faint); letter-spacing: 0.03em; text-transform: uppercase; }
.cmp-layout-btn {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  font: 600 12px/1 var(--ui-font); color: var(--text-dim);
  background: var(--bg-raised); border: 1px solid var(--border-soft);
  border-radius: 8px; padding: 6px 12px; transition: color 120ms, background 120ms, border-color 120ms;
}
.cmp-layout-btn:hover { color: var(--text); }
.cmp-layout-btn.is-active { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-border); }
.cmp-layout-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

/* P3 column mode: lay the per-version rows out as columns. The cap stays 4, so a
   block never holds more than 4 columns. English-only — no original-language
   causation is asserted anywhere in this layout. */
.cmp-page-rows.is-columns .cmp-rows {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 14px;
  align-items: stretch;
}
.cmp-page-rows.is-columns .cmp-row { height: 100%; }

@media (max-width: 620px) {
  .cmp-body { padding: 4px 13px 14px; }
  .cmp-text { font-size: 16px; }
}

/* ============================================================================
   14. READING-SETTINGS DIALOG + HEADER GEAR
   ============================================================================ */

/* ---- Reading-settings dialog (_settings_dialog.ejs) + header gear ---- */
.settings-gear {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 40 -> 44 so the bar's two icon controls (this and .auth-btn) align and the
     header clears WCAG 2.5.5. Budgeted as the one +4px in the ≤400px reclaim
     (docs/patreon-login-button-spec.md §9.3/§9.5). */
  width: 44px;
  height: 44px;
  flex: none;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.settings-gear:hover { color: var(--accent); border-color: var(--accent-border); background: var(--accent-soft); }
.settings-gear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.settings-dialog {
  /* A normal centered modal — it now holds only the grouped reading controls
     (translation + OT edition), so it needs no extra width. */
  width: min(560px, calc(100vw - 32px));
  /* Cap the height so this content-heavy dialog reads as a centered modal with
     breathing room top and bottom, rather than filling the viewport edge-to-edge;
     the body scrolls internally only when it exceeds the cap. */
  max-height: min(90vh, 860px);
  overflow: auto;
  /* margin:auto restores the centering the UA modal default provides — the
     global `* { margin: 0 }` reset zeroes it, which otherwise pins the dialog
     to the top-left corner. With position:fixed + inset:0 (UA), auto centers. */
  margin: auto;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--bg-raised);
  color: var(--text);
  padding: 0;
  box-shadow: var(--shadow);
}
.settings-dialog::backdrop { background: rgba(5, 10, 24, 0.6); }
.settings-form { padding: 22px 24px 24px; }
.settings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}
.settings-title { font: 700 20px/1.1 var(--ui-font); color: var(--text); }
.settings-close {
  appearance: none;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  border-radius: 8px;
}
.settings-close:hover { color: var(--accent); }
.settings-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Grouping fieldset — strip the UA chrome so it reads as a flush section, then
   add a divider above the second group. The legend is a small section heading. */
.settings-group { border: 0; margin: 0; padding: 0; min-width: 0; }
.settings-group + .settings-group { border-top: 1px solid var(--border-soft); margin-top: 16px; padding-top: 4px; }
.settings-legend {
  padding: 0;
  font: 600 13px/1.2 var(--ui-font);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}
.settings-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 16px 0;
  border-top: 1px solid var(--border-soft);
}
.settings-row:first-of-type { border-top: none; padding-top: 0; }
/* Inside a group the legend already separates the first row from the section
   above, so its top divider is redundant. */
.settings-group .settings-row:first-of-type { padding-top: 2px; }
.settings-label { font: 600 14px/1.2 var(--ui-font); color: var(--text); }
.settings-hint { margin: 0; font: 400 12px/1.4 var(--ui-font); color: var(--text-dim); }
/* Fill the row up to a comfortable cap rather than enforcing a hard floor, so
   the select never overflows the dialog on a narrow phone (a 220px floor breaks
   below ~290px viewports). */
.settings-select { width: 100%; max-width: 320px; min-width: 0; }
/* Compare bridge note — set off from the last group with a divider above. */
.settings-bridge { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border-soft); }

/* ============================================================================
   15. VERSE "ABOUT" TAB — CORPUS INSIGHTS
   ============================================================================ */

/* ---- Verse "About" tab — corpus-intelligence insight blocks ---- */
.verse-about .verse-stats { margin-bottom: 4px; }
.verse-insights {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 18px;
}
.vi-block {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 16px 18px;
}
.vi-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent);
}
.vi-head svg { width: 17px; height: 17px; flex: none; }
.vi-note {
  margin: 0;
  font-size: 14px;
  line-height: 1.65;
  color: var(--text-dim);
}
.vi-note strong { color: var(--text); font-weight: 700; }
.vi-note + .vi-note { margin-top: 8px; }
.vi-note--sub { font-size: 12.5px; color: var(--text-faint); }
/* "About this verse" provenance line — a .vi-note directly under the section
   header, which is margin:0, so it supplies the gap above .verse-stats itself. */
.verse-provenance { margin: 0 0 18px; }
.vi-inline-link { color: var(--accent); font-weight: 600; text-decoration: none; white-space: nowrap; }
.vi-inline-link:hover { text-decoration: underline; }
/* A <button> that reads as an inline text link (no native chrome) — used for
   the data-open-settings affordance inside running prose (e.g. the /w/
   concordance intro's "change" reading-translation trigger). Strips UA button
   styling so it sits flush in the sentence; keeps it keyboard-focusable. */
.inline-link-btn {
  appearance: none; -webkit-appearance: none;
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--accent); font-weight: 600;
  text-decoration: none; cursor: pointer;
}
.inline-link-btn:hover { text-decoration: underline; }
.inline-link-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
/* Word chips (rare/hapax/first-mention/repetition) + inline glyphs. */
.vi-chips {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.vi-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 7px 12px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
}
.vi-glyph { color: var(--text); }
.vi-glyph.hebrew { font-family: var(--hebrew-font); font-size: 19px; }
.vi-glyph.greek { font-family: var(--greek-font); font-size: 17px; }
.vi-gloss { color: var(--text-dim); font-size: 13px; font-style: italic; }
.vi-strongs {
  color: var(--accent);
  font-family: var(--mono-font);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
}
.vi-strongs:hover, .vi-strongs:focus { text-decoration: underline; outline: none; }
.vi-times { color: var(--accent); font-weight: 700; font-size: 13px; }
/* Cross-reference verse links. */
.vi-reflist {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
}
.vi-reflist a {
  display: inline-block;
  padding: 5px 10px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 7px;
  color: var(--accent);
  font-size: 13px;
  text-decoration: none;
  white-space: nowrap;
}
.vi-reflist a:hover, .vi-reflist a:focus { border-color: var(--accent-border); outline: none; }
.vi-more a { color: var(--text-dim); }
/* Grammar profile: part-of-speech tally + verb forms. */
.vi-pos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}
.vi-pos li {
  font-size: 13px;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 7px;
  padding: 5px 11px;
}
.vi-pos-n { color: var(--text); font-weight: 700; }
.vi-subhead {
  margin: 14px 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-dim);
}
.vi-verbs { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.vi-verbs li {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 11px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
}
.vi-verb-parse { color: var(--text-dim); font-size: 13px; }
/* Pair the two compact tally blocks (grammar + repetition) side by side; they
   stack again when the panel is too narrow for two readable columns. */
.vi-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 16px;
}
.vi-pair .vi-block { margin: 0; }

/* ============================================================================
   16. CROSS-REFERENCES PANEL
   ============================================================================ */

/* ---- Cross-references (topical — OpenBible.info / Treasury of Scripture
   Knowledge) ----
   A dedicated panel under the word-study tabs. The primary set renders as a
   reference + target-verse-text list; the long tail collapses into bare
   reference chips inside a <details> (every link stays in the HTML for
   crawlers). Reuses the --bg-card / --accent / chip vocabulary of .vi-block. */
.cross-refs {
  margin: 26px 0 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 20px 22px 18px;
}
/* Header is two stacked rows: the title row (icon + heading + count badge) and
   the intro paragraph on its own row beneath; the divider sits under both. */
.cross-refs-head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0 0 11px;
}
.cross-refs-head-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
}
.cross-refs-head-title { margin: 0; min-width: 0; font: 700 19px/1.15 var(--ui-font); color: var(--text); }
.cross-refs-count {
  flex: none;
  margin-left: auto;
  font: 600 12px/1 var(--ui-font);
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  padding: 5px 10px;
}
.cross-refs-intro {
  margin: 0 0 18px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
.cross-refs-intro strong { color: var(--text); font-weight: 700; }

/* One card per primary reference — gold-accented left edge, reference pill
   above the target-verse preview. */
.cross-refs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cross-ref {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 7px;
  padding: 13px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent-border);
  border-radius: 9px;
}
.cross-ref-link {
  align-self: flex-start;
  font: 700 12.5px/1 var(--ui-font);
  letter-spacing: 0.01em;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.cross-ref-link:hover, .cross-ref-link:focus { text-decoration: underline; outline: none; }
.cross-ref-text {
  font-family: var(--reading-font);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
/* Paginated card pages. SSR renders every page visible (the full verse↔verse
   mesh stays crawlable without JS); app.js reveals the control below and
   collapses to one 8-card page at a time. The flex gap keeps the stacked pages
   evenly spaced in the no-JS fallback. */
.cross-refs-pages { display: flex; flex-direction: column; gap: 10px; }

/* Prev / page-indicator / next control — SSR-hidden, revealed by app.js so it
   never shows as a dead control without JS (the global `[hidden] !important`
   rule keeps it hidden despite this `display: flex`). */
.cross-refs-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 18px 0 0;
}
.cross-refs-pgbtn {
  flex: none;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 9px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms, opacity 120ms;
}
.cross-refs-pgbtn:hover:not(:disabled),
.cross-refs-pgbtn:focus-visible:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.cross-refs-pgbtn:disabled { opacity: 0.4; cursor: default; }
.cross-refs-pgind {
  min-width: 3.4em;
  text-align: center;
  font: 600 12.5px/1 var(--ui-font);
  letter-spacing: 0.02em;
  color: var(--text-dim);
}
.cross-refs-attr {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 22px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}
.cross-refs-attr-icon { flex: none; color: var(--text-faint); }
.cross-refs-attr a { color: var(--text-faint); }
.cross-refs-attr a:hover { color: var(--accent); }
@media (max-width: 600px) {
  .cross-refs { padding: 18px 16px 16px; }
}

/* ============================================================================
   17. COMMENTARY PANEL
   ============================================================================ */

/* Per-verse public-domain commentary panel. SSR renders every source stacked
   (crawlers + no-JS read the full text); app.js collapses it to a single-source
   view driven by the source picker. Note prose uses the reading font. */
.commentary {
  margin: 26px 0 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 20px 22px 18px;
}
.commentary-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px 24px;
  flex-wrap: wrap;
  margin: 0 0 18px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--border-soft);
}
.commentary-head-lead { display: flex; align-items: flex-start; gap: 12px; min-width: 0; flex: 1 1 280px; }
.commentary-head-icon,
.commentary-source-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
}
.commentary-head-text { min-width: 0; padding-top: 1px; }
.commentary-head h2 { margin: 0 0 3px; font: 700 19px/1.15 var(--ui-font); color: var(--text); }
.commentary-intro {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
.commentary-intro strong { color: var(--text); font-weight: 700; }
/* Second intro paragraph: what Lemma did to the republished notes below it
   (AdSense remediation L8). .commentary-intro is margin:0, so the pair needs an
   explicit gap; the rule is separated by a hairline so the provenance claim
   reads as a statement about the corpus, not more reading guidance. */
.commentary-provenance {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-soft);
}

/* Source picker — a custom listbox revealed only by app.js (pure enhancement). */
.commentary-picker { flex: none; }
.commentary-picker-label {
  display: block;
  margin: 0 0 6px;
  font: 700 11px/1 var(--ui-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.commentary-picker-control { position: relative; }
.commentary-picker-button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 248px;
  padding: 11px 14px;
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  background: var(--bg-raised);
  color: var(--text);
  font: 600 15px/1.2 var(--ui-font);
  text-align: left;
  cursor: pointer;
}
.commentary-picker-button:hover { border-color: var(--accent); }
.commentary-picker-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.commentary-picker-book { flex: none; color: var(--accent); }
.commentary-picker-value { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.commentary-picker-chevron { flex: none; color: var(--text-dim); transition: transform 0.15s ease; }
.commentary-picker-button[aria-expanded="true"] .commentary-picker-chevron { transform: rotate(180deg); }

.commentary-picker-menu {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.45);
}
.commentary-picker-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 7px;
  font: 600 15px/1.25 var(--ui-font);
  color: var(--text);
  cursor: pointer;
}
.commentary-picker-option + .commentary-picker-option { margin-top: 2px; }
.commentary-picker-option:hover,
.commentary-picker-option.is-active { background: var(--accent-soft); }
.commentary-picker-option[aria-selected="true"] { color: var(--accent); font-weight: 700; }
.commentary-picker-option:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.commentary-picker-check { flex: none; color: var(--accent); opacity: 0; }
.commentary-picker-option[aria-selected="true"] .commentary-picker-check { opacity: 1; }

/* Source block + heading */
.commentary-source { margin: 0; }
.commentary-source + .commentary-source {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--border-soft);
}
.commentary-source-head { display: flex; align-items: center; gap: 12px; margin: 0 0 16px; }
.commentary-source-icon { width: 44px; height: 44px; border-radius: 12px; }
.commentary-source-meta { min-width: 0; }
.commentary-source-name { margin: 0; font: 700 18px/1.25 var(--reading-font); color: var(--text); }
.commentary-source-author { margin: 2px 0 0; font: 500 13px/1.3 var(--ui-font); color: var(--text-dim); }

/* Per-source "Copy note" control — small, unobtrusive, pushed to the right of
   the source-head row (the head is a flex row, so margin-left:auto seats it
   top-right). Matches the .strongs-cite-btn pill family (accent-soft fill,
   accent-border, invert on hover/focus). SSR-hidden; revealed by app.js
   (initCommentaryCopy). */
.commentary-copy {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  margin-left: auto;
  padding: 6px 11px;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 13px/1 var(--ui-font);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.commentary-copy:hover,
.commentary-copy:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}
.commentary-copy-icon { display: inline-flex; flex: none; }
/* Visually-hidden live region (the announce is for screen readers; the button's
   own label is the visible affordance). Keeps it out of layout without
   display:none, so aria-live still fires. */
.commentary-copy-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Quote card — decorative serif quotes flank the reading-font note prose. */
.commentary-quote {
  position: relative;
  margin: 0;
  padding: 2px 40px 4px 46px;
}
.commentary-quote::before {
  content: '\201C';
  position: absolute;
  top: 6px;
  left: 4px;
  font: 700 52px/1 var(--reading-font);
  color: var(--accent);
}
.commentary-quote::after {
  content: '\201D';
  position: absolute;
  right: 12px;
  bottom: -22px;
  font: 700 52px/1 var(--reading-font);
  color: var(--accent);
  opacity: 0.85;
}
.commentary-notes {
  margin: 0;
  padding-left: 22px;
  border-left: 2px solid var(--accent-border);
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.commentary-note {
  margin: 0;
  font-family: var(--reading-font);
  font-size: 16.5px;
  line-height: 1.75;
  color: var(--text-dim);
  /* Prose fills the commentary panel; line length is bounded by .app { max-width: var(--content-max) }. */
}

/* Attribution footer */
.commentary-attr {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 26px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}
.commentary-attr-icon { flex: none; color: var(--text-faint); }

@media (max-width: 600px) {
  .commentary { padding: 18px 16px 16px; }
  .commentary-head { flex-direction: column; gap: 16px; }
  .commentary-picker { width: 100%; }
  .commentary-picker-button { min-width: 0; }
  .commentary-picker-menu { left: 0; right: 0; }
  .commentary-quote { padding: 2px 24px 4px 38px; }
  .commentary-quote::before { font-size: 44px; }
  .commentary-quote::after { font-size: 44px; }
}

/* ----------------------------------------------------------------------------
   Lesson kit (teaching starters, #110) — verse/_lesson_kit.ejs. The FINAL study
   panel: a context frame, a numbered list of discussion questions, and a "things
   to notice" list. Reuses the cross-refs/commentary panel visual language (gold
   icon-chip header, card surface, accent-tinted disclosure). Every item is a
   restatement or open question, anchored to its on-page datum. SSR-only.
   ---------------------------------------------------------------------------- */
.lesson-kit {
  margin: 26px 0 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 20px 22px 18px;
}
.lesson-kit-head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 0 0 14px;
}
.lesson-kit-head-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
}
.lesson-kit-head-title { margin: 0; min-width: 0; font: 700 19px/1.15 var(--ui-font); color: var(--text); }

/* Copy + Print action buttons (v2). The actions group sits at the end of the
   flex head row (margin-left:auto pushes it right), exactly mirroring the
   .commentary-copy treatment: accent-soft background, invert on hover/focus,
   SSR-hidden + revealed by initLessonKitExport. */
.lesson-kit-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex: none;
}
.lesson-kit-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 6px 11px;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 13px/1 var(--ui-font);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.lesson-kit-btn:hover,
.lesson-kit-btn:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}
.lesson-kit-btn-icon { display: inline-flex; flex: none; }
/* Visually-hidden live region — out of layout, still fires aria-live. */
.lesson-kit-copy-status {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Disclosure — the non-negotiable honesty rail. Accent-tinted card, mirroring
   .word-story-disclosure's quiet-but-prominent treatment. */
.lesson-kit-disclosure {
  margin: 0 0 18px;
  padding: 12px 14px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
}
.lesson-kit-disclosure-lead {
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  font-size: 11px;
}

/* Context frame — a single short lead line in the reading font. */
.lesson-kit-context {
  margin: 0 0 18px;
  font-family: var(--reading-font);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--text);
}

.lesson-kit-subhead {
  margin: 18px 0 10px;
  font: 700 13px/1.2 var(--ui-font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}

.lesson-kit-questions {
  margin: 0;
  padding: 0 0 0 1.4em;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.lesson-kit-question {
  font-family: var(--reading-font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
}
.lesson-kit-question::marker { color: var(--accent); font-weight: 700; }

.lesson-kit-observations {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.lesson-kit-observation {
  position: relative;
  padding-left: 22px;
  font-family: var(--reading-font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-dim);
}
.lesson-kit-observation::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 0.62em;
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--accent);
}

.lesson-kit a { color: var(--accent); }

@media (max-width: 600px) {
  .lesson-kit { padding: 18px 16px 16px; }
  .lesson-kit-question { font-size: 15.5px; }
}

/* ----------------------------------------------------------------------------
   NT printed-edition textual-variant apparatus (verse/_variants.ejs) — the NT
   mirror of the MT↔LXX compare panel, a full-width panel below the study zone.
   Each card shows the variant Greek, which printed editions contain it (chips,
   absent ones struck through), and TAGNT's prose note. PRINTED editions only.
   ---------------------------------------------------------------------------- */
.variant-apparatus {
  margin: 26px 0 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 20px 22px 18px;
}
.variant-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 18px;
  flex-wrap: wrap;
  margin: 0 0 14px;
}
.variant-title { margin: 0; font: 700 18px/1.25 var(--reading-font); color: var(--text); }
.variant-count {
  flex: none;
  font: 600 11px/1 var(--ui-font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
  padding: 5px 10px;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
}
.variant-disclosure {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
  max-width: 80ch;
}
.variant-disclosure strong { color: var(--text); font-weight: 700; }

.variant-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 14px; }
.variant-card {
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
}
.variant-card-head { margin: 0 0 9px; }
.variant-kind {
  display: inline-block;
  font: 700 10.5px/1 var(--ui-font);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 6px;
  color: var(--text-dim);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
}
.variant-kind--addition,
.variant-kind--wording { color: var(--accent); }

.variant-greek { margin: 0; font-family: var(--reading-font); font-size: 21px; line-height: 1.5; color: var(--text); }
.variant-gloss { margin: 4px 0 0; font: italic 400 14px/1.5 var(--reading-font); color: var(--text-dim); }

.variant-editions { display: flex; flex-wrap: wrap; gap: 7px 16px; margin: 12px 0 0; }
.variant-ed-group { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 5px; }
.variant-ed-label {
  font: 700 10.5px/1 var(--ui-font);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-right: 2px;
}
.variant-ed {
  font: 600 12px/1 var(--mono-font);
  padding: 4px 7px;
  border-radius: 5px;
  border: 1px solid var(--border-soft);
  cursor: help;
}
.variant-ed--in { color: var(--accent); border-color: var(--accent-border); background: var(--accent-soft); }
.variant-ed--out { color: var(--text-faint); text-decoration: line-through; text-decoration-thickness: 1px; opacity: 0.85; }

.variant-note { margin: 12px 0 0; font-size: 14px; line-height: 1.65; color: var(--text-dim); max-width: 80ch; }
.variant-attr {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 18px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}
.variant-attr a { color: var(--text-dim); }

@media (max-width: 600px) {
  .variant-apparatus { padding: 18px 16px 16px; }
  .variant-greek { font-size: 19px; }
}

/* Targum (Aramaic OT paraphrase) parallel panel (#67). Brought onto the icon-led
   "gold head" standard shared by cross-references / commentary / MT↔LXX compare
   (icon badge + sans h2 + gold count badge + intro). The Aramaic line is a
   featured right-to-left (Hebrew script) blockquote with an RTL right-edge accent
   rule (the mirror of commentary's left rule); the English sits below it; the
   per-source attribution closes each card with the shared globe attr-icon row. */
.targum-panel {
  margin: 26px 0 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  padding: 20px 22px 18px;
}
.targum-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 11px;
}
.targum-head-lead { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1 1 280px; }
.targum-head-icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 11px; background: var(--accent-soft); color: var(--accent); }
.targum-head-text { min-width: 0; }
.targum-head h2 { margin: 0; font: 700 19px/1.15 var(--ui-font); color: var(--text); }
.targum-count { flex: none; margin-left: auto; font: 600 12px/1 var(--ui-font); color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-border); border-radius: 999px; padding: 5px 10px; }
.targum-disclosure {
  margin: 0 0 18px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
.targum-disclosure strong { color: var(--text); font-weight: 700; }

.targum-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 14px; }
.targum-card {
  padding: 14px 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
}
.targum-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 14px;
  flex-wrap: wrap;
  margin: 0 0 10px;
}
.targum-source-name { font: 700 14px/1.3 var(--reading-font); color: var(--text); }
.targum-coverage {
  font: 600 10.5px/1 var(--ui-font);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.targum-aramaic {
  margin: 0;
  font-family: var(--hebrew-font);
  font-size: 26px;
  line-height: 1.7;
  color: var(--text);
  direction: rtl;
  text-align: right;
  padding-right: 16px;
  border-right: 2px solid var(--accent-border);
}
.targum-english { margin: 10px 0 0; font-size: 15px; line-height: 1.65; color: var(--text-dim); max-width: 80ch; }
.targum-english--none { font-style: italic; color: var(--text-faint); }

/* #132 — UNREVIEWED machine-translated Onkelos English. Rendered in a tinted
   caution panel with a dashed + solid left accent so a reader can tell it from the
   plain published-PD .targum-english at a glance (the honesty rail). Reuses the
   established --warn status idiom (soft amber fill + amber border + amber label,
   the banner pattern used elsewhere in this file) — deliberately caution/neutral,
   never celebratory. Theme-consistent via the shared CSS custom properties. */
.targum-english--mt {
  margin: 12px 0 0;
  padding: 12px 14px;
  background: var(--warn-soft);
  border: 1px dashed var(--warn-border);
  border-left: 3px solid var(--warn-border);
  border-radius: 8px;
  max-width: 80ch;
}
.targum-mt-label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
  font: 700 11px/1.45 var(--ui-font);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--warn);
}
.targum-mt-conf {
  flex: none;
  font: 600 10.5px/1 var(--ui-font);
  letter-spacing: 0.02em;
  text-transform: none;
  border-radius: 999px;
  padding: 4px 9px;
  border: 1px solid var(--border-soft);
  color: var(--text-faint);
  background: var(--bg-raised);
}
.targum-mt-conf--high { color: var(--success); background: var(--success-soft); border-color: var(--success-border); }
.targum-mt-conf--medium { color: var(--warn); background: var(--warn-soft); border-color: var(--warn-border); }
.targum-mt-conf--low { color: var(--error); background: var(--error-soft); border-color: var(--error-border); }
.targum-english-text {
  margin: 9px 0 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
  max-width: 80ch;
}
.targum-mt-note {
  margin: 9px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}

.targum-attr {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin: 14px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
}
.targum-attr-icon { flex: none; margin-top: 1px; color: var(--text-faint); }

@media (max-width: 600px) {
  .targum-panel { padding: 18px 16px 16px; }
  .targum-head { gap: 14px; }
  .targum-aramaic { font-size: 23px; }
}

/* ============================================================================
   18. WORD GRID
   ============================================================================ */

/* ---- Word grid ----
   `justify-content: flex-start` lets flex-items honor the writing direction:
   in LTR the first word sits at the left edge and the row fills right (Greek
   reading order); in RTL (the `.rtl` class is added for Hebrew verses) the
   first word sits at the right edge and the row fills left, matching how the
   text would actually be written and read. */
.word-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: flex-start;
}
.word-grid.rtl { direction: rtl; }

/* ============================================================================
   19. VERSE PAGER
   ============================================================================ */

/* ---- Verse pager ----
   Sits BELOW the word grid (reading-flow order: finish the verse, then page). */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--border-soft);
}
.pager-btn {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: var(--radius);
  padding: 10px 16px;
  min-height: 44px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s;
}
.pager-btn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent-border); }
.pager-btn:disabled { opacity: 0.4; cursor: default; }
.pager-label {
  color: var(--text-dim);
  font-size: 13px;
  min-width: 140px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.pager-label .pager-ref { color: var(--text); font-weight: 600; }

/* ============================================================================
   20. WORD CARD
   ============================================================================ */
.word {
  /* Rendered as a native <button> for focusability + Enter/Space activation;
     reset the UA button chrome so it looks identical to the original card. */
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  color: inherit;
  width: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 92px;
  max-width: 150px;
  padding: 16px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 14px;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s, background 0.15s, transform 0.08s;
}
.word:hover { border-color: var(--accent-border); background: #20293400; background-color: #1f2a47; }
.word:active { transform: translateY(1px); }
.word.selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: 0 0 0 1px var(--accent-border);
}

/* ============================================================================
   21. KEYBOARD FOCUS RING
   ============================================================================ */

/* ---- Keyboard focus ring ----
   :focus-visible (not :focus) so mouse clicks don't show the ring, only
   keyboard/AT focus does. High-contrast accent outline on every control. */
.word:focus-visible,
.chip:focus-visible,
.pager-btn:focus-visible,
.search-btn:focus-visible,
.lexicon-close:focus-visible,
#lexiconTitle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.word .original {
  font-size: 24px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.25;
}
.word.hebrew .original { font-family: var(--hebrew-font); direction: rtl; font-size: 28px; }
.word.greek .original { font-family: var(--greek-font); }

.word .translit {
  font-size: 13px;
  font-style: italic;
  color: var(--text-faint);
  direction: ltr;
}
.word .strongs {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  direction: ltr;
  margin-top: 2px;
}
/* Gloss wraps to as many lines as it needs (demo look) instead of truncating —
   the curated glosses are short, but multi-word BDB fallbacks still read fully. */
.word .gloss {
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-dim);
  direction: ltr;
}

/* Textual-variant marker on a word button — a small, understated "≠" in the top
   corner with a hover/focus tooltip (title attr). This is ~a few dozen words
   NT-wide, so it must whisper, not shout: muted color, no fill, no alarm. The
   button is position:static by default, so anchor the marker. */
.word.is-variant {
  position: relative;
  border-style: dashed;
}
.word-variant-mark {
  position: absolute;
  top: 5px;
  inset-inline-end: 7px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: var(--text-faint);
  pointer-events: none;
}

/* ============================================================================
   22. STATUS / ERRORS
   ============================================================================ */

/* ---- Status / errors ---- */
.status {
  padding: 30px 20px;
  text-align: center;
  color: var(--text-dim);
}
/* Error banner — mirrors the .data-warning visual language but in a red palette. */
.status.error {
  color: var(--error);
  background: var(--error-soft);
  border: 1px solid var(--error-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  text-align: left;
  font-size: 14px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.status.error .status-icon { flex: none; line-height: 1.5; }
.status.error .status-hint {
  display: block;
  margin-top: 4px;
  color: var(--text-dim);
  font-size: 13px;
}

/* ============================================================================
   23. LEXICON PANEL (home / verse)
   ============================================================================ */

/* ---- Lexicon panel ---- */
.lexicon {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-width: 600px;
  position: static;
  overflow: hidden;
}
.lexicon-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--accent-soft);
}
.lexicon-head h2 { font-size: 15px; color: var(--accent); font-weight: 600; }
.lexicon-close {
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  /* 44x44 hit area without enlarging the visible glyph */
  width: 44px;
  height: 44px;
  margin: -10px -10px -10px 0;
  display: grid;
  place-items: center;
}
.lexicon-close:hover { color: var(--text); }

.lexicon-body { padding: 16px; }

.lex-lemma {
  font-size: 30px;
  text-align: center;
  margin-bottom: 4px;
  color: var(--text);
}
.lex-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.lex-lemma.greek { font-family: var(--greek-font); }
/* Gloss sits directly under the lemma — the headline meaning, before the
   Strong's / transliteration / pronunciation meta line. */
.lex-gloss {
  text-align: center;
  font-style: italic;
  color: var(--accent);
  font-size: 16px;
  margin-bottom: 6px;
}
.lex-sub {
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
  margin-bottom: 14px;
}
.lex-sub .strongs { color: var(--accent); font-weight: 600; }
/* The lex-sub Strong's is now an <a> linking to /w/:strongs — keep it visually
   identical to the old <span> by default, underline on hover/focus. */
.lex-sub a.strongs { text-decoration: none; }
.lex-sub a.strongs:hover,
.lex-sub a.strongs:focus { text-decoration: underline; outline: none; }

/* Inline Strong's references inside lexicon prose (Origin, BDB body, etc.).
   Gold + no underline by default, underline on hover/focus. */
.strongs-link {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  font-family: var(--mono-font);
}
.strongs-link:hover,
.strongs-link:focus { text-decoration: underline; outline: none; }

/* The verse/home lexicon panel's morphology, origin, TWOT/TDNT, and definition
   now render as icon-badged .lex-card blocks (shared with the Strong's page),
   so the old .lex-row / .lex-definition label-value styles were removed. */

/* ============================================================================
   24. ABOUT / FAQ STATIC CONTENT
   ============================================================================ */

/* ---- About / FAQ (static descriptive content for SEO + first-time visitors) ---- */
.about,
.faq {
  max-width: 760px;
  margin: 48px auto 0;
}
/* The FAQ stretches to the full content width (matching the site header /
   title bar), unlike the narrower About article. Override only .faq so the
   About page keeps its comfortable reading measure. */
.faq {
  max-width: none;
}
/* /about, /faq, /contact and /terms all render a <section class="about|faq">
   whose first child is the page heading. That heading became the page <h1> on
   2026-08-21; the h2 selectors stay beside it so a second-level heading added
   here still matches the house style. */
.about h1,
.about h2,
.faq h1,
.faq h2 {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 12px;
}
/* Centered, serif FAQ/About title with a gold ornamental divider beneath it
   (both pages share the .faq-title-ornament markup). */
.faq h1,
.faq h2,
.about h1,
.about h2 {
  font-family: var(--reading-font);
  font-size: 32px;
  letter-spacing: 0;
  text-align: center;
  color: var(--text);
  margin: 4px 0 16px;
}
/* Gold ornament under the title: a center gem (rotated square) flanked by
   gold rules that fade outward. Purely decorative (the element is aria-hidden). */
.faq-title-ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  max-width: 340px;
  margin: 0 auto 30px;
}
.faq-title-line {
  flex: 1 1 auto;
  height: 1px;
}
.faq-title-ornament > .faq-title-line:first-child {
  background: linear-gradient(to right, transparent, var(--accent));
}
.faq-title-ornament > .faq-title-line:last-child {
  background: linear-gradient(to left, transparent, var(--accent));
}
.faq-title-gem {
  flex: none;
  width: 9px;
  height: 9px;
  transform: rotate(45deg);
  background: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Question filter box (progressive enhancement; SSR-[hidden] until app.js
   reveals it). Rounded search field; the empty-state line shows on no match. */
.faq-filter {
  margin: 0 0 16px;
}
.faq-filter-input {
  width: 100%;
  min-height: 42px;
  padding: 9px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-card);
  color: var(--text);
  font-family: var(--ui-font);
  font-size: 14px;
}
.faq-filter-input::placeholder { color: var(--text-faint); }
.faq-filter-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}
.faq-filter-empty {
  margin-top: 10px;
  color: var(--text-dim);
  font-size: 14px;
}
.about h3 {
  font-size: 15px;
  font-weight: 600;
  color: var(--accent);
  margin-top: 22px;
  margin-bottom: 8px;
  /* Clear the sticky .faq-pills jump bar when a pill (or /about#sources deep
     link) lands on a section heading — mirrors .faq-section-head. */
  scroll-margin-top: calc(var(--header-h) + 72px);
}
/* Sub-headings inside an /about section — today the two groups under
   "What Lemma is not" (the data's limits vs the absent capabilities). Reads
   one step below .about h3: same UI face, no accent colour, so a reader can
   see it subdivides the section rather than starting a new one. Without a rule
   here an h4 falls to the browser default, which inside .about is the same
   size as body text and would read as bold prose, not a heading. */
.about h4 {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
  margin-top: 18px;
  margin-bottom: 8px;
}
/* A Hebrew word quoted INSIDE a run of English prose — the examples in the
   "What Lemma adds" cards. Every other Hebrew surface on the site is a grid
   cell or a hero with its own sizing rule, so none of them is reusable here.
   The font matters more than it looks: without --hebrew-font (Ezra SIL) a
   pointed word falls through to whatever the system offers for Hebrew, which
   routinely misplaces the vowel points — the one thing this site cannot afford
   to render wrong. Slightly up-sized because niqqud at body size is
   unreadable. Applied to a bdi with dir="rtl", matching views/morphology.ejs:
   the isolate keeps the surrounding English punctuation on the correct side.
   No Greek counterpart until prose actually quotes a Greek word inline. */
.about-heb {
  font-family: var(--hebrew-font);
  font-size: 1.15em;
  line-height: 1;
  color: var(--text);
}
.about p {
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.7;
  margin-bottom: 12px;
}
.about strong,
.faq strong { color: var(--text); font-weight: 600; }
.about em,
.faq em { color: var(--text); font-style: italic; }
/* Body-prose links inherit the accent (gold) used elsewhere in the app —
   .tabpanel p a, .strongs-link, .support-link, .lex-sub a all share this
   no-underline-until-hover pattern. Without this rule the UA default
   (browser blue) leaks through on FAQ and About. :focus-visible mirrors
   :hover so keyboard users get the same affordance. */
.about a,
.faq a {
  color: var(--accent);
  text-decoration: none;
}
.about a:hover,
.about a:focus-visible,
.faq a:hover,
.faq a:focus-visible { text-decoration: underline; }

/* FAQ segmented pill nav (scroll-spy, not tabs). Horizontal chip strip; the
   in-view section's pill lights up via app.js's initVerseJumpNav (.is-active /
   aria-current). Each pill inherits .faq a (gold), so the active-link override
   below restores its color.
   STICKY: the strip pins to the top of the viewport (the header is not sticky
   and scrolls away) so a reader can jump between sections without scrolling
   back up. The opaque page-bg + bottom border keep cards from showing through
   as they scroll under it; section/card scroll-margin-top (below) clears it.
   SINGLE ROW at every width: the strip scrolls sideways rather than wrapping,
   so the sticky bar's height is constant and the scroll-margin-top below always
   clears a jumped-to section/card (a wrapped 2-row strip would under-clear it). */
.faq-pills {
  position: sticky;
  top: var(--header-h);
  z-index: 5;
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  gap: 8px;
  margin: 0 0 18px;
  padding: 12px 0;
  background: var(--bg);
  border-bottom: 1px solid var(--border-soft);
  /* Part 1 + Part 2 — same scrollbar-hide + auto-hiding edge fade as .site-subnav.
     This sticky pill row is the other horizontal scroller whose native scrollbar
     we now hide, so it needs the same no-JS overflow cue. Its own background-color
     is already var(--bg), so the `local` covers blend in invisibly but still mask
     the `scroll` shadow layers at each end. The longhands sit AFTER the `background`
     shorthand above so that shorthand's image/position/size/repeat/attachment reset
     doesn't clobber them. Cover width matches .site-subnav's 56px (widened from an
     earlier 36px) for the same reason: on this near-black band the dissolve of the
     pills' own lighter text/chips is the legible cue, not the 14px black radial
     shadow, so it needs a longer run to read clearly. */
  scrollbar-width: none;
  background-image:
    linear-gradient(to right, var(--bg), transparent),
    linear-gradient(to left, var(--bg), transparent),
    radial-gradient(farthest-side at left center, rgba(0, 0, 0, 0.5), transparent),
    radial-gradient(farthest-side at right center, rgba(0, 0, 0, 0.5), transparent);
  background-position: left center, right center, left center, right center;
  background-size: 56px 100%, 56px 100%, 14px 100%, 14px 100%;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.faq-pills::-webkit-scrollbar { display: none; }
.faq-pill {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-card);
  color: var(--text-dim);
  font-family: var(--ui-font);
  font-size: 14px;
  text-decoration: none;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.faq-pill:hover { color: var(--accent); border-color: var(--accent-border); }
.faq-pill-ico { display: inline-flex; flex: none; }
.faq-pill-ico svg { width: 18px; height: 18px; display: block; }
/* Active pill: NON-color-only cue (the critic's flag) — gold border + gold text
   + bolder weight + a 2px gold underline tick via ::after, so it's still
   distinguishable without relying on hue alone. */
.faq-pill.is-active,
.faq-pill[aria-current] {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-soft);
  font-weight: 600;
}
.faq-pill.is-active::after,
.faq-pill[aria-current]::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 5px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}
.faq-pill:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Expand/Collapse-all control. Right-aligned; [hidden] in SSR until app.js
   reveals it (so no-JS users never see a dead control — everything is open). */
.faq-controls {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 16px;
}
.faq-toggle-all {
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: transparent;
  color: var(--text-dim);
  font-family: var(--ui-font);
  font-size: 13px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms;
}
.faq-toggle-all:hover { color: var(--accent); border-color: var(--accent-border); }
.faq-toggle-all:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Section heading with a gold left accent bar + the matching section icon.
   scroll-margin-top clears the sticky pill bar when a pill jumps here. */
.faq-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 30px 0 12px;
  padding-left: 12px;
  border-left: 3px solid var(--accent);
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  scroll-margin-top: calc(var(--header-h) + 72px);
}
.faq-section-ico { display: inline-flex; flex: none; color: var(--accent); }
.faq-section-ico svg { width: 20px; height: 20px; display: block; }

/* Accordion cards. Every <details> ships SSR-`open`; collapsing is enhancement.
   The native disclosure triangle is removed (we draw our own .faq-toggle). */
.faq-items { margin-bottom: 8px; }
.faq-item {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  margin-bottom: 10px;
  /* Clear the sticky pill bar when a /faq#question deep link lands here. */
  scroll-margin-top: calc(var(--header-h) + 72px);
}
.faq-item > summary { list-style: none; }
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  padding: 12px 16px;
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.faq-q-text { flex: 1 1 auto; }
.faq-q:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* Circular +/- affordance. Glyph drawn in CSS off the [open] state — no glyph
   in the HTML, so the accordion state and the affordance can never disagree. */
.faq-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--accent);
  font-family: var(--ui-font);
  font-size: 18px;
  line-height: 1;
}
.faq-item > summary .faq-toggle::before { content: "+"; }
.faq-item[open] > summary .faq-toggle::before { content: "\2212"; }
.faq-a {
  padding: 0 16px 14px;
  /* Answer prose fills the full card width (matching the question header), so a
     card never reads as half-empty on the wide content column. */
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
}

.feature-list {
  list-style: none;
  display: grid;
  gap: 10px;
  margin-top: 4px;
}
.feature-list li {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.6;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* Print: show every answer regardless of collapse state, and drop the
   interactive affordances that mean nothing on paper. SSR ships every
   <details open>, so the normal path already prints in full; these rules
   also force-reveal a details a reader (or no-JS native toggle) collapsed
   before printing. Belt-and-suspenders across engines: older ones hide the
   answer via the child's display (covered by .faq-a), modern Chromium/Firefox
   gate it behind ::details-content's content-visibility (covered below); on
   engines without that pseudo the rule is a harmless no-op. */
@media print {
  .faq-a { display: block !important; }
  .faq-item:not([open])::details-content { content-visibility: visible !important; }
  .faq-toggle,
  .faq-toggle-all,
  .faq-pills { display: none !important; }
}

/* Mobile: tighten the (already single-row, sideways-scrolling) sticky pill bar
   and title; pills stay tappable (44px); cards go full-width. */
@media (max-width: 600px) {
  .faq-pills { padding: 10px 0; }
  .faq-pill { font-size: 13px; padding: 6px 12px; }
  .faq h1, .faq h2 { font-size: 26px; }
  .faq-controls { justify-content: stretch; }
  .faq-toggle-all { width: 100%; }
}

/* ============================================================================
   25. SITE FOOTER
   ============================================================================ */

/* ---- Footer ---- */
/* Full-bleed band, mirroring .site-header's breakout (§8): the negative
   margins span the viewport past .app's max-width; .footer-inner (§30)
   re-centers the contents to the content column. overflow-x: clip on the
   root (set above) absorbs the scrollbar-width sliver, same as the header. */
.site-footer {
  margin-top: 48px;
  padding-top: 18px;
  padding-bottom: 24px;
  border-top: 1px solid var(--border-soft);
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  background: var(--bg-raised);
}
.credits {
  color: var(--text-faint);
  font-size: 12px;
  line-height: 1.7;
}
.credits a { color: var(--text-dim); }
.credits a:hover { color: var(--accent); }

/* ============================================================================
   26. RESPONSIVE — HOME / GLOBAL @MEDIA
   ============================================================================ */

/* ---- Responsive ---- */
@media (max-width: 760px) {
  .app {
    padding:
      0
      calc(16px + env(safe-area-inset-right))
      calc(48px + env(safe-area-inset-bottom))
      calc(16px + env(safe-area-inset-left));
  }
  /* Compact single-row sticky bar on mobile: shorter offset token, no tagline,
     and the secondary nav (About/FAQ/Support — all present in the footer)
     collapsed; Learn stays as the one reading-adjacent destination. */
  :root { --header-h: 56px; }
  /* Compact-on-scroll, mobile: 56 → 50px. The desktop is-scrolled token (52px)
     lives outside any media query, so this override is needed to keep the
     compact bar shorter than the mobile base too. */
  html.is-scrolled { --header-h: 50px; }
  /* The section-nav row's pills/padding are unchanged on mobile, so the row is
     about the same height; 46 just trims the desktop value's extra slack. The
     row scrolls sideways, so it stays one line and the height is constant. */
  body.v-page { --subnav-h: 46px; }
  .site-header-inner {
    padding-left: calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
  .brand-mark-img { width: 34px; height: 34px; }
  .brand-text p { display: none; }
  /* Must out-specify the base `.site-nav a` (0,1,1) rule, hence the qualified
     selector — a bare `.nav-secondary` (0,1,0) would lose the cascade and the
     links would stay visible and overflow the single-row bar. */
  .site-nav a.nav-secondary { display: none; }
  .lexicon { max-width: none; }
  .search-btn { padding: 0 18px; }
  .brand-text .brand-name { font-size: 22px; }
  /* Word cards: tighter min-width so more fit per row without overflow. */
  .word { min-width: 64px; padding: 9px 10px; }
  .word .original { font-size: 18px; }
  .word.hebrew .original { font-size: 20px; }
  .word .gloss { max-width: 88px; }
}

/* Narrow phones (~360px and the 280px Galaxy Fold edge). */
@media (max-width: 400px) {
  .app {
    padding:
      0
      calc(12px + env(safe-area-inset-right))
      calc(40px + env(safe-area-inset-bottom))
      calc(12px + env(safe-area-inset-left));
  }
  .search-form { gap: 8px; }
  .search-input { padding: 13px 13px; }
  .search-btn { padding: 0 14px; }
  .placeholder { padding: 40px 16px; }
  .placeholder-original { font-size: 24px; }
  /* Keep the pager on one row: trim button text padding and label reserve. */
  .pager { gap: 8px; }
  .pager-btn { padding: 10px 12px; }
  .pager-label { min-width: 0; font-size: 12px; }

  /* ---- Header packing for the Patreon sign-in control (spec §9.3) ----
     The auth control PAYS ITS OWN WAY here: the MT/LXX toggle and Learn both STAY,
     per owner ruling. Every reclaim below is tightening or a brand collapse — no
     control is removed, hidden, or made unreachable.

     SPECIFICITY NOTE: the @media (max-width: 600px) block that packs the header
     lives ~6000 lines BELOW this one, so a bare `.brand-mark-img` / `.site-nav a`
     here would be silently overridden by it at ≤400px (it sets 32px and
     `padding: 6px 10px`). The two rules that collide with it are therefore
     descendant-qualified to (0,2,0)/(0,2,1) — the same cascade discipline §9.2
     mandates for the .header-auth rules — so the ≤400px reclaim actually applies.

     CONSEQUENCE, and it is NOT the "intended nesting" this comment used to claim:
     raising the specificity also out-specifies the ≤360px block (~line 9500), since
     `.site-nav` and both `.nav-dropdown-toggle` instances live inside `.header-end`.
     THIS BLOCK NOW OWNS THE NAV-LINK PADDING AT EVERY WIDTH ≤400px — 360px included.
     A bare `.site-nav a` rule down there can no longer win; the three declarations
     that used to duplicate this block's work were deleted (see the comment on that
     block), two of which were also LOOSER and were quietly inverting the reclaim
     below 360px. To tighten further at ≤360px, qualify with `.header-end` there too.
     Nothing else in this block collides with any later query. */
  .site-header-inner {
    padding-left: calc(10px + env(safe-area-inset-left));
    padding-right: calc(10px + env(safe-area-inset-right));
    column-gap: 10px;
  }
  /* Brand collapses to its mark. NOT display:none — the wordmark is the only place
     the site is NAMED in the document (the page's own <h1> names the page, not the
     site), so removing it from the a11y tree would leave a reader with no way to
     tell what they are on. That reasoning used to be about headings and is not any
     more: since 2026-08-21 .brand-text holds a span, and hiding it here costs no
     page its <h1>. The treatment is unchanged for the surviving reason. This is the
     .visually-hidden ruleset, inlined because it applies to a different element at a
     different breakpoint. .brand-link keeps its own aria-label="Lemma home", and the
     mark remains a full-size home target. */
  .brand-text {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .site-header-inner .brand-mark-img { width: 30px; height: 30px; }
  /* SECOND RECLAIM, 2026-08-11, paying for the page-share control (§8's
     .header-share) — a FIFTH child of .header-end. Same contract as the first: all
     four values below are tightening, none removes, hides or shrinks a control.
     MEASURED on / at 360px with the control and these four at their previous values
     (8px / 2px / 6px 7px / 8px 8px): the brand link collapsed to 2.6px and the 30px
     mark overhung the MT|LXX toggle by 17.4px. Reclaiming 22px moves the width at
     which the mark starts to overhang from 377px back to 355px — clear at every
     common phone width (360, 375, 390, 393) as master was.
     320px is NOT recovered and was already broken: master overhangs by 17.4px there
     (the row needs 57px it does not have), and this change takes it to 20px. Closing
     that needs a control to leave the bar, which is the owner ruling above. */
  .header-end { gap: 6px; }
  .site-nav { gap: 0; }
  .header-end .site-nav a,
  .header-end .nav-dropdown-toggle { padding: 6px 6px; font-size: 12px; }
  /* Tightened, NOT removed — both segments keep their labels, their 28px height, and
     their behaviour. Horizontal padding only. */
  .ot-toggle-btn { padding: 8px 6px; }
  /* Re-assert the 44px box at (0,2,0) so it survives the .nav-dropdown-toggle padding
     override above (see the cascade note in §9.2). */
  .header-auth .auth-btn,
  .header-auth .auth-menu-toggle { width: 44px; padding: 0; }
}

/* Touch devices: enlarge small controls to the 44px comfortable minimum. */
@media (pointer: coarse) {
  .chip { min-height: 44px; }
  /* THE VERTICAL HALF IS FREE, which is the whole reason this is here and the 32px
     WIDTH is not also raised. §8's .header-share-toggle note explains why the box is
     32px: the row's rendered height is load-bearing (--subnav-h, every jump target's
     scroll-margin-top, the compact state) and the control is a fifth child of an
     already-packed .header-end, so its width was the price of joining that row. But
     its NEIGHBOURS are already 44px tall (.auth-btn, .settings-gear), so growing only
     the block axis costs zero header height and zero row width while taking the
     touch target from 32x32 to 32x44. Confirmed: the bar is still 56px at 390px
     coarse. Same idiom as .chip above. */
  .header-share-toggle { min-block-size: 44px; }
}

/* Respect users who ask for reduced motion: kill transitions/animations and
   smooth scrolling. The JS gates scrollIntoView to behavior:'auto' to match. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================================
   27. SSR VERSE PAGE (/v/:slug/:ch/:v) — breadcrumbs, pager, word-by-word, tabs
   ----------------------------------------------------------------------------
   Server-rendered verse page (/v/:bookSlug/:chapter/:verse)
   These selectors only appear in views/verse.ejs; the home page is unaffected.
   ============================================================================ */

/* Wrap the brand mark + text in an anchor so users can click back to home.
   Inherits surrounding flex layout from .brand. */
.brand-link {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: inherit;
}
.brand-link:hover .brand-text .brand-name { color: var(--accent); }

/* Breadcrumb trail. Helps both users and search engines understand the page's
   place in the corpus; the BreadcrumbList JSON-LD mirrors this DOM. */
.breadcrumbs {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--text-dim);
}
.breadcrumbs ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 10px;
}
.breadcrumbs li + li::before {
  content: '/';
  margin-right: 10px;
  color: var(--text-faint);
}
.breadcrumbs a {
  color: var(--text-dim);
  text-decoration: none;
  border-bottom: 1px dotted var(--border);
}
.breadcrumbs a:hover { color: var(--accent); border-bottom-color: var(--accent-border); }
.breadcrumbs [aria-current="page"] { color: var(--text); }

/* Server-side pager uses real <a> links rather than <button>s. Match the
   client pager visually so the page doesn't jump on hydration. */
.verse-pager .pager-btn {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 45%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.verse-pager .pager-btn.disabled {
  opacity: 0.4;
  pointer-events: none;
}
.verse-pager .pager-btn { padding: 12px 18px; font-size: 14px; }
.pager-arrow { font-size: 16px; line-height: 1; }
/* The forward link reads gold by default (demo look); the back link stays dim
   until hover. Disabled spans keep the muted look from .disabled above. */
.verse-pager .pager-next:not(.disabled) { color: var(--accent); border-color: var(--accent-border); }
.verse-pager .pager-next:not(.disabled):hover { background: var(--accent-soft); }

/* Plain-text word-by-word table — crawler-readable and visually de-emphasized.
   This is the substantive uniqueness layer per verse page. */
.verse-words-table {
  margin: 32px 0 24px;
  padding: 18px 20px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.verse-words-table h2 {
  margin: 0 0 12px;
  font-size: 15px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
/* Verse detail — a single column now: the Word-by-word tab's focus card folds
   in what the separate lexicon panel used to show, so there's no 2-col split. */
.verse-detail { margin-top: 20px; }

/* ===== On-this-page section nav + two-column study zone =====
   The verse page can run long (word study + cross-references + commentary).
   Two complementary affordances, both pure CSS/JS over unchanged SSR DOM —
   the crawlable source order and visibility never change:
     1. An "On this page" section nav (.site-subnav) jumps between the study
        sections. It rides INSIDE the sticky header band as a second row
        (views/_section_nav.ejs, included by _header on the verse page) so the
        page shows one sticky bar, not a header stacked over a standalone strip.
        Anchor links work with no JS; app.js lights up the in-view section
        (scroll-spy, keyed off the data-jump-nav/data-jump-link hooks).
     2. On wide screens the word-study panel and the cross-references rail sit
        side by side (.verse-study-grid.has-rail) so the reader sees a word's
        sense and its scriptural echoes at once — the simultaneity the desktop
        study tools (Logos/STEP) charge for, delivered crawlable and free. */

/* The section-nav is only rendered on the verse page, and body.v-page is the
   stable ancestor that scopes the offset token (chosen over :has() for robustness
   — no evergreen-:has dependency). The value is the real height of the
   .site-subnav row: pill (~31px) + 7px top/bottom padding ≈ 45px, rounded to 48
   to also cover the 1px separator + sub-pixel rounding so a deep-linked section
   never tucks a hair under the bar. Mobile override is in the 760px block. */
body.v-page { --subnav-h: 48px; }

/* The section-nav row inside the header band. It is NOT independently sticky and
   carries NO background of its own — it rides inside .site-header (which is the
   sticky, opaque, bottom-bordered band), so it's part of the one bar. A separator
   line sets it off from the brand row above. Single horizontally-scrollable row at
   every width (like .faq-pills) so it never wraps and inflates the bar height
   unpredictably — the height is constant, which keeps --subnav-h / the
   scroll-margin-top math honest. Only rendered on the verse page (body.v-page). */
.site-subnav-wrap {
  border-top: 1px solid var(--border-soft);
}
.site-subnav {
  max-width: var(--content-max);
  margin: 0 auto;
  /* Match the header-inner / .app gutters so the row lines up with the content. */
  padding:
    7px
    calc(20px + env(safe-area-inset-right))
    7px
    calc(20px + env(safe-area-inset-left));
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  align-items: center;
  gap: 8px 10px;
  /* Part 1 — hide the native horizontal scrollbar (mirrors the .tablist idiom
     further down this file); the row still scrolls by swipe / trackpad / keyboard,
     so this only removes the visual bar, never the scrolling itself. */
  scrollbar-width: none;
  /* Part 2 — pure-CSS auto-hiding edge fade (the Lea Verou `background-attachment:
     local` scroll-shadow) so overflow reads as "scrollable", not "broken", with
     ZERO JS and ZERO added layout height (all four layers are backgrounds, so the
     row height — and --subnav-h — stay honest). The two `local` COVER layers scroll
     WITH the content and are painted in var(--bg) — the opaque .site-header band
     this row rides on — so they mask the pinned `scroll` SHADOW layers at each end:
     a fade auto-appears only when there is more content that way and auto-hides at
     the extremes. Covers fade to `transparent`; because var(--bg) is near-black,
     modern premultiplied-alpha interpolation keeps the fade clean (no grey seam).
     Cover width is 56px (widened from an earlier 36px) — on this near-black band a
     black inner shadow barely registers, so the readable cue is the dissolve of the
     pills' own lighter text/chips into the header, and that only reads clearly over
     a longer run. The 14px radial shadow layers are left as-is; deepening their
     black doesn't help legibility here, only the wider dissolve does. */
  background-image:
    linear-gradient(to right, var(--bg), transparent),
    linear-gradient(to left, var(--bg), transparent),
    radial-gradient(farthest-side at left center, rgba(0, 0, 0, 0.5), transparent),
    radial-gradient(farthest-side at right center, rgba(0, 0, 0, 0.5), transparent);
  background-position: left center, right center, left center, right center;
  background-size: 56px 100%, 56px 100%, 14px 100%, 14px 100%;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.site-subnav::-webkit-scrollbar { display: none; }
.verse-jump-label {
  flex: none;
  font: 600 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.verse-jump-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* flex: none keeps each pill at its content width in the single horizontally-
     scrollable row, so they never squeeze (and the row scrolls instead). */
  flex: none;
  padding: 7px 12px;
  font: 600 13px/1 var(--ui-font);
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.verse-jump-link svg { width: 15px; height: 15px; flex: none; opacity: 0.85; }
.verse-jump-link:hover,
.verse-jump-link:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.verse-jump-link.is-active {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
/* The one section-nav entry that navigates AWAY (to /morphology) instead of
   scrolling to an in-page #section. It has no data-jump-link, so the scroll-spy
   (initVerseJumpNav) never marks it .is-active — and it must not read like the
   muted in-page jump pills. So it gets a persistent accent outline + underline
   (an actionable "leaves this page" link, distinct from both the muted rest and
   the filled .is-active state) and a thin left divider setting it off from the
   "Verse" pill. margin-left widens the gap so the divider sits centered in it. */
.verse-jump-cross {
  position: relative;
  margin-left: 12px;
  color: var(--accent);
  border-color: var(--accent-border);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.verse-jump-cross::before {
  content: "";
  position: absolute;
  left: -11px;
  top: 50%;
  width: 1px;
  height: 18px;
  transform: translateY(-50%);
  background: var(--border);
}
/* Touch: give the chip a comfortable ≥44px hit area WITHOUT growing the visual
   pill. A taller pill would inflate the .site-subnav row past --subnav-h and
   desync the deep-link scroll-margin math (see --subnav-h above), so instead a
   transparent overlay extends the tap target with zero layout effect — the
   header band isn't overflow-clipped, so the overlay isn't cut off. */
@media (pointer: coarse) {
  .verse-jump-cross::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
}
/* Anchored sections clear the combined header + in-header section-nav band when
   jumped to (or deep-linked). --subnav-h is the section-nav row's height (set on
   body.v-page; 0 elsewhere) so the offset is exactly the bar height + a little
   breathing room. When the header compacts (html.is-scrolled), --header-h shrinks
   and --subnav-h holds, so this reconciles automatically — no is-scrolled
   override needed. */
#results, #verse-study, #verse-words, #verse-about, #compare-editions, #cross-references, #commentary, #compare, #textual-variants, #targum, #lesson-kit { scroll-margin-top: calc(var(--header-h) + var(--subnav-h) + 8px); }

/* Always-visible corpus-intelligence highlights — a teaser strip under the
   translation that surfaces the top "About this verse" facts on first paint. */
.verse-highlights {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 18px 0 0;
  padding: 12px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
.vh-label {
  font: 600 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.vh-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.vh-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  font: 500 12.5px/1.3 var(--ui-font);
  color: var(--text-dim);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
}
.vh-chip svg { width: 15px; height: 15px; flex: none; color: var(--accent); opacity: 0.9; }
.vh-chip strong { color: var(--text); font-weight: 700; }
.vh-sub { color: var(--text-faint); }
/* R3 — the length-divergence chip is a link into the side-by-side panel. */
.vh-chip--diverge { padding: 0; border-color: var(--accent-border); background: var(--accent-soft); }
.vh-chip-link {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: 999px;
  color: var(--text); text-decoration: none;
}
.vh-chip-link:hover { text-decoration: none; }
.vh-chip-link:hover strong { text-decoration: underline; }
.vh-chip-link svg { width: 15px; height: 15px; flex: none; color: var(--accent); opacity: 0.9; }
.vh-more {
  margin-left: auto;
  font: 600 12.5px/1 var(--ui-font);
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.vh-more:hover, .vh-more:focus-visible { text-decoration: underline; outline: none; }
@media (max-width: 560px) {
  .vh-more { margin-left: 0; }
  .vh-sub { display: none; }
}

/* ----------------------------------------------------------------------------
   "What this verse means" frame (#58)
   ----------------------------------------------------------------------------
   A plain-English meaning frame for everyday readers, ABOVE the interlinear. The
   body is a VERBATIM, ATTRIBUTED excerpt of one stored PD/CC commentary note —
   so the visual language borrows the accent-card family (.verse-lxx-note) and the
   reading-font note prose (.commentary-quote) to read as a featured quotation. */
.verse-meaning {
  margin: 18px 0 0;
  padding: 16px 18px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-left-width: 3px;
  border-radius: var(--radius);
}
.verse-meaning-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 10px;
}
.verse-meaning-icon { display: inline-flex; flex: none; color: var(--accent); }
.verse-meaning-icon svg { width: 20px; height: 20px; }
.verse-meaning-heading {
  margin: 0;
  font: 600 12px/1.2 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
.verse-meaning-excerpt {
  margin: 0;
  font: 400 17px/1.65 var(--reading-font);
  color: var(--text);
}
.verse-meaning-attribution {
  margin: 8px 0 0;
  font: 600 13px/1.4 var(--ui-font);
  color: var(--text-dim);
}
.verse-meaning-note {
  margin: 10px 0 0;
  font: 400 12.5px/1.5 var(--ui-font);
  color: var(--text-faint);
}
.verse-meaning-more {
  margin-left: 6px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  white-space: nowrap;
}
.verse-meaning-more:hover,
.verse-meaning-more:focus-visible { text-decoration: underline; outline: none; }
@media (max-width: 560px) {
  .verse-meaning-excerpt { font-size: 16px; }
}

/* "Old Testament root" callout (#113) — reuses the .verse-meaning card idiom
   (box, head, icon, heading, note) and adds only the parts _meaning lacks: the
   reference link and the OT-verse preview quote. SSR-only; self-omits when there
   is no OT-target cross-reference. */
.verse-ot-root-ref {
  margin: 0;
  font: 600 17px/1.4 var(--ui-font);
}
.verse-ot-root-ref a {
  color: var(--accent);
  text-decoration: none;
}
.verse-ot-root-ref a:hover,
.verse-ot-root-ref a:focus-visible { text-decoration: underline; outline: none; }
.verse-ot-root-quote {
  margin: 8px 0 0;
  padding: 0 0 0 12px;
  border-left: 2px solid var(--accent-border);
  font: 400 16px/1.6 var(--reading-font);
  color: var(--text);
}

/* Study zone wrapper. Default: a single column (word study, then — if present —
   the cross-refs rail) stacked in source order. The .verse-detail/.cross-refs
   own margins are folded into the wrapper gap. */
.verse-study-grid {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
.verse-study-grid .verse-detail { margin-top: 0; }
.verse-study-grid .cross-refs { margin-top: 0; }
/* Wide screens with a rail present: word study (primary) | cross-refs (rail).
   The 340px rail is fixed so the cards stay comfortable; the primary column
   takes the remainder (>=~676px at the 1080px breakpoint, so the word-study
   master-detail keeps a usable reading width). Top-aligned. */
@media (min-width: 1080px) {
  .verse-study-grid.has-rail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 24px;
    align-items: stretch;
  }
  /* Fill the column height: a short verse's word-study card shouldn't float
     beside a taller cross-refs rail (e.g. Genesis 1:3). .verse-detail wraps the
     two stacked .verse-section cards, so stretch the wrapper and let the LAST
     section (About) grow to absorb the extra height — the cross-refs rail sits
     beside the whole stack, so growing the bottom card keeps both columns even. */
  .verse-study-grid.has-rail > .verse-detail { display: flex; flex-direction: column; }
  .verse-study-grid.has-rail > .verse-detail > .verse-section:last-child { flex: 1 1 auto; }
}

/* At the wide content cap (.app--wide = 1280px) the cross-refs rail gets a touch
   more room. (This block formerly also restored an inner word-by-word "left
   rail"; that rail was a strict subset of the word rows and was removed — the
   word list is a single column at every width now.) */
@media (min-width: 1280px) {
  .verse-study-grid.has-rail { grid-template-columns: minmax(0, 1fr) 360px; }
}

/* ===== Word-by-word master-detail (#verse-words) =====
   A focus card with morphology facets above a single list of every word as a
   selectable row. app.js hydrates focus changes. (The former compact left rail
   was a strict subset of these rows — same words/links/behavior, less info — and
   was removed per the seminary-tool-critic ruling.) */
.wbw { min-width: 0; }

/* Shared chips/badges across the word rows and the focus card. */
.wbw-num {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font: 600 12px/1 var(--ui-font);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.wbw-strongs {
  flex: none;
  font: 600 12px/1 var(--mono-font);
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 6px;
  padding: 4px 8px;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
/* LXX-only vocabulary badge in the word rows — the gold-pill analog of a
   Strong's number for a Septuagint word that has a /lxx study page instead.
   UI font (not mono) so the "LXX" label reads as a word, not a code. */
.wbw-lxx-pill { font-family: var(--ui-font); letter-spacing: 0.06em; }
.wbw-glyph { color: var(--text); font-weight: 600; line-height: 1.2; }
.wbw-glyph.hebrew { font-family: var(--hebrew-font); }
.wbw-glyph.greek { font-family: var(--greek-font); }
.wbw-translit { font-style: italic; color: var(--text-faint); }

/* ---- Word column ---- */
.wbw-main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.wbw-focus-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 20px 22px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}

.wbw-focus-lead { text-align: center; }
.wbw-focus-glyph-row { display: flex; align-items: center; justify-content: center; gap: 14px; }
.wbw-focus-glyph { font-size: 40px; color: var(--text); font-weight: 600; }
.wbw-focus-glyph.hebrew { font-family: var(--hebrew-font); font-size: 44px; }
.wbw-focus-glyph.greek { font-family: var(--greek-font); }
.wbw-focus-translit { margin-top: 8px; font-size: 20px; font-style: italic; color: var(--text-dim); overflow-wrap: break-word; }

.wbw-audio {
  display: none; /* app.js reveals (.wbw.has-audio) when speech synthesis exists */
  align-items: center;
  justify-content: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--accent);
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
}
.wbw.has-audio .wbw-audio { display: inline-flex; }
.wbw-audio:hover { border-color: var(--accent-border); background: var(--accent-soft); }
.wbw-audio:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.wbw-focus-body {
  min-width: 0;
  border-top: 1px solid var(--border-soft);
  padding-top: 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
/* align-items:center sizes each column child to its MAX-CONTENT width (not the
   card's), so a wide gloss/parse/flex-wrap row would spill and force page-level
   horizontal overflow at ~390px (#199). Cap every direct child at the card
   content width: the flex-wrap containers below (.wbw-focus-insights /
   .wbw-facets / .wbw-deeplinks) then actually wrap, and block text can break.
   Kept centered — this only bounds the width, it doesn't change alignment. */
.wbw-focus-body > * { max-width: 100%; }
.wbw-focus-strongs { font-size: 13px; padding: 5px 10px; }
/* LXX-only vocabulary chip — links to the synthetic /lxx study page. Mono font
   doesn't fit a word phrase, so use the UI font; keep the gold accent. */
.wbw-focus-lxx { font-family: var(--ui-font); font-weight: 600; letter-spacing: .01em; }
.wbw-focus-gloss { font: 600 30px/1.15 var(--reading-font); color: var(--accent); text-align: center; overflow-wrap: break-word; }
.wbw-focus-morphsummary {
  font: 600 12px/1.4 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  overflow-wrap: break-word;
}
/* Textual-variant note — shown in the focus card in place of the morph summary
   when the morphology edition reads a different word here than the base text
   (so there's no honest parse). Understated, non-alarmist: a quiet outlined
   chip, not an error color. Mirrors the .wbw-rest-variant idiom below. */
.wbw-focus-variant {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0 0;
  padding: 8px 13px;
  max-width: 38ch;
  border: 1px dashed var(--border);
  border-radius: 12px;
  background: var(--bg-card);
  font: 500 12.5px/1.4 var(--ui-font);
  color: var(--text-dim);
  text-align: left;
}
.wbw-variant-icon { flex: none; width: 15px; height: 15px; color: var(--text-faint); }

/* Per-word corpus-insight strip (frequency + first canonical occurrence) — sits
   under the morph summary in the focus card. Two accent-soft chips, mirroring
   the verse-level .verse-highlights idiom so the per-word and per-verse facts
   read as the same family. */
.wbw-focus-insights {
  list-style: none;
  margin: 2px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 10px;
}
.wbw-insight {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  border-radius: 999px;
  font: 500 13px/1.3 var(--ui-font);
  color: var(--text-dim);
}
.wbw-insight-icon { flex: none; width: 15px; height: 15px; color: var(--accent); }
.wbw-insight-text strong { color: var(--text); font-weight: 700; }
.wbw-insight-link { color: var(--accent); text-decoration: none; font-weight: 600; }
.wbw-insight-link:hover { text-decoration: underline; }
/* The frequency fact deep-links into the /w/ concordance (Appearances tab).
   Keep its count strong + readable like the plain-text variant while the
   surrounding label takes the accent link colour. */
.wbw-insight-freq strong { color: var(--text); font-weight: 700; }

.wbw-facets { margin-top: 2px; display: flex; flex-wrap: wrap; gap: 14px 20px; }
.wbw-facet { display: flex; flex-direction: column; gap: 6px; }
.wbw-facet-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: 600 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}
.wbw-facet-icon { color: var(--accent); }
.wbw-facet-value {
  font: 500 13px/1 var(--ui-font);
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
}

/* Contextual "study this word across the corpus" deep-links (grammar →
   /morphology, concordance → /concordance). Secondary to the facet chips above,
   but they must read as actionable pills, not captions — so at rest they carry
   the accent-outline idiom (accent text + accent-border, no fill) rather than the
   muted --text-dim they used to; hover/focus fills them with --accent-soft.
   Stacks single-column on narrow cards. */
.wbw-deeplinks {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
}
.wbw-deeplink {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  font: 500 13px/1.3 var(--ui-font);
  color: var(--accent);
  text-decoration: none;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.wbw-deeplink:hover,
.wbw-deeplink:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.wbw-deeplink strong { color: var(--text); font-weight: 700; }
.wbw-deeplink:hover strong,
.wbw-deeplink:focus-visible strong { color: var(--accent); }
.wbw-deeplink-icon { flex: none; display: inline-flex; color: var(--accent); }
/* Proclitic disclosure caption (#159) — names the prefix POS(es) a Hebrew/Aramaic
   word sets aside before the head the grammar link follows. DISPLAY-ONLY (no
   link), so it must NOT read as one: muted, small, no accent colour. width:100%
   drops it onto its own row in the flex nav (under the grammar link, not inline
   beside it); subordinate to the deep-links above it. Wraps cleanly at 320px. */
.wbw-deeplink-note {
  width: 100%;
  margin: 4px 0 0;
  font: 500 0.8em/1.4 var(--ui-font);
  color: var(--text-faint);
}
.wbw-deeplink-note strong { color: var(--text-dim); font-weight: 600; }
@media (max-width: 560px) {
  .wbw-deeplinks { flex-direction: column; align-items: stretch; }
  .wbw-deeplink { justify-content: flex-start; }
}
/* Touch: comfortable ≥44px tap target. Already inline-flex + align-items:center,
   so the content just centers in the taller pill. */
@media (pointer: coarse) {
  .wbw-deeplink { min-height: 44px; }
}

/* Collapsible BDB/Thayer inside the focus card (keeps the SEO lexicon prose). */
.wbw-lex { width: 100%; margin-top: 4px; border-top: 1px solid var(--border-soft); padding-top: 12px; }
.wbw-lex-summary {
  cursor: pointer;
  font: 600 13px/1 var(--ui-font);
  color: var(--accent);
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.wbw-lex-summary::-webkit-details-marker { display: none; }
.wbw-lex-summary::before { content: '\25B8'; font-size: 11px; transition: transform 0.12s; }
.wbw-lex[open] .wbw-lex-summary::before { transform: rotate(90deg); }
.wbw-lex-body { margin-top: 12px; font-family: var(--reading-font); color: var(--text-dim); font-size: 15px; line-height: 1.6; }
.wbw-lex-meta { margin: 0 0 8px; font-size: 13px; }
.wbw-lex-metalabel { color: var(--text-faint); font-family: var(--ui-font); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.wbw-lex-def { color: var(--text); }
.wbw-lex-body .strongs-link { color: var(--accent); text-decoration: none; }
.wbw-lex-body .strongs-link:hover { text-decoration: underline; }

/* ---- Remaining words ---- */
.wbw-rest {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  overflow: hidden;
}
/* Each <li> lays its row and the sibling compare button side by side (#196), so
   they share one height (align-items:stretch) and one bottom divider. The divider
   moved OFF .wbw-rest-row and ONTO the <li> so both children sit above one border
   rather than only the row. .wbw-rest keeps overflow:hidden + radius, so the row
   and compare cells stay clipped to the rounded corners. */
.wbw-rest-li { display: flex; align-items: stretch; }
.wbw-rest-li:not(:last-child) { border-bottom: 1px solid var(--border-soft); }
/* The word rows are a tidy table: each row is its own CSS grid with an
   IDENTICAL track template, so — because every row is width:100% with the same
   padding — the fixed-px and fr/minmax tracks resolve to the same widths on
   every row and the cells line up into vertical columns (glyph under glyph,
   translit under translit, pill under pill, gloss under gloss). No content-sized
   (auto / max-content) track is used for an aligned column, since that would
   size per-row and re-ragged the list. Every optional cell is always emitted
   (an empty aria-hidden placeholder when absent — see verse.ejs) so a missing
   gloss/pill/morph leaves an empty cell that still holds its column rather than
   collapsing it. Columns: num | glyph | translit | strongs | gloss | morph |
   chevron. */
.wbw-rest-row {
  display: grid;
  grid-template-columns:
    26px
    minmax(0, 1.3fr)
    minmax(64px, 0.9fr)
    64px
    minmax(0, 1.5fr)
    minmax(0, 2fr)
    18px;
  align-items: center;
  column-gap: 12px;
  /* Take the remaining <li> width beside the fixed compare cell; min-width:0 lets
     it shrink (its inner grid tracks ellipsize) rather than push the button off. */
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: none;
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  transition: background 0.12s;
}
.wbw-rest-row:hover { background: var(--accent-soft); }
.wbw-rest-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The glyph column varies a lot in width (Hebrew especially): keep it bounded
   to its track and ellipsize a long word rather than blow the column out and
   re-ragged the rest. The RTL dir="rtl" on .wbw-glyph.hebrew keeps the Hebrew
   reading right-to-left WITHIN this cell while the grid column order (num on the
   visual left) is unchanged. */
.wbw-rest-row .wbw-glyph {
  font-size: 20px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wbw-rest-row .wbw-translit {
  font-size: 14px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The Strong's / LXX pill sits in a fixed-width slot. justify-self:start keeps
   the pill its own size (pills don't stretch to fill the cell), so they all
   start at the same left edge of the column → pill-under-pill alignment. The
   empty placeholder (.wbw-strongs-empty) simply holds the column. */
.wbw-rest-row .wbw-strongs { justify-self: start; }
.wbw-strongs-empty { display: block; }
.wbw-rest-gloss {
  color: var(--text);
  font-family: var(--reading-font);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wbw-rest-morph { min-width: 0; font-size: 12px; color: var(--text-dim); }
/* Variant note in a rest-row — same column as the morph prose, italic + faint so
   it reads as a quiet aside, not a parse. */
.wbw-rest-variant { font-style: italic; color: var(--text-faint); }
.wbw-chevron { color: var(--text-faint); justify-self: end; }
/* Per-row "Compare this word" on-ramp (#196) — a distinct control with its own
   ≥44px hit area, sibling to (never nested in) the row so a tap navigates to
   /concordance instead of being hijacked into setFocus. Resting colour is
   --text-dim (one step up from faint) so the glyph reads as a touch-legible
   affordance without a hover — which never fires on touch — and it raises to the
   accent on hover/focus. min-height guarantees the touch-target floor even if a
   short row would otherwise fall under it. */
.wbw-rest-compare {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  border-left: 1px solid var(--border-soft);
  color: var(--text-dim);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.wbw-rest-compare:hover { color: var(--accent); background: var(--accent-soft); }
.wbw-rest-compare:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The inert placeholder emitted for a head-less row (proclitic-/suffix-only or
   LXX-only word — no real Strong's, so no compare deep-link). It holds the same
   fixed 44px column, keeping its border-left divider, so tightening the compare
   gate never re-rags the aligned word grid. Non-interactive: no pointer cursor,
   no hover lift, and it stays faint (the FIX 4 touch-legibility bump is for the
   real control only). */
.wbw-rest-compare-empty { cursor: default; color: var(--text-faint); }
.wbw-rest-compare-empty:hover { background: none; color: var(--text-faint); }
@media (max-width: 560px) {
  /* Mobile reclaims width for the glyph (the original-language column — this
     tool's primary axis) so the fixed 44px compare cell (#196) no longer clips
     short Hebrew/Greek words to a one-character stub. Three columns are dropped
     ENTIRELY (track removed, not merely the cell hidden, so no empty gap):
       - morph  (already dropped — low-signal at this width);
       - chevron (redundant here: the whole row is tap-to-focus, and the compare
                  glyph now sits at the row end);
       - gloss  (its ≤26px stub was unreadable anyway; the meaning stays on the
                 focus card and the running gloss line above).
     The freed space is handed to the glyph track (1.9fr, up from 1.3fr) so short
     words — בָּרָא / אֵת / וְאֵת / λόγος — render WHOLE at 390px. Remaining
     columns: num | glyph | translit | strongs. The corresponding cells
     (.wbw-rest-morph / .wbw-chevron / .wbw-rest-gloss) are display:none'd below. */
  .wbw-rest-row {
    grid-template-columns:
      26px
      minmax(0, 1.9fr)
      minmax(52px, 0.9fr)
      52px;
    column-gap: 10px;
    padding: 11px 12px;
  }
  .wbw-rest-morph,
  .wbw-chevron,
  .wbw-rest-gloss { display: none; }
  /* Row padding tightens here, but the compare cell must not drop below the
     touch-target floor — keep it ≥44px in both dimensions. */
  .wbw-rest-compare { min-width: 44px; min-height: 44px; }
}

/* Tabbed panel — Lexicon / Where the word appears / About on /w/... and
   the LXX lemma page. ARIA pattern: a tablist of buttons with aria-selected,
   and corresponding tabpanels keyed via aria-controls. Tab switching is wired
   in app.js. (The verse page used to share this chrome via .verse-tabs, but it
   no longer tabs — its Word-by-word + About are flat stacked .verse-section
   cards now; see .verse-section below.) */
.strongs-tabs {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

/* #91: "On this page" quick-jump row between the hero and the tabs — a calm,
   single-line affordance that lands readers on the buried marquee panels
   (renderings / concordance) without a long scroll. Quiet navigation, not a
   banner: muted by default, gold accent on hover/focus (the .verse-jump-link /
   .strongs-gloss-range-more palette). Wraps on narrow screens. */
.strongs-jump {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  /* #93: tightened top margin (was 16px) so the jump nav clears the fold on a
     stock ~800px-tall desktop viewport without scrolling — part of the hero
     vertical-rhythm trim, no markup/JS change. */
  margin: 10px 0 0;
  /* Part 1 — scrollbar-hide for consistency with the other jump rows. This row
     WRAPS (flex-wrap: wrap, no overflow-x), so there is no horizontal scrollbar to
     hide today; the rule is a defensive no-op and needs no edge-fade affordance. */
  scrollbar-width: none;
}
.strongs-jump::-webkit-scrollbar { display: none; }
.strongs-jump-label {
  flex: none;
  font: 600 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.strongs-jump-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  font: 600 13px/1 var(--ui-font);
  color: var(--text-dim);
  text-decoration: none;
  white-space: nowrap;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-jump-link:hover,
.strongs-jump-link:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}

/* Verse-page study sections (/v/...): the former Word-by-word / About tabs,
   now two always-visible stacked cards inside .verse-detail#verse-study. Each
   carries its own card chrome (the old .verse-tabs wrapper is gone) and a
   visible <h2> landmark, so the rich corpus analysis is no longer buried in an
   unselected tab. They keep the .tabpanel class so the inner .tabpanel-scoped
   styling (padding + p typography) still applies unchanged. */
.verse-section {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* Clip the flush header bar (which breaks out to the card edges below) to the
     card's rounded corners — same pattern as .strongs-tabs. */
  overflow: hidden;
}
.verse-section + .verse-section { margin-top: 20px; }
/* Full-bleed header bar. These sections also carry .tabpanel (18px 20px body
   padding); the head breaks OUT of that padding with matching negative margins
   so the bar — its background, its bottom divider, and its top corners — sits
   flush with the card edges instead of floating as an inset chip. The bottom
   margin restores the gap to the first body child. Weight (700/17px) matches the
   sibling panel headings (.cross-refs-head-title / .commentary-head h2 are
   700/19px) so the four study-zone <h2>s read as peers, not a hierarchy. */
.verse-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: -18px -20px 18px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border-soft);
  background: var(--bg-card);
  color: var(--text);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.verse-section-icon {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--accent);
  opacity: 0.95;
}
.tablist {
  display: flex;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-soft);
}
.tab-btn {
  appearance: none;
  -webkit-appearance: none;
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: none;
  border: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 14px 16px;
  min-height: 48px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 120ms, border-color 120ms, background 120ms;
}
/* Feather-style tab icon — inherits currentColor so it tints gold with the
   label when the tab is selected (.tab-btn[aria-selected="true"] sets accent). */
.tab-btn-icon {
  width: 16px;
  height: 16px;
  flex: none;
  opacity: 0.85;
}
.tab-btn[aria-selected="true"] .tab-btn-icon { opacity: 1; }
/* Keep a tab label (and its T1 occurrence-count parenthetical) on a single line
   so the longer "Where it appears (1,317)" label never wraps mid-tab on the
   equal-width desktop layout. The count rides inline inside the label, so it
   inherits this nowrap and stays attached to the text. */
.tab-btn-label { white-space: nowrap; }
/* The occurrence count is supporting detail — slightly dimmer + lighter than the
   label text so the word "appears" reads first. Tints with the active accent
   because it inherits currentColor (no explicit color). */
.tab-btn-count {
  font-weight: 500;
  opacity: 0.75;
}
.tab-btn:hover { color: var(--text); }
.tab-btn[aria-selected="true"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
  background: var(--bg-raised);
}
.tab-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
/* Narrow screens: four icon+label tabs won't fit four-up (especially with the
   longer T1 "Where it appears (1,317)" label), so let the tablist scroll
   horizontally with momentum + a hidden scrollbar and size each tab to its
   content on ONE line (icon beside label) instead of wrapping. flex:0 0 auto +
   white-space:nowrap on the button keep each whole tab atomic, so nothing wraps
   or overlaps mid-tab down to ~320px — the row just scrolls. */
@media (max-width: 600px) {
  .tablist {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tablist::-webkit-scrollbar { display: none; }
  .tab-btn {
    flex: 0 0 auto;
    white-space: nowrap;
    gap: 6px;
    padding: 12px 14px;
    font-size: 13px;
  }
  /* Tuck the count tighter on mobile so the longer label adds minimal width. */
  .tab-btn-count { margin-left: -2px; }
}
.tabpanel { padding: 18px 20px; }
.tabpanel[hidden] { display: none; }
.tabpanel p {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
  margin: 0 0 10px;
}
.tabpanel p:last-child { margin-bottom: 0; }
.tabpanel p strong { color: var(--accent); font-weight: 600; }
.tabpanel p a { color: var(--accent); text-decoration: none; }
.tabpanel p a:hover,
.tabpanel p a:focus { text-decoration: underline; outline: none; }

/* Visually hidden but kept in the a11y + crawler tree — used for tabpanel
   headings whose visual label is already shown by the tab button. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.lex-hint {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--text-faint);
  font-style: italic;
}

/* ============================================================================
   28. SSR STRONG'S PAGE (/w/:strongs) — hero, gloss history, occurrences, about
   ----------------------------------------------------------------------------
   Server-rendered Strong's lexicon page (/w/:strongs).
   ============================================================================ */

/* Hero: 2-column grid — left is the word panel (lemma + pronounce button +
   gloss + a 2×2 stat-card grid: Strong's code, transliteration,
   pronunciation, corpus usage), right is a Definition card surfacing the
   BDB/Thayer body so readers don't have to scroll/click into the tab to see
   what the word actually means. The two columns are equal-height (stretch)
   so the definition card's download action can sit flush at the bottom.
   Stacks on mobile (see @media at the bottom). */
.strongs-hero {
  /* #93: tightened vertical rhythm (was `12px 0 28px` margin, `24px 22px`
     padding) so the hero is shorter and the #91 jump nav below it stays above
     the fold on a stock ~800px-tall desktop viewport. Horizontal padding is
     unchanged; mobile keeps its own padding override in the @media block. */
  margin: 12px 0 18px;
  padding: 20px 22px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: 28px;
  align-items: stretch;
}
.strongs-hero-word {
  text-align: center;
  /* Padding keeps the lemma off the divider in narrow viewports right
     before the mobile stack kicks in. */
  padding: 4px 6px;
  display: flex;
  flex-direction: column;
}

/* Lemma + pronounce button sit on one centered row. */
.strongs-lemma-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.strongs-lemma {
  font-size: 56px;
  font-weight: 600;
  line-height: 1.1;
  color: var(--text);
}
.strongs-lemma.hebrew { font-family: var(--hebrew-font); }
.strongs-lemma.greek { font-family: var(--greek-font); }

/* Pronounce button — circular gold-outline control next to the lemma.
   Hidden until app.js confirms SpeechSynthesis support (then unhidden),
   removed entirely otherwise so it never shows as a dead control. */
.strongs-audio-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.strongs-audio-btn svg { width: 20px; height: 20px; }
.strongs-audio-btn:hover,
.strongs-audio-btn:focus-visible {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  outline: none;
}
.strongs-audio-btn.speaking {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  animation: strongs-audio-pulse 1.1s ease-in-out infinite;
}
@keyframes strongs-audio-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-border); }
  50% { box-shadow: 0 0 0 5px transparent; }
}

.strongs-gloss {
  margin: 16px 0 0;
  font-size: 20px;
  color: var(--accent);
  font-style: italic;
}

/* #81: SECONDARY "fuller meaning range" line under the headline gloss. Styled
   strictly subordinate — smaller and dimmer than the gold headline above — so it
   reads as the word's RANGE, never as a competing primary meaning. */
.strongs-gloss-range {
  margin: 6px 0 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--text-dim);
}
.strongs-gloss-range-lead {
  text-transform: lowercase;
  letter-spacing: 0.01em;
  opacity: 0.85;
}
/* #8 V1: the proper-noun count line ("BDB lists 4 entries for 'Moab'") carries an
   acronym + a name, both case-significant — the lowercase that's right for the
   quoted-common-word modes ("'word' is one of 9 main senses") would mangle them.
   Scope lowercase OFF for the name branch only; common-noun/enumerate modes keep it. */
.strongs-gloss-range-lead--name {
  text-transform: none;
}
.strongs-gloss-range-terms {
  font-style: italic;
}
.strongs-gloss-range-more {
  white-space: nowrap;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.strongs-gloss-range-more:hover,
.strongs-gloss-range-more:focus-visible {
  border-bottom-color: currentColor;
}
/* When the line IS the count+pointer (no separate "also:" lead/terms), the link
   carries the whole sentence — keep it reading as muted body text, not a button,
   with only the trailing arrow tinted on hover. */
.strongs-gloss-range > .strongs-gloss-range-more:only-child {
  color: var(--text-dim);
}
.strongs-gloss-range > .strongs-gloss-range-more:only-child:hover,
.strongs-gloss-range > .strongs-gloss-range-more:only-child:focus-visible {
  color: var(--accent);
}

/* 2-up stat grid — code / transliteration / pronunciation / usage. */
.strongs-stat-grid {
  /* #93: trimmed top gap (was 20px) as part of the hero height reduction. */
  margin-top: 16px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.strongs-stat-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  padding: 16px 12px;
  min-height: 96px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
}
.strongs-stat-value {
  font-size: 21px;
  font-weight: 600;
  line-height: 1.15;
  color: var(--text);
  word-break: break-word;
}
.strongs-stat-value.translit { font-style: italic; font-family: var(--reading-font); }
.strongs-stat-value.pron { font-family: var(--mono-font); font-size: 19px; }
.strongs-stat-value.big {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.strongs-stat-label {
  font-size: 12px;
  color: var(--text-dim);
}
.strongs-stat-usage { gap: 4px; }
.strongs-stat-usage-head {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--accent);
}
.strongs-stat-usage-head svg { width: 13px; height: 13px; flex: none; }

.strongs-code {
  display: inline-block;
  padding: 2px 9px;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 4px;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.02em;
  font-family: var(--mono-font);
}

/* Subtle divider between the two columns — mirrors the navy/gold palette
   used elsewhere on the page so the boundary reads as a sectional break
   rather than an outline. Only renders at desktop widths; mobile stack
   removes it. */
.strongs-hero-def {
  border-left: 1px solid var(--border-soft);
  padding: 4px 4px 4px 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}
.strongs-hero-def-head {
  display: flex;
  align-items: center;
  gap: 12px;
}
.strongs-hero-def-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.strongs-hero-def-icon svg { width: 20px; height: 20px; }
.strongs-hero-def-label {
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
}
.strongs-hero-def-body {
  font-size: 17px;
  line-height: 1.55;
  color: var(--text);
  margin: 0;
  /* Preserve the sense outline (newlines + indentation) the paginator emits;
     each page is budgeted upstream so it stays a compact preview. */
  white-space: pre-wrap;
}
.strongs-hero-def-body[hidden] { display: none; }

/* Paged definition viewport. When more than one page exists it gets a
   min-height so stepping between a long and a short page doesn't make the
   card jump; single-page entries stay snug (no forced whitespace). */
.strongs-hero-def-pages { min-width: 0; }
/* #93: reserved viewport trimmed (was 150px) so the (taller) definition column —
   which controls the stretch-grid hero height — is shorter, helping the jump nav
   clear the fold. Mobile zeroes this out in the @media block (unchanged). */
.strongs-hero-def-pages.is-paged { min-height: 132px; }

/* Prev / page-indicator / next control row for the definition pages. */
.strongs-hero-def-pager {
  display: flex;
  align-items: center;
  gap: 10px;
}
.strongs-hero-def-pgbtn {
  flex: none;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: 15px;
  line-height: 1;
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms, opacity 120ms;
}
.strongs-hero-def-pgbtn:hover:not(:disabled),
.strongs-hero-def-pgbtn:focus-visible:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.strongs-hero-def-pgbtn:disabled {
  opacity: 0.4;
  cursor: default;
}
.strongs-hero-def-pgind {
  font-size: 12px;
  color: var(--text-dim);
  font-family: var(--mono-font);
  letter-spacing: 0.02em;
  min-width: 3.2em;
  text-align: center;
}
.strongs-hero-def-rule {
  width: 100%;
  border: none;
  border-top: 1px solid var(--border-soft);
  margin: 2px 0 0;
}
.strongs-hero-def-empty {
  font-size: 14px;
  color: var(--text-dim);
  font-style: italic;
}
/* Actions pinned to the bottom of the (stretched) definition column so the
   download button sits flush at the card's lower edge, as in the design. */
.strongs-hero-def-actions {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  align-items: center;
}
.strongs-hero-def-more {
  font-size: 13px;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.strongs-hero-def-more:hover,
.strongs-hero-def-more:focus {
  text-decoration: underline;
  outline: none;
}
/* Prominent gold-outline download button, right-aligned (margin-left:auto
   keeps it hugging the right edge whether or not the "read full entry"
   link is present beside it). */
.strongs-hero-def-share {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  padding: 10px 18px;
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  background: var(--accent-soft);
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-hero-def-share svg { width: 17px; height: 17px; flex: none; }
.strongs-hero-def-share:hover,
.strongs-hero-def-share:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}

/* Citation / export card — sits last in the hero definition aside (so the
   Definition card reads first). Always-visible standalone bordered card: a
   single "Cite this entry" heading, the plain-text citation, copy buttons, and a
   <details> carrying BibTeX + RIS in readonly textareas. All copy behavior is in
   app.js (initCitation); the markup is data-* driven, CSP-clean. There is no
   outer collapse — only the BibTeX/RIS machine formats are demoted behind the
   native <details> below. */
.strongs-cite {
  /* #93: tightened the gap above + internal padding (were 16px each) so the
     definition column — the taller of the two and thus the hero's controlling
     height — shrinks, helping the #91 jump nav clear the fold. Still an
     uncramped standalone card. */
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: var(--bg-card);
}
/* #93: .strongs-cite-head is now the <summary> that toggles the collapsed cite
   card. Compact title row (~40px) so the collapsed card is small enough that the
   right (definition) column stops governing the hero height — keeping the #91
   jump nav above a 1280×800 desktop fold. cursor/list-style/marker mirror the
   .strongs-cite-formats-summary pattern; the trailing chevron signals it expands. */
.strongs-cite-head {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
}
.strongs-cite-head::-webkit-details-marker { display: none; }
/* Keyboard focus gets a real ring (matches .strongs-cite-formats-summary) — WCAG 2.4.7. */
.strongs-cite-head:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}
/* When the card is open, restore the gap between the title row and the body. */
.strongs-cite[open] > .strongs-cite-head { margin-bottom: 12px; }
/* Chevron mirrors .strongs-cite-formats-chevron: points right when collapsed,
   rotates to point down when open. Pushed to the row's trailing edge. */
.strongs-cite-chevron {
  flex: none;
  margin-left: auto;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 140ms ease;
  color: var(--text-dim);
}
.strongs-cite[open] > .strongs-cite-head .strongs-cite-chevron {
  transform: rotate(45deg);
}
.strongs-cite-icon { flex: none; color: var(--text-dim); display: inline-flex; }
.strongs-cite-icon svg { width: 16px; height: 16px; }
.strongs-cite-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.strongs-cite-text {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}
.strongs-cite-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 12px;
}
.strongs-cite-btn {
  font: 600 13px/1 var(--ui-font);
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  padding: 7px 13px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-cite-btn.small { padding: 5px 10px; font-size: 12px; }
.strongs-cite-btn:hover,
.strongs-cite-btn:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}
.strongs-cite-status {
  font-size: 12.5px;
  color: var(--accent);
  font-weight: 600;
  min-height: 1em;
}
.strongs-cite-formats { margin-top: 8px; }
.strongs-cite-formats-summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font: 600 13px/1 var(--ui-font);
  color: var(--text-dim);
  list-style: none;
  padding: 7px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg-raised);
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-cite-formats-summary::-webkit-details-marker { display: none; }
.strongs-cite-formats-summary:hover {
  color: var(--accent);
  border-color: var(--accent-border);
}
/* Keyboard focus gets a real ring (matches .ot-toggle-btn), not just the faint
   border shift — WCAG 2.4.7. */
.strongs-cite-formats-summary:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.strongs-cite-formats-icon { flex: none; display: inline-flex; }
.strongs-cite-formats-icon svg { width: 16px; height: 16px; }
.strongs-cite-formats-chevron {
  flex: none;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 140ms ease;
}
.strongs-cite-formats[open] > .strongs-cite-formats-summary .strongs-cite-formats-chevron {
  transform: rotate(-135deg);
}
.strongs-cite-format { margin-top: 10px; }
.strongs-cite-format-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 5px;
}
.strongs-cite-format-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.strongs-cite-code {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--mono-font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 9px 11px;
  resize: vertical;
  /* Firefox: thumb + track, in that order. Reuses the box's own border/fill
     tokens so the scrollbar reads as part of the card, not an OS widget. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-soft) var(--bg-raised);
}
.strongs-cite-code:focus {
  outline: none;
  border-color: var(--accent-border);
}
/* WebKit/Chromium: same track/thumb pairing as the scrollbar-color line above.
   The thumb's transparent-looking inset (a border matching the track colour)
   keeps it slim and pill-shaped rather than a flush rectangle. */
.strongs-cite-code::-webkit-scrollbar {
  width: 10px;
}
.strongs-cite-code::-webkit-scrollbar-track {
  background: var(--bg-raised);
  border-radius: 8px;
}
.strongs-cite-code::-webkit-scrollbar-thumb {
  background: var(--border-soft);
  border: 2px solid var(--bg-raised);
  border-radius: 8px;
}
.strongs-cite-code::-webkit-scrollbar-thumb:hover {
  background: var(--accent-border);
}

/* ── Verse page share menu (views/verse/_share.ejs) ─────────────────────────
   A native <details> disclosure in the verse header (so it works with no JS),
   styled to match the existing pill controls (.faq-pill / .strongs-cite-btn).
   The <summary> is the trigger; the panel drops below it. app.js's
   initVerseShare layers aria-expanded sync + outside-click/Escape close on top.
   All tokens are the shared design tokens — no new colors. */
.verse-share {
  position: relative;
  /* Shrink-wrap to the trigger instead of stretching across the results-head
     column (it's a flex child, so the default align-items:stretch would make it
     full-width). Stretching made the absolutely-positioned menu's containing
     block the whole row, so `right:0` pinned the dropdown to the row's far edge,
     detached from the left-aligned button. flex-start ties the menu to the button. */
  align-self: flex-start;
  flex: none;
}
/* The trigger — a pill matching .faq-pill's chrome. list-style:none + the
   ::-webkit-details-marker reset hide the native disclosure triangle so our
   own chevron is the only affordance. */
.verse-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
  font: 600 13px/1 var(--ui-font);
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 8px 14px;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.verse-share-btn::-webkit-details-marker { display: none; }
.verse-share-btn:hover {
  color: var(--accent);
  border-color: var(--accent-border);
}
.verse-share-btn:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.verse-share-btn-icon { flex: none; display: inline-flex; }
.verse-share-btn-icon svg { width: 16px; height: 16px; display: block; }
.verse-share-btn-chevron {
  flex: none;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 140ms ease;
}
.verse-share[open] > .verse-share-btn .verse-share-btn-chevron {
  transform: rotate(-135deg);
}

/* The dropdown panel. Absolutely positioned directly below the trigger; now that
   the Share control is folded into the RIGHT side of the single-row .results-head
   (right-aligned next to the version badge), the panel is anchored to the trigger's
   RIGHT edge (right:0) and opens leftward, so a 360px panel can't run off the right
   side of the viewport. The containing block is still .verse-share (position:relative,
   shrink-wrapped to the trigger) — see the note above. On narrow screens (<=560px)
   it falls back to in-flow static block (below) so it never overflows the viewport. */
.verse-share-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  left: auto;
  /* Above the sticky site header (25) so the dropdown overlays the bar. */
  z-index: 30;
  width: min(360px, calc(100vw - 32px));
  box-sizing: border-box;
  padding: 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.verse-share-status {
  display: block;
  min-height: 1em;
  margin-bottom: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent);
}
.verse-share-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
}
/* Menu rows + the small cite-format copy buttons share one item class. */
.verse-share-item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  font: 600 13.5px/1.3 var(--ui-font);
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 9px 12px;
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.verse-share-item.small {
  width: auto;
  font-size: 12px;
  padding: 5px 10px;
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent-border);
}
.verse-share-item:hover,
.verse-share-item:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.verse-share-item.small:hover,
.verse-share-item.small:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
}
.verse-share-item-icon { flex: none; display: inline-flex; color: var(--text-dim); }
.verse-share-item:hover .verse-share-item-icon,
.verse-share-item:focus-visible .verse-share-item-icon { color: var(--accent); }
.verse-share-item-icon svg { width: 17px; height: 17px; display: block; }
.verse-share-item-label { flex: 1 1 auto; }

/* Cite-this-verse block inside the menu — mirrors .strongs-cite chrome. */
.verse-share-cite {
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}
.verse-share-cite-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.verse-share-cite-icon { flex: none; color: var(--text-dim); display: inline-flex; }
.verse-share-cite-icon svg { width: 16px; height: 16px; }
.verse-share-cite-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.verse-share-cite-text {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
}
.verse-share-cite-actions { margin-bottom: 10px; }
.verse-share-cite-formats { margin-top: 4px; }
.verse-share-cite-formats-summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font: 600 12.5px/1 var(--ui-font);
  color: var(--text-dim);
  list-style: none;
  padding: 6px 11px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg-raised);
  transition: color 120ms, border-color 120ms, background 120ms;
}
.verse-share-cite-formats-summary::-webkit-details-marker { display: none; }
.verse-share-cite-formats-summary:hover {
  color: var(--accent);
  border-color: var(--accent-border);
}
.verse-share-cite-formats-summary:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.verse-share-cite-formats-icon { flex: none; display: inline-flex; }
.verse-share-cite-formats-icon svg { width: 15px; height: 15px; }
.verse-share-cite-formats-chevron {
  flex: none;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 140ms ease;
}
.verse-share-cite-formats[open] > .verse-share-cite-formats-summary .verse-share-cite-formats-chevron {
  transform: rotate(-135deg);
}
.verse-share-cite-format { margin-top: 10px; }
.verse-share-cite-format-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 5px;
}
.verse-share-cite-format-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.verse-share-cite-code {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--mono-font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  padding: 9px 11px;
  resize: vertical;
  /* Same scrollbar treatment as .strongs-cite-code — see that rule's comment. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-soft) var(--bg-raised);
}
.verse-share-cite-code:focus {
  outline: none;
  border-color: var(--accent-border);
}
.verse-share-cite-code::-webkit-scrollbar {
  width: 10px;
}
.verse-share-cite-code::-webkit-scrollbar-track {
  background: var(--bg-raised);
  border-radius: 8px;
}
.verse-share-cite-code::-webkit-scrollbar-thumb {
  background: var(--border-soft);
  border: 2px solid var(--bg-raised);
  border-radius: 8px;
}
.verse-share-cite-code::-webkit-scrollbar-thumb:hover {
  background: var(--accent-border);
}
/* On a phone the absolute dropdown could clip; let it flow in-document and
   span the header instead. */
@media (max-width: 560px) {
  /* The header actions group spans the row so the full-width Share control below
     resolves against the whole header, and the dropdown flows in-document (static)
     full-width instead of clipping off-screen. */
  .results-head-actions { width: 100%; }
  .verse-share { width: 100%; }
  .verse-share-menu {
    position: static;
    width: 100%;
    margin-top: 8px;
  }
}

/* Body sections — definitions, short def, occurrences, about. */
.strongs-section {
  margin: 0 0 28px;
}
.strongs-section h2 {
  margin: 0 0 12px;
  font-size: 14px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 6px;
}
.strongs-short-def {
  font-size: 16px;
  color: var(--text);
  margin: 0;
}

/* Gloss history — Strong's 1890 vs modern curated gloss. Rendered as the
   full content of its own tab (between Lexicon Entry and Where the word
   appears).

   Visual treatment mirrors the Lexicon Entry tab's icon-badged cards: a gold
   section header with a short accent underline, then a 2-up grid of comparison
   cards (a circular icon badge + label + large serif gloss value), with the
   Modern card highlighted by a gold border + glow. A bordered panel below
   carries the explanatory note, the "agrees" badge, and the share button. The
   single-* states collapse the grid to one centered card. */
.gloss-history {
  margin: 0;
}

/* Gold section header + short accent underline (matches .lex-source-head).
   Scoped under .tabpanel so its gold color outranks the generic
   `.tabpanel p { color: --text-dim }` rule (which would otherwise win on
   specificity and render this header gray). */
.tabpanel .gloss-history-head {
  position: relative;
  margin: 0 0 18px;
  padding-bottom: 9px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}
.gloss-history-head::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 48px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

/* 2-up comparison cards. Collapses to one column on narrow panels. */
.gloss-history-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 16px;
}
.gloss-history-cards-single {
  grid-template-columns: 1fr;
  max-width: 480px;
}

.gloss-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 22px 24px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}
/* Modern card carries the focal gold treatment: brighter border + soft glow. */
.gloss-card-modern {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent-border), 0 0 28px -8px var(--accent);
  background:
    linear-gradient(180deg, var(--accent-soft), transparent 70%),
    var(--bg-card);
}

.gloss-card-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.gloss-card-icon svg { width: 26px; height: 26px; }

.gloss-card-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.gloss-card-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.gloss-card-modern .gloss-card-label { color: var(--accent); }
.gloss-card-value {
  font-family: var(--reading-font);
  font-size: 30px;
  font-style: italic;
  line-height: 1.2;
  color: var(--text);
  word-break: break-word;
}

/* Explanatory panel — a bordered, full-width card holding the note, the
   (optional) "agrees" badge, and the share button, all centered. */
.gloss-history-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 26px 24px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}

/* "Strong's 1890 agrees" badge — only on the agree state. Mint-green pill so
   the positive signal reads distinctly from the gold accent. */
.gloss-confirmed-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--success);
  background: var(--success-soft);
  border: 1px solid var(--success-border);
  border-radius: 999px;
  padding: 3px 10px;
  letter-spacing: 0.04em;
  cursor: help;
  white-space: nowrap;
}
.gloss-confirmed-check {
  font-weight: 900;
  font-size: 12px;
}

/* Action row: the info (ⓘ) affordance + the download button, centered. */
.gloss-history-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}

/* Info affordance — replaces the always-on caveat paragraph. A quiet round
   ⓘ button that reveals the state-specific explanation in a pure-CSS popover
   on hover or keyboard/touch focus (no inline JS — CSP-safe). The note text
   is also wired via aria-describedby so it's exposed to assistive tech even
   while visually hidden. */
.gloss-info {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  border: 1px solid var(--border-soft);
  background: var(--bg-card);
  color: var(--text-dim);
  cursor: help;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.gloss-info svg { width: 17px; height: 17px; }
.gloss-info:hover,
.gloss-info:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}

.gloss-info-pop {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  max-width: min(340px, 78vw);
  padding: 13px 15px;
  font-size: 13px;
  line-height: 1.65;
  font-style: italic;
  text-align: left;
  color: var(--text-dim);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.7);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 140ms, transform 140ms, visibility 140ms;
  z-index: 6;
}
/* Arrow pointing down at the icon. */
.gloss-info-pop::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--bg-card);
}
.gloss-info:hover .gloss-info-pop,
.gloss-info:focus-within .gloss-info-pop {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}

/* Standardized to match the hero's "Download definition card" button
   (.strongs-hero-def-share): filled gold-tinted rounded rectangle that fills
   to solid gold with dark text on hover. */
.gloss-history-share {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  text-decoration: none;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.gloss-history-share-icon { width: 17px; height: 17px; flex: none; }
.gloss-history-share:hover,
.gloss-history-share:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}

@media (max-width: 600px) {
  .gloss-history-cards { grid-template-columns: 1fr; gap: 12px; }
  .gloss-card { padding: 18px 18px; gap: 14px; }
  .gloss-card-icon { width: 48px; height: 48px; }
  .gloss-card-icon svg { width: 22px; height: 22px; }
  .gloss-card-value { font-size: 26px; }
  .gloss-history-panel { padding: 22px 18px; }
}

/* The full BDB/Thayer text. Preserve line breaks; long entries can be 400+
   words and benefit from a relaxed measure. */
.strongs-definition {
  font-size: 15px;
  line-height: 1.7;
  color: var(--text);
  white-space: pre-line;
  max-width: 70ch;
}
.strongs-no-def {
  color: var(--text-faint);
  font-style: italic;
}

/* Verse-occurrence list — the internal-linking layer back into verse pages. */
.strongs-occurrences-intro {
  margin: 0 0 14px;
  color: var(--text-dim);
  font-size: 14px;
}

/* #156: corpus-wide grammar-search bridge. Sits directly beneath the parse-filter
   strip and links the word's dominant parse value out to the whole-corpus
   /morphology grammar search. An unobtrusive call-to-action — reads as a quiet
   "keep exploring" link, not a button. Wraps cleanly at narrow widths. */
.corpus-grammar-link {
  margin: 0 0 18px;
  font-size: 14px;
}
.corpus-grammar-link a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.corpus-grammar-link a:hover,
.corpus-grammar-link a:focus {
  text-decoration: underline;
}
.corpus-grammar-link strong {
  font-weight: 700;
}
.strongs-verse-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 8px;
}
.strongs-verse-list li { margin: 0; }
.strongs-verse-list a {
  display: block;
  padding: 8px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  font-size: 14px;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.strongs-verse-list a:hover,
.strongs-verse-list a:focus {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}

/* Occurrence tile — three stacked rows: ref (dim), surface form(s) of the
   focus word for THIS verse (the inflected form, prominent), and morph
   badge(s) (compact chip). Surfaces are <bdi>s so a Hebrew RTL form and the
   LTR " · " separator don't collide. The whole tile is the existing anchor;
   hover state cascades through to the badge. */
.strongs-verse-list a.verse-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  /* #95: tap-target floor. The live .has-text tiles (ref + surface + verse text)
     already render well over 44px tall, so this is a no-op for them; it only
     guarantees the ≥44px touch target for a degenerate ref-only tile (no reader
     translation attached AND no surface/morph) in the text-less 150px grid. Pure
     floor — it never compresses the normal tall tiles' visual density. */
  min-height: 44px;
  box-sizing: border-box;
}
.verse-ref {
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.verse-surfaces {
  font-size: 16px;
  line-height: 1.25;
  unicode-bidi: isolate;
}
.verse-surfaces.hebrew { font-size: 18px; }
.verse-surface + .verse-surface::before {
  content: " · ";
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 400;
  unicode-bidi: isolate;
}
.verse-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Englishman's-concordance verse text — the reader's PD translation under the
   ref/surface, so the word is read in real context. Dim + slightly smaller than
   the surface so the tile still leads with the inflected original form. */
.verse-tile-text {
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-dim);
  margin-top: 2px;
}
/* When tiles carry full verse text, a tight 180px card grid would clip the
   prose, so the list runs as a single readable column of wide rows. The
   per-tile hover/focus colour shift cascades to the text via `color`. */
.strongs-verse-list.has-text {
  grid-template-columns: 1fr;
  gap: 6px;
}
.strongs-verse-list.has-text a.verse-tile { padding: 10px 14px; }
.strongs-verse-list.has-text a.verse-tile:hover .verse-tile-text,
.strongs-verse-list.has-text a.verse-tile:focus .verse-tile-text { color: var(--accent); }

/* #79: per-occurrence copy control. The button is a SIBLING of the tile <a>
   (never nested — invalid HTML), positioned over the tile's top-right corner via
   a relatively-positioned <li> wrapper. Reserve space so the button never overlaps
   the verse text (the link still fills the cell behind it; the button sits on top
   and is the only interactive element there). Shown on hover/focus of the tile and
   when the button itself is focused, so it stays unobtrusive but keyboard-reachable. */
.strongs-verse-list li.verse-tile-wrap { position: relative; }
.strongs-verse-list li.verse-tile-wrap a.verse-tile { padding-right: 78px; }
.occ-copy {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border: 1px solid var(--accent-border);
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 12px/1 var(--ui-font);
  cursor: pointer;
  opacity: 0;
  transition: color 120ms, border-color 120ms, background 120ms, opacity 120ms;
}
.strongs-verse-list li.verse-tile-wrap:hover .occ-copy,
.strongs-verse-list li.verse-tile-wrap:focus-within .occ-copy {
  opacity: 1;
}
.occ-copy:hover,
.occ-copy:focus-visible,
.occ-copy:focus {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  opacity: 1;
  outline: none;
}
.occ-copy-icon { display: inline-flex; flex: none; }
/* Touch / coarse-pointer devices have no hover, so reveal the button at rest
   (lower contrast) — otherwise it would be permanently invisible there. */
@media (hover: none), (pointer: coarse) {
  .occ-copy { opacity: 0.85; }
}

/* #90: per-occurrence "Compare translations" expander. Sits beside the #79 copy
   button in the same .verse-tile-wrap, anchored to the tile's bottom-right corner
   (the copy button owns the top-right). Like the copy button it's SSR-hidden,
   revealed by JS, and shown on hover/focus of the tile (or always-at-rest on
   touch). When expanded it stays visible (.is-open) so the open state never
   "disappears" when the pointer leaves. Reuses the accent-pill look so it reads
   as a sibling affordance of Copy. Tap target ≥44px on coarse pointers. */
.occ-compare {
  position: absolute;
  bottom: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border: 1px solid var(--accent-border);
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 12px/1 var(--ui-font);
  cursor: pointer;
  opacity: 0;
  transition: color 120ms, border-color 120ms, background 120ms, opacity 120ms;
}
.strongs-verse-list li.verse-tile-wrap:hover .occ-compare,
.strongs-verse-list li.verse-tile-wrap:focus-within .occ-compare,
.occ-compare.is-open,
.occ-compare[aria-expanded="true"] {
  opacity: 1;
}
.occ-compare:hover,
.occ-compare:focus-visible,
.occ-compare:focus {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  opacity: 1;
  outline: none;
}
.occ-compare-icon { display: inline-flex; flex: none; }
@media (hover: none), (pointer: coarse) {
  .occ-compare { opacity: 0.85; }
  /* #92 Item 3: comfortable ≥44px tap targets on touch (was 32px → ~32px tall,
     under the 44×44 WCAG/iOS minimum). box-sizing so min-height is the OUTER box
     incl. border; padding keeps the icon+label centered. Desktop density (the
     base 4px 9px rule) is untouched — this only applies on coarse pointers. */
  .occ-copy, .occ-compare {
    min-height: 44px;
    padding: 11px 13px;
    box-sizing: border-box;
  }
}

/* The revealed parallel-compare region beneath a tile. Reuses the .cmp-* row
   classes from the verse-page compare panel verbatim (app.js builds them with the
   same markup), so it inherits .cmp-row / .cmp-text / .cmp-license-chip styling
   for free. This wrapper just gives the inline expansion its own spacing + a left
   spine so it reads as a child of the tile above it. */
.occ-compare-panel {
  margin: 0 0 10px;
  padding: 12px 14px 4px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
}
.occ-compare-intro {
  margin: 0 0 10px;
  font: 500 12.5px/1.45 var(--ui-font);
  color: var(--text-dim);
}
/* The "nothing to compare — choose more versions" graceful state (the reader's
   compare set is effectively just their reading version). */
.occ-compare-empty {
  margin: 0 0 8px;
  font: 500 13px/1.45 var(--ui-font);
  color: var(--text-faint);
}
/* The compare region's own non-alignment caption (the honesty rail — whole-verse
   parallel text, never a word-level claim). Mirrors .cmp-nonalign. */
.occ-compare-nonalign {
  margin: 0 0 10px;
  font: italic 500 12px/1.45 var(--ui-font);
  color: var(--text-faint);
}
.occ-compare-error {
  margin: 0 0 8px;
  font: 500 13px/1.45 var(--ui-font);
  color: var(--text-faint);
}
.morph-badge {
  display: inline-block;
  font-family: var(--mono-font);
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  padding: 1px 5px;
  cursor: help;
}
.strongs-verse-list a.verse-tile:hover .morph-badge,
.strongs-verse-list a.verse-tile:focus .morph-badge {
  color: var(--accent);
  border-color: var(--accent-border);
}

/* Parse-filter matched cue. When a parse filter is active, the surface form(s)
   and morph badge(s) whose decoded feature genuinely equals the active facet
   carry `.matched` — an honest highlight (the morph really decodes, unlike the
   deliberately-unhighlighted English). A verse may show both matching and
   non-matching forms; only the genuine matches are emphasized. Subtle gold
   underline + weight on the form, gold-tinted fill on the badge — reuses the
   accent tokens, no layout shift (underline + transparent border keep the box
   the same size). */
.verse-surface.matched {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent-border);
  text-underline-offset: 3px;
}
.morph-badge.matched {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  font-weight: 600;
}

/* Book-tab / pagination links carry #tabpanel-occurrences so the browser
   scrolls back to the verses after each filter/page click. Without this
   margin the anchor would land flush against the viewport top, hiding the
   book-tab strip the user was just interacting with. */
#tabpanel-occurrences {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

/* Block-center the Where it appears (occurrences) panel content to match the
   hero/About/Lexicon Entry contained-column look. Left-align is preserved on
   all child elements (tiles, prose) — only the block itself is centered. */
.strongs-occurrences {
  max-width: 800px;
  margin-inline: auto;
}

/* Within-About anchor for the verse-page focus card's "See how English versions
   render this word →" deep-link (/w/<S>#about-renderings). Same offset as the
   tab anchors so the renderings heading clears the sticky site header instead of
   landing flush under it. About is default-open, so this is a plain in-page jump
   (no tab swap). */
#about-renderings {
  scroll-margin-top: calc(var(--header-h) + 16px);
}

/* Anti-flash: scroll-anchor.js adds this class to <html> while the browser
   is about to anchor-scroll to #tabpanel-occurrences. We keep the body
   visually empty until the JS scrolls and removes the class — that way the
   user never sees the brief pre-scroll paint that produced the visible
   flash. Pure visibility, no layout change. */
html.pending-anchor-scroll body {
  visibility: hidden;
}

/* Per-book filter strip inside the Occurrences panel. Pills (not tabs) so
   they read as a *filter* control distinct from the main tabbed card above.
   Each pill links to /w/<S>?book=<slug> — server-side filter, no JS — and
   the active pill is filled with the accent. Wraps for many-book Strong's. */
.strongs-book-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 18px;
  padding: 0 0 14px;
  border-bottom: 1px solid var(--border-soft);
}
.book-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  line-height: 1.3;
  text-decoration: none;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.book-tab:hover,
.book-tab:focus {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.book-tab.active {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--bg);
}
.book-tab.active:hover,
.book-tab.active:focus {
  background: var(--accent);
  color: var(--bg);
}
.book-tab-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  background: var(--bg-raised);
  border-radius: 999px;
  padding: 1px 7px;
  line-height: 1.5;
}
.book-tab.active .book-tab-count {
  background: rgba(10, 21, 48, 0.22);
  color: var(--bg);
}
/* #92 Item 3: comfortable ≥44px tap targets on touch for the concordance filter
   chips (the per-book strip AND the parse-filter strip both use .book-tab). The
   base 6px 12px padding gives ~29px tall — under the 44×44 minimum. Raise the
   min-height + vertical padding ONLY on coarse pointers; the chip is already an
   inline-flex row with centered content, so the larger box stays a single line
   and the wrap-flow layout is unchanged. Desktop density is untouched. */
@media (hover: none), (pointer: coarse) {
  .book-tab {
    min-height: 44px;
    padding: 10px 14px;
    box-sizing: border-box;
  }
}

/* Per-book group inside the paginated concordance. Each book gets a header
   (clickable into its /v/:slug index) with its total occurrence count, then
   its verse-chip grid (reusing .strongs-verse-list above). */
.strongs-book-group { margin: 0 0 22px; }
.strongs-book-group:last-of-type { margin-bottom: 0; }
.strongs-book-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 10px;
  padding: 0 0 6px;
  border-bottom: 1px solid var(--border-soft);
  font-size: 14px;
  font-weight: 600;
}
.strongs-book-link { color: var(--text); text-decoration: none; }
.strongs-book-link:hover,
.strongs-book-link:focus { color: var(--accent); outline: none; }
.strongs-book-count {
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* Pagination nav for the concordance. Prev / page-of / next on one row;
   the boundary page renders the unavailable direction as a muted span so the
   layout doesn't jump when the user lands on page 1 or the last page. */
.strongs-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 24px 0 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--border-soft);
  font-size: 14px;
}
.strongs-pagination .page-link {
  display: inline-block;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-card);
  color: var(--text);
  text-decoration: none;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.strongs-pagination .page-link:hover,
.strongs-pagination .page-link:focus {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.strongs-pagination .page-link.disabled {
  color: var(--text-dim);
  background: transparent;
  border-color: var(--border-soft);
  cursor: default;
  opacity: 0.55;
}
.strongs-pagination .page-link.disabled:hover,
.strongs-pagination .page-link.disabled:focus {
  border-color: var(--border-soft);
  color: var(--text-dim);
  background: transparent;
}
.strongs-pagination .page-indicator { color: var(--text-dim); font-size: 13px; }

/* About-tab content — entry-specific corpus stats. Whole panel center-aligns
   so the cards, headings, and prose all read as a focused summary instead of
   the loose left-aligned paragraph the panel used to be. */
.strongs-about {
  text-align: center;
}
.strongs-about a {
  color: var(--accent);
  text-decoration: none;
}
.strongs-about a:hover,
.strongs-about a:focus { text-decoration: underline; outline: none; }

/* Gold section headers (ABOUT THIS WORD / MOST CONCENTRATED IN / WORD PROFILE).
   Scoped under .tabpanel so the accent color + sizing outrank the generic
   `.tabpanel p { color: --text-dim; font-size: 14px }` rule — same trick as
   .gloss-history-head. */
.tabpanel .about-head {
  margin: 0 0 12px;
  font: 700 12px/1.2 var(--ui-font);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.tabpanel .about-intro {
  font-size: 15px;
  color: var(--text);
  line-height: 1.6;
  margin: 0 0 26px;
}
.tabpanel .about-intro strong { color: var(--accent); font-weight: 600; }

/* Provenance line on the /w/ and /lxx/ About tabs (AdSense remediation L9) —
   the one place either page states which of the material on it is Lemma's own
   work. A LEFT rule rather than the hairline .commentary-provenance uses: this
   one follows .about-intro, whose 26px bottom margin already supplies the
   separation, and a second horizontal rule there would collide with the
   .about-rule convention that divides the About sub-sections below it. */
.about-provenance {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
  margin: 0 0 26px;
  padding: 2px 0 2px 12px;
  border-left: 2px solid var(--border-soft);
}

/* Horizontal rule between About sub-sections. */
.about-rule {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: 26px 0 22px;
}

/* Stat cards — four across on desktop, 2x2 on phones. Icon, big value, label,
   one-line note. The two count cards read neutral; the first/last reference
   cards (.about-stat-ref) go gold + serif. */
.about-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin: 0 0 4px;
  padding: 0;
}
/* #77: the frequency-rank card is now always present, so a multi-verse word
   shows five cards (distinct verses + books + first + last + frequency). In the
   wide 4-column grid the fifth card would otherwise wrap alone to the second
   row, stranded at quarter width on the left. Centre that lone wrapped card by
   spanning the two middle columns so the second row reads balanced. Scoped to
   EXACTLY five cards (:nth-child(5):last-child), so the four-card hapax row and
   any other count are untouched. */
.about-stats > .about-stat:nth-child(5):last-child {
  grid-column: 2 / span 2;
}
.about-stat {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 22px 16px 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
}
.about-stat-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-bottom: 2px;
  color: var(--text-dim);
}
.about-stat-icon svg { width: 28px; height: 28px; }
.about-stat-value {
  margin: 0;
  font: 600 24px/1.1 var(--ui-font);
  color: var(--text);
}
.about-stat-of { font-size: 18px; font-weight: 400; color: var(--text-dim); }
.about-stat-label {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.about-stat-note {
  margin: 4px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-dim);
  max-width: 24ch;
}
.about-stat-ref .about-stat-icon { color: var(--accent); }
.about-stat-ref .about-stat-value {
  font-family: var(--reading-font);
  font-size: 21px;
  font-weight: 600;
}
.about-stat-ref .about-stat-value a { color: var(--accent); }

/* "View all N occurrences in the concordance →" (R5) — frames the corpus stats
   above as a preview that leads into the real Appearances concordance tab. A
   plain anchor (works with no JS via the #tabpanel-occurrences fragment); JS
   switches tabs in place. A pill so it reads as an action, not body copy. */
.about-concordance-jump {
  /* C4: symmetric vertical margin so the pill sits evenly between the
     corpus-stats grid above and the <hr>/section below (was 14px 0 0 — space
     above, none below, which read as crowding the rule beneath it). Still
     centered horizontally. */
  margin: 20px 0;
  text-align: center;
}
.about-concordance-jump a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  padding: 7px 14px;
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  background: var(--accent-soft);
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-about .about-concordance-jump a:hover,
.strongs-about .about-concordance-jump a:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  text-decoration: none;
  outline: none;
}

/* Two-column band: most-concentrated + by-section. Collapses to one column
   when the panel can't fit two readable tracks. */
.about-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 26px 44px;
  align-items: start;
}

/* Most-concentrated list — icon | book name | verses | percent, one per row. */
.about-topbooks { list-style: none; padding: 0; margin: 0; }
.about-topbook {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-soft);
}
.about-topbook:last-child { border-bottom: 0; }
.about-topbook-icon { display: inline-flex; color: var(--accent); }
.about-topbook-icon svg { width: 20px; height: 20px; }
.about-topbook-name {
  font-family: var(--reading-font);
  font-size: 18px;
  color: var(--accent);
}
.about-topbook-verses { font-size: 13px; color: var(--text-dim); white-space: nowrap; }
.about-topbook-pct {
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  min-width: 3.5ch;
  text-align: right;
}

/* Section-breakdown bars. The SVG track sits between a left-aligned section
   label and a right-aligned count/percent so all rows align across sections.
   SVG rect width is a presentation attribute (CSP-safe under strict policy). */
.about-bars {
  list-style: none;
  padding: 0;
  margin: 0;
}
.about-bar {
  display: grid;
  grid-template-columns: 120px 1fr 92px;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 13px;
  text-align: left;
}
.about-bar-label {
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.about-bar-track {
  display: block;
  width: 100%;
  height: 7px;
  background: var(--border-soft);
  border-radius: 4px;
  overflow: hidden;
}
.about-bar-fill { fill: var(--accent); }
.about-bar-value {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Traditional-corpus roll-up (About tab, #82) — a labeled LIST, deliberately
   NOT parts-of-whole bars: the NT corpora overlap, so bars (which imply a
   partition summing to 100) would mislead. The distinct visual treatment (a
   plain label + "N verses · P%", no track) is itself an honesty signal that
   these shares are independent, not slices of a whole. */
.about-corpora {
  list-style: none;
  padding: 0;
  /* Kept in lockstep with .about-forms' max-width, so the two blocks line up. */
  max-width: 760px;
  margin-inline: auto;
}
.about-corpus {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: 14px;
}
.about-corpus:last-child { border-bottom: 0; }
.about-corpus-name { color: var(--text); }
.about-corpus-value {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Translation-rendering breakdown (About tab, #13/#22) — per-version compact
   histograms ("How translations render this word": KJV + ASV + BSB). The class is
   .renderings-breakdown (distinct from the #about-renderings deep-link id on the
   sibling heading). On a wide screen the versions sit side by side (.is-multi →
   auto-fit columns); they stack on mobile. Each bar reuses the CSP-safe SVG-width
   fill pattern of .about-bar (no inline styles); the label column wraps so
   multi-word renderings read in full. */
/* #79: at-a-glance per-version rendering summary — one compact line per version
   (name + top 3 content renderings with counts) above the detailed histograms.
   Each line stands alone; counts are never merged across versions. */
.rndr-summary {
  list-style: none;
  padding: 0;
  margin: 0 0 14px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.rndr-summary-row {
  font-family: var(--ui-font);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-dim);
}
.rndr-summary-ver {
  font-weight: 700;
  color: var(--text);
  margin-right: 4px;
}
.rndr-summary-word { color: var(--text); font-weight: 600; }
.rndr-summary-item { white-space: nowrap; }
.rndr-summary-none { font-style: italic; color: var(--text-faint); }

/* #80: grammatical-forms profile atop the Appearances concordance — a compact
   read-only summary of the word's full head-parse distribution, echoing the
   .rndr-summary idiom (the #79 renderings rollup) for visual consistency. */
/* Grammar key (#88) — the Appearances-tab collapsed plain-English decoder for
   the parse-filter chips + per-tile morph badges. Mirrors the /morphology page's
   .morphology-glossary block but kept /w/-scoped so the two pages can diverge. */
.grammar-key {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 4px 16px;
  margin: 0 0 16px;
}
.grammar-key-summary {
  font: 600 13.5px/1.4 var(--ui-font);
  color: var(--text);
  cursor: pointer;
  padding: 10px 0;
  min-height: 44px; /* #88: ≥44px touch target (was ~39px); keeps list-item marker — no flex */
  box-sizing: border-box;
  list-style-position: inside;
}
.grammar-key-summary:hover { color: var(--accent); }
.grammar-key-body {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px 24px;
  padding: 6px 0 14px;
}
.grammar-key-facet {
  font: 700 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 8px 0 6px;
}
.grammar-key-list { margin: 0; }
.grammar-key-list dt {
  font: 600 13px/1.4 var(--ui-font);
  color: var(--text);
  margin-top: 6px;
}
.grammar-key-list dd {
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 1px 0 0;
}
/* #92 Item 2: the word-specific verbatim BDB meaning appended to a stem entry in
   the touch-reachable grammar-key <details> (mirrors the chip title=). Accent so
   it reads as the word's own sense, distinct from the generic grammar def. */
.grammar-key-meaning {
  color: var(--accent);
  font-weight: 600;
}

.parse-distribution {
  margin: 0 0 16px;
  padding: 14px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}
.parse-dist-head {
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 8px;
}
.parse-dist-distinct {
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-faint);
}
.parse-dist-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.parse-dist-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-family: var(--ui-font);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-dim);
}
.parse-dist-parse { color: var(--text); font-weight: 600; }
.parse-dist-count { white-space: nowrap; color: var(--text-dim); }
.parse-dist-more {
  font-family: var(--ui-font);
  font-size: 12px;
  font-style: italic;
  color: var(--text-faint);
  margin: 8px 0 0;
}
.parse-dist-note {
  font-family: var(--ui-font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-faint);
  margin: 8px 0 0;
}

.renderings-breakdown { margin: 2px 0 4px; }
/* #92: on phones (≥360px) lay the 2–4 version cards out 2-up so they read as a
   compact 2×2 grid instead of one tall single-column stack. The narrowest phones
   (<360px) keep the single-column normal-flow stack — two columns there would be
   too cramped for the histogram bars. The desktop (≥760px) auto-fit rule below
   takes over from this band. 3 versions → 2+1; 4 → 2×2; 2 → 1 row. */
@media (min-width: 360px) and (max-width: 759.98px) {
  .renderings-breakdown.is-multi {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    align-items: start;
  }
  /* #94: in the 2-up phone band each card's inner content is only ~138px wide, so
     the default 3-column histogram row (88px label + 1fr bar + 52px count + gaps)
     squeezes the bar to near-zero and wraps the rendering label. Re-flow the row
     to two lines: the rendering word + count on the first line, the bar spanning
     the full card width on a second line below — reclaiming full bar + label width.
     DOM order is .rndr-word, .rndr-track (svg bar), .rndr-count, so place each into
     its grid cell explicitly. Scoped to the .is-multi 2-up band only — the desktop
     ≥760px auto-fit and the <360px single-column stack keep the inline 3-col row. */
  .renderings-breakdown.is-multi .rndr-row {
    grid-template-columns: 1fr auto;
    column-gap: 8px;
    row-gap: 5px;
  }
  .renderings-breakdown.is-multi .rndr-word { grid-column: 1; }
  .renderings-breakdown.is-multi .rndr-count {
    grid-column: 2;
    font-variant-numeric: tabular-nums;
    font-size: 13.5px;
  }
  .renderings-breakdown.is-multi .rndr-track { grid-column: 1 / -1; }
}
@media (min-width: 760px) {
  .renderings-breakdown.is-multi {
    display: grid;
    /* auto-fit so 2 or 3 tagged versions (KJV / ASV / BSB …) flow side by side as
       width allows, and gracefully wrap to fewer columns on a narrow panel.
       #75: bumped 210→232px so each card's inner content keeps usable width once
       the new card padding (16px each side) is subtracted. */
    grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
    gap: 16px;
    align-items: start;
  }
}
/* #75: card each per-version block in the same visual language as the corpus stat
   cards (.about-stat) and the hero stat cards (.strongs-stat-card) — subtle bg,
   soft border, rounded corners, comfortable padding — so the 2–4 version
   comparison reads as discrete cards instead of bare columns. Layout of the
   .is-multi grid is responsive (#92): 2-col on phones ≥360px, single full-width
   stack below 360px, desktop auto-fit ≥760px; the histogram bars keep full usable
   width inside the card padding in every band. The single-version case (no
   .is-multi) is one such card, always full-width. */
.about-rndr-version {
  min-width: 0;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  padding: 16px;
}
.about-rndr-head {
  margin: 0 0 4px;
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
}
/* Per-version license chip in the rendering-breakdown head (so the CC BY-SA ULT is
   never read as public domain alongside the PD KJV/ASV/BSB). */
.about-rndr-lic {
  display: inline-block;
  margin-left: 6px;
  font: 600 9.5px/1 var(--ui-font);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-faint);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 5px;
  padding: 3px 5px;
  vertical-align: middle;
}
.about-rndr-lic.is-cc { color: var(--accent); border-color: var(--accent-border); }
.about-rndr-intro {
  margin: 0 0 8px;
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-dim);
}
.rndr-bars { list-style: none; padding: 0; margin: 0; }
.rndr-row {
  display: grid;
  grid-template-columns: minmax(88px, 42%) 1fr 52px;
  align-items: center;
  gap: 9px;
  padding: 5px 0;
  font-size: 13px;
  text-align: left;
}
.rndr-word { color: var(--text); font-weight: 600; }
.rndr-track {
  display: block;
  width: 100%;
  height: 8px;
  background: var(--border-soft);
  border-radius: 4px;
  overflow: hidden;
}
.rndr-fill { fill: var(--accent); }
.rndr-count {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.rndr-foot {
  margin: 4px 0 0;
  font-family: var(--ui-font);
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-faint);
}

/* #77: the Word-profile grid (`.about-profile*`) was retired from the About tab.
   Its rules are removed here; its two surviving facts now live in the corpus-
   stats grid (frequency) and the Word-origin meta line (part of speech). */

/* Root word + dominant form render in the original script. */
.about-root-lemma { color: var(--accent); }
.about-root-lemma.hebrew, .about-form-glyph.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.about-root-lemma.greek, .about-form-glyph.greek { font-family: var(--greek-font); }
.about-root-translit { font-style: italic; color: var(--text-dim); }
.about-root-gloss { color: var(--text-dim); }
.about-form-glyph { font-size: 21px; color: var(--accent); }

/* Word origin (#38a) — the etymology study block: a derivation line, a compact
   part-of-speech / TWOT-TDNT meta row, and the authored public-domain Strong's
   (1890) derivation note in a decorative quote card. Reuses the About-tab type
   scale + accent tokens; centered to match the sibling collapse panels. */
.about-origin {
  max-width: 620px;
  margin-inline: auto;
}
.about-origin-deriv {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text);
  margin: 0 0 12px;
}
.about-origin-code { color: var(--text-dim); }
.about-origin-meta {
  display: flex;
  flex-wrap: wrap;
  /* Center the meta line horizontally to match the centered Word Origin section
     (the .strongs-about panel is text-align:center; this flex row needs its own
     justify-content + text-align to follow suit). */
  justify-content: center;
  text-align: center;
  gap: 6px 18px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 0 0 16px;
}
.about-origin-label {
  font-weight: 600;
  color: var(--text);
}
.about-origin-prose {
  position: relative;
  padding: 14px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-inline-start: 3px solid var(--accent);
  border-radius: 12px;
}
.about-origin-quote {
  margin: 0;
  font-family: var(--reading-font);
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
}
.about-origin-quote a { color: var(--accent); }
.about-origin-cite {
  margin: 10px 0 0;
  font-size: 12.5px;
  font-style: italic;
  color: var(--text-dim);
}

/* #61: verbatim BDB etymology/derivation header(s) — the lead etymology element
   for Hebrew. A quote-card like the Strong's-1890 prose, one labeled paragraph per
   homograph. Hebrew runs inside are <bdi dir="rtl"> (bidi-isolated), so the mixed
   RTL/LTR prose reads correctly. */
.about-origin-bdb {
  position: relative;
  padding: 14px 16px;
  margin: 0 0 14px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-inline-start: 3px solid var(--accent);
  border-radius: 12px;
}
.about-origin-bdbline {
  margin: 0 0 8px;
  font-family: var(--reading-font);
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
}
.about-origin-bdbline:last-of-type { margin-bottom: 0; }
.about-origin-bdblabel {
  font-weight: 700;
  color: var(--accent);
}
.about-origin-bdb .about-origin-cite { margin-top: 10px; }

/* Bible dictionary (#38b) — stacked public-domain articles (Easton's / Smith's /
   Hitchcock's) on proper-noun pages. Each source is a labelled block of reading-
   font paragraphs; the source head echoes the gold .about-head accent. */
.about-dict-source {
  margin: 0 0 20px;
}
.about-dict-source:last-of-type {
  margin-bottom: 8px;
}
.about-dict-sourcehead {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.about-dict-note {
  margin: 0 0 10px;
  font-family: var(--reading-font);
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
}
.about-dict-note:last-child {
  margin-bottom: 0;
}
.about-dict-foot {
  margin-top: 4px;
}

/* Forms-in-the-corpus table (#37) — the enumerated written-forms list. Left-
   aligned (the panel is centered by default), tabular numerals on the count, a
   slim frequency bar echoing the renderings/section histograms. The parse cell
   links into the concordance's parse facet. */
.about-forms {
  width: 100%;
  /* Cap the width so it reads as a study table, not a full-width spreadsheet —
     otherwise the short Parsing text leaves a big empty gulf before the
     right-flushed Uses column. Form + Uses shrink to content; Parsing + the
     Example column take the slack. */
  max-width: 760px;
  margin-inline: auto;
  border-collapse: collapse;
  text-align: left;
  margin-top: 4px;
  font-family: var(--ui-font);
}
.about-forms th {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 4px 10px 8px;
  border-bottom: 1px solid var(--border);
}
.about-forms td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-faint, var(--border));
  vertical-align: middle;
}
.about-forms tr:last-child td { border-bottom: 0; }
.about-forms-form { white-space: nowrap; }
.about-forms-form .about-form-glyph { font-size: 19px; }
.about-forms-tr {
  margin-inline-start: 8px;
  font-style: italic;
  font-size: 13px;
  color: var(--text-dim);
}
.about-forms-parse {
  font-family: var(--reading-font);
  font-size: 14px;
  line-height: 1.45;
  color: var(--text);
}
.about-forms-parse a { color: var(--accent); text-decoration: none; }
.about-forms-parse a:hover, .about-forms-parse a:focus { text-decoration: underline; }
.about-forms-noparse { color: var(--text-faint); }
/* Example-verse cell — a representative occurrence linked to its /v/ page.
   Reading/UI type + accent link, matching .about-forms-parse a. */
.about-forms-example {
  font-family: var(--reading-font);
  font-size: 14px;
  line-height: 1.45;
  white-space: nowrap;
}
.about-forms-example a { color: var(--accent); text-decoration: none; }
.about-forms-example a:hover, .about-forms-example a:focus { text-decoration: underline; }
.about-forms-example .about-forms-noexample { color: var(--text-faint); }
.about-forms-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.about-forms-bar {
  vertical-align: middle;
  margin-inline-end: 8px;
  opacity: 0.85;
}
.about-forms-bar-fill { fill: var(--accent); }
.about-forms-count { color: var(--text); }
.about-forms-more { margin-top: 10px; }
@media (max-width: 560px) {
  .about-forms-bar { display: none; }
  .about-forms th, .about-forms td { padding-inline: 6px; }
}

/* Word story (rule-based NLG) — the About-tab lead-in. A short auto-summary of
   the page's data, every clause linking to its source. Reads as plain reading
   prose (--reading-font) under a quiet disclosure label, set off by a soft card
   so it's clearly an auto-assembled summary and not editorial copy. Consistent
   with the About-tab type scale (.about-intro / .about-senses-intro). */
.word-story {
  margin: 0 0 24px;
  padding: 16px 18px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
.word-story-disclosure {
  margin: 0 0 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
}
.word-story-disclosure-lead {
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  font-size: 11px;
}
/* Scoped under .tabpanel so the intended 16px/1.62 reading size outranks the
   generic `.tabpanel p { font-size: 14px; line-height: 1.7 }` rule (same
   specificity trick as .tabpanel .about-head / .about-intro). The measure cap
   matches the sibling About prose convention (.about-origin → max-width:620px;
   margin-inline:auto) so desktop lines land in the comfortable ~45–75ch range
   instead of running edge-to-edge (~184ch). Mobile is unaffected — the column is
   narrower than the cap. */
.tabpanel .word-story-body {
  margin: 0;
  max-width: 66ch;
  margin-inline: auto;
  font-family: var(--reading-font);
  font-size: 16px;
  line-height: 1.62;
  color: var(--text);
}
.word-story-sentence { /* discrete inline element so mobile can drop whole
                          low-priority fragments without truncating mid-sentence */ }
.word-story-body a { color: var(--accent); }
/* Mobile (Q2): drop whole low-priority fragments (family + the detail-heavy
   closing variant, marked .word-story-extra by the composer) — never the
   identity, hook, or disclosure. Same 560px breakpoint the rest of the About
   tab uses. The composer keeps each sentence a discrete inline element, so the
   surrounding sentences flow unbroken. */
@media (max-width: 560px) {
  .word-story-extra { display: none; }
}

/* Senses facet — the top-level BDB/Thayer senses as a numbered list. Reuses the
   About-tab type scale; the gold ordinal markers echo .about-head's accent. */
.about-senses-intro {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-dim);
  margin: 0 0 16px;
}
.about-senses-intro a { color: var(--accent); }
.about-senses {
  margin: 0;
  padding: 0 0 0 8px;
  list-style: none;
  counter-reset: about-sense;
  display: grid;
  gap: 10px;
}
.about-sense {
  counter-increment: about-sense;
  position: relative;
  padding: 10px 14px 10px 44px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  font-family: var(--reading-font);
  font-size: 16px;
  line-height: 1.45;
  color: var(--text);
}
.about-sense::before {
  content: counter(about-sense);
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent);
  color: var(--bg);
  font: 700 12px/1 var(--ui-font);
}
/* Full-BDB sense (#42) example-reference link — a compact "e.g. <verse>" after
   the gloss, in the UI font so it reads as metadata, not part of the gloss. */
.about-sense-ref {
  margin-left: 6px;
  font-family: var(--ui-font);
  font-size: 12.5px;
  white-space: nowrap;
  color: var(--accent);
}
.about-bdb-cite { margin-top: 12px; }

/* #61/#45: nested full-BDB sense tree — BDB's own a/b/c sub-sense hierarchy as
   indented <ul>/<li> lists, with the lexicon's verbatim marker (1/a/I…) and fuller
   prose. Each item carries its own marker text (BDB mixes 1/a/I and restarts
   numbering per binyan), so we do NOT use a CSS counter — the marker is rendered
   inline (hence list-style:none). Hebrew runs in the prose are <bdi dir="rtl">.
   (Also reused verbatim, same classes, by the Jastrow facet's `.about-jastrow-tree`
   — a fix here applies to both.)

   Hotfix: the whole panel is `.strongs-about { text-align: center }` (see above),
   which the tree used to inherit — markers and wrapped prose lines read centered
   instead of as a left-aligned outline. `text-align: left` here breaks that
   inheritance for the tree only (same "explicit left-align inside the centered
   About panel" pattern as `.about-bdb-legend-table`), and `.about-bdb-item` gets a
   classic CSS-only hanging indent (padding-inline-start + matching negative
   text-indent) so a wrapped prose line lands under the prose, not under the
   marker, and nested sub-lists read as a clear outline. The marker itself becomes
   a fixed-min-width inline-block so every marker column (however wide the BDB
   marker text is: "1." vs "12." vs "III.") lines up consistently. */
.about-bdb-tree {
  margin: 0;
  font-family: var(--reading-font);
  text-align: left;
}
.about-bdb-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
/* Nested sub-lists indent and sit slightly tighter than their parent item. */
.about-bdb-list .about-bdb-list {
  margin-top: 8px;
  padding-inline-start: 18px;
  border-inline-start: 1px solid var(--border-soft);
  gap: 6px;
}
.about-bdb-item {
  font-size: 15.5px;
  line-height: 1.5;
  color: var(--text);
  /* Hanging indent: the negative text-indent pulls the FIRST line (marker +
     start of prose) back to the item's left edge; every wrapped line falls back
     to the normal padding-inline-start offset, landing under the prose rather
     than under the marker. Applies recursively to nested `.about-bdb-item`s, so
     each deeper level hangs under its own marker too. */
  padding-inline-start: 30px;
  text-indent: -30px;
}
/* A structural-parent scaffold row (no own prose — just an outline node whose
   lettered children carry the content): show its marker, dim, no card. */
.about-bdb-item.is-scaffold {
  color: var(--text-dim);
  font-size: 14.5px;
}
.about-bdb-marker {
  display: inline-block;
  min-width: 26px;
  font: 700 13px/1.4 var(--ui-font);
  color: var(--accent);
  margin-inline-end: 2px;
}
.about-bdb-prose { color: var(--text); }
.about-bdb-item.is-scaffold .about-bdb-prose { color: var(--text-dim); }
@media (max-width: 480px) {
  .about-bdb-item {
    padding-inline-start: 24px;
    text-indent: -24px;
  }
  .about-bdb-marker { min-width: 20px; }
}

/* #86(b): BDB abbreviations legend — a small, unobtrusive native <details> that
   decodes the scholarly sigla (𝔊/𝔙/𝔖/𝔗/ψ/√/‖/†) a non-expert meets in the
   verbatim sense tree. Collapsed by default (one click for novices, out of the
   way for experts); sits with the binyan primer ABOVE the collapsible apparatus
   so it never hides on collapse. No JS — the native disclosure handles it. */
.about-bdb-legend {
  margin: 0 0 16px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg-raised);
}
.about-bdb-legend > summary {
  cursor: pointer;
  list-style: none;
  padding: 9px 12px;
  font: 600 13px/1.4 var(--ui-font);
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 8px;
}
.about-bdb-legend > summary::-webkit-details-marker { display: none; }
/* A small chevron that rotates when the disclosure opens. */
.about-bdb-legend > summary::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.about-bdb-legend[open] > summary::before { transform: rotate(45deg); }
.about-bdb-legend > summary:hover { color: var(--text); }
.about-bdb-legend > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.about-bdb-legend-intro {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 0;
  padding: 0 12px 8px;
}
.about-bdb-legend-table {
  /* Center the table in the card. A display:table box stretches to fill its
     container — and the sigil column's `width:1%` (a full-width-table idiom) pins
     it to 100% — so plain auto margins had no slack to center into (the table
     read as left-aligned). width:max-content shrink-wraps the table to its widest
     row instead, so margin auto then has room to center it; max-width caps it so a
     narrow viewport fills the card and wraps. */
  display: table;
  width: max-content;
  max-width: 100%;
  border-collapse: collapse;
  margin: 0 auto;
  text-align: left;
  font-family: var(--ui-font);
}
.about-bdb-legend-table th {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 0 12px 6px;
  border-bottom: 1px solid var(--border);
}
.about-bdb-legend-table th:first-child,
.about-bdb-legend-table td:first-child {
  padding-inline-start: 12px;
}
.about-bdb-legend-table th:last-child,
.about-bdb-legend-table td:last-child {
  padding-inline-end: 12px;
}
.about-bdb-legend-table td {
  padding: 6px 12px;
  border-bottom: 1px solid var(--border-faint, var(--border));
  vertical-align: top;
}
.about-bdb-legend-table tbody tr:last-child td {
  border-bottom: 0;
  padding-bottom: 12px;
}
.about-bdb-legend-sigil-cell {
  width: 1%;
  white-space: nowrap;
  font-weight: 700;
  color: var(--accent);
}
.about-bdb-legend-table td:last-child {
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text);
  white-space: normal;
}
@media (max-width: 360px) {
  .about-bdb-legend-table th,
  .about-bdb-legend-table td {
    padding-inline: 8px;
  }
}

/* #71: homograph divider — for a Hebrew word BDB splits into 2+ distinct words
   (homographs), e.g. H2617 חֶסֶד = I "kindness" + II "shame". Each homograph's
   senses render under its own divider so they read as separate words. Visually
   distinct from the binyan stem sub-head (.about-senses-group, plain bold) and the
   numbered/lettered sense markers: a gold accent rule + the lemma in reading type,
   BDB's own roman numeral as a pill, and (when BDB gives one) its verbatim head
   gloss. Carries the meaning of a head-gloss-only homograph that has no sub-senses,
   so it is no longer invisible. */
.about-homograph-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: 18px 0 10px;
  padding-block-start: 12px;
  border-block-start: 2px solid var(--accent);
}
.about-homograph-head:first-child { margin-top: 0; }
.about-homograph-lemma {
  font-family: var(--reading-font);
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
}
.about-homograph-num {
  font: 700 12px/1 var(--ui-font);
  color: var(--bg);
  background: var(--accent);
  border-radius: 4px;
  padding: 3px 7px;
  letter-spacing: 0.04em;
}
.about-homograph-gloss {
  font-size: 14.5px;
  color: var(--text-dim);
}

/* Same-root word family — chips linking to other entries that cite the same
   etymological root. Each chip is an internal /w/ link carrying the member's
   lemma + transliteration + Strong's + short gloss. Reuses the card surface +
   accent tokens; a responsive auto-fit grid. */
.about-family-subhead {
  margin-top: 18px;
  margin-bottom: 10px;
  font-size: 12px;
}
.about-family {
  list-style: none;
  margin: 0 0 6px;
  padding: 0;
  display: grid;
  /* auto-fit (not auto-fill) collapses any track that ends up with no chip
     placed in it, so a lone tile or a short row (no full row above it) shrinks
     the track group to just its own width instead of stretching across
     leftover columns; justify-content then centers that (possibly narrower)
     track group. A full row still fills the width exactly as before — the
     fixed 220px max just stops a tile from stretching wider than its
     neighbours in a partial row. min(100%, 220px) is unchanged from before and
     keeps a single tile from overflowing a narrow (~320px) viewport. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 220px));
  justify-content: center;
  gap: 10px;
}
.about-family-chip { margin: 0; }
.about-family-link {
  display: flex;
  flex-direction: column;
  gap: 3px;
  height: 100%;
  box-sizing: border-box;
  padding: 10px 13px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  text-decoration: none;
  transition: border-color 120ms, background 120ms;
}
.about-family-link:hover,
.about-family-link:focus-visible {
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
  text-decoration: none;
}
.about-family-lemma {
  font-size: 19px;
  line-height: 1.2;
  color: var(--accent);
}
.about-family-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.about-family-lemma.greek { font-family: var(--greek-font); }
.about-family-translit {
  font-style: italic;
  font-size: 13px;
  color: var(--text-dim);
}
.about-family-code {
  font-family: var(--mono-font);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--text-faint);
}
.about-family-gloss {
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-dim);
}
.about-family-more {
  margin-top: 0;
  margin-bottom: 4px;
  font-size: 13px;
}
/* #78: the disclaimer line under the proper-names sub-group — sits between the
   "Proper names from this root" subhead and the name chips, so a learner reads
   names as names, not as additional senses. */
.about-family-names-note {
  margin-top: 0;
  margin-bottom: 10px;
  font-size: 13px;
}

/* About-tab lower-panel collapses (R1 declutter) — the cognate word-family +
   Septuagint cell are SSR-expanded (crawler/no-JS see everything) and collapsed
   by JS so the tab reads core-stats-first. The head row carries the section
   title (left) and the reveal toggle (right). The toggle is SSR-hidden via the
   global [hidden] rule and only un-hidden by app.js's initAboutCollapse, so
   without JS the panel just renders open with no control. The chevron rotates
   off aria-expanded so it points down when open, right when collapsed. */
.about-collapse-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* The .about-head inside carries its own bottom margin; zero it here so the
     row aligns and the toggle sits flush with the title baseline. */
}
/* #77: the `.about-collapse--centered .about-profile` rule was removed with the
   retired Word-profile grid (its sole user). The `--centered` modifier is no
   longer emitted by any template. */
.about-collapse-head .about-head {
  margin-bottom: 0;
  text-align: left;
}
.about-collapse-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.about-collapse-toggle:hover,
.about-collapse-toggle:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
/* CSS-only chevron — a rotated border-wedge so no inline SVG/style is needed.
   Points right when collapsed (aria-expanded="false"); rotates to point down
   when the panel is open. */
.about-collapse-toggle-chevron {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 140ms ease;
}
.about-collapse-toggle[aria-expanded="true"] .about-collapse-toggle-chevron {
  transform: rotate(45deg);
}
/* When collapsed, drop the head's own bottom gap so the section reads tight. */
.about-collapse-body {
  margin-top: 14px;
}
/* Constrain three sections' content to the same centered prose column the other
   About sections use (.about-origin → max-width:620px; margin-inline:auto), so
   their prose/articles/lists don't stretch edge-to-edge while the BDB Senses
   tree, renderings, forms and corpus stats sit constrained. Scoped by id to ONLY
   these three bodies — the shared .about-collapse-body (BDB senses, forms,
   Septuagint usage) is left untouched. */
#about-jastrow-body,
#about-dict-body,
#about-lxxpar-body {
  max-width: 620px;
  margin-inline: auto;
}

/* Download word-profile card — same filled gold button as the hero share link,
   centered below the profile. Selectors are scoped under .strongs-about so they
   outrank the panel's generic `.strongs-about a:hover { text-decoration:
   underline }` (which would otherwise underline the button on hover). */
.about-share-wrap {
  display: flex;
  justify-content: center;
  margin-top: 26px;
}
.strongs-about .about-share,
.verse-about .about-share {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  padding: 10px 18px;
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  background: var(--accent-soft);
  transition: color 120ms, border-color 120ms, background 120ms;
}
.strongs-about .about-share svg,
.verse-about .about-share svg { width: 17px; height: 17px; flex: none; }
.strongs-about .about-share:hover,
.strongs-about .about-share:focus-visible,
.verse-about .about-share:hover,
.verse-about .about-share:focus-visible {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  text-decoration: none;
  outline: none;
}

/* Lexicon-entry tab intro — replaces the visual role the per-section h2
   border-bottom used to play before these sections were tabbed. */
.strongs-tab-intro {
  margin: 0 0 14px;
  color: var(--text-dim);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--border-soft);
  padding-bottom: 8px;
}

/* ----------------------------------------------------------------------------
   Lexicon Entry tab (/w/) — icon-badged field cards. A gold "From <Lexicon>"
   header, then a 2-up grid of short scalar fields (part of speech, TDNT/TWOT)
   and full-width blocks for origin, definition, and the Strong's concordance
   entry. Each card pairs a circular gold icon badge with a cool-toned label
   and its value.
   ---------------------------------------------------------------------------- */

/* Block-center the Lexicon Entry panel content (like the hero/About sections).
   Only the block is constrained — prose and tiles remain left-aligned. */
.strongs-lexicon {
  max-width: 800px;
  margin-inline: auto;
}

/* Gold source header with a short accent underline. Scoped under .tabpanel so
   its gold color outranks the generic `.tabpanel p { color: --text-dim }` rule
   (which would otherwise win on specificity and render this header gray).
   Centered to match the contained-column layout. */
.tabpanel .lex-source-head {
  position: relative;
  margin: 0 0 18px;
  padding-bottom: 9px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  text-align: center;
}
.lex-source-head::after {
  content: "";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: 48px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
}

/* 2-up grid for the short scalar cards; a lone card stretches to full width. */
.lex-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 12px;
  margin-bottom: 12px;
}
/* Meta row (part of speech + TDNT/TWOT + Origin on one row). A smaller min
   track lets all three sit side-by-side on desktop while still collapsing to
   1–2 columns as the panel narrows. Top-align because Origin can wrap to
   several lines next to the single-line scalar fields. */
.lex-card-grid-meta {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.lex-card-grid-meta .lex-card { align-items: flex-start; }

.lex-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
}
/* Full-width field blocks: top-align the badge with the label and add inter-
   block spacing. */
.lex-card-block {
  align-items: flex-start;
  margin-bottom: 12px;
}

.lex-card-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.lex-card-icon svg { width: 22px; height: 22px; }
.lex-card-icon-text {
  font-family: var(--reading-font);
  font-size: 19px;
  font-weight: 600;
}

.lex-card-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.lex-card-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.lex-card-value {
  font-size: 17px;
  line-height: 1.35;
  color: var(--text);
}
/* Long-form fields (origin, definition, Strong's entry): preserve the source
   line breaks. Reference-style fields (origin, Strong's concordance entry) fill
   the card width; only the flowing Definition keeps a readable measure (below). */
.lex-card-prose {
  font-size: 16px;
  line-height: 1.7;
  white-space: pre-wrap;
}
/* The Definition is long-form reading prose — cap its measure so lines stay
   comfortable even when the panel is wide. Origin / Strong's-entry are reference
   data and intentionally extend full width. Bumped to 18px/1.75 so the BDB body
   reads at a comfortable book-like size distinct from the scalar field values. */
.lex-card-def {
  max-width: 72ch;
  font-size: 18px;
  line-height: 1.75;
}
/* Long multi-sense definitions: flow into balanced columns (capped at 2) so a
   tall entry fills the panel width instead of running as one narrow ribbon.
   `columns: 32ch 2` keeps each column a readable ~32ch measure and uses 2
   columns only when the viewport can fit them — it collapses to a single column
   on narrow screens automatically. Applied server-side via .lex-card-cols only
   when the entry is long enough to warrant it. */
.lex-card-def.lex-card-cols {
  max-width: none;
  columns: 32ch 2;
  column-gap: 40px;
  column-rule: 1px solid var(--border-soft);
}
/* Keep each numbered sense intact across the column break where possible. */
.lex-card-def.lex-card-cols { orphans: 2; widows: 2; }

@media (max-width: 600px) {
  .strongs-lemma { font-size: 44px; }
  .strongs-audio-btn { width: 42px; height: 42px; }
  /* Stack hero columns on phones — vertical divider becomes a horizontal
     border-top under the word panel so the boundary stays visible. */
  .strongs-hero {
    padding: 18px 14px;
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .strongs-hero-def {
    border-left: none;
    border-top: 1px solid var(--border-soft);
    padding: 16px 0 0;
  }
  .strongs-stat-card { min-height: 84px; padding: 14px 10px; }
  .strongs-stat-value.big { font-size: 26px; }
  .strongs-hero-def-pages.is-paged { min-height: 0; }
  /* Lexicon cards: tighten padding + badge so the value column keeps room. */
  .lex-card { padding: 14px 14px; gap: 12px; }
  .lex-card-icon { width: 42px; height: 42px; }
  .lex-card-icon svg { width: 20px; height: 20px; }
  .lex-card-value { font-size: 16px; }
  .lex-card-prose { font-size: 15px; }
  /* Definition prose: keep a readable but not oversized scale on phones. */
  .lex-card-def { font-size: 16px; line-height: 1.7; }
  /* Force the definition back to one column on phones — two columns get too
     narrow to read on a small screen. */
  .lex-card-def.lex-card-cols { columns: auto; column-rule: none; }
  /* Download button spans full width when it wraps under the "read full
     entry" link on a phone. */
  .strongs-hero-def-share { margin-left: 0; flex: 1 0 100%; justify-content: center; }
  .strongs-verse-list { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  /* Pagination: indicator on its own row above the prev/next pair so both
     actions get full tap-target width on a phone. */
  .strongs-pagination { flex-wrap: wrap; gap: 10px; }
  .strongs-pagination .page-indicator { order: -1; width: 100%; text-align: center; }
  .strongs-pagination .page-link { flex: 1; text-align: center; }
  /* About tab: stats stack 2-up; cards + word-profile collapse to one column;
     bar columns tighten so the label + value still flank a usable bar. */
  .about-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  /* #77: in the narrow 2-column grid a five-card word wraps to 2 + 2 + 1; the
     lone fifth (frequency) card spans both columns so it reads as a full-width
     summary row rather than a stranded half-width card. */
  .about-stats > .about-stat:nth-child(5):last-child { grid-column: 1 / span 2; }
  .about-stat { padding: 16px 10px 14px; border-radius: 12px; }
  .about-stat-icon { width: 38px; height: 38px; }
  .about-stat-icon svg { width: 24px; height: 24px; }
  .about-stat-value { font-size: 21px; }
  .about-stat-ref .about-stat-value { font-size: 17px; }
  .about-stat-note { font-size: 12px; max-width: none; }
  .about-cols { gap: 22px; }
  .about-bar { grid-template-columns: 96px 1fr 78px; font-size: 12px; }
}

/* ============================================================================
   29. SSR CHAPTER + BOOK INDEX (/v/:slug/:ch and /v/:slug)
   ----------------------------------------------------------------------------
   Server-rendered chapter index (/v/:bookSlug/:chapter)
   and book index (/v/:bookSlug).
   ============================================================================ */

.chapter-head, .book-head {
  margin: 4px 0 18px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-soft);
}
/* Chapter head is centered (title + meta + the practice buttons below already
   center); the book index keeps its left-aligned head. */
.chapter-head { text-align: center; }
.chapter-title, .book-title {
  margin: 0 0 6px;
  font-size: 28px;
  color: var(--text);
}
.chapter-meta, .book-meta {
  margin: 0;
  font-size: 13px;
  color: var(--text-dim);
}

/* Chapter view: numbered list of verses with original text + gloss line. */
.chapter-verse-list {
  list-style: none;
  padding: 0;
  margin: 18px 0 28px;
  display: grid;
  gap: 14px;
}
.chapter-verse {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  transition: border-color 120ms;
}
.chapter-verse:hover,
.chapter-verse:focus-within {
  border-color: var(--accent-border);
}
/* The whole row is one link (not just the number) — the link carries the grid +
   padding, so a click anywhere on the verse card opens it word-by-word. */
.chapter-verse-link {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 12px;
  align-items: start;
  padding: 14px 14px;
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius);
}
.chapter-verse-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.cv-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}
.chapter-verse-link:hover .cv-num,
.chapter-verse-link:focus-visible .cv-num {
  background: var(--accent);
  color: var(--on-accent);
}
.cv-text { min-width: 0; }
.cv-original {
  margin: 0 0 4px;
  font-size: 17px;
  line-height: 1.65;
  color: var(--text);
}
.cv-original[lang="he"] { font-family: var(--hebrew-font); font-size: 22px; line-height: 1.5; }
.cv-original[lang="grc"] { font-family: var(--greek-font); }
.cv-gloss {
  margin: 0;
  font-size: 13px;
  color: var(--text-faint);
  line-height: 1.5;
}
/* R3 — per-verse length-divergence flag on the chapter index row. */
.cv-diverge {
  margin: 6px 0 0;
  display: inline-flex; align-items: center; gap: 6px;
  font: 600 11.5px/1.3 var(--ui-font); color: var(--accent);
}
.cv-diverge-badge {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 1px 6px; border-radius: 999px;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  font: 700 10px/1.4 var(--ui-font); letter-spacing: 0.04em; color: var(--accent);
}

.chapter-about p, .book-about p {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
  max-width: 70ch;
}
.chapter-about, .book-about { margin-top: 20px; }

/* Chapter "About" promoted to a full-width panel with a gold stats strip. */
.chapter-about {
  margin-top: 28px;
  padding: 22px 24px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.chapter-about h2 {
  margin: 0 0 16px;
  font-size: 18px;
}
.chapter-about p {
  margin: 0 auto;
  text-align: center;
}
.chapter-about a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.chapter-about a:hover, .chapter-about a:focus { text-decoration: underline; }

/* R3 — chapter-level "where MT and LXX diverge in length" summary. */
.chapter-about p.chapter-diverge {
  text-align: left; max-width: none;
  margin: 4px 0 0; padding: 14px 16px;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  font-size: 13.5px; line-height: 1.7; color: var(--text-dim);
}
.chapter-diverge strong { color: var(--text); }
.chapter-diverge-badge {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 1px 7px; margin-right: 4px; border-radius: 999px;
  background: var(--bg-card); border: 1px solid var(--accent-border);
  font: 700 10px/1.5 var(--ui-font); letter-spacing: 0.04em; color: var(--accent);
}
.chapter-diverge-link { white-space: nowrap; }
.chapter-about p.chapter-diverge-hedge {
  text-align: left; max-width: none;
  margin: 8px 0 0; font-size: 12px; color: var(--text-faint); line-height: 1.55;
}

.chapter-about-stats {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 12px;
}
.chapter-stat {
  padding: 14px 12px;
  text-align: center;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.chapter-stat-num {
  display: block;
  font-family: var(--reading-font);
  font-size: 28px;
  line-height: 1.1;
  font-weight: 700;
  color: var(--accent);
}
.chapter-stat-label {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* ============================================================================
   LXX structural-divergence note + interstitial
   ----------------------------------------------------------------------------
   Surfaced when an OT book's Greek text lives under a different lxx_words book
   number (Nehemiah → Esdras B). The full-page interstitial (.lxx-structure-note)
   replaces the empty LXX word grid; the compact asides (.book-lxx-note /
   .verse-lxx-note) cross-link the merged relationship from the MT pages. Every
   approxChapter link is CHAPTER-level only — the .lxx-structure-hedge /
   .verse-lxx-note-hedge copy makes clear it is not a verse-level alignment.
   ============================================================================ */
.lxx-structure-note {
  margin: 8px 0 0;
  padding: 22px 22px 20px;
  background: var(--bg-raised);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.lxx-structure-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.lxx-structure-badge,
.book-lxx-note-badge {
  flex: none;
  display: inline-block;
  padding: 3px 8px;
  font: 700 12px/1 var(--ui-font);
  letter-spacing: 0.06em;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 6px;
}
.lxx-structure-title {
  margin: 0;
  font-size: 19px;
  color: var(--text);
}
.lxx-structure-lede {
  margin: 0 0 16px;
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.7;
  max-width: 72ch;
}
.lxx-structure-route {
  padding: 14px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.lxx-structure-route-label {
  margin: 0 0 8px;
  color: var(--text-faint);
  font-size: 14px;
}
.lxx-structure-route-target {
  margin: 0 0 10px;
  font-size: 15px;
  color: var(--text-dim);
}
.lxx-structure-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.lxx-structure-link:hover,
.lxx-structure-link:focus { text-decoration: underline; outline: none; }
.lxx-structure-hedge {
  display: flex;
  gap: 8px;
  margin: 0;
  padding-top: 10px;
  border-top: 1px dashed var(--border-soft);
  color: var(--text-faint);
  font-size: 13px;
  line-height: 1.6;
}
.lxx-structure-hedge-icon {
  flex: none;
  width: 17px;
  height: 17px;
  margin-top: 1px;
  color: var(--accent);
}
.lxx-structure-back { margin: 16px 0 0; }
.lxx-structure-back-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text-dim);
  font-size: 14px;
  text-decoration: none;
}
.lxx-structure-back-link:hover,
.lxx-structure-back-link:focus { color: var(--accent); outline: none; }
.lxx-structure-back-icon { width: 16px; height: 16px; flex: none; }
.lxx-structure-learn { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--border-soft); }
.lxx-structure-learn-link { color: var(--accent); text-decoration: none; font: 600 13.5px/1.5 var(--ui-font); }
.lxx-structure-learn-link:hover { text-decoration: underline; }

/* Compact cross-link asides on the MT (and Ezra-LXX) book + verse pages. */
.book-lxx-note {
  display: flex;
  gap: 12px;
  margin: 0 0 20px;
  padding: 14px 16px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.book-lxx-note-body { min-width: 0; }
.book-lxx-note-text {
  margin: 0;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.65;
  max-width: 72ch;
}
.book-lxx-note-link-row {
  margin: 8px 0 0;
  font-size: 14px;
  color: var(--text-dim);
}
.book-lxx-note-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
.book-lxx-note-link:hover,
.book-lxx-note-link:focus { text-decoration: underline; outline: none; }
.book-lxx-note-hedge {
  margin: 6px 0 0;
  color: var(--text-faint);
  font-size: 12.5px;
  line-height: 1.55;
}
.verse-lxx-note {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin: 0 0 16px;
  padding: 12px 14px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.verse-lxx-note-text {
  margin: 0;
  color: var(--text-dim);
  font-size: 13.5px;
  line-height: 1.6;
}
.verse-lxx-note-hedge {
  color: var(--text-faint);
  font-size: 12.5px;
}

/* ----------------------------------------------------------------------------
   LXX Psalm dual-numbering banner
   ----------------------------------------------------------------------------
   Persistent strip on every Psalm page in LXX mode (SSR verse/chapter/book +
   the SPA range view). NETS-style "Greek Psalm 22 (Hebrew Psalm 23)" identity +
   merge/split disclosure. Built by services/lemma/psalm-banner.js. The banner
   discloses THAT verse numbers can differ, NEVER by how much (no-fabrication
   contract). Reuses the accent palette of the merged-book asides so it reads as
   the same family of disclosure.
   ---------------------------------------------------------------------------- */
.lxx-psalm-banner {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin: 0 0 16px;
  padding: 14px 16px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.lxx-psalm-banner-badge {
  flex: none;
  display: inline-block;
  padding: 3px 8px;
  font: 700 12px/1 var(--ui-font);
  letter-spacing: 0.06em;
  color: var(--accent);
  background: var(--bg-card);
  border: 1px solid var(--accent-border);
  border-radius: 6px;
}
.lxx-psalm-banner-body { min-width: 0; }
.lxx-psalm-banner-lede {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-dim);
  max-width: 74ch;
}
.lxx-psalm-banner-heading {
  display: inline-block;
  margin-right: 8px;
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}
.lxx-psalm-banner-text { color: var(--text-dim); }
.lxx-psalm-banner-note {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
  max-width: 74ch;
}
.lxx-psalm-banner-note--hedge {
  color: var(--text-faint);
  font-size: 12.5px;
}
.lxx-psalm-banner-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.lxx-psalm-banner-link:hover,
.lxx-psalm-banner-link:focus { text-decoration: underline; outline: none; }

/* Book view: opening-verse hero + chapter chip grid. */
.book-opening {
  margin: 0 0 24px;
  padding: 18px 18px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.book-opening h2 {
  margin: 0 0 10px;
  font-size: 14px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.book-opening .cv-original { margin-bottom: 6px; }
.book-opening-link {
  display: inline-block;
  margin-top: 10px;
  color: var(--accent);
  text-decoration: none;
  font-size: 14px;
}
.book-opening-link:hover, .book-opening-link:focus { text-decoration: underline; outline: none; }

.book-chapters h2,
.book-vocab h2 {
  margin: 0 0 12px;
  font-size: 14px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Book index — most-frequent content lemmas (AdSense remediation L10). Reuses
   the /lexicon listing's .vocab-* card wholesale; the only book-local rule is
   the multi-column track, because twelve full-width rows would push the "About
   this book" panel off a phone screen entirely. */
.book-vocab { margin: 0 0 28px; }
.book-vocab-list {
  /* min() on the track floor, not a bare 250px: auto-fit still forces the
     minimum when the container is narrower than it, which is the grid blowout
     that cost a phone-width overflow once already. */
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
  margin-bottom: 0;
}
.book-chapter-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 28px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
  gap: 8px;
}
.book-chapter-grid li { margin: 0; }
.book-chapter-grid a {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  font-size: 15px;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.book-chapter-grid a:hover, .book-chapter-grid a:focus {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}

@media (max-width: 600px) {
  .chapter-verse { grid-template-columns: 36px 1fr; padding: 12px; }
  .cv-num { width: 30px; height: 30px; font-size: 13px; }
  .cv-original[lang="he"] { font-size: 20px; }
  .book-chapter-grid { grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)); }
  .book-chapter-grid a { height: 44px; font-size: 14px; }
}

/* ============================================================================
   30. FOOTER — brand strip + grouped nav + legal/attribution bar
   Replaces the retired .footer-built / .footer-links single-row footer.
   Blowout-safe (minmax(0,1fr) + min-width:0 + overflow-wrap), focus-visible,
   44px touch targets, breakpoint aligned to the header (760px).
   ============================================================================ */
/* Gutters match .app's (§7), so the band's contents line up with the page
   content above it, same as .site-header-inner. */
.footer-inner {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 calc(20px + env(safe-area-inset-right)) 0 calc(20px + env(safe-area-inset-left));
}

/* --- Brand strip --- */
.footer-brand { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; flex-wrap: wrap; }
.footer-brand-main { max-width: 62ch; min-width: 0; }
.footer-wordmark { display: inline-flex; align-items: center; gap: 8px; font-family: var(--ui-font); font-weight: 700; font-size: 20px; letter-spacing: 0.5px; color: var(--text); text-decoration: none; }
.footer-wordmark:hover { color: var(--accent); }
.footer-wordmark-img { display: block; width: 28px; height: 28px; border-radius: 6px; }
.footer-blurb { color: var(--text-dim); font-size: 14px; line-height: 1.6; margin: 8px 0 0; }
.footer-teaser { color: var(--text-faint); font-size: 12.5px; line-height: 1.5; margin: 8px 0 0; }
.footer-support { flex-shrink: 0; text-align: right; }
.footer-cta { display: inline-block; font-family: var(--ui-font); font-weight: 600; font-size: 14px; color: var(--on-accent); background: var(--accent); border: 1px solid var(--accent-border); border-radius: 8px; padding: 11px 18px; text-decoration: none; transition: background 120ms, box-shadow 120ms; }
.footer-cta:hover { box-shadow: 0 0 0 3px var(--accent-soft); }
.footer-fund { color: var(--text-faint); font-size: 12px; margin: 8px 0 0; }

/* --- Nav grid: explicit column counts with minmax(0,1fr) (see #199 lesson).
       align-items:start keeps the short Septuagint column from stretching. --- */
.footer-nav { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px 32px; align-items: start; margin: 28px 0; }
.footer-col { min-width: 0; }
.footer-col-title { font-family: var(--ui-font); font-weight: 700; font-size: 13px; letter-spacing: 0.4px; text-transform: uppercase; color: var(--accent); margin: 0 0 6px; }
.footer-col-desc { color: var(--text-faint); font-size: 12px; line-height: 1.5; margin: 0 0 12px; }
.footer-col-links { list-style: none; margin: 0; padding: 0; }
.footer-col-links li { margin: 0 0 8px; }
.footer-col-links a { color: var(--text-dim); font-size: 13.5px; text-decoration: none; }
.footer-col-links a:hover { color: var(--accent); }

/* --- Legal / attribution bar --- */
.footer-legal { border-top: 1px solid var(--border-soft); padding-top: 16px; margin-top: 8px; overflow-wrap: anywhere; text-align: center; }
.footer-attrib, .footer-meta { color: var(--text-faint); font-size: 12px; line-height: 1.6; margin: 0; }
.footer-attrib { margin-bottom: 8px; }
.footer-legal a { color: var(--text-dim); text-decoration: none; }
.footer-legal a:hover { color: var(--accent); text-decoration: underline; }
.footer-legal strong { color: var(--accent); font-weight: 600; }

/* --- Focus-visible: restores the outline removed with the old footer (P0 #1). --- */
.site-footer a:focus-visible, .footer-cta:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

/* --- Mobile: aligned to the header's 760px compaction. 4→2 cols, brand stacks,
       nav links become 44px block targets. Legal-bar links stay inline prose. --- */
@media (max-width: 760px) {
  .footer-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px 24px; }
  .footer-brand { flex-direction: column; align-items: stretch; gap: 16px; }
  .footer-support { text-align: left; }
  .footer-col-links a { display: flex; align-items: center; min-height: 44px; }
  /* Match .app's mobile gutter (§26) so the band's contents stay aligned with
     the page content above it at narrow widths, same as .site-header-inner. */
  .footer-inner {
    padding-left: calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
}

/* --- Narrow phones (incl. 320px): single stacked column. --- */
@media (max-width: 480px) { .footer-nav { grid-template-columns: minmax(0, 1fr); } }

/* ============================================================================
   31. ABOUT / FAQ / SUPPORT CONTENT PAGES
   ----------------------------------------------------------------------------
   About / FAQ / Support content pages.
   .about and .faq selectors already exist above (from when these lived on
   home.ejs); the body-prose typography there carries over unchanged.
   .feature-list — bulleted feature list on /about.
   ============================================================================ */
/* "What you can do" feature grid (/about#features). Icon cards, ALL OPEN — no
   accordion: this is a marketing + SEO surface whose whole job is to let a
   newcomer (and a crawler) scan every capability at once, so nothing is hidden
   behind a collapse toggle. The section header is a plain <h3> + intro <p>, to
   match the "Sources & licenses" header below it. */
.feature-cards {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  display: grid;
  gap: 10px;
}
.feature-card {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.feature-card-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 11px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
}
.feature-card-ico svg { width: 23px; height: 23px; }
.feature-card-text { min-width: 0; }
.feature-card-title {
  display: block;
  color: var(--text);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.4;
  margin-bottom: 3px;
}
.feature-card-desc {
  display: block;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.6;
}
/* Two columns on wider screens so the reader sees more capabilities per fold
   instead of an 11-row vertical scroll (mobile stays single-column, matching
   the source mockup). */
@media (min-width: 640px) {
  .feature-cards { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .feature-card { gap: 12px; padding: 12px 13px; }
  .feature-card-ico { width: 40px; height: 40px; }
}

/* /tools hub — surfaces the three corpus-search power-tools (Search, Grammar,
   Concordance) as full-card links. Reuses the .feature-card visual language
   (raised card + soft-gold icon medallion + tokenized text), but the whole card
   is the anchor so the page works with no JS. Tokens only — no new design vars. */
/* /septuagint-differences — the MT↔LXX structural-divergence hub (R4). */
.lxx-diff { max-width: 76ch; margin: 0 auto; }
.lxx-diff h1 { font-size: 30px; margin: 0 0 12px; line-height: 1.2; }
.lxx-diff-lede { color: var(--text-dim); font-size: 16px; line-height: 1.7; margin: 0 0 8px; }
.lxx-diff-lede strong { color: var(--text); }
.lxx-diff-block { margin-top: 34px; }
.lxx-diff-block h2 { font-size: 21px; margin: 0 0 12px; }
.lxx-diff-note { color: var(--text-dim); font-size: 14.5px; line-height: 1.7; margin: 0 0 14px; }
.lxx-diff-hedge { color: var(--text-faint); font-size: 12.5px; line-height: 1.6; margin: 10px 0 0; }
.lxx-diff-table {
  width: 100%; border-collapse: collapse; margin: 6px 0 4px;
  font: 500 14px/1.5 var(--ui-font);
}
.lxx-diff-table caption {
  text-align: left; color: var(--text-faint);
  font: 600 11px/1 var(--ui-font); text-transform: uppercase; letter-spacing: 0.06em;
  padding-bottom: 8px;
}
.lxx-diff-table th, .lxx-diff-table td {
  text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}
.lxx-diff-table thead th {
  color: var(--text-faint); font: 600 12px/1.2 var(--ui-font);
  text-transform: uppercase; letter-spacing: 0.04em; border-bottom-color: var(--border);
}
.lxx-diff-table tbody th { color: var(--text); font-weight: 600; white-space: nowrap; }
.lxx-diff-table tbody td { color: var(--text-dim); }
.lxx-diff-tag {
  display: inline-block; margin-left: 4px; padding: 1px 7px; border-radius: 999px;
  background: var(--accent-soft); border: 1px solid var(--accent-border);
  font: 600 10.5px/1.5 var(--ui-font); color: var(--accent);
}
.lxx-diff-examples { list-style: none; padding: 0; margin: 16px 0 0; display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.lxx-diff-example {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-radius: 10px;
  background: var(--bg-raised); border: 1px solid var(--border-soft);
  color: var(--text); text-decoration: none;
}
.lxx-diff-example:hover { border-color: var(--accent-border); background: var(--bg-card); }
.lxx-diff-example-pair { font: 500 13.5px/1.4 var(--ui-font); }
.lxx-diff-example-pair strong { color: var(--accent); }
.lxx-diff-example-go { font: 600 12px/1 var(--ui-font); color: var(--accent); white-space: nowrap; flex: none; }
.lxx-diff-card {
  padding: 16px 18px; margin: 0 0 12px;
  background: var(--bg-raised); border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent); border-radius: 10px;
}
.lxx-diff-card-title { font-size: 16px; margin: 0 0 8px; }
.lxx-diff-card .lxx-diff-note { margin: 0 0 10px; }
.lxx-diff-card-links { margin: 0; font: 600 13px/1.5 var(--ui-font); }
.lxx-diff-card-links a { color: var(--accent); text-decoration: none; }
.lxx-diff-card-links a:hover { text-decoration: underline; }
.lxx-diff-foot {
  margin: 34px 0 0; padding-top: 16px; border-top: 1px solid var(--border-soft);
  color: var(--text-dim); font-size: 14px; line-height: 1.7;
}
.lxx-diff-foot a { color: var(--accent); text-decoration: none; font-weight: 600; }
.lxx-diff-foot a:hover { text-decoration: underline; }

.tools-page {
  max-width: 70ch;
  margin: 0 auto;
}
.tools-page h1 {
  font-size: 30px;
  margin: 0 0 12px;
}
.tools-lede {
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1.7;
  margin: 0 0 22px;
}
.tools-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.tools-card {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 16px;
  height: 100%;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  text-decoration: none;
  color: inherit;
}
.tools-card:hover,
.tools-card:focus-visible {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.tools-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tools-card-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 11px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
}
.tools-card-ico svg { width: 23px; height: 23px; }
.tools-card-text { min-width: 0; }
.tools-card-title {
  display: block;
  color: var(--text);
  font-family: var(--ui-font);
  font-weight: 600;
  font-size: 16px;
  line-height: 1.4;
  margin-bottom: 4px;
}
.tools-card-desc {
  display: block;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.6;
}
.tools-card-eg {
  display: block;
  color: var(--text-faint);
  font-family: var(--ui-font);
  font-size: 12.5px;
  margin-top: 8px;
}
.tools-card-eg em { font-style: italic; }

/* ---- Homepage "Explore Lemma" showcase (below search + results) ---- */
.home-explore {
  padding-top: 26px;
  margin-top: 6px;
  border-top: 1px solid var(--border-soft);
}
.home-explore-heading {
  font-family: var(--ui-font);
  font-size: 22px;
  line-height: 1.3;
  margin: 0 0 6px;
}
.home-explore-lede {
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.6;
  margin: 0 0 18px;
}

/* Featured hero — reuses .tools-card structure; full-width, larger, accent-tinted. */
.home-hero {
  gap: 18px;
  padding: 22px 24px;
  margin: 0 0 8px;
  background: var(--accent-soft);
  border-color: var(--accent-border);
  /* .tools-card sets height:100% so grid TILES equalize inside .tools-grid. The
     hero is a STANDALONE card (not a grid child), so that 100% resolves against
     .home-explore's grid-stretched height and balloons the card. Force content
     height. */
  height: auto;
}
.home-hero .tools-card-ico { width: 52px; height: 52px; }
.home-hero .tools-card-ico svg { width: 27px; height: 27px; }
.home-hero .tools-card-title { font-size: 19px; }
.home-hero .tools-card-desc { font-size: 15px; line-height: 1.65; }
.home-hero .tools-card-eg { color: var(--accent); font-weight: 600; font-size: 13.5px; }
.home-hero-hint {
  color: var(--text-dim);
  font-family: var(--ui-font);
  font-size: 13.5px;
  margin: 0 0 22px;
}
.home-hero-hint a {
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px; font-weight: 600;
}
.home-hero-hint a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.home-explore-group { margin: 0 0 24px; }
.home-explore-group:last-of-type { margin-bottom: 18px; } /* holds whether group C or B is last (LXX-gated) */
.home-explore-subhead {
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 4px;
}
.home-explore-groupdesc {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 12px;
}

/* Uniform tile widths across groups. The shared .tools-grid uses
   auto-FIT + minmax(240px,1fr), which collapses empty tracks and BALLOONS a
   2-card group (Search across the Bible; The Septuagint) into half-width tiles
   next to the third-width tiles of the 3-card group. Override, homepage-scoped:
     - >=760px: explicit 3 equal columns -> a 2-card group keeps third-width tiles
       plus one empty slot (uniform, no ballooning).
     - <760px: auto-FILL (not auto-fit) minmax(240px,1fr) -> tiles keep their
       natural width down to 1-up; no ballooning; mobile-safe (240 < a 320px
       viewport's content width). */
.home-explore .tools-grid {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
@media (min-width: 760px) {
  .home-explore .tools-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.home-explore-all { margin: 4px 0 0; font-family: var(--ui-font); font-size: 14px; }
.home-explore-all a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Sources & licenses (/about#sources). A category-grouped set of provenance
   cards — NOT a numbered sequence: the sources are independent, so the layout
   groups them by category (texts, lexicons, translations, …) and never implies
   an ordering or derivation between them. Each card carries a title + license
   chip, a descriptive body, and a structured Source / License / Provenance
   key-value footer so the provenance of every datum is verifiable at a glance. */
.sources-list {
  list-style: none;
  padding: 0;
  margin: 8px 0 16px;
  display: grid;
  gap: 12px;
}
/* Category labels sit inside the same grid as the cards but read as section
   headings, not cards — they replace the "Option 3" numbered spine, which
   would have implied a false ranking/pipeline between independent sources. */
.source-group-head {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 16px 0 0;
  padding: 0 2px 6px;
  border-bottom: 1px solid var(--border-soft);
  color: var(--accent);
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.sources-list > .source-group-head:first-child { margin-top: 0; }
.source-group-icon { flex: none; color: var(--accent); }
.sources-list > li:not(.source-group-head) {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.source-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 6px;
  color: var(--text);
  font-size: 15px;
  line-height: 1.4;
}
.source-title strong { color: var(--text); font-weight: 600; }
.source-body {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
  margin: 0 0 10px;
}
.source-body strong { color: var(--text); font-weight: 600; }
.source-body em { color: var(--text); font-style: italic; }
.source-body a,
.source-prov a {
  color: var(--accent);
  text-decoration: none;
}
.source-body a:hover, .source-body a:focus,
.source-prov a:hover, .source-prov a:focus { text-decoration: underline; outline: none; }

/* Structured provenance footer — a labeled key/value list so Source, License,
   and the public-domain / attribution rationale are each scannable rather than
   buried in a run-on sentence. */
.source-prov {
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--border-soft);
  display: grid;
  gap: 7px;
  font-size: 12.5px;
  line-height: 1.6;
}
.prov-row {
  display: grid;
  grid-template-columns: 96px 1fr;
  gap: 4px 12px;
  align-items: baseline;
}
.prov-row dt {
  color: var(--text-faint);
  font-family: var(--ui-font);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding-top: 2px;
}
.prov-row dd { margin: 0; color: var(--text-dim); }
.source-prov code {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 11px;
  color: var(--text-dim);
}
/* Obligation marker — spells out, in text, exactly what reuse the license
   requires, so the requirement never rides on badge colour alone (WCAG 1.4.1). */
.license-oblig {
  display: inline-block;
  margin-left: 2px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  color: var(--text-faint);
  font-family: var(--ui-font);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
/* ShareAlike is the most demanding tier — keep its descriptor visible with a
   copyleft glyph and accent tint so it can't be mistaken for a no-conditions
   public-domain note. */
.license-oblig-sa {
  background: var(--accent-soft);
  border-color: var(--accent-border);
  color: var(--accent);
}
.license-oblig-sa::before { content: '\21BB\00A0'; font-weight: 700; }

.license-tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent-border);
}
.license-tag.license-pd {
  background: var(--bg-card);
  color: var(--text-dim);
  border-color: var(--border-soft);
}
/* CC BY-SA: a solid accent fill makes it visually heavier than the outlined
   attribution pill and the muted public-domain pill, so the three obligation
   tiers stay distinguishable by weight, not colour alone. */
.license-tag.license-tag-sa {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
/* In-title ShareAlike flag — a second, always-visible text cue beside the
   badge so the ShareAlike obligation reads even at a glance. */
.license-oblig-chip {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
  font-family: var(--ui-font);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.license-oblig-chip::before { content: '\21BB\00A0'; }
.sources-note {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
  margin-top: 8px;
  padding: 12px 14px;
  background: var(--bg-card);
  border-left: 3px solid var(--accent-border);
  border-radius: 4px;
}
.sources-note strong { color: var(--text); font-weight: 600; }

/* On narrow phones, stack each provenance label above its value so long
   license/provenance text isn't squeezed into a sliver beside the label. */
@media (max-width: 480px) {
  .prov-row {
    grid-template-columns: 1fr;
    gap: 1px;
  }
  .prov-row dt { padding-top: 4px; }
}

/* Generic CTA — used on /about and /support to point back to the tool. Also
   used on a <button> (the /support no-JS logout), hence inline-flex + cursor.
   min-height 44px meets the WCAG 2.5.5 target-size floor. */
.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 18px;
  border-radius: var(--radius);
  color: var(--accent);
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.cta:hover, .cta:focus {
  background: var(--accent);
  color: var(--on-accent);
}
/* Keep a visible ring for keyboard users (replaces the old outline:none, which
   suppressed the focus indicator for everyone — an a11y regression). */
.cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.cta-primary {
  background: linear-gradient(135deg, #d4a839 0%, #b8852a 100%);
  color: var(--on-accent);
  border: none;
  font-size: 15px;
  padding: 12px 22px;
}
.cta-primary:hover, .cta-primary:focus {
  box-shadow: 0 6px 18px rgba(200, 161, 59, 0.3);
  background: linear-gradient(135deg, #e6b54a 0%, #d4a839 100%);
  color: var(--on-accent);
}

/* ============================================================================
   32. SUPPORT PAGE (/support)
   ----------------------------------------------------------------------------
   Support page (/support) — tier cards + ways-to-help list.
   ============================================================================ */
/* The reading measure lives on the CHILDREN, not on this container, so ONE
   section — the tier comparison — can opt out to a wider measure without negative
   margins or a transform (both of which would have to fight the page's
   safe-area padding at 390px). Every other direct child still lands at the
   measure and stays centered, so this page's prose sections and
   views/upgrade.ejs (which shares .support-page) render as they did before.

   32.85rem, NOT 70ch — and the difference is the whole reason this is a custom
   property. `ch` resolves against the ELEMENT's own font-size, which was
   harmless while the cap sat on the container (one element, one font-size) but
   is not once it sits on every child: .support-page p is 15px (specificity
   (0,1,1)), so a direct-child <p> — views/upgrade.ejs's .support-tier-login — was
   resolving its own "70ch" as 492.7px against the sections' 525.5px, and
   margin-inline:auto then centered it 16.4px in from their left edge.

   The value is MEASURED, not guessed: 70ch for this page's inherited font
   (Gentium, 16px) is 525.55px — 1ch is 7.508px, so 70ch is 32.85rem, nowhere
   near the 35rem an 0.5em-per-ch assumption would give. Being in rem it is now
   also immune to a Gentium load failure shifting every prose column. */
.support-page {
  --support-measure: 32.85rem; /* = the pre-change 70ch, 525.55px */
  /* GRID-ITEM half of the blowout guard — margin is `0`, NOT the `0 auto` it
     was, and that is the whole of the fix.

     .content is a grid whose track is already capped at `minmax(0, 1fr)`
     (#199), but capping the TRACK does not constrain the ITEM. Auto INLINE
     MARGINS on a grid item suppress the default `stretch`, which makes the box
     shrink-to-fit — and shrink-to-fit is floored at MIN-CONTENT. So this box
     sized itself to its widest descendant's min-content and overflowed the
     capped track: the comparison table's `min-width: 820px` measured
     .support-page at 856px inside a 366px track at 390px wide. Because html and
     body are `overflow-x: clip`, that did not produce a scrollbar — it SILENTLY
     CLIPPED, leaving two of the four tier columns unreachable on a phone.
     (`min-width: 0` alone does NOT fix this; it was measured and it does not.
     The auto margin is the mechanism.)

     Nothing rendered moves: this box has no max-width of its own, so the auto
     margins had nothing to center — the reading measure and the centering both
     live on `.support-page > *` below. Stretched, it simply follows the track,
     and the 820px table overflows inside .pricing-table-wrap's own scroller,
     which is where it is meant to. min-width: 0 stays as the companion guard so
     a future descendant cannot re-inflate the item through automatic minimum
     size. */
  margin: 0;
  min-width: 0;
}
.support-page > * {
  max-width: var(--support-measure);
  margin-inline: auto;
}
/* Shared by /support, the upgrade wall and the beta-access page. The hero
   headline on each is that page's <h1> as of 2026-08-21; the h2 selector stays
   for the section headings below it, which are still h2s. */
.support-page h1,
.support-page h2 {
  font-size: 30px;
  margin: 0 0 12px;
}
.support-page h3 {
  font-size: 18px;
  margin: 28px 0 10px;
  color: var(--text);
}
.support-page p {
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.7;
}
.support-lede {
  font-size: 16px;
  color: var(--text);
  margin: 0 0 24px;
}

/* ---- Support-page prose links: white by default, gold on hover +
   :focus-visible (the .about a / .faq a idiom; focus mirrors hover so keyboard
   users get the same affordance). Scoped :not(.cta) so the Patreon / tool action
   BUTTONS keep their button styling. Underline-on-hover keeps the affordance
   from being color-only. ---- */
.support-page a:not(.cta) {
  color: var(--text);
  text-decoration: none;
}
.support-page a:not(.cta):hover,
.support-page a:not(.cta):focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

/* ---- Content panels. Each flat <h2>-led group is wrapped in a .support-section
   so the page reads as a sequence of cards — the .verse-section panel idiom
   (raised bg, soft border, shared radius). Consecutive sections share a fixed
   gap; the first/last child margins fold into the padding for even insets.
   Nested cards (.support-ledger-item / .support-tier) step up one elevation to
   --bg-card so they don't merge with this raised background — the layering reads
   page(--bg) → section(--bg-raised) → inner card(--bg-card). ---- */
.support-section {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 22px;
}
.support-section + .support-section { margin-top: 18px; }
.support-section > :first-child { margin-top: 0; }
.support-section > :last-child { margin-bottom: 0; }
.support-section .support-ledger-item {
  background: var(--bg-card);
}
/* Every panel title goes gold — the .footer-col-title idiom (color only, same
   size/weight as the page's other h2s from .support-page h2 above). Scoped to
   .support-section so the page's actual headlines — .support-hero h2 ("Keep
   Lemma free...") and .support-thanks-hero h2 (the patron thank-you) — are
   untouched: neither is a .support-section, both are hero copy, not a panel
   title. Applies uniformly to every .support-section on this page AND on
   views/upgrade.ejs, which shares the class. */
.support-page .support-section h2 { color: var(--accent); }

/* ---- Row wrappers: group adjacent .support-section panels into a horizontal
   band instead of the page's default vertical stack (the two bands framing
   the tier comparison — prose+ledger above it, the three closing panels
   below). A <div>, not a <section>: it carries no heading of its own, and
   needs its own opt-out of the reading measure — otherwise a multi-column
   band inherits the page's 32.85rem cap like any other direct child of
   .support-page and cannot be wider than one panel already was. Reuses the
   SAME mechanism as .support-section-wide below (a local --support-measure
   override), not a second one.

   Equal height: grid's default align-items: stretch already makes every
   .support-section in the row match the tallest track, so a short panel
   (e.g. "Contact") doesn't leave a ragged edge beside a taller neighbour —
   .support-section has no height of its own, it simply fills the cell.

   Sibling margin: .support-section + .support-section above adds 18px
   between STACKED panels; inside a row the panels are still adjacent
   siblings, so without this override every panel but the first in a row
   would carry that stray top margin ON TOP of the grid gap. Zeroed here —
   the grid `gap` owns all spacing between panels in a row. The row wrapper
   itself is a <div>, so `.support-section + .support-section` does not match
   ACROSS it, and `.support-page > *` carries no vertical margin at all (only
   max-width + margin-inline) — so without an explicit rule the bands sat
   flush against each other and against #choose-your-level, with zero gap.
   `margin-block: 10px` below is that rule: .support-row is itself a normal
   block box in .support-page's normal flow (only its OWN children are grid
   items), so its margin collapses with its block siblings the usual way —
   netting a real ~10px gap on both sides of a row (the hero's own 26px
   bottom margin still wins collapsing into support-row-2, which is correct
   and expected). */
.support-row {
  --support-measure: 1080px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
  margin-block: 10px;
}
.support-row > .support-section { margin-top: 0; }

/* Mobile-first single column (390px/280px never scroll sideways); 2-up from
   620px, matching .pricing-grid's own first step just above. The 3-panel row
   goes 2-then-3 rather than straight to 3, so mid-width phones/small tablets
   don't squeeze three panels' worth of prose into narrow columns; 1080px is
   .pricing-grid's own second step, reused rather than inventing a third
   breakpoint for this block. */
@media (min-width: 620px) {
  .support-row-2,
  .support-row-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1080px) {
  .support-row-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- /support redesign (4-tier): hero + ledger + thank-you + logout ---- */
/* margin-inline: auto (not 0) — the reading measure now caps the CHILDREN of
   .support-page, so a hero with zeroed inline margins would sit left-aligned in
   the full-width column instead of centered under the sections. */
.support-hero {
  margin: 0 auto 26px;
}
/* .support-hero is also views/upgrade.ejs's hero, which wraps in the plain
   .app column (1100px) rather than .app--wide (1280px) — see the top of this
   file and of that template. Scoping the wider measure to .app--wide (only
   support.ejs's wrapper) rather than to .support-hero directly means only
   /support's hero picks it up; upgrade.ejs's hero keeps the page's narrower
   32.85rem prose measure, untouched. Same mechanism as .support-section-wide
   below (a local --support-measure override), not a second one — the hero
   now spans the full 1080px band, matching the other three bands on this
   page instead of sitting in a ~525px column alone. */
.app--wide .support-hero { --support-measure: 1080px; }
.support-hero-eyebrow {
  font-family: var(--ui-font);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 8px;
}
.support-hero .support-lede {
  margin: 0 0 18px;
}
.support-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 8px;
}
.support-cta-note {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-faint);
  margin: 0;
}

/* ---- Beta-gate exit band — views/beta-gate.ejs ONLY -------------------------
   The two ways off a gated deploy (pledge, or leave for the free public site),
   stacked above the hero so they are read before the prose explaining them.

   THE ONLY RULES IN §32 NO OTHER VIEW USES. /support and views/upgrade.ejs share
   every other .support-* class in this section, which is why that page's template
   header could claim for a year that it added no CSS; these two names are the
   exception, and they are scoped so the claim stays true in the other direction —
   nothing here can move either of those pages.

   A GRID, and that is the layout decision rather than a default. `.cta` is
   `display: inline-flex`, which BLOCKIFIES to `flex` on a grid item, so each link
   fills the band with no display override and no `width: 100%` fighting the
   button's own padding — and the single `minmax(0, 1fr)` track means a long label
   wraps INSIDE the button instead of widening the band at 390px, where the primary
   label is comfortably wider than the column.

   `text-align: center` is not redundant with `.cta`'s own `justify-content:
   center`. That centers the anonymous flex item; the LINES inside it still follow
   text-align, so the moment the label wrapped it went ragged-left inside a
   perfectly centered box.

   Scoped under .support-page for this section's usual two reasons — it beats the
   page-wide element rules (`.support-page p` is (0,1,1) and would otherwise win
   over a bare `.beta-exits-or`), and it keeps the band from leaking if either name
   is reused. The `margin` shorthand RE-STATES `margin-inline: auto`, which
   `.support-page > *` supplies at (0,1,0): without it the shorthand resets the
   inline margins to 0 and the band sits left of the hero it introduces. */
.support-page .beta-exits {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  margin: 0 auto 22px;
  padding: 16px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.support-page .beta-exits .cta { text-align: center; }
/* The separator: the word is REAL TEXT, read out in order between the two links,
   because it is what tells a screen-reader user these are alternatives rather than
   a sequence. The hairlines either side are decoration and are drawn with
   pseudo-elements, so nothing empty sits in the DOM to be announced. */
.support-page .beta-exits-or {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-family: var(--ui-font);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}
.support-page .beta-exits-or::before,
.support-page .beta-exits-or::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--border-soft);
}

/* ---- Beta-gate page composition — views/beta-gate.ejs ONLY ------------------
   The second family in §32 that no other view uses, and the reason every rule
   below carries `.support-page.beta-gate-page` rather than a bare class:
   .support-page, .support-hero, .support-hero-eyebrow, .support-hero-actions,
   .support-section, .support-lede and the whole .pricing-* set are SHARED with
   views/support.ejs and views/upgrade.ejs. The compound selector matches only
   where the gate page puts its own hook on the section, so nothing here can move
   either of those two pages — and at (0,3,n) it also sits above the page's
   existing `.support-page .thing` rules at (0,2,0), so this block does not
   depend on being later in the file than any of them.

   WHAT WAS WRONG. The page was a 526px centered column whose entire top half —
   eyebrow, heading, lede, the mandatory free-tier paragraph, and the five
   per-reader state branches — was one undifferentiated run of start-aligned
   prose with no mark, no head and no card, sitting between two panels. Worse,
   measured at 1280px before this pass: the "Lemma itself is free" paragraph
   ended at y=566 and the state branches' action row began at y=566. ZERO
   separation — nothing distinguished the page's ARGUMENT from the reader's own
   ANSWER, which is the one thing they came for.

   THE TREATMENT is the sibling app's (H:\workspace_web\geBibleApp
   docs/SPEC-beta-gate-layout.md — on that repo's `bug/beta-gate-and-ad-placement`
   branch, NOT main), translated onto this page's vocabulary rather than copied:
   none of that spec's tokens exist here, and this app has a real third surface
   token, so the color-mix it needs to fake a mid elevation is not required and is
   not used.

   THREE ELEVATIONS, all from existing tokens:
     page      --bg
     panels    --bg-raised + --border-soft   (the exit band, #beta-levels via
               .support-section-wide, and "What stays free")
     top card  --bg-card + --border          (the state block, below)
   The state block takes the STRONGER border deliberately: --bg-card is also what
   .pricing-card sits on, and the heavier edge is what keeps the page's one
   answer-to-the-reader from reading as a third price card.

   CENTERED HEAD, START-ALIGNED BODY. Only the eyebrow and the title row centre.
   No prose rule sets text-align at all: a centered BLOCK reads as design, and
   centered SENTENCES of four or five lines read as a poster. The controls inside
   the state card stay at the start of the text column for the same reason — a
   centered button under a ragged-right paragraph floats free of the sentence it
   belongs to.

   NOT PANELLED, and deliberately: the header stack and the hero prose. A hero in
   a box is a page inside a page. "What stays free" is left EXACTLY as it was —
   it is already a .support-section at the mid elevation, so it already carries
   the panel treatment this pass hands out, and it is the page's mandatory
   free-tier counterweight rather than a sign-off line. Lightening it to a
   hairline rule would have cost it the gold h2 that rule set gives it and would
   have quietened the one section the template's header block says the page must
   not get wrong.

   NO MEDIA QUERY, and none is needed. Everything below is either a flex row that
   centres at any width or a card that fills the column it is already in; the
   column itself is fluid and capped by --support-measure, which this block never
   touches. Verified by measurement at 1280px and 390px. */

/* The eyebrow is a 12.5px uppercase LABEL, not prose, and it is a single text
   node — so text-align is the right tool and flex would buy nothing. (The
   sibling app centres its own eyebrow with justify-content only because that one
   holds two children and needs the gap.) It also keeps the label centred if it
   ever wraps, which a single anonymous flex item would not. */
.support-page.beta-gate-page .support-hero-eyebrow { text-align: center; }

/* THE HEADING'S BLOCK-END MARGIN MOVES TO THE ROW, and that is the one
   correction to the idiom rather than a copy of it: `align-items: center` centres
   flex items on their MARGIN boxes, so the 12px bottom margin `.support-page h2`
   gives every heading on this page would push the glyph 6px ABOVE the cap-height
   it is meant to sit beside. The row takes the 12px, the heading takes none, and
   the page's vertical rhythm is unchanged. */
.support-page.beta-gate-page .beta-gate-title-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin: 0 0 12px;
}
/* Lets the heading wrap inside the row at narrow widths instead of forcing the
   row wider than the column — a grid/flex item's automatic minimum size refuses
   to shrink below its content otherwise. */
.support-page.beta-gate-page .beta-gate-title-row h1 { margin: 0; min-width: 0; }
.support-page.beta-gate-page .beta-gate-title-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: var(--accent);
}
/* 28px against the 30px heading: the glyph's circle is 18 of its 24 viewBox
   units, so it renders 21px — the heading's cap-height. Sized here, never in the
   markup, so the mark cannot drift from the type it sits beside. */
.support-page.beta-gate-page .beta-gate-title-glyph { width: 28px; height: 28px; }

/* THE STATE BLOCK — the top elevation. NO GOLD EDGE AND NO HEADING, and neither
   may be added: this one card renders the thank-you to a paying supporter being
   told no AND the "sign-in isn't switched on" fault state, so a gold rule would
   celebrate one and decorate the other, and a heading would need a word of copy
   on a page whose copy is frozen.

   It is FLUSH with the prose above it rather than stepping out past it, which is
   the one place this diverges from the app it is modelled on. There the panels
   step out because the measure sits on the paragraphs; here `.support-page > *`
   puts the measure on every direct child, and stepping a nested card out past it
   would need a negative margin or a transform — both of which this section's own
   opening comment rejects for having to fight the page's safe-area padding at
   390px. The card's padding insets its text instead, which is the same reading
   (a defined object against the page talking) in this page's existing idiom, and
   exactly what .support-section already does two blocks further down. */
.support-page.beta-gate-page .beta-gate-state {
  margin: 20px 0 0;
  padding: 20px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
/* Spacing is normalised INSIDE the card rather than inherited, because the
   branches' own paragraphs carry no bottom margin at all (`.support-page p` sets
   none and the reset zeroes it), so two consecutive <p> in the entitled branch
   would butt-join inside a box where it is far more visible than it was on the
   open page. Zero the bottom edges, then space between siblings only: the gaps
   are uniform whatever branch renders, and the card's padding owns the inset at
   both ends without a first/last-child exception. */
.support-page.beta-gate-page .beta-gate-state > * { margin-bottom: 0; }
.support-page.beta-gate-page .beta-gate-state > * + * { margin-top: 14px; }
/* The one exception: the offer disclosure is placed ABOVE the button it
   qualifies (see .pricing-cta-offer's own comment), so it binds DOWN to that
   button rather than sitting equidistant between two blocks. */
.support-page.beta-gate-page .beta-gate-state > .support-hero-offer + * { margin-top: 8px; }

/* Running-cost ledger — one card per cost, token-driven. */
.support-ledger {
  list-style: none;
  padding: 0;
  margin: 14px 0 16px;
  display: grid;
  gap: 10px;
}
.support-ledger-item {
  padding: 12px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.6;
}
.support-ledger-item strong { color: var(--text); }
.support-tier-fineprint {
  font-size: 13.5px;
  color: var(--text-faint);
  line-height: 1.6;
  margin: 4px 0 10px;
}
.support-thanks-hero {
  margin: 0 auto 24px; /* see .support-hero — centered, not inline-zeroed */
  padding: 22px 24px;
  background: linear-gradient(180deg, rgba(200, 161, 59, 0.10), var(--bg-raised) 70%);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
}
.support-thanks-hero h1 { margin: 0 0 8px; }
.support-thanks-star {
  display: block;
  font-size: 30px;
  line-height: 1;
  color: var(--accent);
  margin: 0 0 8px;
}
.support-logout {
  margin: 14px 0 0;
}

/* Prose-card tier grid — now used ONLY by views/about.ejs's funding section
   (two cards: Free + Ad-free supporter). /support's own tier comparison moved to
   the .pricing-* pricing-page layout below; these rules are kept unchanged so
   that move could not disturb the About page. auto-fit + minmax reflows as the
   container narrows, and the @600px rule further down collapses it to a single
   column (so no horizontal scroll at 360/280px). */
.support-tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 16px;
  margin: 18px 0 12px;
}
.support-tier {
  padding: 18px 18px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
/* h4 only. These cards' headings were <h3> when /support owned them; the
   redesign moved /support to .pricing-* and views/about.ejs — now the sole
   consumer — uses <h4>, so the h3 half of this selector matched nothing. */
.support-tier h4 {
  margin: 0 0 10px;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}
.support-tier p {
  margin: 0 0 12px;
  font-size: 14px;
}
.support-tier-featured {
  border-color: var(--accent-border);
  background: linear-gradient(180deg, rgba(200,161,59,0.08), var(--bg-raised) 60%);
}
.support-tier-login {
  font-size: 12px;
  color: var(--text-faint);
}
/* The "Sign in with Patreon" link intentionally follows the page-wide prose-link
   idiom above (.support-page a:not(.cta): white → gold on hover/focus), so it has
   no color rule of its own — keeps every prose link on the page consistent. */
.support-tier-pending {
  color: var(--text-faint);
  font-style: italic;
}

/* ----------------------------------------------------------------------------
   /support tier comparison — conventional pricing-page layout.
   ----------------------------------------------------------------------------
   A PARALLEL class family (.pricing-*), not an edit of .support-tier* above:
   views/about.ejs reuses those on its funding cards, so restyling them into
   price cards would have silently redesigned the About page too. Nothing here
   is shared with another template.

   Every rule is scoped under .support-page for two reasons: it beats the
   page-wide element rules (.support-page p / h3, which are (0,1,1) and would
   otherwise win over a bare class), and it keeps the layout from leaking if a
   .pricing-* name is ever reused elsewhere.

   Pure CSS/SSR: no tabs, no JS disclosure — all four cards are always rendered
   and always visible ("keep stacked, don't tab"), so crawlers and a no-JS
   reader get the whole comparison.
   ---------------------------------------------------------------------------- */

/* The one section that opts out of the page's reading measure: four price cards
   cannot be compared at a glance stacked 2-up in a prose column. Bounded by
   .app--wide's 1280px column, so it never drives horizontal scroll. */
.support-section-wide { --support-measure: 1080px; }
/* The hero's fallback CTA (#choose-your-level — rendered when only per-tier
   Patreon links are configured, so there is no generic link for a tier-less
   button) jumps here. The site header is position:sticky, so without this the
   section heading lands underneath it. Same idiom and same offset as the other
   in-page jump targets on the site. */
.support-page .support-section-wide { scroll-margin-top: calc(var(--header-h) + 16px); }
/* ...and its prose spans the FULL band too — no narrower measure of its own.
   This selector used to cap these children (the <h2>, .pricing-intro,
   .pricing-note, .support-tier-fineprint, .pricing-lifecycle,
   .support-tier-login) at 30rem/480px, flush with the grid's left edge —
   under half of the 1080px panel, and reported as a defect. A 1080px line of
   15px prose is longer than this site's usual reading measure, but the
   exception existed only to KEEP a narrower measure here, and removing that
   narrowing is what was asked for, so nothing re-imposes a cap.

   The .pricing-grid / .pricing-table-wrap exclusions stay for documentation
   even though `max-width: none` would no longer reach them either way — the
   grid sizes itself via its own grid-template-columns, and the table scrolls
   inside .pricing-table-wrap's own box; neither took a measure from here. */
.support-page .support-section-wide > :not(.pricing-grid):not(.pricing-table-wrap) { max-width: none; }

.support-page .pricing-intro { margin: 0 0 4px; color: var(--text); }
.support-page .pricing-note { margin: 0 0 10px; font-size: 13.5px; color: var(--text-faint); }
.support-page .pricing-lifecycle { margin: 0 0 10px; }
.support-page .pricing-lifecycle strong { color: var(--text); }

/* Mobile-first: one column, so 390px (and 280px) can never scroll sideways.
   Two-up from 620px, and the full four-across at 1080px — the same breakpoint
   the verse study grid uses for its two-column layout. */
.support-page .pricing-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  margin: 18px 0 16px;
}
@media (min-width: 620px) {
  .support-page .pricing-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1080px) {
  .support-page .pricing-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Column layout so .pricing-features can absorb the slack and pin the CTA to the
   foot of every card — the buttons line up across the row whatever each card's
   feature text wraps to. padding-top leaves room for the badge, which straddles
   the top border; it is on EVERY card so the four headers stay aligned. */
.support-page .pricing-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 24px 16px 18px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.support-page .pricing-card-featured {
  border-color: var(--accent-border);
  background: linear-gradient(180deg, rgba(200, 161, 59, 0.10), var(--bg-card) 62%);
}
.support-page .pricing-badge {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--bg-raised);
  color: var(--accent);
  font: 700 10.5px/1.4 var(--ui-font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Price-forward header: name, then the amount as the card's loudest element,
   then one line of who it's for. */
.support-page .pricing-card-head {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-soft);
}
.support-page .pricing-name {
  margin: 0 0 6px;
  font: 700 12px/1.3 var(--ui-font);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.support-page .pricing-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 3px;
  margin: 0 0 8px;
}
.support-page .pricing-amount {
  font: 700 32px/1 var(--ui-font);
  letter-spacing: -0.02em;
  color: var(--text);
}
.support-page .pricing-period {
  font: 500 13px/1 var(--ui-font);
  color: var(--text-faint);
}
/* min-height reserves TWO lines (3em at 13px/1.5). The four "who it's for" lines
   are written to fit inside two at every card width this grid produces, but they
   are not all the same length — without the reservation, whichever one happens to
   fit on a single line at a given width lifts that card's feature list a row out
   of step with its neighbours, and the comparison stops reading across. */
.support-page .pricing-who {
  margin: 0;
  min-height: 3em;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-faint);
}

/* Each card's HEADLINE bullets (3-5 per card, from the per-cell `summary` in
   views/support.ejs) — not the full matrix, which is the .pricing-table below.
   The columns therefore no longer bullet the same rows, by design; reading
   ACROSS is the table's job now, and reading DOWN one card is this list's.
   flex:1 lets the list take the slack so .pricing-cta lands at the foot. */
.support-page .pricing-features {
  flex: 1 1 auto;
  display: grid;
  align-content: start;
  gap: 10px;
  margin: 14px 0 16px;
  padding: 0;
  list-style: none;
}
.support-page .pricing-features li {
  display: grid;
  grid-template-columns: 15px minmax(0, 1fr);
  gap: 8px;
  align-items: start;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
}
.support-page .pricing-features strong { color: var(--text); font-weight: 700; }
/* The glyph is aria-hidden and colour is only a reinforcement — every row also
   carries a .visually-hidden "Included." / "Not included." for screen readers,
   so inclusion is never signalled by colour or symbol alone. */
.support-page .pricing-mark {
  font: 700 13px/1.55 var(--ui-font);
  text-align: center;
}
.support-page .pricing-yes .pricing-mark { color: var(--success); }
.support-page .pricing-no { color: var(--text-faint); }
.support-page .pricing-no .pricing-mark { color: var(--text-faint); }
.support-page .pricing-no strong { color: var(--text-dim); font-weight: 600; }

/* One CTA per card, same place on every card. Full-width button: .cta is already
   an inline-flex with justify-content:center, so the label stays centered. */
.support-page .pricing-cta { margin: auto 0 0; }
.support-page .pricing-cta .cta { width: 100%; }

/* What the button below actually opens, when its href says something the label
   does not — a Patreon checkout link carrying `is_free_trial=true`. Derived from
   that button's own resolved URL (config/patreon-links.js reads the parameter;
   config/support-features.js owns the sentence), so no tier is named in CSS, in
   the template, or in the copy.

   FOUR PLACEMENTS, ONE RULE. .pricing-cta-offer is the per-card note on
   /support. .support-hero-offer is the same sentence above a hero CTA, in three
   places: /support's own hero button (the biggest control on the page, which had
   no disclosure at all until the note stopped being a pricing-loop-only thing),
   the upgrade wall (views/upgrade.ejs), whose single CTA opens the BLOCKED
   TIER's checkout and so carries an offer the label does not state, and /about's
   funding section (views/about.ejs). The wall needs no selector of its own
   because its section is also .support-page; /about is NOT a .support-page, so
   its own container is named below — that second selector is the whole cost of
   closing the last surface that rendered a Patreon CTA with nothing describing
   what it opens. Same styling because it is the same claim about the same kind
   of destination — one rule, not four copies.

   PLACED ABOVE ITS BUTTON on purpose, in every spot: .pricing-features is the
   card's flex grower, so the LAST child is what lands on the card's bottom edge,
   and a note under the button would lift only that card's CTA and break the row
   the four buttons read across. It also means the qualification is read before
   the label it qualifies.

   Gold rather than --text-faint: this qualifies a label that states a price, so
   it is the one line a reader must not skim. It states no duration — the
   parameter asserts only that a trial was REQUESTED — which is a property of the
   copy, checked (not guaranteed) at boot: config/support-features.js pins the
   shipped sentence verbatim and screens for the common phrasings of a term. */
.support-page .pricing-cta-offer,
.support-page .support-hero-offer,
.funding-patreon .support-hero-offer {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--accent);
}

/* ---- Full comparison table -------------------------------------------------
   The cards carry each level's headline; this carries the whole matrix, with the
   long-form note in every cell. Plain SSR <table> — no tabs, no JS disclosure.

   THE SCROLL RULE: at 390px a five-column comparison cannot fit, and the one
   thing that must never happen is the PAGE scrolling sideways. So the table gets
   a min-width and .pricing-table-wrap owns the overflow — the scroll happens
   inside that box, bounded by .support-section's padding. Above ~1080px the
   section is wider than the min-width and nothing scrolls at all.

   :focus-visible is styled because tabindex="0" (needed so a keyboard user can
   scroll the region) makes this box focusable — an unstyled focus ring on a
   focusable div is a real a11y regression, not a nitpick. */
.support-page .pricing-table-wrap {
  /* position: relative is LOAD-BEARING, not decoration — even though the
     table cells below no longer carry a .visually-hidden span (the state,
     "Included"/"Not included", is now visible text in .pricing-table-state;
     see the comments further down). It was added because .visually-hidden is
     `position: absolute`, and an abspos box is positioned against its nearest
     POSITIONED ancestor — with none, that is the initial containing block, so
     those spans escaped this scroller entirely and contributed their offsets to
     the ROOT's scrollable overflow: measured, documentElement.scrollWidth was
     678px at a 390px viewport while body.scrollWidth was a correct 390px. Only
     html's `overflow-x: clip` kept that from being a visible page scrollbar.
     The rule stays as a defensive guard: it costs nothing, and it's what keeps
     any FUTURE abspos content added to a cell (a badge, a tooltip) contained
     inside this scroller instead of silently reopening the same 678px bug.
     (.pricing-card is position: relative for its badge and so never had the
     problem.) */
  position: relative;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  margin: 0 0 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.support-page .pricing-table-wrap:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* border-collapse: SEPARATE (with zero spacing), not collapse — the row-header
   column below is position:sticky, and a collapsed table's borders belong to the
   table, so they do not paint on a sticky cell (the divider vanishes mid-scroll
   in Chrome). Every cell therefore draws its own border-top instead. */
.support-page .pricing-table {
  width: 100%;
  min-width: 820px;
  border-collapse: separate;
  border-spacing: 0;
  font-family: var(--ui-font);
}
/* The caption is the table's accessible name AND its visible header band, so it
   is deliberately SHORT: a paragraph here would inherit the table's 820px
   min-width and force a 390px reader to scroll sideways to read a sentence. The
   explanatory prose stays in .pricing-intro, above, at the reading measure. */
.support-page .pricing-table caption {
  text-align: left;
  padding: 14px 14px 12px;
  color: var(--text);
  font: 700 12px/1.3 var(--ui-font);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.support-page .pricing-table th,
.support-page .pricing-table td {
  text-align: left;
  vertical-align: top;
  padding: 11px 14px;
  border-top: 1px solid var(--border-soft);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
}
.support-page .pricing-table thead th {
  border-top: 0;
  color: var(--text);
  white-space: nowrap;
}
/* Optional, cheap emphasis for the featured tier's column — cards[key].featured
   is the same flag that badges the Autodidact card "Recommended" above, reused
   here rather than a second source of truth. Header-only: the column has no
   different markup or content below it, just this one accent tint so the eye
   can find it while scanning the matrix. */
.support-page .pricing-table thead th.pricing-table-th-featured {
  background: var(--accent-soft);
  color: var(--accent);
}
.support-page .pricing-table tbody tr:first-child > * { border-top-color: var(--border); }
.support-page .pricing-table-tier {
  display: block;
  font: 700 12px/1.3 var(--ui-font);
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.support-page .pricing-table-price {
  display: block;
  margin-top: 3px;
  font: 500 12px/1.3 var(--ui-font);
  color: var(--text-faint);
}
/* The feature column stays put while the tier columns scroll — without it, a
   390px reader scrolled two columns right is looking at four ticks with no idea
   which row they belong to. box-shadow, not border-right: see the
   border-collapse note above. */
.support-page .pricing-table-rowhead {
  position: sticky;
  left: 0;
  z-index: 1;
  min-width: 150px;
  background: var(--bg-card);
  box-shadow: 1px 0 0 var(--border-soft);
  color: var(--text);
  font-weight: 700;
}
/* Cell = a visible state chip ("Included" / "Not included") stacked above the
   note, plus a faint state-tinted cell background, so a column reads at a
   glance instead of as a wall of near-uniform prose. Previously the state
   lived ONLY in a .visually-hidden span next to a 13px aria-hidden glyph — the
   single most important fact in the cell (is this included?) was the one
   thing a sighted reader could not read. The label is now real, visible text,
   so this cell no longer carries a .visually-hidden span (a screen reader
   would otherwise announce the state twice); .pricing-features on the cards
   above is untouched and keeps its own .visually-hidden span exactly as
   before. Still the SAME .pricing-mark / .pricing-yes / .pricing-no state
   classes as the cards, so the tick, the cross, and their colours stay defined
   once (above) — this block only adds the table's own stacked layout and cell
   tint on top of them. An empty `<td></td>` (the "no copy for this tier" case)
   carries neither class, so it gets no chip, no tint, and no label.

   The td itself is NOT touched here — no display:flex/grid on it. A <td> only
   participates in the table's row-based layout while it renders as
   `display: table-cell`; overriding that (measured with display:flex) makes
   Chrome wrap it in an anonymous table-cell box instead, which broke row
   height entirely (every row in this table ballooned to 300-365px). The stack
   is achieved the plain way instead: .pricing-table-state is inline-flex (so
   the glyph + label sit on one line, sized to content) and .pricing-table-note
   is a block, which always starts on its own line after an inline sibling
   regardless of the inline element's own width — no flex parent required. */
.support-page .pricing-table-state {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  font: 700 10.5px/1.4 var(--ui-font);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-faint);
}
/* The tint is reinforcement ONLY — the chip's own text already says the state;
   colour or the glyph alone never carries it. --success-soft is translucent
   (an rgba), which stays safe even though a tinted cell scrolls under the
   sticky .pricing-table-rowhead column: that column's OWN background is an
   opaque solid (var(--bg-card), a hex colour, not rgba), so it fully occludes
   any tint scrolling beneath it regardless of that tint's alpha — checked by
   scrolling a tinted "yes" cell under the sticky column at 390px. The "no"
   tint uses --bg-raised (a different, darker solid) rather than --border-soft:
   --border-soft is also this table's border-top colour, so using it as a fill
   too would erase that row divider on every "not included" cell. */
.support-page .pricing-table td.pricing-yes {
  background: var(--success-soft);
}
.support-page .pricing-table td.pricing-yes .pricing-table-state {
  color: var(--success);
  border-color: var(--success-border);
}
.support-page .pricing-table td.pricing-no {
  background: var(--bg-raised);
}
/* The note is secondary to the state chip above it now — smaller and dimmer,
   the same "faint" role .pricing-who plays under a card's headline — and a
   block, so it always drops to its own line under the inline-flex chip (see
   above). It used to be inline-BLOCK at a hard-coded `calc(100% - 21px)` (the
   old glyph's 15px width + 6px gap), so a wrapped second line stayed clear of
   the tick instead of running back under it; the chip is above the note now,
   not beside it, so that magic number described a layout that no longer
   exists and is removed rather than left stale. */
.support-page .pricing-table-note {
  display: block;
  margin-top: 5px;
  color: var(--text-faint);
  font-size: 12px;
}

.support-ways {
  margin: 8px 0 20px 18px;
  color: var(--text-dim);
  line-height: 1.7;
}
.support-ways li { margin-bottom: 8px; }
.support-ways strong { color: var(--text); }

/* About-page funding highlight. Built on the prose-card tier grid (.support-tiers
   / .support-tier / .support-tier-featured, defined above, including their 600px
   single-column collapse) plus a Patreon-branded header and the integration
   mount point [data-patreon-embed].

   /about is the ONLY consumer of those three classes: /support's tier comparison
   is the separate .pricing-* pricing-page layout. So restyle .support-tier* for
   About's needs freely — nothing on /support will move — and conversely, do NOT
   reach for them when changing the /support price cards. */
.funding-intro {
  font-size: 16px;
  color: var(--text);
  margin: 0 0 4px;
}
.funding-patreon-badge {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 10px;
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.funding-patreon-ico { display: inline-flex; }
.funding-patreon-ico svg { width: 15px; height: 15px; display: block; }
/* Integration mount point: a future Patreon widget replaces its contents; the
   SSR fallback (CTA / thank-you / pending) sits here until then. */
.patreon-embed { margin-top: 14px; }
.funding-patreon-thanks {
  margin: 0;
  font-weight: 600;
  color: var(--accent);
}
/* Early-access callout, between the tier cards and .funding-note. Deliberately
   NOT a .support-tier: it is not a third column and must not read as a fourth
   thing to buy — the same offer the two cards describe, stated as a benefit.
   Accent-tinted rather than bordered like the cards, so it reads as a note ON
   the grid above it rather than another member of it. */
.funding-early {
  font-size: 15px;
  color: var(--text);
  margin: 16px 0 0;
  padding: 14px 16px;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}
.funding-early strong:first-child { color: var(--accent); }
.funding-note {
  font-size: 14px;
  color: var(--text-dim);
  margin: 18px 0;
}

@media (max-width: 600px) {
  /* No padding on the sticky band — its height comes from .site-header-inner's
     min-height: var(--header-h). Padding here would re-inflate the bar (and
     desync the sticky offsets, which assume the bar == --header-h). */
  .brand-mark-img { width: 32px; height: 32px; }
  .brand-text .brand-name { font-size: 20px; }
  .site-nav a,
  .nav-dropdown-toggle { padding: 6px 10px; font-size: 13px; }
  .results { padding: 18px 14px; }
  .support-tiers { grid-template-columns: 1fr; }
  .support-section { padding: 18px 16px; }
}

/* Sub-360px header packing. The two primary nav links (Tools, Learn) ride the
   single header row beside the brand + OT toggle + gear; once "Tools" joined
   "Learn" the row's intrinsic width grew to ~306px and clipped its last link on
   the ~280px Galaxy Fold edge (320px+ still fit). Reclaim the width by tightening
   the header's OWN spacing — never the brand wordmark, which stays legible.

   THIS BLOCK NO LONGER OWNS THE NAV-LINK PADDING OR THE HEADER GAPS. The ≤400px
   header-packing block (~line 3479) took them over when the Patreon control landed,
   and it had to raise its specificity to do it: the @media (max-width: 600px) block
   directly above sets `.site-nav a, .nav-dropdown-toggle { padding: 6px 10px }` at
   (0,1,0)/(0,1,1) and sits ~6,000 lines BELOW the 400px block, so a bare selector
   there would lose on source order. Qualifying it as `.header-end .site-nav a,
   .header-end .nav-dropdown-toggle` (0,2,1)/(0,2,0) fixed that — and, because
   `.site-nav` and both `.nav-dropdown-toggle` instances (Tools, and the supporter
   account menu) all live inside `.header-end`, it also permanently out-specifies
   anything bare down here. A `.site-nav a { padding }` rule in this block can no
   longer win at any width; it is not a source-order question any more.

   The three declarations that used to be here were therefore removed, not moved:
     • `.site-nav a, .nav-dropdown-toggle { padding: 6px 8px }` — DEAD. Measured
       computed padding at 360px and 320px is the 400px block's `6px 7px`.
     • `.header-end { gap: 9px }` and `.site-nav { gap: 3px }` — these still MATCHED
       (both bare, both tying the 400px block at (0,1,0) and winning on source
       order), and both were LOOSER than the values above them: the reclaim inverted
       below 360px, spending ~3px exactly where the header has the least room.
   Re-stating any of them here can only loosen the packing. If this block ever needs
   to tighten further, it must beat (0,2,1) — qualify with `.header-end` too. */
@media (max-width: 360px) {
  .site-header-inner {
    padding-left: calc(10px + env(safe-area-inset-left));
    padding-right: calc(10px + env(safe-area-inset-right));
    /* Third-tier gap, below the ≤400px block's 10px. See the .header-end note
       below — these two exist together or not at all. */
    column-gap: 6px;
  }
  .brand-link { gap: 10px; }
  /* THIRD RECLAIM, 2026-08-11 — the ≤320px case, and the one thing here that is
     not merely cosmetic. With the page-share control added and the ≤400px block's
     reclaim applied, /  at 320px still ran the row 15.4px past the bar's padding
     edge, and because .header-end is `flex: none` and the root carries
     `overflow-x: clip`, the overflow lands entirely on the LAST child: 15.4px of
     the 44px Patreon sign-in button was clipped away, with no scrollbar and no
     error to say so. Master does not clip it (measured 2.6px of brand still to
     give), so this is the one regression at 320px that had to be paid for rather
     than reported.
     These three declarations reclaim 20px, which un-clips it. They are BARE and
     therefore rely on source order over the ≤400px block ~6,200 lines above —
     which is exactly the trap that block's own comment documents, so: they win
     only because each is (0,1,0) and this block is LOWER. Anything added here that
     collides with a DESCENDANT-qualified rule up there (`.header-end .site-nav a`,
     `.header-end .nav-dropdown-toggle`) must be qualified with `.header-end` too.
     What is NOT fixed at 320px: the 30px brand mark still overhangs the MT|LXX
     toggle, by 19.4px against master's 17.4px. That is a pre-existing failure — the
     row wants ~57px it does not have — and closing it needs a control to leave the
     bar, which is an owner ruling (docs/patreon-login-button-spec.md §9.3), not a
     packing decision. */
  .header-end { gap: 4px; }
  .ot-toggle-btn { padding: 8px 4px; }
}

/* ============================================================================
   33. 404 NOT-FOUND PAGE (/totally-bogus, unknown verses/words)
   ----------------------------------------------------------------------------
   Custom 404 hero rendered by views/404.ejs above the (verbatim) home search +
   results scaffold. Centered illustration + heading + copy + two action links
   (Return home / FAQ), reusing the shared .cta / .cta-primary buttons. The
   <img> carries width/height attributes so the reserved box prevents layout
   shift while the picture loads.
   ============================================================================ */
.notfound {
  max-width: 640px;
  margin: 48px auto 0;
  padding: 8px 0 24px;
  text-align: center;
}
.notfound-img {
  display: block;
  width: min(800px, 100%);
  max-width: 100%;
  height: auto;
  margin: 0 auto 24px;
  border-radius: var(--radius);
}
.notfound h1,
.notfound h2 {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 12px;
}
.notfound p {
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1.7;
  margin: 0 auto 16px;
}
.notfound-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 20px;
}
/* Comfortable touch targets (>=44px tall) for the action links on the 404
   page; .cta already carries the accent styling, this just guarantees the
   tappable height when these CTAs sit on their own. */
.notfound-actions .cta {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 600px) {
  .notfound { margin-top: 28px; }
  .notfound h1, .notfound h2 { font-size: 21px; }
  .notfound-actions .cta { flex: 1 1 auto; }
}

/* ============================================================================
   LXX VOCABULARY BROWSE INDEX (/lxx)
   Frequency-sorted directory of Septuagint-only vocabulary (the genuine words
   that have a curated gloss but no Strong's number). Reuses the --bg-card /
   --accent / --greek-font vocabulary of the rest of the app — each row is a
   card linking to that word's /lxx/:slug study page.
   ============================================================================ */
.vocab-hero { max-width: 760px; margin: 4px 0 22px; }
.vocab-title {
  font-family: var(--reading-font);
  font-size: 30px;
  color: var(--text);
  margin: 0 0 12px;
}
.vocab-intro { color: var(--text); font-size: 16px; line-height: 1.7; margin: 0 0 12px; }
.vocab-note { color: var(--text-dim); font-size: 14px; line-height: 1.65; margin: 0 0 14px; }
.vocab-meta {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.vocab-meta strong { color: var(--accent); }

.vocab-list {
  list-style: none;
  display: grid;
  gap: 8px;
  margin: 0 0 22px;
  padding: 0;
}
.vocab-item { margin: 0; }
.vocab-link {
  display: grid;
  grid-template-columns: minmax(140px, 210px) 1fr auto;
  align-items: baseline;
  gap: 3px 18px;
  padding: 12px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.vocab-link:hover { border-color: var(--accent-border); background: var(--bg-raised); }
.vocab-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vocab-greek {
  grid-column: 1; grid-row: 1;
  font-family: var(--greek-font);
  font-size: 22px;
  line-height: 1.2;
  color: var(--text);
}
.vocab-translit {
  grid-column: 1; grid-row: 2;
  font-family: var(--mono-font);
  font-size: 13px;
  color: var(--accent);
}
.vocab-gloss {
  grid-column: 2; grid-row: 1 / span 2;
  align-self: center;
  font-family: var(--reading-font);
  font-size: 16px;
  color: var(--text-dim);
}
.vocab-freq {
  grid-column: 3; grid-row: 1 / span 2;
  align-self: center;
  justify-self: end;
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}
.vocab-freq-x { color: var(--text-faint); margin-left: 1px; }

.vocab-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 0 0 24px;
  font-family: var(--ui-font);
}
.vocab-pager-btn {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-card);
  color: var(--accent);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
}
.vocab-pager-btn:hover { border-color: var(--accent-border); background: var(--bg-raised); }
.vocab-pager-btn.is-disabled {
  color: var(--text-faint);
  background: transparent;
  border-color: var(--border-soft);
  pointer-events: none;
}
.vocab-pager-status { font-size: 13px; color: var(--text-dim); }

.vocab-foot {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.7;
  border-top: 1px solid var(--border-soft);
  padding-top: 16px;
}
.vocab-foot a { color: var(--accent); }

@media (max-width: 560px) {
  .vocab-title { font-size: 25px; }
  .vocab-link { grid-template-columns: 1fr auto; gap: 2px 12px; }
  .vocab-gloss { grid-column: 1 / -1; grid-row: 3; font-size: 15px; }
  .vocab-freq { grid-column: 2; grid-row: 1 / span 2; }
}

/* ============================================================================
   STRONG'S LEXICON BROWSE INDEX (/lexicon) — extends the .vocab-* list above
   with a Hebrew row variant, a Strong's-code chip, a sort toggle, and the
   two-testament landing hub.
   ============================================================================ */
.vocab-hebrew {
  grid-column: 1; grid-row: 1;
  font-family: var(--hebrew-font);
  font-size: 24px;
  line-height: 1.25;
  color: var(--text);
}
.vocab-code {
  font-family: var(--mono-font);
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.vocab-translit-text::before { content: "·"; color: var(--text-faint); margin: 0 5px; }
.vocab-freq-zero { color: var(--text-faint); font-weight: 600; }

/* Sort toggle (by frequency / by number / switch testament). */
.vocab-sort { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.vocab-sort-btn {
  display: inline-flex; align-items: center; min-height: 34px;
  padding: 6px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-card);
  color: var(--text-dim);
  font: 600 13px/1 var(--ui-font);
  text-decoration: none;
}
.vocab-sort-btn:hover { border-color: var(--accent-border); color: var(--accent); }
.vocab-sort-btn.is-active {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent-border);
}
.vocab-sort-alt { margin-left: auto; }

/* Lexicon hub (landing) — two testament columns. */
.lex-hubs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  margin: 0 0 24px;
}
.lex-hub {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 18px 16px;
}
.lex-hub-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 4px; }
.lex-hub-title { font-family: var(--reading-font); font-size: 22px; color: var(--text); margin: 0; }
.lex-hub-sub { font: 600 11px/1 var(--ui-font); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); }
.lex-hub-stat { font-family: var(--ui-font); font-size: 12.5px; color: var(--text-dim); margin: 0 0 14px; }
.lex-hub-stat strong { color: var(--accent); }
.lex-hub-lead {
  font: 700 11px/1 var(--ui-font); text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-dim); margin: 0 0 8px;
}
.lex-hub-actions { display: flex; flex-wrap: wrap; gap: 8px; }

/* Compact card variant used in the hub teasers — a robust two-column stack
   (lemma / code+translit / gloss in col 1, frequency in col 2) so it never
   overflows the narrow hub column. */
.vocab-list-compact { gap: 6px; margin-bottom: 14px; }
.vocab-list-compact .vocab-link {
  grid-template-columns: 1fr auto;
  padding: 9px 12px;
  background: var(--bg-card);
}
.vocab-list-compact .vocab-greek { font-size: 19px; }
.vocab-list-compact .vocab-hebrew { font-size: 21px; }
.vocab-list-compact .vocab-gloss { grid-column: 1; grid-row: 3; align-self: start; font-size: 14px; }
.vocab-list-compact .vocab-freq { grid-column: 2; grid-row: 1 / span 3; }

@media (max-width: 760px) {
  .lex-hubs { grid-template-columns: 1fr; }
}

/* ============================================================================
   FULL-TEXT SEARCH RESULTS (/search?q=)
   Real results for an English phrase / word-study query: a "Word studies"
   section (lexicon hits → /w/ pages) above the verse list (FTS hits → /v/
   pages, each with a <mark>-highlighted snippet). Token-driven so it inherits
   the theme; no hard-coded colours.
   ============================================================================ */
.search-results h1, .search-results h2 { margin-bottom: 18px; }
.search-section { margin-bottom: 28px; }
.search-section h3 {
  font-family: var(--ui-font);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 12px;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.search-count {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-faint);
}

/* #30 disclosure — names the translations actually searched (WEB + KJV). */
.search-scope {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  margin: 0 0 12px;
}

/* Sort toggle — plain GET links (CSP-safe, no inline JS). The active option is a
   non-link span (aria-current) styled as a filled chip. */
.search-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 14px;
}
.search-sort-label {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
}
.search-sort-opt {
  font-family: var(--ui-font);
  font-size: 13px;
  padding: 4px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border-soft);
  text-decoration: none;
  color: var(--text);
  background: var(--bg-card);
}
.search-sort-opt:hover, .search-sort-opt:focus {
  border-color: var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.search-sort-opt.is-active {
  border-color: var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  cursor: default;
}

/* Word-study hits — compact rows linking to the Strong's page. */
.search-lexicon-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.search-lexicon-link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  padding: 10px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--text);
}
.search-lexicon-link:hover, .search-lexicon-link:focus {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.search-lexicon-strongs {
  font-family: var(--mono-font);
  font-size: 13px;
  color: var(--accent);
}
/* #114: the headword renders in the correct script face — Hebrew (Ezra SIL) for
   H-numbers, Greek (Gentium) for G-numbers — set by the modifier the template
   emits off the Strong's prefix, so a pointed Hebrew lemma (niqqud + cantillation)
   no longer flows through the Greek-tuned face. */
.search-lexicon-lemma { font-size: 17px; }
.search-lexicon-lemma--hebrew { font-family: var(--hebrew-font); }
.search-lexicon-lemma--greek { font-family: var(--greek-font); }
.search-lexicon-translit { font-style: italic; color: var(--text-dim); font-size: 14px; }
.search-lexicon-gloss { color: var(--text-dim); font-size: 14px; }

/* Verse hits — one readable row per verse: bold reference link + snippet. */
.search-verse-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.search-verse-item {
  padding: 12px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
/* Reference link + the matched-version tag share a baseline-aligned head row. */
.search-verse-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 4px;
}
.search-verse-ref {
  font-family: var(--ui-font);
  font-weight: 600;
  font-size: 14px;
  color: var(--accent);
  text-decoration: none;
}
.search-verse-ref:hover, .search-verse-ref:focus { text-decoration: underline; }
/* The translation the highlighted excerpt actually matched in (WEB / KJV) — a
   small uppercase tag so a reader always knows the source of the shown wording. */
.search-verse-version {
  font-family: var(--ui-font);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: 3px;
  padding: 1px 6px;
}
.search-verse-snippet {
  font-family: var(--reading-font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  margin: 0;
}
/* The FTS match highlight — scoped to the snippet so it can't bleed into other
   <mark> usage. Soft-gold fill + accent text keeps it on-theme and legible. */
.search-verse-snippet mark {
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 3px;
  padding: 0 2px;
}

/* Prev/next pager — plain links (works with no JS), disabled ends as spans. */
.search-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
}
.search-pager-link {
  font-family: var(--ui-font);
  font-size: 14px;
  padding: 8px 14px;
  border-radius: var(--radius);
  border: 1px solid var(--border-soft);
  text-decoration: none;
  color: var(--text);
  background: var(--bg-card);
}
.search-pager-link.prev, .search-pager-link.next { min-height: 40px; display: inline-flex; align-items: center; }
.search-pager-link:hover, .search-pager-link:focus {
  border-color: var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
}
.search-pager-link.disabled {
  color: var(--text-faint);
  background: transparent;
  border-color: transparent;
  cursor: default;
}
.search-pager-status {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
}

/* "More ways to search" affordance row — the secondary grammar/concordance
   links surfaced on the homepage (under the reference box) and in the verse-page
   word-study panel. Subordinate to the primary search; a tight inline cluster of
   plain <a> links. Tokens only — no hard-coded colors. */
.search-more {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 12px 0 0;
  font-family: var(--ui-font);
  font-size: 13px;
}
.search-more-label { color: var(--text-faint); }
/* Persistent underline at rest: these links otherwise signal "link" by gold
   colour + arrow alone, which fails WCAG "don't rely on colour". Shared across the
   home, verse and search surfaces. */
.search-more-link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 600;
}
.search-more-link:hover, .search-more-link:focus { text-decoration: underline; }
/* Inside the verse word-study panel the row sits above the word-by-word grid;
   give it a little breathing room beneath. */
.verse-search-more { margin-bottom: 14px; }

/* The "Search by grammar →" cross-link on the /search page. */
.search-by-grammar {
  font-family: var(--ui-font);
  font-size: 13.5px;
  color: var(--text-dim);
  margin: 0 0 18px;
}
.search-by-grammar a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; font-weight: 600; }
.search-by-grammar a:hover, .search-by-grammar a:focus { text-decoration: underline; }
/* Stacked cross-links (grammar + concordance) read as a tight cluster. */
.search-by-grammar + .search-by-grammar { margin-top: -10px; }
/* Touch: ≥44px tap target for both shared "search by grammar / occurrence" link
   idioms. inline-flex + vertical-align keeps them inline after their label / lead
   text (.search-more is a flex row; .search-by-grammar wraps them in a <p>). */
@media (pointer: coarse) {
  .search-more-link,
  .search-by-grammar a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    vertical-align: middle;
  }
}

/* The "see all occurrences →" cross-link beneath each Word-studies hit — sends
   the reader from the lexicon entry to the full corpus concordance. */
.search-word-studies .search-lexicon-list li {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}
.search-lexicon-occurrences {
  font-family: var(--ui-font);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  padding-left: 14px;
}
.search-lexicon-occurrences:hover, .search-lexicon-occurrences:focus { text-decoration: underline; }

/* ----------------------------------------------------------------------------
   /search EMPTY STATE — the "No exact match" recovery surface. Centered hero
   (icon + headline + honest version-scope disclosure), a no-JS GET form, an
   inline examples line, a responsive suggestion-card grid (reuses the
   .tools-card visual language), and the CTA. Tokens only — no hard-coded
   colours, no inline styles (CSP-locked).
   ---------------------------------------------------------------------------- */
.search-empty {
  /* The section is a grid item in .content; auto side-margins would collapse it
     to its content width (the squished column), so we let it STRETCH to fill the
     full content width (the .app cap) and center the inner hero text/form via
     their own max-width + margin:auto below. */
  text-align: center;
}
.search-empty-ico {
  display: inline-grid;
  place-items: center;
  width: 72px;
  height: 72px;
  margin: 8px auto 18px;
  border-radius: 18px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
}
.search-empty-ico svg { width: 38px; height: 38px; }
.search-empty-title {
  font-family: var(--reading-font);
  font-size: 34px;
  line-height: 1.2;
  margin: 0 0 14px;
}
.search-empty-lede {
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1.7;
  max-width: 60ch;
  margin: 0 auto 12px;
}
.search-empty-q,
.search-empty-eg {
  font-style: italic;
  color: var(--accent);
}
/* "Did you mean …" — the prominent recovery line. The suggestion itself is a
   button (the page's primary recovery action). The wrapper stays plain text so
   it inherits the parent's text-align (centered on the empty state, left on the
   results page); the button is inline-flex so it sits on the same line. */
.search-didyoumean {
  font-family: var(--ui-font);
  font-size: 15px;
  color: var(--text);
  margin: 4px auto 18px;
}
.search-didyoumean-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  vertical-align: middle;
  margin-left: 8px;
  padding: 7px 15px;
  border-radius: var(--radius);
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  transition: background 120ms, color 120ms;
}
.search-didyoumean-btn:hover, .search-didyoumean-btn:focus {
  background: var(--accent);
  color: var(--on-accent);
  text-decoration: none;
}
/* No-JS GET form — works without JavaScript, leverages the smart resolver. */
.search-empty-form {
  display: flex;
  gap: 8px;
  max-width: 480px;
  margin: 0 auto 16px;
}
.search-empty-input {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--ui-font);
  font-size: 15px;
  padding: 11px 14px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
}
.search-empty-input::placeholder { color: var(--text-faint); }
.search-empty-input:focus {
  outline: none;
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-empty-btn {
  flex: none;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  padding: 11px 18px;
  border-radius: var(--radius);
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
}
.search-empty-btn:hover, .search-empty-btn:focus {
  background: var(--accent);
  color: var(--on-accent);
  outline: none;
}
/* Inline "Examples:" line — small links separated by middots. */
.search-empty-examples {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  margin: 0 auto 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 4px 10px;
}
.search-empty-examples-label { color: var(--text-faint); }
.search-empty-examples a { color: var(--accent); text-decoration: none; }
.search-empty-examples a:hover, .search-empty-examples a:focus { text-decoration: underline; }
.search-empty-heading {
  font-family: var(--ui-font);
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 0 14px;
}
/* Suggestion-card grid — same card language as .tools-card. Four small cards +
   two wider tool cards (which span the full row on wide layouts). */
.search-suggest-grid {
  list-style: none;
  padding: 0;
  margin: 0 0 28px;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  text-align: left;
}
.search-suggest-wide { grid-column: 1 / -1; }
/* Two-across only where the auto-fit grid genuinely has ≥2 columns; `span 2`
   would otherwise FORCE a 2nd column on a 1-column phone layout and overflow. */
@media (min-width: 640px) {
  .search-suggest-wide { grid-column: span 2; }
}
.search-suggest-card {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 14px;
  height: 100%;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  text-decoration: none;
  color: inherit;
}
.search-suggest-card:hover,
.search-suggest-card:focus-visible {
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.search-suggest-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.search-suggest-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  color: var(--accent);
}
.search-suggest-ico svg { width: 21px; height: 21px; }
.search-suggest-text { min-width: 0; }
.search-suggest-title {
  display: block;
  color: var(--text);
  font-family: var(--ui-font);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.4;
}
.search-suggest-desc {
  display: block;
  color: var(--text-dim);
  font-size: 13.5px;
  line-height: 1.5;
  margin-top: 2px;
}
.search-empty-cta { margin: 0; }

/* ============================================================================
   LEMMA CONCORDANCE (/concordance)
   True lemma corpus search — resolve a query to a Strong's, list EVERY verse it
   occurs in. Reuses the .strongs-verse-list / .verse-tile / .search-pager /
   .search-lexicon-list primitives so it inherits the theme with no hard-coded
   colours; only the lemma header + group-heading chrome is new.
   ============================================================================ */
.concordance { max-width: 100%; }
.concordance-head {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border-soft);
}
.concordance-title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 14px;
  margin: 0 0 6px;
  font-size: 24px;
}
.concordance-strongs {
  font-family: var(--mono-font);
  font-size: 15px;
  color: var(--accent);
  text-decoration: none;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  padding: 2px 8px;
}
.concordance-strongs:hover, .concordance-strongs:focus { background: var(--accent-soft); }
.concordance-lemma { font-family: var(--greek-font); }
.concordance-lemma.hebrew { font-size: 28px; }
.concordance-translit { font-style: italic; color: var(--text-dim); font-size: 18px; }
.concordance-gloss {
  font-family: var(--reading-font);
  font-size: 17px;
  color: var(--text);
  margin: 0 0 8px;
}
.concordance-counts {
  font-family: var(--ui-font);
  font-size: 14px;
  color: var(--text-dim);
  margin: 0;
  line-height: 1.5;
}
.concordance-entry-link {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  white-space: nowrap;
}
.concordance-entry-link:hover, .concordance-entry-link:focus { text-decoration: underline; }

.concordance-group { margin-bottom: 32px; }
.concordance-group-heading {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: var(--ui-font);
  font-size: 15px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text);
  margin: 0 0 10px;
}
.concordance-group-count {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-faint);
}
/* The Septuagint group's heading carries a subtle accent rule so it reads as a
   distinct, secondary corpus — never visually merged with the primary group. */
.concordance-lxx {
  border-top: 1px solid var(--border-soft);
  padding-top: 24px;
}
.concordance-group-intro {
  font-family: var(--ui-font);
  font-size: 13.5px;
  color: var(--text-dim);
  line-height: 1.5;
  margin: 0 0 16px;
}
.concordance-book-group { margin-bottom: 18px; }
.concordance-book-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 15px;
  margin: 0 0 8px;
}
.concordance-book-link { color: var(--text); text-decoration: none; font-weight: 600; }
.concordance-book-link:hover, .concordance-book-link:focus { color: var(--accent); }
.concordance-book-count { font-size: 12px; color: var(--text-faint); font-weight: 400; }

.concordance-lead {
  font-family: var(--reading-font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--text);
  max-width: 60ch;
}
.concordance-candidates { margin-top: 16px; }
.concordance-foot {
  font-family: var(--ui-font);
  font-size: 13.5px;
  color: var(--text-dim);
  margin-top: 24px;
}
.concordance-foot a { color: var(--accent); text-decoration: none; font-weight: 600; }
.concordance-foot a:hover, .concordance-foot a:focus { text-decoration: underline; }

/* ============================================================================
   COMPARE WORDS WORKSPACE (/concordance, #192)
   Place 2–4 Hebrew/Greek words side by side. The compare header is a responsive
   grid of word cards (up to 4 wide, 2-col mid, 1-col phone); the "verses that use
   both words" panel reuses the .strongs-verse-list / .verse-tile primitives.
   dir="rtl" lives on the .compare-lemma <bdi> glyph ONLY — the card + its Latin
   stat lines stay LTR.
   ============================================================================ */
.compare { max-width: 100%; }
.compare-intro { margin: 0 0 20px; }
.compare-h1 { display: flex; align-items: center; gap: 10px; font-family: var(--reading-font); font-size: 30px; margin: 0 0 8px; color: var(--text); }
.compare-h1-ico { flex-shrink: 0; color: var(--accent); }
.compare-h1-ico svg { display: block; width: 27px; height: 27px; }
.compare-lead {
  font-family: var(--ui-font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-dim);
  max-width: 64ch;
  margin: 0;
}
.compare-lead strong { color: var(--text); }

.compare-cards {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
  align-items: stretch;
  margin: 0 0 18px;
}
@media (min-width: 560px) { .compare-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 980px) { .compare-cards { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } }

.compare-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.compare-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 6px;
}
.compare-card-code {
  font-family: var(--mono-font);
  font-size: 13px;
  color: var(--accent);
  text-decoration: none;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  padding: 1px 7px;
}
.compare-card-code:hover, .compare-card-code:focus { background: var(--accent-soft); }
.compare-card-remove {
  /* 44px min hit area (accessibility) while the glyph stays visually compact;
     negative margins keep the large target from inflating the card-top row. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: -8px -8px -8px 0;
  font-size: 20px;
  line-height: 1;
  color: var(--text-faint);
  text-decoration: none;
  border-radius: 6px;
}
.compare-card-remove:hover, .compare-card-remove:focus { color: var(--text); background: var(--bg-raised); }

/* Fixed min-height so cards align across scripts even when a Hebrew glyph carries
   niqqud + cantillation marks (taller than a Greek/Latin line). */
.compare-lemma-row {
  min-height: 56px;
  display: flex;
  align-items: center;
  margin: 0 0 2px;
}
.compare-lemma { font-family: var(--greek-font); font-size: 30px; line-height: 1.25; color: var(--text); }
.compare-lemma.hebrew { font-family: var(--hebrew-font); }
.compare-translit { font-family: var(--ui-font); font-style: italic; font-size: 14px; color: var(--text-dim); margin: 0 0 8px; }

.compare-meaning {
  font-family: var(--ui-font);
  font-size: 14px;
  color: var(--text);
  margin: 0 0 10px;
  padding: 8px 10px;
  background: var(--bg-raised);
  border-radius: 8px;
}
.compare-meaning-label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 2px;
}
.compare-meaning-text { font-family: var(--reading-font); font-size: 15px; color: var(--text); }
.compare-meaning-none { color: var(--text-faint); font-style: italic; }

.compare-stat { font-family: var(--ui-font); font-size: 14px; color: var(--text); margin: 0 0 4px; }
.compare-stat strong { font-size: 16px; }
.compare-stat-occ { color: var(--text-faint); font-size: 12.5px; }
.compare-stat-dim { font-size: 12.5px; color: var(--text-dim); margin: 0 0 8px; }
.compare-stat-corpus { display: block; color: var(--text-faint); font-size: 11.5px; }
.compare-first { font-family: var(--ui-font); font-size: 12.5px; color: var(--text-dim); margin: 0 0 10px; }
.compare-first a { color: var(--accent); text-decoration: none; }
.compare-first a:hover, .compare-first a:focus { text-decoration: underline; }
.compare-fullconc { margin: auto 0 0; padding-top: 8px; }
.compare-fullconc a { font-family: var(--ui-font); font-size: 13px; font-weight: 600; color: var(--accent); text-decoration: none; white-space: nowrap; }
.compare-fullconc a:hover, .compare-fullconc a:focus { text-decoration: underline; }

/* ── #194a: /concordance "Copy with reference" affordances ─────────────────────
   Progressive enhancement — the verse text + each word's identity are already
   SSR'd and select-copyable; these buttons ship `hidden` and are revealed by
   /js/concordance.js. EVERY rule here is SCOPED under a concordance-only ancestor
   (.compare / .compare-panel / .compare-usage / .compare-card) so the shared
   .verse-tile / .strongs-verse-list primitives on /w/ and /lxx/ are untouched. */

/* Anchor for the per-verse corner button (concordance tiles only — the /w/ + /lxx/
   tiles keep their own .verse-tile-wrap anchoring). */
.compare-panel .strongs-verse-list > li,
.compare-usage .strongs-verse-list > li { position: relative; }

/* Reserve room at the tile's top-right so the corner button never runs under the
   reference. Scoped to concordance text tiles only. */
.compare-panel .strongs-verse-list.has-text > li > a.verse-tile,
.compare-usage .strongs-verse-list.has-text > li > a.verse-tile { padding-right: 62px; }

/* "Verses that use both words" — this is the ONE compare-panel whose verse list is
   a DIRECT child of the panel (the "Each word in context" lists are nested inside
   .compare-usage-col, so the `>` child combinator leaves them — and the /w/, /lxx/,
   morphology lists — untouched). The shared .has-text primitive renders a single
   full-width column, which strands a wide band of blank space to the right of each
   short tile on desktop. Reflow it into a responsive card grid that fills the panel
   width (auto-fills to 2–3 columns on desktop, collapses to 1 on a phone) while
   keeping each column wide enough to read the verse prose without clipping. The
   track is capped (not `1fr`) so an underfilled row has real free space, and
   `justify-content: center` centers that row in the panel instead of hugging the
   left edge — a single tile on a wide screen, or the last odd tile of a row,
   lands in the middle of the reading column rather than flush-left. */
.compare-panel > .strongs-verse-list.has-text {
  grid-template-columns: repeat(auto-fill, minmax(320px, 460px));
  gap: 10px;
  justify-content: center;
}

/* Shared copy-button look — muted accent pill, theme-aware via the existing custom
   props. Covers both the per-verse and per-card variants. */
.compare .compare-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 4px 9px;
  border: 1px solid var(--accent-border);
  border-radius: 7px;
  background: var(--accent-soft);
  color: var(--accent);
  font: 600 12px/1 var(--ui-font);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms, opacity 120ms;
}
.compare .compare-copy:hover,
.compare .compare-copy.is-copied {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
}
.compare .compare-copy:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Per-verse: unobtrusive top-right corner button, revealed on tile hover/focus
   (keyboard-reachable via :focus-within on the <li>). */
.compare-panel .strongs-verse-list > li > .compare-copy-verse,
.compare-usage .strongs-verse-list > li > .compare-copy-verse {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
}
.compare-panel .strongs-verse-list > li:hover > .compare-copy-verse,
.compare-panel .strongs-verse-list > li:focus-within > .compare-copy-verse,
.compare-usage .strongs-verse-list > li:hover > .compare-copy-verse,
.compare-usage .strongs-verse-list > li:focus-within > .compare-copy-verse { opacity: 1; }

/* Per-card: a compact button at the very bottom of the card, under "Full
   concordance →" (the card is a flex column; keep it from stretching full-width). */
.compare-card .compare-copy-card {
  align-self: flex-start;
  margin-top: 8px;
}

/* Touch / coarse pointers have no hover — reveal the corner button at rest (lower
   contrast) and grow both variants to a ≥44px tap target. */
@media (hover: none), (pointer: coarse) {
  .compare-panel .strongs-verse-list > li > .compare-copy-verse,
  .compare-usage .strongs-verse-list > li > .compare-copy-verse { opacity: 0.85; }
  .compare .compare-copy {
    min-height: 44px;
    padding: 11px 13px;
    box-sizing: border-box;
  }
}

/* Add-word slot — a dashed placeholder card holding the no-JS GET form. */
.compare-add {
  justify-content: center;
  border-style: dashed;
  background: transparent;
}
.compare-add-form { display: flex; flex-direction: column; gap: 8px; }
.compare-add-label { font-family: var(--ui-font); font-size: 12px; font-weight: 600; color: var(--text-dim); }
.compare-add-input {
  font-family: var(--ui-font);
  /* 16px keeps iOS Safari from zooming the viewport on focus of the core action. */
  font-size: 16px;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  min-height: 44px;
}
.compare-add-input:focus { outline: 2px solid var(--accent-border); outline-offset: 1px; }
.compare-add-btn {
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 600;
  color: var(--bg);
  background: var(--accent);
  border: 0;
  border-radius: 8px;
  padding: 10px 14px;
  min-height: 44px;
  cursor: pointer;
}
.compare-add-btn:hover, .compare-add-btn:focus { filter: brightness(1.08); }
.compare-add-nomatch { font-family: var(--ui-font); font-size: 12.5px; color: var(--text-dim); margin: 2px 0 0; }

.compare-noteq {
  font-family: var(--ui-font);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-dim);
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 0 0 24px;
  max-width: 74ch;
}
.compare-noteq strong { color: var(--text); }

.compare-panel { margin: 0 0 28px; }
.compare-panel-h2 {
  font-family: var(--ui-font);
  font-size: 15px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text);
  margin: 0 0 10px;
}
.compare-panel-intro {
  font-family: var(--ui-font);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 0 0 16px;
  max-width: 74ch;
}
.compare-panel-intro strong { color: var(--text); }
/* Rail-1 state + the awaiting-2nd-word state read as quiet notice cards. */
.compare-crosscorpus .compare-panel-intro,
.compare-await .compare-panel-intro {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 12px 14px;
}

/* Landing — a centered search-hero mirroring the /search empty state. It reuses
   the .search-empty-* (ico / title / lede / form / examples / heading) and
   .search-suggest-* (grid / card) primitives; only the wrapper centering and a
   wider, capped question grid are landing-specific. The concordance shell is
   .app--wide, so the grid + foot are width-capped and auto-centered — the hero
   text/form self-center via their own max-width, exactly as on /search. */
.compare-landing { text-align: center; }
.compare-question-grid {
  max-width: 760px;
  margin: 0 auto 28px;
  /* Question prompts run longer than the /search suggestions — a wider min
     track keeps them to ~2–3 readable columns (still one column on a phone). */
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.compare-landing-foot { max-width: 60ch; margin: 0 auto; font-family: var(--ui-font); font-size: 13.5px; color: var(--text-dim); }
.compare-landing-foot a { color: var(--accent); text-decoration: none; font-weight: 600; }
.compare-landing-foot a:hover, .compare-landing-foot a:focus { text-decoration: underline; }

/* /w/ hero on-ramp — "Compare with another word →". */
.strongs-compare-cta { margin: 0 0 16px; }
.strongs-compare-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  padding: 7px 12px;
}
.strongs-compare-link:hover, .strongs-compare-link:focus { background: var(--accent-soft); }
.strongs-compare-icon { flex: 0 0 auto; }

/* About-tab "Compare all same-root words →". */
.about-family-compare { margin: 14px 0 0; }
.about-family-compare-link { font-family: var(--ui-font); font-size: 13.5px; font-weight: 600; color: var(--accent); text-decoration: none; }
.about-family-compare-link:hover, .about-family-compare-link:focus { text-decoration: underline; }
.about-family-compare-note { display: block; font-family: var(--ui-font); font-size: 12px; color: var(--text-faint); margin-top: 3px; }

/* ---- Compare-words P1 (#193): per-word colour key, sense line, suggestions,
   distribution, usage-in-context. The four word colours ride a single --wc custom
   property (set by .compare-c0..3) so a word keeps ONE colour across its card, its
   distribution column/bar, its shared-verse surface, and its usage block. Colour is
   an ENHANCEMENT only — every surface is also labelled/ordered, so a colour-blind
   reader loses nothing. Dark-theme palette (the app is dark-only). ------------- */
.compare-c0 { --wc: #6db3f2; } /* sky */
.compare-c1 { --wc: #e6b24e; } /* amber */
.compare-c2 { --wc: #82d69a; } /* green */
.compare-c3 { --wc: #c98bdb; } /* violet */

/* Card gets a coloured top edge = the legend for its colour. The add-word slot has
   no --wc, so it falls back to the neutral border. */
.compare-card { border-top: 3px solid var(--wc, var(--border)); }

/* BDB/Thayer sense line (#193b) — sits under the one-word gloss. */
.compare-sense { font-family: var(--ui-font); font-size: 12px; line-height: 1.5; color: var(--text-dim); margin: -4px 0 10px; }
.compare-sense-src { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-faint); }

/* Per-column parse-facet chips (#194b) — "by stem/tense/case/state" pill links
   into the word's OWN /w/ concordance, filtered to that grammatical form. Every
   selector is scoped under .compare-card so no bare shared class is restyled;
   Rail 2: a form split is NOT a meaning difference (the note says so). */
.compare-card .compare-facets { margin: 0 0 10px; }
.compare-card .compare-facets-label {
  font-family: var(--ui-font); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); margin: 0 0 6px;
}
.compare-card .compare-facets-list { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; }
.compare-card .compare-facet-chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--ui-font); font-size: 12px; text-decoration: none; color: var(--text);
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 999px; padding: 3px 9px; min-height: 26px;
}
.compare-card .compare-facet-chip:hover, .compare-card .compare-facet-chip:focus { border-color: var(--accent-border); background: var(--accent-soft); }
.compare-card .compare-facet-count { font-family: var(--mono-font); font-size: 11px; font-weight: 600; color: var(--text-dim); }
.compare-card .compare-facet-more { color: var(--text-dim); }
.compare-card .compare-facets-note { font-family: var(--ui-font); font-size: 10.5px; line-height: 1.45; color: var(--text-faint); margin: 6px 0 0; }
@media (hover: none), (pointer: coarse) {
  .compare-card .compare-facet-chip { min-height: 44px; }
}

/* Suggest-the-second-word (#193c) — pill chips that append a word to the bench. */
.compare-suggest { margin: 0 0 20px; }
.compare-suggest-head { font-family: var(--ui-font); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-faint); margin: 0 0 8px; }
.compare-suggest-list { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 6px; padding: 0; }
.compare-suggest-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--ui-font); text-decoration: none;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 999px; padding: 5px 12px; min-height: 34px;
}
.compare-suggest-chip:hover, .compare-suggest-chip:focus { border-color: var(--accent-border); background: var(--accent-soft); }
.compare-suggest-lemma { font-family: var(--greek-font); font-size: 16px; color: var(--text); }
.compare-suggest-lemma.hebrew { font-family: var(--hebrew-font); }
.compare-suggest-gloss { font-size: 12.5px; color: var(--text-dim); }
.compare-suggest-add { color: var(--accent); font-weight: 700; font-size: 15px; }
.compare-suggest-note { font-family: var(--ui-font); font-size: 11.5px; color: var(--text-faint); margin: 0; }

/* "Where each word is used" — per-word section FOOTPRINT strips (redesign spec
   docs/concordance-weu-redesign-2026.md). Small multiples on a shared canon axis; the
   bar HEIGHT encodes the over/under-representation ratio (capped 3×, the true figure
   in the <title> + details). SVG bars use presentation attributes + the .compare-c0..3
   fill classes (CSP-clean, never inline style). Full-width stacked, 390px + RTL safe. */
/* Boxed card look, scoped to THIS panel only (modifier on the shared
   .compare-panel — every other panel on the page stays an unboxed,
   margin-separated section). Padding is the only inset; it does not cap the
   content's width — .wud-intro / .wud-rail2 / .wud-strips / .wud-axis still
   fill the card's full inner width (see the full-width overrides below). */
.wud-panel {
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding-block: 22px;
  padding-inline: 22px;
}

/* Full content width (overrides .compare-panel-intro's 74ch measure) — the WEU
   section is charts + text on ONE shared full-width canon axis, per owner directive. */
.wud-intro { max-width: none; }
.wud-warn { color: var(--accent); }

/* Mixed Hebrew×Greek — the not-comparable note above the two corpus blocks. */
.wud-mixed-note {
  display: flex; gap: 8px;
  font-family: var(--ui-font); font-size: 12.5px; line-height: 1.55;
  color: var(--text-dim); background: var(--bg-raised);
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 10px 14px; margin: 14px 0 0;
}
.wud-mixed-note strong { color: var(--text); }
.wud-mixed-note .compare-rail2-i { color: var(--accent); flex: 0 0 auto; font-size: 14px; }

.wud-block + .wud-block { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--border-soft); }
.wud-corpus { font-family: var(--ui-font); font-size: 13px; font-weight: 600; color: var(--text-dim); margin: 16px 0 8px; }

/* One-line, book-named, location-only takeaway. */
.wud-inshort {
  font-family: var(--ui-font); font-size: 14.5px; line-height: 1.5;
  color: var(--text); margin: 14px 0 16px;
}
.wud-inshort .wud-inshort-lemma { font-style: italic; color: var(--text); }
.wud-inshort strong { color: var(--text); font-weight: 700; }

/* Small-multiples strips: ALWAYS a single stacked column so every word's chart is the
   same width and its bars are dead-aligned under the ONE shared section axis below.
   Full-width by design (no max-width cap) — .wud-axis is a sibling in the same
   .wud-block, so both fill the same content column and stay equal-width. */
.wud-strips { display: flex; flex-direction: column; gap: 14px; }
.wud-strip { margin: 0; }
.wud-strip-caption { display: flex; align-items: baseline; gap: 8px; margin: 0 0 4px; flex-wrap: wrap; }
.wud-glyph { font-family: var(--greek-font); font-size: 18px; color: var(--wc, var(--text)); }
.wud-glyph.hebrew { font-family: var(--hebrew-font); }
.wud-translit { font-style: italic; font-size: 12.5px; color: var(--text-dim); }
.wud-strip-total { margin-inline-start: auto; font-family: var(--ui-font); font-size: 12px; color: var(--text-faint); white-space: nowrap; }

/* The mini column chart. preserveAspectRatio="none" stretches x to full width; the
   bars keep their pixel height. The dashed line marks the "expected" (1×) level.
   A fixed inline-end GUTTER (padding, matched on .wud-axis so the bars stay
   dead-aligned under their labels) reserves a column no bar can occupy, so the
   "expected" label sits clear of every bar — even the tallest rightmost one. */
.wud-chart { position: relative; height: 46px; padding-inline-end: 56px; }
.wud-chart-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.wud-bar { fill: var(--wc, var(--accent)); }
.wud-bar--thin { fill: transparent; stroke: var(--wc, var(--accent)); stroke-width: 1; stroke-dasharray: 2 2; vector-effect: non-scaling-stroke; }
.wud-expected-line { stroke: var(--text-faint); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.85; vector-effect: non-scaling-stroke; }
/* Sits in the reserved gutter, at the dashed line's height and just past its end —
   annotates the line, never overlaps or masks a bar, so NO opaque background. */
.wud-expected-label {
  position: absolute; inset-inline-end: 0; bottom: 33.33%;
  transform: translateY(50%); white-space: nowrap;
  font-family: var(--ui-font); font-size: 10px; color: var(--text-faint);
  pointer-events: none;
}

/* Shared section axis — flex so 4 (OT) or 5 (NT) columns auto-fit and wrap at 390px.
   Full-width, same as .wud-strips (no max-width cap), with the same matched
   inline-end gutter as .wud-chart so each label stays centered under its
   (now gutter-narrowed) bar column. */
.wud-axis { display: flex; list-style: none; margin: 4px 0 0; padding: 0; padding-inline-end: 56px; }
.wud-axis-label {
  flex: 1 1 0; min-width: 0; text-align: center;
  font-family: var(--ui-font); font-size: 11px; line-height: 1.25;
  color: var(--text-dim); overflow-wrap: anywhere;
}
.wud-axis-caption {
  font-family: var(--ui-font); font-size: 11.5px; line-height: 1.5;
  color: var(--text-faint); margin: 8px 0 0;
}

/* "Most verses in" locator + PINNED raw-count disclosure — the two travel together. */
.wud-mostin { margin: 14px 0 0; }
.wud-mostin-line { font-family: var(--ui-font); font-size: 13px; line-height: 1.6; color: var(--text); margin: 0; }
.wud-mostin-line .wud-glyph { font-size: 16px; }
.wud-mostin-label { color: var(--text-dim); font-weight: 600; }
.wud-mostin-book { color: var(--accent); text-decoration: none; white-space: nowrap; }
.wud-mostin-book:hover, .wud-mostin-book:focus { text-decoration: underline; }
.wud-mostin-book strong { font-weight: 700; }
.wud-mostin-sep { color: var(--text-faint); }
.wud-mostin-see { color: var(--text-faint); font-size: 12px; }
.wud-mostin-note { display: block; font-family: var(--ui-font); font-size: 11.5px; color: var(--text-faint); margin: 3px 0 0; }

/* Low-n word — a locator line, no chart. */
.wud-lown { font-family: var(--ui-font); font-size: 13px; line-height: 1.6; color: var(--text-dim); margin: 14px 0 0; }
.wud-lown .wud-glyph { font-size: 16px; }
.wud-lown strong { color: var(--text); }

/* Co-occurrence chip — the "sameness" counterweight, visible near the strips.
   display:flex (not inline-flex) + width:max-content lets it shrink-wrap to its
   content while still being a block box, so margin-inline:auto can center it in
   the now-full-width panel instead of hugging the start edge. */
.wud-cochip {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px;
  margin: 16px 0 0; margin-inline: auto; padding: 8px 14px;
  border: 1px solid var(--accent-border); border-radius: 999px;
  background: var(--accent-soft); color: var(--text);
  font-family: var(--ui-font); font-size: 13px; line-height: 1.4;
  text-decoration: none; width: max-content; max-width: 100%;
}
.wud-cochip:hover, .wud-cochip:focus { border-color: var(--accent); }
.wud-cochip-icon { color: var(--accent); flex: 0 0 auto; }
.wud-cochip-text { min-width: 0; }
.wud-cochip strong { color: var(--text); font-weight: 700; }
.wud-cochip-see { color: var(--accent); font-weight: 600; }
@media (hover: none), (pointer: coarse) { .wud-cochip { min-height: 44px; box-sizing: border-box; } }

/* Exact-numbers <details> — selectable table; scrolls INSIDE the disclosure. */
.wud-numbers { margin: 16px 0 0; }
.wud-numbers > summary { font-family: var(--ui-font); font-size: 13px; font-weight: 600; color: var(--accent); cursor: pointer; }
.wud-numbers > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wud-numbers-corpus { font-family: var(--ui-font); font-size: 12.5px; color: var(--text-dim); margin: 12px 0 6px; }
.wud-numbers-scroll { overflow-x: auto; margin-top: 8px; }
.wud-numbers-table { border-collapse: collapse; width: 100%; font-family: var(--ui-font); }
.wud-numbers-table th, .wud-numbers-table td { text-align: left; padding: 6px 12px 6px 0; border-bottom: 1px solid var(--border-soft); font-size: 13px; white-space: nowrap; vertical-align: top; }
.wud-numbers-table thead th { border-bottom: 2px solid var(--wc, var(--border)); }
.wud-numbers-table tbody th { font-weight: 600; color: var(--text); }
.wud-numbers-table .wud-glyph { font-size: 16px; }
.wud-numbers-translit { display: block; font-style: italic; font-size: 11px; color: var(--text-dim); }
.wud-numbers-ratio { color: var(--text-faint); }

/* Narrow-width breathing room (Fix 4): keep the caption's verse count and the
   "expected" gutter label off the panel's right edge at ~390px. Cosmetic only —
   no overflow (the gutter already clears the bars). */
@media (max-width: 420px) {
  .wud-strip-caption { padding-inline-end: 8px; }
  .wud-expected-label { inset-inline-end: 8px; }
  /* Tighten the card inset so its border/padding never pushes content off-screen
     at ~390px — the axis/bar gutters above already handle the narrow content. */
  .wud-panel { padding-inline: 14px; padding-block: 16px; }
}

/* Rail 2 standing note — a distribution difference is not a meaning difference. */
.compare-rail2 {
  display: flex; gap: 8px;
  font-family: var(--ui-font); font-size: 12.5px; line-height: 1.55;
  color: var(--text-dim); background: var(--bg-raised);
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 10px 14px; margin: 16px 0 0; max-width: 78ch;
}
.compare-rail2 strong { color: var(--text); }
.compare-rail2-i { color: var(--accent); flex: 0 0 auto; font-size: 14px; }
/* WEU Carson note spans the full panel width like the rest of its section. */
.wud-rail2 { max-width: none; }

/* Usage-in-context (#193d) — ≤2 text columns side by side; 3+ words stack (the
   .has-text tile list is single-column by design because 13px prose shreds in a
   tight grid). Each column is colour-keyed to its card. */
.compare-usage-cols { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 760px) { .compare-usage[data-words="2"] .compare-usage-cols { grid-template-columns: 1fr 1fr; } }
.compare-usage-col { border-top: 3px solid var(--wc, var(--border)); background: var(--bg-card); border-radius: var(--radius); padding: 12px 14px; }
.compare-usage-word { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin: 0 0 8px; }
.compare-usage-lemma { font-family: var(--greek-font); font-size: 20px; color: var(--text); }
.compare-usage-lemma.hebrew { font-family: var(--hebrew-font); }
.compare-usage-count { font-family: var(--ui-font); font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.compare-usage-more { margin: 8px 0 0; }
.compare-usage-more a { font-family: var(--ui-font); font-size: 13px; font-weight: 600; color: var(--accent); text-decoration: none; }
.compare-usage-more a:hover, .compare-usage-more a:focus { text-decoration: underline; }

/* Colour-keyed shared-verse + usage surfaces (#193e): tint the matched form to its
   source card's colour. Enhancement only (surfaces stay grouped + ordered). */
.verse-surface.compare-c0, .verse-surface.compare-c1,
.verse-surface.compare-c2, .verse-surface.compare-c3 { color: var(--wc); }

/* Compact 3–4-card layout on a phone so the bench stays comparable without a long
   scroll (design open-Q4, light touch). */
@media (max-width: 559px) {
  .compare-cards[data-count="3"] .compare-card,
  .compare-cards[data-count="4"] .compare-card { padding: 10px 12px; }
  .compare-cards[data-count="3"] .compare-lemma-row,
  .compare-cards[data-count="4"] .compare-lemma-row { min-height: 44px; }
  .compare-cards[data-count="3"] .compare-lemma,
  .compare-cards[data-count="4"] .compare-lemma { font-size: 26px; }
}

/* ============================================================================
   MORPHOLOGY (GRAMMAR) SEARCH (/morphology)
   A plain GET facet form (corpus radio + grammatical-attribute dropdowns + an
   optional book select) over a paginated verse-tile result list. Token-driven —
   reuses the .verse-tile / .verse-surfaces / .verse-tile-text and .search-pager
   primitives so it inherits the theme with no hard-coded colours.
   ============================================================================ */
.morphology-lede {
  font-family: var(--ui-font);
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-dim);
  max-width: 70ch;
  margin: 0 0 20px;
}
.morphology-lede strong { color: var(--text); }

/* Centered content-page hero (glyph + title + explainer) — matches the /about
   and /learn heroes. Pure CSS over unchanged, escaped SSR markup; the glyph is
   the decorative aleph-alpha mark (aria-hidden in the template). */
.morphology-hero {
  text-align: center;
  margin: 4px 0 24px;
}
.morphology-hero-glyph {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 14px;
  font-size: 30px;
  line-height: 1.2;
  color: var(--accent);
  margin: 0 0 4px;
}
.morphology-hero-aleph { font-family: var(--hebrew-font); }
.morphology-hero-alpha { font-family: var(--greek-font); }
.morphology-hero-dot { color: var(--accent-border); font-size: 20px; }
.morphology-hero h1,
.morphology-hero h2 {
  font-family: var(--reading-font);
  font-size: 32px;
  letter-spacing: 0;
  color: var(--text);
  text-align: center;
  margin: 4px 0 14px;
}
.morphology-hero .morphology-lede {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}
/* #160 — results-state hero compression. Once the reader has searched, drop the
   lede and shrink the glyph/title so the answer sits higher on the (mobile)
   viewport. Pure CSS over the SSR `morphology-page--results` class. */
.morphology-page--results .morphology-lede { display: none; }
.morphology-page--results .morphology-hero { margin: 4px 0 12px; }
.morphology-page--results .morphology-hero-glyph { font-size: 22px; }
.morphology-page--results .morphology-hero h1,
.morphology-page--results .morphology-hero h2 { font-size: 24px; margin: 2px 0 8px; }

/* #Pass-C — results-first hero readout. On a populated / empty search the hero
   stops being the centered aleph·alpha landing and becomes the ANSWER: a small
   kicker, the query-aware count headline (or the empty message), and the active-
   filter remove-chips. Left-aligned so it reads like a results header and aligns
   with the wide results column below. Spans full width above the grid. */
.morphology-hero--readout { text-align: left; }
/* The kicker is the hero heading inside .morphology-hero — an <h1> since
   2026-08-21, an <h2> before it — so the #160 compression rule
   `.morphology-page--results .morphology-hero h1` would blow it up to 24px — this
   more-specific selector (always present with the kicker, since readout ⇒
   morphology-page--results) keeps it a small label. The `.morphology-hero--readout`
   selector (#164 V1) additionally covers the FAIL-HONEST hero, which carries
   `.morphology-hero--readout` but NOT `.morphology-page--results` (result is null),
   so its kicker was losing to `.morphology-hero h1` (32px, centered). It is a no-op
   on the real-results / empty heroes (those already win via the
   `.morphology-page--results …` selector with identical declarations). */
.morphology-page--results .morphology-hero .morphology-kicker,
.morphology-hero--readout .morphology-kicker,
.morphology-kicker {
  font: 700 11px/1.2 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  /* The kicker is the hero heading, so it inherits `text-align: center` from
     `.morphology-hero h1`; force left so the eyebrow lines up with the
     left-aligned count / chips below it. */
  text-align: left;
  margin: 0 0 8px;
}
/* The count headline IS the results heading (kept query-aware, not a generic
   "Search Results"): a big accent number + the honest "verses" unit + the
   construction. .morphology-count already caps the number at 25px. Scoped as a
   descendant of the readout hero so it beats the equal-specificity, later-in-
   source base `.morphology-results-head` (15px/8px) without `!important`. */
.morphology-hero--readout .morphology-results-head {
  font-size: 17px;
  line-height: 1.35;
  margin: 0 0 4px;
}
.morphology-hero--readout .morphology-empty {
  font-size: 15.5px;
  color: var(--text-dim);
  margin: 0;
}
.morphology-hero--readout .morphology-cooccur-note { margin: 6px 0 0; }

/* #169 Fix 3 — a one-line gloss of the leading facet term directly under the hero
   count, so a phone reader gets the term's meaning without scrolling to the rail
   glossary (which sits below all the results on a narrow layout). Hidden at the
   rail breakpoint (>=1080px), where that glossary is already visible beside the
   results — no desktop duplication. Matches the .morphology-search-grid grid
   breakpoint. */
.morph-hero-gloss {
  font: 13px/1.5 var(--ui-font);
  color: var(--text-dim);
  margin: 4px 0 0;
  max-width: 72ch;
}
.morph-hero-gloss strong { color: var(--text); font-weight: 600; }
@media (min-width: 1080px) {
  .morph-hero-gloss { display: none; }
}

.morphology-unavailable {
  font-family: var(--ui-font);
  font-size: 14px;
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  padding: 12px 16px;
}
.morphology-unavailable code {
  font-family: var(--mono-font);
  font-size: 12.5px;
}

/* The facet form — a bordered card so the controls read as one unit. */
.morphology-form {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 28px;
}

/* #Pass-C — the collapsible "Refine" wrapper around the FULL faceted form. Native
   <details>, no JS: OPEN on the bare + 0-hit states (server-set), CLOSED on a
   populated results view. The <summary> is a full-width bar that reads as one
   card with the form below it when open (matched borders, joined radii); when
   closed it's the single one-line control the results-first layout demotes the
   form to. Tap target >=40px via padding. */
.morphology-refine { margin: 0; }
.morphology-refine > .morphology-form { margin-bottom: 0; }
.morphology-refine-summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  cursor: pointer;
  list-style: none;
  font: 600 14px/1.35 var(--ui-font);
  color: var(--text);
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 13px 16px;
}
.morphology-refine-summary::-webkit-details-marker { display: none; }
.morphology-refine-summary:hover { border-color: var(--border); }
.morphology-refine-summary:focus-visible {
  outline: none;
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Open: the summary loses its bottom radius and the form loses its top border +
   top radius so the two read as a single card. */
.morphology-refine[open] > .morphology-refine-summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.morphology-refine[open] > .morphology-form {
  border-top: none;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.morphology-refine-summary-label { font-weight: 700; color: var(--accent); }
.morphology-refine-summary-bits {
  color: var(--text-dim);
  min-width: 0;
  overflow-wrap: anywhere;
}
.morphology-refine-summary-cta {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--text-dim);
}
/* CSS chevron that flips on open (pure presentation — the state is the native
   <details> open attribute; no JS, no icon font). */
.morphology-refine-summary-cta::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.15s ease;
}
.morphology-refine[open] > .morphology-refine-summary .morphology-refine-summary-cta::after {
  transform: rotate(-135deg);
}

/* #149 — /morphology split layout. The primary search form (left) beside a rail
   of navigational panels (right). Flex column by default so it stacks (form,
   then rail) on narrow / no-JS / phone widths; a 2-col grid at >=1080px,
   mirroring the proven .verse-study-grid.has-rail pattern. The grid wrapper
   carries the bottom margin the form used to own (so the flex gap doesn't stack
   on top of the form's own margin). */
/* #Pass-C — results-first grid (void-fix). The container holds TWO children in
   source order: a left-column wrapper (.morphology-search-main, which stacks the
   collapsible refine <details> over the results-region in normal flow) and the
   rail. On phones (flex column) everything stacks in reading order — refine,
   results, then rail — with no `order:` hack. On desktop it becomes a 2-column
   grid: the wrapper is the WIDE primary column, the rail the fixed right column.
   Because the wrapper is only as tall as its OWN content, a tall rail can no
   longer inflate the left column's row track — the earlier
   "refine rail / results rail" named-areas grid let the row-spanning rail stretch
   the short refine row, opening an empty void on 1-hit / 0-hit results. Decoupling
   the rail from the left column's tracks is the fix; `align-items: start` keeps
   each column top-aligned. */
.morphology-search-grid {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-bottom: 28px;
}
.morphology-search-main {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
.morphology-search-main > .morphology-refine { margin-bottom: 0; }
/* Sit flush in the flex column — the flex `gap` owns the spacing (no collapsed
   child margins fighting it). */
.morphology-results-region { min-width: 0; }
.morphology-results-region > :first-child { margin-top: 0; }

@media (min-width: 1080px) {
  .morphology-search-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 24px 30px;
    align-items: start;
  }
  /* Preserve the old cross-row 24px refine→results spacing now that the two
     stack inside the wrapper rather than across two grid rows. */
  .morphology-search-main { gap: 24px; }
}
/* At the wide content cap (.app--wide = 1280px) the rail gets a touch more room,
   the .verse-study-grid precedent. */
@media (min-width: 1280px) {
  .morphology-search-grid { grid-template-columns: minmax(0, 1fr) 340px; }
}

/* The rail — a column of navigational panels. Panels stack with a gap so more
   siblings can be appended cleanly (four ship later). Non-sticky. */
.morphology-rail {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
/* A rail panel card — matches the .morphology-form card look. */
.morph-rail-panel {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 16px;
}
/* The Share panel (relocated to the top of the rail, relabeled from "Cite this
   search") — it already carries its own card chrome (border/radius/background)
   from the /w/ page, matching
   .morph-rail-panel closely enough that dropping it in as-is reads as one clean
   first panel (no nested card-in-a-card border). The only misfit is its /w/-page
   `margin-top: 12px` (meant to separate it from the hero above it there); as the
   rail's first child that would just push it 12px below the aside's top edge,
   since `.morphology-rail`'s own flex `gap` already provides the spacing to the
   next panel. Zero it here so the card sits flush with its siblings. */
.morphology-rail > .strongs-cite {
  margin-top: 0;
}
/* Rail-panel heads: a gold --accent glyph in an --accent-soft rounded badge next
   to a bold title, matching the site's panel-heading convention (.cross-refs-head /
   .commentary-head) but scaled down for the narrow 340px rail. */
.morph-rail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  margin: 0 0 12px;
  font: 700 15.5px/1.2 var(--ui-font);
  color: var(--text);
}
.morph-rail-head-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--accent);
}
.morph-rail-head-icon svg { width: 18px; height: 18px; }
.morph-rail-intro {
  font: 13.5px/1.5 var(--ui-font);
  color: var(--text-dim);
  margin: 0 0 12px;
}
.morph-rail-recipes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.morphology-corpus {
  border: none;
  padding: 0;
  margin: 0 0 18px;
}
/* Corpus legend + facet-group subheads are the form's SECTION TITLES — promoted to a
   clear heading tier (sentence-case, full-strength text, a touch larger) so they
   visibly outrank the dim all-caps .morphology-facet-label controls beneath them. The
   step DOWN to those labels is what gives the form its hierarchy. Hierarchy is by
   weight/brightness only — NO accent/gold here. (The rail-panel heads have their own
   gold-glyph treatment — see .morph-rail-head below.) */
.morphology-corpus legend,
.morphology-group-head {
  font: 700 13px/1.25 var(--ui-font);
  color: var(--text);
  padding: 0;
  margin: 0 0 10px;
}

/* Corpus picker — CSS-styled NATIVE radios as pills. The <input> is the real
   control, VISUALLY CLIPPED via .visually-hidden (NOT display:none, which would
   kill focus + screen-reader semantics); the adjacent .morph-pill-face is the
   visible pill, driven entirely by the radio's :checked / :focus-visible state.
   Same no-JS clipped-input pattern as the compare version picker (.cmp-pill). */
.morphology-corpus-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.morph-pill { display: inline-flex; margin: 0; cursor: pointer; }
.morph-pill-face {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 15px; border-radius: 999px;
  font: 500 13.5px/1.1 var(--ui-font); color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  transition: background 120ms, border-color 120ms, color 120ms;
  user-select: none; white-space: nowrap;
}
.morph-pill:hover .morph-pill-face { color: var(--text); border-color: var(--border); }
.morph-pill-input:checked + .morph-pill-face {
  color: var(--accent); font-weight: 600;
  background: var(--accent-soft); border-color: var(--accent-border);
}
.morph-pill-input:checked + .morph-pill-face::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); flex: none;
}
/* Focus ring follows the (clipped) radio onto the visible face. */
.morph-pill-input:focus-visible + .morph-pill-face {
  outline: none; box-shadow: 0 0 0 3px var(--accent-soft); border-color: var(--accent-border);
}

/* Grouped facet layout (P1-5) — part-of-speech/form, other attributes, passage.
   Each group is a borderless <fieldset> with a legend subhead; the controls
   inside reuse the .morphology-facets grid. */
.morphology-group { border: 0; padding: 0; margin: 0 0 18px; min-width: 0; }
.morphology-group:last-of-type { margin-bottom: 16px; }

.morphology-facets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px 16px;
}
.morphology-facet {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}
.morphology-facet-label {
  display: block;
  font: 600 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}
/* Facet dropdowns (#143) — one native single-<select> per facet, matching the
   Book <select> (same rule) exactly. width:100% + min-width:0 makes every select
   fill its grid cell and TRUNCATE a long option (e.g. "Participle Active (12,345)")
   natively rather than blowing the column out. Works with NO JS. */
.morphology-facet select {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  font-family: var(--ui-font);
  font-size: 14px;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  min-height: 40px;
}
.morphology-facet select:focus {
  outline: none;
  border-color: var(--accent-border);
}

/* #172 chapter-range scope — the two "From / To chapter" number inputs sit in a
   compact two-up row under the Book <select>. Its OWN grid (not .morphology-facets)
   so the <=560px single-column rule below doesn't stack the two short inputs; capped
   width keeps them from stretching the full form. Reuses the .morphology-facet
   label/gap tokens; the inputs reuse .search-input, which fills the cell via the
   flex-column stretch (same as the Strong's input). Wraps cleanly at 390px. */
.morphology-chapter-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 16px;
  max-width: 360px;
  margin-top: 12px;
}
.morphology-facet--chapter .search-input {
  width: 100%;
  min-width: 0;
  /* Keep the 16px anti-zoom floor (matches the Strong's .search-input) so iOS
     doesn't zoom on focus; the tighter padding keeps the compact input height. */
  font-size: 16px;
  padding: 9px 12px;
}
.morphology-chapter-hint { margin-top: 8px; }

.morphology-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}
.morphology-reset {
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: none;
}
.morphology-reset:hover, .morphology-reset:focus { color: var(--accent); text-decoration: underline; }

.morphology-prompt,
.morphology-empty {
  font-family: var(--ui-font);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 0 0 8px;
}
.morphology-empty strong { color: var(--text); }
/* #164 V3b — the "adjust your filters" link is the PRIMARY recovery affordance in
   the fail-honest guidance state. Its inline ~22px height is below the 44px touch
   floor, so on coarse pointers give it an inline-block hit area (padding-block +
   min-height, border-box). Scoped to `pointer: coarse` so desktop reading density
   is untouched; the link stays inline in the sentence flow. */
@media (pointer: coarse) {
  .morphology-empty a {
    display: inline-block;
    min-height: 44px;
    padding-block: 10px;
  }
}

/* Hero worked examples (#144b) — real pointed-Hebrew / accented-Greek specimens
   above the fold, so the tool shows the script it searches before results load. */
.morphology-hero-examples {
  list-style: none;
  /* #169 Fix 2 — centre the equal-width pair (max-width matching the lede) so the
     cards don't stretch edge-to-edge on the wide layout. */
  margin: 0 auto 22px;
  max-width: 720px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 14px;
}
.morph-hero-eg {
  display: flex;
  align-items: baseline;
  gap: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 9px 14px;
  /* #169 Fix 2 — the two cards share the row equally on wide screens. */
  flex: 1 1 0;
  min-width: 0;
}
.morph-hero-glyph { font-size: 24px; line-height: 1.3; color: var(--text); }
.morph-hero-glyph.hebrew { font-family: var(--hebrew-font); }
.morph-hero-glyph.greek { font-family: var(--greek-font); }
.morph-hero-eg-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.morph-hero-eg-parse { font: 600 12.5px/1.35 var(--ui-font); color: var(--accent); }
/* #169 Fix 2 — plain-English subtitle under the jargon parse line; a quieter,
   smaller cue so the beginner gets the meaning without the grammar terms. */
.morph-hero-eg-plain { font: 12.5px/1.4 var(--ui-font); color: var(--text-dim); }
.morph-hero-eg-ref { font: 12px/1.3 var(--ui-font); color: var(--text-dim); text-decoration: none; }
.morph-hero-eg-ref:hover, .morph-hero-eg-ref:focus { color: var(--accent); text-decoration: underline; }

/* Worked-example query links — one-click real /morphology queries that each
   return live hits. Now the rows of the Grammar recipes rail (#149); the old
   centered `.morphology-worked` container + its `-head`/`-list` rules were
   removed with the in-main block, but the link look is reused verbatim. */
.morph-worked-link {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 10px 14px;
  font: 600 14px/1.35 var(--ui-font);
  color: var(--text);
  text-decoration: none;
}
.morph-worked-link:hover, .morph-worked-link:focus {
  border-color: var(--accent-border);
  color: var(--accent);
}
.morph-worked-arrow { color: var(--accent); flex: 0 0 auto; }

/* "Explore the corpus" mini-index (#151) — the third rail panel's list of
   part-of-speech browse links (label + corpus-wide distinct-verse count). Borderless
   rows INSIDE the already-carded .morph-rail-panel (no card-in-a-card border), with a
   subtle hover/focus-visible background + accent text mirroring .morph-worked-link's
   hover tokens; the count stays muted + tabular so the numbers align. */
.morph-explore-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.morph-explore-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 8px;
  border-radius: 6px;
  font: 500 13.5px/1.4 var(--ui-font);
  color: var(--text);
  text-decoration: none;
  transition: background 120ms, color 120ms;
}
.morph-explore-link:hover, .morph-explore-link:focus-visible {
  background: var(--bg-raised);
  color: var(--accent);
  outline: none;
}
.morph-explore-link:focus-visible {
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.morph-explore-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.morph-explore-count {
  flex: 0 0 auto;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
.morph-explore-more {
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text-faint);
  margin: 6px 0 0;
}

/* "Related study tools" cross-nav (#152) — the LAST rail item, a static
   internal-link mesh. Now a full peer panel: the markup carries .morph-rail-panel
   alongside .morph-rail-related, so it gets the same card chrome (--bg-card /
   --border-soft / --radius / 16px padding) as the three panels above — promoted just
   as the glossary card was. .morph-rail-related therefore no longer needs its own
   border/padding rule (that would fight the card chrome); it survives only as the
   semantic hook for the inner list styling below. Each row is a compact two-line
   block (tool name + muted one-line descriptor), reusing the .morph-explore-link
   hover tokens. */
.morph-related-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.morph-related-link {
  display: flex;
  flex-direction: column;
  padding: 6px 8px;
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  transition: background 120ms;
}
.morph-related-link:hover, .morph-related-link:focus-visible {
  background: var(--bg-raised);
  outline: none;
}
.morph-related-link:focus-visible {
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.morph-related-label {
  font: 600 13px/1.35 var(--ui-font);
  color: var(--text);
}
.morph-related-desc {
  font: 400 12px/1.35 var(--ui-font);
  color: var(--text-faint);
  overflow-wrap: anywhere;
}

/* The reverse "drill these forms" CTA (#144d) used to render here as
   `.morphology-drill` / `.morphology-drill-link`; it now lives as the first
   item of the "Related study tools" rail panel (plain `.morph-related-link`,
   no dedicated CSS needed) — see views/morphology.ejs. */

.morphology-results-head {
  font-family: var(--ui-font);
  font-size: 15px;
  color: var(--text);
  margin: 0 0 8px;
}
/* P0-2: the count is a capped headline — accent on the NUMBER ONLY (the summary
   text stays default-coloured). Capped at 25px so the specimen's ~30px script
   glyph stays the largest thing in the results zone. */
.morphology-count {
  color: var(--accent);
  font-weight: 700;
  font-size: 25px;
  line-height: 1.15;
}
.morphology-results-head strong { color: var(--text); }
/* #173 subordinate word-instance count under the hero verse count. Deliberately
   smaller/lighter than .morphology-count (25px/accent) so the DISTINCT-VERSE count
   stays visually primary; muted text keeps it legible at 390px. */
.morphology-occurrences {
  font-family: var(--ui-font);
  font-size: .95rem;
  line-height: 1.4;
  color: var(--text-dim);
  margin: .2rem 0 0;
  max-width: 72ch;
}
.morphology-occurrences-count { font-weight: 600; color: var(--text); }
.morphology-version-note {
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-faint);
  margin: 0 0 14px;
  max-width: none;
}

/* Book group divider in the verse list (P0-3) — a slim uppercase rule that
   headers each canonical-order book run. It is a plain <li> (a divider, not a
   link) and carries dir="ltr" in the markup so the English name never bleeds RTL
   over the Hebrew tiles below it. */
.morph-group-head {
  list-style: none;
  margin: 12px 0 2px;
  padding: 0 2px 4px;
  font: 700 11px/1.3 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  text-align: left;
  border-bottom: 1px solid var(--border-soft);
}
.morph-group-head:first-child { margin-top: 0; }

.morph-tool-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  font: 600 12.5px/1 var(--ui-font);
  color: var(--accent);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
.morph-tool-btn:hover,
.morph-tool-btn:focus-visible,
.morph-tool-btn:focus {
  color: var(--on-accent);
  border-color: var(--accent);
  background: var(--accent);
  outline: none;
}
/* Copy references now sits in the Share panel's second `.strongs-cite-actions`
   row alongside Copy citation / Copy permalink / the Download links — align
   its pill height with its `.strongs-cite-btn` row-mates so the mixed button
   styles read as one consistent row. */
.strongs-cite-actions .morph-tool-btn {
  min-height: 29px;
}

/* Result tiles — same look as the /w concordance tiles, but their base styling
   was scoped to .strongs-verse-list a, so it is mirrored here for the
   morphology list (single readable column, since tiles carry verse text). */
.morphology-verse-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px;
}
.morphology-verse-list li { margin: 0; }
/* #163 — positioning context for the absolutely-pinned per-tile "Examine" control
   (see the .verse-tile-examine block below). Scoped to direct-child <li> so it
   covers the result tiles + the .morph-group-head dividers but never leaks into a
   nested list; the region <div> stays in normal flow and still opens beneath the
   <a> since the button is taken out of flow. */
.morphology-verse-list > li { position: relative; }
/* P0-8: lead each tile with a scannable reference — bump the ref column so it
   reads down the left edge. Scoped to the morphology list so the /w/ concordance
   tiles (`.strongs-verse-list .verse-ref`, still 11px) are untouched. The surface
   glyph (`.verse-surfaces`) is deliberately NOT demoted — each tile is a different
   inflected form, informative payload. */
.morphology-verse-list .verse-ref {
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
}
.morphology-verse-list a.verse-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  text-decoration: none;
  transition: border-color 120ms, color 120ms, background 120ms;
}
.morphology-verse-list a.verse-tile:hover,
.morphology-verse-list a.verse-tile:focus {
  border-color: var(--accent-border);
  color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.morphology-verse-list a.verse-tile:hover .verse-tile-text,
.morphology-verse-list a.verse-tile:focus .verse-tile-text { color: var(--accent); }

/* Origin tile (#138) — the verse the reader arrived from via a grammar
   deep-link, floated to the top of the results. A subtle gold left-accent + a
   faint tint so it reads as "yours" without shouting; the meaning is carried by
   the visible text badge below (not colour alone) for AT / no-JS. */
.morphology-verse-list a.verse-tile--origin {
  border-color: var(--accent-border);
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
}
.morphology-verse-list a.verse-tile--origin:hover { border-left-color: var(--accent); }
.verse-tile-origin-badge {
  display: inline-block;
  align-self: flex-start;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  font-family: var(--ui-font);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--accent);
}

.morphology-other-search {
  font-family: var(--ui-font);
  font-size: 13.5px;
  color: var(--text-dim);
  margin: 22px 0 0;
}
.morphology-other-search a { color: var(--accent); text-decoration: none; font-weight: 600; }
.morphology-other-search a:hover, .morphology-other-search a:focus { text-decoration: underline; }

@media (max-width: 560px) {
  /* Each facet is now a full-width native <select>, so stack them one per row on
     a phone (390px) — a 2-up grid would crush the option text. */
  .morphology-facets { grid-template-columns: 1fr; }
}

/* #169 Fix 2 — stack the two hero example cards vertically on a phone. Above this
   width they sit side by side as an equal-width pair (flex: 1 1 0). Column
   direction + the default cross-axis stretch gives each card the full width. */
@media (max-width: 420px) {
  .morphology-hero-examples { flex-direction: column; }
  .morph-hero-eg { flex: 0 0 auto; }
}

/* Honesty disclosure inside the form (proper-noun gap). */
.morphology-disclose {
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-faint);
  margin: 0 0 16px;
  max-width: 72ch;
}
.morphology-disclose a { color: var(--text-dim); text-decoration: underline; }
.morphology-disclose a:hover, .morphology-disclose a:focus { color: var(--accent); }

/* Gold divider separating the Active-filters chips from the relocated
   result-interpretation disclosures inside the rail panel (hotfix, v0.7.147).
   A single thin accent-colored rule, not a boxed sub-card — .morphology-disclose
   keeps its own font/size/color styling untouched; only the panel itself
   (.morph-rail-panel) provides the card chrome. */
.morph-rail-divider {
  border-top: 1px solid var(--accent);
  margin: 14px 0 12px;
}
/* Zero the last disclosure paragraph's bottom margin so it doesn't stack with
   the panel's own bottom padding. */
.morph-rail-panel .morphology-disclose:last-child {
  margin-bottom: 0;
}

/* Validation "did you mean…" notice (task #134): a dropped facet value, a
   mistyped param, or a wrong-testament book. Restrained amber info panel so the
   surviving-facet count is never read as the full query the reader intended. */
.morphology-notice {
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-left-width: 3px;
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 0 0 20px;
  color: var(--warn);
  font-family: var(--ui-font);
  font-size: 13.5px;
  line-height: 1.5;
}
.morphology-notice-list { list-style: none; margin: 0; padding: 0; }
.morphology-notice-item + .morphology-notice-item { margin-top: 6px; }
.morphology-notice strong { color: var(--text); font-weight: 600; }
.morphology-notice code {
  font-family: var(--mono-font, monospace);
  font-size: 0.92em;
}

/* Grammar glossary / legend (#150) — RELOCATED into the /morphology rail as the
   second navigational card, so it now matches .morph-rail-panel's card look
   (--bg-card / --border-soft / --radius). Still a native <details> teaching
   reference (works with NO JS). No bottom margin — the rail's flex gap owns the
   spacing between it and the recipes panel above. */
/* Plain content inside a .morph-rail-panel (V3) — the panel now provides the card
   chrome (bg/border/radius/padding), so the glossary carries none of its own to
   avoid a card-in-a-card double border/background. */
.morphology-glossary {
  margin: 0;
}
.morphology-glossary-summary {
  font: 600 13.5px/1.4 var(--ui-font);
  color: var(--text);
  cursor: pointer;
  padding: 10px 0;
  list-style-position: inside;
}
.morphology-glossary-summary:hover { color: var(--accent); }
/* Single column — the glossary now lives in a ~320-340px rail, not full width, so
   the groups stack with a tightened vertical rhythm instead of an auto-fill grid. */
.morphology-glossary-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 4px 0 12px;
}
.morphology-glossary-facet {
  font: 700 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0 0 6px;
}
.morphology-glossary-list { margin: 0; }
.morphology-glossary-list dt {
  font: 600 12.5px/1.4 var(--ui-font);
  color: var(--text);
  margin-top: 6px;
}
.morphology-glossary-list dd {
  font-family: var(--ui-font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 1px 0 0;
}

/* Active-filter remove chips — the no-JS faceted-refine gesture. */
.morphology-chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: 0;
  margin: 0;
}
.morph-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text);
  text-decoration: none;
  transition: border-color 120ms, background 120ms, color 120ms;
}
.morph-chip:hover, .morph-chip:focus {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}
.morph-chip--book .morph-chip-val { font-style: italic; }
/* #172 chapter-range chip — same look as the book chip (italic scope descriptor),
   rendered immediately after it in the active-filter strip. */
.morph-chip--chapter .morph-chip-val { font-style: italic; }
/* Set-B (same-verse co-occurrence, #143) chip — visually distinct from a primary
   filter chip: a dashed, neutral-tinted pill with a small "also" tag. */
.morph-chip--co {
  background: var(--bg-raised);
  border-style: dashed;
  border-color: var(--border);
}
.morph-chip--co:hover, .morph-chip--co:focus { border-color: var(--accent); }
.morph-chip-co-label {
  font: 700 9.5px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.morph-chip-x {
  font-size: 15px;
  line-height: 1;
  color: var(--text-faint);
}
.morph-chip:hover .morph-chip-x, .morph-chip:focus .morph-chip-x { color: var(--accent); }

/* #171 Tier 4a — OR-within-a-facet multi-select pills. Progressive enhancement
   over the native single <select> (which stays the no-JS baseline): each picked
   value becomes a removable pill backed by a hidden input, so submit yields
   ?stem=A&stem=B. Styled to match the active-filter .morph-chip pills. */
.morph-value-pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0;
  margin: 2px 0 0;
}
.morph-value-pills:empty { display: none; } /* collapse — no dead space, no gap slot */
.morph-value-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 4px 4px 10px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text);
}
.morph-value-pill-label { line-height: 1.2; }
.morph-value-pill-x {
  -webkit-appearance: none;
  appearance: none;
  position: relative; /* anchors the coarse-pointer 44x44 ::after hit-area overlay */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  margin: 0;
  padding: 0 2px;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  color: var(--text-faint);
  border-radius: 999px;
  transition: color 120ms;
}
.morph-value-pill-x:hover { color: var(--accent); }
.morph-value-pill-x:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  color: var(--accent);
}

/* #176 per-word EXCLUSION — the negation visual language. A muted error (red)
   tint distinguishes an exclusion from a positive filter (gold accent-soft) and a
   co-occurrence (neutral dashed). Placed AFTER .morph-chip / .morph-chip--co so an
   equal-specificity override wins; a set-B exclusion combines
   .morph-chip--co (dashed) + .morph-chip--not (red tint). */
.morph-chip--not {
  background: var(--error-soft);
  border-color: var(--error-border);
}
.morph-chip--not:hover, .morph-chip--not:focus { border-color: var(--error); color: var(--error); }
.morph-chip--not:hover .morph-chip-x, .morph-chip--not:focus .morph-chip-x { color: var(--error); }
/* Exclude PILL (in-form) — the counterpart of the exclusion chip; its label reads
   "not Qal", so the tint reinforces the negation. Same geometry as .morph-value-pill. */
.morph-value-pill--not {
  background: var(--error-soft);
  border-color: var(--error-border);
}

/* #176 Fix 3 (CLS) / #179 — reserved slot shared by the SSR no-JS Exclude <select>
   and the JS-created Match/Exclude toggle that REPLACES it on hydration. The
   min-height holds BOTH controls at the same box height, so the swap grows nothing
   (the bare-landing reflow #176 measured: +140px desktop / +513px mobile). Both
   inner controls are SHORTER than the min-height, so the slot renders at exactly
   30px (desktop) / 52px (touch) in either state — height-neutral. display:flex so
   the injected toggle's own 4px top margin is honored (not collapsed). #179: the
   slot is no longer empty with no-JS — it ships a real exclude control (see
   .morph-facet-exclude below), so exclusion is now a no-JS capability. The empty
   pills <ul> that follows collapses to 0 (`.morph-value-pills:empty`). */
.morph-facet-mode-slot {
  display: flex;
  align-items: flex-start;
  min-height: 30px;
}
@media (hover: none), (pointer: coarse) {
  /* Touch bumps each toggle button / exclude select to a 44px tap target, so reserve more. */
  .morph-facet-mode-slot { min-height: 52px; }
}

/* #179 — SSR no-JS Exclude control. A REAL native exclude <select> a no-JS reader
   uses to CONSTRUCT a `<facet>_not=` exclusion (the only facet control that had no
   server-rendered input). It lives INSIDE .morph-facet-mode-slot, so it shares the
   slot's reserved min-height with the JS Match/Exclude toggle that replaces it on
   hydration — the swap is height-neutral (the #176/#178 CLS win holds). Styled as a
   compact, QUIET secondary control (smaller + dimmer than the primary match <select>
   above it) that still plainly reads "Exclude". The overrides beat the base
   `.morphology-facet select` (0,1,1) via the two-class
   `.morph-facet-mode-slot .morph-facet-exclude-select` (0,2,0), independent of source
   order. Compact height keeps it under the 30px slot; no top margin needed. */
.morph-facet-exclude {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  margin-top: 2px;
}
.morph-facet-exclude-label {
  flex: none;
  font: 600 10px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
}
.morph-facet-mode-slot .morph-facet-exclude-select {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  min-height: 24px;
  padding: 3px 8px;
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--text-dim);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.morph-facet-mode-slot .morph-facet-exclude-select:focus {
  outline: none;
  border-color: var(--accent-border);
}
@media (hover: none), (pointer: coarse) {
  /* Match the slot's 52px touch reserve — a 44px tap target for the select, so the
     SSR control and the JS toggle both fit the taller touch slot (CLS-neutral). */
  .morph-facet-mode-slot .morph-facet-exclude-select { min-height: 44px; }
}

/* #176 Match / Exclude segmented toggle (JS-created, per facet). Two quiet buttons;
   the pressed segment fills — Match with the gold accent, Exclude with the negative
   accent to match its pills. No inline styles (CSP). */
.morph-facet-mode {
  display: inline-flex;
  margin: 4px 0 0;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-raised);
}
.morph-facet-mode-btn {
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  margin: 0;
  padding: 3px 11px;
  background: transparent;
  color: var(--text-faint);
  font: 600 11.5px/1.5 var(--ui-font);
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.morph-facet-mode-btn + .morph-facet-mode-btn { border-left: 1px solid var(--border); }
.morph-facet-mode-btn:hover { color: var(--text); }
/* Pressed Match — gold fill + gold text + a subtle inset ring so the DEFAULT mode
   reads clearly at rest, closer in weight to the loud pressed-Exclude (#176 Fix 4:
   the prior `--accent-soft` + default text was barely distinguishable). */
.morph-facet-mode-btn[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-border);
}
/* The Exclude segment (last child) uses the negative accent when active; it drops
   the Match ring (its brighter red text already carries the weight). */
.morph-facet-mode-btn:last-child[aria-pressed="true"] {
  background: var(--error-soft);
  color: var(--error);
  box-shadow: none;
}
.morph-facet-mode-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* Comfortable >=44px tap targets on touch (rendered-UX audit V2). Same
   pointer-coarse pattern as the /w concordance controls (#92 Item 3): these
   morphology controls measure 25-33px tall on a phone, under the 44x44
   WCAG/iOS minimum. box-sizing:border-box (global) makes min-height the OUTER
   box; each control's existing align-items:center keeps its content centred, so
   the visible styling is unchanged. Desktop density (the base rules) is
   untouched — this widens the hit area on coarse pointers only. */
@media (hover: none), (pointer: coarse) {
  .morph-pill-face,
  .morph-chip,
  .morph-worked-link,
  .morph-explore-link,
  .morph-related-link,
  .morphology-glossary-summary,
  .morph-tool-btn,
  .morph-facet-mode-btn {
    min-height: 44px;
  }
  /* The remove-× keeps a >=44x44 tap zone WITHOUT growing the pill's layout box.
     A min-height/min-width here would inflate the flex row to ~54px tall (chunky);
     instead expand only the HIT AREA with a transparent centred overlay — the
     #163/#92 pointer-coarse pattern. The pill visual stays compact. A little extra
     pill padding + a wider inter-pill gap keep two stacked pills' 44px hit zones
     from overlapping across the row gap (centres land ~47px apart >= 44). */
  .morph-value-pills { gap: 10px; }
  .morph-value-pill { padding-top: 10px; padding-bottom: 10px; }
  .morph-value-pill-x::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
  }
}

/* Same-verse co-occurrence panel (#143) — a native <details> card in the form,
   styled like the grammar glossary so it reads as a secondary, optional block. */
.morphology-cooccur {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 4px 16px;
  margin: 0 0 18px;
}
.morphology-cooccur-summary {
  font: 600 13.5px/1.4 var(--ui-font);
  color: var(--text);
  cursor: pointer;
  padding: 10px 0;
  list-style-position: inside;
}
.morphology-cooccur-summary:hover { color: var(--accent); }
.morphology-cooccur[open] > .morphology-cooccur-summary { color: var(--accent); margin-bottom: 4px; }
.morphology-cooccur-body { padding: 4px 0 12px; }
/* Disclosure line under the co-occurrence result heading. */
.morphology-cooccur-note {
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-faint);
  margin: 0 0 14px;
  max-width: 72ch;
}
.morphology-cooccur-note strong { color: var(--text-dim); }

/* Contextual definitions for the selected categories — bare text, no box
   (hotfix, v0.7.149). This block always sits between two .morph-rail-divider
   gold lines in the Active-filters rail panel (its only usage site), so the
   dividers' own margins (14px top / 12px bottom) define the section breaks;
   the block carries zero margin of its own so it doesn't double-stack with
   them, matching the chips->divider and divider->disclosure spacing already
   used elsewhere in the panel. Previously a boxed callout (background,
   left border, border-radius, padding) — that chrome is gone; only the
   text styling below (bold term + definition line) is unchanged. */
.morphology-context {
  margin: 0;
}
.morphology-context-line {
  font-family: var(--ui-font);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 0;
}
.morphology-context-line + .morphology-context-line { margin-top: 5px; }
.morphology-context-term { color: var(--text); font-weight: 700; }

/* Worked-specimen card — the example-first result. */
.morph-specimen {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 0 0 18px;
}
.morph-specimen-cap {
  font: 700 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.morph-specimen-ref { color: var(--accent); text-decoration: none; }
.morph-specimen-ref:hover, .morph-specimen-ref:focus { text-decoration: underline; }
.morph-specimen-form {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 12px;
  margin: 0 0 6px;
}
.morph-specimen-glyph { font-size: 30px; line-height: 1.2; color: var(--text); }
.morph-specimen-translit {
  font-family: var(--ui-font);
  font-size: 14px;
  font-style: italic;
  color: var(--text-dim);
}
.morph-specimen-parse {
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  margin: 0 0 6px;
}
/* #169 Fix 4 — plain-English glosses of each parse term, under the jargon parse
   line. Kept subtle (small, muted definition) so it teaches without overpowering
   the specimen. Definitions are verbatim from grammar-glossary.js. */
.morph-specimen-glosses {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.morph-specimen-gloss-term { font: 600 12px/1.4 var(--ui-font); color: var(--text); }
.morph-specimen-gloss-def { font: 12px/1.4 var(--ui-font); color: var(--text-faint); }
.morph-specimen-lex {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  font-family: var(--ui-font);
  font-size: 13.5px;
  color: var(--text-dim);
  margin: 0 0 8px;
}
.morph-specimen-lex-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
}
.morph-specimen-lemma { font-size: 16px; color: var(--text); }
.morph-specimen-gloss { color: var(--text); }
.morph-specimen-strongs {
  font-family: var(--mono-font);
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
}
.morph-specimen-strongs:hover, .morph-specimen-strongs:focus { color: var(--accent); border-color: var(--accent-border); }
.morph-specimen-text {
  font-family: var(--ui-font);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-dim);
  margin: 0;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}
/* Full verse in context (#144e) — the whole original-language verse with the
   matched form(s) marked. Only the ORIGINAL script is highlighted; the English
   (.morph-specimen-text) stays un-highlighted (no word-level alignment). The
   matched cue reuses the accent-soft fill of the .verse-surface.matched
   convention (the honest-highlight precedent). box-decoration-break keeps a
   wrapped match's fill intact across line breaks. */
.morph-specimen-verse {
  font-size: 20px;
  line-height: 1.95;
  color: var(--text-dim);
  margin: 0 0 8px;
  overflow-wrap: break-word;
}
.morph-specimen-verse.hebrew { font-family: var(--hebrew-font); }
.morph-specimen-verse.greek { font-family: var(--greek-font); }
.morph-specimen-word { color: var(--text-dim); }
.morph-specimen-match {
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 600;
  border-radius: 3px;
  padding: 0 2px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Worked-specimen broad-search collapse (#162) — on a broad result set the static
   top specimen is near-decorative, so it sits in a native <details>: closed when
   total > pageSize, open otherwise. No-JS-safe. The figure inside keeps its own
   bottom margin, so the wrapper adds none. */
.morph-specimen-details { margin: 0; }
.morph-specimen-summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font: 700 11px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin: 0 0 8px;
  list-style: none;
}
.morph-specimen-summary::-webkit-details-marker { display: none; }
.morph-specimen-summary::before {
  content: "\25BE"; /* ▾ — rotates to point right when collapsed */
  font-size: 10px;
  color: var(--text-faint);
  transition: transform 120ms;
}
.morph-specimen-details:not([open]) > .morph-specimen-summary::before { transform: rotate(-90deg); }
.morph-specimen-summary:hover,
.morph-specimen-summary:focus-visible { color: var(--accent); outline: none; }
/* Keep the open card flush under its summary (drop the figure's default 18px). */
.morph-specimen-details[open] > .morph-specimen { margin-bottom: 0; }

/* Multi-match readout (#162) — honest count of matched ORIGINAL forms in the
   verse; all of them are <mark>ed in the in-context verse. Never an English claim. */
.morph-specimen-multi {
  font: 600 12px/1.35 var(--ui-font);
  color: var(--accent);
  margin: 0 0 8px;
}
/* Inline-fragment footer link (#162) — the /v/ escape hatch inside the region. */
.morph-specimen-foot { margin: 10px 0 0; }
.morph-specimen-open {
  font: 600 12.5px/1 var(--ui-font);
  color: var(--accent);
  text-decoration: none;
}
.morph-specimen-open:hover,
.morph-specimen-open:focus { text-decoration: underline; }

/* Per-tile "Examine" control (#162, redesigned #163) — pinned ON the tile's edge
   instead of floating in its own row. It is a SIBLING of a.verse-tile (never a
   child: nested interactive elements are invalid HTML), so the tile link stays the
   primary /v/ destination and keeps working with JS off; public/js/morphology.js
   reveals the SSR-`hidden` button. The result <li> is `position: relative` (above),
   so the button is taken out of flow and absolutely pinned top-right, while the
   inline region stays in normal flow and still opens directly beneath the <a> on click. */
.verse-tile-examine {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-end: 8px;
  margin: 0;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  /* R2: restore the #162 ~44px tap-target floor. The button is out of flow
     (position:absolute), so a taller hit box adds ZERO row height — free on these
     tall default cards. From inset-block-start:8px this spans y8→y52, i.e. across
     the ref + surfaces lines, which is why R1 reserves BOTH of those lines. */
  min-height: 44px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 999px;
  font: 600 12px/1 var(--ui-font);
  color: var(--text-dim);
  cursor: pointer;
  transition: color 120ms, border-color 120ms, background 120ms;
}
/* De-gilded: quiet by default, a soft-accent state on hover/focus (no heavy gold
   fill), and the app's standard visible focus ring on :focus-visible. */
.verse-tile-examine:hover,
.verse-tile-examine:focus {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: none;
}
.verse-tile-examine:focus-visible {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.verse-tile-examine-caret { font-size: 11px; transition: transform 120ms; }
.verse-tile-examine[aria-expanded="true"] .verse-tile-examine-caret { transform: rotate(180deg); }

/* Reserve trailing room for the top-right control on the two SHORT top lines it
   actually overlaps — the ref and the surfaces — NOT the whole `<a>`. The ~44px
   button (R2) starts 8px down and reaches only into these two lines; the long,
   multi-line `.verse-tile-text` (English) sits BELOW it and never underlaps it, so
   it keeps the FULL card width (no empty right band on mobile, no dead gutter with
   JS off). Kept UNCONDITIONAL (not `:has()`-gated, not gated on the JS-reveal
   class): a per-line reserve on two short lines leaves no visible gutter even while
   the button is `hidden`, and gating on hydration would re-introduce a CLS reflow.
   Logical property → flips to the correct side on the RTL-isolated Hebrew tiles.
   ~100px clears the widest "Examine ▾" label plus its 8px edge offset. */
.morphology-verse-list .verse-ref,
.morphology-verse-list .verse-surfaces {
  padding-inline-end: 100px;
}

/* The inline specimen region — an indented wrapper; the fetched .morph-specimen
   figure carries its own card chrome, so the region itself is border-less and only
   the loading/error states draw a card. */
.verse-tile-examine-region {
  margin: 6px 0 2px;
  border-inline-start: 2px solid var(--accent-border);
  padding-inline-start: 10px;
}
.verse-tile-examine-region .morph-specimen { margin: 0; }
.verse-tile-examine-loading,
.verse-tile-examine-msg {
  font-family: var(--ui-font);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 0;
  padding: 12px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.verse-tile-examine-msg .morph-specimen-open { color: var(--accent); }

/* Narrow-to-a-book chip strip — a fast per-book apply filter above the results.
   A WRAPPING set of small pill links (NOT remove chips: no ×) that matches the
   .morph-chip visual language. The list wraps onto as many rows as it needs
   (flex-wrap on .morph-book-narrow-list below) so every book with hits stays
   visible without a horizontal scrollbar, and the 390px layout is never forced
   into body-level horizontal scroll. Each chip is a real navigable
   /morphology?…&book=slug link, so it works with JS off. */
.morph-book-narrow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin: 0 0 16px;
}
.morph-book-narrow-label {
  font: 600 12px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  flex: none;
}
.morph-book-narrow-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  padding: 2px 0;
  margin: 0;
  min-width: 0;
  /* Take our own full-width row under the label and WRAP the chips onto as many
     rows as needed, rather than scrolling a single row sideways — every book
     with hits stays visible without a horizontal scrollbar (the old
     overflow-x:auto pattern hid the tail past the fold). */
  flex: 1 1 100%;
}
.morph-book-narrow-list > li { flex: none; }
.morph-book-narrow-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 120ms, background 120ms, color 120ms;
}
.morph-book-narrow-chip:hover,
.morph-book-narrow-chip:focus {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}
.morph-book-narrow-name { font-weight: 600; }
/* The hit count reads as a subordinate/muted number beside the book name. */
.morph-book-narrow-count {
  font-size: 11.5px;
  color: var(--text-faint);
}
.morph-book-narrow-chip:hover .morph-book-narrow-count,
.morph-book-narrow-chip:focus .morph-book-narrow-count { color: var(--accent); }
/* Plain-text "Top 12 of N books" hint — a muted count cue only, never a link. */
.morph-book-narrow-more {
  font-family: var(--ui-font);
  font-size: 12px;
  color: var(--text-faint);
  flex: none;
}
/* Differentiator caption — a muted full-width row below the chips, so the
   nav strip (jump-to-book) never reads as a duplicate of the section chart
   (concentration). Wraps at 390px; carries its own line via flex-basis 100%. */
.morph-book-narrow-note {
  font-family: var(--ui-font);
  font-size: 12px;
  color: var(--text-faint);
  flex: 1 1 100%;
  margin: 6px 0 0;
}
/* Comfortable >=44px tap target on touch, matching the other morphology controls
   (the .morph-chip / .verse-tile-examine pointer-coarse pattern — the page's 44px
   tap floor) without changing desktop density. */
@media (hover: none), (pointer: coarse) {
  .morph-book-narrow-chip { min-height: 44px; }
}

/* Per-book distribution band — reuses the /w About-tab .about-bar markup. */
.morph-dist { margin: 0 0 20px; }
/* #Pass-C — lifted out of .morphology-results into its own standalone panel, so
   it gets the same card chrome as the rail panels / form to read as a distinct
   block rather than buried mid-results. */
.morph-dist--panel {
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 16px;
}
.morph-dist-head {
  font: 600 13px/1 var(--ui-font);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin: 0 0 6px;
}
/* Always-visible unit caption under the panel head, for BOTH distribution leads —
   the rare-form (per-book) lead has no .morph-dist-note, so this states "distinct
   verses" on screen (the per-bar title tooltip is invisible on touch/SR). Muted
   caption matching .morph-dist-note's register (--ui-font, 12.5px, --text-faint). */
.morph-dist-subhead {
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text-faint);
  margin: 0 0 10px;
}
.morph-dist-book { color: var(--text-dim); text-decoration: none; }
.morph-dist-book:hover, .morph-dist-book:focus { color: var(--accent); text-decoration: underline; }
/* Tap-target floor (usability benchmark V1) — .morph-dist-book (the rare-form
   per-book leaderboard link) and .morph-specimen-ref (the worked-example
   figcaption ref link, defined near L10418) are bare inline <a> tags that
   render only ~15-18px tall on a phone, under the 44px WCAG/iOS floor — and
   each is the PRIMARY locator affordance in its context. inline-flex +
   align-items:center grows and vertically centers the hit area without
   touching desktop density (display stays unset there, matching the
   .morphology-empty a / pointer-coarse pattern above). */
@media (hover: none), (pointer: coarse) {
  .morph-dist-book,
  .morph-specimen-ref {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
.morph-dist-more {
  font-family: var(--ui-font);
  font-size: 12.5px;
  color: var(--text-faint);
  margin: 6px 0 0;
}

/* #165 — section observed-vs-expected variant. The section value text
   ("N verses · P% of matching verses · R× baseline") is far longer than a per-book
   "1,234 · 45%", so the tight 3-column .about-bar grid can't hold it on one line.
   This scoped variant keeps the SAME .about-bar-label / .about-bar-track /
   .about-bar-fill / .about-bar-value pieces (the CSP-safe SVG bar) but lays them
   out as label + value on the top row and the full-width bar below, so the value
   is free to WRAP and reads cleanly down to 390px. Because the section label no
   longer sits in the fixed narrow column, the longer labels ("Former Prophets" /
   "General Epistles") never clip — so the per-book .about-bar breakpoint rule is
   left untouched. The plain per-book list (in the <details> and the rare-form
   lead) keeps the original 3-column grid. */
.morph-dist-list--sections .about-bar {
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "label value"
    "track track";
  align-items: baseline;
  column-gap: 12px;
  row-gap: 5px;
}
.morph-dist-list--sections .about-bar-label {
  grid-area: label;
  white-space: normal;
  color: var(--text);
}
.morph-dist-list--sections .about-bar-track { grid-area: track; }
.morph-dist-list--sections .about-bar-value {
  grid-area: value;
  white-space: normal;
  color: var(--text-dim);
}

/* Over/under-representation cue (▲/▼) — a small muted marker beside the
   ×baseline number. aria-hidden decorative: the "R× baseline" text alongside it
   already carries the meaning, and the disclosure line explains the direction. */
.morph-dist-ratio { font-size: 11px; }
.morph-dist-ratio--over { color: var(--accent); }
.morph-dist-ratio--under { color: var(--text-faint); }

/* Observed-vs-expected disclosure — the honest denominator framing. Matches
   .morphology-version-note (--ui-font, ~12.5px, --text-faint) incl. max-width:none
   so it fills the content width, consistent with the hotfix just shipped. */
.morph-dist-note {
  font-family: var(--ui-font);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-faint);
  margin: 10px 0 0;
  max-width: none;
}

/* ============================================================================
   VOCABULARY TRAINER (/learn)
   ----------------------------------------------------------------------------
   Frequency-ordered flashcard drill. Mobile-first (the drill must work one-
   handed on a phone). All colour/spacing from tokens; reuses .cta / .cta-primary
   for the primary actions and the per-language glyph fonts for lemmas.
   ============================================================================ */
.learn { max-width: 72ch; margin: 0 auto; }
.learn-intro { font-size: 16.5px; line-height: 1.65; color: var(--text-dim); margin: 0 0 16px; }
.learn-intro strong { color: var(--text); }

/* --- Controls (the plain GET form, enhanced by learn.js) --- */
.learn-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
  margin: 24px 0 28px;
  padding: 18px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.learn-control { display: flex; flex-direction: column; gap: 6px; flex: 1 1 200px; min-width: 0; }
.learn-control label {
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.learn-select {
  font-family: var(--ui-font);
  font-size: 15px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text);
  cursor: pointer;
}
.learn-select:focus {
  border-color: var(--accent-border);
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}
.learn-controls-go { flex: 0 0 auto; cursor: pointer; }

/* --- Affix-mode toggle (Hebrew parsing quiz only) ---
   A full-width row of the .learn-controls flex form: the checkbox + label sit on
   their own line beneath the corpus/POS selects, with a small muted helper note.
   No inline styles (CSP); all colour/spacing from tokens. */
.learn-control-check { flex: 1 1 100%; min-width: 0; }
.learn-check {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 15px;
  color: var(--text);
}
.learn-check input[type="checkbox"] { margin-top: 2px; cursor: pointer; flex: 0 0 auto; }
.learn-check-note {
  margin: 6px 0 0;
  font-family: var(--ui-font);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* --- Trainer mount (hydrated by learn.js) --- */
.vocab-trainer { margin: 8px 0 32px; }

/* progress / stats strip */
.vocab-progress { margin-bottom: 18px; }
.vocab-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-family: var(--ui-font);
  margin-bottom: 12px;
}
.vocab-stat { display: inline-flex; align-items: baseline; gap: 5px; }
.vocab-stat-num { font-size: 22px; font-weight: 700; color: var(--accent); }
.vocab-stat-label { font-size: 13px; color: var(--text-dim); }
.vocab-boxes {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  font-family: var(--ui-font);
}
.vocab-box {
  font-size: 12px;
  padding: 4px 9px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-raised);
  color: var(--text-dim);
  white-space: nowrap;
}
.vocab-box-new { border-color: var(--accent-border); color: var(--accent); background: var(--accent-soft); }
.vocab-note {
  margin-top: 10px;
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  padding: 8px 12px;
}

/* card stage */
.vocab-stage { min-height: 240px; }
.vocab-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 28px 22px;
  text-align: center;
}
.vocab-card-front { padding-bottom: 6px; }
.vocab-lemma-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
.vocab-lemma { font-size: 44px; line-height: 1.2; color: var(--text); }
.vocab-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.vocab-lemma.greek { font-family: var(--greek-font); }
.vocab-translit {
  font-family: var(--mono-font);
  font-size: 16px;
  color: var(--text-dim);
  margin: 10px 0 0;
}

/* pronounce button — same idiom as .strongs-audio-btn */
.vocab-audio {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.vocab-audio svg { width: 20px; height: 20px; }
.vocab-audio:hover, .vocab-audio:focus-visible {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
  outline: none;
}

/* card back (revealed) */
.vocab-card-back {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--border-soft);
}
.vocab-gloss {
  font-size: 24px;
  color: var(--accent);
  font-style: italic;
  margin: 0 0 10px;
}
.vocab-freq { font-family: var(--ui-font); font-size: 14px; color: var(--text-dim); margin: 0 0 12px; }
.vocab-freq strong { color: var(--text); }
.vocab-study-link {
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
}
.vocab-study-link:hover, .vocab-study-link:focus { text-decoration: underline; }

/* controls under the card */
.vocab-controls { margin-top: 22px; }
.vocab-reveal { cursor: pointer; }
.vocab-rate { display: flex; gap: 12px; justify-content: center; }
.vocab-rate-btn {
  flex: 1 1 0;
  max-width: 220px;
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 600;
  padding: 12px 16px;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.vocab-rate-miss {
  border: 1px solid var(--error-border);
  background: var(--error-soft);
  color: var(--error);
}
.vocab-rate-miss:hover, .vocab-rate-miss:focus-visible {
  background: var(--error);
  color: var(--on-accent);
  outline: none;
}
.vocab-rate-know {
  border: 1px solid var(--success-border);
  background: var(--success-soft);
  color: var(--success);
}
.vocab-rate-know:hover, .vocab-rate-know:focus-visible {
  background: var(--success);
  color: var(--on-accent);
  outline: none;
}

/* session done / empty / loading / error states */
.vocab-done { text-align: center; padding: 24px 12px; }
.vocab-done h3 { font-family: var(--ui-font); margin: 0 0 10px; color: var(--text); }
.vocab-done p { color: var(--text-dim); margin: 0 auto 18px; max-width: 46ch; }
.vocab-restart { cursor: pointer; }
.vocab-message {
  text-align: center;
  padding: 26px 16px;
  color: var(--text-dim);
  font-family: var(--ui-font);
}
.vocab-message-error {
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
}

/* --- No-JS / pre-hydration fallback preview list --- */
.learn-fallback { margin: 8px 0 28px; }
.learn-fallback-note { font-family: var(--ui-font); font-size: 14.5px; color: var(--text-dim); margin: 0 0 14px; }
.learn-fallback-note strong { color: var(--text); }
.learn-empty { color: var(--text-dim); }
.learn-preview { list-style: none; margin: 0; padding: 0; counter-reset: learn-rank; }
.learn-preview-row {
  counter-increment: learn-rank;
  border-bottom: 1px solid var(--border-soft);
}
.learn-preview-link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 6px 14px;
  padding: 11px 6px;
  text-decoration: none;
  color: var(--text);
}
.learn-preview-link::before {
  content: counter(learn-rank);
  grid-row: span 2;
  align-self: center;
  font-family: var(--mono-font);
  font-size: 13px;
  color: var(--text-faint);
  min-width: 2ch;
  text-align: right;
}
.learn-preview-lemma { font-size: 26px; line-height: 1.25; }
.learn-preview-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.learn-preview-lemma.greek { font-family: var(--greek-font); }
.learn-preview-translit { font-family: var(--mono-font); font-size: 13.5px; color: var(--text-dim); }
.learn-preview-gloss {
  grid-column: 2 / 3;
  font-style: italic;
  color: var(--accent);
  font-size: 15px;
}
.learn-preview-count {
  grid-column: 3 / 4;
  grid-row: 1 / 3;
  align-self: center;
  font-family: var(--mono-font);
  font-size: 13px;
  color: var(--text-faint);
  white-space: nowrap;
}
.learn-preview-link:hover .learn-preview-lemma,
.learn-preview-link:focus .learn-preview-lemma { color: var(--accent); }
.learn-preview-more { margin: 18px 0 0; }

/* --- "How the drill works" explainer --- */
.learn-how { margin: 30px 0 8px; }
.learn-how h3 { font-family: var(--ui-font); color: var(--text); margin: 0 0 12px; }
.learn-how-list { margin: 0; padding-left: 20px; color: var(--text-dim); line-height: 1.65; }
.learn-how-list li { margin-bottom: 8px; }
.learn-how-list strong { color: var(--text); }

/* --- Vocab card: production-mode prompt + polysemy "primary sense" caption --- */
.vocab-gloss-block { margin: 0; }
/* Production mode (gloss on the front) leads with a small prompt so the card
   reads as "recall the word", not a bare definition. */
.vocab-prompt {
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  margin: 0 0 10px;
}
/* Polysemy hedge: a single drill gloss is the PRIMARY sense, not the whole
   range — the caption + the reframed /w/ link make that explicit. */
.vocab-gloss-caption {
  font-family: var(--ui-font);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  margin: 0 0 4px;
}
/* In production mode the lemma sits on the back; give it room to breathe. */
.vocab-card-production .vocab-card-back .vocab-lemma { font-size: 40px; }

/* ===================================================================== */
/* Parsing quiz (/learn/parse) — hydrated by parse.js                    */
/* Reuses the .learn-controls / .learn-select / .learn-how / .cta idioms;*/
/* the .parse-* rules below cover the quiz-specific surfaces only.        */
/* ===================================================================== */

/* No-JS / pre-hydration worked-sample card. */
.parse-fallback { margin: 8px 0 28px; }
.parse-sample-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 22px;
  margin-top: 14px;
}
.parse-sample-prompt { font-family: var(--ui-font); font-size: 15px; color: var(--text-dim); margin: 0 0 10px; }
.parse-sample-lemma { font-size: 22px; }
.parse-sample-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.parse-sample-lemma.greek { font-family: var(--greek-font); }
.parse-sample-gloss { font-style: italic; color: var(--accent); }
.parse-sample-surface { font-size: 38px; line-height: 1.25; margin: 0 0 16px; color: var(--text); }
.parse-sample-surface.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.parse-sample-surface.greek { font-family: var(--greek-font); }
.parse-sample-answer-label {
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  margin: 0 0 8px;
}
.parse-sample-answer { margin: 0 0 14px; display: grid; grid-template-columns: 1fr; gap: 4px; }
.parse-sample-pair {
  display: grid;
  grid-template-columns: 12ch 1fr;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px solid var(--border-soft);
}
.parse-sample-pair dt { font-family: var(--ui-font); font-size: 13px; color: var(--text-faint); margin: 0; }
.parse-sample-pair dd { margin: 0; color: var(--text); font-size: 14px; }
.parse-sample-study { margin: 0; font-family: var(--ui-font); font-size: 14px; }
.parse-sample-study a { color: var(--accent); text-decoration: none; font-weight: 600; }
.parse-sample-study a:hover, .parse-sample-study a:focus { text-decoration: underline; }

/* Interactive quiz mount. */
.parse-quiz { margin: 8px 0 32px; }

/* progress / stats strip */
.parse-progress { margin-bottom: 18px; }
.parse-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-family: var(--ui-font);
}
.parse-stat { display: inline-flex; align-items: baseline; gap: 5px; }
.parse-stat-num { font-size: 22px; font-weight: 700; color: var(--accent); }
.parse-stat-label { font-size: 13px; color: var(--text-dim); }
.parse-note {
  margin-top: 10px;
  font-family: var(--ui-font);
  font-size: 13px;
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  padding: 8px 12px;
}

/* the live card */
.parse-stage { min-height: 240px; }
.parse-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 26px 22px;
}
.parse-prompt { font-family: var(--ui-font); font-size: 15px; color: var(--text-dim); margin: 0 0 8px; text-align: center; }
.parse-lemma { font-size: 22px; }
.parse-lemma.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.parse-lemma.greek { font-family: var(--greek-font); }
.parse-prompt-gloss { font-style: italic; color: var(--accent); }
.parse-surface {
  font-size: 46px;
  line-height: 1.2;
  text-align: center;
  color: var(--text);
  margin: 0 0 22px;
}
.parse-surface.hebrew { font-family: var(--hebrew-font); direction: rtl; }
.parse-surface.greek { font-family: var(--greek-font); }

/* the parse-builder dropdown grid */
.parse-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 0 0 18px;
}
.parse-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.parse-field-label {
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
}
.parse-select:disabled { opacity: 0.85; cursor: default; }

/* graded result */
.parse-result {
  margin: 6px 0 18px;
  padding: 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-raised);
}
.parse-result-heading {
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  margin: 0 0 10px;
}
.parse-result-list { margin: 0 0 12px; display: grid; gap: 4px; }
.parse-result-pair {
  display: grid;
  grid-template-columns: 12ch 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 6px 8px;
  border-radius: var(--radius);
}
.parse-result-pair.is-correct { background: var(--success-soft); }
.parse-result-pair.is-wrong { background: var(--error-soft); }
.parse-result-facet { font-family: var(--ui-font); font-size: 13px; color: var(--text-faint); margin: 0; }
.parse-result-vals { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 14px; }
.parse-result-mark { font-family: var(--ui-font); font-weight: 700; }
.parse-result-pair.is-correct .parse-result-mark { color: var(--success); }
.parse-result-pair.is-wrong .parse-result-mark { color: var(--error); }
.parse-result-correct { color: var(--text); font-weight: 600; }
.parse-result-yours { color: var(--text-dim); font-size: 13px; font-style: italic; }
.parse-result-verdict { font-family: var(--ui-font); font-size: 14px; margin: 0 0 10px; }
.parse-result-verdict.is-correct { color: var(--success); }
.parse-result-verdict.is-wrong { color: var(--text-dim); }
.parse-result-study { font-family: var(--ui-font); font-size: 14px; font-weight: 600; color: var(--accent); text-decoration: none; }
.parse-result-study:hover, .parse-result-study:focus { text-decoration: underline; }

/* action buttons */
.parse-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.parse-check, .parse-next, .parse-restart { cursor: pointer; }

/* session done */
.parse-done { text-align: center; padding: 22px 12px; }
.parse-done h3 { font-family: var(--ui-font); margin: 0 0 10px; color: var(--text); }
.parse-done p { color: var(--text-dim); margin: 0 auto 16px; max-width: 52ch; }
.parse-done-study-label {
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-faint);
  margin: 0 0 8px;
}
.parse-done-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 0 0 18px; }
.parse-done-link {
  font-family: var(--mono-font);
  font-size: 13px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  text-decoration: none;
}
.parse-done-link:hover, .parse-done-link:focus { background: var(--accent); color: var(--on-accent); }

/* loading / error message */
.parse-message {
  text-align: center;
  padding: 26px 16px;
  color: var(--text-dim);
  font-family: var(--ui-font);
}
.parse-message-error {
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
}

/* cross-links footer */
.parse-crosslink, .learn-crosslink { display: flex; flex-wrap: wrap; gap: 12px; margin: 26px 0 8px; }

/* ---- Passage-anchored drilling (#23d) -------------------------------------
   The SSR "Passage drill" banner on /learn + /learn/parse, the live "Drilling
   <ref>" banner the trainers render, the verse-context block in the parse drill
   (the verse shown so a syncretic form is graded fairly), the ambiguity
   disclosure, and the read->drill links on the verse + chapter pages. */

/* SSR banner on the /learn + /learn/parse pages (server-rendered when ?ref=) */
.learn-passage-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 14px;
  margin: 0 0 18px;
  padding: 14px 18px;
  background: var(--bg-raised);
  border: 1px solid var(--border-soft);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}
.learn-passage-tag {
  font-family: var(--ui-font);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent);
}
.learn-passage-text { font-family: var(--ui-font); font-size: 15px; color: var(--text-dim); margin: 0; flex: 1 1 16ch; }
.learn-passage-text strong { color: var(--text); }
.learn-passage-link { color: inherit; text-decoration: none; }
.learn-passage-link:hover, .learn-passage-link:focus { text-decoration: underline; }
.learn-passage-clear { font-family: var(--ui-font); font-size: 13px; margin: 0; flex: 0 0 auto; }
.learn-passage-clear a { color: var(--text-faint); text-decoration: none; }
.learn-passage-clear a:hover, .learn-passage-clear a:focus { text-decoration: underline; color: var(--text-dim); }

/* live "Drilling <ref>" banner the trainers render once a passage deck loads */
.parse-passage-banner, .vocab-passage-banner {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0 0 14px;
  padding: 10px 14px;
  background: var(--accent-soft, var(--bg-raised));
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
}
.parse-passage-tag, .vocab-passage-tag {
  font-family: var(--ui-font);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
}
.parse-passage-ref, .vocab-passage-ref { font-family: var(--ui-font); font-size: 15px; color: var(--text); }

/* verse context inside a parse card / the SSR sample (the verse shown for a fair
   parse). The original-language surface above is the highlighted form; this is
   the WHOLE verse in English (no English word-level highlight in the store). */
.parse-context, .parse-sample-context {
  margin: 0 0 20px;
  padding: 12px 16px;
  border-left: 3px solid var(--border);
  background: var(--bg-raised);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.parse-context-ref, .parse-sample-context-ref {
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  margin: 0 0 4px;
}
.parse-context-text, .parse-sample-context-text {
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 0;
  font-style: italic;
}

/* the always-on ambiguity disclosure on a graded parse */
.parse-result-disclosure { font-family: var(--ui-font); font-size: 12.5px; color: var(--text-faint); margin: 0 0 10px; }

/* read->drill links on the verse + chapter pages (one primary action + a quieter
   secondary). Reuses the search-more visual language. */
.verse-drill {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  margin: 0 0 14px;
  font-family: var(--ui-font);
  font-size: 14px;
}
.verse-drill-label { color: var(--text-faint); }
.verse-drill-link { color: var(--accent); text-decoration: none; font-weight: 600; }
.verse-drill-link:hover, .verse-drill-link:focus { text-decoration: underline; }
.verse-drill-primary { font-weight: 700; }
/* Chapter "Practice this chapter" — stack the label over a row of the two action
   buttons. Scoped to .chapter-drill so the verse page's inline drill line (which
   reuses .verse-drill / .verse-drill-link) keeps its plain-link styling. */
.chapter-drill {
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}
.verse-drill-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}
.chapter-drill .verse-drill-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: var(--radius);
  border: 1px solid var(--accent-border);
  background: var(--accent-soft);
  color: var(--accent);
  transition: background 120ms, color 120ms;
}
.chapter-drill .verse-drill-link:hover,
.chapter-drill .verse-drill-link:focus {
  background: var(--accent);
  color: var(--on-accent);
  text-decoration: none;
}
/* The primary (Drill) starts unfilled like the secondary — its heavier weight
   (.verse-drill-primary, 700) is the only resting distinction; both fill on
   hover via the rule above. */

@media (max-width: 560px) {
  .learn-controls { flex-direction: column; align-items: stretch; }
  .learn-controls-go { width: 100%; text-align: center; }
  .vocab-lemma { font-size: 38px; }
  .vocab-gloss { font-size: 21px; }
  .vocab-rate { flex-direction: column; }
  .vocab-rate-btn { max-width: none; }
  .learn-preview-link { grid-template-columns: auto 1fr; }
  .learn-preview-count { grid-column: 2 / 3; grid-row: auto; align-self: baseline; }
  .parse-surface { font-size: 36px; }
  .parse-sample-surface { font-size: 30px; }
  .parse-fields { grid-template-columns: 1fr; }
  .parse-actions { flex-direction: column; }
  .parse-check, .parse-next { width: 100%; text-align: center; }
  .parse-sample-pair, .parse-result-pair { grid-template-columns: 10ch 1fr; }
  .parse-crosslink { flex-direction: column; }
}

/* ============================================================================
   34. COMPARE BASKET (#197) — per-row mark toggle + cross-page tray
   ============================================================================

   Everything below is styling for DOM that only exists when JavaScript ran
   (public/js/word-basket.js builds it). Nothing here is server-rendered, so a
   no-JS visitor sees none of it and the word rows keep their exact #196 layout.

   Two surfaces:
     1. .wbw-rest-mark — a per-row "mark this word" toggle, injected as a third
        sibling inside .wbw-rest-li (after the #196 compare cell). Mirrors
        .wbw-rest-compare's box (fixed ≥44px cell + border-left divider), with a
        pressed state and a DISTINCT bookmark glyph.
     2. .basket-tray — the fixed, bottom-docked tray: a collapsed count pill that
        expands to two corpus lanes (Hebrew · OT / Greek · NT), each with its own
        chips and its own single-corpus compare action.

   Two rules here are load-bearing and easy to delete by accident:
     - `body.has-basket-tray { padding-bottom }` is what stops the fixed tray
       from sitting on the footer links. The class is toggled from JS
       (buildTray/destroyTray), so it is only paid for when a tray exists.
     - `.basket-live` is the screen-reader announcement region. It is appended
       to <body>, NOT to the tray, because the tray is destroyed on empty and a
       live region must be rendered before its text changes.
   ============================================================================ */

/* ---- Per-row mark toggle ---- */

/* Same box as .wbw-rest-compare so the two controls read as one column pair and
   the row keeps one shared height. `button` resets are needed here (the compare
   control is an <a>): background/border/padding/appearance. */
.wbw-rest-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: none;
  border-left: 1px solid var(--border-soft);
  background: none;
  color: var(--text-dim);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  transition: background 0.12s, color 0.12s;
}
.wbw-rest-mark:hover { color: var(--accent); background: var(--accent-soft); }
.wbw-rest-mark:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Resting chip outline — the ONE thing that differentiates this control from the
   #196 compare cell beside it. Both are 44px, both --text-dim, both 17px 2px
   outline glyphs, so a mis-tap navigates to /concordance instead of banking the
   word. The outline makes the mark cell read as a TOGGLE (a thing with a state)
   rather than a link, which is what it is.
   Deliberately NOT done by fading the compare glyph a shade: that would undo
   #196's FIX 4 touch-legibility bump AND collide with .wbw-rest-compare-empty's
   --text-faint, making the live control indistinguishable from the inert
   placeholder.
   An absolutely-positioned pseudo-element, so it costs zero layout: the cell
   stays exactly 44px wide and the grid tracks are untouched. Not applied to the
   inert .wbw-rest-mark-empty placeholder (a <span>) — an outline there would
   promise an affordance that isn't. */
button.wbw-rest-mark { position: relative; }
button.wbw-rest-mark::before {
  content: '';
  position: absolute;
  top: 6px;
  right: 5px;
  bottom: 6px;
  left: 5px;
  border: 1px solid var(--border-soft);
  border-radius: 8px;
  pointer-events: none;
  transition: border-color 0.12s;
}
button.wbw-rest-mark:hover::before,
button.wbw-rest-mark[aria-pressed="true"]::before { border-color: var(--accent-border); }
/* Marked: the bookmark fills and the cell takes the accent tint, so the state is
   legible without hover (which never fires on touch). The CSS `fill` beats the
   svg's `fill="none"` presentation attribute and is inherited by the path. */
.wbw-rest-mark[aria-pressed="true"] { color: var(--accent); background: var(--accent-soft); }
.wbw-rest-mark[aria-pressed="true"] .wbw-rest-mark-icon { fill: currentColor; }
/* Inert placeholder for a head-less row (proclitic-/suffix-only or LXX-only
   word — no real Strong's, so nothing the workspace could compare). Holds the
   same fixed column so injecting the toggle never re-rags the aligned grid. */
.wbw-rest-mark-empty { cursor: default; color: var(--text-faint); }
.wbw-rest-mark-empty:hover { background: none; color: var(--text-faint); }

@media (max-width: 560px) {
  /* The mark cell is a SECOND fixed 44px column on a 390px row, so its width has
     to be reclaimed or the glyph track (this tool's primary axis) collapses and
     short words clip — the exact regression #196's audit just fixed.
     The Strong's pill pays for it: at this width it is redundant with the glyph
     + transliteration for a "do I want to mark this word?" decision, and for a
     Strong's-tagged word the number is still on the focus card and on every /w/
     page. Dropping the TRACK (not just the cell) plus its 10px gap frees 62px
     against the 44px the mark cell costs, so the glyph column comes out AHEAD
     of the #196 baseline.

     KNOWN COLLATERAL, accepted: the selector below also hides the LXX badge
     (verse.ejs emits it as `.wbw-strongs.wbw-lxx-pill`), and for an LXX-only
     word that badge is NOT recoverable from the focus card or a /w/ page — the
     word has no Strong's at all and routes to /lxx/:slug instead. Restoring it
     would mean restoring the whole track, which is exactly the re-ragging this
     rule exists to prevent, so at ≤560px the LXX marker is carried by the row's
     /lxx/ link target and by the focus card's "Septuagint word →" action
     (_wbw_focus.ejs) rather than by a visible pill.
     Scoped to .has-mark — a class word-basket.js adds only when it actually
     injected the cells — so the no-JS row layout is untouched.
     Columns here: num | glyph | translit. */
  .wbw-rest.has-mark .wbw-rest-row {
    grid-template-columns:
      26px
      minmax(0, 1.9fr)
      minmax(52px, 0.9fr);
  }
  .wbw-rest.has-mark .wbw-strongs,
  .wbw-rest.has-mark .wbw-strongs-empty { display: none; }
  /* Row padding tightens at this width; keep the touch-target floor. */
  .wbw-rest-mark { min-width: 44px; min-height: 44px; }
}

/* ---- Focus-card mark toggle (#200) ---- */

/* The focused word's row is hidden (it IS the card above), so its .wbw-rest-mark
   never shows; this is its stand-in ON the card. A card CONTROL — a pill with the
   bookmark glyph + a state label — NOT a 44px grid cell like .wbw-rest-mark.
   word-basket.js injects it (never SSR'd, so a no-JS visitor sees no toggle) and
   labelFor() maintains aria-pressed, which drives BOTH the accent state and the
   visible-label swap below. Direct child of .wbw-focus-body, so the #199
   `> * { max-width:100% }` cap keeps it inside the card at ~390px. */
.wbw-focus-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg-raised);
  color: var(--text-dim);
  font: 600 13px/1.3 var(--ui-font);
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.wbw-focus-mark:hover { color: var(--accent); border-color: var(--accent-border); background: var(--accent-soft); }
.wbw-focus-mark:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wbw-focus-mark-icon { flex: none; }
/* Marked: accent tint + a FILLED bookmark, matching the row mark's pressed look so
   the two controls read as one action surfaced in two places. The CSS `fill` beats
   the svg's `fill="none"` presentation attribute and is inherited by the path. */
.wbw-focus-mark[aria-pressed="true"] {
  color: var(--accent);
  border-color: var(--accent-border);
  background: var(--accent-soft);
}
.wbw-focus-mark[aria-pressed="true"] .wbw-focus-mark-icon { fill: currentColor; }
/* aria-pressed also swaps the visible label (Mark to compare ⇄ Marked — in basket),
   so the text always tracks the state with no JS text-sync and no MutationObserver. */
.wbw-focus-mark-marked { display: none; }
.wbw-focus-mark[aria-pressed="true"] .wbw-focus-mark-unmarked { display: none; }
.wbw-focus-mark[aria-pressed="true"] .wbw-focus-mark-marked { display: inline; }

/* ---- The tray ---- */

/* Bottom-docked on every viewport. The CONTAINER is transparent and
   pointer-events:none so a collapsed basket never blocks taps on the footer, ad
   slot or page content underneath — only the pill and the expanded panel take
   pointer events. column-reverse paints the panel ABOVE the pill while the DOM
   order stays pill-first (so keyboard order is toggle → contents).
   z-index sits above the sticky header (25). The 45 was originally chosen to sit
   below the homegrown consent banner's 50; that banner is gone (2026-08-05), and
   what replaced it — Google's Privacy & messaging dialog — is a cross-origin
   iframe that sets its own stacking context far above anything here, so there is
   no local ceiling left to stay under. Kept at 45 rather than raised: nothing
   between 25 and 50 competes with the tray, and re-numbering a working layer buys
   nothing. */
.basket-tray {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 12px;
  /* Longhand so a UA without env() drops only this line, not the whole
     shorthand (which would leave the tray with zero padding). This used to cite
     `.consent` in consent.css as the precedent; that rule was deleted with the
     consent banner on 2026-08-05, so the idiom now stands on its own. */
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  pointer-events: none;
}
.basket-tray > * { pointer-events: auto; }

/* The tray is position:fixed and therefore reserves no space; without this the
   collapsed pill sits on top of the footer links (measured: a 14px bite out of
   the 37px "Privacy" target at 390px) and over the word list's right columns on
   desktop. The class is toggled by word-basket.js in buildTray/destroyTray, so
   a page with an empty basket keeps its exact original bottom spacing.
   The plain value first, then the safe-area longhand, for the same
   env()-unknown reason as above. */
body.has-basket-tray { padding-bottom: 64px; }
body.has-basket-tray { padding-bottom: calc(64px + env(safe-area-inset-bottom)); }

/* Announcement region (word-basket.js appends it to <body>, not to the tray —
   the tray is destroyed when the basket empties, and a live region must already
   be rendered when its text changes). Visually hidden, never clipped away from
   the accessibility tree. */
.basket-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  pointer-events: none;
}

.basket-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  background: var(--bg-raised);
  box-shadow: var(--shadow);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: background 0.12s, color 0.12s;
}
.basket-pill:hover { background: var(--bg-card); color: var(--accent); }
.basket-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.basket-pill-icon { color: var(--accent); fill: currentColor; }
.basket-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 12px;
  font-weight: 700;
}

/* 45vh, not 60vh: an open panel spans two thirds of a phone screen at 60vh, and
   this reader navigates verse→verse with the basket in hand. Desktop takes the
   taller budget back below (it is a 360px side card there, not a full-width bar
   over the text). */
.basket-panel {
  width: 100%;
  max-height: 45vh;
  overflow-y: auto;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* Scrolling shadows. With both lanes full the panel scrolls internally, and
     nothing signalled that — lane 2's compare action (which IS the feature) was
     sliced at the panel edge with no affordance. Layers 1-2 are opaque
     bg-raised caps attached to the CONTENT (background-attachment: local) so
     they slide away as you scroll; layers 3-4 are the shadows they uncover,
     attached to the ELEMENT. First layer paints on top, so the caps hide the
     shadows exactly at the two ends. Pure CSS — no scroll listener. */
  background-color: var(--bg-raised);
  background-image:
    linear-gradient(var(--bg-raised), rgba(0, 0, 0, 0)),
    linear-gradient(rgba(0, 0, 0, 0), var(--bg-raised)),
    linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0)),
    linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.3));
  background-position: top, bottom, top, bottom;
  background-size: 100% 22px, 100% 22px, 100% 9px, 100% 9px;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.basket-lanes { display: flex; flex-direction: column; gap: 14px; }
.basket-lane {
  padding: 10px 12px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--bg-card);
}
/* Lane label — the corpus name, which is the whole reason the two sets never
   merge into one bench. Styled as a title, deliberately NOT a heading element
   (the tray is injected onto every page and must not disturb the outline). */
.basket-lane-title {
  margin: 0 0 8px;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}
/* Chips WRAP rather than stacking one per row. A full basket (4 + 4) stacked was
   623px of panel — over budget, pushing lane 2's compare action off the internal
   scroll fold. Chips are short (a transliteration + a short gloss), so wrapping
   roughly halves the height and keeps both lanes' compare buttons reachable. */
.basket-chips {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-flow: row wrap;
  gap: 6px 8px;
}
/* Each chip becomes a self-contained boxed unit, since it no longer has a full
   row to delimit it. max-width keeps a long gloss from forcing a lone chip per
   line (the stacked layout it replaced). */
.basket-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  max-width: 100%;
  padding: 2px 4px 2px 8px;
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  background: var(--bg-raised);
}
.basket-chip-word {
  color: var(--text);
  font-style: italic;
  text-decoration: none;
  white-space: nowrap;
}
.basket-chip-word:hover { color: var(--accent); text-decoration: underline; }
.basket-chip-word:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.basket-chip-gloss {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--reading-font);
  font-size: 13px;
  color: var(--text-dim);
}
.basket-chip-remove {
  flex: 0 0 auto;
  margin-left: auto;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.basket-chip-remove:hover { color: var(--accent); background: var(--accent-soft); }
.basket-chip-remove:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Per-lane compare action. Rail 1: its href carries THIS lane's words only —
   there is no control anywhere that emits a mixed-corpus ?w= list. */
.basket-go {
  display: block;
  padding: 9px 12px;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 14px;
  text-align: center;
  text-decoration: none;
}
.basket-go:hover { background: var(--accent); color: var(--on-accent); }
.basket-go:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* A lane with one word has nothing to compare: a disabled button, so it is not
   in the tab order and cannot promise a comparison the workspace would refuse. */
.basket-go-idle {
  width: 100%;
  border-color: var(--border);
  background: none;
  color: var(--text-faint);
  cursor: default;
  font: inherit;
  font-size: 13px;
}
.basket-go-idle:hover { background: none; color: var(--text-faint); }

/* Quiet inline refusal note (lane at cap). Never an alert(); collapses when
   empty so it leaves no gap in the resting tray. It is the FIRST child of the
   panel (above the lanes), because a cap refusal only fires when the lanes are
   full — i.e. when the panel is at its tallest and scrolling internally — and
   appended after them it rendered below the fold on a phone. It is
   aria-hidden: the spoken copy is .basket-live, which is always rendered. */
.basket-note {
  margin: 0 0 12px;
  padding: 8px 10px;
  border: 1px solid var(--warn-border);
  border-radius: 8px;
  background: var(--warn-soft);
  color: var(--warn);
  font-size: 13px;
  line-height: 1.5;
}
.basket-note:empty { display: none; }

.basket-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
}
.basket-hint {
  margin: 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-faint);
}
.basket-clear {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: none;
  color: var(--text-dim);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, color 0.12s;
}
.basket-clear:hover { color: var(--accent); background: var(--accent-soft); }
.basket-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (min-width: 720px) {
  /* Desktop: a compact bottom-right card instead of a full-width bar. */
  .basket-tray {
    left: auto;
    width: min(360px, calc(100vw - 32px));
    padding: 16px;
    padding-bottom: calc(16px + env(safe-area-inset-bottom));
  }
  /* A side card does not cover the text the way a full-width phone bar does, so
     the taller budget comes back here. */
  .basket-panel { max-height: 60vh; }
}

@media (prefers-reduced-motion: reduce) {
  .wbw-rest-mark,
  .wbw-rest-mark::before,
  .basket-pill,
  .basket-chip-remove,
  .basket-clear { transition: none; }
}

/* ============================================================================
   TIER-LABELLED ARTIFACT CONTROLS — study sheet (/v/) + batch export (/morphology)
   ============================================================================

   docs/access-tiers-spec.md §5.3: "Download buttons render for everyone,
   labelled with the tier they require. A free user who clicks gets the upgrade
   page, not a dead control. No silent dimming, no unlabelled bump."

   So there is deliberately NO disabled/dimmed state here and no tier-conditional
   styling — the control looks identical to every visitor, and the tier chip is a
   LABEL, not a lock. Both surfaces are native <details> + a plain GET form, so
   they work with JS off; they stack to one column below 560px.
   ============================================================================ */

.verse-sheet {
  margin: 1.1rem 0 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
}

.verse-sheet-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  cursor: pointer;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
  list-style: none;
}

.verse-sheet-summary::-webkit-details-marker { display: none; }
.verse-sheet-summary:hover,
.verse-sheet-summary:focus-visible { color: var(--accent); }
.verse-sheet-summary-icon { flex: none; display: inline-flex; color: var(--text-dim); }
.verse-sheet-summary-icon svg { width: 17px; height: 17px; display: block; }
.verse-sheet-summary:hover .verse-sheet-summary-icon { color: var(--accent); }
.verse-sheet-summary-label { flex: 1 1 auto; }

.verse-sheet-summary-chevron {
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.6;
}

.verse-sheet[open] .verse-sheet-summary-chevron { transform: rotate(-135deg); }

.verse-sheet-body {
  padding: 0 14px 14px;
  border-top: 1px solid var(--border-soft);
}

.verse-sheet-lede,
.verse-sheet-note,
.verse-sheet-free {
  margin: 0.65rem 0 0;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.verse-sheet-free { color: var(--text-faint); }

.verse-sheet-group { margin-top: 1rem; }

.verse-sheet-group-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 0.45rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* The tier LABEL. Gold, because it names a supporter tier — never a lock icon
   and never applied to the control itself. */
.verse-sheet-tier,
.morph-batch-tier {
  display: inline-block;
  padding: 2px 8px;
  border: 1px solid var(--accent-border);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: none;
}

.verse-sheet-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
}

.verse-sheet-btn {
  display: inline-block;
  padding: 7px 13px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text);
  font-size: 0.82rem;
  font-family: inherit;
  text-decoration: none;
  cursor: pointer;
}

.verse-sheet-btn:hover,
.verse-sheet-btn:focus-visible {
  border-color: var(--accent-border);
  color: var(--accent);
}

.verse-sheet-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}

.verse-sheet-field,
.morph-batch-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 0.74rem;
  color: var(--text-faint);
}

.verse-sheet-field input,
.verse-sheet-field select,
.morph-batch-field select {
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-card);
  color: var(--text);
  font-size: 0.85rem;
  font-family: inherit;
}

.verse-sheet-field input { width: 5.5rem; }

/* --- /morphology batch export ------------------------------------------- */

.morph-batch {
  margin-top: 10px;
  border-top: 1px solid var(--border-soft);
  padding-top: 10px;
}

.morph-batch-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text);
  list-style: none;
}

.morph-batch-summary::-webkit-details-marker { display: none; }
.morph-batch-summary:hover,
.morph-batch-summary:focus-visible { color: var(--accent); }
.morph-batch-summary-label { flex: 1 1 auto; }

.morph-batch-body { padding-top: 8px; }

.morph-batch-lede,
.morph-batch-note {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--text-dim);
}

.morph-batch-note { margin: 0.6rem 0 0; color: var(--text-faint); }

.morph-batch-label {
  display: block;
  margin-bottom: 4px;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.morph-batch-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 8px 9px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  font-family: var(--mono-font);
  font-size: 0.76rem;
  line-height: 1.45;
  resize: vertical;
}

.morph-batch-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  margin-top: 8px;
}

/* 390px: the verse-sheet form's two number fields plus the format select must
   not force a horizontal scroll, so each field takes the full row. */
@media (max-width: 560px) {
  .verse-sheet-form { flex-direction: column; align-items: stretch; }
  .verse-sheet-field,
  .verse-sheet-field input,
  .verse-sheet-field select { width: 100%; }
  .verse-sheet-btn { width: 100%; text-align: center; }
  .morph-batch-actions { flex-direction: column; align-items: stretch; }
}

/* ============================================================================
   PRINT STYLES — lesson-kit handout + general page hygiene
   ============================================================================

   Two independent concerns:

   1. GENERAL PRINT HYGIENE (@media print, always): hide non-content chrome
      that is meaningless on paper — site nav/header, footer, sticky jump nav,
      ads, the compare-basket tray, and the Copy/Print buttons themselves.

   2. HANDOUT ISOLATION (body.lesson-kit-printing, inside @media print): when
      the lesson kit's Print button triggered the dialog, scope the printout to
      the .lesson-kit panel only. All sibling study panels are hidden by their
      real selector; the kit expands full-width. The disclosure and all link text
      remain visible (no suppression of .lesson-kit a or .lesson-kit-disclosure).
      The body class is added/removed by initLessonKitExport around window.print().
   ============================================================================ */

@media print {
  /* --- General chrome: suppress non-content elements on any page print --- */

  /* Site header (sticky nav band) and the sub-nav "On this page" strip. */
  .site-header,
  .site-subnav {
    display: none !important;
  }

  /* Site footer. */
  .site-footer {
    display: none !important;
  }

  /* Ad slot, and the compare-basket tray (.basket-tray, appended to
     document.body by word-basket.js) — floating chrome, meaningless on paper.
     `.consent` was here too, for the banner consent.js used to build; both are
     gone as of 2026-08-05 and the selector went with them rather than being
     kept as insurance against a re-add that is not planned. Google's Privacy &
     messaging dialog replaces it and is a cross-origin iframe, so this
     stylesheet cannot suppress it — it is also modal, so a reader printing
     underneath one is not a case that arises. */
  .ad-slot,
  .basket-tray {
    display: none !important;
  }

  /* The Copy and Print buttons are meaningless on paper. */
  [data-lesson-kit-copy],
  [data-lesson-kit-print] {
    display: none !important;
  }

  /* Ensure the lesson kit panel itself is always full-width, not constrained
     by any flex/grid parent, and not clipped. Applies to every print, not only
     the handout mode — so a reader who uses Ctrl+P on a verse page gets the
     full kit content. */
  .lesson-kit {
    width: 100% !important;
    max-width: none !important;
    box-shadow: none !important;
    border: 1px solid #ccc !important;
    break-inside: avoid;
  }

  /* --- Handout isolation: only when the kit's Print button triggered it --- */

  /* Hide all the sibling study panels so the printed page is the lesson kit
     handout only. Each selector targets the real top-level section class from
     its respective partial: _lesson_kit sits LAST in <main>, so hiding
     everything ABOVE it yields a clean single-panel printout.

     Panels hidden: verse box (.results), parallel-compare (.verse-compare),
     study grid + word study + cross-refs (.verse-study-grid), MT↔LXX compare
     (.verse-mtlxx), textual variants (.variant-apparatus), targum
     (.targum-panel), and commentary (.commentary). The breadcrumb (.breadcrumbs),
     reference-search box (.search), support strip (.support — and its wrapper card
     .ad-support-panel, which since 2026-08-07 also holds the top ad unit; the
     WRAPPER is the load-bearing one, since `.ad-slot` is already hidden for every
     print above and suppressing only the strip inside it would print an empty
     bordered card), and highlights
     strip (.verse-highlights) are also suppressed so the handout leads with the
     lesson kit itself. */
  body.lesson-kit-printing .results,
  body.lesson-kit-printing .verse-compare,
  body.lesson-kit-printing .verse-study-grid,
  body.lesson-kit-printing .verse-mtlxx,
  body.lesson-kit-printing .variant-apparatus,
  body.lesson-kit-printing .targum-panel,
  body.lesson-kit-printing .commentary,
  body.lesson-kit-printing .breadcrumbs,
  body.lesson-kit-printing .search,
  body.lesson-kit-printing .support,
  body.lesson-kit-printing .ad-support-panel,
  body.lesson-kit-printing .verse-highlights {
    display: none !important;
  }

  /* The lesson kit is normally inside <main> which may have a top padding or
     margin set for the non-print reading layout — reset it so the handout
     starts at the top of the page. */
  body.lesson-kit-printing main {
    padding-top: 0 !important;
    margin-top: 0 !important;
  }

  /* Keep the kit's accent links readable in black-and-white printing. */
  body.lesson-kit-printing .lesson-kit a {
    color: inherit;
    text-decoration: underline;
  }
}
