/* ============================================================================
   HBD2 — Almanac · Pedia · Yearbook
   Complete stylesheet. Self-contained. Zero external network requests.
   Above-the-fold styles for the home page (masthead, sticky nav, today panel)
   are duplicated inline in /index.php so first paint never waits for this file.
============================================================================ */

/* ---------- Design tokens — UNIQUE TO THIS FILE --------------------------
 * The site's shared design tokens are owned by the inline critical CSS
 * emitted by hbd_render_critical_css() in /inc/boot.php. That's the SINGLE
 * SOURCE OF TRUTH for:
 *
 *     surfaces : --paper, --ink, --ink-soft, --rule
 *     accents  : --t-red
 *     type     : --display, --sans
 *     layout   : --maxw, --nav-h
 *
 * Only the tokens unique to /css/hbd2.css live below: the secondary cream
 * surface (--paper-2) and dark warm ink (--ink-2), the 26 plate accent
 * palette (--L-A..--L-Z, --L-NUM), Today-in-History panel colors, and
 * selection highlight.
 *
 * Adding a NEW shared token? Define it ONCE in critical CSS, not here —
 * defining the same token in both files silently lets cascade order win,
 * which has bitten us before.
 * ----------------------------------------------------------------------- */
:root{
  /* ============================================================
     SURFACE TOKENS — secondary cream + dark warm ink. The primary
     surface (--paper, --ink, --ink-soft, --rule, --t-red) lives in
     the critical CSS :root (boot.php) so it's available above-the-
     fold; only the secondary surface lives here.
     ============================================================ */
  --paper-2:  #F7F4EC;
  --ink-2:    #3A3126;

  /* ============================================================
     PLATE ACCENT PALETTE — 26 vivid mid-stops keyed by the first
     letter of each plate's headline. Each plate accent gets paired
     with a deep dark corner and soft light corner inside
     .plate__frame to give the gem-like gradient signature of the
     site. --L-NUM is the fallback for headlines that start with a
     digit or symbol rather than a letter.
     ============================================================ */
  --L-A:#DD4728; --L-B:#E7A723; --L-C:#96C527; --L-D:#359792;
  --L-E:#206AAC; --L-F:#67529E; --L-G:#BD4E77; --L-H:#ED5227;
  --L-I:#DDA327; --L-J:#4B923A; --L-K:#2E9C9E; --L-L:#3057A7;
  --L-M:#924697; --L-N:#D83953; --L-O:#ED7F1D; --L-P:#B59E33;
  --L-Q:#539465; --L-R:#2D6E95; --L-S:#6F4095; --L-T:#B13569;
  --L-U:#E6682F; --L-V:#CA992B; --L-W:#468658; --L-X:#2D54A6;
  --L-Y:#804098; --L-Z:#98324F;
  --L-NUM: #2B68A1;

  /* ============================================================
     ACCENT COLORS — Today-in-History panel + editorial plum.
     ============================================================ */
  --today-blue: #005BF7;
  --today-red:  #EA4335;
  --editorial-plum: #6B2D5C;

  /* ============================================================
     BRAND-BLUE GRADIENT (§19 #67) — the 3-stop linear gradient that
     defines the brand card on the masthead, the footer chrome, and
     the catnav active state. Previously hand-written in 4 places.
     ============================================================ */
  --brand-blue-grad: linear-gradient(135deg, #071833 0%, #005BF7 55%, #2E8BFF 100%);

  /* ============================================================
     GEM-CARD BEVEL (§19 #67) — the inset bevel that gives the site
     its signature gem-like quality. Previously hand-written 32
     times with minor drift. Single source of truth here.
       --bevel       : default 1px top-light + 1px bottom-dark
       --bevel-hover : same shape, slightly stronger contrast
     The drop-shadow part of the gem language stays inline at the
     callsite because each callsite tints its drop to its own
     accent color (rgba of plate hue) — a token wouldn't help.
     ============================================================ */
  --bevel:       0 1px 0 rgba(255,255,255,.18) inset, 0 -1px 0 rgba(0,0,0,.30) inset;
  --bevel-hover: 0 1px 0 rgba(255,255,255,.22) inset, 0 -1px 0 rgba(0,0,0,.32) inset;

  /* ============================================================
     CARD-DROP SHADOW (§19 #67) — neutral dark drop for plates that
     don't tint their drop to an accent color (mini-cal, generic
     plates, footer cards). Per-card accent-tinted drops stay
     inline because they're per-card.
     ============================================================ */
  --shadow-card: 0 18px 40px -16px rgba(0,0,0,.35), 0 6px 14px -6px rgba(0,0,0,.20);

  /* ============================================================
     TYPE SCALE (§19 #67) — 9 named ramps replacing 28 ad-hoc clamp()
     declarations. Pick by semantic role, not by trial-and-error.
       --fs-xs       11px           — micro UI labels (pills, badges)
       --fs-sm       13px           — small body, kicker metadata
       --fs-body     17px           — default body text
       --fs-h4       clamp 15-18    — kickers, captions, sub heads
       --fs-h3       clamp 20-28    — section headings, plate titles
       --fs-h2       clamp 24-46    — page titles, hero headlines
       --fs-h1       clamp 40-84    — masthead wordmark
       --fs-display  clamp 60-110   — page hero
       --fs-mega     clamp 80-180   — special hero (Z2 banner)
     ============================================================ */
  --fs-xs:       11px;
  --fs-sm:       13px;
  --fs-body:     17px;
  --fs-h4:       clamp(15px, 1.3vw, 18px);
  --fs-h3:       clamp(20px, 2.4vw, 28px);
  --fs-h2:       clamp(24px, 4vw, 46px);
  --fs-h1:       clamp(40px, 7vw, 84px);
  --fs-display:  clamp(60px, 10vw, 110px);
  --fs-mega:     clamp(80px, 16vw, 180px);

  /* ============================================================
     BORDER-RADIUS SCALE (§19 #67) — 6 named steps replacing 15
     ad-hoc values. Pick the closest semantic step.
       --r-xs       3px    — micro UI (date pills, year tags)
       --r-sm       6px    — small chips and buttons
       --r-md       10px   — plate frames, card frames
       --r-lg       14px   — hero frame, masthead cards
       --r-xl       18px   — brandbar cards, prominent CTAs
       --r-pill     999px  — fully rounded (pills, lozenges)
       --r-circle   50%    — avatars, dots
     ============================================================ */
  --r-xs:        3px;
  --r-sm:        6px;
  --r-md:        10px;
  --r-lg:        14px;
  --r-xl:        18px;
  --r-pill:      999px;
  --r-circle:    50%;

  /* ============================================================
     TRANSITION TIMINGS (§19 #67) — 3 named durations replacing 9
     ad-hoc values that clustered around 3 semantic feels.
       --t-fast   .15s   — micro-interactions (focus rings, ticks)
       --t-base   .22s   — standard hover snap (cards, links, btns)
       --t-slow   .35s   — content reveal (hero lift, image fade)
     ============================================================ */
  --t-fast:      .15s;
  --t-base:      .22s;
  --t-slow:      .35s;

  /* Standard ease curve — gentle decelerating curve. Used by the
     hero hover lift, plate frame transitions, and modal entries. */
  --ease:        cubic-bezier(.2,.7,.2,1);

  /* ============================================================
     SELECTION & HIGHLIGHT (existing).
     ============================================================ */
  --hl-yellow:     #FFE066;
  --hl-yellow-ink: #1A1408;
}

/* ---------- Reset / base -------------------------------------------------
   Site-wide base resets (html, body, a, img, .wrap, .skip-link) live in
   the inline critical CSS via hbd_render_critical_css() in /inc/boot.php
   so first paint is correct on every page. Don't reintroduce them here —
   that's how we silently shipped 16px body text when the design called
   for 17px. The base typography baseline (.h1-h4 weights, selection
   highlight, focus-visible outline, reduced-motion guard) stays here
   because none of those are duplicated and they aren't first-paint
   critical. */
*, *::before, *::after { box-sizing: border-box; }

svg { display: block; }
h1, h2, h3, h4 { font-family: var(--display); font-weight: 600; }

/* SOFT YELLOW selection — much more pleasant than the old ochre. */
::selection     { background: var(--hl-yellow); color: var(--hl-yellow-ink); text-shadow: none; }
::-moz-selection{ background: var(--hl-yellow); color: var(--hl-yellow-ink); text-shadow: none; }

a:focus-visible, button:focus-visible, input:focus-visible{
  outline: 2px solid var(--t-red);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}
@media (prefers-reduced-motion: reduce){
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}


/* ==========================================================================
   MASTHEAD + BRANDBAR — see hbd_render_critical_css() in /inc/boot.php.
   The masthead (rich layered gradient bg + 42px grid texture) and the
   four brandbar cards (HBD2 brand + Almanac/Pedia/Yearbook section cards
   with their gem-like linear gradients and hover lift) are site-wide
   chrome above the fold, so all of that CSS lives in the inline critical
   CSS for first-paint correctness. Don't reintroduce .masthead* or
   .brandbar* rules here — having them in two files lets cascade order
   silently win, which produced the dead-radial-highlight and dead-(-3px)-
   hover bugs we already had to track down.
========================================================================== */

/* ==========================================================================
   CATNAV — see hbd_render_critical_css() in /inc/boot.php.
   The sticky catnav is site-wide chrome above the fold, so all its CSS
   lives in the inline critical CSS for first-paint correctness. Don't
   reintroduce .catnav rules here — duplicated rules in two files drift
   silently and produced bugs we already had to track down.
========================================================================== */

/* ==========================================================================
   TODAY-IN-HISTORY — see /index.php's $home_extra_css.
   The Today panel is homepage-only and above the fold, so all its CSS
   (gradient, layout, cross-fade, mobile adaptation, the @property
   declarations that make --ph/--ps/--pa transitionable) lives in the
   inline critical CSS emitted by hbd_render_critical_css() so first paint
   is fully styled with no async dependency. Don't reintroduce .today*
   rules here — duplicating them caused a phantom second divider and
   stale class-name dead code (.today__art, .today__date-kicker, etc).
========================================================================== */


/* ==========================================================================
   1. AD — site-wide ad slot (edited in /inc/ads.php)
      No "Sponsored" footer per request — just a clean head + body.
========================================================================== */
.ad{
  max-width: 980px;
  margin: 36px auto;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--paper-2);
  overflow: hidden;
  box-shadow: 0 16px 40px -36px rgba(0,0,0,.55);
}
@media (max-width: 640px){ .ad { margin: 24px 14px; border-radius: var(--r-md); } }

