/*
  tokens.css — Sh'elah Design Token Layer
  ─────────────────────────────────────────
  Single source of truth for all semantic CSS custom properties.

  Consumers (components, layout, feature sheets) reference ONLY token names —
  never raw hex values. Switching themes is done by toggling [data-theme] on
  <html>; the 574 scattered body.theme-dark overrides across 9 files become
  one block here.

  Load order: this file MUST precede all feature CSS sheets.

  Theming strategy
  ────────────────
  1. :root declares light-mode values (defaults for all browsers).
  2. [data-theme="dark"] declares dark-mode token overrides on the root element.
  3. @media (prefers-color-scheme: dark) provides the same overrides for users
     who haven't explicitly toggled the theme — no JavaScript required for
     initial paint (FOUC prevention handled by the inline <head> script).
  4. body.theme-dark is kept as an alias during the body-class → data-theme
     migration so untouched selectors in older CSS sheets keep working.

  Spacing / typography
  ────────────────────
  All spacing uses the 4 px / 8 px grid. Fluid type uses clamp() so the ramp
  works from 320 px → 4 K without media-query breakpoints.
*/

/* ═══════════════════════════════════════════════════════════════════
   FALLBACK FACES (audit L-12)
   Local fonts resized to the web fonts' metrics and named right after them
   in the font stacks, so text drawn before Cardo or Ezra SIL arrive takes
   the space it will keep, and nothing reflows when they swap in (both
   stay font-display: swap). Measured in Chrome on a paragraph at 1000px:
   size-adjust matches the width; ascent/descent-override are the web
   font's ascent and descent divided by that size. Where the local font is
   missing (no Georgia on Android, say) the face is skipped and the stack
   carries on as before.
   ═══════════════════════════════════════════════════════════════════ */
@font-face {
    font-family: 'Cardo Fallback';
    src: local('Georgia'), local('Georgia Regular');
    font-weight: 400;
    size-adjust: 96.57%;
    ascent-override: 102.52%;
    descent-override: 37.69%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Cardo Fallback';
    src: local('Georgia Bold'), local('Georgia-Bold');
    font-weight: 700;
    size-adjust: 89.67%;
    ascent-override: 110.4%;
    descent-override: 40.59%;
    line-gap-override: 0%;
}

/* Hebrew letters and points only: Latin in a Hebrew run falls through to
   Cardo, as it did before. */
@font-face {
    font-family: 'Ezra SIL Fallback';
    src: local('Times New Roman'), local('TimesNewRomanPSMT');
    unicode-range: U+0590-05FF, U+FB1D-FB4F;
    size-adjust: 134.04%;
    ascent-override: 80.05%;
    descent-override: 30.14%;
    line-gap-override: 0%;
}

/* ═══════════════════════════════════════════════════════════════════
   LIGHT THEME (default / :root)
═══════════════════════════════════════════════════════════════════ */

