/* --------------------------------------------------------------------------
   Design tokens (Sefaria-minimal refresh)
   -------------------------------------------------------------------------
   Palette + typography + spacing + radius are all declared here so every
   downstream rule references the same source. Our identity stays: warm
   cream background + deep red accent + Frank Ruhl Libre / Iowan Old Style
   serifs. What changed is the *chrome*: shadows collapse to a whisper,
   gradients disappear (``--accent-2`` now aliases ``--accent`` so any
   legacy ``linear-gradient(180deg, var(--accent-2), var(--accent))`` reads
   as a flat fill), the border palette gains a soft "hair" hue for 1 px
   dividers, and we get a spacing scale so hero panels, cards and grids
   share the same rhythm.
   ------------------------------------------------------------------------- */
:root {
    /* Surfaces */
    --bg: #f8f6f1;
    --surface: #ffffff;
    --surface-2: #f2ede1;
    --surface-soft: #fbf9f4;

    /* Ink scale */
    --ink: #2a2a2a;
    --ink-2: #4a4a4a;
    --ink-muted: #6b6b6b;
    --muted: #6b6b6b;
    --muted-2: #8a8a8a;

    /* Borders / hairlines */
    --hair: #e6e0d1;
    --hair-strong: #d9d3c6;
    --border: #d9d3c6;

    /* Accent (stays deep red — used sparingly for CTAs, focus, verse
       markers and the category strip). ``--accent-2`` is kept as an alias
       so historical ``linear-gradient(180deg, var(--accent-2), var(--accent))``
       calls collapse to a solid flat fill without a global rewrite. */
    --accent: #8a1e1e;
    --accent-2: var(--accent);
    --accent-strong: #6c1616;

    /* Per-category accent slot (overridden in ``.card[data-cat=...]``
       and ``[data-cat=...]`` roots below). Default to the site red so
       any surface that hasn't opted in still renders sensibly. */
    --cat-accent: var(--accent);

    /* Semantic colours (unchanged intent, quieter contrast) */
    --success: #237a4b;
    --info: #285e9c;
    --warn: #b47b00;
    --error: #a71d1d;

    /* Elevation. Default cards live flat; ``--shadow-soft`` only lifts
       modals, sticky headers and the search drawer. Legacy
       ``var(--shadow)`` sites collapse to none and read as flat. */
    --shadow: none;
    --shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.04);
    --shadow-modal: 0 12px 32px rgba(0, 0, 0, 0.14);

    /* Radius */
    --radius-sm: 6px;
    --radius: 8px;
    --radius-lg: 12px;

    /* Spacing rhythm (4px base) */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;

    /* Typography */
    --font-en: 'Iowan Old Style', 'Palatino Linotype', 'Georgia', serif;
    --font-he: 'Frank Ruhl Libre', 'David', 'SBL Hebrew', 'Times New Roman', serif;
    --font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Assistant',
               'Rubik', 'Helvetica Neue', Arial, sans-serif;
}

/* Category accent colour map — muted paper-stamp hues, one per top-level
   Sefaria category, so each surface (home tile, category page, reader
   header) can carry a quiet identity without the palette turning into
   pop-art. Fallback stays ``--accent`` (deep red) for anything the map
   doesn't know about. */
[data-cat="Tanakh"],
[data-cat="Torah"]                  { --cat-accent: #8a1e1e; }
[data-cat="Mishnah"]                { --cat-accent: #4d6a4b; }
[data-cat="Talmud"]                 { --cat-accent: #2f5d68; }
[data-cat="Midrash"]                { --cat-accent: #8b5a2b; }
[data-cat="Halakhah"]               { --cat-accent: #5a6a2e; }
[data-cat="Kabbalah"]               { --cat-accent: #5c3a68; }
[data-cat="Liturgy"]                { --cat-accent: #7a5a1a; }
[data-cat="Jewish Thought"]         { --cat-accent: #385a80; }
[data-cat="Tosefta"]                { --cat-accent: #4d6a4b; }
[data-cat="Chasidut"]               { --cat-accent: #6a4a2e; }
[data-cat="Musar"]                  { --cat-accent: #7a5a1a; }
[data-cat="Responsa"]               { --cat-accent: #5a6a2e; }
[data-cat="Second Temple"]          { --cat-accent: #7c6a3f; }
[data-cat="Reference"]              { --cat-accent: #4a4a4a; }

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-en);
    line-height: 1.5;
}
/* Sticky footer: body is a flex column, footer margin-top:auto pushes it
   to the viewport bottom whenever the main content is shorter than the
   window. Works for every page variant (regular, reader, error, etc.). */
html { height: 100%; }
body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}
.site-footer { margin-top: auto; flex-shrink: 0; }

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}
/* Admin users (and other --wide panels) need the full viewport —
   the shared .container 1200px cap is what forced the inner scrollbar. */
main.container:has(.admin-panel--wide) {
    max-width: none;
    width: 100%;
    padding-inline: 8px;
}

/* -----------------------------------------------------------------------
   Site header — slim (~72 px), flat, 1 px hairline below. Brand + user
   avatar pin to the viewport edges (RTL: brand to the physical right,
   avatar to the left), the nav + search stay inside the container.
   ----------------------------------------------------------------------- */
.site-header {
    background: var(--bg);
    border-bottom: 1px solid var(--hair-strong);
    box-shadow: none;
    position: sticky;
    top: 0;
    z-index: 10;
}

.header-inner {
    display: flex;
    gap: var(--space-5);
    align-items: center;
    padding-inline: var(--space-5);
    padding-block: var(--space-3);
    min-height: 72px;
    flex-wrap: wrap;
    /* Reserve room on each edge for the pinned brand wordmark + avatar. */
    padding-inline-start: 300px;  /* wordmark + beta notice + breathing room */
    padding-inline-end: 168px;    /* 72 avatar + gap + logout pill + offset */
}

.brand {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    inset-inline-start: var(--space-5);
    inset-inline-end: auto;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    line-height: 0;
    z-index: 2;
}
.brand-logo {
    display: block;
    height: 44px;
    width: auto;
    max-width: 180px;
    border-radius: 0;
    box-shadow: none;
    transition: filter 150ms ease;
}
.beta-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px;
    border: 1px solid #d7aa45;
    border-radius: 999px;
    background: #fff7df;
    color: #76520a;
    line-height: 1.1;
    white-space: nowrap;
}
.beta-badge strong {
    font-size: .72rem;
    letter-spacing: .02em;
}
.beta-badge small {
    padding-inline-start: 6px;
    border-inline-start: 1px solid rgba(118, 82, 10, .25);
    font-size: .68rem;
}
@media (max-width: 900px) {
    .header-inner {
        padding-inline-start: var(--space-5);
        padding-inline-end: var(--space-5);
        min-height: 0;
    }
    .brand {
        position: static;
        transform: none;
        margin-inline-start: 0;
    }
    .brand-logo { height: 36px; max-width: 150px; }
    .beta-badge small { display: none; }
}
.brand:hover .brand-logo {
    filter: brightness(1.05);
}
.brand:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* -------------------------------------------------- User-nav (far left)
   Mirror of ``.brand``: absolute-positioned relative to the sticky
   .site-header so it hugs the *viewport* left edge instead of being
   clamped inside the centered 1200 px .container band.  In RTL,
   "inline-end" resolves to the physical left. */
.user-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    inset-inline-end: 20px;
    inset-inline-start: auto;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    z-index: 2;
}

.user-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--hair-strong);
    box-shadow: none;
    color: var(--ink-2);
    text-decoration: none;
    font-weight: 600;
    font-size: 1.9rem;
    transition: border-color 120ms, background-color 120ms;
}
.user-avatar:hover {
    border-color: var(--accent);
}
.user-avatar:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.user-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    -webkit-user-drag: none;
    user-drag: none;
}
.user-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: var(--surface-2);
    color: var(--ink-2);
    font-family: var(--font-en);
    letter-spacing: 0.02em;
}

/* Small avatar shown inline in the admin users table — distinct from
   the large 72px header/settings ``.user-avatar`` since a table row
   needs a compact, single-line-height circle. */
.admin-user-cell {
    display: flex;
    align-items: center;
    gap: 8px;
}
.admin-table-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--hair-strong);
    color: var(--ink-2);
    font-weight: 600;
    font-size: 0.85rem;
    font-family: var(--font-en);
}
.admin-table-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.admin-num {
    font-variant-numeric: tabular-nums;
}
.admin-table-avatar.is-clickable {
    cursor: zoom-in;
    transition: border-color 120ms, transform 120ms;
}
.admin-table-avatar.is-clickable:hover,
.admin-table-avatar.is-clickable:focus-visible {
    border-color: var(--accent);
    transform: scale(1.08);
    outline: none;
}

/* Full-size avatar popup — click a thumbnail in an admin table to see
   the original image. Single reusable overlay per page. */
.avatar-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(20, 16, 14, 0.82);
    padding: 32px;
    animation: avatar-lightbox-fade 140ms ease-out;
}
.avatar-lightbox[hidden] { display: none; }
@keyframes avatar-lightbox-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}
.avatar-lightbox-fig {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    max-width: min(90vw, 960px);
}
.avatar-lightbox-fig img {
    max-width: 100%;
    max-height: 85vh;
    border-radius: 12px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
    background: var(--surface-2);
}
.avatar-lightbox-fig figcaption {
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
    text-align: center;
}
.avatar-lightbox-close {
    position: absolute;
    top: 18px;
    inset-inline-end: 22px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 120ms;
}
.avatar-lightbox-close:hover,
.avatar-lightbox-close:focus-visible {
    background: rgba(255, 255, 255, 0.24);
    outline: none;
}

.inline-form {
    display: inline-flex;
    margin: 0;
    padding: 0;
}

.focus-max-form,
.focus-edit-form {
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.focus-text-input {
    min-width: 7rem;
    max-width: 12rem;
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-family: var(--font-he), serif;
}
.focus-max-input {
    width: 4.5rem;
    padding: 4px 6px;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-variant-numeric: tabular-nums;
}
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Narrow viewports: same treatment as .brand — drop back into flow so
   the header row doesn't lay text under the absolutely-positioned
   pill. */
@media (max-width: 900px) {
    .user-nav {
        position: static;
        transform: none;
        margin-inline-end: 8px;
    }
    .user-avatar { width: 72px; height: 72px; font-size: 1.9rem; }
}

.site-nav {
    display: flex;
    gap: 18px;
    flex: 1;
    align-items: center;
    flex-wrap: nowrap;
}
.site-nav a {
    color: var(--ink-2);
    text-decoration: none;
    padding: 6px 4px;
    font-family: var(--font-ui);
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: 0;
    border-radius: 0;
    border-bottom: 1px solid transparent;
    transition: color 120ms ease, border-color 120ms ease;
    white-space: nowrap;
    flex-shrink: 0;
}
.site-nav a:hover {
    background: transparent;
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.site-nav a[aria-current="page"],
.site-nav a.is-current {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
@media (max-width: 900px) {
    .site-nav { gap: 12px; }
    .site-nav a { font-size: 0.95rem; padding: 6px 4px; }
}

/* ----------------------------------------------------------- login panel
   Google-only auth: single button + a short lede explaining the flow.
   Panel is centred, deliberately narrow so the CTA stays the focal
   point of the page. */
.auth-panel {
    max-width: 460px;
    margin: 40px auto;
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    padding: 32px 28px;
    box-shadow: none;
    text-align: center;
}
.auth-panel h1 { margin: 0 0 12px; font-size: 1.6rem; }
.auth-lede {
    color: var(--ink-muted);
    margin: 0 0 20px;
    line-height: 1.55;
}
.btn-google {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: #ffffff;
    color: #202124;
    border: 1px solid #dadce0;
    border-radius: var(--radius-sm);
    padding: 10px 20px;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    font-weight: 500;
    text-decoration: none;
    transition: background 120ms ease, border-color 120ms ease;
    box-shadow: none;
}
.btn-google:hover {
    background: #f8f9fa;
    border-color: #b8bcbf;
    box-shadow: none;
}
.btn-google:focus-visible {
    outline: 2px solid #4285F4;
    outline-offset: 2px;
}
.btn-google-large {
    padding: 12px 26px;
    font-size: 1.05rem;
    min-width: 260px;
}
.btn-google .google-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
}
.auth-google-missing {
    background: var(--surface-2);
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    padding: 16px;
    text-align: start;
}
.auth-google-missing code { direction: ltr; }

/* ---- Header quick-search (compact) ----------------------------------- */
.quick-search { display: flex; gap: 8px; align-items: center; }
.quick-search input {
    padding: 7px 32px 7px 12px;
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius-sm);
    min-width: 220px;
    background-color: var(--surface);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6b6b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><path d='m20 20-3.5-3.5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 15px 15px;
    font-family: var(--font-ui);
    font-size: 0.92rem;
    color: var(--ink);
    box-shadow: none;
    transition: border-color 120ms, box-shadow 120ms;
}
.quick-search input::placeholder { color: var(--muted-2); opacity: 1; }
.quick-search input:hover { border-color: var(--muted-2); }
.quick-search input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
    background-color: var(--surface);
}
.quick-search button {
    padding: 7px 14px;
    font-size: 0.9rem;
}

main.container { padding-top: 24px; padding-bottom: 40px; }

.site-footer {
    border-top: 1px solid var(--border);
    background: var(--bg);
    margin-top: auto;
    color: var(--muted);
    font-size: 0.875rem;
}

/* ---- main footer body ---- */
.footer-body {
    display: flex;
    gap: 48px;
    padding: 40px 0 32px;
    align-items: flex-start;
}

/* brand column */
.footer-brand-col {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 220px;
}
.footer-logo { display: inline-block; }
.footer-logo img { display: block; }
.footer-tagline {
    margin: 0;
    font-size: 0.85rem;
    color: var(--ink-muted);
    line-height: 1.4;
}
.footer-tagline-sub { color: var(--muted-2); font-size: 0.78rem; }

/* link columns */
.footer-links {
    flex: 1;
    display: flex;
    gap: 40px;
    justify-content: flex-end;
    flex-wrap: wrap;
}
.footer-col {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 100px;
}
.footer-col-title {
    font-weight: 700;
    font-size: 0.78rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ink);
    margin-bottom: 2px;
}
.footer-col a {
    color: var(--muted);
    text-decoration: none;
    transition: color .15s;
    font-size: 0.875rem;
}
.footer-col a:hover { color: var(--accent); }

/* ---- bottom strip ---- */
.footer-bottom {
    border-top: 1px solid var(--border);
    padding: 12px 0;
}
.footer-bottom-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 0.8rem;
    color: var(--muted-2);
}
.footer-attribution a {
    color: var(--muted);
    text-decoration: none;
}
.footer-attribution a:hover { color: var(--accent); text-decoration: underline; }

/* responsive */
@media (max-width: 700px) {
    .footer-body { flex-direction: column; gap: 28px; padding: 28px 0 20px; }
    .footer-brand-col { max-width: 100%; }
    .footer-links { justify-content: flex-start; gap: 24px; }
    .footer-bottom-inner { flex-direction: column; align-items: flex-start; }
}

h1, h2, h3, h4 { font-family: var(--font-en); color: var(--ink); letter-spacing: -0.005em; }
h1 { font-size: 2rem; margin-top: 0; font-weight: 700; }
h2 { margin-top: var(--space-6); font-size: 1.5rem; font-weight: 600; }
h3 { font-size: 1.2rem; font-weight: 600; }

/* Section title used above card grids on home / category / search pages.
   Sits with a muted lead-in rule so it lands quietly against the page. */
.section-title {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    color: var(--ink);
    margin: var(--space-6) 0 var(--space-4);
    font-size: 1.35rem;
    font-weight: 600;
}
.section-title::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--hair);
}

.he { font-family: var(--font-he); }

/* Any element explicitly marked as Hebrew (dir="rtl") right-aligns by default.
   Inline Hebrew spans inside LTR flows keep their bidirectional isolation.
   The `.book-table` variants below carry extra specificity so they beat the
   generic `.book-table td { text-align: left }` rule further down the file. */
[dir="rtl"] { text-align: right; }
td[dir="rtl"], th[dir="rtl"] { text-align: right; direction: rtl; }
.book-table td[dir="rtl"],
.book-table th[dir="rtl"] {
    text-align: right;
    direction: rtl;
}

/* Book/gematria tables: cells whose primary content is Hebrew (has a
   .he-primary child) get right-aligned automatically. */
.book-table td:has(> .he-primary),
.book-table td:has(> a.he-primary),
.book-table td.he-cell {
    text-align: right;
    direction: rtl;
}
.book-table td:has(> .he-primary) .en-secondary,
.book-table td:has(> a.he-primary) .en-secondary,
.book-table td.he-cell .en-secondary {
    direction: ltr;
    text-align: right;
    display: block;
    margin-top: 2px;
}

/* Hebrew-first display: HE is the primary label, EN is muted metadata. */
.he-primary {
    font-family: var(--font-he);
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--ink);
    display: inline-block;
}
.en-secondary {
    display: inline-block;
    color: var(--ink-muted);
    font-size: 0.85rem;
    margin-left: 8px;
    font-family: var(--font-en);
}
/* When HE-primary and EN-secondary stack in cells or headers, keep them tidy. */
h1 .he-primary { font-size: 2.15rem; }
h1 .en-secondary { font-size: 1rem; vertical-align: middle; }
td .en-secondary, li .en-secondary { display: block; margin-left: 0; margin-top: 2px; }
.card-title .he-primary { font-size: 1.35rem; }
.card-title .en-secondary { font-size: 0.85rem; margin-left: 10px; }
.breadcrumbs .he { font-family: var(--font-he); }

/* -----------------------------------------------------------------------
   Hero panel (home + section landing pages) — flat, airy, no shadow.
   ``--surface-soft`` gives it a warm off-white against the cream body.
   ----------------------------------------------------------------------- */
.hero {
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    padding: var(--space-6) var(--space-5);
    border-radius: var(--radius-lg);
    box-shadow: none;
    margin-bottom: var(--space-5);
}
.hero h1 { margin-top: 0; font-size: 2.2rem; letter-spacing: -0.01em; }
.hero .lede { color: var(--muted); max-width: 640px; font-size: 1.05rem; line-height: 1.6; }
/* ---- Hero search (home page) ----------------------------------------- */
.hero-search {
    display: flex;
    gap: var(--space-2);
    max-width: 780px;
}
.hero-search input {
    flex: 1;
    min-width: 0;
    padding: 12px 44px 12px 18px;
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius);
    background-color: var(--surface);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6b6b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='7'/><path d='m20 20-3.5-3.5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 18px 18px;
    font-family: var(--font-ui);
    font-size: 1rem;
    color: var(--ink);
    box-shadow: none;
    transition: border-color 120ms, box-shadow 120ms;
}
.hero-search input::placeholder { color: var(--muted-2); opacity: 1; }
.hero-search input:hover { border-color: var(--muted-2); }
.hero-search input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
    background-color: var(--surface);
}
/* Suppress Chromium's built-in search-cancel X and speech mic buttons
   so they don't collide with our own magnifying-glass icon or leave a
   dead zone at the field's edge. */
.hero-search input::-webkit-search-decoration,
.hero-search input::-webkit-search-cancel-button,
.hero-search input::-webkit-search-results-button,
.hero-search input::-webkit-search-results-decoration,
.quick-search input::-webkit-search-decoration,
.quick-search input::-webkit-search-cancel-button,
.quick-search input::-webkit-search-results-button,
.quick-search input::-webkit-search-results-decoration,
.form-row input[type="search"]::-webkit-search-decoration,
.form-row input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    display: none;
}

/* Note: hero-search button styling now inherits from the naked-button
   rule up in the buttons section so all "חיפוש" buttons match. */

/* -----------------------------------------------------------------------
   Card grid + card (category / book cards) — flat surface, 1 px hair
   border, no shadow, no translate on hover. The 3 px top strip carries
   the category accent from ``[data-cat=...]``; on hover the surface
   nudges to ``--surface-soft`` and the border darkens to ``--hair-strong``.
   ----------------------------------------------------------------------- */
.card-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-5);
}
/* Collapse to 2 columns on tablets, 1 column on phones so cards keep
   enough width to stay readable. */