/* When the head band is hidden via /inc/ads.php (head_show=false), the
   wrapper carries .ad--no-head so the body is the only thing inside the
   bordered card. Nothing extra to do here visually — the rule exists as
   a hook in case future styling needs to differ. */
.ad--no-head .ad__body{ /* reserved for future spacing tweaks */ }

.ad__head{
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--t-red);
  text-align: center;
  padding: 10px 14px;
  background: #fff;
  border-bottom: 1px solid var(--rule);
}
.ad__body{
  display: block;
  background: var(--paper-2);
  line-height: 0;
  text-align: center;            /* centers smaller-than-container creatives */
}
.ad__body > a{ display: inline-block; }
/* Let the creative speak at its natural pixel size. We DON'T force
   width: 100% any more — a 600px banner displays at 600px, not stretched
   to fill 980px. max-width: 100% is the only safety net so an oversized
   creative doesn't break the layout, and margin: 0 auto centers anything
   smaller than the container. Iframes/AdSense <ins> still respect their
   own width attributes / responsive logic. */
.ad__body img,
.ad__body iframe,
.ad__body video,
.ad__body ins{
  display: block;
  margin: 0 auto;
  height: auto;
  max-width: 100%;
}


/* ==========================================================================
   2. CATEGORY GROUPS (home page)
========================================================================== */
.group{
  padding: 56px 0 20px;
  content-visibility: auto;
  contain-intrinsic-size: 0 900px;
}
.group:first-of-type { padding-top: 44px; }
.group__title{
  margin: 0 0 28px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  letter-spacing: -.025em;
  line-height: 1;
  color: var(--ink);
}


/* ==========================================================================
   PLATE GRID + PLATE TILE — single source of truth.
   Used by the homepage and /colors/ today; available to any future page
   that includes hbd2.css. The 3D effect is built from layers inside
   .plate__frame: a radial highlight (top-left convex sheen), a linear
   gradient (dark anchor → vivid accent → soft light corner), inset
   highlights/shadows for the bevel, and drop shadows that anchor the
   tile to the page. Hover lifts the tile by 4px and intensifies the
   drop shadow. The accent color comes from --accent, set inline on
   each .plate by hbd_render_plate() from a per-plate hash via
   hbd_plate_accent().
========================================================================== */
.plates{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(138px, 1fr));
  gap: 20px 16px;
}
@media (min-width:  640px){ .plates { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 24px 20px; } }
@media (min-width: 1024px){ .plates { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 28px 24px; } }
@media (min-width: 1280px){ .plates { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 32px 26px; } }

.plate{
  display: block;
  position: relative;
  color: var(--ink);
  text-decoration: none;
}
.plate--no-letter .plate__letter{ display: none; }

.plate__frame{
  margin: 0 0 10px;
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--r-lg);
  overflow: hidden;
  /* Layered background: a soft radial highlight (top-left glossy sheen)
     painted over a 3-stop linear gradient (deep anchor corner, vivid
     accent in the middle, soft light corner). --accent is set inline
     by hbd_render_plate via hbd_plate_accent(). */
  background:
    radial-gradient(circle at 26% 22%, rgba(255,255,255,.22), transparent 55%),
    linear-gradient(135deg,
      color-mix(in oklab, var(--accent) 45%, black 55%) 0%,
      var(--accent) 55%,
      color-mix(in oklab, var(--accent) 80%, white 20%) 100%);
  box-shadow:
    var(--bevel),
    0 14px 30px -20px rgba(0,0,0,.42),
    0 4px 10px -4px rgba(0,0,0,.20);
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
}

.plate__letter{
  position: absolute; inset: 0;
  z-index: 1;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-display);
  line-height: 1;
  letter-spacing: -.04em;
  color: #fff;
  text-shadow: 0 2px 16px rgba(0,0,0,.22), 0 1px 0 rgba(0,0,0,.30);
  padding: 0 10%;
  text-align: center;
}
.plate__letter[data-long]{
  font-size: var(--fs-h2);
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}

.plate__art{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  z-index: 2;
}

/* When .plate--has-image is on, the gradient + letter are visually
   suppressed; the image owns the frame. */
.plate--has-image .plate__letter{ display: none; }
.plate--has-image .plate__frame{
  box-shadow:
    0 14px 30px -20px rgba(0,0,0,.42),
    0 4px 10px -4px rgba(0,0,0,.20);
}

a.plate[href]:hover .plate__frame{
  transform: translateY(-4px);
  box-shadow:
    var(--bevel-hover),
    0 26px 44px -18px rgba(0,0,0,.46),
    0 8px 14px -6px rgba(0,0,0,.22);
}
a.plate[href]:hover .plate__art   { transform: scale(1.05); transition: transform var(--t-slow) var(--ease); }
a.plate[href]:hover .plate__letter{ letter-spacing: -.01em; }

.plate__label{
  font-family: var(--display);
  font-weight: 600;
  font-size: 17px;
  line-height: 1.2;
  color: var(--ink);
  text-align: center;
  letter-spacing: -.005em;
  padding: 0 4px;
}


/* ==========================================================================
   4. FOOTER
========================================================================== */
.footer{
  background: var(--ink);
  color: #fff;
  padding: 48px 0 24px;
  margin-top: 56px;
}
.footer__nav{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 28px;
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-weight: 600;
  margin-bottom: 28px;
}
.footer__nav a{
  color: #fff;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color var(--t-base), border-color var(--t-base);
}
/* Hover blue — brighter cousin of the catnav's --today-blue (#005BF7).
   The catnav sits on white, where #005BF7 has 5.5:1 contrast (passes AA).
   The footer sits on near-black --ink, where #005BF7 only reaches 3.4:1
   (fails AA at this font size). The masthead gradient already uses #2E8BFF
   as its bright stop; the same value here lands at 5.6:1 on --ink and
   reads as the same blue to the eye, so the hover signal stays unified
   across the catnav + footer while both surfaces remain accessible. */
.footer__nav a:hover { color: #2E8BFF; border-color: #2E8BFF; }

.colophon{
  border-top: 1px solid rgba(255,255,255,.18);
  padding-top: 18px;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.6);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}
@media (max-width: 640px){
  .colophon { justify-content: center; text-align: center; }
}


/* ==========================================================================
   5. ENDMARK
========================================================================== */
.endmark{ background: var(--ink); padding: 0; line-height: 0; text-align: center; }
.endmark a  { display: block; }
.endmark img{ display: block; width: 100%; height: auto; opacity: .95; transition: opacity var(--t-slow) ease; }
.endmark a:hover img { opacity: 1; }


/* ==========================================================================
   6. TIH (Today in World History) — magazine detail page
   /ht/{mmm}{dd}/index.php
   Uses the --accent-h CSS variable on each plate to paint a unique HSL
   gradient. So every plate has a distinct, beautiful color, derived
   deterministically from the plate's title.
========================================================================== */
.tih-page{ background: var(--paper); color: var(--ink); }

/* --- 6.1 Banner -------------------------------------------------------- */
.tih-banner{
  background:
    radial-gradient(circle at 18% 18%, rgba(255,255,255,.24), transparent 38%),
    radial-gradient(circle at 85% 80%, rgba(0,0,0,.22), transparent 42%),
    var(--brand-blue-grad);
  color: #fff;
  padding: 38px 0 32px;
  position: relative;
  overflow: hidden;
}
/* 42px grid texture overlay with a soft fade toward the bottom — same
   texture used by the masthead, the homepage today panel, the cal-banner,
   and the colors-hero so the whole site shares one visual rhythm. The
   radials in .tih-banner's background-shorthand sit beneath this layer;
   the .wrap sits above it via z-index:2. */
.tih-banner::before{
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
  background-size: 42px 42px;
  mask-image: linear-gradient(to bottom, rgba(0,0,0,.85), transparent 92%);
  pointer-events: none;
  z-index: 1;
}
.tih-banner .wrap{ position: relative; z-index: 2; }
.tih-banner__kicker{
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .28em;
  text-transform: uppercase;
  opacity: .82;
  margin-bottom: 8px;
}
.tih-banner__date{
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: .95;
  letter-spacing: -.035em;
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 18px;
  flex-wrap: wrap;
}
.tih-banner__weekday{
  font-family: var(--sans);
  font-weight: 800;
  font-size: var(--fs-h4);
  letter-spacing: .22em;
  text-transform: uppercase;
  background: rgba(255,255,255,.16);
  border: 1px solid rgba(255,255,255,.28);
  padding: 6px 12px;
  border-radius: var(--r-pill);
  align-self: center;
}
.tih-banner__sub{
  font-family: var(--display);
  font-style: italic;
  font-size: var(--fs-h4);
  line-height: 1.4;
  margin: 12px 0 0;
  opacity: .92;
  max-width: 64ch;
}

/* --- 6.2 Section heading + scroll padding ----------------------------- */
.tih-main{ padding-bottom: 24px; }
.tih-section{ scroll-margin-top: calc(var(--nav-h) + 16px); }

.tih-h2{
  max-width: var(--maxw);
  margin: 56px auto 22px;
  padding: 0 28px 12px;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h2);
  letter-spacing: -.02em;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}