:root {
    /* Phosphor (bold) glyphs for CSS-drawn marks: painted with mask-image so
       they take currentColor and follow the theme. Use as
       `mask: var(--icon-check) center / contain no-repeat`. */
    --icon-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z'/%3E%3C/svg%3E");
    --icon-caret-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M184.49,136.49l-80,80a12,12,0,0,1-17-17L159,128,87.51,56.49a12,12,0,1,1,17-17l80,80A12,12,0,0,1,184.49,136.49Z'/%3E%3C/svg%3E");
    --icon-thumbs-up: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M237,77.47A28,28,0,0,0,216,68H164V56a44.05,44.05,0,0,0-44-44,12,12,0,0,0-10.73,6.63L72.58,92H32a20,20,0,0,0-20,20v88a20,20,0,0,0,20,20H204a28,28,0,0,0,27.78-24.53l12-96A28,28,0,0,0,237,77.47ZM36,116H68v80H36ZM220,96.5l-12,96a4,4,0,0,1-4,3.5H92V106.83L126.82,37.2A20,20,0,0,1,140,56V80a12,12,0,0,0,12,12h64a4,4,0,0,1,4,4.5Z'/%3E%3C/svg%3E");
    --icon-thumbs-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M243.78,156.53l-12-96A28,28,0,0,0,204,36H32A20,20,0,0,0,12,56v88a20,20,0,0,0,20,20H72.58l36.69,73.37A12,12,0,0,0,120,244a44.05,44.05,0,0,0,44-44V188h52a28,28,0,0,0,27.78-31.47ZM68,140H36V60H68Zm151,22.65a4,4,0,0,1-3,1.35H152a12,12,0,0,0-12,12v24a20,20,0,0,1-13.18,18.8L92,149.17V60H204a4,4,0,0,1,4,3.5l12,96A4,4,0,0,1,219,162.65Z'/%3E%3C/svg%3E");
    --icon-lock-simple: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M208,76H180V56A52,52,0,0,0,76,56V76H48A20,20,0,0,0,28,96V208a20,20,0,0,0,20,20H208a20,20,0,0,0,20-20V96A20,20,0,0,0,208,76ZM100,56a28,28,0,0,1,56,0V76H100ZM204,204H52V100H204Z'/%3E%3C/svg%3E");
    --icon-warning-circle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M128,20A108,108,0,1,0,236,128,108.12,108.12,0,0,0,128,20Zm0,192a84,84,0,1,1,84-84A84.09,84.09,0,0,1,128,212Zm-12-80V80a12,12,0,0,1,24,0v52a12,12,0,0,1-24,0Zm28,40a16,16,0,1,1-16-16A16,16,0,0,1,144,172Z'/%3E%3C/svg%3E");
    --icon-chat-text: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M216,44H40A20,20,0,0,0,20,64V224A19.82,19.82,0,0,0,31.56,242.1a20.14,20.14,0,0,0,8.49,1.9,19.91,19.91,0,0,0,12.82-4.72l.12-.11L84.47,212H216a20,20,0,0,0,20-20V64A20,20,0,0,0,216,44Zm-4,144H80a11.93,11.93,0,0,0-7.84,2.92L44,215.23V68H212ZM84,108A12,12,0,0,1,96,96h64a12,12,0,1,1,0,24H96A12,12,0,0,1,84,108Zm0,40a12,12,0,0,1,12-12h64a12,12,0,0,1,0,24H96A12,12,0,0,1,84,148Z'/%3E%3C/svg%3E");

    color-scheme: light dark;

    /* ── Surface hierarchy ──────────────────────────────────────────── */
    --surface-0:          #faf7f0;   /* page background */
    --surface-1:          #f5efe5;   /* subtle panels */
    --surface-2:          #fff9f1;   /* elevated cards */
    --surface-3:          #f6f1e7;   /* topbar */
    --surface-pill:       #f1ede4;   /* chips, tags */
    --surface-border:     #d7cebc;   /* dividers */
    --surface-scrim:      rgba(0, 0, 0, 0.35);   /* modal backdrop */

    /* ── Ink / text ─────────────────────────────────────────────────── */
    --ink-primary:        #334155;   /* body text */
    --ink-secondary:      #5a6b85;   /* secondary / muted text — darkened from #64748b 2026-08 to clear WCAG AA 4.5:1 on --surface-pill (was 4.07:1); see docs/ACCESSIBILITY_AUDIT.md */
    --ink-on-accent:      #ffffff;   /* text on filled accent backgrounds */
    --ink-heading:        #002147;   /* navy headings */

    /* ── Accent palette (semantic) ──────────────────────────────────── */
    --accent-primary:     #1f3f63;   /* deep blue — primary CTA */
    --accent-primary-hover: #18355a;
    --accent-gold:        #d4af37;   /* 1.97:1 on --surface-0 in light mode — icons/borders/accents only, NEVER body/label text here without a darker variant; see docs/ACCESSIBILITY_AUDIT.md */
    --accent-gold-light:  #f0d980;
    --accent-purple:      #7c3aed;
    --accent-teal:        #0d9488;
    --accent-green:       #059669;
    --accent-red:         #be123c;
    --accent-orange:      #ea580c;

    /* ── Data-viz series (admin feedback charts) ────────────────────── */
    /* Categorical slots 1 and 2 of the dataviz reference palette, validated
       with its validate_palette.js against --surface-2 (the card the charts sit
       on): lightness band, chroma floor, CVD and normal-vision separation and
       3:1 contrast all pass in both themes. Charts also carry a legend, direct
       labels and a table view, so hue is never the only channel. */
    --viz-series-1:       #2a78d6;   /* helpful */
    --viz-series-2:       #eb6834;   /* not helpful */

    /* ── Controls ───────────────────────────────────────────────────── */
    --ctrl-bg:            #f4f0e7;
    --ctrl-bg-hover:      #ece5d8;
    --ctrl-border:        #d6d2c7;
    /* Was #2f4a67 / #223e5a -- a cool navy that read as a stray "blue"
       tint on icon-only controls like #settingsMenuBtn/#mobileLangToggle
       (design pass, 2026-09-13). The dark-theme block's own
       --ctrl-text (#999181/#b8b0a0, see below) is already a warm neutral,
       not navy -- this brings light mode's generic control-text color into
       the same warm family instead of a one-off dark-mode fix. Luminance-
       matched to the old navy pair (0.065/0.045 relative luminance) so
       every existing contrast ratio against any background using this
       token is preserved; only the hue moved from cool to warm.
       --ctrl-filled-bg/-hover (below) are untouched -- that's the
       deliberate "primary action" blue identity (Save Current, etc.),
       not a stray tint. */
    --ctrl-text:          #5a442b;
    --ctrl-text-strong:   #4c3924;
    --ctrl-filled-bg:     #46688d;
    --ctrl-filled-hover:  #3d5b7b;

    /* ── AI-specific tokens ─────────────────────────────────────────── */
    --ai-surface:         #f5efe5;
    --ai-border:          #d7cebc;
    --ai-src-header-bg:   #f1ede4;
    --ai-src-body-bg:     #fffaf2;
    --ai-src-he-bg:       #fffdf8;
    --ai-src-en-bg:       #faf7f0;
    --ai-wiki-accent:     #1f3f63;
    --ai-custom-accent:   #7c3aed;
    --ai-trust-bg:        #faf7f0;
    --ai-trust-border:    #d7cebc;
    /* --ai-warning-*: previously dark-theme-only (defined below at the
       [data-theme="dark"] block, never given a light value, so unused
       anywhere). Completing the light half here so
       the safety-referral disclaimer banner has a real value in both
       themes; all three colors verified ≥4.5:1 against each other. */
    --ai-warning-bg:      #fef6e7;
    --ai-warning-border:  #c8902a;
    --ai-warning-text:    #7a4a06;

    /* ── Loading / skeleton tokens ──────────────────────────────────── */
    --load-skeleton-base:      #ede8df;
    --load-skeleton-highlight: #f7f2ea;
    --load-skeleton-shimmer:   rgba(255,255,255,0.55);

    /* ── Border radii ───────────────────────────────────────────────── */
    --radius-xs:  0.25rem;   /* 4px  */
    --radius-sm:  0.375rem;  /* 6px  */
    --radius-md:  0.625rem;  /* 10px */
    --radius-lg:  1rem;      /* 16px */
    --radius-xl:  1.5rem;    /* 24px */
    --radius-full: 9999px;

    /* ── Spacing (4px / 8px grid) ───────────────────────────────────── */
    --sp-1:  0.25rem;   /* 4px  */
    --sp-2:  0.5rem;    /* 8px  */
    --sp-3:  0.75rem;   /* 12px */
    --sp-4:  1rem;      /* 16px */
    --sp-6:  1.5rem;    /* 24px */
    --sp-8:  2rem;      /* 32px */
    --sp-12: 3rem;      /* 48px */

    /* ── Fluid typography (clamp: min, preferred, max) ──────────────── */
    --text-xs:   clamp(0.7rem,  0.65rem + 0.25vw, 0.75rem);
    --text-meta:      0.8125rem;   /* 13px: captions, secondary rows (fixed, not fluid) */
    --text-body-sm:   0.9375rem;   /* 15px: dense body in panels and detail rows (fixed) */
    --text-sm:   clamp(0.8rem,  0.78rem + 0.25vw, 0.875rem);
    --text-base: clamp(0.9rem,  0.88rem + 0.3vw,  1rem);
    --text-md:   clamp(1rem,    0.96rem + 0.35vw, 1.125rem);
    --text-lg:   clamp(1.1rem,  1.05rem + 0.4vw,  1.25rem);
    --text-xl:   clamp(1.25rem, 1.15rem + 0.5vw,  1.5rem);
    --text-2xl:  clamp(1.5rem,  1.3rem + 0.75vw, 2rem);
    --text-3xl:  clamp(1.75rem, 1.5rem + 1vw,    2.5rem);

    /* ── Motion (honor prefers-reduced-motion via JS helper) ────────── */
    --motion-dur-fast:   150ms;
    --motion-dur-base:   220ms;
    --motion-dur-slow:   400ms;
    /* One turn of the search bar's loading halo (shelah-halo-orbit). */
    --motion-dur-orbit:  3s;
    --motion-ease-out:   cubic-bezier(0.25, 0, 0.3, 1);
    --motion-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    /* Deceleration curve for card/scale-in transform reveals — no overshoot,
       distinct from --motion-ease-spring; was repeated as a raw literal at
       5+ sites across style.css/ai.css before being named here. */
    --motion-ease-decel: cubic-bezier(0.22, 1, 0.36, 1);
    /* The gap between siblings of a cascade (answer blocks, source cards,
       reveals): 30 to 80 ms reads as one gesture, and callers cap the length. */
    --motion-stagger:     40ms;
    /* Views (audit §2): the old one fades out, the new one fades in
       shifted 12px from the side the navigation goes to. */
    --motion-dur-view-out: 120ms;
    --motion-dur-view-in:  240ms;
    --motion-view-shift:   var(--sp-3);

    /* ── Elevation (shadow tokens) ──────────────────────────────────── */
    --shadow-sm:  0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.05);
    --shadow-md:  0 4px 12px rgba(0,0,0,0.1), 0 2px 4px rgba(0,0,0,0.06);
    --shadow-lg:  0 16px 40px rgba(0,0,0,0.12), 0 4px 8px rgba(0,0,0,0.06);

    /* ── Legacy aliases (keep backward compat with existing CSS) ─────── */
    --surface-base:     var(--surface-0);
    --surface-subtle:   var(--surface-1);
    --surface-elevated: var(--surface-2);
    --surface-topbar:   var(--surface-3);
    --text-main:        var(--ink-primary);
    --text-muted:       var(--ink-secondary);
    --accent-blue:      var(--accent-primary);
    --accent-deep-blue: var(--accent-primary);
    --ink:              var(--ink-heading);
    --paper:            #fffaf2;
    --gold:             var(--accent-gold);
    --gold-light:       var(--accent-gold-light);
    --border-light:     #ded4c4;
    --control-bg:           var(--ctrl-bg);
    --control-bg-hover:     var(--ctrl-bg-hover);
    --control-border:       var(--ctrl-border);
    --control-text:         var(--ctrl-text);
    --control-accent:       #315c86;   /* filled range track + checked switch */
    --control-text-strong:  var(--ctrl-text-strong);
    --control-strong-bg:    var(--ctrl-filled-bg);
    --control-strong-bg-hover: var(--ctrl-filled-hover);

    /* ── Typography ─────────────────────────────────────────────────── */
    --font-serif:  'Cardo', 'Cardo Fallback', Georgia, serif;
    --font-sans:   'Inter', system-ui, sans-serif;
    --font-hebrew: 'Ezra SIL', 'Ezra SIL Fallback', 'Cardo', 'Cardo Fallback', serif;
    /* Emphasis in Hebrew is a thin stroke on the regular face (see style.css):
       English bold puts about 35% more ink on a line than regular, and this
       does the same for Ezra SIL and for Cardo's Hebrew. */
    --he-emphasis-stroke: 0.025em;

    /* ── Calendar event colors (by Hebcal category — must match
       backend/app.py's _holiday_color_for_category palette) ────────── */
    --cal-event-holiday:   #802f3e;
    /* Shabbat / parashah are green again (the consolidation pass turned them
       teal). Derived from --accent-green; #04694a = 6.72:1 against the white
       chip text. Kept in sync with app.py's palette. */
    --cal-event-shabbat:   color-mix(in srgb, var(--accent-green) 70%, black);
    /* Day-number tint for Shabbat/parashah and holiday cells (paired with a
       marker glyph in calendar.css, so state is never colour-only).
       6.29:1 / 8.2:1 on the cream cell. */
    --cal-day-shabbat-fg:  var(--cal-event-shabbat);
    --cal-day-holiday-fg:  var(--cal-event-holiday);
    /* Was #5a99b7: only 3.15:1 against the white event-chip text
       (textColor: "#ffffff" from the calendar API) — fails 4.5:1 AA.
       Darkened within the same blue family; now 5.46:1. Kept in sync
       with backend/app.py's palette per the note above. */
    --cal-event-rh:        #35708c;
    --cal-event-minor:     #594176;
    --cal-event-modern:    #2563eb;
    --cal-event-fast:      #374151;
    --cal-event-special:   #6b7280;

    /* ═══════════════════════════════════════════════════════════════════
       APPLE-STYLE SURFACES — geometry, material, motion (calendar detail card,
       Clerk modals, sliders)
       ─────────────────────────────────────────────────────────────────
       Radii follow the concentric rule: an inner radius is the outer radius
       minus the padding between them (`--radius-inner`).  Sizes on the 4/8 grid.
       The pt values Apple does not publish (popover/sheet radius, slider
       dimensions) are calibrated estimates, so they live here as tokens and
       can be tuned in one place.
    ═══════════════════════════════════════════════════════════════════ */
    --radius-popover: 14px;
    --radius-sheet:   20px;
    --radius-control: 12px;
    --surface-pad:    8px;                                             /* inset between a surface and the rows in it */
    --radius-inner:   calc(var(--radius-popover) - var(--surface-pad)); /* concentric child of a popover */

    --hit-min: 44px;                                                    /* minimum touch target */

    /* Slider: a slim track and a small 14px thumb that grows slightly on
       press. The 44px hit area comes from the input's own height
       (--hit-min on .reader-range-slider), not from the thumb. */
    --slider-track-h:   4px;
    --slider-thumb:     14px;
    /* The press-grow to 16px, as a scale (16 / 14) so it runs on the
       compositor instead of resizing the thumb every frame. */
    --slider-thumb-press-scale: 1.1429;

    /* Material — warm cream glass over the page */
    --glass-blur:    22px;
    --glass-sat:     1.7;
    --glass-bg:      rgba(255, 249, 241, 0.90);
    --glass-edge:    rgba(255, 255, 255, 0.70);
    --glass-hairline: rgba(51, 65, 85, 0.14);
    --glass-shadow:  0 18px 48px rgba(52, 40, 18, 0.20), 0 2px 8px rgba(52, 40, 18, 0.10);
    --glass-shadow-sheet: 0 -12px 40px rgba(52, 40, 18, 0.20), 0 -1px 6px rgba(52, 40, 18, 0.08);
}