@media (max-width: 900px) {
    .card-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .card-grid { grid-template-columns: 1fr; }
}
.card {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-top: 3px solid var(--cat-accent);
    border-radius: var(--radius);
    padding: var(--space-4) var(--space-4) var(--space-3);
    text-decoration: none;
    color: inherit;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-height: 118px;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.card:hover {
    background: var(--surface-soft);
    border-color: var(--hair-strong);
    border-top-color: var(--cat-accent);
}
.card:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.card-title {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-family: var(--font-he);
    font-weight: 600;
    font-size: 1.35rem;
    line-height: 1.3;
    color: var(--ink);
}
.card-title .he { font-size: 1.5rem; }
.card-desc {
    color: var(--muted);
    font-size: 0.92rem;
    line-height: 1.5;
    margin: 0;
    /* Clamp descriptions to 2 lines so cards keep an even rhythm. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.card-meta { color: var(--muted-2); font-size: 0.8rem; margin-top: auto; }

/* Admin-only per-card cache indicator. Fat progress bar collapses to a
   2 px hairline in the category accent so it recedes visually. */
.card-cache { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; }
.card-cache-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    font-size: 0.78rem;
    color: var(--muted);
}
.card-cache-bar { height: 2px; margin-top: 0; background: var(--surface-2); }
.card-cache-bar .progress-bar { background: var(--cat-accent); }
.card-cache-error { color: var(--error); }

/* Legacy left-stripe cache hints — kept for admins on the older paths but
   flattened to 2 px so they read as a whisper next to the category top strip. */
.card.cache-full    { box-shadow: inset 2px 0 0 var(--success); }
.card.cache-partial { box-shadow: inset 2px 0 0 var(--info); }
.card.cache-empty   { box-shadow: inset 2px 0 0 var(--hair-strong); }
.card.cache-full    .card-cache-bar .progress-bar { background: var(--success); }
.card.cache-partial .card-cache-bar .progress-bar { background: var(--info); }

.badge-outline {
    background: transparent;
    color: var(--ink-muted);
    border: 1px solid var(--border);
}

/* ----------------------------------------------------------- book cards
   Book listings (category → books) now use the same ``.card-grid`` +
   ``.card`` scaffolding as category cards.  The whole tile is the link;
   we removed the historical "פתיחה / הורדה" buttons so every user has
   exactly one interaction — click to open.  ``.book-card`` is a light
   variant with a slightly smaller minimum footprint since a book title
   is short and we want a denser grid than at the category level. */
.card-grid.book-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
}
@media (max-width: 900px) {
    .card-grid.book-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
    .card-grid.book-grid { grid-template-columns: 1fr; }
}
.card.book-card {
    min-height: 84px;
    padding: 12px 14px 10px;
    gap: 6px;
    border-top-width: 2px;
}
.card.book-card .card-title { font-size: 1.05rem; }
.card.book-card .card-title .he { font-size: 1.2rem; line-height: 1.35; }
.card.book-card .card-cache-slot {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: auto;
}
.card.book-card .card-cache-slot .cache-count {
    color: var(--ink-muted);
    font-size: 0.8rem;
}
.card.book-card .card-cache-slot .progress { flex: 1 1 100%; height: 6px; }

/* ------------------------------------------------------- public inventory */
.inventory-page {
    padding-block: var(--space-6) var(--space-8);
}
.inventory-hero {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-6);
    padding: var(--space-6);
    margin-bottom: var(--space-5);
    background: linear-gradient(135deg, var(--surface-soft), var(--surface));
    border: 1px solid var(--hair);
    border-top: 4px solid var(--accent);
    border-radius: var(--radius-lg);
}
.inventory-hero h1 {
    margin: 3px 0 8px;
    font-family: var(--font-he);
    font-size: clamp(1.9rem, 4vw, 2.8rem);
    color: var(--ink);
}
.inventory-hero .lede {
    max-width: 720px;
    margin: 0;
}
.inventory-eyebrow {
    color: var(--accent);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
}
.inventory-stats {
    display: flex;
    flex: 0 0 auto;
    gap: 1px;
    overflow: hidden;
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    background: var(--hair);
}
.inventory-stats div {
    display: grid;
    min-width: 105px;
    padding: 12px 16px;
    text-align: center;
    background: var(--surface);
}
.inventory-stats strong {
    font-size: 1.45rem;
    color: var(--accent);
}
.inventory-stats span {
    color: var(--muted);
    font-size: .75rem;
}
.inventory-toolbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: 12px 0;
    background: var(--page-bg, #f8f5f0);
}
.inventory-search {
    display: flex;
    align-items: center;
    width: min(560px, 100%);
    border: 1px solid var(--hair-strong);
    border-radius: 999px;
    background: var(--surface);
}
.inventory-search > span {
    padding-inline: 14px 0;
    color: var(--muted);
    font-size: 1.3rem;
}
.inventory-search input {
    width: 100%;
    padding: 11px 12px;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ink);
    font: inherit;
}
.inventory-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(138, 30, 30, .1);
}
.inventory-result-count {
    white-space: nowrap;
    color: var(--muted);
    font-size: .85rem;
}
.inventory-category-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 4px 0 var(--space-5);
    overflow: visible;
}
.inventory-category-chip {
    flex: 0 0 auto;
    padding: 7px 12px;
    border: 1px solid var(--hair);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink-muted);
    cursor: pointer;
    font: inherit;
}
.inventory-category-chip span {
    margin-inline-start: 5px;
    color: var(--muted);
    font-size: .75rem;
}
.inventory-category-chip--new {
    border-color: #c89b32;
    background: #fff8e6;
    color: #76520a;
}
.inventory-category-chip:hover,
.inventory-category-chip.is-active {
    border-color: var(--accent);
    background: var(--accent);
    color: #fff;
}
.inventory-category-chip.is-active span { color: rgba(255, 255, 255, .75); }
.inventory-groups {
    display: grid;
    gap: var(--space-6);
}
.inventory-list-loading {
    padding: 36px 16px;
    text-align: center;
    color: var(--muted);
}
.inventory-load-more-wrap {
    display: flex;
    justify-content: center;
    padding-top: var(--space-5);
}
.inventory-group {
    scroll-margin-top: 90px;
}
.inventory-group-head {
    display: flex;
    align-items: end;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--hair);
}
.inventory-group-head h2 {
    margin: 0;
    font-family: var(--font-he);
    font-size: 1.65rem;
}
.inventory-group-head p {
    max-width: 760px;
    margin: 4px 0 0;
    color: var(--muted);
    font-size: .85rem;
}
.inventory-group-head > a {
    flex: 0 0 auto;
    color: var(--accent);
    font-size: .85rem;
    text-decoration: none;
}
.inventory-group-head > a:hover { text-decoration: underline; }
.inventory-book-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}
.inventory-book {
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
}
.inventory-book[open] {
    border-color: var(--hair-strong);
    grid-column: span 3;
}
.inventory-book summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 74px;
    padding: 12px 14px;
    cursor: pointer;
    list-style: none;
}
.inventory-book summary::-webkit-details-marker { display: none; }
.inventory-book summary:hover { background: var(--surface-soft); }
.inventory-book summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.inventory-book-copy {
    display: grid;
    min-width: 0;
}
.inventory-book-copy strong {
    overflow: hidden;
    color: var(--ink);
    font-family: var(--font-he);
    font-size: 1.08rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.inventory-book-copy small {
    overflow: hidden;
    color: var(--muted);
    font-size: .72rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.inventory-expand-label {
    flex: 0 0 auto;
    color: var(--accent);
    font-size: .75rem;
}
.inventory-book[open] .inventory-expand-label { font-size: 0; }
.inventory-book[open] .inventory-expand-label::after {
    content: "סגירת מקורות";
    font-size: .75rem;
}
.inventory-book-body {
    padding: 14px;
    border-top: 1px solid var(--hair);
    background: var(--surface-soft);
}
.inventory-loading {
    padding: 8px 0;
    color: var(--muted);
}
.inventory-section-links {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin-bottom: 14px;
}
.inventory-section-links a {
    padding: 6px 10px;
    border: 1px solid var(--hair);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font-family: var(--font-he);
    font-size: .88rem;
    text-decoration: none;
}
.inventory-section-links a:hover {
    border-color: var(--accent);
    color: var(--accent);
}
.inventory-section-links--grouped {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 12px 18px;
    margin-bottom: 14px;
    direction: rtl;
}
.inventory-parasha-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px 10px;
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    background: var(--surface-soft, var(--surface));
    flex: 0 1 auto;
    min-width: min(100%, 11rem);
    max-width: 100%;
    box-sizing: border-box;
}
.inventory-parasha-head {
    font-family: var(--font-he);
    font-weight: 700;
    font-size: .95rem;
    color: var(--ink);
    text-decoration: none;
    align-self: flex-start;
    white-space: nowrap;
}
.inventory-parasha-head:hover {
    color: var(--accent);
}
.inventory-parasha-group .inventory-section-links {
    margin-bottom: 0;
}
.inventory-open-book { display: inline-flex; }
.inventory-empty {
    margin-top: var(--space-6);
    padding: 42px 20px;
    text-align: center;
    border: 1px dashed var(--hair-strong);
    border-radius: var(--radius-lg);
    color: var(--muted);
}
.inventory-empty strong,
.inventory-empty span { display: block; }
.inventory-empty strong {
    margin-bottom: 5px;
    color: var(--ink);
    font-size: 1.1rem;
}
@media (max-width: 900px) {
    .inventory-hero { align-items: stretch; flex-direction: column; }
    .inventory-stats { align-self: flex-start; }
    .inventory-book-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .inventory-book[open] { grid-column: span 2; }
}
@media (max-width: 560px) {
    .inventory-page { padding-top: var(--space-4); }
    .inventory-hero { padding: var(--space-4); }
    .inventory-stats { width: 100%; }
    .inventory-stats div { min-width: 0; width: 50%; }
    .inventory-toolbar { align-items: stretch; flex-direction: column; gap: 6px; }
    .inventory-book-grid { grid-template-columns: 1fr; }
    .inventory-book[open] { grid-column: span 1; }
    .inventory-group-head { align-items: flex-start; flex-direction: column; }
}

/* ----------------------------------------------- book auto-download page */
.book-download {
    max-width: 720px;
    margin: 32px auto;
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    padding: 32px 28px;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    gap: 20px;
}
.book-download-head h1 {
    margin: 0 0 6px 0;
    font-size: 1.9rem;
}
.book-download-head p { margin: 0; }
.book-download-bar { height: 8px; }
.book-download-bar .progress-bar {
    background: var(--accent);
}
.book-download-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}
.book-download-stats .stat {
    background: var(--surface-2);
    border-radius: var(--radius);
    padding: 10px 12px;
    text-align: center;
}
.book-download-stats .stat-label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
}
.book-download-stats .stat-value {
    font-size: 1.4rem;
    font-weight: 700;
    margin-top: 2px;
}
.book-download-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}
.book-download-error {
    background: #fdecec;
    border: 1px solid #f4c6c6;
    color: var(--error);
    padding: 10px 14px;
    border-radius: var(--radius);
    white-space: pre-wrap;
    word-break: break-word;
}

/* -------------------------------------------------- tracked books filter */
.tracked-head {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 18px 0 12px;
}
.tracked-head h2 { margin: 0; }
.tracked-head p { margin: 0; }
.tracked-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}
.tracked-filter-bar .chip {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--fg);
    font-size: 0.85em;
    text-decoration: none;
    transition: background 0.12s ease, color 0.12s ease;
}
.tracked-filter-bar .chip:hover {
    background: var(--surface-2);
}
.tracked-filter-bar .chip.is-active {
    background: var(--accent, #2b6aa0);
    color: #fff;
    border-color: var(--accent, #2b6aa0);
}

/* -------------------------------------------------- downloads timeline */
:root {
    --tl-cached-books:    #4a7f2e;
    --tl-cached-extras:   #b58a2f;
    --tl-inflight-books:  #2b6aa0;
    --tl-inflight-extras: #7f5d8a;
}
.downloads-timeline {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 18px;
    box-shadow: var(--shadow);
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.downloads-timeline .timeline-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    flex-wrap: wrap;
}
.downloads-timeline .timeline-head h2 { margin: 0; }
.downloads-timeline .timeline-head p { margin: 4px 0 0; }
.downloads-timeline .timeline-controls {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.downloads-timeline .timeline-controls select {
    padding: 4px 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    font: inherit;
}
.timeline-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    font-size: 0.85em;
    color: #444;
}
.tl-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.03);
    border: 1px solid rgba(0, 0, 0, 0.06);
}
.tl-chip .tl-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
    flex: none;
}
.tl-chip-cached-books    .tl-dot { background: var(--tl-cached-books); }
.tl-chip-cached-extras   .tl-dot { background: var(--tl-cached-extras); }
.tl-chip-inflight-books  .tl-dot { background: var(--tl-inflight-books); }
.tl-chip-inflight-extras .tl-dot { background: var(--tl-inflight-extras); }

.timeline-canvas-wrap {
    position: relative;
    width: 100%;
    /* Fixed height for the main cumulative chart; throughput below gets
       its own override. The canvas element itself sizes to fill this
       box (see [data-timeline-canvas] width/height rules). */
    height: 220px;
}
.timeline-canvas-wrap canvas {
    width: 100%;
    height: 100%;
    display: block;
}
.timeline-throughput-wrap {
    height: 120px;
    margin-top: 4px;
    /* Reserve vertical space for the subhead label so it doesn't shift
       the canvas when it renders. */
    padding-top: 22px;
}
.timeline-subhead {
    position: absolute;
    top: 0;
    left: 8px;
    font-weight: 600;
    letter-spacing: 0.02em;
}
/* ``[hidden]`` and ``.timeline-empty`` share specificity (0-1-0), so the
   later rule wins — meaning ``display: flex`` here would override the
   user-agent's ``[hidden] { display: none }`` and the message would
   leak through the chart. Scope our layout to :not([hidden]) so the
   hidden attribute keeps working. */
.timeline-empty:not([hidden]) {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 20px;
}
.timeline-empty[hidden] { display: none !important; }

/* -------------------------------------------------- downloads DB panel */
.db-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 18px;
    box-shadow: var(--shadow);
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.db-panel-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
}
.db-panel-head h2 { margin: 0; }
.db-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 12px;
}
.db-rows-table td:nth-child(2) {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    text-align: right;
    min-width: 120px;
}

/* -------------------------------------------------- new sources panel */
/* Hourly TOC watcher — surfaces books just discovered upstream. */
.new-sources-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 18px;
    box-shadow: var(--shadow);
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.new-sources-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}
.new-sources-head h2 { margin: 0 0 4px; }
.new-sources-head p { margin: 0; max-width: 720px; }
.new-sources-actions { display: flex; gap: 8px; align-items: center; }