@media (max-width: 640px){ .tih-h2 { padding-left: 18px; padding-right: 18px; } }
.tih-h2 small{
  display: block;
  font-family: var(--sans);
  font-style: normal;
  font-weight: 800;
  font-size: 11px;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--today-blue);
  margin-bottom: 6px;
}

/* --- 6.3 Hero --------------------------------------------------------- */
.tih-hero{
  display: block;
  margin: 32px auto 28px;
  max-width: var(--maxw);
  padding: 0 28px;
}
@media (max-width: 640px){ .tih-hero { padding: 0 18px; } }
.tih-hero__frame{
  position: relative;
  aspect-ratio: 16 / 7;
  border-radius: var(--r-lg);
  overflow: hidden;
  background:
    radial-gradient(circle at 24% 20%, rgba(255,255,255,.22), transparent 55%),
    radial-gradient(circle at 76% 80%, rgba(0,0,0,.30), transparent 55%),
    linear-gradient(135deg,
      hsl(var(--accent-h, 215) 40% 22%) 0%,
      hsl(var(--accent-h, 215) 55% 36%) 60%,
      hsl(var(--accent-h, 215) 65% 50%) 100%);
  box-shadow: var(--bevel), var(--shadow-card);
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
}
/* Hover lift gated on [href] (§10 site-wide link convention). When the
 * hero has 'href' => null, the rendered <a class="tih-hero"> has no href
 * attribute — per HTML spec non-clickable / non-focusable; this selector
 * keeps the hover lift off until the author sets a real URL. */
.tih-hero[href]:hover .tih-hero__frame{
  transform: translateY(-4px);
  box-shadow:
    var(--bevel-hover),
    0 28px 50px -20px rgba(0,0,0,.40),
    0 10px 18px -8px rgba(0,0,0,.22);
}
@media (max-width: 720px){ .tih-hero__frame { aspect-ratio: 4 / 3; } }
.tih-hero__art{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  z-index: 1;        /* sits above the frame's gradient (z-index 0) */
}
.tih-hero__placeholder{
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-style: italic;
  color: rgba(255,255,255,.85);
  font-size: var(--fs-h4);
  padding: 24px;
  text-align: center;
}
.tih-hero__caption{
  position: absolute;
  z-index: 2;        /* above the image */
  left: 0; right: 0; bottom: 0;
  padding: 32px 36px 28px;
  color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,.78) 0%, rgba(0,0,0,.42) 50%, transparent 100%);
}
.tih-hero__year{
  /* §19 #66 typography refinement. Was a red ALL-CAPS pill;
     now an italic-display white label on the existing dark-
     gradient bottom of the caption. Mixed case, slightly
     bigger, no background, no padding, no rounded corners.
     The caption's own black-to-transparent bottom gradient
     (from .tih-hero__caption) provides the readability
     contrast that the pill used to provide. */
  display: block;
  font-family: var(--display);
  font-style: italic;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.45;
  letter-spacing: .01em;
  color: rgba(255, 255, 255, .92);
  margin-bottom: 10px;
}
.tih-hero__headline{
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--fs-h2);
  line-height: 1.1;
  letter-spacing: -.025em;
  margin: 0;
  text-shadow: 0 2px 14px rgba(0,0,0,.4);
  max-width: 26ch;
}

/* §19 #65 — editorial block below the hero frame. Renders the hero's
   full kicker + excerpt as a magazine-style lede paragraph after the
   image-and-headline panel. Replaces the pre-#64 pattern where the
   hero story was duplicated as a plate in the events grid; now the
   hero is the canonical place for its full editorial treatment. */
.tih-hero__editorial{
  max-width: var(--maxw);
  margin: -8px auto 32px;
  padding: 0 28px;
}
@media (max-width: 640px){ .tih-hero__editorial { padding: 0 18px; } }
.tih-hero__kicker{
  /* §19 #66 typography refinement. Was sans-serif 13px soft-ink
     constrained to max-width: 72ch (which on desktop produced a
     line visibly narrower than the hero image above — the bug the
     user spotted). Now an italic display-serif in editorial plum at
     responsive 15-18px size; max-width constraint REMOVED so the
     line spans the same width as the image above (the parent
     .tih-hero__editorial already provides the max-width and side
     padding that match .tih-hero, so this element naturally fills
     the editorial column). Comfortable line-height for reading
     dot-separated metadata lists. */
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: var(--fs-h4);
  line-height: 1.6;
  letter-spacing: 0;
  color: var(--editorial-plum);
  margin-bottom: 18px;
}
.tih-hero__excerpt{
  font-family: var(--display);
  font-size: var(--fs-h4);
  line-height: 1.65;
  color: var(--ink);
  margin: 0;
  max-width: 72ch;
}

/* --- 6.4 Highlights — the 4 (or N) marquee year cards ----------------- */
.tih-highlights{
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 28px 8px;
}
@media (max-width: 640px){ .tih-highlights { padding: 0 18px 8px; } }
.tih-highlights__grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px;
  padding: 0;
}
.tih-highlight{
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 200px;
  padding: 22px 22px 20px;
  border-radius: var(--r-lg);
  color: #fff;
  overflow: hidden;
  background:
    radial-gradient(circle at 22% 18%, rgba(255,255,255,.30), transparent 55%),
    radial-gradient(circle at 78% 82%, rgba(0,0,0,.35), transparent 55%),
    linear-gradient(140deg,
      hsl(var(--accent-h, 215) 70% 32%) 0%,
      hsl(var(--accent-h, 215) 65% 44%) 55%,
      hsl(var(--accent-h, 215) 60% 56%) 100%);
  box-shadow:
    var(--bevel),
    0 12px 28px -12px rgba(0,0,0,.40),
    0 4px 10px -4px rgba(0,0,0,.22);
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
  text-shadow: 0 1px 8px rgba(0,0,0,.35);
}
/* §19 #61 dormancy convention: hover affordances only fire on highlights
   that have an href attribute. When the page sets 'href' => null the
   renderer omits the attribute entirely and this rule does not match,
   so the card stays flat — matching .tih-plate__link[href]:hover and
   .tih-hero[href]:hover. The transform/box-shadow change here is the
   visual "lift" affordance, so its absence is the visual signal of
   dormancy. No DOM-shape change, no modifier class. */
.tih-highlight[href]:hover{
  transform: translateY(-5px);
  box-shadow:
    var(--bevel-hover),
    0 24px 44px -16px rgba(0,0,0,.45),
    0 8px 14px -6px rgba(0,0,0,.26);
}
.tih-highlight__event{
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.2;
  letter-spacing: -.015em;
  max-width: 18ch;
}
.tih-highlight__year{
  align-self: flex-end;
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: 1;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0,0,0,.40);
  opacity: .96;
}

/* --- 6.5 Editorial plates (Headlines / Births / Observances) ----------- */
.tih-plates{
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 28px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 28px 22px;
}
@media (min-width: 1024px){ .tih-plates { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 36px 28px; } }
@media (min-width: 1280px){ .tih-plates { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 40px 32px; } }
@media (max-width: 640px){ .tih-plates { padding: 0 18px; gap: 24px 16px; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); } }

.tih-plate--wide { grid-column: span 2; }
@media (max-width: 720px){ .tih-plate--wide { grid-column: span 1; } }

.tih-plate{
  display: block;
  color: var(--ink);
  /* §19 #64 — TOC strip anchor-scrolls to individual plates by id.
     Match the .tih-section scroll-offset so the sticky catnav doesn't
     cover the destination plate's top edge after the scroll lands. */
  scroll-margin-top: calc(var(--nav-h) + 16px);
}

/* Inner link — the clickable hit zone covering image + kicker + title.
 * The excerpt below is a sibling, NOT inside this anchor (the §19 #60 /
 * §21 restructure that enables inline cross-references). Visually
 * identical to the old outer-<a> behavior: block-level, inherits color,
 * no underline. Hovering the link lifts the frame and zooms the image. */
.tih-plate__link{
  display: block;
  color: inherit;
  text-decoration: none;
}
.tih-plate__link:focus-visible{
  outline: 2px solid hsl(var(--accent-h, 215) 55% 45%);
  outline-offset: 3px;
  border-radius: var(--r-md);
}
.tih-plate__frame{
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  overflow: hidden;
  background:
    radial-gradient(circle at 22% 18%, rgba(255,255,255,.30), transparent 55%),
    radial-gradient(circle at 78% 82%, rgba(0,0,0,.30), transparent 55%),
    linear-gradient(140deg,
      hsl(var(--accent-h, 215) 65% 32%) 0%,
      hsl(var(--accent-h, 215) 60% 44%) 55%,
      hsl(var(--accent-h, 215) 55% 56%) 100%);
  box-shadow:
    var(--bevel),
    0 10px 24px -12px rgba(0,0,0,.36),
    0 3px 8px -3px rgba(0,0,0,.20);
  margin-bottom: 14px;
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
}
.tih-plate--wide .tih-plate__frame{ aspect-ratio: 16 / 9; }
/* Hover affordances gated on [href] (§10 site-wide link convention).
 * An <a class="tih-plate__link"> without href is per HTML spec non-
 * clickable and non-focusable; the [href] attribute selector ensures
 * the lift / zoom / pointer-cursor only activate when the destination
 * URL is present. Authors flip 'href' => null → '/real/url/' and the
 * affordances turn on automatically. */
.tih-plate__link[href]:hover .tih-plate__frame{
  transform: translateY(-4px);
  box-shadow:
    var(--bevel-hover),
    0 22px 40px -16px rgba(0,0,0,.42),
    0 7px 12px -6px rgba(0,0,0,.22);
}
.tih-plate__art{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  z-index: 2;
}
.tih-plate__art[hidden]{ display: none !important; }
.tih-plate__link[href]:hover .tih-plate__art{
  transform: scale(1.05);
  transition: transform .6s var(--ease);
}