/* ═══════════════════════════════════════════════════════════════════
   MOTION KEYFRAMES — shared token layer
   Single source of truth for every @keyframes rule in the app
   (ENGINEERING_RULES.md: "zero new @keyframes outside the token layer").
   Feature sheets (ai.css, loading.css, sidebar.css, …) reference these
   by name via `animation:` — they never define their own. Theme-
   independent: values reference no colors that need per-theme swaps.
   Reduced motion: typography.css's global `@media (prefers-reduced-
   motion: reduce)` fallback collapses all durations to ~0; components
   additionally set `animation: none` for a fully static end-state.
═══════════════════════════════════════════════════════════════════ */

@keyframes shelah-fade-in {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes shelah-fade-up {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes shelah-scale-in {
    from { opacity: 0; transform: scale(0.95); }
    to   { opacity: 1; transform: scale(1); }
}

/* A bar growing up from its baseline (admin trend). It starts at 60%, not 0:
   nothing in the real world appears from nothing. */
@keyframes shelah-grow-up {
    from { opacity: 0; transform: scaleY(0.6); }
    to   { opacity: 1; transform: scaleY(1); }
}

@keyframes shelah-slide-in-left {
    from { opacity: 0; transform: translateX(-16px); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes shelah-slide-in-right {
    from { opacity: 0; transform: translateX(16px); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes shelah-slide-down-fade {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes shelah-overlay-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Transform-only (not background-position) per ENGINEERING_RULES.md's
   animate-only-transform/opacity performance guard — consumers apply this
   to a ::after overlay that sweeps across the skeleton via translateX,
   rather than animating the element's own background directly. */
@keyframes shelah-shimmer {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
}

/* The one-time AI discovery tip's ring around its anchor (conversation.css
   .ai-attention::after): a ripple that grows out and fades. */
@keyframes shelah-attention-ping {
    0%   { transform: scale(1);    opacity: 0.7; }
    70%  { transform: scale(1.25); opacity: 0; }
    100% { transform: scale(1.25); opacity: 0; }
}

@keyframes shelah-spin {
    to { transform: rotate(360deg); }
}

@keyframes shelah-dot-bounce {
    0%, 80%, 100% { transform: translateY(0);     opacity: 0.4; }
    40%            { transform: translateY(-6px);  opacity: 1;   }
}

/* Transform and opacity only, so the loop runs on the compositor. It used
   to pulse a drop-shadow as well, which repainted the element on every
   frame for as long as it looped; the glow is now a static filter on the
   elements that want one (.search-ai-sparkle). */
@keyframes shelah-warm-pulse {
    0%, 100% { opacity: 0.7; transform: scale(0.97); }
    50%      { opacity: 1;   transform: scale(1.04); }
}

/* The search bar's loading halo (ai.css .search-liftoff-underlay): its
   gold-and-blue conic gradient turns steadily around the bar while an AI
   question loads. Transform only. Both keyframes repeat the SAME transform
   list as the element's base transform (translate, scale, then rotate), so
   each term interpolates on its own and the turn is pure rotation; a bare
   rotate() against that base would matrix-interpolate and drag the square off
   centre each cycle. The 2.2 stretch must match ai.css. */
@keyframes shelah-halo-orbit {
    from { transform: translate(-50%, -50%) scale(2.2, 1) rotate(0deg); }
    to   { transform: translate(-50%, -50%) scale(2.2, 1) rotate(360deg); }
}

/* View transitions (::view-transition-*(root), below). Forward comes in
   from the inline end, Back from the inline start; RTL mirrors both. */
@keyframes shelah-view-in {
    from {
        opacity: 0;
        transform: translateX(calc(var(--motion-view-shift) * var(--motion-view-dir, 1) * var(--motion-view-sign, 1)));
    }
    to { opacity: 1; transform: none; }
}
@keyframes shelah-view-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}

/* M-7: the verse a citation opened at gets a one-shot wash, so the reader
   doesn't just "jump somewhere" (ai.css .segment-row.cite-highlight). */
@keyframes shelah-cite-highlight {
    0%, 60% { opacity: 1; }
    100%    { opacity: 0; }
}

/* The Ask panel's own motion (conversation.css applies these by name; the
   conv- prefix is kept so a grep from either file finds the other). */
@keyframes conv-status-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.75; }
}
@keyframes conv-status-dot {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}
@keyframes conv-rise {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
}
@keyframes conv-cite-flash {
    0%, 100% { opacity: 0; }
    18%, 60% { opacity: 1; }
}
@keyframes conv-citepop-in {
    from { opacity: 0; transform: scale(0.96); }
    to { opacity: 1; transform: none; }
}


/* ═══════════════════════════════════════════════════════════════════
   VIEW TRANSITIONS (audit §2.3; static/js/motion.js transitionView)
   Only with <html data-view-transitions> (the VIEW_TRANSITIONS flag).
   The page's chrome, and the overlays over it, get names of their own
   while a transition runs (data-vt-active) so they hold still while the
   page underneath changes; otherwise they'd be part of the root snapshot
   and slide with it.
═══════════════════════════════════════════════════════════════════ */

html[dir="rtl"] { --motion-view-sign: -1; }
/* Back: the type where supported, else the attribute motion.js sets. */
html[data-vt-direction="back"] { --motion-view-dir: -1; }
@supports selector(:active-view-transition-type(back)) {
    html:active-view-transition-type(back) { --motion-view-dir: -1; }
}

html[data-view-transitions]::view-transition-old(root) {
    animation: shelah-view-out var(--motion-dur-view-out) var(--motion-ease-out) both;
}
html[data-view-transitions]::view-transition-new(root) {
    animation: shelah-view-in var(--motion-dur-view-in) var(--motion-ease-decel) both;
}

html[data-vt-active] header[role="banner"] { view-transition-name: shelah-topbar; }
html[data-vt-active] #leftSidebar { view-transition-name: shelah-library; }
html[data-vt-active] #rightSidebar { view-transition-name: shelah-commentary; }
html[data-vt-active] #mobileBottomTabs { view-transition-name: shelah-tabs; }
html[data-vt-active] #convPanel { view-transition-name: shelah-conv-panel; }
html[data-vt-active] #convPip { view-transition-name: shelah-conv-pip; }
html[data-vt-active] #calendarModal { view-transition-name: shelah-calendar; }

@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) { animation: none !important; }
}

/* Theme switch (topbar_shared.js withThemeFade): the picture of the old theme
   fades into the new one. Scoped by data-vt-theme, so the route transitions'
   flag above is untouched. The browser's own cross-fade is kept; only its
   length is ours. Reduced motion keeps a shorter fade, since a cut between a
   light and a dark page is the harsher of the two. */
html[data-vt-theme]::view-transition-group(root) {
    animation-duration: var(--motion-dur-base);
}
html[data-vt-theme]::view-transition-old(root),
html[data-vt-theme]::view-transition-new(root) {
    animation-duration: var(--motion-dur-base);
    animation-timing-function: var(--motion-ease-out);
}
@media (prefers-reduced-motion: reduce) {
    html[data-vt-theme]::view-transition-group(root) { animation: none !important; }
    html[data-vt-theme]::view-transition-old(root) { animation: shelah-overlay-in 120ms linear reverse both !important; }
    html[data-vt-theme]::view-transition-new(root) { animation: shelah-overlay-in 120ms linear both !important; }
}


/* ═══════════════════════════════════════════════════════════════════
   DARK THEME — [data-theme="dark"]
   Also applied when body carries .theme-dark (migration alias)
   and when prefers-color-scheme: dark with no explicit override.
═══════════════════════════════════════════════════════════════════ */

[data-theme="dark"],
html.theme-dark,
body.theme-dark {
    color-scheme: dark;

    /* ── Surface hierarchy ──────────────────────────────────────────── */
    /* Hue/saturation calibrated to match .navigator-pane / .pulse-pane (the
       sidebars) — those use a near-neutral ~12% R↔B spread; surface-pill,
       ctrl-bg and ctrl-border previously ran 25-34%, reading visibly more
       olive/yellow than the sidebars right next to them. Lightness levels
       are unchanged, only the warm bias was tightened. */
    --surface-0:          #0c0c0b;   /* near-black background */
    --surface-1:          #131211;   /* dark charcoal panels — darker than
                                         surface-2 on purpose, so settings/menu
                                         panels read as a distinct, deeper layer
                                         behind the buttons that sit on them */
    --surface-2:          #1e1d1a;   /* elevated cards / buttons — matches the
                                         sidebar panel's own lighter gradient stop */
    --surface-3:          #161410;   /* topbar */
    --surface-pill:       #23211f;   /* chips, tags */
    --surface-border:     #2e2c2a;   /* dark dividers */
    --surface-scrim:      rgba(0, 0, 0, 0.72);

    /* ── Ink / text ─────────────────────────────────────────────────── */
    --ink-primary:        #c0bab0;
    /* Lightened #807870 -> #888077 (2026-08: 4.31:1 against
       --surface-1) -> #999188 (2026-08-20: the
       dark-theme half of the pa11y-ci gate, run for the first time, caught
       this at 4.34:1 against --surface-2 -- the home page's card and footer
       surface -- on 15 elements). Each earlier pass fixed only the one
       surface it had measured, so this value is now checked against EVERY
       dark surface in this block, --ctrl-bg-hover included:
         --surface-0 #0c0c0b 6.30  --surface-1 #131211 6.02
         --surface-2 #1e1d1a 5.43  --surface-3 #161410 5.92
         --surface-pill #23211f 5.17  --ctrl-bg-hover #2d2b28 4.54
       Separation from --ink-primary narrows to 1.61:1 (was 2.02:1) -- still
       plainly muted, and the alternative (a value clearing 4.5:1 by ~0.03)
       is what made this recur twice. See also --text-muted's duplicate
       literal below and in the prefers-color-scheme fallback block. */
    --ink-secondary:      #999188;
    --ink-on-accent:      #f0ebe3;
    --ink-heading:        #d4cec4;

    /* ── Accent palette — muted warm tones on near-black bg ─────────── */
    --accent-primary:     #6888a8;
    --accent-primary-hover: #789ab8;
    /* Was #b89028 -- a saturated mustard/brass that read as a harsh, out-
       of-place "yellow" against the rest of the muted dark palette
       (design pass, 2026-09-13), most visible on the large solid
       fill of a checked .reader-switch toggle. Softened to a paler,
       lower-saturation champagne gold at the same hue (~43°) -- still
       reads as "gold," just creamier. Contrast only improved: as text
       this measures 7.3-8.5:1 against every dark surface it's used on
       (was 4.5-5:1 in places, some call-outs elsewhere in this file
       measured right at the 4.5:1 floor against those exact literals --
       those comments are now conservative, not wrong). */
    --accent-gold:        #c9ac5e;
    --accent-gold-light:  #d1c39f;
    --accent-purple:      #8868c0;
    --accent-teal:        #2a9c88;
    --accent-green:       #2aaa7a;
    /* Was #c04870, a rose (hue ~340°) that read pink, and at 3.1-4.1:1 it
       needed mixing toward the heading ink for text, pinker still. A true
       red (hue 0°) instead: 4.96-6.61:1 on every dark surface as is. */
    --accent-red:         #f26b6b;
    --accent-orange:      #c86840;

    --viz-series-1:       #3987e5;   /* helpful: see the light-theme note above */
    --viz-series-2:       #d95926;   /* not helpful */

    /* ── Controls ───────────────────────────────────────────────────── */
    --ctrl-bg:            #23211f;
    --ctrl-bg-hover:      #2d2b28;
    --ctrl-border:        #373532;
    /* Lightened from #888070 2026-08-20 for the same reason as
       --ink-secondary above: the dark-theme
       pa11y-ci run caught the topbar language button at 4.10:1 against
       --ctrl-bg/--surface-pill #23211f. Now 5.14:1 there and 4.52:1 against
       --ctrl-bg-hover, so the hovered state passes too. Keep in sync with
       --control-text in the legacy-alias section and with both duplicates in
       the prefers-color-scheme fallback block below. */
    --ctrl-text:          #999181;
    --ctrl-text-strong:   #b8b0a0;
    --ctrl-filled-bg:     #6888a8;
    --ctrl-filled-hover:  #789ab8;

    /* ── AI-specific ────────────────────────────────────────────────── */
    --ai-surface:         var(--surface-2);
    --ai-border:          var(--surface-border);
    --ai-src-header-bg:   var(--surface-pill);
    --ai-src-body-bg:     var(--surface-2);
    --ai-src-he-bg:       var(--surface-2);
    --ai-src-en-bg:       var(--surface-pill);
    --ai-wiki-accent:     var(--accent-primary);
    --ai-custom-accent:   var(--accent-purple);
    --ai-trust-bg:        var(--surface-pill);
    --ai-trust-border:    var(--surface-border);

    /* ── Loading / skeleton — dark theme ────────────────────────────── */
    --load-skeleton-base:      #23211f;
    --load-skeleton-highlight: #2d2b28;
    --load-skeleton-shimmer:   rgba(255,255,255,0.04);

    /* ── Elevation ──────────────────────────────────────────────────── */
    --shadow-sm:  0 1px 3px rgba(0,0,0,0.50), 0 1px 2px rgba(0,0,0,0.35);
    --shadow-md:  0 4px 12px rgba(0,0,0,0.60), 0 2px 4px rgba(0,0,0,0.40);
    --shadow-lg:  0 16px 40px rgba(0,0,0,0.70), 0 4px 8px rgba(0,0,0,0.50);

    /* ── Legacy aliases (keep backward compat) ──────────────────────── */
    --surface-base:     var(--surface-0);
    --surface-subtle:   var(--surface-1);
    --surface-elevated: var(--surface-2);
    --surface-topbar:   var(--surface-3);
    --text-main:        var(--ink-primary);
    --text-muted:       var(--ink-secondary);
    --accent-blue:      var(--accent-primary);
    --accent-deep-blue: var(--accent-primary);
    --ink:              var(--ink-heading);
    --paper:            var(--surface-2);
    /* This alias correctly references --ink-secondary above, so it tracks
       the pa11y-ci contrast fix automatically. The duplicate hardcoded
       --text-muted literal in the prefers-color-scheme fallback block
       below did NOT and needed its own fix -- see that block's comment. */
    --gold:             var(--accent-gold);
    --gold-light:       var(--accent-gold-light);
    --border-light:     var(--surface-border);
    --control-bg:           var(--ctrl-bg);
    --control-bg-hover:     var(--ctrl-bg-hover);
    --control-border:       var(--ctrl-border);
    --control-text:         var(--ctrl-text);
    --control-accent:       var(--accent-gold);   /* same gold as the rest of the dark palette */
    --control-text-strong:  var(--ctrl-text-strong);
    --control-strong-bg:    var(--ctrl-filled-bg);
    --control-strong-bg-hover: var(--ctrl-filled-hover);

    /* ── Dark-mode-only tokens ──────────────────────────────────────── */
    --accent-cream:     #ddd5c8;

    /* ── Tailwind utility remaps ────────────────────────────────────── */
    --tw-dark-bg-slate-100:     #1a1917;
    --tw-dark-bg-slate-200:     #211f1d;
    --tw-dark-bg-white-85:      rgba(16, 14, 10, 0.90);
    --tw-dark-border-slate-400: #373532;
    --tw-dark-text-slate-900:   #e4dcd0;
    --tw-dark-text-slate-800:   #d4ccbf;
    --tw-dark-text-white:       #d0c8b8;
    --tw-dark-text-slate-700:   #bcb4a5;
    --tw-dark-text-slate-600:   #a09890;
    --tw-dark-text-slate-500:   #97918a;
    --tw-dark-text-slate-400:   #908983;
    --tw-dark-text-slate-300:   #908880;
    --tw-dark-bg-hover:         #282420;
    --tw-dark-bg-emerald:       #121a14;
    --tw-dark-border-emerald:   #1e3022;
    --tw-dark-text-emerald:     #60a870;
    --tw-dark-bg-amber:         #181408;
    --tw-dark-border-amber:     #302810;
    --tw-dark-text-amber:       #b09050;
    --tw-dark-bg-red:           #180d10;
    --tw-dark-border-red:       #301820;
    --tw-dark-text-red:         #a87080;
    --tw-dark-text-blue:        #909aab;
    --tw-dark-bg-blue:          #131211;
    --tw-dark-border-blue:      #282420;
    --tw-dark-focus-border:     #504840;
    --tw-dark-checkbox-accent:  #807050;

    /* ── Corpus accent tokens ───────────────────────────────────────── */
    --accent-menu:              #b8b2a8;
    --accent-zmanim:            #b0ada4;
    --accent-tanakh:            #a8b4b0;
    --accent-mishnah:           #acaab8;
    --accent-talmud:            #b8b0a0;
    --accent-talmud-hover:      #a8906a;
    --accent-halakhah:          #b0a8a8;
    --accent-customs:           #aca6b8;
    --accent-thought:           #a8ada8;

    /* ── Reader ─────────────────────────────────────────────────────── */
    --range-complete:           #8b6f47;   /* keep — non-grey slider accent */
    --range-incomplete:         #dfccb0;   /* keep — non-grey slider track */
    --reader-row-border:        #2c2820;
    --reader-topbar-border:     #242018;
    --reader-btn-color:         #a89880;
    --reader-btn-hover:         #c8c0b0;
    --reader-thumb-border:      #141513;   /* keep — non-grey */
    --reader-thumb-bg:          #d7c9b2;   /* keep — non-grey */

    /* ── AI ─────────────────────────────────────────────────────────── */
    --ai-warning-bg:            #1a1208;
    --ai-warning-border:        #3a2c10;
    --ai-warning-text:          #c09840;
    --ai-badge-hover-border:    #484038;

    /* ── Zmanim ─────────────────────────────────────────────────────── */
    --zmanim-warn-accent:       #9a5832;
    --zmanim-warn-text:         #c89870;

    /* ── Calendar ───────────────────────────────────────────────────── */
    --cal-event-holiday:        #9c3040;
    /* Dark-theme event chips render white text (see routes_calendar.py's
       textColor: "#ffffff") over a solid fill. shabbat/rh/modern/special
       below were tuned to "pop" against the dark page background but
       weren't re-checked against their OWN white text: 3.76/2.61/3.26/3.24:1,
       all failing 4.5:1 AA. Darkened within each hue family; now
       6.52/6.61/5.89/6.01:1 respectively. holiday (7.22:1), minor (5.53:1)
       and fast (5.87:1) already passed and are unchanged. */
    /* Green (not teal): 7.77:1 against the white chip text. The chip
       reds/greens are too dark for day-number text on the dark cell
       (≈2.4:1), so the day tints are lifted — ≥5.6:1 on #1c1c1c. */
    --cal-event-shabbat:        color-mix(in srgb, var(--accent-green) 55%, black);
    --cal-day-shabbat-fg:       var(--accent-green);
    --cal-day-holiday-fg:       color-mix(in srgb, var(--cal-event-holiday) 60%, white);
    --cal-event-rh:             #27637f;
    --cal-event-minor:          #7a5aa0;
    --cal-event-modern:         #3a63ad;
    --cal-event-fast:           #5b6578;
    --cal-event-special:        #5f636d;
    --cal-modal-header-start:   #181818;
    --cal-modal-header-end:     #121212;
    --cal-icon-bg:              #303030;

    /* ── Halacha ────────────────────────────────────────────────────── */
    --halacha-ruling-color:            #7898b0;
    --halacha-ruling-bg:               #0e1318;
    --halacha-custom-color:            #8870b0;
    --halacha-custom-bg:               #101018;
    --halacha-source-color:            #a89030;
    --halacha-source-bg:               #141208;
    --halacha-custom-ruling-bg:        #100d18;
    --halacha-ruling-ashkenazi-bg:     #0e1218;
    --halacha-ruling-sefardi-bg:       #141008;
    --halacha-ruling-yemenite-bg:      #0e1408;
    --halacha-ruling-bukharian-bg:     #110818;
    --halacha-ruling-bukharian-border: #8830a0;

    /* ── Prayer ─────────────────────────────────────────────────────── */
    --prayer-accent-border:     #705a28;

    /* ── Misc ───────────────────────────────────────────────────────── */
    --home-label-color:         #989080;
    --fc-day-number-color:      #b8b0a8;
    --prose-text-dark:          #c4bcb0;
    --icon-muted:               #787068;
    --tooltip-text:             #e0d8cc;
    --search-hover-border:      #484038;

    /* ── Apple-style surfaces: material (see the :root section) ─────── */
    --glass-bg:      rgba(30, 29, 26, 0.90);
    --glass-edge:    rgba(255, 255, 255, 0.10);
    --glass-hairline: rgba(255, 255, 255, 0.10);
    --glass-shadow:  0 18px 48px rgba(0, 0, 0, 0.62), 0 2px 8px rgba(0, 0, 0, 0.40);
    --glass-shadow-sheet: 0 -12px 40px rgba(0, 0, 0, 0.62), 0 -1px 6px rgba(0, 0, 0, 0.40);
}


/* ═══════════════════════════════════════════════════════════════════
   SYSTEM PREFERENCE FALLBACK
   Applies dark tokens to users without an explicit theme toggle when
   their OS is set to dark mode. The inline <head> script overrides
   this with [data-theme] once localStorage is read.
═══════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --surface-0:          #0c0c0b;
        --surface-1:          #131211;
        --surface-2:          #1e1d1a;
        --surface-3:          #161410;
        --surface-pill:       #23211f;
        --surface-border:     #2e2c2a;
        --surface-scrim:      rgba(0, 0, 0, 0.72);

        --ink-primary:        #c0bab0;
        /* Keep in sync with --ink-secondary in the [data-theme="dark"]
           block above -- see that block's comment (pa11y-ci contrast fix). */
        --ink-secondary:      #999188;
        --ink-heading:        #d4cec4;

        --accent-primary:     #6888a8;
        --accent-primary-hover: #789ab8;
        /* Keep in sync with the explicit dark-theme block above (~L331) --
           same creamier, lower-saturation gold swap. */
        --accent-gold:        #c9ac5e;
        --accent-gold-light:  #d1c39f;
        --accent-purple:      #8868c0;
        --accent-teal:        #2a9c88;
        --accent-green:       #2aaa7a;
        --accent-red:         #f26b6b;
        --accent-orange:      #c86840;
        --viz-series-1:       #3987e5;
        --viz-series-2:       #d95926;

        --ctrl-bg:            #23211f;
        --ctrl-bg-hover:      #2d2b28;
        --ctrl-border:        #373532;
        /* Keep in sync with --ctrl-text in the [data-theme="dark"] block
           above -- see that block's comment (pa11y-ci contrast fix). */
        --ctrl-text:          #999181;
        --ctrl-text-strong:   #b8b0a0;
        --ctrl-filled-bg:     #6888a8;
        --ctrl-filled-hover:  #789ab8;

        --ai-surface:         #1e1d1a;
        --ai-border:          #2e2c2a;
        --ai-src-header-bg:   #23211f;
        --ai-src-body-bg:     #1e1d1a;
        --ai-src-he-bg:       #1e1d1a;
        --ai-src-en-bg:       #23211f;
        --ai-wiki-accent:     #6888a8;
        --ai-custom-accent:   #8868c0;
        --ai-trust-bg:        #23211f;
        --ai-trust-border:    #2e2c2a;

        --load-skeleton-base:      #23211f;
        --load-skeleton-highlight: #2d2b28;
        --load-skeleton-shimmer:   rgba(255,255,255,0.04);

        --shadow-sm:  0 1px 3px rgba(0,0,0,0.50), 0 1px 2px rgba(0,0,0,0.35);
        --shadow-md:  0 4px 12px rgba(0,0,0,0.60), 0 2px 4px rgba(0,0,0,0.40);
        --shadow-lg:  0 16px 40px rgba(0,0,0,0.70), 0 4px 8px rgba(0,0,0,0.50);

        --surface-base:     #0c0c0b;
        --surface-subtle:   #131211;
        --surface-elevated: #1e1d1a;
        --surface-topbar:   #161410;
        --text-main:        #c0bab0;
        /* Keep in sync with --ink-secondary above (pa11y-ci contrast fix) --
           this legacy-alias section duplicates literals instead of var()
           references, which is exactly how .home-library-description's
           dark-mode override (static/style.css) went stale before. */
        --text-muted:       #999188;
        --accent-blue:      #6888a8;
        --accent-deep-blue: #6888a8;
        --accent-cream:     #ddd5c8;
        --control-bg:       #23211f;
        --control-bg-hover: #2d2b28;
        --control-border:   #373532;
        --control-text:     #999181;
        --control-accent:   #c9ac5e;
        --control-text-strong: #b8b0a0;
        --control-strong-bg:   #6888a8;
        --control-strong-bg-hover: #789ab8;

        /* ── Tailwind utility remaps ──────────────────────────────── */
        --tw-dark-bg-slate-100:     #1a1917;
        --tw-dark-bg-slate-200:     #211f1d;
        --tw-dark-bg-white-85:      rgba(16,14,10,0.90);
        --tw-dark-border-slate-400: #373532;
        --tw-dark-text-slate-900:   #e4dcd0;
        --tw-dark-text-slate-800:   #d4ccbf;
        --tw-dark-text-white:       #d0c8b8;
        --tw-dark-text-slate-700:   #bcb4a5;
        --tw-dark-text-slate-600:   #a09890;
        --tw-dark-text-slate-500:   #97918a;
        --tw-dark-text-slate-400:   #908983;
        --tw-dark-text-slate-300:   #908880;
        --tw-dark-bg-hover:         #282420;
        --tw-dark-bg-emerald:       #121a14;
        --tw-dark-border-emerald:   #1e3022;
        --tw-dark-text-emerald:     #60a870;
        --tw-dark-bg-amber:         #181408;
        --tw-dark-border-amber:     #302810;
        --tw-dark-text-amber:       #b09050;
        --tw-dark-bg-red:           #180d10;
        --tw-dark-border-red:       #301820;
        --tw-dark-text-red:         #a87080;
        --tw-dark-text-blue:        #909aab;
        --tw-dark-bg-blue:          #131211;
        --tw-dark-border-blue:      #282420;
        --tw-dark-focus-border:     #504840;
        --tw-dark-checkbox-accent:  #807050;

        /* ── Corpus accent tokens ─────────────────────────────────── */
        --accent-menu:              #b8b2a8;
        --accent-zmanim:            #b0ada4;
        --accent-tanakh:            #a8b4b0;
        --accent-mishnah:           #acaab8;
        --accent-talmud:            #b8b0a0;
        --accent-talmud-hover:      #a8906a;
        --accent-halakhah:          #b0a8a8;
        --accent-customs:           #aca6b8;
        --accent-thought:           #a8ada8;

        /* ── Reader ───────────────────────────────────────────────── */
        --range-complete:           #8b6f47;
        --range-incomplete:         #dfccb0;
        --reader-row-border:        #2c2820;
        --reader-topbar-border:     #242018;
        --reader-btn-color:         #a89880;
        --reader-btn-hover:         #c8c0b0;
        --reader-thumb-border:      #141513;
        --reader-thumb-bg:          #d7c9b2;

        /* ── AI ───────────────────────────────────────────────────── */
        --ai-warning-bg:            #1a1208;
        --ai-warning-border:        #3a2c10;
        --ai-warning-text:          #c09840;
        --ai-badge-hover-border:    #484038;

        /* ── Zmanim ───────────────────────────────────────────────── */
        --zmanim-warn-accent:       #9a5832;
        --zmanim-warn-text:         #c89870;

        /* ── Calendar ─────────────────────────────────────────────── */
        --cal-event-holiday:        #9c3040;
        --cal-event-shabbat:        color-mix(in srgb, var(--accent-green) 55%, black);
        --cal-day-shabbat-fg:       var(--accent-green);
        --cal-day-holiday-fg:       color-mix(in srgb, var(--cal-event-holiday) 60%, white);
        --cal-event-rh:             #27637f;
        --cal-event-minor:          #7a5aa0;
        --cal-event-modern:         #3a63ad;
        --cal-event-fast:           #5b6578;
        --cal-event-special:        #5f636d;
        --cal-modal-header-start:   #181818;
        --cal-modal-header-end:     #121212;
        --cal-icon-bg:              #303030;

        /* ── Halacha ──────────────────────────────────────────────── */
        --halacha-ruling-color:            #7898b0;
        --halacha-ruling-bg:               #0e1318;
        --halacha-custom-color:            #8870b0;
        --halacha-custom-bg:               #101018;
        --halacha-source-color:            #a89030;
        --halacha-source-bg:               #141208;
        --halacha-custom-ruling-bg:        #100d18;
        --halacha-ruling-ashkenazi-bg:     #0e1218;
        --halacha-ruling-sefardi-bg:       #141008;
        --halacha-ruling-yemenite-bg:      #0e1408;
        --halacha-ruling-bukharian-bg:     #110818;
        --halacha-ruling-bukharian-border: #8830a0;

        /* ── Prayer ───────────────────────────────────────────────── */
        --prayer-accent-border:     #705a28;

        /* ── Misc ─────────────────────────────────────────────────── */
        --home-label-color:         #989080;
        --fc-day-number-color:      #b8b0a8;
        --prose-text-dark:          #c4bcb0;
        --icon-muted:               #787068;
        --tooltip-text:             #e0d8cc;
        --search-hover-border:      #484038;

        /* ── Apple-style surfaces: material ───────────────────────── */
        --glass-bg:      rgba(30, 29, 26, 0.90);
        --glass-edge:    rgba(255, 255, 255, 0.10);
        --glass-hairline: rgba(255, 255, 255, 0.10);
        --glass-shadow:  0 18px 48px rgba(0, 0, 0, 0.62), 0 2px 8px rgba(0, 0, 0, 0.40);
        --glass-shadow-sheet: 0 -12px 40px rgba(0, 0, 0, 0.62), 0 -1px 6px rgba(0, 0, 0, 0.40);
    }
}


/* Reduce Transparency is handled where the material is applied (it must beat
   the dark-OS block above, which has higher specificity than a bare :root). */
@media (prefers-contrast: more) {
    :root { --glass-hairline: var(--ink-secondary); }
}