.new-sources-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    align-items: baseline;
    line-height: 1.7;
    padding: 6px 10px;
    background: #fdfbf4;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-variant-numeric: tabular-nums;
}
/* Status pill — colour reflects current watcher health. */
.watcher-status {
    padding: 0 8px;
    border-radius: 999px;
    font-weight: 600;
    background: #eee;
    color: #555;
}
.watcher-status-success { background: #d4edda; color: #155724; }
.watcher-status-info    { background: #d1ecf1; color: #0c5460; }
.watcher-status-error   { background: #f8d7da; color: #721c24; }
.watcher-status-muted   { background: #eee; color: #555; }

.new-sources-empty {
    padding: 12px 14px;
    background: #fdfbf4;
    border: 1px dashed var(--border);
    border-radius: 6px;
    margin: 0;
}
.new-sources-table th,
.new-sources-table td {
    vertical-align: top;
}
.new-sources-table td .progress {
    max-width: 140px;
    margin-bottom: 2px;
}

/* -----------------------------------------------------------------------
   Category page — quiet 3 px accent bar under the breadcrumbs pulls the
   category colour into the page frame. Body inherits the ``data-cat``
   from ``.category-page`` so book cards + subcategory cards below also
   pick up the same accent through their ``[data-cat=...]`` chains.
   ----------------------------------------------------------------------- */
.category-page > .breadcrumbs {
    padding-bottom: 8px;
    border-bottom: 3px solid var(--cat-accent);
    margin-bottom: var(--space-4);
}
.category-header {
    margin-bottom: var(--space-5);
}
.category-header h1 { font-size: 2rem; margin: 0 0 6px; }
.category-header .lede { color: var(--muted); font-size: 1rem; max-width: 780px; }

.breadcrumbs {
    color: var(--muted);
    margin-bottom: 12px;
    font-family: var(--font-ui);
    font-size: 0.88rem;
}
.breadcrumbs a { color: var(--muted); text-decoration: none; transition: color 120ms; }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs .sep { margin: 0 6px; color: var(--muted-2); }
.breadcrumbs > *:last-child { color: var(--ink); }

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}
.section-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---- Buttons ---------------------------------------------------------
   Flat treatment: 1 px hairline outline for secondary, solid accent fill
   for primary, ghost stays transparent. Radius 6 px, no drop shadows,
   no translate on hover — hover just repaints the surface.
   -------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: var(--surface);
    border: 1px solid var(--hair-strong);
    color: var(--ink);
    padding: 8px 16px;
    border-radius: var(--radius-sm);
    text-decoration: none;
    cursor: pointer;
    font-family: var(--font-ui);
    font-size: 0.92rem;
    font-weight: 500;
    line-height: 1.2;
    box-shadow: none;
    transition: background-color 120ms, border-color 120ms, color 120ms;
    -webkit-user-select: none;
    user-select: none;
    white-space: nowrap;
}
.btn:hover {
    background: var(--surface-2);
    border-color: var(--muted-2);
    box-shadow: none;
}
.btn:active { background: var(--surface-2); }
.btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.btn.primary {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    box-shadow: none;
}
.btn.primary:hover {
    background: var(--accent-strong);
    border-color: var(--accent-strong);
    box-shadow: none;
    color: #fff;
}
.btn.primary:active { background: var(--accent-strong); }
.btn.danger {
    color: var(--error);
    border-color: #e8bcbc;
    background: var(--surface);
}
.btn.danger:hover {
    background: #fbe9e9;
    border-color: var(--error);
}
.btn.small { padding: 5px 10px; font-size: 0.82rem; border-radius: 4px; }
.btn:disabled {
    opacity: 0.5;
    cursor: default;
    box-shadow: none;
}

/* Naked <button type="submit"> inside our search forms — flat accent so
   every "חיפוש" button matches ``.btn.primary``. */
.hero-search button,
.quick-search button,
form.advanced-search button[type="submit"]:not(.btn) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 18px;
    border-radius: var(--radius-sm);
    background: var(--accent);
    color: #fff;
    border: 1px solid var(--accent);
    cursor: pointer;
    font: inherit;
    font-weight: 500;
    box-shadow: none;
    transition: background-color 120ms, border-color 120ms;
}
.hero-search button:hover,
.quick-search button:hover,
form.advanced-search button[type="submit"]:not(.btn):hover {
    background: var(--accent-strong);
    border-color: var(--accent-strong);
    box-shadow: none;
}
.hero-search button:active,
.quick-search button:active,
form.advanced-search button[type="submit"]:not(.btn):active {
    background: var(--accent-strong);
}
.hero-search button:focus-visible,
.quick-search button:focus-visible,
form.advanced-search button[type="submit"]:not(.btn):focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.book-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: none;
    border: 1px solid var(--hair);
}
.book-table th, .book-table td {
    text-align: left;
    padding: 10px 14px;
    border-bottom: 1px solid var(--hair);
    vertical-align: middle;
}
.book-table th {
    background: var(--surface-2);
    font-family: var(--font-ui);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.book-table tr:last-child td { border-bottom: none; }
.cache-cell { min-width: 160px; }

.progress {
    width: 100%;
    background: var(--surface-2);
    height: 6px;
    border-radius: 3px;
    overflow: hidden;
    margin-top: 4px;
}
.progress-bar {
    background: var(--accent);
    height: 100%;
    transition: width 0.3s;
}

.badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 0.8rem;
}
.badge-success { background: #d5efdd; color: var(--success); }
.badge-info { background: #dbe7f4; color: var(--info); }
.badge-error { background: #f6d8d8; color: var(--error); }
.badge-muted { background: var(--surface-2); color: var(--ink-muted); }
.badge-verse  { background: #e8d5f0; color: #6a2f8a; }
.badge-phrase { background: #d9ecff; color: #145aa0; }
.badge-word   { background: #fff0c8; color: #7a5a00; }
.badge-count  { background: var(--accent); color: white; font-weight: 600; }
.count-cell { text-align: center; vertical-align: middle; }
.other-refs { margin-top: 4px; }
.other-refs summary { cursor: pointer; }
.other-refs ul { list-style: disc inside; margin: 4px 0 0; padding: 0 8px 0 0; font-size: 0.95rem; }
.form-row label.checkbox-label {
    flex-direction: row;
    align-items: center;
    gap: 6px;
    min-width: unset;
    flex: 0 0 auto;
}
/* Torah / Bible scope selector row. Kept as its own ``.form-row`` so
   the checkboxes sit on a clean line under the primary search controls
   with a visible section label on the right (Hebrew RTL context). */
.form-row.scope-row {
    align-items: center;
    gap: 14px;
    padding: 8px 12px;
    background: rgba(56, 132, 255, 0.06);
    border: 1px solid rgba(56, 132, 255, 0.18);
    border-radius: var(--radius);
    margin-top: 4px;
}
.form-row.scope-row .scope-label {
    font-weight: 600;
    color: var(--ink);
    margin-inline-end: 4px;
}
.form-row.scope-row .scope-check {
    padding: 4px 10px;
    border-radius: 999px;
    background: white;
    border: 1px solid var(--border);
    transition: background-color 120ms ease, border-color 120ms ease;
}
.form-row.scope-row .scope-check:hover {
    background: rgba(56, 132, 255, 0.08);
    border-color: rgba(56, 132, 255, 0.35);
}
.form-row.scope-row .scope-hint {
    flex: 1 1 200px;
    text-align: end;
}

/* Small inline hint appended to a field label; kept in the label's text
   line so it doesn't push the input off the shared row baseline. */
.field-hint { color: var(--ink-muted); font-weight: normal; font-size: 0.8em; }
.gematria-row.gematria-kind-verse  { background: rgba(232, 213, 240, 0.15); }
.gematria-row.gematria-kind-phrase { background: rgba(217, 236, 255, 0.15); }
.gematria-row.gematria-kind-word   { background: rgba(255, 240, 200, 0.15); }

/* Whole-row click affordance for search & gematria results. */
.is-clickable {
    cursor: pointer;
    transition: background-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
}
.is-clickable:hover { background-color: var(--surface-2); }
tr.is-clickable:hover { background-color: rgba(56, 132, 255, 0.08); }
.is-clickable:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
li.is-clickable:hover { background-color: var(--surface-soft); }
.cache-count { font-size: 0.85rem; color: var(--ink-muted); margin-left: 6px; }

/* -----------------------------------------------------------------------
   Reader page — thin category accent under the breadcrumbs, quiet header
   and prev/next chrome. Sizes tuned to Sefaria's spacious reader shell.
   ----------------------------------------------------------------------- */
.reader-page > .reader-layout .reader-body > .breadcrumbs {
    padding-bottom: 8px;
    border-bottom: 3px solid var(--cat-accent);
    margin-bottom: var(--space-4);
}
.reader-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
}
.reader-title { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.reader-title .he-primary { font-size: 2rem; font-weight: 700; }
.reader-title .en-secondary { font-size: 1rem; }
.reader-nav { display: flex; gap: 8px; align-items: center; }
.reader-nav.bottom { margin-top: 28px; justify-content: space-between; }

.reader-focus-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    font-size: 0.95rem;
    color: var(--ink-2);
    cursor: pointer;
    user-select: none;
}
.reader-focus-toggle input {
    width: 1.05rem;
    height: 1.05rem;
    accent-color: #5c3a68;
    cursor: pointer;
}
.reader-body.gematria-focus-hidden mark.gematria-multi-mark {
    background: transparent;
    box-shadow: none;
    padding: 0;
    cursor: inherit;
}
.reader-body.gematria-focus-hidden mark.gematria-multi-mark::after {
    display: none;
}

.reader-toolbar {
    display: flex;
    gap: 20px;
    padding: 8px 12px;
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    margin-bottom: 16px;
    box-shadow: none;
}

/* Flowing reader: the whole chapter is one continuous Hebrew paragraph,
   filling the container width. Each verse is inline; its number renders as
   a small superscript marker before the Hebrew text. Line-height opens up
   to ~1.85 for Sefaria-like breathing room on Hebrew with nikud + taamim. */
.segments {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    box-shadow: none;
    padding: 28px 32px;
    direction: rtl;
    font-family: var(--font-he);
    font-size: 1.2rem;
    line-height: 1.95;
    text-align: right;
    unicode-bidi: isolate;
    word-spacing: 0.02em;
}
.segments .segment,
.segments .segment.he-only {
    display: inline;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    box-shadow: none;
    grid-template-columns: none;
    gap: 0;
}
.segments .segment + .segment::before {
    /* Guarantee a break between verses even if the raw text lacks one. */
    content: " ";
}
.segments .segment-index {
    display: inline-block;
    font-family: var(--font-en);
    font-size: 0.7rem;
    line-height: 1;
    vertical-align: super;
    color: var(--ink-muted);
    direction: ltr;
    unicode-bidi: isolate;
    padding: 0;
    margin: 0 0.15em 0 0.25em;
    text-align: center;
}
/* Torah עליה start marker (ראשון…שביעי / מפטיר). */
.segments .aliyah-tag {
    display: inline-block;
    font-family: var(--font-he);
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.2;
    vertical-align: super;
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
    border-radius: 999px;
    padding: 1px 7px;
    margin: 0 0.2em 0 0.15em;
    white-space: nowrap;
}
.segments .segment-text.he-col {
    display: inline;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    direction: rtl;
    text-align: right;
    unicode-bidi: isolate;
}
.segments .segment-text.en-col {
    display: inline;
    color: var(--ink-muted);
    font-size: 0.9em;
    margin: 0 0.35em;
}
.segments.hide-en .en-col { display: none; }
.segments.hide-he .he-col { display: none; }

/* ---------------- Reader layout: left chapter nav + main body -------- */
.reader-layout {
    display: grid;
    grid-template-columns: 200px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
}
/* Torah פרשה nav needs more width so groups wrap side-by-side. */
.reader-layout:has(.reader-chapter-nav--parasha) {
    grid-template-columns: minmax(260px, 320px) minmax(0, 1fr);
}
.reader-layout.no-nav {
    grid-template-columns: 1fr;
}
.reader-body {
    min-width: 0;
}
.reader-chapter-nav {
    position: sticky;
    top: 20px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 12px 10px;
    box-shadow: none;
    direction: rtl;
}
/* Compact wrapping פרשות — fit viewport, no inner scrollbar. */
.reader-chapter-nav--parasha {
    max-height: none;
    overflow: visible;
    position: sticky;
    top: 12px;
    padding: 10px 8px;
}
.reader-chapter-nav-head {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 6px 10px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
}
.reader-chapter-nav-title {
    font-family: var(--font-he);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ink);
}
.reader-chapter-nav-sub {
    font-size: 0.78rem;
}
.reader-chapter-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
    gap: 4px;
    direction: rtl;
}
.reader-chapter-list li { margin: 0; padding: 0; }
.reader-chapter-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    padding: 6px 4px;
    min-height: 40px;
    border: 1px solid var(--hair);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--ink-2);
    background: var(--surface);
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.reader-chapter-link:hover {
    background: var(--surface-soft);
    border-color: var(--hair-strong);
    color: var(--ink);
}
.reader-chapter-link.is-current {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    box-shadow: 0 1px 6px rgba(138, 30, 30, 0.28);
}
.reader-chapter-link.is-current .muted { color: rgba(255,255,255,0.75); }
.reader-chapter-link .he {
    font-family: var(--font-he);
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1;
}
.reader-chapter-link .en {
    font-family: var(--font-en);
    font-size: 0.7rem;
    line-height: 1;
}

/* Torah: פרשה groups wrap next to each other; chapters nest under each. */
.reader-parasha-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px 10px;
    direction: rtl;
}
.reader-parasha-group {
    margin: 0;
    padding: 6px 8px;
    border: 1px solid var(--hair);
    border-radius: var(--radius-sm);
    background: var(--surface-soft, var(--surface));
    flex: 0 1 auto;
    min-width: 5.5rem;
    max-width: 100%;
    box-sizing: border-box;
}
.reader-parasha-link {
    display: block;
    padding: 1px 2px 4px;
    text-decoration: none;
    color: var(--ink);
    font-family: var(--font-he);
    font-weight: 700;
    font-size: 0.82rem;
    line-height: 1.2;
    border-radius: var(--radius-sm);
    white-space: nowrap;
}
.reader-parasha-link:hover {
    background: transparent;
    color: var(--accent);
}
.reader-parasha-link.is-current,
.reader-parasha-group.is-current-group > .reader-parasha-link {
    color: var(--accent);
}
.reader-chapter-list--nested {
    margin-top: 0;
    padding-inline: 0;
    gap: 3px;
    grid-template-columns: repeat(auto-fill, minmax(28px, 1fr));
}
.reader-chapter-nav--parasha .reader-chapter-link {
    min-height: 28px;
    padding: 3px 2px;
}
.reader-chapter-nav--parasha .reader-chapter-link .he {
    font-size: 0.8rem;
}
.reader-chapter-nav--parasha .reader-chapter-nav-head {
    padding: 2px 4px 8px;
    margin-bottom: 6px;
}

/* Chapter nav collapses under the reader on narrower screens. */
@media (max-width: 1080px) {
    .reader-layout {
        grid-template-columns: 1fr;
    }
    .reader-chapter-nav {
        position: static;
        max-height: none;
    }
    .reader-chapter-list {
        grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    }
}

/* ---------------- Mikra'ot Gedolot style reader (base texts only) --------
   Wrapper holds a filter bar on top and a 3-column grid beneath: mefarshim
   on the right, primary text in the middle, mefarshim on the left. */
.reader-mg { display: block; direction: rtl; }
.reader-mg-grid {
    position: relative;
    display: grid;
    /* Center caps around 520px so the flowing Hebrew stays readable;
       remaining width splits evenly between the two side panes so each
       mefarash card has real room to breathe. */
    grid-template-columns: minmax(280px, 1fr) minmax(280px, 520px) minmax(280px, 1fr);
    gap: 0;
    align-items: start;
    direction: rtl;
    isolation: isolate;
}

/* Reader pages benefit from more horizontal room than the 1200px default;
   sides get roughly 400-500px each on typical widescreen monitors. The
   dilugim (Torah code) grid needs the same extra width so 72 letters per
   row fit without horizontal scrolling. */
main.container:has(.reader-mg) {
    max-width: 1720px;
}
.reader-mg-side {
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Top pad keeps the first card's border + hover outline + box-shadow
       from being clipped by the pane's overflow container. Bottom pad
       matches so scrolling to the end doesn't clip the last card either. */
    padding: 10px 18px;
    min-width: 0;
    min-height: 0;
    /* Locked to viewport height so a very long side never stretches the
       reader page: content overflows into an internal scrollbar on the
       pane rather than growing the grid row and the whole page along with
       it. Sticky-top keeps the pane in view as the center text scrolls. */
    position: sticky;
    top: 16px;
    align-self: start;
    height: calc(100vh - 32px);
    overflow-y: auto;
    z-index: 1;
}
.reader-mg-side::-webkit-scrollbar { width: 6px; }
.reader-mg-side::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.15);
    border-radius: 3px;
}
.reader-mg-side::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.3); }
.reader-mg-center {
    min-width: 0;
    position: relative;
    z-index: 1;
}
.reader-mg-center .segments {
    /* Keep the flowing-paragraph look introduced earlier, just with a
       verse marker button that we can target with SVG lines. */
    position: relative;
}

/* Filter chip bar sits above the grid. Server-rendered, JS toggles. */
/* Compact "מקור" callout above the mefarshim grid when the primary text
   is a commentary (Beit Yosef, Rashi, ...) and we resolved its base. */
.mg-base-link {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 6px 12px;
    margin: 0 0 10px;
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-radius: var(--radius-sm);
    font-size: 0.95rem;
}
.mg-base-link a {
    font-weight: 600;
    color: var(--accent);
}
.mg-filter-bar {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 10px 12px;
    margin: 0 0 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    direction: rtl;
    box-shadow: none;
}
.mg-filter-label {
    font-family: var(--font-he);
    font-weight: 600;
    color: var(--muted);
    flex: 0 0 auto;
}
.mg-filter-chips {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    flex: 1 1 auto;
    min-width: 0;
}
.mg-filter-chips li { margin: 0; }
.mg-filter-chip {
    font-family: var(--font-he);
    font-size: 0.9rem;
    padding: 3px 12px;
    border-radius: 999px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, opacity 0.12s;
    line-height: 1.3;
    box-shadow: none;
}
.mg-filter-chip:not(.is-active) {
    background: transparent;
    color: var(--accent);
    opacity: 0.7;
}
.mg-filter-chip:hover { opacity: 1; }
.mg-filter-actions {
    display: flex;
    gap: 6px;
    margin-inline-end: 0;
}
.btn.ghost {
    background: transparent;
    border: 1px solid var(--hair);
    color: var(--muted);
    box-shadow: none;
}
.btn.ghost:hover {
    background: var(--surface-2);
    color: var(--ink);
    border-color: var(--hair-strong);
}
.mg-commentary.is-hidden { display: none !important; }

/* Little badge inside each filter chip signalling whether the underlying
   commentator book is present in the local cache. */
.mg-chip-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    font-family: var(--font-en);
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1;
    margin-inline-start: 6px;
    vertical-align: middle;
    color: #fff;
    background: rgba(255, 255, 255, 0.25);
}
.mg-filter-chip:not(.is-active) .mg-chip-badge { background: rgba(138, 30, 30, 0.15); color: var(--accent); }
.mg-chip-badge.cache-full { background: #1f9d55; color: #fff; }
.mg-chip-badge.cache-flight { background: #d68a1c; color: #fff; }
.mg-chip-badge.cache-err { background: var(--accent); color: #fff; }
.mg-chip-badge.cache-miss { background: rgba(255,255,255,0.35); color: #fff; }
.mg-filter-chip:not(.is-active) .mg-chip-badge.cache-full { background: #cfeadc; color: #1f9d55; }
.mg-filter-chip:not(.is-active) .mg-chip-badge.cache-flight { background: #f6e4c1; color: #d68a1c; }

/* Missing-books row: commentators whose text couldn't be surfaced because
   we don't have their book cached locally. Each row offers a one-click
   download so the reader can populate them. */
.mg-missing-bar {
    background: #fbf6e9;
    border: 1px solid #e3d6a9;
    border-radius: var(--radius);
    padding: 8px 12px;
    margin: 0 0 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    direction: rtl;
}
.mg-missing-label {
    font-family: var(--font-he);
    color: #6b4e12;
    font-weight: 500;
    flex: 0 0 auto;
}
.mg-missing-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1 1 auto;
}
.mg-missing-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 999px;
    background: #fff;
    border: 1px solid #e3d6a9;
    font-family: var(--font-he);
    font-size: 0.88rem;
}
.mg-missing-item a { color: #6b4e12; text-decoration: none; }
.mg-missing-item a:hover { text-decoration: underline; }
.mg-missing-item .btn.small { padding: 2px 8px; font-size: 0.78rem; }

/* Verse marker (in text) — quiet 22 px surface-2 circle with muted-ink
   number; only fills accent on hover / active. Sefaria-style. */
.mg-verse-marker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--surface-2);
    border: 1px solid var(--hair-strong);
    color: var(--ink-2);
    font-family: var(--font-en);
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1;
    margin: 0 0.25em;
    padding: 0;
    vertical-align: middle;
    direction: ltr;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.mg-verse-marker:hover,
.mg-verse-marker.is-active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

.mg-commentary {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 12px 14px;
    box-shadow: none;
    transition: background-color 0.15s, border-color 0.15s;
    scroll-margin-top: 100px;
}
.mg-commentary:hover {
    background: var(--surface-soft);
    border-color: var(--hair-strong);
}
.mg-commentary.is-active {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

/* ============================================================
 * Sticky verse selection ("focus mode").
 *
 * When a verse is clicked in the reader, the .reader-mg root
 * gains ``.mg-mode-focus``, the selected .segment /
 * .mg-verse-marker / matching .mg-commentary cards gain
 * ``.is-selected`` (persistent — not the 1.2s ``.is-active``
 * flash), and everything else fades so the user can trace
 * this verse's mefarshim visually across both side panes.
 *
 * Selection state is per-reader-root, so the reader page and
 * the modal reader don't fight over each other.
 * ============================================================ */

/* Selected verse marker: filled accent, subtle pulse ring so
 * the eye lands there before the mefarshim on the sides. */
.mg-verse-marker.is-selected {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    transform: scale(1.15);
    box-shadow: 0 0 0 3px rgba(138, 30, 30, 0.18);
}

/* Selected verse body: warm background band + accent stripe
 * so the whole verse (not just the marker) reads as selected. */
.segment.is-selected {
    background: rgba(255, 220, 128, 0.28);
    border-radius: 6px;
    /* Two stripes — one on each edge — hint that the verse
     * connects to mefarshim on both sides of the layout. */
    box-shadow:
        inset 4px 0 0 var(--accent),
        inset -4px 0 0 var(--accent);
    padding: 4px 10px;
    transition: background 0.18s, box-shadow 0.18s;
}

/* Selected mefarshim card: heavy border in accent + brighter
 * background so it pops against dimmed siblings. */
.mg-commentary.is-selected {
    background: var(--surface-soft);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
    position: relative;
    z-index: 2;
}
.mg-commentary.is-selected .mg-marker {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.mg-commentary.is-selected .mg-commentary-head {
    border-bottom-color: rgba(138, 30, 30, 0.4);
}

/* When focus mode is active, dim everything not selected —
 * still visible but visually pushed back so the selected
 * verse and its mefarshim dominate. */
.reader-mg.mg-mode-focus .mg-commentary:not(.is-selected) {
    opacity: 0.32;
    filter: saturate(0.6);
}
.reader-mg.mg-mode-focus .mg-commentary:not(.is-selected):hover {
    opacity: 0.7;   /* fade back in on hover so users can peek */
}
.reader-mg.mg-mode-focus .segment:not(.is-selected) {
    opacity: 0.55;
}
.reader-mg.mg-mode-focus .segment:not(.is-selected) .segment-text {
    color: #4b4033;
}
/* Verse markers other than the selected one keep their normal
 * appearance so users can still see verse numbers to jump to
 * next. Only their text dims via the parent .segment rule. */
.reader-mg.mg-mode-focus .segment:not(.is-selected) .mg-verse-marker {
    opacity: 0.85;
}

/* Subtle "clickable" affordance on the segment body so users
 * discover the click-to-focus behaviour without a tooltip. */
.reader-mg .segment { cursor: pointer; transition: background 0.15s, opacity 0.18s; }
.reader-mg .segment:hover:not(.is-selected) { background: rgba(255, 220, 128, 0.10); border-radius: 6px; }

/* Reduced-motion users don't want the smooth-scroll or the
 * subtle lift on the selected card. */
@media (prefers-reduced-motion: reduce) {
    .segment.is-selected,
    .mg-commentary.is-selected { transition: none; transform: none; }
}

/* ============================================================
 * ``is-anchor-highlight`` — soft spotlight for the modal's
 * target verse.
 *
 * When a modal opens on a specific ref (e.g. from the Reader
 * Connections panel, or a search / gematria / entropy result),
 * the anchor verse and its matching mefarshim cards get this
 * class. It provides the same accent-border feel as the sticky
 * ``.is-selected`` state but WITHOUT applying ``mg-mode-focus``
 * to the root — so the rest of the chapter stays full-colour
 * and readable. That's the difference from the reader-page
 * click behaviour: modal readers are for reading the whole
 * chapter, not focusing on a slice.
 * ============================================================ */
.mg-commentary.is-anchor-highlight {
    background: var(--surface-soft);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
    position: relative;
    z-index: 2;
}
.mg-commentary.is-anchor-highlight .mg-marker {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.mg-verse-marker.is-anchor-highlight {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
/* The segment already carries ``.is-highlighted`` when the modal
 * opens on a specific verse (see the ``.modal .segment.is-highlighted``
 * block earlier in this file) — we don't need to re-style it here. */

/* Modal readers: even if a user later clicks a verse inside the
 * modal and activates focus mode, don't dim the surrounding text
 * to a whisper — half a chapter greyed out is user-hostile. Keep
 * everything readable; the accent border on the selected verse
 * and cards is enough of a visual anchor. */
.modal .reader-mg.mg-mode-focus .mg-commentary:not(.is-selected) {
    opacity: 1;
    filter: none;
}
.modal .reader-mg.mg-mode-focus .segment:not(.is-selected) {
    opacity: 1;
}
.modal .reader-mg.mg-mode-focus .segment:not(.is-selected) .segment-text {
    color: inherit;
}


.mg-commentary-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--hair);
    padding-bottom: 6px;
    font-size: 0.9rem;
}
.mg-marker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--surface-2);
    color: var(--ink-2);
    border: 1px solid var(--hair-strong);
    font-family: var(--font-en);
    font-size: 0.7rem;
    line-height: 1;
    flex: 0 0 auto;
}
.mg-commentator {
    font-family: var(--font-he);
    font-weight: 600;
    font-size: 1rem;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--ink);
}
.mg-commentary-body {
    font-family: var(--font-he);
    font-size: 0.98rem;
    line-height: 1.85;
    color: var(--ink);
    direction: rtl;
    text-align: right;
    unicode-bidi: isolate;
}

/* Connector SVG kept in markup for layout stability but never drawn. */
.mg-svg-overlay {
    display: none !important;
}

/* Below the medium-width breakpoint the sides collapse under the text so
   commentaries still remain accessible on narrow screens. */
@media (max-width: 1080px) {
    .reader-mg-grid {
        grid-template-columns: 1fr;
    }
    .reader-mg-side {
        padding: 12px 0 0;
        position: static;
        height: auto;
        max-height: none;
        overflow: visible;
    }
    .mg-svg-overlay { display: none; }
}

/* Side-by-side layout for a commentary + the base source it discusses.
   Kept LTR at the grid level so the first (source) column visually lands
   on the LEFT and the commentary sits on the RIGHT — matching the
   original mefarshim-beside-source visual metaphor even in RTL pages. */
.reader-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    margin: 8px 0 20px;
    align-items: start;
}
.reader-pair-col {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    box-shadow: none;
    padding: 16px 20px;
    min-width: 0;
    direction: rtl;
}
.reader-pair-base {
    background: #fbf6e9;
    border-color: #e3d6a9;
}
.reader-pair-base .reader-pair-label { color: #8a6a1f; }
.reader-pair-base .segments { color: #4a3608; font-size: 1.15rem; }
.reader-pair-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
    border-bottom: 1px dashed var(--border);
    padding-bottom: 8px;
}
.reader-pair-label {
    font-family: var(--font-he);
    font-size: 0.85rem;
    color: var(--ink-muted);
    letter-spacing: 0.04em;
}
.reader-pair-head .he { text-decoration: none; }
.reader-pair-head .he:hover { text-decoration: underline; }
.reader-pair-commentary { background: var(--surface); }
.reader-pair-commentary .reader-pair-label { color: var(--accent); }
@media (max-width: 900px) {
    .reader-pair { grid-template-columns: 1fr; }
}

/* Text-selection floating menu: appears above the current selection with
   quick actions (search / gematria). Positioned in fixed coordinates by
   JS so it tracks the selection wherever it lives on the page. */
.selection-menu[hidden] { display: none; }
.selection-menu {
    position: fixed;
    z-index: 90;
    display: flex;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
    padding: 4px;
    transform: translate(-50%, -100%);
    animation: selection-menu-in 0.12s ease-out;
}
@keyframes selection-menu-in {
    from { opacity: 0; transform: translate(-50%, calc(-100% + 6px)); }
    to   { opacity: 1; transform: translate(-50%, -100%); }
}
.selection-menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
}
.selection-menu-btn:hover { background: rgba(138, 30, 30, 0.08); color: var(--accent); }
.selection-menu-btn .icon {
    font-size: 0.95rem;
    color: var(--accent);
    font-family: var(--font-he);
}

/* Wrap the current selection with a lightweight highlight while the
   drawer is open so users know which text drove the results. */
.reader-selection-highlight {
    background: #fff4c8;
    padding: 0 2px;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(240, 201, 90, 0.4);
}

/* Left-side slide-in drawer with search / gematria results triggered by
   the selection menu. Sits above other floating elements (modal excepted). */
.selection-drawer[hidden] { display: none; }
.selection-drawer {
    position: fixed;
    top: 68px;
    bottom: 20px;
    left: 16px;
    width: min(380px, 40vw);
    z-index: 80;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    display: flex;
    flex-direction: column;
    animation: selection-drawer-in 0.16s ease-out;
}
/* Lesson editor + viewer: park the reference/gematria drawer on
   the physical right side.  In a fully RTL layout (as the whole
   editor is) the reader's eye lands on the right side of the
   viewport after selecting a phrase, so surfacing search results
   there — rather than at the far left — cuts the visual jump.
   The reader page keeps its long-standing left-side placement to
   avoid overlapping the primary reading column, so this override
   is scoped tightly via ``:has()`` to the two lesson pages that
   opt-in with ``data-lesson-editor`` / ``data-lesson-view``. */
body:has([data-lesson-editor], [data-lesson-view]) .selection-drawer {
    left: auto;
    right: 16px;
}
@keyframes selection-drawer-in {
    from { opacity: 0; transform: translateX(-16px); }
    to   { opacity: 1; transform: translateX(0); }
}
.selection-drawer-head {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}
.selection-drawer-titles { flex: 1; min-width: 0; }
.selection-drawer-label {
    display: block;
    font-family: var(--font-he);
    margin-bottom: 4px;
}
.selection-drawer-text {
    font-family: var(--font-he);
    font-size: 1rem;
    line-height: 1.4;
    max-height: 4.2em;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    color: var(--ink);
}
.selection-drawer-tabs {
    display: flex;
    gap: 4px;
    padding: 8px 12px 0;
    border-bottom: 1px solid var(--border);
}
.selection-tab {
    border: 1px solid transparent;
    background: transparent;
    padding: 8px 12px;
    border-radius: 6px 6px 0 0;
    font: inherit;
    font-size: 0.9rem;
    cursor: pointer;
    color: var(--ink-muted);
    font-family: var(--font-he);
}
.selection-tab:hover { color: var(--ink); }
.selection-tab.is-active {
    color: var(--accent);
    border-color: var(--border);
    border-bottom-color: var(--surface);
    background: var(--surface);
    margin-bottom: -1px;
    font-weight: 600;
}
.selection-drawer-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 14px;
}
.selection-hits {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.selection-hit {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px 10px;
    background: #fafafa;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
    /* Layout: optional checkbox on the leading edge (right in RTL),
       the hit content fills the rest. */
    display: flex;
    align-items: flex-start;
    gap: 8px;
}
.selection-hit:hover { background: #fff; border-color: var(--accent); }
.selection-hit.is-selected {
    background: var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(138, 30, 30, 0.12);
}
.selection-hit-main { flex: 1; min-width: 0; }
.selection-hit-check-wrap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    cursor: pointer;
    /* Own its own hit target so users can tap the small square
       without accidentally opening the preview modal. */
}
.selection-hit-check {
    width: 16px;
    height: 16px;
    margin: 0;
    cursor: pointer;
    accent-color: var(--accent);
}
.selection-bulk-bar[hidden] { display: none; }
.selection-bulk-bar {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    margin: -12px -14px 10px;
    background: var(--surface);
    border-bottom: 1px solid var(--accent);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.selection-bulk-count {
    font-family: var(--font-he);
    font-size: 0.9rem;
    color: var(--accent);
    font-weight: 600;
    flex: 1;
}
.selection-hit-ref {
    display: block;
    font-family: var(--font-he);
    color: var(--accent);
    font-weight: 600;
    margin-bottom: 4px;
    text-decoration: none;
}
.selection-hit-snippet {
    font-family: var(--font-he);
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--ink);
    direction: rtl;
    text-align: right;
}
.selection-hit-meta {
    display: flex;
    gap: 6px;
    margin-top: 4px;
    font-size: 0.8rem;
    color: var(--ink-muted);
}
.selection-loading, .selection-error, .selection-empty {
    padding: 12px 4px;
    font-family: var(--font-he);
}
.selection-error { color: var(--error); }
.selection-empty { color: var(--ink-muted); font-style: italic; }
.selection-meta { margin-top: 12px; }

@media (max-width: 900px) {
    .selection-drawer {
        left: 8px;
        right: 8px;
        width: auto;
        top: 60px;
    }
}

/* Legacy base-source block (still used elsewhere; new reader uses
   .reader-pair-base above). */
.base-source {
    background: var(--surface-soft);
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius);
    padding: 18px 22px;
    margin-bottom: 20px;
    direction: rtl;
    box-shadow: none;
}
.base-source-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    border-bottom: 1px solid #e3d6a9;
    padding-bottom: 6px;
}
.base-source-label {
    font-family: var(--font-en);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #8a6a1f;
}
.base-source-head .he {
    font-family: var(--font-he);
    font-size: 1.05rem;
    color: #6b4e12;
    text-decoration: none;
}
.base-source-head .he:hover { text-decoration: underline; }
.base-source-body {
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 0;
    font-size: 1.15rem;
    color: #4a3608;
}