/* When the TIH plate has its image, the photograph covers the frame
   (image is z-index:2, gradient stays underneath). Hide the placeholder
   so it doesn't show through any image transparency. Renderer adds
   .tih-plate--has-image; the <img>'s onerror strips it on 404. */
.tih-plate--has-image .tih-plate__placeholder{ display: none; }

.tih-plate__placeholder{
  position: absolute; inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 16px 18px;
  color: rgba(255,255,255,.94);
  text-shadow: 0 1px 6px rgba(0,0,0,.30);
}
.tih-plate__placeholder strong{
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.1;
  margin-bottom: 6px;
}
.tih-plate__placeholder em{
  font-family: var(--sans);
  font-style: normal;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  font-weight: 800;
  opacity: .82;
}
.tih-plate__hint{
  margin: 10px 0 0;
  font-size: 12px;
  opacity: .85;
  line-height: 1.45;
  font-style: italic;
}

.tih-plate__kicker{
  /* §19 #66 typography refinement. Was 10px ALL-CAPS red with
     .22em letter-spacing — visually loud and hard to read in
     long metadata lists. Now matches the hero kicker family:
     italic display-serif in editorial plum, mixed case, 13px
     (one step down from the hero kicker's responsive 15-18px),
     normal letter-spacing. Plates and hero now read as one
     editorial-typography family. */
  font-family: var(--display);
  font-style: italic;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
  color: var(--editorial-plum);
  margin-bottom: 6px;
}
.tih-plate__title{
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h4);
  line-height: 1.25;
  letter-spacing: -.005em;
  color: var(--ink);
  margin: 0 0 6px;
}
.tih-plate--wide .tih-plate__title{ font-size: var(--fs-h3); }
.tih-plate__excerpt{
  font-family: var(--display);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0;
}

/* --- 6.5c CROSS-REFERENCE STYLES (§21) ---------------------------------- *
 *
 * Single visual treatment for ALL cross-references. Body color with a
 * subtle indigo underline; hover deepens the color and thickens the
 * underline. Magazine-class density — quiet enough to not interrupt
 * reading in articles with 30+ refs, distinct enough to recognize as
 * a link without prior context.
 *
 * Section modifier classes (.ref--today, .ref--pedia, .ref--almanac,
 * .ref--yearbook, .ref--facts, .ref--quotes, .ref--quiz, .ref--static,
 * .ref--path, .ref--anchor) are still emitted by hbd_refs_render() —
 * they're available for future targeted treatments and as an analytics
 * hook — but the base .ref style is unified. Per the established design
 * convention of editorial reference sites (Wikipedia, Britannica, NYT,
 * FT, Bloomberg), ONE link color carries an entire encyclopedia.
 *
 * The rule applies in any rich-text context — TIH plate excerpts, pedia
 * article bodies, fact descriptions, etc.
 * ----------------------------------------------------------------------- */