.book-status-panel {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 20px;
    box-shadow: none;
}
.book-status-panel h3 { margin-top: 0; }

.schema {
    background: var(--surface);
    border: 1px solid var(--border);
    padding: 12px;
    border-radius: var(--radius);
    max-height: 400px;
    overflow: auto;
    font-size: 0.85rem;
}

.chip-list { list-style: none; padding: 0; display: flex; gap: 8px; flex-wrap: wrap; }
.chip-list li { background: var(--surface-2); padding: 4px 10px; border-radius: 999px; font-size: 0.9rem; }

.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.lede { color: var(--muted); }
.empty { color: var(--muted); padding: 20px; text-align: center; }
.error { color: var(--error); }

/* -----------------------------------------------------------------------
   Text-to-Speech: per-segment speaker button.
   ------------------------------------------------------------------------
   Injected client-side by ``initReaderTTS()`` (static/app.js) so no server
   template touches it.  Sits inline at the end of each verse / commentary
   block; muted by default, becomes the page accent on hover; enters a
   loading state (spin) while the /api/tts request is in flight and a
   pulsing "playing" state while the MP3 plays.
   ----------------------------------------------------------------------- */
.tts-speaker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    margin: 0 4px 0 2px;
    vertical-align: middle;
    background: transparent;
    border: 0;
    border-radius: 999px;
    color: var(--muted-2);
    cursor: pointer;
    transition: background 120ms, color 120ms, transform 120ms;
    /* Keep the button LTR so the SVG doesn't flip in RTL context. */
    direction: ltr;
    unicode-bidi: isolate;
}
.tts-speaker svg { display: block; }
.tts-speaker:hover {
    background: var(--surface-2);
    color: var(--accent);
}
.tts-speaker:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.tts-speaker.is-loading {
    color: var(--accent);
    animation: tts-spin 900ms linear infinite;
    pointer-events: none;
}
.tts-speaker.is-playing {
    color: var(--accent);
    background: var(--surface-soft);
    animation: tts-pulse 1600ms ease-in-out infinite;
}
@keyframes tts-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}
@keyframes tts-pulse {
    0%, 100% { opacity: 0.85; }
    50%      { opacity: 1; transform: scale(1.05); }
}
/* Inside a commentary head bar (right of the "פתח ↗" link) the button
   should not add extra vertical margin — the header is already tight. */
.mg-commentary .tts-speaker { margin-inline-start: 6px; }

/* Anon-user login prompt shown when a not-signed-in visitor clicks the
   speaker.  Same visual language as the reader context modal but
   smaller and self-contained (no dependency on the shared #context-modal).
   ----------------------------------------------------------------------- */
.tts-modal[hidden] { display: none; }
.tts-modal {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}
.tts-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
}
.tts-modal-dialog {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-modal);
    padding: var(--space-5);
    max-width: 420px;
    width: calc(100% - 32px);
    text-align: center;
}
.tts-modal-dialog h2 {
    margin: 0 0 var(--space-3);
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--ink);
}
.tts-modal-dialog p {
    margin: 0 0 var(--space-2);
    color: var(--muted);
    line-height: 1.55;
}
.tts-modal-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: center;
    margin-top: var(--space-4);
    flex-wrap: wrap;
}

/* -----------------------------------------------------------------------
   Flash messages — rendered by ``base.html`` when a route emits
   ``flash()``. Full-width strip below the header, quiet border, no shadow.
   ----------------------------------------------------------------------- */
.flash-bar {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-top: var(--space-4);
}
.flash {
    padding: 10px 14px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--hair-strong);
    background: var(--surface);
    color: var(--ink);
    font-size: 0.95rem;
    line-height: 1.5;
}
.flash-info    { background: #eef4fb; border-color: #cadaee; color: #1c4a86; }
.flash-success { background: #ecf7f0; border-color: #b6d4c1; color: #1a5c39; }
.flash-error,
.flash-danger  { background: #fdecec; border-color: #f0c4c4; color: #7d1616; }
.flash-warning { background: #fff6e5; border-color: #eadaa8; color: #7a5a1a; }

/* -----------------------------------------------------------------------
   Feedback form (/feedback) — flat card, deliberate whitespace, radio
   options render as pill toggles so users pick a category at a glance.
   ----------------------------------------------------------------------- */
.feedback-panel {
    max-width: 720px;
    margin: var(--space-6) auto;
    padding: var(--space-6) var(--space-5);
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    box-shadow: none;
}
.feedback-head { margin-bottom: var(--space-5); }
.feedback-head h1 {
    margin: 0 0 var(--space-2);
    font-size: 1.8rem;
    font-weight: 700;
    color: var(--ink);
}
.feedback-head .lede {
    margin: 0;
    color: var(--muted);
    line-height: 1.6;
    max-width: 600px;
}
.feedback-form {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}
.feedback-kind {
    margin: 0;
    padding: 0;
    border: 0;
}
.feedback-kind legend {
    padding: 0;
    margin: 0 0 var(--space-2);
    font-family: var(--font-ui);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--ink-2);
    letter-spacing: 0.02em;
}
.kind-options {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}
.kind-option {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    background: var(--surface);
    border: 1px solid var(--hair-strong);
    border-radius: 999px;
    font-family: var(--font-ui);
    font-size: 0.95rem;
    color: var(--ink-2);
    cursor: pointer;
    transition: background 120ms, border-color 120ms, color 120ms;
}
.kind-option:hover {
    background: var(--surface-2);
    color: var(--ink);
}
.kind-option input[type="radio"] {
    accent-color: var(--accent);
    margin: 0;
}
.kind-option:has(input[type="radio"]:checked) {
    background: var(--surface-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
}

.feedback-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.feedback-label {
    font-family: var(--font-ui);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--ink-2);
    letter-spacing: 0.02em;
}
.feedback-field input[type="text"],
.feedback-field textarea {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: var(--font-he);
    font-size: 1rem;
    color: var(--ink);
    box-shadow: none;
    transition: border-color 120ms, box-shadow 120ms;
    direction: rtl;
}
.feedback-field textarea {
    line-height: 1.6;
    resize: vertical;
    min-height: 160px;
}
.feedback-field input[type="text"]::placeholder,
.feedback-field textarea::placeholder {
    color: var(--muted-2);
    opacity: 1;
}
.feedback-field input[type="text"]:hover,
.feedback-field textarea:hover { border-color: var(--muted-2); }
.feedback-field input[type="text"]:focus,
.feedback-field textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}
.feedback-hint {
    align-self: flex-start;
    font-size: 0.8rem;
    color: var(--muted-2);
}
.feedback-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: flex-start;
    padding-top: var(--space-2);
}
.feedback-gate {
    padding: var(--space-5);
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    text-align: center;
}
.feedback-gate h2 {
    margin: 0 0 var(--space-3);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--ink);
}
.feedback-gate p {
    margin: 0 auto var(--space-3);
    max-width: 520px;
    color: var(--muted);
    line-height: 1.6;
}
.feedback-gate-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: center;
    margin-top: var(--space-4) !important;
    margin-bottom: 0 !important;
}

/* -----------------------------------------------------------------------
   Account settings (/auth/settings) — wider than the login panel, stacks
   an avatar + heading up top, then flat cards for info, preferences, and
   (admin only) shortcut tiles.
   ----------------------------------------------------------------------- */
.settings-panel {
    max-width: 760px;
    margin: var(--space-6) auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}
.settings-head {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: 0 var(--space-2);
}
.settings-avatar {
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--hair-strong);
    display: flex;
    align-items: center;
    justify-content: center;
}
.settings-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.settings-avatar-fallback {
    font-family: var(--font-en);
    font-size: 1.6rem;
    font-weight: 600;
    color: var(--ink-2);
}
.settings-head-text h1 {
    margin: 0 0 4px;
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--ink);
}
.settings-lede {
    margin: 0;
    color: var(--muted);
    line-height: 1.5;
    font-size: 0.95rem;
}

.settings-card {
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    box-shadow: none;
}
.settings-section-title {
    margin: 0 0 var(--space-4);
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--hair);
    font-family: var(--font-ui);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--ink-2);
    letter-spacing: 0.05em;
    text-transform: none;
}

.settings-info {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.settings-info-row {
    display: grid;
    grid-template-columns: 140px 1fr;
    align-items: baseline;
    gap: var(--space-3);
}
.settings-info-row dt {
    margin: 0;
    font-family: var(--font-ui);
    font-size: 0.9rem;
    color: var(--muted);
}
.settings-info-row dd {
    margin: 0;
    color: var(--ink);
    font-size: 1rem;
    word-break: break-word;
}

.settings-form { margin: 0; }
.settings-checkbox {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    cursor: pointer;
    color: var(--ink);
    font-size: 0.98rem;
}
.settings-checkbox input[type="checkbox"] {
    accent-color: var(--accent);
    width: 16px;
    height: 16px;
    margin: 0;
}
.settings-actions {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    margin-top: var(--space-4);
    padding-top: var(--space-4);
    border-top: 1px solid var(--hair);
    flex-wrap: wrap;
}
.settings-inline-form { display: inline; margin: 0; }
.btn-danger-ghost {
    background: transparent;
    color: var(--accent);
    border: 1px solid var(--hair-strong);
}
.btn-danger-ghost:hover {
    background: var(--surface-soft);
    border-color: var(--accent);
    color: var(--accent-strong);
}

.settings-admin-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--space-3);
}
.settings-admin-tile {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: var(--space-4);
    background: var(--surface-soft);
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--ink);
    transition: background 120ms, border-color 120ms, transform 120ms;
}
.settings-admin-tile:hover {
    background: var(--surface-2);
    border-color: var(--accent);
    transform: translateY(-1px);
}
.settings-admin-tile-title {
    font-family: var(--font-ui);
    font-size: 1rem;
    font-weight: 600;
    color: var(--ink);
}
.settings-admin-tile-desc {
    font-size: 0.85rem;
    color: var(--muted);
    line-height: 1.4;
}

.badge-success { background: #e6f2e9; color: #1a5c39; border: 1px solid #b6d4c1; }
.badge-admin   { background: var(--surface-soft); color: var(--accent); border: 1px solid var(--accent); }

@media (max-width: 560px) {
    .settings-head { flex-direction: column; text-align: center; }
    .settings-info-row { grid-template-columns: 1fr; gap: 2px; }
    .settings-info-row dt { color: var(--muted-2); font-size: 0.82rem; }
}

/* -----------------------------------------------------------------------
   Error page — centered hero panel with big serif code + muted message.
   ----------------------------------------------------------------------- */
.error-hero {
    max-width: 520px;
    margin: var(--space-7) auto;
    padding: var(--space-6) var(--space-5);
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    text-align: center;
}
.error-code {
    font-family: var(--font-en);
    font-size: 3.5rem;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: -0.02em;
    line-height: 1;
    margin-bottom: var(--space-3);
}
.error-message {
    font-family: var(--font-he);
    color: var(--ink-2);
    font-size: 1.1rem;
    line-height: 1.6;
    margin: 0 0 var(--space-5);
}

/* ---- Advanced-search / form-row inputs & selects --------------------- */
.advanced-search {
    background: var(--surface);
    border: 1px solid var(--hair);
    padding: 20px 22px 16px;
    border-radius: var(--radius-lg);
    margin-bottom: 24px;
    box-shadow: none;
}
.form-row {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: flex-end;
    margin-bottom: 12px;
}
.form-row label {
    display: flex;
    flex-direction: column;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--ink-muted);
    letter-spacing: 0.02em;
    flex: 1;
    min-width: 200px;
}
.form-row label.wide-select {
    flex: 2 1 260px;
    min-width: 260px;
}
.form-row input,
.form-row select {
    padding: 9px 12px;
    border: 1px solid var(--hair-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    font-family: var(--font-ui);
    font-size: 0.95rem;
    font-weight: 400;
    color: var(--ink);
    box-shadow: none;
    transition: border-color 120ms, box-shadow 120ms;
    max-width: 100%;
    min-width: 0;
    text-overflow: ellipsis;
}
.form-row input::placeholder { color: var(--muted-2); opacity: 1; }
.form-row input:hover,
.form-row select:hover { border-color: var(--muted-2); }
.form-row input:focus,
.form-row select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}
.form-row select {
    /* Custom chevron so the native browser one doesn't clash with the
       rounded corners.  Positioned on the physical LEFT because RTL
       inline-start = right (already the "leading" side of the field). */
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
    background-repeat: no-repeat;
    background-position: left 12px center;
    background-size: 16px 16px;
    padding-left: 34px;
    padding-right: 12px;
    cursor: pointer;
}
.form-row input[type="number"] {
    /* Number spinners look particularly ugly on Chromium/Windows.
       Hide them; users can still type. */
    -moz-appearance: textfield;
}
.form-row input[type="number"]::-webkit-outer-spin-button,
.form-row input[type="number"]::-webkit-inline-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.search-summary { color: var(--ink-muted); margin: 16px 0; }