.ref{
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: rgba(28, 86, 179, .50);
  transition: text-decoration-color var(--t-fast),
              text-decoration-thickness var(--t-fast),
              color var(--t-fast);
}
.ref:hover,
.ref:focus-visible{
  color: #1a3d80;
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}
.ref:focus-visible{
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* --- 6.5b TIH plate — long-title placeholder fix (§19 #59) -------------- *
 *
 * Background. .tih-plate__frame is aspect-locked (4:3 or 16:9 for --wide)
 * with overflow:hidden so that <img class="tih-plate__art"> can object-
 * fit:cover into a consistent rectangle. When the renderer's no-image
 * branch fires, .tih-plate__placeholder (position:absolute;inset:0)
 * renders <strong>YEAR · TITLE</strong> into that locked box. The text
 * has no object-fit to crop it — long titles simply overflow the locked
 * height and the overflow:hidden clips them at both top and bottom.
 *
 * The fix below is scoped strictly to .tih-plate:not(.tih-plate--has-
 * image). For that branch only, the frame becomes a CSS Grid: a ::before
 * pseudo carries the aspect-ratio as a MINIMUM via padding-bottom, and
 * the placeholder overlays it in the same grid cell. Short titles float
 * centered against the 4:3 / 16:9 floor; long titles grow the frame
 * downward without clipping. The parent .tih-plates grid's default
 * align-items:stretch keeps row peers visually balanced — peer plates
 * stretch to fill the same row height.
 *
 * Image-bearing plates are NOT touched. Their 4:3 / 16:9 lock plus
 * <img>'s object-fit:cover remain the deployed behavior. The
 * :not(.tih-plate--has-image) selector scopes everything away from
 * them, and .tih-plate--has-image .tih-plate__placeholder is already
 * display:none (line 697 above), so this section never affects them.
 * ----------------------------------------------------------------------- */
.tih-plate:not(.tih-plate--has-image) .tih-plate__frame{
  aspect-ratio: auto;
  display: grid;
  overflow: visible;
}
.tih-plate:not(.tih-plate--has-image) .tih-plate__frame::before{
  content: "";
  grid-area: 1 / 1;
  padding-bottom: 75%;          /* 4:3 minimum (3/4 = .75 of frame width) */
  pointer-events: none;
}
.tih-plate--wide:not(.tih-plate--has-image) .tih-plate__frame::before{
  padding-bottom: 56.25%;       /* 16:9 minimum (9/16 = .5625) for wide variant */
}
.tih-plate:not(.tih-plate--has-image) .tih-plate__placeholder{
  position: static;             /* override the base absolute positioning */
  inset: auto;
  grid-area: 1 / 1;             /* overlay the spacer in the same grid cell */
}
.tih-plate:not(.tih-plate--has-image) .tih-plate__placeholder strong{
  overflow-wrap: anywhere;      /* allow word-internal break on long tokens */
  hyphens: auto;
}

/* --- 6.6 Pull quote ----------------------------------------------------- */
.tih-quote{
  max-width: 880px;
  margin: 56px auto;
  padding: 36px 28px;
  font-family: var(--display);
  font-style: italic;
  font-weight: 500;
  font-size: var(--fs-h3);
  line-height: 1.4;
  color: var(--today-blue);
  text-align: center;
  position: relative;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.tih-quote__mark{
  display: block;
  font-family: var(--display);
  font-style: normal;
  font-size: var(--fs-display);
  line-height: .6;
  margin-bottom: 8px;
  color: var(--today-blue);
  opacity: .25;
}
.tih-quote cite{
  display: block;
  font-family: var(--sans);
  font-style: normal;
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 800;
  margin-top: 18px;
}

.tih-back{
  max-width: var(--maxw);
  margin: 32px auto 0;
  padding: 0 28px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.tih-back a{
  color: var(--today-blue);
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: border-color var(--t-base);
}
.tih-back a:hover{ border-color: var(--today-blue); }
@media (max-width: 640px){ .tih-back { padding: 0 18px; } }


/* ==========================================================================
   7. STATIC PAGES — page banner + editorial prose + contact cards
      Used by /cntct/, /terms/, and any future static informational page.
========================================================================== */

/* Page banner — shares the hero gradient with .tih-banner but lighter weight,
   for non-TIH static pages where there's no date / weekday badge. */
.page-banner{
  background:
    radial-gradient(circle at 18% 18%, rgba(255,255,255,.20), transparent 38%),
    radial-gradient(circle at 85% 80%, rgba(0,0,0,.22), transparent 42%),
    var(--brand-blue-grad);
  color: #fff;
  padding: 56px 0 48px;
  position: relative;
  overflow: hidden;
}
.page-banner .wrap{ position: relative; }
.page-banner__kicker{
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .28em;
  text-transform: uppercase;
  opacity: .82;
  margin-bottom: 10px;
}
.page-banner__title{
  font-family: var(--display);
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: 1.02;
  letter-spacing: -.025em;
  margin: 0;
}
.page-banner__sub{
  font-family: var(--display);
  font-style: italic;
  font-size: var(--fs-h4);
  line-height: 1.4;
  margin: 14px 0 0;
  opacity: .92;
  max-width: 64ch;
}

/* Editorial prose — reusable long-form body text (Terms, About, etc.) */
.prose{
  max-width: 720px;
  margin: 56px auto 80px;
  padding: 0 28px;
  font-family: var(--display);
  font-size: 17px;
  line-height: 1.75;
  color: var(--ink-2);
}
@media (max-width: 640px){
  .prose{ padding: 0 18px; margin-top: 40px; margin-bottom: 56px; }
}
.prose h2{
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.2;
  letter-spacing: -.015em;
  color: var(--ink);
  margin: 2.4em 0 .55em;
}
.prose h2:first-of-type{ margin-top: 0; }
.prose h3{
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -.005em;
  color: var(--ink);
  margin: 1.6em 0 .35em;
}
.prose p{ margin: 0 0 1.1em; }
.prose ul, .prose ol{ margin: 0 0 1.1em; padding-left: 1.4em; }
.prose li{ margin-bottom: .35em; }
.prose strong{ font-weight: 700; color: var(--ink); }
.prose a{
  color: var(--today-blue);
  border-bottom: 1px solid rgba(0,91,247,.30);
  transition: border-color var(--t-base), color var(--t-base);
}
.prose a:hover{ border-bottom-color: var(--today-blue); }
.prose hr{
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.4em 0;
}
.prose__updated{
  display: inline-block;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 36px;
  padding: 6px 12px;
  background: var(--paper-2);
  border-radius: var(--r-pill);
}

/* Contact info cards — three (or N) editorial info tiles */
.contact-grid{
  max-width: 980px;
  margin: 56px auto 56px;
  padding: 0 28px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
}
@media (max-width: 640px){
  .contact-grid{ padding: 0 18px; margin-top: 36px; gap: 14px; }
}
.contact-card{
  position: relative;
  background: var(--paper-2);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: transform var(--t-base) ease, box-shadow var(--t-base) ease;
}
.contact-card:hover{
  transform: translateY(-2px);
  box-shadow: 0 18px 36px -22px rgba(0,0,0,.32);
}
.contact-card__label{
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--today-blue);
}
.contact-card__value{
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h4);
  line-height: 1.4;
  letter-spacing: -.005em;
  color: var(--ink);
  font-style: normal;   /* override <address>'s default italic */
}
.contact-card__value a{
  color: var(--ink);
  border-bottom: 1px solid rgba(0,91,247,.30);
  transition: color var(--t-base), border-color var(--t-base);
  word-break: break-word;
}
.contact-card__value a:hover{
  color: var(--today-blue);
  border-bottom-color: var(--today-blue);
}
.contact-card__hint{
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 4px 0 0;
}


/* ============================================================================
   /ht/calendar/index.php — calendar of the year
   Twelve months in a 2-up grid (1-up on mobile). Each .cal-month sets its own
   --accent inline; every day tile derives its dark→accent→light gradient from
   that single token via color-mix(in oklab, ...). All 365/366 tiles share
   one CSS rule, so adding/removing months is a data change, not a CSS change.
============================================================================ */

/* ---- Banner ---------------------------------------------------------------
 * .cal-banner* — see /ht/calendar/index.php under "$cal_extra_css".
 * The banner is /ht/calendar/-only AND above the fold, so it lives in that
 * page's inline critical CSS for first-paint correctness — same pattern as
 * the homepage's .today panel. Updating banner styling is a single-file
 * change in /ht/calendar/index.php; no edits in this file are required.
============================================================================ */

/* ---- Calendar grid --------------------------------------------------------*/
.cal-main{ padding: 40px 0 72px; background: var(--paper-2, #F7F4EC); }
.cal-months{
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}
@media (min-width: 720px){
  .cal-months{ grid-template-columns: repeat(2, 1fr); gap: 28px; }
}

/* ---- Single month card ----------------------------------------------------*/
.cal-month{
  background: var(--paper);
  border-radius: var(--r-xl);
  padding: 22px 22px 24px;
  border: 1px solid var(--rule);
  box-shadow:
    0 1px 0 rgba(255,255,255,.6) inset,
    0 14px 30px -22px rgba(0,0,0,.18),
    0 4px 10px -4px rgba(0,0,0,.08);
}
.cal-month__head{
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--accent);
}
.cal-month__name{
  font-family: var(--display);
  font-size: 26px;
  margin: 0;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -.01em;
}
.cal-month__stone{
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 800;
}

/* ---- Day-of-week labels --------------------------------------------------*/
.cal-month__dow{
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cal-month__dow li{
  text-align: center;
  font-family: var(--sans);
  font-size: 10px;
  letter-spacing: .12em;
  font-weight: 800;
  color: var(--ink-soft);
}

/* ---- Day tile grid -------------------------------------------------------*/
.cal-month__days{
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cal-day{ aspect-ratio: 1; position: relative; }
.cal-day--blank{ visibility: hidden; }

.cal-day__num{
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border-radius: var(--r-md);
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h4);
  color: #fff;
  text-decoration: none;
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
  /* Same gradient language as the homepage plates and masthead cards, but
     dialled to the "medium" saturation tier — softer corners and a quieter
     sheen so a screen full of 365 tiles stays easy on the eye. */
  background:
    radial-gradient(circle at 26% 22%, rgba(255,255,255,.16), transparent 55%),
    linear-gradient(135deg,
      color-mix(in oklab, var(--accent) 60%, black 40%) 0%,
      var(--accent) 55%,
      color-mix(in oklab, var(--accent) 85%, white 15%) 100%);
  box-shadow:
    var(--bevel),
    0 5px 10px -5px rgba(0,0,0,.28);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base), filter var(--t-base);
}
a.cal-day__num:hover{
  transform: translateY(-2px) scale(1.06);
  box-shadow:
    var(--bevel-hover),
    0 12px 22px -8px rgba(0,0,0,.36);
  z-index: 2;
  filter: saturate(1.15);
}
a.cal-day__num:focus-visible{
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  z-index: 2;
}

/* ---- Today highlight (visitor's local today, set client-side) ----------- */
/* Blue ring — uses --today-blue (#005BF7), the site's brand color for
   "today." Chosen for high contrast: every month accent on the calendar
   is a different hue (May = emerald, October = orange, etc.), so a ring
   in the SAME accent would blend in. Blue stays visible on every accent.
   Set CLIENT-SIDE by JS in hbd_render_cal_month — respects the visitor's
   local timezone instead of the server's. */
.cal-day--today .cal-day__num{
  transform: scale(1.08);
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 5px var(--today-blue),
    var(--bevel),
    0 10px 22px -8px rgba(0,91,247,.45);
  z-index: 3;
  filter: saturate(1.2);
}
.cal-day--today a.cal-day__num:hover{
  transform: scale(1.12) translateY(-2px);
}

/* ---- Back link ----------------------------------------------------------- */
.cal-back{
  text-align: center;
  margin: 40px 0 0;
  font-family: var(--sans);
  font-size: 14px;
}
.cal-back a{
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
  transition: color var(--t-base), border-color var(--t-base);
}
.cal-back a:hover{ color: var(--ink); border-color: var(--ink); }

/* ---- Mobile tightening --------------------------------------------------- */
@media (max-width: 480px){
  /* .cal-banner mobile padding lives inline in /ht/calendar/index.php with
     the rest of the cal-banner styles (above-the-fold / single source). */
  .cal-month{ padding: 16px 14px 18px; border-radius: var(--r-lg); }
  .cal-month__head{ margin-bottom: 10px; padding-bottom: 8px; }
  .cal-month__name{ font-size: 22px; }
  .cal-month__stone{ font-size: 10px; }
  .cal-month__days, .cal-month__dow{ gap: 4px; }
  .cal-day__num{ border-radius: var(--r-md); font-size: 14px; }
  .cal-day--today .cal-day__num{
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 4px var(--today-blue),
      var(--bevel),
      0 6px 14px -6px rgba(0,91,247,.40);
  }
}

/* Reduced-motion respect — keep static highlight, drop scale & hover lift. */
@media (prefers-reduced-motion: reduce){
  .cal-day__num{ transition: none; }
  a.cal-day__num:hover{ transform: none; }
  .cal-day--today .cal-day__num{ transform: none; }
}


/* ============================================================================
   Pedia section — horizontal A–Z × a–z index (677 tiles)
   Rendered by hbd_render_pedia_index() in boot.php. Each row sets its own
   --accent inline; every tile (header + sub-tiles) derives a dark→accent→
   light gradient from that single token. Same gradient language as the
   masthead cards and the calendar tiles — same family, different rhythm.
============================================================================ */

.group--pedia .group__title{ margin-bottom: 18px; }

.pedia-index{
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* One band per starting letter. Header column on the left (fixed 56px),
   sub-tile flow grid on the right. align-items:start so the header stays a
   fixed-size anchor even when the sub-tiles wrap to multiple rows. */
.pedia-row{
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 8px;
  align-items: start;
}

/* The big section letter — A, B, … Z, # */
.pedia-row__head{
  height: 54px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md);
  font-family: var(--display);
  font-weight: 800;
  font-size: 28px;
  color: #fff;
  text-decoration: none;
  text-shadow: 0 1px 2px rgba(0,0,0,.40);
  background:
    radial-gradient(circle at 26% 22%, rgba(255,255,255,.18), transparent 55%),
    linear-gradient(135deg,
      color-mix(in oklab, var(--accent) 55%, black 45%) 0%,
      var(--accent) 55%,
      color-mix(in oklab, var(--accent) 80%, white 20%) 100%);
  box-shadow:
    var(--bevel),
    0 8px 16px -8px rgba(0,0,0,.32);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base), filter var(--t-base);
}
.pedia-row__head[href]:hover{
  transform: translateY(-2px) scale(1.03);
  box-shadow:
    var(--bevel-hover),
    0 14px 26px -10px rgba(0,0,0,.42);
  filter: saturate(1.15);
}
.pedia-row__head:focus-visible{
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* The 26 sub-letter tiles flow with auto-fill so the layout adjusts itself
   to whatever viewport is available. 48px minimum keeps the "Aa" labels
   readable on the smallest phone. */
.pedia-row__tiles{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
  gap: 6px;
}

.pedia-tile{
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md);
  /* Typography matched to the calendar tile (.cal-day__num): same serif
     family + weight, same fluid clamp, but the upper end is pushed a hair
     above the calendar's 17px because two letters ("Aa") need slightly
     more footprint than two digits ("30") to read at the same visual
     weight. The positive letter-spacing replaces the previous tight
     setting so the upper-and-lower-case pair has visible breathing room
     instead of squashing together. */
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h4);
  letter-spacing: .06em;
  color: #fff;
  text-decoration: none;
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
  /* Same medium-saturation gradient formula as the calendar tiles, so
     adding 677 of them on the homepage feels consistent with the calendar's
     365 tiles — neither shouts louder than the other. */
  background:
    radial-gradient(circle at 26% 22%, rgba(255,255,255,.16), transparent 55%),
    linear-gradient(135deg,
      color-mix(in oklab, var(--accent) 60%, black 40%) 0%,
      var(--accent) 55%,
      color-mix(in oklab, var(--accent) 85%, white 15%) 100%);
  box-shadow:
    var(--bevel),
    0 4px 8px -4px rgba(0,0,0,.26);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base), filter var(--t-base);
}
.pedia-tile[href]:hover{
  transform: translateY(-2px) scale(1.10);
  box-shadow:
    var(--bevel-hover),
    0 12px 20px -8px rgba(0,0,0,.40);
  z-index: 2;
  filter: saturate(1.18);
}
.pedia-tile:focus-visible{
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  z-index: 2;
}

/* '#' (numbers) band — just the header tile, no sub-tiles. */
.pedia-row--num{ grid-template-columns: 56px; }