.query-history {
    margin: 12px 0 20px;
}
.query-history-title {
    margin: 0 0 8px;
    font-weight: 600;
}
.query-history-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.query-history-chip {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--ink);
    text-decoration: none;
    font-size: 0.95rem;
    max-width: 16rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.query-history-chip:hover,
.query-history-chip:focus-visible {
    border-color: var(--accent);
    background: #f7efe8;
    color: var(--accent-strong);
    outline: none;
}
.aggregations { margin-bottom: 16px; }
.aggregations ul { columns: 3; padding-left: 20px; }

.search-results { list-style: none; padding: 0; }
.search-hit {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 14px 18px;
    margin-bottom: 10px;
    box-shadow: none;
    transition: background-color 120ms, border-color 120ms;
}
.search-hit:hover {
    background: var(--surface-soft);
    border-color: var(--hair-strong);
}
.search-hit-head {
    display: flex;
    gap: 12px;
    align-items: baseline;
    flex-wrap: wrap;
    margin-bottom: 4px;
}
.search-hit-ref { font-weight: 600; color: var(--accent); text-decoration: none; font-size: 1.05rem; }
.snippet { margin: 6px 0 0; }
.snippet.he {
    font-family: var(--font-he);
    direction: rtl;
    text-align: right;
    font-size: 1.1rem;
    line-height: 1.9;
    unicode-bidi: isolate;
}
.snippet b { background: #fff5c0; padding: 0 2px; }

.pagination { display: flex; gap: 12px; justify-content: center; margin-top: 24px; }

.gematria-status {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 20px;
    box-shadow: none;
}
.gematria-status h3 { margin-top: 0; }
.gematria-form .he { font-family: var(--font-he); font-size: 1.1rem; }

/* ---------------------------------------------------------------- dilugim
   Torah-letter matrix. Rendered as a table so per-cell hover/highlight
   stays cheap even at 72+ letters per row × hundreds of rows. */
:root {
    --dilugim-0: #f6b93b;
    --dilugim-1: #6ec6ff;
    --dilugim-2: #b39ddb;
    --dilugim-3: #ff8a80;
    --dilugim-4: #a5d6a7;
    --dilugim-5: #ffd54f;
    --dilugim-6: #f48fb1;
    --dilugim-7: #80cbc4;
}
.dilugim-form .form-row { align-items: end; }
.dilugim-form .form-actions { display: flex; align-items: end; gap: 8px; }
.dilugim-form input[type="text"] { direction: rtl; font-family: var(--font-he); font-size: 1.05rem; }
.dilugim-form .dilugim-smart-row {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
    flex-wrap: wrap;
    row-gap: 8px;
}
.dilugim-form .dilugim-smart-row label {
    flex: 0 0 auto;
    min-width: 150px;
}
.dilugim-form .dilugim-smart-row input[type="number"] { max-width: 110px; }
.dilugim-smart-hint {
    align-self: center;
    max-width: 460px;
    line-height: 1.35;
}

.dilugim-smart-results {
    background: #fdfbf4;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 12px 16px;
    margin: 14px 0;
}
.dilugim-smart-results[hidden] { display: none; }
.dilugim-smart-head h3 { margin: 0 0 4px; font-size: 1rem; font-weight: 600; }
.dilugim-smart-head p { margin: 0 0 10px; }
.dilugim-smart-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 10px;
}
.dilugim-smart-width {
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px 10px;
}
.dilugim-smart-width-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.dilugim-smart-width-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(138, 30, 30, 0.08);
    color: var(--accent);
    font-size: 0.9rem;
}
.dilugim-smart-width-badge strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.dilugim-smart-matches {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 240px;
    overflow-y: auto;
}
.dilugim-smart-matches li { margin: 0; padding: 0; }
.dilugim-smart-match {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 6px;
    border-radius: 4px;
    text-decoration: none;
    color: inherit;
}
.dilugim-smart-match:hover {
    background: #f6efe0;
}
.dilugim-smart-match .dilugim-swatch { flex: 0 0 12px; }
.dilugim-smart-match .he { font-family: var(--font-he); font-size: 1.05rem; }

.dilugim-results {
    background: #fdfbf4;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 12px 16px;
    margin: 14px 0;
}
.dilugim-results h3 { margin: 0 0 8px; font-size: 1rem; font-weight: 600; }
.dilugim-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    margin-bottom: 6px;
}
.dilugim-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.95rem;
}
.dilugim-swatch {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.15);
}
.dilugim-swatch.swatch-combined {
    background: linear-gradient(45deg, #ff6d00, #ffab00);
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.35);
}

.dilugim-match-list {
    margin-top: 10px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.dilugim-match-list-head {
    padding: 8px 12px;
    background: #f6f2e6;
    border-bottom: 1px solid var(--border);
    font-size: 0.9rem;
    color: var(--ink-muted);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.dilugim-match-list-items {
    max-height: 320px;
    overflow-y: auto;
    padding: 0;
    margin: 0;
    list-style: none;
    counter-reset: dilugim-match;
}
.dilugim-match-row {
    display: grid;
    grid-template-columns: 26px 20px 1fr auto;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    font-size: 0.93rem;
    border-bottom: 1px solid rgba(0,0,0,0.06);
    cursor: pointer;
    transition: background 0.1s ease;
}
.dilugim-match-row:hover { background: #fdf6e3; }
.dilugim-match-row:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}
.dilugim-match-row::before {
    counter-increment: dilugim-match;
    content: counter(dilugim-match);
    font-size: 0.75rem;
    color: var(--muted);
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.dilugim-match-row .dilugim-swatch {
    width: 14px;
    height: 14px;
}
.dilugim-match-row.is-combined {
    background: linear-gradient(90deg, rgba(255, 171, 0, 0.15), transparent 60%);
}
.dilugim-match-row.is-chain {
    background: linear-gradient(90deg, rgba(46, 125, 50, 0.10), transparent 60%);
}
.dilugim-match-row .dilugim-match-meta {
    white-space: nowrap;
}
.dilugim-match-row.is-jumped {
    background: #fff3c4;
    animation: dilugim-jump-flash 1.2s ease;
}
@keyframes dilugim-jump-flash {
    0%   { background: #ffe066; }
    100% { background: #fff3c4; }
}

/* ---------------- result-row expand → snippet preview --------------
   The tab used to render the whole 305k-letter Chumash grid up-front.
   Now nothing is drawn until a user clicks a specific match — at which
   point we lay a compact snippet inline below the row (a small table
   of ~11 rows around the match with the pattern letters coloured). */
.dilugim-legend-item.is-dim { opacity: 0.35; }

.dilugim-match-row {
    display: block;                    /* was a flex row, now a container */
    padding: 6px 8px;
    border-radius: 4px;
    cursor: pointer;
    border: 1px solid transparent;
}
.dilugim-match-row:hover { background: #f6efe0; }
.dilugim-match-row[aria-expanded="true"] {
    background: #fffbe6;
    border-color: #e6d590;
}
.dilugim-match-summary {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.dilugim-match-toggle {
    margin-inline-start: auto;
    color: var(--muted);
    transition: transform 0.15s ease;
    font-size: 0.9rem;
}
.dilugim-match-row[aria-expanded="true"] .dilugim-match-toggle {
    transform: rotate(180deg);
    color: var(--accent);
}
.dilugim-match-preview[hidden] { display: none; }
.dilugim-match-preview {
    margin-top: 8px;
    padding: 8px 10px 10px;
    background: #fdfbf4;
    border: 1px solid var(--border);
    border-radius: 6px;
    /* No overflow-x: the snippet grid uses display:grid + 1fr columns and
       always fits the container width. Overflow here was making the whole
       line horizontally scrollable, which the user explicitly wanted gone. */
    overflow: hidden;
}
.dilugim-snippet-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding-bottom: 6px;
    margin-bottom: 6px;
    border-bottom: 1px dashed var(--border);
}
.dilugim-snippet-head .he { font-size: 1.1rem; }

/* Snippet layout: a CSS grid where every letter occupies one column of
   ``1fr``, so ``width`` cells always stretch across the full container
   regardless of viewport size. The row-number column sits in front (LTR)
   and takes a fixed narrow slot. JS sets ``--dilugim-w`` per snippet
   (matches the row width) so the same CSS handles a 12-letter search
   and a 256-letter one. */
.dilugim-snippet-grid {
    display: grid;
    grid-template-columns: 42px 1fr;
    align-items: stretch;
    gap: 3px 6px;
    direction: rtl;
    width: 100%;
    font-family: var(--font-he), "SBL Hebrew", "Ezra SIL", serif;
}
.dilugim-snippet-row {
    display: contents;
}
.dilugim-snippet-row.is-match-row .dilugim-snippet-cells {
    background: rgba(255, 250, 205, 0.5);
    border-radius: 3px;
}
.dilugim-snippet-idx {
    font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
    font-size: 0.72rem;
    color: var(--muted);
    text-align: right;
    padding-inline-end: 6px;
    white-space: nowrap;
    user-select: none;
    direction: ltr;
    align-self: center;
}
.dilugim-snippet-cells {
    display: grid;
    grid-template-columns: repeat(var(--dilugim-w, 72), 1fr);
    direction: rtl;
    gap: 1px;
    letter-spacing: 0;
    line-height: 1.4;
    min-width: 0;
}
.dilugim-snippet-cells > span {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    padding: 1px 0;
    text-align: center;
    border-radius: 2px;
    font-size: clamp(0.55rem, calc(96% / var(--dilugim-w, 72)), 1.15rem);
    line-height: 1.15;
    overflow: hidden;
}
/* Matched letter within a snippet — background comes from inline style
   (per-word palette). ``is-primary`` cells (the match the user clicked
   on) get a bolder outline than chain peers. */
.dilugim-snippet-cell.is-match {
    color: #1a1a1a;
    font-weight: 700;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
}
.dilugim-snippet-cell.is-match.is-primary {
    box-shadow: 0 0 0 2px rgba(0,0,0,0.55);
}
.dilugim-snippet-cell.is-match.is-peer {
    outline: 1px dashed #2e7d32;
    outline-offset: 1px;
}
.dilugim-snippet-cell.is-match.is-combined {
    box-shadow: 0 0 0 2px rgba(255, 111, 0, 0.75);
}

/* Flash the snippet host briefly after auto-expand so the user's eye
   lands on the fresh content instead of the row that produced it. */
.dilugim-match-preview.is-match-flash {
    animation: dilugim-snippet-flash 1.4s ease;
}
@keyframes dilugim-snippet-flash {
    0%   { box-shadow: 0 0 0 4px rgba(255, 111, 0, 0.55); }
    100% { box-shadow: 0 0 0 0 rgba(255, 111, 0, 0); }
}

@media (max-width: 1100px) {
    .dilugim-snippet-cells { font-size: 0.98rem; }
    .dilugim-snippet-cells > .he > span { min-width: 0.9em; }
    .dilugim-snippet-idx { font-size: 0.65rem; }
}

table.book-table td.he { font-family: var(--font-he); font-size: 1.15rem; }
/* Pointed Hebrew (nikud + taamim) needs extra line-height so the marks above
   and below the letters don't collide with neighbouring rows. */
table.book-table td.gematria-pointed {
    font-family: var(--font-he);
    font-size: 1.35rem;
    line-height: 2.05;
    padding-top: 12px;
    padding-bottom: 12px;
}

/* ------------------------------------------------------ downloads summary */
.downloads-summary {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 16px 18px;
    margin-bottom: 18px;
    box-shadow: none;
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.summary-tiles {
    display: grid;
    /* Split-face tiles (Cached / In flight / Errors) need enough width
       for two side-by-side value columns; bumping the min from 160px
       to 220px keeps them from collapsing into narrow strips on
       mid-width viewports without hurting the plain tiles. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
}
.summary-tile {
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.tile-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); }
.tile-value { font-size: 1.85rem; font-weight: 700; color: var(--ink); line-height: 1.1; }
.tile-sub { font-size: 0.82rem; }
.tile-cached .tile-value { color: var(--success); }
.tile-in-flight .tile-value { color: var(--info); }
.tile-remaining .tile-value { color: var(--warn); }
.tile-error .tile-value { color: var(--error); }
.tile-action { align-self: flex-start; margin-top: 6px; }
.tile-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.tile-actions .tile-action { align-self: auto; margin-top: 0; }
.tile-workers .tile-value { color: var(--accent); }

/* Split-face tile: two side-by-side columns showing books vs sub-refs.
   Uses grid so the two columns share width equally regardless of value
   length, and a soft divider makes the split legible at a glance. */
.tile-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 10px;
    margin-top: 2px;
}
.tile-split-col {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 4px 8px 4px 10px;
    border-right: 1px solid var(--border);
    min-width: 0;
}
.tile-split-col:last-child {
    border-right: none;
    padding-right: 0;
}
.tile-split-hdr {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ink-muted);
    font-weight: 600;
}
.tile-split-val {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.05;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.tile-split-meta {
    font-size: 0.75rem;
    line-height: 1.25;
}
/* Column-specific accents so the tone matches the tile's status without
   yelling — books get the tile's primary hue, sub-refs stay neutral. */
.tile-cached .tile-split-col:first-child .tile-split-val { color: var(--success); }
.tile-in-flight .tile-split-col:first-child .tile-split-val { color: var(--info); }
.tile-remaining .tile-split-col:first-child .tile-split-val { color: var(--warn); }
.tile-error .tile-split-col:first-child .tile-split-val { color: var(--error); }
.tile-cached .tile-split-col:last-child .tile-split-val,
.tile-in-flight .tile-split-col:last-child .tile-split-val,
.tile-remaining .tile-split-col:last-child .tile-split-val,
.tile-error .tile-split-col:last-child .tile-split-val {
    color: var(--ink);
    opacity: 0.72;
}
.summary-bars { display: flex; flex-direction: column; gap: 10px; }
.summary-bar-row { display: flex; flex-direction: column; gap: 4px; }
.summary-bar-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 0.9rem;
}
.summary-bars .progress { height: 12px; }

.download-catalog textarea {
    width: 100%;
    padding: 10px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    font-family: var(--font-en);
    font-size: 0.95rem;
    margin-bottom: 8px;
}
.catalog-filter {
    width: 100%;
    padding: 8px 12px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    margin: 12px 0;
    background: white;
}
.catalog-list {
    list-style: none;
    padding: 0;
    max-height: 400px;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}
.catalog-list li {
    display: flex;
    gap: 10px;
    align-items: baseline;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
}
.catalog-list li:last-child { border-bottom: none; }

@media (max-width: 720px) {
    .segments { padding: 18px 20px; font-size: 1.1rem; }
    .quick-search input { min-width: 0; }
    .aggregations ul { columns: 1; }
}

/* ------------------------------------------------------------------ modal */
/* Context popup shown when the user clicks a search-result / gematria ref.
   Renders the full chapter on the left, commentaries on the right, both
   panels scroll independently. */
.modal[hidden] { display: none; }
.modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
}
.modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
}
.modal-dialog {
    position: relative;
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-modal);
    width: min(1600px, 96vw);
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
    gap: 12px;
    flex-wrap: wrap;
}
.modal-title { margin: 0; display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.modal-title-block { min-width: 0; flex: 1; }
.modal-subtitle { margin: 4px 0 0; font-size: 0.9rem; }
.modal-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.modal-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    padding: 0;
    overflow: hidden;
}

/* Modal-scoped overrides on the shared mg layout — the popup lives inside
   a fixed container so we swap sticky viewport-height sides for grid tracks
   that scroll independently within the modal-body. */
.modal-reader-mg {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.modal-reader-mg > .mg-filter-bar {
    margin: 12px 16px 0;
    flex: 0 0 auto;
}
.modal-reader-mg-grid {
    flex: 1;
    min-height: 0;
    grid-template-columns: minmax(240px, 1fr) minmax(280px, 520px) minmax(240px, 1fr);
    /* Base reader grid uses `align-items: start` because its side panes
       carry a hard viewport-height. Inside the modal we want the single
       explicit row to fill the flex parent — `1fr` (not `auto`) is what
       gives the ``overflow-y: auto`` panes a bounded height to scroll
       against. `grid-auto-rows` only affects implicit rows, so switching
       to `grid-template-rows: 1fr` was needed to actually bound the
       primary row. */
    grid-template-rows: minmax(0, 1fr);
    align-items: stretch;
}
.modal-reader-mg-side {
    position: relative;
    top: 0;
    height: 100%;
    max-height: 100%;
    min-height: 0;
    overflow-y: auto;
    padding: 14px 16px;
    background: #fafaf6;
    /* Prevent scroll chaining bleeding into the parent modal-body — without
       this, wheeling upward inside a pane at scrollTop=0 propagates up and
       whatever ancestor scrolls next can consume the momentum, leaving the
       pane feeling "stuck" until the user grabs the scrollbar directly. */
    overscroll-behavior: contain;
}
.modal-reader-mg-right { border-right: 1px solid var(--border); }
.modal-reader-mg-left { border-left: 1px solid var(--border); }
.modal-reader-mg-center {
    height: 100%;
    max-height: 100%;
    overflow-y: auto;
    padding: 14px 16px;
    background: var(--surface);
    z-index: 1;
    position: relative;
    min-height: 0;
    overscroll-behavior: contain;
}
/* SVG overlay lives inside the grid; scroll containers inside individual
   panes still recompute correctly via the scroll listeners we install
   in initMgOverlay. */

/* Popup chapter view: one flowing Hebrew paragraph inside the center
   column of the modal mg layout. */
.modal-segments {
    direction: rtl;
    font-family: var(--font-he);
    font-size: 1.15rem;
    line-height: 1.95;
    text-align: right;
    unicode-bidi: isolate;
    word-spacing: 0.02em;
}
.modal-segments .modal-segment {
    display: inline;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    grid-template-columns: none;
    gap: 0;
    transition: background 0.15s;
}
.modal-segments .modal-segment + .modal-segment::before { content: " "; }
.modal-segment .modal-seg-index {
    display: inline-block;
    direction: ltr;
    unicode-bidi: isolate;
    color: var(--ink-muted);
    font-family: var(--font-en);
    font-size: 0.7rem;
    line-height: 1;
    vertical-align: super;
    margin: 0 0.15em 0 0.25em;
}
.modal-segment .modal-seg-he {
    display: inline;
    direction: rtl;
    text-align: right;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    unicode-bidi: isolate;
}
.modal-segment.is-highlighted .modal-seg-he {
    background: #fff4c8;
    box-shadow: 0 0 0 2px rgba(240, 201, 90, 0.35);
    border-radius: 3px;
    padding: 0 3px;
}
.modal-segment mark {
    background: #ffe15a;
    padding: 0 2px;
    border-radius: 2px;
}

/* Focus-verse marker for the popup layout (.segment) — used when a caller
   opens the modal on a specific verse ref (e.g. clicking an entropy /
   search / gematria result). The whole verse gets a soft warm background,
   a left accent, and the verse-number badge changes into an "active"
   pill so the user can spot the target verse even at a glance in a
   long chapter. */
.modal .segment.is-highlighted {
    background: linear-gradient(90deg,
        rgba(232, 130, 30, 0.14) 0%,
        rgba(255, 240, 200, 0.55) 40%,
        rgba(255, 240, 200, 0.00) 100%);
    border-radius: 6px;
    box-shadow: inset 4px 0 0 0 rgba(232, 130, 30, 0.85);
    padding: 4px 6px;
    scroll-margin-top: 24px;
}
.modal .segment.is-highlighted .segment-index,
.modal .segment.is-highlighted .mg-verse-marker {
    background: rgba(232, 130, 30, 0.9);
    color: #fff;
    border-color: rgba(232, 130, 30, 1);
    box-shadow: 0 0 0 3px rgba(232, 130, 30, 0.25);
    transform: scale(1.05);
}
.modal .segment.is-highlighted .segment-text {
    background: rgba(255, 225, 120, 0.35);
    border-radius: 3px;
    padding: 0 3px;
}
.modal .segment.is-highlighted.is-highlight-flash {
    animation: verse-flash 1.6s ease-out;
}
@keyframes verse-flash {
    0%   { box-shadow: inset 4px 0 0 0 rgba(232, 130, 30, 0.85),
                       0 0 0 3px rgba(232, 130, 30, 0.60); }
    30%  { box-shadow: inset 4px 0 0 0 rgba(232, 130, 30, 0.85),
                       0 0 0 8px rgba(232, 130, 30, 0.00); }
    100% { box-shadow: inset 4px 0 0 0 rgba(232, 130, 30, 0.85); }
}

/* Global fallback for <mark> inside the reader modal / segments / mg
   cards. The popup layout was rebuilt to use ``.segment`` cards (not
   ``.modal-segment``) so the older, more specific rule alone would miss
   the phrase-highlighted matches. */
.modal .segment mark,
.modal .mg-commentary-body mark,
.reader-body mark {
    background: #ffe15a;
    color: inherit;
    padding: 0 2px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(232, 168, 30, 0.5);
}

/* Extra emphasis on the specific match we scrolled to, so a user can
   spot their query at a glance even if the verse has other candidates. */
.modal .segment mark.is-focus-match,
.reader-body mark.is-focus-match {
    background: #ffb84d;
    box-shadow: 0 0 0 2px rgba(232, 130, 30, 0.55);
}

/* Curated gematria-multiplier focus hits (admin word list → reader). */
.reader-body mark.gematria-multi-mark {
    background: rgba(92, 58, 104, 0.16);
    color: inherit;
    padding: 0 2px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(92, 58, 104, 0.45);
    cursor: help;
    position: relative;
}
.reader-body mark.gematria-multi-mark:hover,
.reader-body mark.gematria-multi-mark:focus {
    background: rgba(92, 58, 104, 0.28);
    box-shadow: 0 0 0 2px rgba(92, 58, 104, 0.55);
    outline: none;
}
.reader-body mark.gematria-multi-mark[data-tip]:hover::after,
.reader-body mark.gematria-multi-mark[data-tip]:focus::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 6px);
    right: 0;
    z-index: 40;
    /* One match per line; do not wrap mid-phrase. */
    white-space: pre;
    width: max-content;
    max-width: min(90vw, 22rem);
    padding: 8px 12px;
    border-radius: 6px;
    background: #3a2442;
    color: #f7f1fb;
    font-size: 0.9rem;
    font-family: var(--font-he), serif;
    line-height: 1.55;
    direction: rtl;
    text-align: right;
    box-shadow: 0 4px 14px rgba(40, 20, 50, 0.28);
    pointer-events: none;
}

.modal-commentaries { display: flex; flex-direction: column; gap: 12px; }
.modal-commentary {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    padding: 10px 12px;
}
.modal-commentary-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 6px;
}
.modal-commentary-name {
    font-weight: 600;
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.modal-commentary-name .he { font-family: var(--font-he); font-size: 1.1rem; }
.modal-commentary-body { font-family: var(--font-he); direction: rtl; text-align: right; line-height: 1.85; }
.modal-commentary-body .modal-en { direction: ltr; text-align: left; font-family: var(--font-en); font-size: 0.92rem; color: var(--ink-muted); margin-top: 4px; }

.modal-loading { color: var(--ink-muted); font-size: 0.95rem; padding: 12px 0; }
.modal-error { color: var(--error); font-size: 0.95rem; padding: 12px 0; }
.modal-empty { color: var(--ink-muted); font-size: 0.95rem; padding: 12px 0; font-style: italic; }

@media (max-width: 900px) {
    .modal-body { grid-template-columns: 1fr; }
    .modal-text-col { border-right: none; border-bottom: 1px solid var(--border); }
    .modal-segments { padding: 12px 14px; font-size: 1.05rem; }
}

/* =====================================================================
   Shared row-hover tooltip. Originally built for the Entropy dashboard
   but now only surfaces on Palindrome rows (see initPalindromeRowHover
   in app.js). Kept CSS class names to avoid an app.js churn.
   ===================================================================== */

.entropy-tooltip {
    position: absolute;
    max-width: 360px;
    background: rgba(46, 32, 18, 0.94);
    color: #fdfbf4;
    font-size: 0.85rem;
    padding: 6px 10px;
    border-radius: 4px;
    pointer-events: none;
    z-index: 5;
    line-height: 1.35;
}
.entropy-tooltip[hidden] { display: none; }

/* Row-hover variant lives on document.body and follows the cursor with
   position: fixed so it can never get clipped by an inner table's
   overflow / scrollbar. Wider than the canvas tooltip because it prints
   the whole verse. */
.entropy-tooltip.entropy-row-tip {
    position: fixed;
    max-width: 520px;
    padding: 8px 12px;
    line-height: 1.55;
    z-index: 60;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}
.entropy-row-tip-ref {
    font-family: var(--font-he);
    font-size: 1rem;
    font-weight: 700;
    color: #ffd792;
    margin-bottom: 4px;
}
.entropy-row-tip-text {
    font-family: var(--font-he);
    font-size: 1.1rem;
    color: #fdfbf4;
    /* Keep long verses readable without ballooning the tip on wide screens. */
    max-height: 12em;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 8;
    -webkit-box-orient: vertical;
}
.entropy-row-tip-meta {
    margin-top: 4px;
    color: rgba(253, 251, 244, 0.75);
}
.entropy-row-tip-meta strong { color: #fdfbf4; font-weight: 700; }

/* Palindrome tab: same tooltip skeleton as entropy but with an amber
   <mark> that stays legible against the dark tip background, and a
   compact per-table layout so both extremes tables share one page. */
.palindrome-row-tip { max-width: 620px; }
.palindrome-row-tip .palindrome-mark {
    background: #ffb84d;
    color: #1a1a1a;
    padding: 0 2px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(232, 130, 30, 0.85);
}
.palindromes-panel .palindrome-table {
    width: 100%;
    font-size: 0.95rem;
}
.palindromes-panel .palindrome-table th { font-weight: 700; }
.palindromes-panel .palindrome-table td.he,
.palindromes-panel .palindrome-table th { text-align: right; }
.palindromes-panel .palindrome-table td.num,
.palindromes-panel .palindrome-table th.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    width: 90px;
}
.palindromes-panel .palindrome-table tr.is-clickable:hover {
    background: #fbf3dc;
}
.palindromes-panel .palindrome-table td.he[dir="rtl"] {
    font-family: var(--font-he);
    font-size: 1.1rem;
    line-height: 1.5;
}

/* Small pill showing how many verses contain this palindrome. Sits in
   the "הופעות" column and mirrors the styling used by the gematria
   count badges for visual consistency. */
.palindrome-count-badge {
    display: inline-block;
    min-width: 2.2em;
    padding: 2px 8px;
    border-radius: 999px;
    background: #eae1c4;
    color: #4a3a12;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 0.9rem;
    text-align: center;
}
.palindrome-table tr:hover .palindrome-count-badge {
    background: #d9c98a;
}

/* Expandable "+N מיקומים נוספים" list under the primary ref. Clicking
   the <summary> or any link inside the list must NOT trigger the row's
   own modal-open delegate — we call event.stopPropagation in the
   template so the wider row click stays as "open the first match". */
.palindromes-panel .palindrome-table .other-refs {
    margin-top: 6px;
    text-align: right;
}
.palindromes-panel .palindrome-table .other-refs > summary {
    cursor: pointer;
    list-style: none;
    color: var(--muted);
    font-size: 0.85rem;
    display: inline-block;
    padding: 2px 6px;
    border-radius: 4px;
}
.palindromes-panel .palindrome-table .other-refs > summary:hover {
    background: #f5edd1;
    color: var(--text);
}
.palindromes-panel .palindrome-table .other-refs > summary::-webkit-details-marker {
    display: none;
}
.palindromes-panel .palindrome-table .other-refs[open] > summary::before {
    content: "▾ ";
}
.palindromes-panel .palindrome-table .other-refs:not([open]) > summary::before {
    content: "▸ ";
}
.palindromes-panel .palindrome-table .other-refs ul {
    list-style: none;
    padding: 6px 10px 4px;
    margin: 4px 0 0;
    max-height: 220px;
    overflow-y: auto;
    background: #fbf5e3;
    border-radius: 6px;
    border: 1px solid var(--border);
    columns: 2;
    column-gap: 12px;
}
.palindromes-panel .palindrome-table .other-refs li {
    break-inside: avoid;
    padding: 2px 0;
    font-size: 0.92rem;
}
.palindromes-panel .palindrome-table .other-refs li a {
    color: var(--link);
    text-decoration: none;
}
.palindromes-panel .palindrome-table .other-refs li a:hover {
    text-decoration: underline;
}

/* --- Search page: "author matches" panel ---------------------------
   Rendered above the regular hit list when the query matches a
   commentator's canonical name (heCollectiveTitle / heCommentator) or a
   word inside a leaf book's heTitle. One <details> card per author;
   the first two auto-open so common queries like "רש\"י" land on a
   list of works immediately without the user having to click. */
.author-matches {
    margin: 18px 0 28px;
    padding: 16px 20px;
    background: #fbf5e3;
    border: 1px solid var(--border);
    border-radius: 8px;
}
.author-matches-head h2 {
    margin: 0 0 4px;
    font-size: 1.15rem;
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}
.author-matches-head p {
    margin: 0 0 12px;
}
.author-card {
    margin-top: 10px;
    padding: 10px 14px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 6px;
}
.author-card > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
}
.author-card > summary::-webkit-details-marker { display: none; }
.author-card > summary::before {
    content: "▸";
    color: var(--muted);
    margin-inline-end: 6px;
    transition: transform 120ms ease;
    display: inline-block;
}
.author-card[open] > summary::before { content: "▾"; }
.author-name {
    font-family: var(--font-he);
    font-size: 1.4rem;
    font-weight: 700;
}
.author-book-count {
    color: var(--muted);
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
    background: #eae1c4;
    padding: 2px 10px;
    border-radius: 999px;
    color: #4a3a12;
    font-weight: 600;
}
.author-book-list {
    list-style: none;
    padding: 6px 0 0;
    margin: 6px 0 0;
    border-top: 1px dashed var(--border);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 6px 14px;
}
.author-book {
    padding: 4px 6px;
    border-radius: 4px;
    line-height: 1.35;
}
.author-book:hover { background: #f5edd1; }
.author-book a {
    color: var(--link);
    text-decoration: none;
    display: block;
    font-family: var(--font-he);
    font-size: 1.05rem;
}
.author-book a:hover { text-decoration: underline; }
.author-book .muted {
    display: block;
    margin-top: 2px;
    font-size: 0.78rem;
}

/* ==========================================================
   Admin dashboard (/admin/)
   ========================================================== */
.admin-panel {
    max-width: 1400px;
    margin: 24px auto;
    padding: 0 20px 40px;
}
/* Wide data tables (users) — full viewport width, no horizontal
   scrollbar: the table must fit the page, not scroll inside a wrap. */
.admin-panel--wide {
    max-width: none;
    width: 100%;
    box-sizing: border-box;
    padding-inline: 12px;
}
.admin-panel--wide .admin-table-wrap {
    overflow-x: visible;
}
.admin-panel--wide .admin-table {
    width: 100%;
    table-layout: auto;
    font-size: 0.84rem;
}
.admin-panel--wide .admin-table th,
.admin-panel--wide .admin-table td {
    padding: 6px 6px;
}
.admin-panel--wide .admin-table thead th {
    font-size: 0.78rem;
    letter-spacing: 0;
    padding: 6px 4px;
}
.admin-panel--wide .admin-table-avatar {
    width: 28px;
    height: 28px;
    font-size: 0.75rem;
}
.admin-panel--wide .admin-user-cell {
    gap: 6px;
}
.admin-panel--wide .pill {
    padding: 1px 6px;
    font-size: 0.75rem;
}
.admin-panel .admin-head {
    display: flex;
    align-items: baseline;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 20px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.admin-panel .admin-head h1 { margin: 0; font-size: 1.9rem; }
.admin-subnav {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-inline-start: auto;
}
.admin-subnav a {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--border);
    font-weight: 600;
    text-decoration: none;
    font-size: 0.95rem;
}
.admin-subnav a:hover { background: var(--surface-2); }
.admin-subnav a.active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}
.admin-nav-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.35rem;
    height: 1.35rem;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.admin-subnav a.active .admin-nav-badge {
    background: #fff;
    color: var(--accent);
}

.admin-notice {
    padding: 10px 14px;
    background: #fff7e6;
    border: 1px solid #f3d38f;
    border-radius: var(--radius);
    color: #7a5900;
    margin-bottom: 18px;
}
.admin-notice code {
    background: rgba(0,0,0,0.05);
    padding: 1px 6px;
    border-radius: 4px;
}

/* --------------------------------------------------------------------
   Shared admin pill — used in tables and feedback cards to make
   boolean / status columns readable at a glance.  Kept small,
   monochrome-plus-accent to match the KPI palette.
   -------------------------------------------------------------------- */
.pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-size: 0.78rem;
    line-height: 1.6;
    font-weight: 600;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--ink-muted);
    white-space: nowrap;
}
.pill--good   { background: #ecf7f0; border-color: #b6d4c1; color: #237a4b; }
.pill--accent { background: #f2ecf7; border-color: #c8b9df; color: #6b4a9e; }
.pill--warn   { background: #fff7e6; border-color: #f3d38f; color: #7a5900; }
.pill--muted  { /* uses defaults above */ }

/* Sub-nav variant used as a filter chip row inside a page (e.g.
   feedback-status filters).  Same visual language, spaced from the
   main head so the two-level hierarchy is clear. */
.admin-subnav--filters {
    margin: 4px 0 14px !important;
    margin-inline-start: 0 !important;
}

/* Wrap tables so wide row widths scroll horizontally instead of
   breaking the layout on narrow viewports. */
.admin-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Tight inline-flex row for per-row action buttons in admin tables
   (edit + delete + …).  Keeps buttons from wrapping onto separate
   lines when the row is wide enough and lets each caller decide the
   button variants. */
.admin-row-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------
   /admin/system live-dashboard specific: thin inline usage bar for the
   filesystem table.  Fixed-width column so the bars line up visually
   across rows regardless of the numeric columns to the right.
   -------------------------------------------------------------------- */
.sys-bar-cell { width: 120px; }
.sys-bar {
    position: relative;
    height: 8px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--hair);
    overflow: hidden;
}
.sys-bar > span {
    display: block;
    height: 100%;
    background: #237a4b;
    transition: width 0.4s ease;
}
.sys-bar--warn     > span { background: #b47b00; }
.sys-bar--critical > span { background: #b1263c; }

/* KPI grid on the system page can be tighter — the tile content is
   short (percentages + one sub-line), no need to reserve a big card. */
.sys-kpi-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

.sys-maxima { margin-top: var(--space-4); }
.sys-max-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 10px;
}
.sys-max-card {
    display: grid;
    gap: 4px;
    min-height: 88px;
    padding: 14px 16px;
    border: 1px solid var(--hair);
    border-top: 3px solid var(--accent);
    border-radius: var(--radius);
    background: var(--surface);
}
.sys-max-card > span {
    color: var(--muted);
    font-size: .8rem;
}
.sys-max-card strong {
    align-self: end;
    color: var(--ink);
    font-size: 1.35rem;
    line-height: 1.2;
}
.sys-max-card--network strong { font-size: .95rem; }
@media (max-width: 1000px) {
    .sys-max-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
    .sys-max-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sys-max-card--network { grid-column: span 2; }
}

/* Trend-graph grid on the system page.  Two columns on desktop,
   collapses to one on narrow viewports so the sparklines never squash
   into an unreadable strip. */
.sys-charts .sys-chart-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
}
.sys-chart {
    margin: 0;
    padding: 12px 12px 8px;
    background: var(--surface-1);
    border: 1px solid var(--hair);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sys-chart figcaption {
    font-size: 12px;
    color: var(--text-2);
    letter-spacing: 0.2px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.sys-chart canvas {
    width: 100%;
    height: 140px;
    display: block;
}
.sys-chart-legend {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--text-2);
}
.sys-swatch {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 2px;
    vertical-align: middle;
}
.sys-swatch--rx { background: #6b8f4e; }
.sys-swatch--tx { background: #a65454; }

/* ─── Alert management page ─────────────────────────────────── */
.alert-settings-form,
.alert-add-form { max-width: 700px; }

.alert-form-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 14px;
}
.alert-label {
    font-weight: 600;
    font-size: .9rem;
    color: var(--text-1, #222);
}
.alert-input,
.alert-select {
    padding: 7px 10px;
    border: 1px solid var(--border, #d6cfc4);
    border-radius: 5px;
    font-size: .9rem;
    background: #fff;
    color: var(--text-1, #222);
    max-width: 340px;
    width: 100%;
}
.alert-input:focus,
.alert-select:focus {
    outline: 2px solid #8a1e1e;
    outline-offset: 1px;
}
.alert-email-list {
    min-height: 100px;
    resize: vertical;
    direction: ltr;
    text-align: left;
}
.alert-form-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 4px;
}
.alert-add-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0 16px;
}
.alert-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border, #d6cfc4);
}
.alert-rule-disabled td { opacity: .5; }
.alert-rule-actions { white-space: nowrap; display: flex; gap: 4px; align-items: center; }

.btn.danger {
    background: transparent;
    color: #b1263c;
    border: 1px solid #b1263c;
}
.btn.danger:hover { background: #b1263c; color: #fff; }

.chip-green { background: #d4edda; color: #155724; }
.chip-gray  { background: #e9ecef; color: #6c757d; }

.admin-flash {
    padding: 10px 16px;
    border-radius: 6px;
    margin-bottom: 12px;
    font-size: .9rem;
    border: 1px solid transparent;
}
.admin-flash--success { background: #d4edda; color: #155724; border-color: #c3e6cb; }
.admin-flash--error   { background: #f8d7da; color: #721c24; border-color: #f5c6cb; }
.admin-flash--warning { background: #fff3cd; color: #856404; border-color: #ffeeba; }

/* System dashboard time-range selector */
.sys-range-btns {
    display: inline-flex;
    gap: 4px;
    align-items: center;
}
.sys-range-btn {
    border: 1px solid var(--border, #d6cfc4);
    background: transparent;
    cursor: pointer;
    border-radius: 4px;
    padding: 2px 10px;
    font-size: 0.8rem;
    color: var(--text-2, #666);
    transition: background .15s, color .15s;
}
.sys-range-btn:hover  { background: #f0ece4; }
.sys-range-btn.active { background: #8a1e1e; color: #fff; border-color: #8a1e1e; }

/* Screen-reader-only labels for form controls that use surrounding
   context as their visible label. */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0);
    white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------
   Feedback inbox cards — visually consistent with the admin-block
   blocks used on the dashboard, but stacked vertically because the
   body copy is variable-length and looks awkward in a grid.
   -------------------------------------------------------------------- */
.feedback-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.admin-block--empty { text-align: center; padding: 24px 16px; }
.feedback-card { padding: 16px 18px; }
.feedback-card-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.feedback-card-title { flex: 1 1 320px; min-width: 0; }
.feedback-card-title h2 {
    margin: 0 0 6px;
    font-size: 1.05rem;
    color: var(--ink);
    line-height: 1.35;
    word-break: break-word;
}
.feedback-card-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.feedback-card-meta .pill { font-size: 0.72rem; padding: 1px 8px; }
.feedback-url {
    color: var(--accent);
    text-decoration: none;
    overflow-wrap: anywhere;
}
.feedback-url:hover { text-decoration: underline; }
.feedback-status-form {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}
.feedback-status-form select {
    padding: 4px 8px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: var(--surface);
    font-size: 0.85rem;
}
.feedback-body {
    background: var(--surface-2);
    border: 1px solid var(--hair);
    border-radius: 6px;
    padding: 10px 12px;
    white-space: pre-wrap;
    word-break: break-word;
    font-family: inherit;
    font-size: 0.92rem;
    line-height: 1.55;
    color: var(--ink);
    margin: 0;
}

/* KPI tiles */
.kpi-grid {
    display: grid;
    /* 5 KPI tiles: fits on wide screens as 5-across (5 × ~200 px +
       gaps ≤ 1400 px content max-width).  Below ~1100 px wraps to
       3-across, then 2-across on tablets, then 1 on phones.  Odd
       leftover tiles (e.g. 5 tiles in a 3-col grid) auto-fill from
       the RTL start edge because of ``grid-auto-flow`` default. */
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}
.kpi {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 14px 16px 14px 20px;   /* extra inline-start room for stripe */
    box-shadow: none;
    position: relative;
    overflow: hidden;
    min-width: 0;
}
.kpi::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    width: 4px;
    height: 100%;
    background: var(--accent);
}
.kpi-blue::before   { background: #285e9c; }
.kpi-green::before  { background: #237a4b; }
.kpi-purple::before { background: #6b4a9e; }
.kpi-amber::before  { background: #b47b00; }
.kpi-teal::before   { background: #167a70; }
.kpi-orange::before { background: #b85c1d; }

/* --------------------------------------------------------------------
   Live-metric KPI states — the admin/system dashboard flips these on
   when a metric crosses 80/90%, so a full disk or thrashing CPU
   reads as "warn"/"critical" without redrawing the whole tile.
   -------------------------------------------------------------------- */
.kpi--warn      { background: #fff7e6; }
.kpi--warn::before      { background: #b47b00 !important; }
.kpi--critical  { background: #fdecec; }
.kpi--critical::before  { background: #b1263c !important; }
.kpi--critical .kpi-value { color: #8a1727; }

.kpi-label {
    color: var(--ink-muted);
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}
.kpi-value {
    font-size: 2.2rem;
    font-weight: 800;
    line-height: 1.1;
    margin: 6px 0 8px;
    color: var(--ink);
}
.kpi-sub { display: flex; gap: 6px; flex-wrap: wrap; }
.kpi-sub .chip {
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    font-size: 0.8rem;
    color: var(--ink-muted);
}
.kpi-sub .chip.up { color: var(--success); border-color: #b6d4c1; background: #ecf7f0; }

/* --------------------------------------------------------------------
   Dash-row variants — one class per row type keeps the layout
   predictable and stops odd wrap patterns like the "single orphan
   card on its own line" bug the original ``auto-fit`` grid produced
   when the block count didn't divide evenly.
   -------------------------------------------------------------------- */
.dash-row {
    display: grid;
    gap: 14px;
    margin-bottom: 18px;
}

/* Timeline row: big 30-day chart flanked by the compact 24-hour
   chart.  2:1 ratio gives the trend chart enough horizontal room
   for readable date ticks. */
.dash-row--timeline {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
@media (max-width: 960px) {
    .dash-row--timeline { grid-template-columns: 1fr; }
}

/* Four small pies in a row — auth split / device / browser / OS. */
.dash-row--pies {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1100px) {
    .dash-row--pies { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
    .dash-row--pies { grid-template-columns: 1fr; }
}

/* Countries chart + top-pages table — 1:2 so the table gets the
   room its rows need. */
.dash-row--geo {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}
@media (max-width: 960px) {
    .dash-row--geo { grid-template-columns: 1fr; }
}

/* Word cloud + heatmap row */
.dash-row--maps {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}
@media (max-width: 960px) {
    .dash-row--maps { grid-template-columns: 1fr; }
}
.wordcloud-wrap {
    width: 100%;
    min-height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 0;
}
.wordcloud-wrap canvas {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Heatmap grid — reserve roughly the rendered grid's height up front
   (JS fills this in after the page loads) so the swap from empty to
   populated doesn't reflow content below it and yank the scroll
   position on the auto-refresh reload. */
.heatmap-wrap { padding: 8px 0; min-height: 120px; }
.heatmap-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    direction: ltr;
}
.heatmap-cell {
    width: 38px;
    min-height: 38px;
    border-radius: 5px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: default;
    font-size: 0.65rem;
    gap: 1px;
    transition: opacity .15s;
}
.heatmap-cell:hover { opacity: .75; }
.heatmap-dow  { font-weight: 700; font-size: .7rem; line-height: 1; }
.heatmap-date { color: inherit; opacity: .7; font-size: .62rem; line-height: 1; }
.heatmap-lvl-0 { background: #f0ece4; color: #999; }
.heatmap-lvl-1 { background: #f5c9c9; color: #7a2020; }
.heatmap-lvl-2 { background: #e89090; color: #5a1414; }
.heatmap-lvl-3 { background: #d05050; color: #fff; }
.heatmap-lvl-4 { background: #a82828; color: #fff; }
.heatmap-lvl-5 { background: #7a1010; color: #fff; }
.heatmap-legend {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 10px;
}
.heatmap-legend-cell {
    width: 16px;
    min-height: 16px;
    border-radius: 3px;
    cursor: default;
    flex-direction: row;
}

/* World hit map — vendored SVG (static/world-map.svg) colored in JS
   from the countries leaderboard. Kept LTR regardless of page
   direction since geography reads the same either way.
   ``aspect-ratio`` matches the source SVG's viewBox (2000x1001) so the
   container reserves its final height *before* the async fetch/inject
   swaps the "loading…" placeholder for the real map — otherwise that
   swap reflows everything below it and yanks the scroll position on
   the dashboard's auto-refresh reload. */
.world-map-wrap {
    position: relative;
    direction: ltr;
    padding: 8px 0 4px;
    aspect-ratio: 2000 / 1001;
    min-height: 220px;
}
.world-map-wrap svg {
    display: block;
    width: 100%;
    height: auto;
}
.world-map-wrap svg path {
    fill: #e7e2d8;
    stroke: var(--surface, #fff);
    stroke-width: 0.75;
    transition: fill .15s, opacity .15s;
}
.world-map-wrap svg path[data-hit] {
    cursor: pointer;
}
.world-map-wrap svg path[data-hit]:hover {
    opacity: .8;
    stroke: var(--accent);
    stroke-width: 1.25;
}
.world-map-legend {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    direction: rtl;
    flex-wrap: wrap;
}
.world-map-legend-swatch {
    width: 16px;
    height: 16px;
    border-radius: 3px;
    display: inline-block;
}
.world-map-tooltip {
    position: absolute;
    z-index: 5;
    pointer-events: none;
    background: rgba(30, 24, 20, 0.92);
    color: #fff;
    padding: 5px 10px;
    border-radius: 6px;
    font-size: 0.82rem;
    line-height: 1.4;
    white-space: nowrap;
    transform: translate(-50%, -100%);
    opacity: 0;
    transition: opacity .1s;
    direction: rtl;
}
.world-map-tooltip.is-visible { opacity: 1; }
.world-map-tooltip strong { font-family: var(--font-he); }

/* Four leaderboards (search / gematria / dilugim / reads). */
.dash-row--leaderboards {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
@media (max-width: 1100px) {
    .dash-row--leaderboards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
    .dash-row--leaderboards { grid-template-columns: 1fr; }
}

/* Two side-by-side tables (recent feedback / recent users). */
.dash-row--twocol {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 900px) {
    .dash-row--twocol { grid-template-columns: 1fr; }
}

/* Legacy ``wide`` modifier still supported for callers that haven't
   migrated to explicit row classes yet — behaves as a plain column
   span within a grid that has enough tracks. */
.dash-row .admin-block.wide,
.dash-row .chart-block--wide { grid-column: span 1; }
@media (min-width: 901px) {
    .dash-row.dash-row--legacy .admin-block.wide,
    .dash-row.dash-row--legacy .chart-block--wide { grid-column: span 2; }
}

.admin-block {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: 14px 16px 16px;
    box-shadow: none;
    margin-bottom: 14px;
}
.admin-block .block-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.admin-block .block-head h2 {
    margin: 0;
    font-size: 1.1rem;
    color: var(--ink);
}
.admin-block .block-head .btn.small {
    margin-inline-start: auto;
    padding: 4px 10px;
    font-size: 0.85rem;
}

.chart-wrap {
    position: relative;
    height: 300px;
}
.chart-wrap.small { height: 220px; }
.chart-block { min-width: 0; }

.admin-list { list-style: none; padding: 0; margin: 0; }
.admin-list li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 6px 0;
    border-bottom: 1px dashed var(--border);
    font-size: 0.95rem;
}
.admin-list li:last-child { border-bottom: none; }
.admin-count {
    display: inline-block;
    min-width: 40px;
    padding: 1px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    text-align: center;
    font-weight: 700;
    font-size: 0.8rem;
    color: var(--ink);
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}
.admin-table th, .admin-table td {
    padding: 8px 10px;
    text-align: start;
    border-bottom: 1px solid var(--border);
}
.admin-table thead th {
    background: var(--surface-2);
    color: var(--ink-muted);
    font-weight: 700;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    text-align: center;
}
.admin-table thead th.is-sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.admin-table thead th.is-sortable:hover,
.admin-table thead th.is-sortable:focus-visible {
    color: var(--ink);
    outline: none;
}
.admin-table thead th.is-sortable::after {
    content: " ↕";
    opacity: 0.35;
    font-weight: 400;
    font-size: 0.75em;
}
.admin-table thead th.is-sorted-asc::after {
    content: " ▲";
    opacity: 0.9;
}
.admin-table thead th.is-sorted-desc::after {
    content: " ▼";
    opacity: 0.9;
}
.admin-table.zebra tbody tr:nth-child(even) { background: rgba(0,0,0,0.02); }
/* Keep date+time on one line in dense admin tables. */
.admin-table time,
.admin-table .admin-datetime {
    white-space: nowrap;
}
.admin-table code {
    background: rgba(0,0,0,0.04);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 0.85rem;
}

/* =====================================================================
   Full-page loading overlay
   --------------------------------------------------------------------
   Reusable modal-style spinner shown in the middle of the viewport for
   long-running client flows.  Currently used by the Google-Docs lesson
   import (`static/app.js :: initLessonImport`) to cover the "loading
   API → picker → server-side import + reference analysis" window.
   ================================================================== */
.page-loading-overlay {
    position: fixed;
    inset: 0;
    background: rgba(20, 22, 30, 0.55);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    opacity: 0;
    pointer-events: none;
    transition: opacity 120ms ease;
}
.page-loading-overlay.is-visible {
    opacity: 1;
    pointer-events: auto;
}
.page-loading-card {
    background: var(--surface, #fff);
    color: var(--ink, #1a1a1a);
    border-radius: 12px;
    padding: 28px 36px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
    min-width: 280px;
    max-width: 420px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}
.page-loading-spinner {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 4px solid rgba(0, 0, 0, 0.1);
    border-top-color: var(--accent, #3b6ea8);
    animation: page-loading-spin 900ms linear infinite;
}
@keyframes page-loading-spin {
    to { transform: rotate(360deg); }
}
.page-loading-label {
    font-size: 1.02rem;
    font-weight: 600;
    line-height: 1.3;
}
.page-loading-sub {
    line-height: 1.4;
}

/* =====================================================================
   Lessons
   ================================================================== */

/* ---- List page ------------------------------------------------------ */
.lessons-page { padding: 8px 0 40px; }
.lessons-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}
.lessons-head h1 {
    margin: 0 0 6px;
    font-size: 1.7rem;
    color: var(--ink);
}
.lessons-head .lede { max-width: 600px; margin: 0; }
.lessons-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 20px;
}
.lessons-tab {
    background: none;
    border: none;
    padding: 10px 16px;
    cursor: pointer;
    color: var(--muted);
    font-size: 0.95rem;
    font-weight: 500;
    border-bottom: 2px solid transparent;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: color 0.15s, border-color 0.15s;
}
.lessons-tab:hover { color: var(--ink); }
.lessons-tab.is-active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.lessons-tab .badge {
    background: var(--surface-2);
    color: var(--muted);
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
}
.lessons-tab.is-active .badge {
    background: var(--accent);
    color: #fff;
}
.lessons-panel[hidden] { display: none; }

.lesson-grid {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
}
@media (max-width: 900px) { .lesson-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .lesson-grid { grid-template-columns: 1fr; } }

.lesson-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0;
    display: flex;
    flex-direction: column;
    transition: border-color 0.15s, transform 0.1s;
}
.lesson-card:hover { border-color: var(--accent); }
.lesson-card-link {
    display: block;
    padding: 16px;
    color: inherit;
    text-decoration: none;
    flex: 1;
}
.lesson-card-title {
    margin: 0 0 8px;
    font-size: 1.05rem;
    color: var(--ink);
}
.lesson-card-topic { margin: 0 0 8px; }
.lesson-card-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin: 0;
}
.lesson-card-actions {
    padding: 8px 16px 12px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 6px;
    flex-wrap: wrap;
}
.lesson-card-delete-form { margin: 0; }
.lesson-visibility {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 4px;
    font-size: 0.78rem;
    font-weight: 600;
}
.lesson-visibility--private { background: var(--surface-2); color: var(--muted); }
.lesson-visibility--shared { background: #d5efdd; color: #1d6c37; }
.lessons-empty {
    text-align: center;
    padding: 60px 20px;
    color: var(--muted);
}
.lessons-empty p { margin: 0 0 16px; }

/* ---- Editor --------------------------------------------------------- */
/* Suggestions used to live in a right-hand side panel.  They now
   render inline inside each step's card (see
   ``.lesson-step-suggestions`` below), so the editor is a plain
   single-column layout with no companion aside. */
.lesson-editor { padding: 8px 0 60px; max-width: 900px; margin: 0 auto; }
.lesson-editor-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.lesson-editor-crumbs {
    display: flex;
    gap: 6px;
    color: var(--muted);
    font-size: 0.9rem;
    align-items: center;
}
.lesson-editor-crumbs a { color: var(--muted); text-decoration: none; }
.lesson-editor-crumbs a:hover { color: var(--accent); }
.lesson-editor-crumbs .sep { color: var(--border); }
.lesson-editor-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    color: var(--muted);
    padding: 4px 10px;
    background: var(--surface-2);
    border-radius: 999px;
}
.lesson-status-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--muted);
}
.lesson-editor-status.is-saved .lesson-status-dot { background: #1d6c37; }
.lesson-editor-status.is-saved { color: #1d6c37; }
.lesson-editor-status.is-dirty .lesson-status-dot { background: #b58500; }
.lesson-editor-status.is-error .lesson-status-dot { background: var(--accent); }
.lesson-editor-status.is-error { color: var(--accent); }
.lesson-editor-actions {
    display: flex;
    gap: 6px;
    align-items: center;
}

.lesson-editor-conflict {
    background: #fff4d6;
    border: 1px solid #d9b400;
    border-radius: 6px;
    padding: 12px 16px;
    margin-bottom: 20px;
}
.lesson-editor-conflict-inner {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.lesson-meta {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 20px;
    display: grid;
    gap: 12px;
}
.lesson-field { display: flex; flex-direction: column; gap: 4px; }
.lesson-field-label {
    font-size: 0.85rem;
    color: var(--muted);
    font-weight: 600;
}
.lesson-field input[type="text"],
.lesson-field textarea {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 8px 10px;
    font-family: inherit;
    font-size: 1rem;
    color: var(--ink);
}
.lesson-field input[type="text"]:focus,
.lesson-field textarea:focus {
    outline: none;
    border-color: var(--accent);
}
.lesson-visibility-choice {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.lesson-steps { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; }
.lesson-steps-empty {
    text-align: center;
    color: var(--muted);
    padding: 30px 20px;
    background: var(--surface-soft);
    border: 1px dashed var(--border);
    border-radius: 8px;
}
.lesson-steps-empty p { margin: 4px 0; }

.lesson-step {
    display: flex;
    gap: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px;
    /* Default cursor — text selection is the primary interaction on
       the card; the grab cursor is scoped to ``.lesson-step-grip``
       so we don't mislead users about where the drag hotspot is. */
    cursor: auto;
}
.lesson-step.is-dragging { opacity: 0.5; }
.lesson-step.is-drop-target { outline: 2px dashed var(--accent); outline-offset: 2px; }
.lesson-step.is-drop-target { border-color: var(--accent); }
.lesson-step-marker {
    flex: 0 0 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.9rem;
}
.lesson-step--note .lesson-step-marker { background: var(--muted); }
.lesson-step--commentary .lesson-step-marker { background: #4a6b8a; }
.lesson-step-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.lesson-step-head {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
}
.lesson-step-grip {
    /* Dedicated drag handle — the only ``draggable=true`` element
       on the card.  Anything else that used to intercept the
       mousedown-drag gesture (previously the whole ``li``) is now
       plain content, so users can highlight verses/notes normally. */
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    color: var(--muted);
    padding: 0 6px;
    font-size: 1.05rem;
    line-height: 1;
    border-radius: 4px;
    letter-spacing: 1px;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.lesson-step-grip:hover {
    background: var(--surface-soft);
    color: var(--ink);
}
.lesson-step-grip:active,
.lesson-step.is-dragging .lesson-step-grip {
    cursor: grabbing;
    background: var(--surface-soft);
}
.lesson-step-kind {
    font-size: 0.78rem;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-weight: 600;
}
.lesson-step-ref { color: var(--accent); text-decoration: none; font-size: 0.9rem; }
.lesson-step-ref:hover { text-decoration: underline; }
.lesson-step-he {
    font-family: inherit;
    line-height: 1.7;
    color: var(--ink);
    padding: 6px 0;
}
/* Note field = a positioned wrap holding two pixel-aligned layers:
   a backdrop (behind, holds <mark> highlights, text invisible) and
   the real textarea (front, transparent background so marks show
   through). Visible card chrome (background/border) lives on the
   wrap since both inner layers are borderless/backgroundless. */
.lesson-step-note-wrap {
    position: relative;
    width: 100%;
    min-height: 60px;
    background: var(--surface-soft);
    border: 1px solid var(--border);
    border-radius: 4px;
}
.lesson-step-note-wrap:focus-within { border-color: var(--accent); }
.lesson-step-note-backdrop,
.lesson-step-note {
    padding: 8px 10px;
    font-family: inherit;
    font-size: 0.95rem;
    line-height: 1.6;
    box-sizing: border-box;
    border: none;
}
.lesson-step-note-backdrop {
    position: absolute;
    inset: 0;
    margin: 0;
    color: transparent;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow: hidden;
    pointer-events: none;
}
.lesson-step-note-backdrop mark.lesson-note-hl {
    background: rgba(250, 176, 5, 0.55);
    color: transparent;
    border-radius: 2px;
}
.lesson-step-note {
    position: relative;
    z-index: 1;
    width: 100%;
    background: transparent;
    color: var(--ink);
    outline: none;
    /* JS grows the element to fit its full content on load/input, so
       there's never a hidden overflow requiring an inner scrollbar. */
    resize: none;
    overflow: hidden;
}
/* Fallback when the exact matched phrase can't be located in the note
   (e.g. edited since the suggestion was generated) — pulse the whole
   field so the click still gives visible feedback. */
.lesson-step-note-wrap.is-flash-highlighted {
    animation: lesson-note-flash 1.4s ease-out;
}
@keyframes lesson-note-flash {
    0% { box-shadow: 0 0 0 3px rgba(138, 30, 30, 0.35); border-color: var(--accent); }
    100% { box-shadow: 0 0 0 0 rgba(138, 30, 30, 0); }
}
.lesson-step-controls {
    display: flex;
    gap: 4px;
    justify-content: flex-end;
    align-items: center;
    margin-top: 4px;
    flex-wrap: wrap;
}
/* The two "insert after this step" buttons sit between the reorder
   arrows and the delete button — a subtle divider on each side of
   the group makes the grouping legible without shouting. */
.lesson-step-controls .lesson-step-add {
    color: var(--accent);
    border-color: rgba(138, 30, 30, 0.25);
}
.lesson-step-controls .lesson-step-add:hover {
    background: rgba(138, 30, 30, 0.06);
}

.lesson-step-adder {
    display: flex;
    gap: 8px;
    padding: 12px 0;
    border-top: 1px dashed var(--border);
}

/* ---- Add-to-lesson button on segments/commentaries ------------------ */
.add-to-lesson.tts-speaker {
    color: var(--muted);
    /* Positioned by the shared .tts-speaker rule; nothing more needed. */
}
.add-to-lesson.tts-speaker:hover {
    color: var(--accent);
}

/* ---- Selection-drawer action ---------------------------------------- */
.selection-drawer-actions {
    padding: 8px 12px 0;
    border-top: 1px solid var(--border);
    margin-top: 6px;
}

/* ---- Lesson picker modal ------------------------------------------- */
.lesson-picker-modal .modal-dialog {
    max-width: 520px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}
.lesson-picker-modal .modal-body {
    overflow-y: auto;
    padding: 16px;
}
.lesson-picker-list {
    list-style: none;
    padding: 0;
    margin: 0 0 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 40vh;
    overflow-y: auto;
}
.lesson-picker-item-btn {
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    cursor: pointer;
    text-align: start;
    transition: border-color 0.12s, background 0.12s;
}
.lesson-picker-item-btn:hover {
    border-color: var(--accent);
    background: var(--surface-soft);
}
.lesson-picker-title {
    font-weight: 600;
    color: var(--ink);
}
.lesson-picker-meta { color: var(--muted); font-size: 0.82rem; }
.lesson-picker-new {
    border-top: 1px solid var(--border);
    padding-top: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.lesson-picker-empty {
    padding: 20px;
    text-align: center;
}
.lesson-picker-loading,
.lesson-picker-error {
    padding: 16px;
    text-align: center;
    color: var(--muted);
}
.lesson-picker-error { color: var(--accent); }

/* ---- Toast --------------------------------------------------------- */
.lesson-toast {
    position: fixed;
    bottom: 20px;
    left: 20px;
    background: var(--ink);
    color: #fff;
    padding: 12px 16px;
    border-radius: 6px;
    display: flex;
    gap: 12px;
    align-items: center;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    z-index: 9999;
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.2s, transform 0.2s;
    pointer-events: none;
}
.lesson-toast.is-visible {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
.lesson-toast .btn {
    background: rgba(255,255,255,0.15);
    color: #fff;
    border-color: rgba(255,255,255,0.25);
}
.lesson-toast .btn:hover {
    background: rgba(255,255,255,0.25);
}

/* ---- Lesson view page ---------------------------------------------- */
.lesson-view { padding: 8px 0 60px; max-width: 900px; margin: 0 auto; }
.lesson-view-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}
.lesson-view-head-text { flex: 1; min-width: 260px; }
.lesson-view-kicker { margin: 0 0 6px; display: flex; gap: 6px; align-items: center; }
.lesson-view-title { margin: 0 0 6px; font-size: 1.8rem; color: var(--ink); }
.lesson-view-topic { margin: 0 0 12px; font-size: 1.05rem; color: var(--muted); }
.lesson-view-goals {
    background: var(--surface-soft);
    border-left: 3px solid var(--accent);
    padding: 8px 14px;
    border-radius: 4px;
    margin-top: 8px;
}
.lesson-view-goals h2 { margin: 0 0 4px; font-size: 0.85rem; text-transform: uppercase; }
.lesson-view-goals p { margin: 0; white-space: pre-wrap; }
.lesson-view-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.lesson-flow {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
    position: relative;
}
.lesson-flow::before {
    /* Vertical connector line running down the marker column. */
    content: "";
    position: absolute;
    top: 32px;
    bottom: 32px;
    right: 15px;    /* RTL: marker sits on the right */
    width: 2px;
    background: var(--border);
}
.lesson-flow-step {
    position: relative;
    display: flex;
    gap: 16px;
    align-items: flex-start;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 14px 16px;
}
.lesson-flow-marker {
    flex: 0 0 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.95rem;
    z-index: 1;
}
.lesson-flow-step--commentary .lesson-flow-marker { background: #4a6b8a; }
.lesson-flow-step--note .lesson-flow-marker { background: var(--muted); }
.lesson-flow-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.lesson-flow-kind {
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-weight: 600;
    margin: 0;
}
.lesson-flow-ref { margin: 0; }
.lesson-flow-ref a { color: var(--accent); text-decoration: none; font-weight: 500; }
.lesson-flow-ref a:hover { text-decoration: underline; }
.lesson-flow-text {
    line-height: 1.75;
    padding: 4px 0;
    color: var(--ink);
    white-space: pre-wrap;
}
.lesson-flow-note {
    background: var(--surface-soft);
    border: 1px solid var(--border);
    /* Accent-tinted trailing border (in RTL that's the "start" edge)
       so a teacher's note reads as a distinct annotation instead of
       melting into the verse text above it. */
    border-inline-start: 3px solid var(--accent);
    border-radius: 4px;
    padding: 10px 12px;
    margin-top: 8px;
    color: var(--ink);
}
.lesson-flow-note-label {
    margin: 0 0 4px;
    font-family: var(--font-he);
    color: var(--accent);
    font-weight: 600;
}
.lesson-flow-note-body {
    white-space: pre-wrap;
    font-size: 1rem;
    line-height: 1.65;
}
/* Free-text (kind=note) steps promote the user's text to the main
   body of the card — bigger type, no boxed background, matches the
   verse-text rhythm of ``.lesson-flow-text``. */
.lesson-flow-freetext {
    font-size: 1.05rem;
    line-height: 1.75;
    color: var(--ink);
    white-space: pre-wrap;
    padding: 6px 0;
}
.lesson-flow-freetext--empty {
    font-style: italic;
    font-size: 0.9rem;
    padding: 4px 0;
}
.lesson-flow-empty {
    text-align: center;
    padding: 40px 20px;
}

/* ---- Print stylesheet ---------------------------------------------- */
/* ---- Inline per-step suggestions (lesson editor) --------------------
   Attached below the note textarea inside each step's card.  A
   distinct dashed border + subtle background tint separates them from
   the note itself without introducing a heavy secondary surface —
   they're candidates, not committed content. */
.lesson-step-suggestions {
    margin-top: 12px;
    padding: 10px 12px;
    border: 1px dashed rgba(138, 30, 30, 0.35);
    border-radius: 8px;
    background: rgba(138, 30, 30, 0.04);
}
.lesson-step-suggestions-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}
.lesson-step-suggestions-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--accent);
    font-family: var(--font-he);
}
.lesson-step-suggestions-bulk {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.lesson-step-suggestions-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.lesson-suggestion-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 12px;
    cursor: pointer;
}
.lesson-suggestion-item:hover { border-color: rgba(138, 30, 30, 0.35); }
.lesson-suggestion-item:hover .lesson-suggestion-ref { text-decoration: underline; }
.lesson-suggestion-ref {
    display: block;
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
    font-family: var(--font-he);
    margin-bottom: 4px;
}
.lesson-suggestion-ref:hover { text-decoration: underline; }
.lesson-suggestion-source {
    display: inline-block;
    font-size: 0.7rem;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--muted);
    margin-inline-start: 6px;
    vertical-align: middle;
}
.lesson-suggestion-source--citation {
    color: var(--accent);
    border-color: rgba(138, 30, 30, 0.3);
}
.lesson-suggestion-snippet {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--ink);
    margin: 6px 0 10px;
    max-height: 5.5em;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
}
.lesson-suggestion-actions {
    display: flex;
    gap: 6px;
}
.lesson-suggestion-actions .btn.small { padding: 4px 10px; font-size: 0.8rem; }

/* ------------------------------------------------------------------ Mobile notice */
/* Full-screen backdrop */
.mobile-notice {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .65);
    backdrop-filter: blur(3px);
    padding: 24px;
    animation: mobile-notice-in .3s ease;
}
/* hidden attribute must win over display:flex */
.mobile-notice[hidden] { display: none !important; }
/* Inner card */
.mobile-notice-card {
    background: #fff;
    border-radius: var(--radius-lg);
    box-shadow: 0 12px 48px rgba(0,0,0,.35);
    padding: 36px 28px 28px;
    text-align: center;
    max-width: 360px;
    width: 100%;
    animation: mobile-notice-card-in .38s cubic-bezier(.22,.68,0,1.1);
}
@keyframes mobile-notice-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes mobile-notice-card-in {
    from { transform: scale(.88) translateY(20px); opacity: 0; }
    to   { transform: scale(1)   translateY(0);    opacity: 1; }
}
.mobile-notice-hide {
    animation: mobile-notice-out .25s ease forwards;
}
@keyframes mobile-notice-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}
.mobile-notice-icon { font-size: 2.8rem; margin-bottom: 14px; display: block; }
.mobile-notice-title {
    margin: 0 0 10px;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--ink);
}
.mobile-notice-text {
    margin: 0 0 22px;
    font-size: 0.92rem;
    line-height: 1.65;
    color: var(--ink-muted);
}
.mobile-notice-close {
    width: 100%;
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    padding: 12px;
    font-size: 1rem;
    border-radius: var(--radius);
    font-weight: 600;
}
.mobile-notice-close:hover { background: var(--accent-strong); }

/* ------------------------------------------------------------------ Cookie banner */
.cookie-banner {
    position: fixed;
    bottom: 24px;
    left: 24px;
    z-index: 9999;
    width: 320px;
    max-width: calc(100vw - 32px);
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 32px rgba(0,0,0,.14), 0 2px 8px rgba(0,0,0,.08);
    padding: 20px;
    animation: cookie-pop-in .35s cubic-bezier(.22,.68,0,1.2);
}
@keyframes cookie-pop-in {
    from { transform: translateY(20px) scale(.96); opacity: 0; }
    to   { transform: translateY(0)    scale(1);   opacity: 1; }
}
.cookie-banner-hide {
    animation: cookie-pop-out .28s ease forwards;
}
@keyframes cookie-pop-out {
    from { transform: translateY(0)    scale(1);   opacity: 1; }
    to   { transform: translateY(16px) scale(.95); opacity: 0; }
}
.cookie-banner-icon {
    font-size: 1.6rem;
    margin-bottom: 8px;
    display: block;
}
.cookie-banner-title {
    font-weight: 700;
    font-size: .95rem;
    color: var(--ink);
    margin: 0 0 6px;
}
.cookie-banner-text {
    font-size: .84rem;
    line-height: 1.55;
    color: var(--ink-muted);
    margin: 0 0 14px;
}
.cookie-banner-link {
    color: var(--accent);
    text-decoration: underline;
}
.cookie-banner-link:hover { color: var(--accent-strong); }
.cookie-banner-actions {
    display: flex;
    gap: 8px;
}
.cookie-accept {
    flex: 1;
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
    font-size: .85rem;
    padding: 7px 14px;
}
.cookie-accept:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.cookie-decline {
    font-size: .85rem;
    padding: 7px 12px;
    color: var(--muted);
    border-color: var(--border);
    background: transparent;
}
.cookie-decline:hover { color: var(--ink); border-color: var(--ink-muted); }

@media (max-width: 400px) {
    .cookie-banner { left: 12px; right: 12px; width: auto; bottom: 12px; }
}
@media print {
    .cookie-banner { display: none; }
}

@media print {
    /* --------------------------------------------------------------
       Print layout — dense, borderless, ink-friendly.  The goal is a
       clean handout: no chrome, no boxes, just the content in the
       teacher's reading order.  See per-rule notes for why each
       block exists.
       -------------------------------------------------------------- */
    .site-header,
    .site-footer,
    .selection-drawer,
    .no-print,
    .lesson-editor-toolbar,
    .lesson-step-adder,
    .lesson-step-controls,
    .lesson-step-add,
    .lesson-step-grip,
    .lesson-editor-conflict,
    .lesson-view-actions,
    .lesson-view-head-actions,
    .lesson-toast,
    .lesson-step-suggestions,
    .lesson-status,
    #lesson-picker,
    #context-modal,
    .modal,
    .flash-bar,
    .tts-speaker,
    .add-to-lesson { display: none !important; }

    @page {
        /* Tight but staple-safe margins. */
        margin: 10mm 12mm;
    }

    /* --------------------------------------------------------------
       Kill the site-wide sticky-footer flex on ``body``.  When
       printing, ``min-height: 100vh`` + ``display: flex`` was forcing
       the print engine to allocate a full-viewport block at the top
       of page 1 — the classic "first page is empty" symptom the user
       reported.  Reverting to a plain block layout for print lets
       content start at the actual top-of-page.
       -------------------------------------------------------------- */
    html, body {
        min-height: 0 !important;
        height: auto !important;
        display: block !important;
        background: #fff !important;
        color: #000 !important;
    }

    /* Kill the marker rail so the content flows edge-to-edge on
       paper. */
    .lesson-editor,
    .lesson-view { display: block !important; padding: 0 !important; margin: 0 !important; }
    .lesson-flow {
        display: block !important;   /* drop screen-mode flex ``gap`` */
        padding: 0 !important;
        margin: 0 !important;
        list-style: none;
    }
    .lesson-flow::before { display: none !important; }
    .lesson-flow-marker { display: none !important; }

    .container { max-width: 100%; padding: 0 !important; margin: 0 !important; }

    /* --------------------------------------------------------------
       Steps: content-first, no chrome.
       *  Deliberately NOT using ``break-inside: avoid`` — long Hebrew
          verses would otherwise force the whole step to the next
          page, leaving a giant blank tail at the bottom of the
          previous page (the "9-page mostly-empty PDF" symptom).
          Allowing natural mid-step page breaks costs a little
          cosmetic tidiness and gains an ~80% reduction in page
          count for large lessons.
       -------------------------------------------------------------- */
    .lesson-flow-step,
    .lesson-step {
        break-inside: auto;
        page-break-inside: auto;
        border: 0 !important;
        outline: 0 !important;
        background: transparent !important;
        box-shadow: none !important;
        padding: 0 !important;
        margin: 0 0 3mm 0 !important;
        display: block !important;
    }
    .lesson-flow-body,
    .lesson-step-body {
        padding: 0 !important;
        margin: 0 !important;
        gap: 0 !important;
        display: block !important;
    }

    /* Free-text notes render as clean paragraphs; drop the accent
       stripe + tinted background used on-screen. */
    .lesson-flow-note,
    .lesson-flow-freetext {
        border: 0 !important;
        border-inline-start: 0 !important;
        background: transparent !important;
        padding: 0 !important;
        margin: 1mm 0 0 0 !important;
    }
    .lesson-flow-note-body,
    .lesson-flow-freetext { font-size: 11pt; line-height: 1.45; }
    .lesson-flow-note-label {
        font-size: 8.5pt;
        color: #333 !important;
        margin: 0 0 0.5mm !important;
    }

    /* Ref/kind labels: tight and quiet so the eye lands on the text. */
    .lesson-flow-kind,
    .lesson-step-kind {
        font-size: 8.5pt;
        color: #333 !important;
        margin: 0 !important;
        padding: 0 !important;
    }
    .lesson-flow-ref,
    .lesson-step-ref {
        font-size: 10pt;
        color: #000 !important;
        margin: 0 0 0.5mm !important;
        text-decoration: none !important;
    }

    /* Hebrew verse / commentary bodies — this is the deliverable, so
       give it a comfortable size but no extra spacing. */
    .lesson-flow-text,
    .lesson-step-he {
        font-size: 12pt;
        line-height: 1.5;
        padding: 0 !important;
        margin: 0.5mm 0 0 !important;
    }

    /* Header block — no bottom border, no flex layout, minimal gap
       before the first step so page 1 fills naturally. */
    .lesson-view-head {
        display: block !important;
        border-bottom: 0 !important;
        margin: 0 0 3mm 0 !important;
        padding: 0 !important;
    }
    .lesson-view-head-text { min-width: 0 !important; }
    .lesson-view-kicker { font-size: 8.5pt; margin: 0 0 0.5mm !important; }
    .lesson-view-title { font-size: 16pt; margin: 0 0 1mm !important; line-height: 1.25; }
    .lesson-view-topic { font-size: 11pt; margin: 0 0 1mm !important; }
    .lesson-view-goals { margin: 0 0 1.5mm !important; }
    .lesson-view-goals h2 { font-size: 9pt; margin: 0 0 0.5mm !important; }
    .lesson-view-goals p { font-size: 10.5pt; line-height: 1.4; margin: 0 !important; }

    a { color: inherit; text-decoration: none; }

    /* --------------------------------------------------------------
       "הדפס דפי מקורות" — sources-only variant.  Triggered by JS
       setting ``body.print-sources-only`` just before opening the
       print dialog.  Hides:
         * Free-text steps          (kind='note')
         * Teacher's annotations    (``.lesson-flow-note`` on text/
                                     commentary steps — the small
                                     ``הערה`` block below the verse)
       Everything else — title, topic, goals, text steps, commentary
       steps — prints as normal so the student receives a clean
       source sheet.
       -------------------------------------------------------------- */
    body.print-sources-only .lesson-flow-step--note,
    body.print-sources-only .lesson-flow-note,
    body.print-sources-only .lesson-step--note {
        display: none !important;
    }
}

/* ------------------------------------------------------------------
   /about — public "אודות" page.
   Kept minimal on purpose: a hero, then a stack of prose sections
   with the standard ``.section-title`` divider used across the site.
   The memorial (``לעילוי נשמת``) list gets slightly warmer surface
   colour and a right-side accent stripe so it reads as a distinct,
   dedicated area without breaking the flat aesthetic.
   ------------------------------------------------------------------ */
.about-page {
    max-width: 780px;
    margin-inline: auto;
    padding-block: var(--space-4) var(--space-7);
}
/* ---- Intro video ---------------------------------------------------- */
.about-page .about-video-block {
    margin-bottom: var(--space-6);
}
.about-page .about-video-wrap {
    position: relative;
    width: 100%;
    background: #000;
    border: 1px solid var(--hair);
    border-radius: var(--radius-lg);
    overflow: hidden;
    aspect-ratio: 16 / 9;
    /* fallback for very old browsers that don't support aspect-ratio */
    max-height: min(60vh, 480px);
}
.about-page .about-video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
}
.about-page .about-video-caption {
    margin: var(--space-2) 0 0;
    text-align: center;
}

.about-page .about-hero {
    text-align: right;
    margin-bottom: var(--space-6);
}
.about-page .about-hero h1 {
    font-size: 2.1rem;
    margin: 0 0 var(--space-3);
    letter-spacing: -0.01em;
}
.about-page .about-hero .lede {
    font-size: 1.1rem;
    line-height: 1.75;
    color: var(--ink-2);
    max-width: 640px;
    margin-inline-start: 0;
}
.about-page .about-block {
    margin-block: var(--space-6);
}
.about-page .about-block p {
    line-height: 1.75;
    color: var(--ink);
    margin-block: var(--space-3);
}
.about-page .about-block a {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 3px;
}
.about-page .about-block a:hover {
    color: var(--accent-strong);
}
.about-page .about-block strong {
    color: var(--ink);
    font-weight: 600;
}

/* ---- לעילוי נשמת ---------------------------------------------------- */
.about-memorial {
    background: var(--surface-soft);
    border: 1px solid var(--hair);
    border-inline-right: 3px solid var(--accent);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-5) var(--space-4);
}
.about-memorial .section-title {
    margin-top: 0;
}
.about-memorial-intro {
    margin-top: 0;
    color: var(--ink-2);
}
.memorial-list {
    list-style: none;
    padding: 0;
    margin: var(--space-4) 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-3);
}
.memorial-card {
    background: var(--surface);
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    padding: var(--space-4);
    text-align: right;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.memorial-card--with-photo {
    align-items: center;
    text-align: center;
}
.memorial-photo-wrap {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 96px;
    height: 96px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--hair);
    flex: 0 0 auto;
}
.memorial-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    filter: grayscale(15%);
}
.memorial-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 100%;
}
.memorial-name {
    font-family: var(--font-he);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--ink);
    line-height: 1.4;
}
.memorial-parents {
    font-family: var(--font-he);
}
.memorial-dates {
    /* spacing handled by parent gap */
}
.memorial-note {
    margin: var(--space-2) 0 0;
    color: var(--ink-2);
    line-height: 1.7;
    font-size: 0.98rem;
    font-family: var(--font-he);
    font-style: italic;
    white-space: pre-line;
}
.about-memorial-verse {
    margin-top: var(--space-4);
    text-align: center;
    font-style: italic;
    color: var(--muted);
}
@media (max-width: 560px) {
    .about-page {
        padding-inline: var(--space-4);
    }
    .about-page .about-hero h1 {
        font-size: 1.7rem;
    }
    .memorial-list {
        grid-template-columns: 1fr;
    }
}

/* ------------------------------------------------------------------ */
/* פרשת שבוע                                                          */
/* ------------------------------------------------------------------ */
.parasha-week-page {
    max-width: 52rem;
    margin: 0 auto;
    padding: var(--space-6) var(--space-5) var(--space-10);
}
.parasha-week-hero h1 {
    margin: 0 0 var(--space-2);
    font-family: var(--font-he);
    font-size: 2rem;
    font-weight: 700;
    color: var(--ink);
}
.parasha-week-error {
    color: var(--danger, #a33);
    font-family: var(--font-he);
}
.parasha-week-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-6);
    margin-top: var(--space-6);
}
.parasha-week-panel {
    min-width: 0;
}
.parasha-week-name {
    margin: 0 0 var(--space-2);
    font-family: var(--font-he);
    font-size: 1.45rem;
    font-weight: 650;
    color: var(--ink);
}
.parasha-week-ref {
    margin: 0 0 var(--space-3);
    font-family: var(--font-he);
    line-height: 1.5;
}
.parasha-week-actions {
    margin: 0 0 var(--space-4);
}
.parasha-week-sub {
    margin: var(--space-4) 0 var(--space-2);
    font-family: var(--font-he);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--ink-2);
}
.parasha-week-aliyot {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.parasha-week-aliyot a {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 0.75rem;
    text-decoration: none;
    color: inherit;
    padding: 0.35rem 0;
    border-bottom: 1px solid color-mix(in srgb, var(--muted-2) 35%, transparent);
}
.parasha-week-aliyot a:hover {
    color: var(--accent, var(--ink));
}
.parasha-week-aliyah-ref {
    font-family: var(--font-he);
}
.parasha-week-kicker {
    margin: 0 0 var(--space-1);
}
.parasha-week-reason {
    margin: 0 0 var(--space-3);
    font-family: var(--font-he);
    color: var(--ink-2);
    line-height: 1.5;
}
.parasha-week-alt-intro {
    margin: 0 0 var(--space-3);
    line-height: 1.5;
}
.parasha-week-alternates {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}
.parasha-week-alt-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.35rem 0.75rem;
    font-family: var(--font-he);
}
.parasha-week-alt-head a {
    color: var(--accent, var(--ink));
    text-decoration: none;
}
.parasha-week-alt-head a:hover {
    text-decoration: underline;
}
.parasha-week-alt-note {
    margin: 0.25rem 0 0;
    line-height: 1.55;
}
.parasha-week-traditions {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}
.parasha-week-tradition-label {
    margin: 0 0 var(--space-1);
    font-family: var(--font-he);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--ink-2);
}
.parasha-week-special {
    margin: 0 0 var(--space-2);
}
@media (max-width: 720px) {
    .parasha-week-grid {
        grid-template-columns: 1fr;
    }
}