/* ---- Mobile: stack header above tiles, slightly smaller everything ---- */
@media (max-width: 720px){
  .pedia-row{
    grid-template-columns: 1fr;
    gap: 6px;
  }
  .pedia-row__head{
    width: 100%;
    height: 40px;
    font-size: 20px;
    border-radius: var(--r-md);
  }
  .pedia-row--num{ grid-template-columns: 1fr; }
  .pedia-row__tiles{
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
    gap: 5px;
  }
  .pedia-tile{
    border-radius: var(--r-sm);
    font-size: 14px;
    letter-spacing: .04em;
  }
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce){
  .pedia-row__head, .pedia-tile{ transition: none; }
  .pedia-row__head:hover, .pedia-tile:hover{ transform: none; }
}


/* ============================================================================
   "Browse this month" mini-calendar on TIH detail pages
   The .cal-month card is reused as-is. We just need:
     - .cal-day--here   — distinct highlight for the date the page is about
                          (different from .cal-day--today; both can co-occur)
     - .tih-section--cal — section wrapper that constrains the single-month
                          card to ~480px and centers it under the heading
============================================================================ */
.tih-section--cal{
  text-align: center;
}
.tih-section--cal .tih-h2{
  text-align: left;       /* keep heading left-aligned like the others */
}
.tih-cal-wrap{
  max-width: 480px;
  margin: 0 auto;
  text-align: left;       /* reset cal-month internal alignment */
}
.tih-cal-cta{
  margin: 18px 0 0;
  font-family: var(--sans);
  font-size: 14px;
  color: var(--ink-soft);
}
.tih-cal-cta a{
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
  transition: color var(--t-base), border-color var(--t-base);
}
.tih-cal-cta a:hover{ color: var(--ink); border-color: var(--ink); }

/* The "here" tile — the date this page is about. Red ring uses
   --t-red (#B4381F), the site's brand accent. Chosen for contrast
   against both (a) the calendar's per-month accent colors (green for
   May, blue for September, etc.), which would blend into a ring of
   the same accent; and (b) the --today blue ring, so when both
   markers appear on the same calendar the user can tell at a glance
   which tile is which. */
.cal-day--here .cal-day__num{
  transform: scale(1.08);
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 5px var(--t-red),
    var(--bevel),
    0 10px 22px -8px rgba(180,56,31,.45);
  z-index: 2;
  filter: saturate(1.15);
}
.cal-day--here a.cal-day__num:hover{
  transform: scale(1.12) translateY(-2px);
}
/* When today === here (visitor is viewing today's page), today wins.
   Today is the more time-sensitive signal; the page-here context is
   implicit (the visitor is already on the page). Single ring, blue. */
.cal-day--today.cal-day--here .cal-day__num{
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 5px var(--today-blue),
    var(--bevel),
    0 10px 22px -8px rgba(0,91,247,.45);
  z-index: 4;
}

/* Mobile tweaks — same ring colors as desktop, just slightly thinner so
   tiles don't crowd at small widths. */
@media (max-width: 480px){
  .cal-day--today .cal-day__num{
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 4px var(--today-blue),
      var(--bevel),
      0 6px 14px -6px rgba(0,91,247,.40);
  }
  .cal-day--here .cal-day__num{
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 4px var(--t-red),
      var(--bevel),
      0 6px 14px -6px rgba(180,56,31,.40);
  }
  .cal-day--today.cal-day--here .cal-day__num{
    box-shadow:
      0 0 0 2px #fff,
      0 0 0 4px var(--today-blue),
      var(--bevel),
      0 6px 14px -6px rgba(0,91,247,.40);
  }
}

@media (prefers-reduced-motion: reduce){
  .cal-day--here .cal-day__num{ transform: none; }
  .cal-day--today .cal-day__num{ transform: none; }
}



/* ============================================================================
   SHARE BUTTON — image sharing for opted-in images
   ----------------------------------------------------------------------------
   Trigger: small white circle in the image's top-right corner. Compact (28px
   on desktop, 30px on touch) — half the bulk of the previous design.
   Popover: 4 brand-coloured icon buttons (Pinterest, WhatsApp, X, Copy Link).
   Identical UX on every device. See attach logic in /js/hbd2.js.
============================================================================ */

/* WRAPPER — JS injects this around every shareable image. Two variants:
     • .sharebtn-wrap            — for images in normal flow (article body
       <img class="article-image">). Wrapper is inline-block + relative,
       sized exactly to its image so the corner button hugs the photo
       and not the surrounding paragraph margin.
     • .sharebtn-wrap--overlay   — for images that already absolute-fill a
       parent frame (tih-plate__art, tih-hero__art, plate__art). Wrapper
       takes over the absolute-fill role; the image inside reverts to
       100% × 100% within the wrapper. */
.sharebtn-wrap{
    position: relative;
    display: inline-block;
    line-height: 0;            /* kill the descender gap under the image */
    max-width: 100%;
    vertical-align: top;
}
.sharebtn-wrap > img{
    display: block;
    max-width: 100%;
    height: auto;
}
.sharebtn-wrap--overlay{
    position: absolute;
    inset: 0;
    display: block;
    line-height: 0;
}
.sharebtn-wrap--overlay > img.tih-plate__art,
.sharebtn-wrap--overlay > img.tih-hero__art,
.sharebtn-wrap--overlay > img.plate__art{
    position: absolute;
    inset: 0;
    width:  100%;
    height: 100%;
    object-fit: cover;
}

/* TRIGGER — the small white circle. */
.sharebtn{
    position: absolute;
    top:   10px;
    right: 10px;
    width:  28px;
    height: 28px;
    padding: 0;
    margin:  0;
    border:  0;
    border-radius: var(--r-circle);
    background: rgba(255,255,255,.96);
    color: #141210;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 6px rgba(0,0,0,.18), 0 1px 2px rgba(0,0,0,.12);
    transition: transform var(--t-fast) ease, background var(--t-fast) ease, box-shadow var(--t-fast) ease;
    z-index: 3;
    -webkit-tap-highlight-color: transparent;
}
.sharebtn:hover, .sharebtn:focus-visible{
    background: #fff;
    transform: scale(1.08);
    box-shadow: 0 4px 12px rgba(0,0,0,.22), 0 2px 4px rgba(0,0,0,.14);
    outline: none;
}
.sharebtn:focus-visible{
    box-shadow: 0 0 0 3px rgba(0,91,247,.40), 0 4px 12px rgba(0,0,0,.22);
}
.sharebtn > svg,
.sharebtn > img{
    width:  15px;
    height: 15px;
    display: block;
    pointer-events: none;          /* clicks always go to the button itself */
}

/* Touch devices: bump the trigger slightly (still subtle, but easier to
   hit with a thumb than the 28px desktop size). 30px hit area + the
   surrounding photo surface comfortably exceeds the WCAG 24px AA minimum
   and the Apple HIG / Material 44–48px touch target via padded miss area. */
@media (max-width: 820px), (hover: none) {
    .sharebtn{
        width:  30px;
        height: 30px;
        top:    8px;
        right:  8px;
    }
    .sharebtn > svg,
    .sharebtn > img{
        width:  16px;
        height: 16px;
    }
}

/* POPOVER — JS positions this with `position: fixed`. */
.sharepop{
    position: fixed;
    z-index: 1000;
    display: flex;
    gap: 6px;
    padding: 8px;
    background: #fff;
    border-radius: var(--r-lg);
    border: 1px solid var(--rule);
    box-shadow: 0 12px 32px rgba(0,0,0,.20), 0 2px 8px rgba(0,0,0,.10);
    animation: sharepop-in .15s ease-out;
    font-family: var(--sans);
}
@keyframes sharepop-in{
    from { opacity: 0; transform: translateY(-4px) scale(.96); }
    to   { opacity: 1; transform: none; }
}

/* POPOVER BUTTONS — brand colours, icon-only, tooltip on hover/focus. */
.sharepop__btn{
    position: relative;
    width:  40px;
    height: 40px;
    padding: 0;
    border:  0;
    border-radius: var(--r-circle);
    cursor: pointer;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    transition: transform var(--t-fast) ease, background var(--t-fast) ease, box-shadow var(--t-fast) ease;
    -webkit-tap-highlight-color: transparent;
}
.sharepop__btn:hover, .sharepop__btn:focus-visible{
    transform: scale(1.08);
    outline: none;
}
.sharepop__btn:focus-visible{
    box-shadow: 0 0 0 3px rgba(0,91,247,.40);
}
.sharepop__btn > svg{
    width:  18px;
    height: 18px;
    display: block;
    pointer-events: none;
}
.sharepop__btn--pin   { background: #E60023; }     /* Pinterest red */
.sharepop__btn--wa    { background: #25D366; }     /* WhatsApp green */
.sharepop__btn--x     { background: #000000; }     /* X black */
.sharepop__btn--copy  { background: #3D3D3A; }     /* neutral charcoal */
.sharepop__btn--copied{ background: #25D366; }     /* matches success state */

/* Tooltip — purely cosmetic (the button already carries an aria-label, so
   screen readers don't need this). Suppressed on touch devices to avoid
   the sticky-tooltip-after-tap problem. */
.sharepop__btn::after{
    content: attr(data-tip);
    position: absolute;
    bottom: -28px;
    left: 50%;
    transform: translateX(-50%);
    background: #141210;
    color: #fff;
    font-family: var(--sans);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .01em;
    padding: 4px 8px;
    border-radius: var(--r-sm);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--t-fast) ease;
    z-index: 1;
}
.sharepop__btn:hover::after,
.sharepop__btn:focus-visible::after{
    opacity: 1;
}
@media (hover: none) {
    .sharepop__btn::after{ display: none; }
}

/* Article-image figure — the conventional editorial wrapper for body
   photos. Authors put class="article-image" on the <figure> AND/OR on the
   <img> inside; the JS share trigger picks up either case. */
.article-image{
    margin: 24px 0 32px;
    text-align: center;
}
.article-image img{
    max-width: 100%;
    height: auto;
    border-radius: var(--r-sm);
    box-shadow: 0 2px 12px rgba(0,0,0,.08), 0 1px 3px rgba(0,0,0,.06);
}
.article-image figcaption{
    margin-top: 10px;
    font-family: var(--sans);
    font-size: 13px;
    line-height: 1.55;
    color: var(--ink-soft);
    font-style: italic;
}


/* ============================================================================
   COMMENTS — Elfsight widget integration
   The widget loads async and renders inside a third-party iframe. We reserve
   vertical space upfront so the page doesn't jump when comments arrive —
   without this, every TIH and encyclopedia page would have ~400-600 px of
   Cumulative Layout Shift on first paint, hurting Core Web Vitals.

   Elfsight platform.js targets div.elfsight-app-{uuid}; we don't style that
   directly (the widget paints itself), but the .tih-comments wrapper
   provides the section heading + space reservation around it.
============================================================================ */
.tih-comments{
    margin: 56px auto 32px;
    padding: 0 var(--gutter, 24px);
    max-width: 880px;
}
.tih-comments h2{
    margin: 0 0 24px;
}
.tih-comments .elfsight-app-66fefdf6-da0e-4d07-9074-acf4b63807ad{
    min-height: 480px;
}
@media (max-width: 640px){
    .tih-comments{ margin: 40px auto 24px; }
    .tih-comments .elfsight-app-66fefdf6-da0e-4d07-9074-acf4b63807ad{
        min-height: 400px;
    }
}


/* ============================================================================
   CONTACT PAGE — Elfsight contact form integration
   The form widget loads async into a third-party iframe; we reserve vertical
   space upfront so the page doesn't jump when the form arrives.

   Also: .contact-card__value--address uses a single text node with newlines
   between address lines (rendered via white-space: pre-line) instead of
   <br> tags — semantically cleaner and trivially editable from the
   $contact['address_lines'] array in /cu/contact-us/index.php.
============================================================================ */
.contact-card__value--address{
    white-space: pre-line;
    font-style: normal;
}
.contact-form{
    max-width: 880px;
    margin: 56px auto 32px;
    padding: 0 var(--gutter, 24px);
}
.contact-form h2{ margin: 0 0 24px; }
.contact-form .elfsight-app-80acd8e7-ff81-4fd9-9f9f-ee40a285e058{
    min-height: 620px;
}
@media (max-width: 640px){
    .contact-form{ margin: 40px auto 24px; }
    .contact-form .elfsight-app-80acd8e7-ff81-4fd9-9f9f-ee40a285e058{
        min-height: 560px;
    }
}


/* ============================================================================
   ENCYCLOPEDIA ARTICLE PAGES — /aa/ … /zz/ + /num/

   Promoted from inline <style> in zz/index.php once the pattern stabilised.
   Used by all 677 two-letter article pages plus /num/. Each article injects
   --ph, --ps, --pa as inline custom properties on .pedia-banner from its
   own md5-derived palette (see hbd_pedia_banner_palette() in /inc/boot.php),
   and these styles read those values to paint a unique gem-toned banner
   per article.
============================================================================ */
/* ============================================================================
 * Article-specific styles. Move this block to /css/hbd2.css once the
 * pattern stabilises and we begin generating all 677 article pages.
 *
 * Design tokens live on body.pedia-page so the rest of the site can scope
 * via that class if needed. The hero borrows --today-blue and --today-red
 * from :root so it visually matches the homepage's "today" band.
 * ========================================================================== */
body.pedia-page{
  --term-blue:  #003FB8;               /* deep editorial blue for the headword       */
  --rule-blue:  rgba(0, 91, 247, .12); /* hairline rule between glossary rows        */
}

/* ---- Article banner — full-bleed gem-gradient header --------------------
   Modelled on the calendar's .cal-banner, but with a per-page palette so
   each of the 677 article pages gets its own visibly distinct gradient.
   Hue / saturation / angle are injected as inline custom properties on
   the .pedia-banner element itself (--ph, --ps, --pa) and read here.

   The background is declared TWICE on purpose:
     1. an HSL fallback (universally supported), then
     2. an OKLCH version that overrides the fallback in modern browsers.
   OKLCH is perceptually uniform — a 0.16 lightness reads equally dark
   for any hue, which is what makes the dark anchor reliably contrast
   with the white headline regardless of which slug landed on which hue.
   Older browsers that don't understand oklch() simply ignore line 2 and
   keep the HSL gradient — graceful degradation, no @supports needed.

   The gradient runs from a near-black anchor through a saturated mid
   stop to a still-dark tint at the same hue. All three stops share
   `--ph`, so the band stays inside one hue family — no shifted bottom
   stop drifting into adjacent zones. Combined with the hue-formula's
   safe arc (see pedia_banner_palette()), this guarantees every page
   reads as a deep green / teal / blue / violet / magenta / pink /
   crimson — never brown, tan, beige, grey, or black. The lightness
   clamp 0.16 → 0.28 → 0.40 keeps white text passing WCAG AA contrast
   everywhere on the band. */
.pedia-banner{
  position: relative;
  overflow: hidden;
  padding: 14px 0 14px;
  text-align: center;
  color: #fff;
  background:
    linear-gradient(135deg,
      hsl(var(--ph) var(--ps) 13%) 0%,
      hsl(var(--ph) var(--ps) 26%) 55%,
      hsl(var(--ph) var(--ps) 38%) 100%);
  background:
    linear-gradient(var(--pa, 135deg),
      oklch(0.16 0.12 var(--ph)) 0%,
      oklch(0.28 0.17 var(--ph)) 55%,
      oklch(0.40 0.17 var(--ph)) 100%);
}
/* Soft top-right highlight — a single radial overlay that gives the band
   a convex "lit from above" feel, the same trick the masthead brand
   cards use. Kept very gentle (12% white at the apex) so it reads as
   ambient light rather than a hot spot. */
.pedia-banner::after{
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 75% -10%, rgba(255,255,255,.12), transparent 60%);
  pointer-events: none;
}
.pedia-banner .wrap{ position: relative; }

/* Kicker — small, wide-tracked, all-caps "ENCYCLOPEDIA" sitting above
   the title. Mirrors the proportions of .cal-banner__kicker exactly so
   the calendar and article banners speak the same typographic language.
   The dotted underline on the inner link is the same affordance the
   homepage uses for its meta links — recognisable as clickable without
   competing with the headline. */
.pedia-banner__kicker{
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .22em;
  text-transform: uppercase;
  font-weight: 800;
  opacity: .85;
  margin-bottom: 10px;
}
.pedia-banner__kicker a{
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted rgba(255,255,255,.42);
  padding-bottom: 1px;
  transition: border-color var(--t-base), opacity var(--t-base);
}
.pedia-banner__kicker a:hover,
.pedia-banner__kicker a:focus-visible{
  border-bottom-color: rgba(255,255,255,.95);
  outline: none;
}

/* Hero title — "Zz" set in the display serif at hero scale. Slightly
   bigger clamp than the calendar year because two-letter titles read
   smaller than four-digit years at the same font-size. The text-shadow
   sits the title slightly above the gradient without becoming a visible
   drop shadow. */
.pedia-banner__title{
  font-family: var(--display);
  font-size: var(--fs-mega);
  margin: 0;
  line-height: .92;
  letter-spacing: -.02em;
  font-weight: 800;
  color: #fff;
  text-shadow: 0 4px 28px rgba(0,0,0,.34);
}

/* A-Z ribbon — 26 thin stripes of the existing letter-accent tokens,
   shown identically on every article page. Decorative; communicates
   "you're somewhere in a 26-letter system" while the breadcrumb, page
   title and URL handle "you are here". The current letter's stripe is
   subtly emphasised (slightly taller via scaleY + a hint of glow) so an
   attentive reader gets a faint "you-are-here" cue without the ribbon
   losing its uniform rhythm. */
.pedia-banner__ribbon{
  display: flex;
  align-items: stretch;
  width: min(560px, 82%);
  height: 6px;
  margin: 18px auto 0;
  border-radius: var(--r-pill);
  overflow: hidden;
  box-shadow: 0 2px 14px rgba(0,0,0,.32);
}
.pedia-banner__ribbon span{
  flex: 1;
  transition: transform var(--t-base) ease;
}
.pedia-banner__ribbon span.is-current{
  transform: scaleY(1.55);
  box-shadow: 0 0 0 1px rgba(255,255,255,.55) inset;
}

/* Mobile — keep the band airy but tighten the vertical rhythm so the
   reader still sees the first glossary entry above the fold on a phone. */
@media (max-width: 640px){
  .pedia-banner{ padding: 12px 0 12px; }
  .pedia-banner__ribbon{ margin-top: 14px; height: 5px; }
}

/* ---- Bottom siblings cards — compact ghost buttons ----------------------
   Used only at the bottom of the article (the in-banner prev/next was
   removed when the banner became a full-bleed gem header). Same blue
   tint and chrome the original hero corners used, lifted out of the
   shared selector group now that the hero versions are gone. */
/* Sibling nav cards — brandbar-style gem gradient. Each card is a twin
   of the brandbar__brand card on the masthead: same #071833 → #005BF7 →
   #2E8BFF blue gradient, same inset bevel + drop-shadow language, same
   -3px hover lift. The pair gives a coherent "navigation-within-
   encyclopedia" affordance that aligns visually with the four brand
   cards at the top of every page. */
.pedia-siblings__sib{
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 22px;
  border-radius: var(--r-lg);
  background: var(--brand-blue-grad);
  border: 1px solid #003fb8;
  color: #fff;
  text-decoration: none;
  white-space: nowrap;
  min-width: 110px;
  overflow: hidden;
  position: relative;
  box-shadow:
    var(--bevel),
    0 18px 40px -28px rgba(0,91,247,.55);
  transition: transform var(--t-base) ease, box-shadow var(--t-base) ease;
  will-change: transform;
}
.pedia-siblings__sib:hover{
  transform: translateY(-3px);
  box-shadow:
    var(--bevel-hover),
    0 22px 44px -22px rgba(0,91,247,.60);
}
.pedia-siblings__sib:active{ transform: translateY(-1px); }
.pedia-siblings__sib:focus-visible{
  outline: 2px solid #fff;
  outline-offset: 3px;
}
.pedia-siblings__kicker{
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: rgba(255,255,255,.86);
  transition: color var(--t-base);
}
.pedia-siblings__label{
  font-family: var(--display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1;
  color: #fff;
  text-shadow: 0 2px 14px rgba(0,0,0,.22);
}
.pedia-siblings__sib:hover .pedia-siblings__kicker{ color: #fff; }

/* ---- Glossary table -----------------------------------------------------
   Two columns, blue hairline between rows. Column 1 is locked to ~25% via
   table-layout: fixed so a long headword wraps inside its own column
   instead of pushing column 2 to the right edge. Wrap strategy: prefer
   word-boundary breaks (multi-word phrases like "ZZ plant" split cleanly
   on spaces); for single long words, the browser inserts a soft hyphen
   at a proper syllable break point ("antidis-establishmentarianism"),
   which is the typographically correct way to mark a continued word —
   without it, a mid-word break could read as two separate words. The
   character-level overflow-wrap fallback only triggers for strings the
   hyphenator cannot resolve (transliterations, identifiers, nonsense
   stress-tests), and is preferable to letting the column overflow. */
.pedia-article__body{
  padding: 56px 0 64px;
  background: var(--paper);
}
.pedia-glossary{
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  border-collapse: separate;       /* keeps cell padding clean across rows    */
  border-spacing: 0;
  table-layout: fixed;             /* respects the 25 / 75 column split       */
}
/* Column widths — declared once on the first body row's cells so fixed
   layout has explicit numbers to honour. */
.pedia-glossary col.pedia-glossary__col--term{ width: 25%; }
.pedia-glossary col.pedia-glossary__col--defn{ width: 75%; }
/* Single hairline that crosses both columns — applied to row N+1's cells
   so it sits BELOW row N's content. No vertical column separator anywhere;
   columns are visually divided by the term column's right padding. */
.pedia-glossary__entry + .pedia-glossary__entry > .pedia-glossary__term,
.pedia-glossary__entry + .pedia-glossary__entry > .pedia-glossary__defn{
  border-top: 1px solid var(--rule-blue);
}
.pedia-glossary__term{
  vertical-align: top;
  text-align: left;
  padding: 1.75rem 2rem 1.75rem 0;    /* right padding = the "tab space"     */
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-h3);
  color: var(--term-blue);
  letter-spacing: -.005em;
  line-height: 1.2;
  font-feature-settings: "kern" 1;
  /* Wrap behaviour: prefer word-boundary breaks; for a single long word
     the browser inserts a soft hyphen at a syllable break (driven by
     <html lang="en"> hyphenation rules), so a continued word reads
     unambiguously as one word rather than two. overflow-wrap only
     triggers for strings the hyphenator can't resolve, as a fallback
     against column overflow. Editorially: avoid pathological strings
     in production; if a real headword needs a specific break point,
     insert &shy; soft-hyphen hints at the desired position. */
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.pedia-glossary__defn{
  vertical-align: top;
  padding: 1.75rem 0;
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
}
.pedia-glossary__defn p{ margin: 0 0 .9rem; }
.pedia-glossary__defn p:last-child{ margin-bottom: 0; }
.pedia-glossary__defn em{
  font-style: italic;
  color: var(--term-blue);
  font-weight: 500;
}
.pedia-glossary__defn strong{
  font-weight: 700;
  color: var(--ink);
}

/* ----------------------------------------------------------------------------
   Anchor styling — see LINK CONVENTION docblock at top of file.
   • All <a> in the glossary inherit surrounding color/style by default, so a
     dormant <a> (no href) is visually indistinguishable from the surrounding
     prose. An <a> without href is also not focusable and not clickable per
     the HTML spec — no extra logic needed to "disable" it.
   • The [href] attribute selector is the activation switch: it only matches
     anchors that have an href, so hover/focus affordances appear automatically
     once a link goes live.
---------------------------------------------------------------------------- */
.pedia-glossary a{
  color: inherit;
  text-decoration: none;
}
.pedia-glossary a[href]:hover{
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.pedia-glossary a[href]:focus-visible{
  outline: 2px solid var(--today-blue);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* Mobile: stack term on top, defn below — table semantics break to blocks. */
@media (max-width: 720px){
  .pedia-glossary,
  .pedia-glossary tbody,
  .pedia-glossary__entry,
  .pedia-glossary__term,
  .pedia-glossary__defn{
    display: block;
    width: auto;
  }
  .pedia-glossary{ table-layout: auto; }
  .pedia-glossary colgroup{ display: none; }
  .pedia-glossary__term{
    padding: 1.5rem 0 .35rem;
    border-top: 1px solid var(--rule-blue);
  }
  .pedia-glossary__entry:first-child > .pedia-glossary__term{
    border-top: 0;
    padding-top: 0;
  }
  .pedia-glossary__defn{
    padding: 0 0 1.5rem;
    border-top: 0 !important;
  }
  .pedia-article__body{ padding: 36px 0 48px; }
}

/* ---- Bottom siblings nav — same cards as the hero, laid out in a row ---
   Card chrome is shared with the hero (see the grouped selectors above),
   so the bottom-of-page navigation reads as the same control language.
   Layout is grid-based: prev card pinned to the left, italic centre meta
   in the middle, next card pinned to the right. */
.pedia-siblings{
  background: var(--paper);
  border-top: 1px solid var(--rule);
  padding: 32px 0;
}
.pedia-siblings__row{
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 20px;
  align-items: center;
}
.pedia-siblings__sib--prev{ justify-self: start; }
.pedia-siblings__sib--next{ justify-self: end;   }
.pedia-siblings__center{
  font-family: var(--display);
  font-style: italic;
  color: var(--ink-soft);
  font-weight: 400;
  font-size: 14px;
  letter-spacing: .02em;
  text-align: center;
  white-space: nowrap;
}
@media (max-width: 600px){
  .pedia-siblings__row{ grid-template-columns: 1fr 1fr; gap: 14px; }
  .pedia-siblings__center{ display: none; }
}

/* ---- Bottom Encyclopedia nav -------------------------------------------- */
.pedia-nav-section{
  padding: 48px 0 64px;
  background: var(--paper-2, #F7F4EC);
  border-top: 1px solid var(--rule);
}
.pedia-nav-section__title{
  font-family: var(--display);
  font-size: var(--fs-h3);
  margin: 0 0 24px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -.01em;
}


/* ============================================================================
   ENCYCLOPEDIA ARTICLE COMMENTS — Elfsight widget integration

   Same widget UUID as TIH pages (66fefdf6...) — Elfsight scopes threads by
   URL automatically, so /aa/ and /zz/ get separate comment threads without
   any per-page configuration. The min-height reservation prevents
   Cumulative Layout Shift while the third-party iframe loads.
============================================================================ */
.pedia-comments{
    margin: 56px 0 32px;
}
.pedia-comments .wrap{
    max-width: 880px;
    padding: 0 var(--gutter, 24px);
}
.pedia-comments__title{
    font-family: var(--display);
    font-size: var(--fs-h3);
    font-weight: 700;
    margin: 0 0 24px;
    color: var(--ink);
    letter-spacing: -.01em;
}
.pedia-comments .elfsight-app-66fefdf6-da0e-4d07-9074-acf4b63807ad{
    min-height: 480px;
}
@media (max-width: 640px){
    .pedia-comments{ margin: 40px 0 24px; }
    .pedia-comments .elfsight-app-66fefdf6-da0e-4d07-9074-acf4b63807ad{
        min-height: 400px;
    }
}

/* ============================================================================
   SCROLL-PERFORMANCE LAYOUT-SKIP — per-tile content-visibility.

   Site-wide tiles: .plate (homepage Almanac/Yearbook + future visual-
   reference pages) and .pedia-tile (procedural Encyclopedia index, 703
   tiles every homepage visit). Off-screen instances skip layout, paint,
   and style work entirely until they approach the viewport.

   This complements the existing content-visibility:auto on .group at the
   top of this stylesheet (§15) with finer-grained skipping — tiles
   within an in-viewport section also get skipped when off-screen, which
   is the regime that matters at the 5000-plate horizon discussed in §19.

   The `auto` keyword in contain-intrinsic-size means the size hints
   below are first-render guesses only; the browser caches the real
   measured size after first paint, so off-screen instances stay
   scroll-accurate even if the initial hints are imperfect. Self-
   correcting.

   .fact (the /facts/ row layout) is NOT included here — per §15, page-
   specific CSS lives in /facts/index.php's $page_extra_css block, not
   in this site-wide stylesheet. That selector will be added in a
   companion change to /facts/index.php.

   Print: force visible so off-screen tiles render in printed output.

   Browser support: Chrome 85+, Edge 85+, Firefox 125+, Safari 18+.
   Unsupported browsers ignore both properties — graceful degradation.
========================================================================== */

.plate,
.pedia-tile{
  content-visibility: auto;
}

.plate{
  /* Plate __frame is a 1:1 square sized by its CSS grid column, plus a
     ~30-50px label below. Typical desktop grid column is ~210-240px,
     so the rendered plate is ~240-290px tall. The hint is a starting
     guess; the `auto` keyword auto-caches the real value after first
     paint. */
  contain-intrinsic-size: auto 220px auto 280px;
}

.pedia-tile{
  /* Procedural Encyclopedia tile: aspect-ratio:1 (see rule above),
     ~40-80px square depending on viewport. The hint is the midpoint;
     `auto` auto-caches the real value. */
  contain-intrinsic-size: auto 60px auto 60px;
}

@media print{
  .plate,
  .pedia-tile{ content-visibility: visible; }
}
