/*
 * Theme base + component styles (Phase 1, GP-native reshape).
 * GeneratePress child theme
 * ---------------------------------------------------------------------------
 * Adapted from the VALIDATED playground (.scratch/pg-shell.html); its .st-*
 * components are renamed to .hofs-* here, keeping the exact structure,
 * spacing, radii, shadows and responsive rules.
 *
 * COLOR SOURCE (reshape §5): the palette is no longer authored here. Our engine
 * derives it and writes GeneratePress's own global_colors (inc/gp-populate.php),
 * so GP emits it natively as :root{--contrast…--accent-2…}. Components read
 * those GP vars DIRECTLY — the old html:root override bridge is gone. The engine
 * tokens fold onto GP slots per §5:
 *   ink→--contrast   muted→--contrast-2   dim→--contrast-3
 *   soft→--base   bg→--base-2   surface→--base-3   brand→--accent   accent→--accent-2
 * Only the guarded helpers GP's palette model can't express survive as
 * --hofs-* (brand-text, on-brand, brand-dark, on-accent, line, border-strong),
 * emitted inline by Hofs_Token_CSS; plus the non-color scales (space/radius/
 * type/shadow/font) in tokens.css. Light-only — the reshape dropped dark mode.
 *
 * Layering:
 *   L2  Targeted GP chrome + global base (body/headings/links/buttons/…)
 *   L3  Content components GP does NOT provide (hero, cards, tabs, …)
 *   L4  A11y utilities (skip-link, sr-only, font-size control)
 *   L5  Reduced-motion
 *
 * Type scaling: the A-/A/A+ control (theme.js) writes --hofs-font-scale on
 * <html>; every type size is calc(<size> * var(--hofs-font-scale)) so the
 * control scales the whole typographic surface. Do NOT re-declare the scales
 * from tokens.css here — this file only consumes them.
 *
 * See .implans/phase-1-gp-native-reshape.md §5.
 */

/* ==========================================================================
   Tier discipline  (reshape §5)
   --------------------------------------------------------------------------
   GeneratePress emits the derived palette natively on :root (--contrast{,-2,-3},
   --base{,-2,-3}, --accent, plus the custom --accent-2 — all written by
   inc/gp-populate.php from our engine), so the components below read those GP
   vars DIRECTLY. There is no override bridge.

   --contrast-3 is the lowest-contrast text token (meets non-text 3.0, NOT body
   4.5). Per H-4 (WCAG 1.4.3), NO text in this file is colored with it — every
   glyph, down to the faintest doc/card/sidebar meta, uses --contrast-2
   (secondary) or --contrast (primary). Hairlines/borders use --hofs-line. */

:root { scroll-padding-top: calc(4rem + var(--hofs-space-3)); }

/* ==========================================================================
   L2 — Global base + targeted GP chrome  (Wave4 §1c)
   --------------------------------------------------------------------------
   A thin set of single-class / element rules for the handful of GP chrome
   pieces whose role our model splits differently than GP's flat ramp
   (page-canvas vs surface; link-text = brand-text; button on-color). GP's
   canonical selectors at single-class specificity — no !important.
   ========================================================================== */

body {
  background: var(--base-2);
  color: var(--contrast);
  font-family: var(--hofs-font-body);
  font-size: calc(var(--hofs-text-base) * var(--hofs-font-scale));
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  text-wrap: pretty;
}

/* H-1 — responsive heading sizes from the tokens.css type ladder (:47-53) +
   Eric's -0.01em tracking. GP's main.min.css hard-codes fixed px (h1 42 / h2 35 /
   h3 29 …) with no media query; theme.css prints after it, so these (0,0,1) rules
   tie on specificity and win on source order. Weight stays GP-native (the
   typography store assigns all-headings → Syne 500). Sizes carry the A-/A/A+
   font-scale like every other type size in this file. */
h1, h2, h3, h4, h5, h6 {
  color: var(--contrast);
  font-family: var(--hofs-font-display);
  letter-spacing: -.01em;
}
h1 { font-size: calc(var(--hofs-text-3xl)  * var(--hofs-font-scale)); }
h2 { font-size: calc(var(--hofs-text-2xl)  * var(--hofs-font-scale)); }
h3 { font-size: calc(var(--hofs-text-xl)   * var(--hofs-font-scale)); }
h4 { font-size: calc(var(--hofs-text-lg)   * var(--hofs-font-scale)); }
h5 { font-size: calc(var(--hofs-text-md)   * var(--hofs-font-scale)); }
/* Item 9 — H6 is the only heading that maps to body size (--hofs-text-base);
   on narrow viewports the clamp bottoms at 1rem/16px, which puts Syne below its
   ~18px legibility floor. max() lifts H6's floor to 1.125rem (18px) so no
   heading equals body size and Syne never renders sub-18px. H1–H5 already clear
   body (H4 = text-lg ≈ 23–26px), so the plan's "H4 = body" premise is stale and
   H1–H5 need no change. */
h6 { font-size: calc(max(1.125rem, var(--hofs-text-base)) * var(--hofs-font-scale)); }

/* Content links — the brand-text token (an AA-legible teal on our light
   surfaces; the reading-legible variant of --accent, which GP uses to color bare
   <a> links). Broad on purpose: this base rule is NOT hand-scoped away from
   nav/buttons — their own higher-specificity FILL rules (GP's site-title +
   .main-navigation … a below, .button, .hofs-btn*) win over a bare `a`, so it
   only reaches content / widget / entry / comment links. hover/focus re-assert
   the same token; no text-decoration here, so nav chrome is untouched. */
a {
  color: var(--hofs-brand-text);
}
a:hover,
a:focus {
  color: var(--hofs-brand-text);
}

/* Item 8 — inline body-content links carry an underline (WCAG 1.4.1). Nav,
   buttons, pathway pills and cards keep their own no-underline treatment; the
   :not() guards keep block/GP/theme (.hofs-btn) buttons that live inside
   .entry-content clean.
   Links inside the dynamic hofs/* data blocks are component links: they keep
   their own styling, as the retired archive templates printed them outside
   .entry-content. So do the Document List block's links (a whole-row
   .hofs-doc card and the .hofs-doc__action pill buttons), whose ACF
   wrapper doesn't match the wp-block-hofs- exemption. A Panel's read-more
   link is a component link too, and a Callouts link keeps its plain underline
   (the Callouts style sets its own link colour); their guards sit in :where() so
   they add no specificity (the listing-page overrides below outrank this rule by
   exactly one class). The Panel body selector is the one the Panel block style's
   body rule uses (section "Content panels" below). */
.entry-content a:not(.button):not(.hofs-btn):not(.wp-element-button):not(.wp-block-button__link):not(.hofs-doc):not(.hofs-doc__action):not([class*="wp-block-hofs-"] a):not(:where(.hofs-panel__more > a, .is-style-hofs-callouts a)),
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :not(:is(h1, h2, h3, h4, h5, h6):first-child, .wp-block-group__inner-container, .hofs-panel__more) a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: from-font;
}

::selection {
  background: var(--accent);
  color: var(--hofs-on-brand);
}

/* Focus-visible ring — brand-text is AA-legible on our light surfaces. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--hofs-brand-text);
  outline-offset: 2px;
  border-radius: var(--hofs-radius-sm);
}
/* Buttons keep their pill on focus: the ring above (0,1,1) would otherwise
   square a button link's pill radius (0,1,0) to radius-sm. */
.hofs-btn:focus-visible,
.hofs-pathway:focus-visible,
.button:focus-visible,
.wp-block-button__link:focus-visible,
.wp-element-button:focus-visible {
  border-radius: var(--hofs-radius-pill);
}

/* H-6 — the doc rows and accordion summaries live inside overflow:hidden
   wrappers (.hofs-doclist / .hofs-accordion), which clip the offset outline
   above (WCAG 2.4.11 fail: a single-item list loses all four sides). Swap to an
   INSET box-shadow ring — painted inside the border box, so the wrapper's clip
   can never reach it. These selectors out-specify the generic *:focus-visible
   rule above. Forced-colors mode strips box-shadow, so keep a transparent inset
   outline as the fallback indicator — the OS repaints its own visible outline
   over any `outline: solid` declaration. .hofs-font-size (inline-flex, no
   overflow clip) does not need this swap and inherits the generic ring. */
.hofs-doc:focus-visible,
.hofs-accordion summary:focus-visible {
  outline: 2px solid transparent;
  outline-offset: -2px;
  box-shadow: inset 0 0 0 2px var(--hofs-brand-text);
}

/* --- GP header / nav / footer chrome --------------------------------------
   GP renders these; we only re-tint them from the token bridge. */
.site-header {
  background: var(--base-3);
}

.main-navigation,
.main-navigation .inside-navigation {
  background: var(--base-3);
}

.main-navigation .main-nav ul li a {
  color: var(--contrast);
}

.main-navigation ul ul {
  background: var(--base-3);
  border-color: var(--hofs-line);
}

/* --- Nav hover / current state: a RAIL, never a filled box -----------------
   GP's legacy colour block painted the hovered + current item with a #3f3f3f
   background; our teal link colour on top of it measured 1.96:1 — a WCAG 1.4.3
   failure, and the visible "grey tab". The backgrounds are now `transparent`
   (written GP-natively in inc/gp-populate.php nav_colors(), so GP itself stops
   emitting them) and GP paints the text `--hofs-brand-text`, which the
   engine's AA guard keeps legible against the bar's own `--base-3` surface
   (#007779 on #fffaf2 = 5.16:1) no matter where the owner drags the knobs.

   All this layer adds is the STATE MARKER. It is deliberately a rail and not a
   tint: a rail is pure decoration sitting beside the glyphs, so no derived
   colour can ever erode the text contrast the guard just guaranteed — whereas a
   tinted pill puts a knob-dependent surface *behind* the text (a 12% accent wash
   already measures 4.40:1, under the line). `box-shadow: inset` rather than a
   border so the rail costs no layout and never shifts the 60px GP row.

   Horizontal bar → bottom rail. Hover previews it at 45%; current commits to a
   full accent rail plus a weight bump. */
.main-navigation .main-nav ul li > a {
  box-shadow: inset 0 -3px 0 transparent;
  transition: box-shadow 120ms ease, color 120ms ease;
}

.main-navigation .main-nav ul li:hover > a,
.main-navigation .main-nav ul li:focus-within > a {
  box-shadow: inset 0 -3px 0 color-mix(in srgb, var(--accent) 45%, transparent);
}

.main-navigation .main-nav ul li[class*="current-menu"] > a {
  box-shadow: inset 0 -3px 0 var(--accent);
  font-weight: 600;
}

/* Vertical contexts — the open dropdown and (below) GP's mobile drawer — stack
   their items, where a bottom rail reads as a row divider. Swap to an
   inline-start rail so the marker still points at the item, not between them. */
.main-navigation .main-nav ul ul li > a {
  box-shadow: inset 3px 0 0 transparent;
}
.main-navigation .main-nav ul ul li:hover > a,
.main-navigation .main-nav ul ul li:focus-within > a {
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent) 45%, transparent);
}
.main-navigation .main-nav ul ul li[class*="current-menu"] > a {
  box-shadow: inset 3px 0 0 var(--accent);
}

.main-navigation.toggled .main-nav ul li > a {
  box-shadow: inset 3px 0 0 transparent;
}
.main-navigation.toggled .main-nav ul li:hover > a,
.main-navigation.toggled .main-nav ul li:focus-within > a {
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent) 45%, transparent);
}
.main-navigation.toggled .main-nav ul li[class*="current-menu"] > a {
  box-shadow: inset 3px 0 0 var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .main-navigation .main-nav ul li > a {
    transition: none;
  }
}

/* Forced-colors mode repaints every link from the OS palette AND strips
   box-shadow — so both signals this state relies on vanish at once, leaving the
   current page indistinguishable from its neighbours. Underline is the one
   marker the mode preserves. (Same reasoning as the doc-row focus ring above,
   opposite conclusion: a ring can be re-drawn with `outline`, but an outline
   here would read as a focus indicator on a non-focused item.) */
@media (forced-colors: active) {
  .main-navigation .main-nav ul li[class*="current-menu"] > a,
  .hofs-nav-more.has-current > .hofs-nav-more__toggle {
    text-decoration: underline;
    text-underline-offset: 0.35em;
    text-decoration-thickness: 2px;
  }
}

/* --- Single-line nav overflow ("•••") -------------------------------------
   Priority+ pattern. The <li> is injected SERVER-SIDE (inc/generatepress.php
   hofs_nav_more_item) so it exists before GP's menu.js runs and inherits GP's
   own dropdown positioning; assets/js/theme.js then moves top-level items in and
   out of its .sub-menu as the bar overflows, and adds `is-visible` only when it
   actually holds something. Hidden by default, so with JS off the menu simply
   wraps to two rows exactly as it does today — no item is ever unreachable. */
.main-navigation .main-nav ul li.hofs-nav-more {
  display: none;
}
.main-navigation .main-nav ul li.hofs-nav-more.is-visible {
  display: block;
}

/* One row from first paint. The fold runs after first paint, so until theme.js
   adds `hofs-nav-measured` a JS-capable page shows the row the fold will
   produce: the items on one line, Search at its end, the overflow clipped. The
   fold then only removes clipped items, and nothing on the page moves. Desktop
   only: below GP's 768px breakpoint the bar is the drawer. */
@media (min-width: 769px) {
  .hofs-js .main-navigation:has(.hofs-nav-more):not(.hofs-nav-measured) :is(.inside-navigation, .main-nav > ul) {
    flex-wrap: nowrap;
  }
  .hofs-js .main-navigation:has(.hofs-nav-more):not(.hofs-nav-measured) .main-nav {
    flex: 1 1 0;
    min-width: 0;
    overflow-x: clip;
    white-space: nowrap;
  }
}

/* The trigger has to sit in the same 60px rhythm as GP's real menu anchors, so
   it borrows their padding/line-height rather than inventing button metrics.
   It is a <button>, which means the theme's own generic button paint (H-5/P-7:
   teal fill, white text, pill radius — GP-native via form_button_*) targets it
   through the bare `button` selector. Every state below therefore has to re-null
   the background explicitly: the base rule alone leaves `button:hover` free to
   drop a solid brand-dark slab behind the dots. */
.hofs-nav-more__toggle {
  display: block;
  padding: 0 20px;
  line-height: 60px;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: 0.08em;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--contrast);
  cursor: pointer;
  box-shadow: inset 0 -3px 0 transparent;
  transition: box-shadow 120ms ease, color 120ms ease;
}
.main-navigation .main-nav ul li.hofs-nav-more:hover > .hofs-nav-more__toggle,
.hofs-nav-more__toggle:hover,
.hofs-nav-more__toggle:focus,
.hofs-nav-more__toggle:active,
.hofs-nav-more.is-open > .hofs-nav-more__toggle {
  background: none;
  color: var(--hofs-brand-text);
  box-shadow: inset 0 -3px 0 color-mix(in srgb, var(--accent) 45%, transparent);
}
/* …and the focus ring is the generic a11y one from the top of this file, which
   the state rule's own box-shadow would otherwise replace. Restore it here so
   keyboard focus stays visible (WCAG 2.4.7) alongside the rail. */
.hofs-nav-more__toggle:focus-visible {
  outline: 2px solid var(--hofs-brand-text);
  outline-offset: -2px;
}
/* The current page can be one of the items that got folded away — mark the
   trigger so "you are here" survives the collapse. */
.hofs-nav-more.has-current > .hofs-nav-more__toggle {
  background: none;
  color: var(--hofs-brand-text);
  box-shadow: inset 0 -3px 0 var(--accent);
}

/* GP opens sub-menus on hover via `.main-navigation:not(.toggled) ul li:hover >
   ul`; `is-open` is our click/keyboard equivalent for the same panel, so touch
   and keyboard users get the disclosure hover-only styling cannot give them.
   Mirrors GP's own open state (main.css:674-681) property for property. */
.main-navigation:not(.toggled) li.hofs-nav-more.is-open > ul.sub-menu {
  left: auto;
  opacity: 1;
  pointer-events: auto;
  height: auto;
  overflow: visible;
}

/* The trigger is the LAST item in the bar, so a left-anchored flyout would run
   off the right edge of the viewport. Anchor this one panel to the right —
   `right` ALONE, deliberately: GP parks a closed sub-menu at `left: -99999px`
   (main.css:634) and an over-constrained fixed-width box ignores `right`, so the
   panel stays hidden until GP's own hover rule (or `.is-open`) releases `left`.
   Setting `left: auto` here would strand it on-screen in the closed state. */
.main-navigation:not(.toggled) li.hofs-nav-more > ul.sub-menu {
  right: 0;
}

/* A folded item may itself have children (e.g. Events), which GP would fly out
   at `left: 100%` — straight off the right edge, since this panel is already
   pinned to it. Send that one nesting level leftward instead. Out-specifies GP's
   own open rule (main.css:684-687, 0-3-4) at 0-4-4. */
.main-navigation:not(.toggled) li.hofs-nav-more ul li:hover > ul,
.main-navigation:not(.toggled) li.hofs-nav-more ul li.sfHover > ul {
  right: 100%;
  left: auto;
}

.main-navigation.toggled .main-nav ul li.hofs-nav-more {
  display: none;
}

/* Item 3 — minimal floating navbar. MOBILE-ONLY (≤768px): GP's drawer only
   functions ≤768px, so a hamburger trigger is meaningful only there; on desktop
   the persistent help pill (item 5) covers always-available access and the nav
   returns on scroll-up. Hidden off-canvas until JS adds --visible on scroll past
   the header. Fill/border/shadow all tokenized. */
.hofs-floatnav {
  display: none;
}
.hofs-floatnav__title {
  font-family: var(--hofs-font-display);
  font-weight: 600;
  font-size: calc(1.125rem * var(--hofs-font-scale));
  color: var(--contrast);
  text-decoration: none;
}
/* TRAP, read before adding any chrome <button> to this theme: GP paints generic
   buttons from `form_button_*` (inc/gp-populate.php button_colors) through a BARE
   `button` selector, and its hover rule `button:hover {…}` is 0-1-1. A component
   rule like `.hofs-floatnav__toggle { background: transparent }` is only
   0-1-0, so it loses the moment the button is hovered — and on a touch device
   that state STICKS after the tap, which is why this hamburger showed up as a
   solid teal slab on a phone but never in a desktop screenshot. Every chrome
   button therefore has to restate its background at 0-1-1 or higher. theme.css
   prints last in the pipeline, so an equal-specificity rule here always wins. */
.hofs-floatnav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--hofs-space-2);
  background: transparent;
  border: 0;
  color: var(--contrast);
  cursor: pointer;
  border-radius: var(--hofs-radius-sm);
}
.hofs-floatnav__toggle:hover,
.hofs-floatnav__toggle:focus,
.hofs-floatnav__toggle:active {
  background: var(--base-2);
  color: var(--contrast);
}
.hofs-floatnav__icon svg {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
}
@media (max-width: 768px) {
  .hofs-floatnav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--hofs-space-3);
    padding: var(--hofs-space-3) var(--hofs-space-5);
    background: var(--base-3);
    border-bottom: 1px solid var(--hofs-line);
    transform: translateY(-100%);
    transition: transform 0.25s ease;
    /* Off-canvas: remove from tab order + a11y tree so keyboard/SR users don't
       hit the phantom title link + toggle before the bar slides in (WCAG 2.4.3,
       2.4.7, 1.3.2). Snaps (no transition on visibility) — reduced-motion path
       unchanged. */
    visibility: hidden;
  }
  .hofs-floatnav--visible {
    transform: translateY(0);
    box-shadow: var(--hofs-shadow-md);
    visibility: visible;
  }
}
/* When the float-nav bar is visible and the user taps ITS hamburger, GP opens
   #site-navigation in-flow at the header's original (scrolled-off) position —
   far above the viewport, so the menu appears dead. While the bar is active
   (body.hofs-floatnav-active, set by theme.js), pin GP's opened .toggled
   drawer as a fixed overlay dropping down directly beneath the bar. GP's
   menu.min.js keeps owning open/close/aria/focus — this only relocates WHERE the
   already-open menu renders. z-index sits below the bar (9999) so the bar stays
   on top; covering the help bar (9998) while open is acceptable. */
@media (max-width: 768px) {
  body.hofs-floatnav-active #site-navigation.toggled {
    position: fixed;
    /* 4rem ≈ the bar's rendered height (padding var(--hofs-space-3) around a
       1.5rem icon + title); the menu drops flush under it. */
    top: 4rem;
    /* GP gives #site-navigation a default top margin (header↔nav spacing); as a
       fixed overlay that margin only opens a gap below the bar — collapse it. */
    margin-top: 0;
    left: 0;
    right: 0;
    max-height: calc(100vh - 4rem);
    overflow-y: auto;
    z-index: 9998;
    box-shadow: var(--hofs-shadow-lg);
  }
}

/* Guardrail: kill the slide for reduced-motion users (the only new transition
   in this wave). */
@media (prefers-reduced-motion: reduce) {
  .hofs-floatnav {
    transition: none;
  }
}

/* Mobile burger — token-colored only; GP owns the drawer behavior. */
.main-navigation .menu-toggle,
.main-navigation .menu-bar-items {
  color: var(--contrast);
}

/* Item 4 — hide the display controls from the mobile bar (they eat header
   width next to the hamburger); reveal the ALREADY-rendered second copy inside
   the slide-out drawer when it is open. CSS-only: GP renders .hofs-controls
   twice, so no PHP/JS. 768px = GP's real mobile breakpoint. The leading
   `.site-header` raises specificity to (1,5,0) so the reveal beats GP's own
   `.has-inline-mobile-toggle #site-navigation .inside-navigation > *:not(...)`
   hide rule (1,4,0). ANCHOR: GP puts `has-inline-mobile-toggle` on the SITE
   HEADER, not on <body> — the former `body.` prefix matched nothing, so this
   reveal never fired and the stepper was unreachable on mobile entirely (all
   six buttons measured 0x0 with the drawer open). Same root cause as the
   search link's hide rule below. */
@media (max-width: 768px) {
  #mobile-menu-control-wrapper .hofs-controls {
    display: none;
  }
  .site-header.has-inline-mobile-toggle #site-navigation.toggled .inside-navigation > .menu-bar-items {
    display: flex;
  }
}

.site-footer,
.site-info {
  background: var(--base-3);
  color: var(--contrast-2);
}

/* --- GP / block-editor buttons --------------------------------------------
   H-5/P-7: paint every GP-core + block button teal-on-brand at pill radius and
   weight 600. The sidebar Search submit is
   <button class="wp-block-search__button wp-element-button"> — matched ONLY by
   .wp-element-button, whose WP-core rule is `:root :where(.wp-element-button)`
   (0,1,0) and paints it grey/square. `:root .wp-element-button` (0,2,0) prints
   after WP-core's global styles and wins. */
.button,
button.button,
input[type="submit"],
.wp-block-button__link,
:root .wp-element-button {
  background: var(--accent);
  color: var(--hofs-on-brand);
  border-radius: var(--hofs-radius-pill);
  font-weight: 600;
}

.button:hover,
.button:focus,
button.button:hover,
button.button:focus,
input[type="submit"]:hover,
input[type="submit"]:focus,
.wp-block-button__link:hover,
.wp-block-button__link:focus,
:root .wp-element-button:hover,
:root .wp-element-button:focus {
  background: var(--hofs-brand-dark);
  color: var(--hofs-on-brand);
}

/* The core Button's default (fill) style wears the theme's primary button
   (.hofs-btn.hofs-btn--primary below): the same box model, type,
   padding, border and shadow over the fill and hover above, so a label that
   wraps lays out the same way too (core centres each line and breaks long
   words; .hofs-btn does neither). Colours, sizes and spacing an editor
   sets on the block still win (they print as inline styles or !important
   classes); the outline style keeps core's own look. */
.wp-block-button:not(.is-style-outline) > .wp-block-button__link {
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-2);
  text-align: inherit;
  word-break: normal;
  font-family: var(--hofs-font-body);
  font-size: calc(.98rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1;
  padding: calc(var(--hofs-space-3) + 1px) var(--hofs-space-5);
  border: 1.5px solid transparent;
  border-radius: var(--hofs-radius-pill);
  box-shadow: var(--hofs-shadow-sm);
  text-decoration: none;
}
/* A Button given a width in the editor fills it; keep its label centred
   there, as core does (a .hofs-btn is never stretched). */
.wp-block-button.has-custom-width:not(.is-style-outline) > .wp-block-button__link {
  justify-content: center;
  text-align: center;
}

/* ==========================================================================
   L3 — Content components  (Wave4 §Decision 2; from pg-shell.html .st-*)
   ========================================================================== */

/* --- Hero band (owns the single <h1>) — pg-shell.html L256-260 ------------- */
.hofs-hero {
  padding: var(--hofs-space-8) var(--hofs-space-6);
  background: linear-gradient(160deg, var(--base), var(--base-3));
  border-bottom: 1px solid var(--hofs-line);
}
.hofs-hero__eyebrow {
  font-family: var(--hofs-font-body);
  font-size: calc(.78rem * var(--hofs-font-scale));
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--hofs-brand-text);
  font-weight: 700;
  margin: 0 0 var(--hofs-space-3);
}
.hofs-hero__title {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight */
  font-size: calc(var(--hofs-text-3xl) * var(--hofs-font-scale));
  line-height: 1.08;
  letter-spacing: -.02em;
  margin: 0 0 var(--hofs-space-4);
  color: var(--contrast);
  text-wrap: balance;
  max-width: 18ch;
}
.hofs-hero__lede {
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  color: var(--contrast-2);
  max-width: 46ch;
  margin: 0 0 var(--hofs-space-6);
  line-height: 1.5;
}
.hofs-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hofs-space-3);
}

/* --- Buttons (pill; on-brand / on-accent) — pg-shell.html L263-268 --------- */
.hofs-btn {
  font-family: var(--hofs-font-body);
  font-size: calc(.98rem * var(--hofs-font-scale));
  font-weight: 600;
  padding: calc(var(--hofs-space-3) + 1px) var(--hofs-space-5);
  border-radius: var(--hofs-radius-pill);
  border: 1.5px solid transparent;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-2);
  line-height: 1;
}
.hofs-btn--primary {
  background: var(--accent);
  color: var(--hofs-on-brand);
  box-shadow: var(--hofs-shadow-sm);
}
.hofs-btn--primary:hover {
  background: var(--hofs-brand-dark);
}
.hofs-btn--accent {
  background: var(--accent-2);
  color: var(--hofs-on-accent);
  box-shadow: var(--hofs-shadow-sm);
}
/* A filled button keeps its label colour on hover and focus: the base link
   rule `a:hover, a:focus` (0,1,1) outranks the fill's colour (0,1,0) and would
   paint the brand-text label onto the brand fill. The palette engine guards
   on-brand against both brand and brand-dark, and on-accent against accent. */
.hofs-btn--primary:hover,
.hofs-btn--primary:focus {
  color: var(--hofs-on-brand);
}
.hofs-btn--accent:hover,
.hofs-btn--accent:focus {
  color: var(--hofs-on-accent);
}
.hofs-btn--ghost {
  background: transparent;
  color: var(--hofs-brand-text);
  border-color: var(--hofs-border-strong);
}
.hofs-btn--ghost:hover {
  border-color: var(--accent);
  background: var(--base);
}

/* --- Section rhythm — pg-shell.html L271-276 ------------------------------- */
.hofs-section {
  padding: var(--hofs-space-7) var(--hofs-space-6);
}
/* A section after another section gets the hairline, whether either is printed
   bare or inside its block's wrapper: most data blocks wrap their sections
   (Events, Assemblies, ...), Latest news, Latest newsletter and Contributions
   don't, and a template prints them bare. So the hairline keys on the box
   before the section's own box (the section, or the wrapper it sits in)
   holding a section. Side-by-side columns get no divider between them. */
:is(.hofs-section, :has(> .hofs-section):not(.wp-block-column)) + .hofs-section,
:is(.hofs-section, :has(> .hofs-section):not(.wp-block-column)) + :has(> .hofs-section) > .hofs-section {
  border-top: 1px solid var(--hofs-line);
}
/* A core Group given the section class (Advanced → Additional CSS class(es))
   is a page section: the section's
   padding replaces GeneratePress's 40px Group box padding. So does the Panel
   block style's (section "Content panels"). */
.wp-block-group.hofs-section > .wp-block-group__inner-container,
.wp-block-group.is-style-hofs-panel > .wp-block-group__inner-container {
  padding: 0;
}
.hofs-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--hofs-space-4);
  margin-bottom: var(--hofs-space-5);
}
.hofs-section__head h2,
.hofs-section__title {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight */
  font-size: calc(var(--hofs-text-xl) * var(--hofs-font-scale));
  margin: 0;
  letter-spacing: -.01em;
  color: var(--contrast);
}
.hofs-section__more {
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-size: calc(.9rem * var(--hofs-font-scale));
  font-weight: 600;
  white-space: nowrap;
}
.hofs-section__more:hover {
  text-decoration: underline;
}

/* --- Districts map — reference image above the directory ------------------- */
/* A core Image block with the `hofs-districts-map` class on the Districts
   page. Reset the browser's default <figure> side margins, cap the width so the raster is
   not upscaled past its detail, and center it. The image keeps the inline
   baseline (core's Image block sets `bottom`), so the gap below it matches. */
.hofs-districts-map {
  margin: 0 0 var(--hofs-space-6);
  text-align: center;
}
.hofs-districts-map img {
  max-width: 100%;
  height: auto;
  vertical-align: baseline;
  border-radius: var(--hofs-radius-sm);
}

/* --- Card grid + cards — pg-shell.html L279-288 ---------------------------- */
.hofs-cardgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: var(--hofs-space-5);
}
/* Assemblies are feature items (usually just one upcoming). Wider tracks +
   auto-fit so a lone assembly stretches full-width instead of sitting narrow,
   while several still flow into columns. */
.hofs-cardgrid--assembly {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
}
.hofs-card,
.hofs-event-card {
  background: var(--base-3);
  /* item 21: --hofs-card-border tracks the elevation knob — the guarded
     border-strong when flat (shadows off), the decorative hairline otherwise.
     Falls back to --hofs-line if the survivor sheet is ever absent. */
  border: 1px solid var(--hofs-card-border, var(--hofs-line));
  border-radius: var(--hofs-radius);
  box-shadow: var(--hofs-shadow-sm);
  padding: var(--hofs-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-2);
}
.hofs-card:hover,
.hofs-event-card:hover {
  box-shadow: var(--hofs-shadow-md);
}
.hofs-card h3,
.hofs-card__title,
.hofs-event-card h3 {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight */
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  margin: 2px 0 0;
  line-height: 1.2;
  color: var(--contrast);
}
.hofs-card p,
.hofs-event-card p {
  margin: 2px 0 0;
  font-size: calc(.92rem * var(--hofs-font-scale));
  color: var(--contrast-2);
  line-height: 1.5;
}
.hofs-card__meta {
  font-size: calc(.82rem * var(--hofs-font-scale));
  color: var(--contrast-2); /* H-4: was --contrast-3 (event date failed 4.5:1) */
  font-weight: 500;
}
.hofs-card__kv {
  display: flex;
  gap: var(--hofs-space-2);
  font-size: calc(.86rem * var(--hofs-font-scale));
}
.hofs-card__kv b {
  color: var(--contrast);
  font-weight: 600;
}
.hofs-card__kv span {
  min-width: 0;
  overflow-wrap: anywhere; /* a value cell: see .hofs-sidebar__row b */
  color: var(--contrast-2);
}

/* --- Chip / pill (reusable + card + event) — pg-shell.html L282-283 -------- */
.hofs-chip,
.hofs-card__chip {
  align-self: flex-start;
  font-size: calc(.72rem * var(--hofs-font-scale));
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--hofs-on-accent);
  background: var(--accent-2);
  padding: 3px 9px;
  border-radius: var(--hofs-radius-pill);
}
.hofs-chip--soft,
.hofs-card__chip--soft {
  color: var(--hofs-brand-text);
  background: var(--base);
}

/* --- Split: main + committee sidebar — pg-shell.html L291-299 -------------- */
/* minmax(0, …) tracks: a plain `1fr` keeps an automatic minimum, so one long URL in
   the blurb or the rail would widen the column past the viewport. With a zero
   minimum the column keeps its share and the text wraps inside it. */
.hofs-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--hofs-space-6);
}
@media (min-width: 800px) {
  .hofs-split {
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  }
}
.hofs-sidebar {
  background: var(--base);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-lg);
  padding: var(--hofs-space-5);
  align-self: start;
}
.hofs-sidebar h3,
.hofs-sidebar__title {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight (was heading-default) */
  margin: 0 0 var(--hofs-space-3);
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  color: var(--contrast);
}
.hofs-sidebar__row {
  display: flex;
  justify-content: space-between;
  gap: var(--hofs-space-3);
  padding: var(--hofs-space-3) 0;
  border-top: 1px solid var(--hofs-line);
  font-size: calc(.9rem * var(--hofs-font-scale));
}
.hofs-sidebar__row:first-of-type {
  border-top: 0;
}
.hofs-sidebar__row span {
  color: var(--contrast-2); /* H-4: was --contrast-3 (label failed 4.5:1) */
}
/* The value cell may hold an unbroken string (a website URL, a meeting ID). As a flex
   child it would keep its min-content width, the whole URL, and push the rail and
   the grid track above it past the viewport. min-width: 0 lets it shrink inside the
   row; overflow-wrap: anywhere lets the string wrap and stops its width counting
   toward the rail's minimum. The card rows, meeting facts and event meta use the same pair. */
.hofs-sidebar__row b {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--contrast);
  font-weight: 600;
  text-align: right;
}
.hofs-sidebar__vacancy {
  margin-top: var(--hofs-space-4);
  padding: var(--hofs-space-3) var(--hofs-space-4);
  border-radius: var(--hofs-radius-sm);
  background: var(--base-3);
  border: 1px dashed var(--hofs-border-strong);
  font-size: calc(.85rem * var(--hofs-font-scale));
  color: var(--contrast-2);
}
.hofs-sidebar__vacancy a {
  color: var(--hofs-brand-text);
  font-weight: 600;
}

/* Collapsible sidebar variant — used for the officers roster groups on
   /contact/, where three long lists otherwise push the form itself off the
   first mobile viewport. Same disclosure pattern as .hofs-cnav: below
   860px the <details> stays closed by default so a visitor sees three tap
   targets and expands the group they want; at desktop widths the rows show
   and the summary reads as the rail's plain title, so the rail is unchanged. */
.hofs-sidebar__summary {
  cursor: pointer;
  list-style: none;                    /* drop the UA disclosure marker */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hofs-space-3);
  padding: var(--hofs-space-3) var(--hofs-space-4);
  border: 1px solid var(--contrast-3);
  border-radius: var(--hofs-radius-sm);
  background: var(--base-2);
  color: var(--contrast);
}
.hofs-sidebar__summary::-webkit-details-marker { display: none; }
.hofs-sidebar__summary::after {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-0.15em);
  transition: transform 150ms ease;
  flex: 0 0 auto;
}
.hofs-sidebar__disclosure[open] > .hofs-sidebar__summary::after {
  transform: rotate(-135deg) translateY(0.15em);
}
.hofs-sidebar__disclosure[open] > .hofs-sidebar__summary {
  margin-bottom: var(--hofs-space-3);
}
.hofs-sidebar__disclosure > .hofs-sidebar__summary .hofs-sidebar__title {
  /* Kill the default title's bottom margin when it sits inside <summary>. */
  margin: 0;
}
/* Desktop: the summary is the plain rail title (no box, no chevron), and
   theme.js (rail disclosures) sets the <details> `open` so its state reads
   "expanded". Until that deferred script runs, and without JS, the server-closed
   <details> would hide the rows (UA `::details-content { content-visibility:
   hidden }`, which no `display` on the children undoes) and then expand them:
   the pseudo-element rule shows them from first paint. It is its own rule, so an
   engine without ::details-content drops only it; there the title still opens
   the group with JS off. */
@media (min-width: 860px) {
  .hofs-sidebar__disclosure::details-content { content-visibility: visible; }
  .hofs-sidebar--collapsible .hofs-sidebar__disclosure > .hofs-sidebar__summary {
    display: block;
    margin-bottom: var(--hofs-space-3);
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    cursor: default;
  }
  .hofs-sidebar--collapsible .hofs-sidebar__summary::after { content: none; }
}

/* --- Tabs (ARIA; behavior in theme.js) — pg-shell.html L302-306 ------------ */
.hofs-tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  border-bottom: 1px solid var(--hofs-line);
  margin-bottom: var(--hofs-space-4);
}
.hofs-tab {
  appearance: none;
  border: 0;
  background: transparent;
  font-family: var(--hofs-font-body);
  font-size: calc(.95rem * var(--hofs-font-scale));
  font-weight: 600;
  color: var(--contrast-2);
  padding: var(--hofs-space-3) var(--hofs-space-4);
  cursor: pointer;
  border-bottom: 2.5px solid transparent;
  margin-bottom: -1px;
}
.hofs-tab[aria-selected="true"] {
  color: var(--hofs-brand-text);
  border-bottom-color: var(--accent);
}
/* Keep the tab transparent on hover/focus: bare <button> otherwise inherits the
   GP/core button teal fill, which lands teal-on-teal (illegible). Signal with a
   colour + a soft underline hint instead. */
.hofs-tab:hover,
.hofs-tab:focus {
  background: transparent;
  color: var(--hofs-brand-text);
}
.hofs-tab:not([aria-selected="true"]):hover {
  border-bottom-color: var(--hofs-line);
}
.hofs-tabpanel {
  font-size: calc(.94rem * var(--hofs-font-scale));
  color: var(--contrast-2);
  line-height: 1.6;
}
.hofs-js .hofs-tabpanel:not(.is-current),
.hofs-tabpanel[hidden] {
  display: none;
}
.hofs-js .hofs-tabpanel__title {
  display: none;
}
html:not(.hofs-js) .hofs-tabs__list {
  display: none;
}

/* --- Accordion (native <details>/<summary>) — pg-shell.html L309-315 ------- */
.hofs-accordion {
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius);
  overflow: hidden;
  background: var(--base-3);
}
.hofs-accordion details + details {
  border-top: 1px solid var(--hofs-line);
}
.hofs-accordion summary {
  cursor: pointer;
  padding: var(--hofs-space-4) var(--hofs-space-5);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(.98rem * var(--hofs-font-scale));
  color: var(--contrast);
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--hofs-space-3);
}
.hofs-accordion summary::-webkit-details-marker {
  display: none;
}
.hofs-accordion summary::after {
  content: "+";
  color: var(--hofs-brand-text);
  font-size: 1.2em;
  font-weight: 700;
  line-height: 1;
}
.hofs-accordion details[open] summary::after {
  content: "\2013"; /* en dash */
}
.hofs-accordion__body {
  padding: 0 var(--hofs-space-5) var(--hofs-space-4);
  font-size: calc(.92rem * var(--hofs-font-scale));
  color: var(--contrast-2);
  line-height: 1.6;
}

/* --- Document list — pg-shell.html L318-327 ------------------------------- */
.hofs-doclist {
  display: flex;
  flex-direction: column;
  /* Reset the list box: this is a bordered card container, NOT a content list.
     GeneratePress styles content `ul` with margin: 0 0 1.5em 3em — that 3em
     left margin was insetting the whole doc-list ~48px past its heading/siblings
     (glaring on a ~380px mobile column, subtle on desktop). Zero it so the card
     aligns to the content edge like every other block. */
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius);
  overflow: hidden;
}
.hofs-doc {
  display: flex;
  align-items: center;
  gap: var(--hofs-space-4);
  padding: var(--hofs-space-4) var(--hofs-space-5);
  background: var(--base-3);
  text-decoration: none;
  color: inherit;
}
/* P-6: each row is wrapped in its own <li> (doc-list-item.php), so no two
   .hofs-doc are adjacent siblings — the inter-row separator must key off
   adjacent list items instead. */
.hofs-doclist li + li .hofs-doc {
  border-top: 1px solid var(--hofs-line);
}
.hofs-doc:hover {
  background: var(--base);
}
.hofs-doc__icon {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--hofs-radius-sm);
  background: var(--base);
  color: var(--hofs-brand-text);
  display: grid;
  place-items: center;
  font-family: var(--hofs-font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
  border: 1px solid var(--hofs-line);
}
.hofs-doc__title {
  flex: 1;
  min-width: 0;
}
/* H-2: doc-list-item.php emits .hofs-doc__name (the document title) and
   .hofs-doc__meta (the secondary line) — NOT `b`/`span`. Title is primary
   ink/bold; meta is secondary (H-4: --contrast-2, was the failing --contrast-3). */
.hofs-doc__name {
  display: block;
  font-size: calc(.95rem * var(--hofs-font-scale));
  color: var(--contrast);
  font-weight: 600;
}
.hofs-doc__meta {
  display: block;
  font-size: calc(.8rem * var(--hofs-font-scale));
  color: var(--contrast-2);
}
.hofs-doc__tag {
  font-family: var(--hofs-font-body);
  font-size: calc(.68rem * var(--hofs-font-scale));
  letter-spacing: .04em;
  color: var(--contrast-2);
  border: 1px solid var(--hofs-border-strong);
  padding: 2px 7px;
  border-radius: var(--hofs-radius-pill);
  white-space: nowrap;
}
.hofs-doc__ext {
  color: var(--hofs-brand-text);
  font-weight: 700;
}

/* H-3 — below 480px the fixed 34px icon + non-shrinking tag can squeeze the
   title flex item to ~0 (one glyph per line, ~1000px row height). Wrap the title
   to its own full-width line so it reads as a normal stacked row — BUT only for
   rows that actually carry an icon or tag (the squeeze case). A SIMPLE row (just
   a title + the trailing ↗ affordance — e.g. the Service-resources links) has
   nothing squeezing the title; forcing it full-width there only orphans the ↗
   onto its own line. Scope the full-width title to icon/tag rows so simple rows
   keep the title + right-aligned ↗ on one line, matching desktop. */
@media (max-width: 480px) {
  .hofs-doc {
    flex-wrap: wrap;
  }
  .hofs-doc:has( .hofs-doc__icon, .hofs-doc__tag ) .hofs-doc__title {
    flex-basis: 100%;
  }
  .hofs-doc__tag {
    white-space: normal;
  }
}

/* --- Document row, multi-action variant (§H doc-list block) ----------------
   A row that carries N action pills instead of being one link. Same bordered
   card as .hofs-doc, but it stacks (title/meta block, then a wrapping row of
   pills) and is a static <div>, so it drops the whole-row link hover. */
.hofs-doc--actions {
  flex-direction: column;
  align-items: stretch;
  gap: var(--hofs-space-3);
}
.hofs-doc--actions:hover {
  background: var(--base-3);
}
.hofs-doc__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hofs-space-2);
  margin-top: var(--hofs-space-1);
}
.hofs-doc__action {
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-2);
  font-family: var(--hofs-font-body);
  font-size: calc(.82rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1;
  padding: calc(var(--hofs-space-2) + 1px) var(--hofs-space-4);
  color: var(--hofs-brand-text);
  background: transparent;
  border: 1.5px solid var(--hofs-brand-text);
  border-radius: var(--hofs-radius-pill);
  text-decoration: none;
  white-space: nowrap;
}
.hofs-doc__action:hover {
  background: var(--accent);
  color: var(--hofs-on-brand);
  border-color: var(--accent);
}
.hofs-doc__action-ext {
  font-size: calc(.66rem * var(--hofs-font-scale));
  font-weight: 700;
  letter-spacing: .04em;
  opacity: .75;
}

/* --- Filter chip row (§D News category chips; reusable) — a segmented control ---
   A rounded track holding pill links; the active chip is teal-filled (matching
   .hofs-btn--primary). Distinct from .hofs-tabs — this navigates (real
   links), tabs swap panels. Wraps on narrow screens. */
.hofs-filter {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 0 0 var(--hofs-space-6);
  padding: 3px;
  background: var(--base-3);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-pill);
}
.hofs-filter__link {
  padding: var(--hofs-space-2) var(--hofs-space-4);
  border-radius: var(--hofs-radius-pill);
  font-size: calc(.9rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1;
  color: var(--contrast-2);
  text-decoration: none;
}
.hofs-filter__link:hover {
  color: var(--hofs-brand-text);
}
.hofs-filter__link.is-active {
  background: var(--accent);
  color: var(--hofs-on-brand);
}

/* --- Events agenda ----------------------------------------------------------
   Events are time-bound notices, so the list reads as an agenda rather than a
   generic card collection. The calendar block is the single strong visual
   gesture; everything else stays quiet and information-led. */
.hofs-eventlist {
  border-top: 1px solid var(--hofs-line);
}
.hofs-event-row {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr);
  gap: clamp(var(--hofs-space-4), 3vw, var(--hofs-space-6));
  padding: var(--hofs-space-5) var(--hofs-space-3);
  border-bottom: 1px solid var(--hofs-line);
  transition: background-color .18s ease;
}
.hofs-event-row:hover {
  background: var(--base);
}
.hofs-event-date {
  align-self: start;
  display: grid;
  justify-items: center;
  min-width: 4.75rem;
  overflow: hidden;
  color: var(--hofs-on-brand);
  background: var(--accent);
  border-radius: var(--hofs-radius-sm);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--hofs-on-brand) 22%, transparent);
}
.hofs-event-date__month {
  width: 100%;
  padding: .35rem .4rem .28rem;
  text-align: center;
  font-size: calc(.72rem * var(--hofs-font-scale));
  font-weight: 800;
  letter-spacing: .08em;
  line-height: 1;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--contrast) 16%, transparent);
}
.hofs-event-date__day {
  padding-top: .28rem;
  font-family: var(--hofs-font-display);
  font-size: calc(2rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1;
}
.hofs-event-date__weekday {
  padding: .15rem .4rem .45rem;
  font-size: calc(.72rem * var(--hofs-font-scale));
  font-weight: 700;
}
.hofs-event-row__body {
  min-width: 0;
}
.hofs-event-row__labels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .75rem;
  margin-bottom: var(--hofs-space-2);
  color: var(--contrast-2);
  font-size: calc(.78rem * var(--hofs-font-scale));
  font-weight: 650;
}
.hofs-event-row__scope {
  padding: .22rem .55rem;
  color: var(--hofs-brand-text);
  background: var(--base);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-pill);
}
.hofs-event-row--nearby .hofs-event-row__scope {
  color: var(--hofs-on-accent);
  background: var(--accent-2);
  border-color: transparent;
}
.hofs-event-row__title {
  margin: 0;
  font-family: var(--hofs-font-display);
  font-size: calc(clamp(1.2rem, 2.2vw, 1.55rem) * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1.18;
}
.hofs-event-row__title a {
  color: var(--contrast);
  text-decoration-color: transparent;
  text-decoration-thickness: .08em;
  text-underline-offset: .16em;
}
.hofs-event-row__title a:hover {
  color: var(--hofs-brand-text);
  text-decoration-color: currentColor;
}
.hofs-event-row__schedule {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem calc(1.5rem + 1px);
  overflow: hidden;
  /* Room for the first glyph's anti-aliasing, which overflow would otherwise clip. */
  margin: var(--hofs-space-2) 0 0 -.25rem;
  padding-left: .25rem;
  color: var(--contrast-2);
  font-size: calc(.88rem * var(--hofs-font-scale));
  font-weight: 600;
}
.hofs-event-row__schedule > * {
  position: relative;
  min-width: 0;
  overflow-wrap: anywhere; /* a long venue name wraps instead of being clipped: see .hofs-sidebar__row b */
}
/* The divider sits in the column gap, so an item that wraps to a line start puts it outside the clipped container. */
.hofs-event-row__schedule > * + *::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-.75rem - 1px);
  border-left: 1px solid var(--hofs-border-strong);
}
.hofs-event-row__summary {
  max-width: 62ch;
  margin: var(--hofs-space-3) 0 0;
  color: var(--contrast-2);
  font-size: calc(.94rem * var(--hofs-font-scale));
  line-height: 1.55;
}
.hofs-event-row__link,
.hofs-event-back {
  display: inline-block;
  margin-top: var(--hofs-space-3);
  color: var(--hofs-brand-text);
  font-size: calc(.88rem * var(--hofs-font-scale));
  font-weight: 700;
  text-underline-offset: .2em;
}
.hofs-event-back {
  margin: 0 0 var(--hofs-space-5);
}

/* --- Event detail ---------------------------------------------------------- */
.hofs-event-detail__header {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  align-items: start;
  gap: clamp(var(--hofs-space-5), 4vw, var(--hofs-space-7));
  padding-bottom: var(--hofs-space-6);
  border-bottom: 1px solid var(--hofs-line);
}
.hofs-event-date--large {
  min-width: 7rem;
}
.hofs-event-date--large .hofs-event-date__month {
  padding-block: .5rem .42rem;
  font-size: calc(.82rem * var(--hofs-font-scale));
}
.hofs-event-date--large .hofs-event-date__day {
  font-size: calc(3.15rem * var(--hofs-font-scale));
}
.hofs-event-date--large .hofs-event-date__weekday {
  padding-bottom: .65rem;
  font-size: calc(.82rem * var(--hofs-font-scale));
}
.hofs-event-detail__header h1 {
  max-width: 19ch;
  margin: 0;
  color: var(--contrast);
  font-family: var(--hofs-font-display);
  font-size: calc(clamp(2rem, 5vw, 3.5rem) * var(--hofs-font-scale));
  font-weight: 500;
  letter-spacing: -.025em;
  line-height: 1.04;
}
.hofs-event-detail__lead {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem calc(1.6rem + 1px);
  overflow: hidden;
  margin: var(--hofs-space-4) 0 0 -.25rem;
  padding-left: .25rem;
  color: var(--contrast-2);
  font-size: calc(1rem * var(--hofs-font-scale));
  font-weight: 650;
}
.hofs-event-detail__lead > * {
  position: relative;
  min-width: 0;
  overflow-wrap: anywhere; /* as .hofs-event-row__schedule > * */
}
/* Wrapped items put the divider outside the clipped gutter, as agenda rows do. */
.hofs-event-detail__lead > * + *::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-.8rem - 1px);
  border-left: 1px solid var(--hofs-border-strong);
}
.hofs-event-detail__layout {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(15rem, .75fr);
  gap: clamp(var(--hofs-space-6), 5vw, var(--hofs-space-8));
  padding-top: var(--hofs-space-7);
}
.hofs-event-detail__content {
  max-width: 66ch;
  font-size: calc(1.04rem * var(--hofs-font-scale));
  line-height: 1.7;
}
.hofs-event-detail__content > :first-child {
  margin-top: 0;
}
.hofs-event-detail__facts {
  align-self: start;
  padding-left: var(--hofs-space-5);
  border-left: 3px solid var(--accent);
}
.hofs-event-detail__facts h2 {
  margin: 0 0 var(--hofs-space-4);
  font-size: calc(1.2rem * var(--hofs-font-scale));
}
.hofs-event-detail__facts dl {
  margin: 0;
}
.hofs-event-detail__facts dl > div {
  padding: var(--hofs-space-3) 0;
  border-top: 1px solid var(--hofs-line);
}
.hofs-event-detail__facts dt {
  color: var(--contrast-2);
  font-size: calc(.76rem * var(--hofs-font-scale));
  font-weight: 700;
}
.hofs-event-detail__facts dd {
  margin: .18rem 0 0;
  color: var(--contrast);
  font-size: calc(.92rem * var(--hofs-font-scale));
  line-height: 1.45;
}
.hofs-event-detail__calendar {
  display: grid;
  gap: var(--hofs-space-2);
  margin-top: var(--hofs-space-4);
}
.hofs-event-detail__calendar a {
  color: var(--hofs-brand-text);
  font-size: calc(.86rem * var(--hofs-font-scale));
  font-weight: 700;
  text-underline-offset: .2em;
}

@media (max-width: 680px) {
  .hofs-filter {
    display: flex;
    border-radius: var(--hofs-radius);
  }
  .hofs-event-row {
    grid-template-columns: 4.25rem minmax(0, 1fr);
    gap: var(--hofs-space-4);
    padding-inline: 0;
  }
  .hofs-event-date {
    min-width: 4.25rem;
  }
  .hofs-event-row__schedule {
    display: grid;
  }
  .hofs-event-detail__header {
    grid-template-columns: minmax(0, 1fr); /* keeps the zero minimum of the wide layout: see .hofs-split */
    gap: var(--hofs-space-4);
  }
  .hofs-event-date--large {
    width: 4.5rem;
    min-width: 4.5rem;
  }
  .hofs-event-date--large .hofs-event-date__day {
    font-size: calc(2.2rem * var(--hofs-font-scale));
  }
  .hofs-event-detail__layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .hofs-event-detail__facts {
    padding-left: 0;
    padding-top: var(--hofs-space-5);
    border-left: 0;
    border-top: 3px solid var(--accent);
  }
}

/* News titles can point directly to their source; mark that destination without
   making the external-link cue compete with the headline. */
.hofs-news__external-marker {
  display: inline-block;
  margin-inline-start: .35em;
  color: var(--hofs-brand-text);
  font-size: .6em;
  vertical-align: .25em;
}

/* --- News archive + singles ----------------------------------------------
   Keep native GeneratePress post markup, but give News the same deliberate
   surface language as the data-driven archives: readable cards in the index and
   a quieter reading surface on a single post. */
.hofs-news-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* a URL in an excerpt wraps: see .hofs-split */
  gap: var(--hofs-space-5);
}
.hofs-news-list > .navigation.pagination {
  grid-column: 1 / -1;
}
.hofs-news-index .inside-article {
  height: 100%;
  padding: var(--hofs-space-6);
  border: 1px solid var(--hofs-card-border, var(--hofs-line));
  border-radius: var(--hofs-radius);
  background: var(--base-3);
  box-shadow: var(--hofs-shadow-md);
  transition: box-shadow .2s ease, transform .2s ease, border-color .2s ease;
}
.hofs-news-index .inside-article:hover {
  border-color: var(--hofs-border-strong);
  box-shadow: var(--hofs-shadow-lg);
  transform: translateY(-2px);
}
.hofs-news-index .entry-header {
  margin-bottom: var(--hofs-space-3);
}
.hofs-news-index .entry-title {
  margin-bottom: var(--hofs-space-2);
  font-size: clamp(1.35rem, 2.2vw, 1.8rem);
  line-height: 1.12;
  text-wrap: balance;
}
.hofs-news-index .entry-meta {
  margin: 0;
  font-size: calc(.82rem * var(--hofs-font-scale));
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.hofs-news-index .entry-summary,
.hofs-news-index .entry-content {
  color: var(--contrast-2);
  line-height: 1.65;
}
.hofs-news-index .entry-summary > :last-child,
.hofs-news-index .entry-content > :last-child {
  margin-bottom: 0;
}
.hofs-news-single .inside-article {
  padding: clamp(1.5rem, 4vw, 3.5rem);
  border-top: 4px solid var(--accent);
  border-radius: var(--hofs-radius);
  background: var(--base-3);
  box-shadow: var(--hofs-shadow-md);
}
.hofs-news-single .entry-title {
  max-width: 18ch;
  margin-bottom: var(--hofs-space-3);
  font-size: clamp(2rem, 5vw, 3.4rem);
  line-height: 1.05;
  text-wrap: balance;
}
.hofs-news-single .entry-meta {
  color: var(--hofs-brand-text);
  font-size: calc(.82rem * var(--hofs-font-scale));
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.hofs-news-single .entry-content {
  max-width: 68ch;
  margin-top: var(--hofs-space-7);
  color: var(--contrast);
  font-size: calc(1.05rem * var(--hofs-font-scale));
  line-height: 1.75;
}
@media (min-width: 760px) {
  .hofs-news-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (prefers-reduced-motion: reduce) {
  .hofs-news-index .inside-article {
    transition: none;
  }
  .hofs-news-index .inside-article:hover {
    transform: none;
  }
}

/* ==========================================================================
   L4 — A11y utilities + nav embellishments
   ========================================================================== */

/* --- Skip link (helpers.php: .hofs-skip-link.screen-reader-text -> #main).
   Hidden state comes from GP's .screen-reader-text; this fully defines the
   :focus reveal, token-driven and self-contained. safe-area-aware. --------- */
.hofs-skip-link:focus {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + var(--hofs-space-3));
  left: calc(env(safe-area-inset-left, 0px) + var(--hofs-space-3));
  z-index: 100000;
  width: auto;
  height: auto;
  clip: auto;
  clip-path: none;
  padding: var(--hofs-space-3) var(--hofs-space-5);
  background: var(--accent);
  color: var(--hofs-on-brand);
  border-radius: var(--hofs-radius-pill);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  text-decoration: none;
  box-shadow: var(--hofs-shadow-lg);
}

/* --- Visually-hidden utility (theme's own; GP also ships .screen-reader-text) */
.hofs-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- Utility-controls wrapper (site-controls.php, in generate_menu_bar_items) */
.hofs-site-controls {
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-3);
}

/* --- Font-size control (helpers.php markup) — segmented A- / A / A+ -------- */
.hofs-font-size {
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-2);
}
/* Pill group (design-language §6): three rounded pills; teal-fill on hover.
   Each button is a UNIFORM box (fixed width/height, glyph centered) so the three
   pills form one clean, aligned row. The graduated glyph below still previews the
   step (A− smaller … A+ larger), but the BUTTON no longer sizes to its glyph —
   that is what made them mismatched sizes and stair-stepped (worst on mobile).
   And the control is chrome: its size is FIXED and does not track
   --hofs-font-scale, so it stays put as the reader bumps the text size. */
.hofs-font-size__btn {
  appearance: none;
  cursor: pointer;
  font-family: var(--hofs-font-body);
  font-weight: 700;
  color: var(--contrast-2);
  background: var(--base-3);
  border: 1px solid var(--hofs-border-strong);
  border-radius: var(--hofs-radius-pill);
  width: 44px;
  height: 36px;
  padding: 0;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
}
.hofs-font-size__btn:hover {
  color: var(--hofs-on-brand);
  background: var(--accent);
  border-color: var(--accent);
}
.hofs-font-size__btn[data-hofs-font-size="decrease"] {
  font-size: .82rem;
}
.hofs-font-size__btn[data-hofs-font-size="reset"] {
  font-size: 1rem;
}
.hofs-font-size__btn[data-hofs-font-size="increase"] {
  font-size: 1.18rem;
}

/* ==========================================================================
   L5 — Motion
   --------------------------------------------------------------------------
   Transitions on the interactive surfaces only; killed under reduced-motion
   (playground L221-222 pattern). Scoped to our own classes + the GP chrome we
   restyle, so no !important and no specificity war.
   ========================================================================== */
/* No `scroll-behavior: smooth` on <html>: it also animates the load-time
   #fragment scroll (/contact/?route=…#send-message), and WebKit abandons that
   animation where it stands when anything above the target re-lays out (the
   nav's "•••" re-fold once web fonts load, for one), stranding the visitor
   ~2000px short of the form. Anchor jumps use the browser's instant default. */
.hofs-btn,
.hofs-card,
.hofs-event-card,
.hofs-doc,
.hofs-tab,
.hofs-chip,
.hofs-card__chip,
.hofs-section__more,
.hofs-sidebar__vacancy a,
.hofs-font-size__btn,
.hofs-filter__link,
.button,
button.button,
input[type="submit"],
.wp-block-button__link,
.wp-element-button {
  transition:
    background-color .25s ease,
    color .25s ease,
    border-color .25s ease,
    box-shadow .25s ease;
}

@media (prefers-reduced-motion: reduce) {
  .hofs-btn,
  .hofs-card,
  .hofs-event-card,
  .hofs-doc,
  .hofs-tab,
  .hofs-chip,
  .hofs-card__chip,
  .hofs-section__more,
  .hofs-sidebar__vacancy a,
  .hofs-font-size__btn,
  .hofs-filter__link,
  .hofs-skip-link:focus,
  .button,
  button.button,
  input[type="submit"],
  .wp-block-button__link,
  .wp-element-button {
    transition: none;
  }
}

/* ==========================================================================
   L4 — Homepage (Wave 4): pathway hero, content panels, callout row
   Parity target: maineaa.ericbigelow.me — warm ground, white rounded cards,
   a full-bleed photo hero with anchored entry buttons. Tones per the L3 map
   (bg→--base-2 · surface→--base-3 · soft→--base · brand→--accent).
   ========================================================================== */

/* The static homepage (body.hofs-home-page, inc/generatepress.php) renders
   through GP's page template: the banner (hooked into <main>), then GP's
   article holding the page's blocks in .entry-content.

   The hero breaks out to the viewport edge (100vw); clip any resulting
   horizontal overflow at the page edge. `clip` (not `hidden`) does NOT create a
   scroll container, so GP's sticky header keeps working. Scoped to the home. */
body.hofs-home-page {
  overflow-x: clip;
}

/* GP's article chrome (padding, base-3 fill) is dropped: the Panels are the
   cards. */
body.hofs-home-page .inside-article {
  padding: 0;
  background: none;
}
body.hofs-home-page .entry-content {
  max-width: 60rem; /* ~960px readable column, matching the prototype */
  margin-inline: auto;
  padding: var(--hofs-space-7) var(--hofs-space-5) var(--hofs-space-8);
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-6);
}
/* The Home page's blocks are spaced by the gap alone (core's Columns block,
   for one, brings a bottom margin of its own). */
body.hofs-home-page .entry-content > * {
  margin-block: 0;
}
/* Wide: out to the column's padding edge. GP's own Wide offset assumes its 40px
   article padding, and the overflow clip above would cut it on a phone. Full
   alignment uses GP's viewport breakout unchanged. */
body.hofs-home-page .entry-content > .alignwide {
  margin-inline: calc(-1 * var(--hofs-space-5));
  width: auto;
  max-width: none;
}

/* --- Pathway hero (full-bleed photo + entry buttons) ---------------------- */
.hofs-homehero {
  position: relative;
  left: 50%;
  right: 50%;
  width: 100vw;
  max-width: 100vw;
  margin-left: -50vw;
  margin-right: -50vw;
  min-height: clamp(22rem, 46vw, 34rem);
  margin-bottom: 0; /* GP spaces .site-main's children; the body below has its own padding */
  display: flex;
  align-items: flex-start;
  background-color: var(--base); /* tone shown behind / around the photo */
}
/* The photo covers the band, as a `cover` background would, with its focus
   (inline object-position) kept in frame. */
.hofs-homehero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hofs-homehero--plain {
  /* No photo set: a calm brand band so the buttons still have a ground. The
     brand-gradient token runs brand -> a lighter, hue-rotated brand (engine-derived)
     so the band reads as depth, not the old flat brand -> brand-8%L. */
  background-image: var(--hofs-brand-gradient);
}
/* Left-anchored scrim so the white pills stay legible over a busy photo. */
.hofs-homehero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(18, 30, 35, 0.44) 0%,
    rgba(18, 30, 35, 0.14) 36%,
    rgba(18, 30, 35, 0) 62%
  );
  pointer-events: none;
}
.hofs-homehero--plain .hofs-homehero__scrim {
  display: none;
}
.hofs-homehero__inner {
  position: relative; /* above the scrim */
  width: 100%;
  max-width: 60rem;
  margin-inline: auto;
  padding: var(--hofs-space-6) var(--hofs-space-5);
}

/* --- Pathway buttons ("Home page buttons" menu, inc/home-pathways.php) ----
   The <ul> is the pill column; each pill (an <a>, or a <summary> for an item
   with children) is a block-level flex box, so it fills its <li>. */
.hofs-pathways {
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-3);
  max-width: 22rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.hofs-pathway {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hofs-space-3);
  background: var(--base-3);
  color: var(--contrast);
  text-decoration: none;
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(1rem * var(--hofs-font-scale));
  line-height: 1.25;
  padding: calc(var(--hofs-space-3) + 2px) var(--hofs-space-5);
  border-radius: var(--hofs-radius-pill);
  border: 1px solid transparent;
  box-shadow: var(--hofs-shadow-md);
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}
.hofs-pathway__arrow {
  color: var(--hofs-brand-text);
  transition:
    color 0.2s ease,
    transform 0.2s ease;
}
.hofs-pathway:hover,
.hofs-pathway:focus-visible {
  background: var(--accent);
  color: var(--hofs-on-brand);
}
.hofs-pathway:hover .hofs-pathway__arrow,
.hofs-pathway:focus-visible .hofs-pathway__arrow {
  color: var(--hofs-on-brand);
  transform: translateX(3px);
}
/* The pills sit on the brand band or a photo, where the generic brand-text ring
   is teal on teal. Two tones instead: an on-brand ring with brand-dark filling
   the gap inside it. The engine keeps on-brand at 4.5:1 or more against brand,
   brand-dark and the band's gradient, so the ring stands out from the plain band,
   and on a photo one of the two contrasts with whatever is behind it. */
.hofs-pathway:focus-visible {
  outline-color: var(--hofs-on-brand);
  box-shadow: 0 0 0 2px var(--hofs-brand-dark), var(--hofs-shadow-md);
}
.hofs-pathway--static {
  /* An entry with no destination: a chip, not a dead-end link. */
  cursor: default;
  box-shadow: var(--hofs-shadow-sm);
}
/* An item with children: native <details>; the <summary> is the pill, and its
   chevron (a disclosure cue, not the link arrow) points down, then up while the
   list is open. The list overlays what follows (out of flow, so opening it
   shifts nothing); it spans its pill's width, so it stays inside the pill column
   horizontally at any viewport width. No hero ancestor clips vertically
   (body.hofs-home-page clips the x axis only). */
.hofs-pathway-group {
  position: relative;
}
summary.hofs-pathway {
  list-style: none;
  cursor: pointer;
}
summary.hofs-pathway::-webkit-details-marker {
  display: none;
}
.hofs-pathway__chevron {
  flex: none;
  width: 0.5em;
  height: 0.5em;
  margin: 0 0.15em 0.25em;
  border: solid var(--hofs-brand-text);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  transition:
    border-color 0.2s ease,
    transform 0.2s ease;
}
.hofs-pathway:hover .hofs-pathway__chevron,
.hofs-pathway:focus-visible .hofs-pathway__chevron {
  border-color: var(--hofs-on-brand);
}
.hofs-pathway-group[open] > .hofs-pathway .hofs-pathway__chevron {
  margin-block: 0.25em 0;
  transform: rotate(-135deg);
}
.hofs-pathway-group .sub-menu {
  position: absolute;
  top: calc(100% + var(--hofs-space-2));
  left: 0;
  right: 0;
  z-index: 20;
  list-style: none;
  margin: 0;
  padding: var(--hofs-space-2) 0;
  background: var(--base-3);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-lg);
  box-shadow: var(--hofs-shadow-lg);
}
.hofs-pathway-group .sub-menu a {
  display: block;
  padding: var(--hofs-space-2) var(--hofs-space-5);
  color: var(--contrast);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(0.94rem * var(--hofs-font-scale));
  line-height: 1.3;
  text-decoration: none;
}
.hofs-pathway-group .sub-menu a:hover,
.hofs-pathway-group .sub-menu a:focus-visible {
  background: var(--base);
  color: var(--hofs-brand-text);
}

/* Item 1 — larger, tappier pathway pills on small viewports. */
@media (max-width: 600px) {
  .hofs-pathways {
    gap: var(--hofs-space-4);
  }
  .hofs-pathway {
    font-size: calc(1.0625rem * var(--hofs-font-scale));
    padding: var(--hofs-space-4) var(--hofs-space-5);
  }
  .hofs-pathway__arrow {
    font-size: 1.125rem;
  }
  /* Drop-down links at least 44px tall (WCAG 2.5.5), like the pills above. */
  .hofs-pathway-group .sub-menu a {
    display: flex;
    align-items: center;
    box-sizing: border-box;
    min-height: 44px;
  }
}

/* --- Content panels (intro card carries the <h1>; situational cards) ------
   The "Panel" block style on core/group (inc/block-styles.php): the Group's
   first heading is the title, the blocks after it are the body, and a
   paragraph with the `hofs-panel__more` class is the read-more link. A
   classic theme wraps a Group's blocks in an inner container, so every child
   selector reaches through it when it is there. */
.wp-block-group.is-style-hofs-panel {
  display: flex;
  flex-direction: column;
  background: var(--base-3);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-lg);
  box-shadow: var(--hofs-shadow-sm);
  padding: var(--hofs-space-6);
  /* When a header pathway (#anchor) scrolls to a panel, clear the sticky header +
     give a little breathing room above (§G). */
  scroll-margin-top: var(--hofs-space-7);
}
/* GeneratePress centres a Group's inner container with auto side margins,
   which in the Panel's flex column would shrink a short card's content to its
   own width. */
.wp-block-group.is-style-hofs-panel > .wp-block-group__inner-container {
  margin-inline: 0;
}
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :is(h1, h2, h3, h4, h5, h6):first-child {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight */
  font-size: calc(var(--hofs-text-xl) * var(--hofs-font-scale));
  line-height: 1.12;
  letter-spacing: -0.01em;
  color: var(--contrast);
  margin: 0;
  text-wrap: balance;
}
/* The intro card's heading is the page's <h1> — give it more presence. */
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > h1:first-child {
  font-size: calc(var(--hofs-text-2xl) * var(--hofs-font-scale));
}
/* The body text: every block but the title and the read-more, so the
   read-more keeps the panel's inherited type. */
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :not(:is(h1, h2, h3, h4, h5, h6):first-child, .wp-block-group__inner-container, .hofs-panel__more) {
  color: var(--contrast-2);
  font-size: calc(1rem * var(--hofs-font-scale));
  line-height: 1.6;
}
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :is(h1, h2, h3, h4, h5, h6):first-child + :not(.hofs-panel__more) {
  margin-top: var(--hofs-space-4);
}
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :is(:last-child, :has(+ .hofs-panel__more)) {
  margin-bottom: 0;
}
:is(.is-style-hofs-panel, .is-style-hofs-panel > .wp-block-group__inner-container) > :not(:is(h1, h2, h3, h4, h5, h6):first-child, .wp-block-group__inner-container, .hofs-panel__more) a {
  color: var(--hofs-brand-text);
  font-weight: 600;
}
/* Read-more (§G): a paragraph holding one link → the full page, laid out at
   the panel's trailing edge below the body. The arrow is drawn after the link
   (hidden from screen readers where the alt-text syntax is supported). */
.hofs-panel__more {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--hofs-space-5);
  font-weight: 600;
  color: var(--hofs-brand-text);
  text-decoration: none;
  white-space: nowrap;
}
.hofs-panel__more > a {
  color: inherit; /* the paragraph's brand-text, in the editor canvas too */
  text-decoration: none;
}
.hofs-panel__more > a::after {
  content: " \2192";
  content: " \2192" / "";
  transition: margin-left .15s ease;
}
.hofs-panel__more > a:hover::after {
  margin-left: 3px;
}

/* --- Callout row (3-up warm quick-reference band) -------------------------
   The "Callouts" block style on core/columns, one callout per Column (first
   heading = title, the rest = body). The grid replaces the Columns block's
   flex row. */
.wp-block-columns.is-style-hofs-callouts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: var(--hofs-space-5);
}
.is-style-hofs-callouts > .wp-block-column {
  background: var(--base);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-lg);
  padding: var(--hofs-space-5);
}
.is-style-hofs-callouts > .wp-block-column > :is(h1, h2, h3, h4, h5, h6):first-child {
  font-family: var(--hofs-font-display);
  font-weight: 500; /* syne-500: Eric's heading weight */
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  color: var(--contrast);
  margin: 0 0 var(--hofs-space-3);
}
.is-style-hofs-callouts > .wp-block-column > :not(:is(h1, h2, h3, h4, h5, h6):first-child) {
  color: var(--contrast-2);
  font-size: calc(0.94rem * var(--hofs-font-scale));
  line-height: 1.55;
}
.is-style-hofs-callouts > .wp-block-column > :last-child {
  margin-bottom: 0;
}
.is-style-hofs-callouts > .wp-block-column > :not(:is(h1, h2, h3, h4, h5, h6):first-child) a {
  color: var(--hofs-brand-text);
  font-weight: 600;
}

@media (prefers-reduced-motion: reduce) {
  .hofs-pathway,
  .hofs-pathway__arrow,
  .hofs-pathway__chevron,
  .hofs-panel__more > a::after {
    transition: none;
  }
  .hofs-pathway:hover .hofs-pathway__arrow,
  .hofs-pathway:focus-visible .hofs-pathway__arrow {
    transform: none;
  }
}

/* ==========================================================================
   L6 — Design-language shell + lift  (see .implans/design-language.md §3–4)
   --------------------------------------------------------------------------
   The prototype's signature move: an interior page presents its main content in
   ONE contained, rounded, softly-shadowed gradient panel floating on the light
   ground — the page title lives inside the panel's head, not in a full-bleed
   band. The static homepage keeps its own composition (L4 Homepage above), and a
   "Your latest posts" front page is an interior page here, so every rule here
   is scoped off `body:not(.hofs-home-page)`. Kept as a single trailing layer
   so the language reads (and reverts) in one place.
   ========================================================================== */

:root {
  /* The one texture in the system — white shading into the soft warm tint;
     barely-there depth, not color. Used by the shell (and, later, panels). */
  --hofs-panel-fill: linear-gradient(150deg, var(--base-3) 0%, var(--base) 100%);
}

/* The page-shell panel. `.site-main` is GP's content column; on interior pages
   it becomes the contained panel.

   CENTERING: GP's flexbox sheet (all.min.css) ships
   `.site-main{margin-left:0!important;margin-right:0!important}` — it assumes the
   column fills the content container, so the flex parent handles placement. Our
   shell is a NARROWER contained panel (62rem inside GP's ~75rem container), so we
   must re-assert AUTO side-margins to actually centre it — otherwise it pins left
   (40px gutter left, ~248px right). Physical margins + !important at this rule's
   higher specificity (`body:not(.hofs-home-page) .site-main`) beat GP's physical !important;
   justified exactly like the Events-Manager override (overriding a vendor's own
   !important sheet, not an internal specificity war). */
body:not(.hofs-home-page) .site-main {
  max-width: 62rem;
  margin-left: auto !important;
  margin-right: auto !important;
  background: var(--hofs-panel-fill);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-xl);
  box-shadow: var(--hofs-shadow-lg);
  padding: clamp(1.5rem, 3vw, 2.75rem);
}

/* Inside the shell the hero is the panel's HEAD: drop the full-bleed band's
   background, divider and heavy padding so the title + lede sit cleanly on top. */
body:not(.hofs-home-page) .hofs-hero {
  background: none;
  border-bottom: 0;
  padding: 0 0 var(--hofs-space-5);
}

/* Sections stop adding side gutters (the shell already pads); the vertical
   rhythm and the inter-section hairline stay. */
body:not(.hofs-home-page) .hofs-section {
  padding-inline: 0;
}
body:not(.hofs-home-page) .hofs-section:first-of-type {
  padding-top: var(--hofs-space-3);
}
/* A section inside its block's wrapper is :first-of-type there; when the box
   before the wrapper holds a section, the section is a later one, with the
   hairline (section rhythm, above) and the base top padding. */
body:not(.hofs-home-page) :is(.hofs-section, :has(> .hofs-section):not(.wp-block-column)) + :has(> .hofs-section) > .hofs-section {
  padding-top: var(--hofs-space-7);
}

/* Listing Pages (body class from hofs_is_listing_page()) wear the archive
   shell. The retired archive templates printed their hero and sections
   straight into .site-main; a Page nests its blocks in GP's article > .inside-article >
   .entry-content, which adds padding (40px, 30px on mobile), a solid base-3
   fill and no gap between blocks. Drop the article chrome and give the blocks
   GP's `.site-main > *` 20px rhythm. The body class keeps the specificity above
   GP's inline mobile `.separate-containers .inside-article` padding. */
body.hofs-listing-page .inside-article {
  padding: 0;
  background: none;
}
body.hofs-listing-page .entry-content > * + * {
  margin-top: 20px;
}
body.hofs-listing-page .entry-content > :last-child {
  margin-bottom: 0;
}
/* With no article padding GP's wide/full breakouts would overflow the panel;
   the archive has none, so align blocks to the column. */
body.hofs-listing-page .entry-content .alignwide,
body.hofs-listing-page .entry-content .alignfull {
  margin-left: 0;
  margin-right: 0;
  width: auto;
  max-width: none;
}
/* Adjacent block wrappers that each hold a section get the later-section
   rhythm (base top padding + hairline) on every page (section rhythm and the
   rule after :first-of-type, above), so intro blocks placed by an editor break
   the adjacency exactly as they would between archive sections. On a listing
   page a data block wrapped in a Group or Columns also counts at the top
   level. */
body.hofs-listing-page .entry-content > :has(.hofs-section) + :has(> .hofs-section) > .hofs-section,
body.hofs-listing-page .entry-content > :has(.hofs-section) + :is(.wp-block-group, .wp-block-columns) .hofs-section {
  padding-top: var(--hofs-space-7);
  border-top: 1px solid var(--hofs-line);
}
/* A data block that prints several sections (Events and Assemblies: upcoming,
   then past) or sidebar cards (the officers roster's groups) holds them as
   siblings inside its own wrapper, out of reach of GP's `.site-main > *` 20px
   bottom margin that spaced them when the retired templates printed them
   straight into .site-main. Keep that gap. */
body.hofs-listing-page .entry-content .hofs-section + .hofs-section,
body.hofs-listing-page .entry-content .hofs-sidebar + .hofs-sidebar {
  margin-top: 20px;
}
/* A section right after a block of sidebar cards (Contact's form after the
   officers roster) had the base section padding with no hairline in the
   retired template, where the section wasn't :first-of-type. */
body.hofs-listing-page .entry-content :has(> .hofs-sidebar) + :has(> .hofs-section) > .hofs-section:first-child {
  padding-top: var(--hofs-space-7);
}
/* An intro above a data block keeps the archive's intro spacing: its own top
   margin over the 20px block rhythm, the same gap below it, the full section
   padding on the data block that follows (the archive's intro breaks
   :first-of-type), and, for an intro wrapped in .hofs-view-intro (the
   blueprints' intro, hofs_page_blueprint()), its own link underline over
   the .entry-content link rule. An intro written in the editor
   as paragraphs or a list gets the same spacing. */
body.hofs-listing-page .entry-content > .hofs-view-intro,
body.hofs-listing-page .entry-content > .wp-block-acf-hofs-page-hero + :is(p, ul, ol),
body.hofs-listing-page .entry-content > :is(p, ul, ol) + :has(.hofs-section) {
  margin-top: var(--hofs-space-6);
}
body.hofs-listing-page .entry-content > :is(.hofs-view-intro, p, ul, ol) + :has(.hofs-section) .hofs-section {
  padding-top: var(--hofs-space-7);
}
/* The CTA hero's body links keep their own underline too (the retired Getting
   Involved template printed the card outside .entry-content). Both selectors
   repeat the body-link rule's :not() guards so they outrank it. */
body.hofs-listing-page .entry-content > .hofs-view-intro a:not(.button):not(.hofs-btn):not(.wp-element-button):not(.wp-block-button__link):not(.hofs-doc):not(.hofs-doc__action),
body.hofs-listing-page .entry-content .hofs-cta-hero__body a:not(.button):not(.hofs-btn):not(.wp-element-button):not(.wp-block-button__link):not(.hofs-doc):not(.hofs-doc__action) {
  text-underline-offset: 2px;
  text-decoration-thickness: auto;
}

/* Gentle lift (design-language §3): cards float at rest and rise 2px on hover,
   shadow blooming sm-tier → lg-tier. Overrides the L3 rest/hover shadows by
   source order; adds `transform` to the eased properties. */
.hofs-card,
.hofs-event-card {
  box-shadow: var(--hofs-shadow-md);
  transition:
    background-color .2s ease,
    color .2s ease,
    border-color .2s ease,
    box-shadow .2s ease,
    transform .2s ease;
}
.hofs-card:hover,
.hofs-event-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--hofs-shadow-lg);
}
@media (prefers-reduced-motion: reduce) {
  .hofs-card,
  .hofs-event-card {
    transition: none;
  }
  .hofs-card:hover,
  .hofs-event-card:hover {
    transform: none;
  }
}

/* --- Footer band (design-language §6; inc/footer.php + site-footer.php) -------
   Sits on GP's .site-footer ground (--base-3, set in L2) above GP's copyright
   rule. Warm-greige top hairline, columns of resource + contact links, circular
   social chips (the Social links menu, a <ul>), a hotline. Columns auto-fit and
   collapse to one on narrow. */
/* The footer sits outside GP's .site-content, so it doesn't inherit GP's
   break-word: give a long link label (an email, a URL) the same wrapping. */
.hofs-footer {
  border-top: 1px solid var(--hofs-line);
  padding: var(--hofs-space-7) var(--hofs-space-5) var(--hofs-space-6);
  overflow-wrap: break-word;
}
.hofs-footer__inner {
  max-width: 70rem;
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: var(--hofs-space-6);
}
.hofs-footer__heading {
  font-family: var(--hofs-font-body);
  font-size: calc(.78rem * var(--hofs-font-scale));
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--contrast-2);
  margin: 0 0 var(--hofs-space-4);
}
.hofs-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-3);
}
.hofs-footer__list a,
.hofs-footer__hotline a {
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-size: calc(.95rem * var(--hofs-font-scale));
}
.hofs-footer__list a:hover,
.hofs-footer__hotline a:hover {
  text-decoration: underline;
}
.hofs-footer__social {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--hofs-space-4);
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--hofs-space-3);
}
.hofs-footer__chip {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--hofs-radius-pill);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--hofs-line);
  background: var(--base-3);
  color: var(--contrast-2);
  transition:
    color .2s ease,
    border-color .2s ease,
    background-color .2s ease,
    transform .2s ease;
}
.hofs-footer__chip:hover {
  color: var(--hofs-brand-text);
  border-color: var(--accent);
  transform: translateY(-2px);
}
.hofs-footer__chip svg {
  width: 1.05rem;
  height: 1.05rem;
  fill: currentColor;
}
.hofs-footer__hotline {
  margin: 0;
  font-size: calc(.95rem * var(--hofs-font-scale));
  color: var(--contrast-2);
  line-height: 1.5;
}
.hofs-footer__hotline-label {
  display: block;
  font-weight: 600;
  color: var(--contrast);
}
@media (prefers-reduced-motion: reduce) {
  .hofs-footer__chip {
    transition: none;
  }
  .hofs-footer__chip:hover {
    transform: none;
  }
}

/* --- Schedule table (meeting-blocks.php: hofs_render_committee_schedule) --
   Each committee's standing meetings and how to attend, data-driven. Scrolls
   inside its own container on narrow so the shell/page never scrolls sideways. */
/* Positioned so any absolutely positioned .screen-reader-text span is clipped
   by this scroller instead of widening the page on narrow screens. */
.hofs-schedule {
  position: relative;
  overflow-x: auto;
}
.hofs-schedule__table {
  width: 100%;
  border-collapse: collapse;
  font-size: calc(0.92rem * var(--hofs-font-scale));
}
.hofs-schedule__table th,
.hofs-schedule__table td {
  text-align: left;
  padding: var(--hofs-space-3) var(--hofs-space-4);
  border-bottom: 1px solid var(--hofs-line);
  vertical-align: baseline;
}
.hofs-schedule__table thead th {
  font-family: var(--hofs-font-body);
  font-size: calc(0.72rem * var(--hofs-font-scale));
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--contrast-2);
  border-bottom: 1.5px solid var(--hofs-border-strong);
  white-space: nowrap;
}
.hofs-schedule__table tbody th {
  font-weight: 600;
  color: var(--contrast);
}
.hofs-schedule__table tbody th a {
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-weight: 600;
}
.hofs-schedule__table tbody th a:hover {
  text-decoration: underline;
}
.hofs-schedule__table td {
  color: var(--contrast-2);
}
.hofs-schedule__table tbody tr:last-child th,
.hofs-schedule__table tbody tr:last-child td {
  border-bottom: 0;
}

/* --- Committee detail: nav rail + main + stat-cards (single-hofs_committee.php) ----
   Committee-detail parity: a left committee-nav to switch committees, the key
   facts promoted to bordered stat-cards up top. Single column on narrow. */
.hofs-committee {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* see .hofs-split */
  grid-template-areas:
    "main"
    "nav";
  gap: var(--hofs-space-6);
}
.hofs-committee__main {
  grid-area: main;
}
.hofs-committee__nav {
  grid-area: nav;
}
@media (min-width: 860px) {
  .hofs-committee {
    grid-template-columns: 15rem minmax(0, 1fr);
    grid-template-areas: "nav main";
  }
  /* The nav sticks while the (often long) main column scrolls. */
  .hofs-committee__nav {
    position: sticky;
    top: var(--hofs-space-5);
    align-self: start;
  }
}
.hofs-committee__cta {
  margin-top: var(--hofs-space-6);
}

/* Committee side-nav — disclosure on narrow viewports, plain list at >=860px.
   Below 860px the <details> stays collapsed by default so this committee's own
   tabs lead the mobile stack; at desktop widths the list shows and the
   <summary> reads as the rail's plain title, so the rail behaves as the
   always-open sidebar it always was. Progressive enhancement: works without JS. */
.hofs-cnav__title {
  font-family: var(--hofs-font-display);
  font-weight: 500;
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  margin: 0;
  color: var(--contrast);
}
.hofs-cnav__summary {
  cursor: pointer;
  list-style: none;                    /* drop the UA disclosure triangle */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--hofs-space-3);
  padding: var(--hofs-space-3) var(--hofs-space-4);
  border: 1px solid var(--contrast-3);
  border-radius: var(--hofs-radius-sm);
  background: var(--base-2);
  color: var(--contrast);
}
.hofs-cnav__summary::-webkit-details-marker { display: none; }
.hofs-cnav__summary::after {
  content: "";
  width: 0.5em;
  height: 0.5em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-0.15em);
  transition: transform 150ms ease;
  flex: 0 0 auto;
}
.hofs-cnav__disclosure[open] > .hofs-cnav__summary::after {
  transform: rotate(-135deg) translateY(0.15em);
}
.hofs-cnav__disclosure[open] > .hofs-cnav__summary {
  margin-bottom: var(--hofs-space-3);
}
/* Desktop: the summary is the plain title and theme.js sets the <details>
   `open` (see the roster disclosure above); the pseudo-element rule shows the
   list from first paint and without JS. */
@media (min-width: 860px) {
  .hofs-cnav__disclosure::details-content { content-visibility: visible; }
  .hofs-cnav .hofs-cnav__disclosure > .hofs-cnav__summary {
    display: block;
    margin-bottom: var(--hofs-space-4);
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    cursor: default;
  }
  .hofs-cnav .hofs-cnav__summary::after { content: none; }
}
.hofs-cnav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-2);
}
.hofs-cnav__link {
  display: block;
  padding: calc(var(--hofs-space-2) + 1px) var(--hofs-space-4);
  border-radius: var(--hofs-radius);
  border: 1px solid transparent;
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-weight: 600;
  font-size: calc(0.92rem * var(--hofs-font-scale));
  line-height: 1.3;
  transition:
    background-color 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease;
}
.hofs-cnav__link:hover {
  background: var(--base);
  border-color: var(--hofs-line);
}
.hofs-cnav__link.is-active {
  background: var(--base);
  border-color: var(--hofs-line);
  color: var(--contrast);
  box-shadow: var(--hofs-shadow-sm);
}
.hofs-cnav__link.is-muted {
  color: var(--contrast-2);
}

/* Stat cards — prominent key facts */
.hofs-statgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: var(--hofs-space-4);
  margin-bottom: var(--hofs-space-6);
}
.hofs-stat {
  background: var(--base-3);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius);
  box-shadow: var(--hofs-shadow-sm);
  padding: var(--hofs-space-4) var(--hofs-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-2);
}
.hofs-stat__label {
  font-family: var(--hofs-font-body);
  font-size: calc(0.72rem * var(--hofs-font-scale));
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--contrast-2);
}
.hofs-stat__value {
  font-size: calc(1rem * var(--hofs-font-scale));
  color: var(--contrast);
  font-weight: 600;
  line-height: 1.35;
}
.hofs-stat__value a {
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-weight: 600;
}
.hofs-stat__value a:hover {
  text-decoration: underline;
}
.hofs-stat__link {
  font-size: calc(0.85rem * var(--hofs-font-scale));
  color: var(--hofs-brand-text);
  text-decoration: none;
  font-weight: 600;
}
.hofs-stat__link:hover {
  text-decoration: underline;
}
@media (prefers-reduced-motion: reduce) {
  .hofs-cnav__link {
    transition: none;
  }
}

/* Committee tabs — Meeting + Get Involved panels (single-hofs_committee.php) --------
   Rendered inside .hofs-tabpanel via the tabs component, which already sets
   the panel colour + line-height; these style the tab-specific blocks. */
.hofs-meeting__facts {
  display: grid;
  gap: var(--hofs-space-3);
  margin: 0 0 var(--hofs-space-5);
}
.hofs-meeting__facts > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hofs-space-1) var(--hofs-space-4);
}
.hofs-meeting__facts dt {
  min-width: 7rem;
  padding-top: 0.15em;
  font-family: var(--hofs-font-body);
  font-size: calc(0.72rem * var(--hofs-font-scale));
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--contrast-2);
}
.hofs-meeting__facts dd {
  min-width: 0;
  overflow-wrap: anywhere; /* a value cell: see .hofs-sidebar__row b */
  margin: 0;
  color: var(--contrast);
  font-weight: 600;
}
.hofs-join__notes {
  font-weight: 500;
  color: var(--contrast-2);
}
.hofs-getinvolved__lede {
  margin: 0 0 var(--hofs-space-3);
  color: var(--contrast);
  font-weight: 600;
}
.hofs-getinvolved__opening {
  margin: 0 0 var(--hofs-space-3);
  color: var(--hofs-brand-text);
  font-weight: 600;
}
.hofs-getinvolved__openings {
  list-style: none;
  margin: 0 0 var(--hofs-space-4);
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* a long note wraps: see .hofs-split */
  gap: var(--hofs-space-2);
}
.hofs-getinvolved__openings li {
  padding: var(--hofs-space-3) var(--hofs-space-4);
  border-radius: var(--hofs-radius-sm);
  background: var(--base-3);
  border: 1px dashed var(--hofs-border-strong);
}
.hofs-getinvolved__role {
  font-weight: 600;
  color: var(--contrast);
}
.hofs-getinvolved__note {
  color: var(--contrast-2);
  font-size: calc(.9rem * var(--hofs-font-scale));
}
.hofs-getinvolved__contact {
  margin: 0 0 var(--hofs-space-4);
}

/* --- Wordmark: two-line brand (name + kicker) — design-language §6 ------------
   GP stacks the site title (.main-title) over the tagline (.site-description);
   style the tagline as the prototype's uppercase kicker and
   tighten the title so the two lines read as one mark. The title/kicker STRINGS
   are the WP site name + tagline (content); this only styles them. */
.site-branding .main-title {
  line-height: 1.05;
  letter-spacing: -0.01em;
}
.site-description {
  margin-top: 3px;
  font-family: var(--hofs-font-body);
  font-size: calc(0.72rem * var(--hofs-font-scale));
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--contrast-2);
}

/* --- Painted logo (Site Identity → "Paint the logo in the accent colour") -----
   inc/brand/class-hofs-logo-tint.php wraps GeneratePress's logo image in
   .hofs-logo-tint__paint, whose --hofs-logo-mask is the logo's own
   address. The block is painted in the accent colour and masked by the logo's
   shape (its alpha), so a one-colour logo follows the palette; the image itself
   is kept for its size and is transparent. No motion, so reduced-motion-safe. */
.site-logo.hofs-logo-tint a {
  display: block;
  line-height: 0;
}
.hofs-logo-tint__paint {
  display: inline-block;
  background-color: var(--accent);
  -webkit-mask: var(--hofs-logo-mask) center / contain no-repeat;
  mask: var(--hofs-logo-mask) center / contain no-repeat;
}
.hofs-logo-tint__paint img {
  display: block;
  width: auto;
  height: clamp(2.25rem, 6vw, 2.75rem);
  opacity: 0;
}
.site-branding-container .site-logo.hofs-logo-tint {
  margin-right: var(--hofs-space-3);
}

/* --- Events Manager frontend — brand its default palette ----------------------
   EM ships its own blue links + blue "read more" button + green accent bar, and
   colors them with `!important` from its own frontend sheet (events-manager.css,
   e.g. `.em-item-title a{color:var(--default-color)!important}`). theme.css loads
   AFTER that sheet, so matching `!important` at equal specificity wins — the one
   sanctioned use of `!important` here: overriding a third-party plugin's own
   !important frontend styles. Scoped strictly to EM's `.em-item*` classes. */
.em-item-title,
.em-item-title a {
  font-family: var(--hofs-font-display);
}
.em-event.em-item .em-item-title a,
h3.em-item-title a {
  color: var(--hofs-brand-text) !important;
}
.em-event.em-item .em-item-title a:hover,
h3.em-item-title a:hover {
  color: var(--hofs-brand-dark) !important;
}
.em-item-info {
  border-left-color: var(--accent) !important; /* EM's green accent bar -> teal */
}
.em-item-read-more.button {
  background: transparent !important;
  color: var(--hofs-brand-text) !important;
  border-color: var(--hofs-brand-text) !important;
  border-radius: var(--hofs-radius-pill);
}
.em-item-read-more.button:hover {
  background: var(--accent) !important;
  color: var(--hofs-on-brand) !important;
  border-color: var(--accent) !important;
}

/* --- Events Manager submission form — brand the [em_event_submission_form] -----
   §F. The event-submission shortcode renders EM's full event editor (form.em-
   event-editor), skinned by EM's bundled `pixelbones` micro-framework: Raleway
   body, blue `.button-primary`, thin grey 1px/4px inputs. We do NOT patch the
   plugin's templates (upgrade-safe) — this is the theme-side skin.

   COLOUR is re-tinted at the source: pixelbones derives its whole accent
   (`--accent-color` → links, button-primary bg+border, input focus borders) from
   three HSL component vars. Overriding those on the form re-points EM's own rules
   to our teal with NO specificity war — cleaner and more complete than chasing
   each accent property with !important. A darker L than EM's default (57% → 28%)
   only improves the white-on-accent contrast EM already ships. (A few widgets —
   the selectize option highlight, the flatpickr/timepicker popups — hardcode
   literal blue/coral instead of reading --accent-color; those are overridden
   explicitly further down.)

   SHAPE/TYPE still needs !important, because EM's pixelbones + WP core
   `buttons.min.css` load after theme.css and set radius/font/size with high
   specificity. Those rules are rooted at `.em-event-editor.em.pixelbones` (all
   three classes are on the form element) so they clear pixelbones' own
   `.em.pixelbones …` rules. Everything is scoped to the form; nothing leaks.

   Scope note: we deliberately DON'T touch the TinyMCE toolbar internals
   (`.mce-*`) or the quicktags toolbar (`.ed_button`/`.button-small`) — those are
   recognisable editor chrome and fragile to re-skin; we only frame the editor
   shell. */

/* Colour source-of-truth: re-tint EM's accent HSL to our teal (#0f7d7f ≈
   hsl(181 79% 28%)); pull the whole form onto Manrope (pixelbones forces Raleway
   on the controls, overridden explicitly below; headings already inherit Syne). */
.em-event-editor,
.em-event-editor .em {
  /* EM re-declares --accent-hue AND --font-family on EVERY `.em` element, so
     overriding the form alone leaves nested `.em` wrappers (and the controls in
     them) blue / Raleway — the override has to ride every `.em` in the subtree.
     Re-pointing pixelbones' own vars here re-tints its accent to teal and its
     type to Manrope at the source, with no per-property !important war. */
  --accent-hue: 181;
  --accent-s: 79%;
  --accent-l: 28%;
  --font-family: var(--hofs-font-body);
}
.em-event-editor {
  font-family: var(--hofs-font-body);
}
.em-event-editor label,
.em-event-editor .em-event-text,
.em-event-editor p {
  font-family: var(--hofs-font-body);
}

/* Text-like fields + selects + selectize + textarea → our line, radius, surface,
   Manrope. (Focus border already goes teal via --accent-color; the ring below is
   the extra affordance.) */
.em-event-editor.em.pixelbones :is(
  input[type="text"], input[type="email"], input[type="url"], input[type="tel"],
  input[type="number"], input[type="search"], input[type="password"],
  input[type="date"], select, textarea, .selectize-input):not([data-nostyle]) {
  font-family: var(--hofs-font-body) !important;
  font-size: calc(1rem * var(--hofs-font-scale)) !important;
  color: var(--contrast) !important;
  background-color: var(--base-3) !important;
  border: 1px solid var(--hofs-line) !important;
  border-radius: var(--hofs-radius-sm) !important;
  padding: .55rem .8rem !important;
  box-shadow: none !important;
}
.em-event-editor input::placeholder,
.em-event-editor textarea::placeholder,
.em-event-editor .selectize-input .placeholder {
  color: var(--contrast-2) !important;
  opacity: 1;
}
/* Mouse/keyboard focus → brand border + soft teal ring (the global
   *:focus-visible outline still fires for keyboard, so a11y is unaffected). */
.em-event-editor.em.pixelbones input:focus,
.em-event-editor.em.pixelbones select:focus,
.em-event-editor.em.pixelbones textarea:focus,
.em-event-editor.em.pixelbones .selectize-input.focus {
  border-color: var(--hofs-brand-text) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent) !important;
}

/* Selectize dropdown (open) — Timezone / Country / weekly-days. EM hardcodes
   literal Bootstrap blue on the selected option and grey on the hovered option
   (NOT via --accent-color, so the HSL re-tint can't reach them). The dropdown DOM
   lives inside the form, so a scoped override lands; neither EM rule is
   !important, so this wins on the added .em-event-editor class + load order. */
.em-event-editor .selectize-dropdown .selected {
  background-color: var(--accent) !important;
  color: var(--hofs-on-brand) !important;
}
.em-event-editor .selectize-dropdown .active:not(.selected) {
  background-color: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  color: var(--contrast) !important;
}
.em-event-editor.em.pixelbones .selectize-control.em-selectize .selectize-dropdown {
  background-color: var(--base-3) !important;
}

/* Primary submit → the site's pill CTA. Colour is inherited from --accent-color
   (teal, set above); here we only reshape it (pixelbones renders it 4px/11px/
   uppercase/Raleway). */
.em-event-editor.em.pixelbones input[type="submit"]:not([data-nostyle]),
.em-event-editor.em.pixelbones button.button-primary:not([data-nostyle]),
.em-event-editor.em.pixelbones .button-primary:not([data-nostyle]) {
  border-radius: var(--hofs-radius-pill) !important;
  font-family: var(--hofs-font-body) !important;
  font-weight: 600 !important;
  font-size: calc(.95rem * var(--hofs-font-scale)) !important;
  text-transform: none !important;
  letter-spacing: normal !important;
  padding: .7rem 1.7rem !important;
  height: auto !important;
  line-height: 1.3 !important;
}
/* Secondary actions (Add Time Slot, recurrence add) → teal outline pill. Excludes
   `.button-small` so the HTML-editor quicktags keep their native toolbar sizing. */
.em-event-editor.em.pixelbones .button-secondary:not(.button-small):not([data-nostyle]),
.em-event-editor.em.pixelbones .em-timerange-add:not([data-nostyle]),
.em-event-editor.em.pixelbones .em-add-recurrence-set:not([data-nostyle]) {
  background: transparent !important;
  color: var(--hofs-brand-text) !important;
  border: 1px solid var(--hofs-brand-text) !important;
  border-radius: var(--hofs-radius-pill) !important;
  font-family: var(--hofs-font-body) !important;
  font-weight: 600 !important;
  font-size: calc(.82rem * var(--hofs-font-scale)) !important;
  letter-spacing: .02em !important;
  text-transform: none !important;
  padding: .5rem 1.1rem !important;
}
.em-event-editor.em.pixelbones .button-secondary:not(.button-small):not([data-nostyle]):hover,
.em-event-editor.em.pixelbones .em-timerange-add:not([data-nostyle]):hover,
.em-event-editor.em.pixelbones .em-add-recurrence-set:not([data-nostyle]):hover {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: var(--hofs-on-brand) !important;
}

/* Event Image dropzone (filepond) → recolour its three grey panel layers
   (#f1f0ef) to a warm field; filepond already rounds them 8px. "Browse" → brand.
   (The label text keeps filepond's near-identical muted grey — not worth fighting
   its late-loading sheet for an imperceptible shift.) */
.em-event-editor.em.pixelbones .em-input-upload.input .filepond--panel-root {
  background-color: var(--base-2) !important;
}
.em-event-editor .filepond--drop-label {
  font-family: var(--hofs-font-body) !important;
}
.em-event-editor .filepond--label-action {
  color: var(--hofs-brand-text) !important;
  text-decoration-color: var(--hofs-brand-text) !important;
}

/* Details editor (TinyMCE) → frame the shell as one of our fields; toolbar
   internals stay native. */
.em-event-editor .mce-tinymce.mce-container,
.em-event-editor .wp-editor-container {
  border: 1px solid var(--hofs-line) !important;
  border-radius: var(--hofs-radius-sm) !important;
  box-shadow: none !important;
  overflow: hidden;
}

/* --- Layout: give EM's flat sections real rhythm + grouping ------------------
   Pure CSS over the plugin markup (no template edits). EM stacks every field
   full-width under 36px Syne section headings — too sparse/uneven. We form-scale
   the headings, put short pairs in two columns, tidy the labels, and even out the
   vertical rhythm. */

/* Section headings → form-scale + a delineating rule (the bare <h3> otherwise
   renders at page-title size and crowds the dense fields below it). */
.em-event-editor.em.pixelbones h3 {
  font-size: calc(1.35rem * var(--hofs-font-scale)) !important;
  line-height: 1.25 !important;
  margin: var(--hofs-space-6) 0 var(--hofs-space-4) !important;
  padding-bottom: var(--hofs-space-3) !important;
  border-bottom: 1px solid var(--hofs-line) !important;
}
.em-event-editor.em.pixelbones > .em-event-editor-section:first-child h3 {
  margin-top: var(--hofs-space-3) !important;
}

/* Field labels → consistent tidy form labels above each control. (Scoped to the
   field-wrapper contexts, so the timerange/checkbox toggle labels are untouched.) */
.em-event-editor.em.pixelbones .input > p > label,
.em-event-editor.em.pixelbones .em-input-field > label,
.em-event-editor.em.pixelbones .em-timezone > label,
.em-event-editor.em.pixelbones .em-datepicker > label,
.em-event-editor.em.pixelbones .em-location-data .input > label {
  display: block;
  font-size: calc(.8rem * var(--hofs-font-scale));
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--contrast);
  margin-bottom: .35rem;
}

/* Even vertical rhythm between field groups. */
.em-event-editor.em.pixelbones .em-input-field,
.em-event-editor.em.pixelbones .em-timezone,
.em-event-editor.em.pixelbones .em-datepicker {
  margin-bottom: var(--hofs-space-4);
}
.em-event-editor.em.pixelbones .multi-day-event-info {
  color: var(--contrast-2) !important;
  font-size: calc(.85rem * var(--hofs-font-scale)) !important;
  margin: .4rem 0 var(--hofs-space-4) !important;
}

/* Your Details → two columns (Name | Email). */
.em-event-editor.em.pixelbones .event-form-submitter > .input {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hofs-space-3) var(--hofs-space-5);
}
.em-event-editor.em.pixelbones .event-form-submitter > .input > p {
  margin: 0;
}

/* Where → grid the address fields two-up; name / street / URL stay full-width.
   (Shown only when a physical location is chosen.) */
.em-event-editor.em.pixelbones .em-location-data.input {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--hofs-space-3) var(--hofs-space-5);
}
.em-event-editor.em.pixelbones .em-location-data.input > .em-location-data-name,
.em-event-editor.em.pixelbones .em-location-data.input > .em-location-data-address,
.em-event-editor.em.pixelbones .em-location-data.input > .em-location-data-country,
.em-event-editor.em.pixelbones .em-location-data.input > .em-location-data-url {
  grid-column: 1 / -1;
}
.em-event-editor.em.pixelbones .em-location-data.input > .input {
  margin-bottom: 0;
}

/* Stack the grids on narrow screens. */
@media (max-width: 600px) {
  .em-event-editor.em.pixelbones .event-form-submitter > .input,
  .em-event-editor.em.pixelbones .em-location-data.input {
    grid-template-columns: 1fr;
  }
}

/* --- Date / time picker popups (flatpickr + jQuery timepicker) ---------------
   DELIBERATE scope deviation: both widgets append their popup to <body>, OUTSIDE
   .em-event-editor, so — unlike every other rule in this EM block — these can't
   be form-scoped. The class prefixes (.flatpickr-*, .ui-em_timepicker-*) are
   EM-widget-specific and, on the front end, only the submission form renders a
   date/time input, so a body-level rule is safe in practice. Theme CSS only; no
   plugin edits. */

/* flatpickr date-range calendar — EM themes the selected/range days flatpickr's
   stock coral #ff5a5f; retint the accents to teal (the calendar chrome is already
   a neutral light panel — left as-is). Order matters: the soft-tint rules
   (hover / inRange) come FIRST, the solid selected/range endpoints LAST, so an
   endpoint that also carries .inRange still renders solid teal, not the tint. */
.flatpickr-day:hover,
.flatpickr-day:focus {
  background: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  border-color: color-mix(in srgb, var(--accent) 12%, transparent) !important;
}
.flatpickr-day.inRange {
  background: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  border-color: color-mix(in srgb, var(--accent) 12%, transparent) !important;
  box-shadow: -5px 0 0 color-mix(in srgb, var(--accent) 12%, transparent),
               5px 0 0 color-mix(in srgb, var(--accent) 12%, transparent) !important;
}
.flatpickr-day.today {
  border-color: var(--hofs-brand-text) !important;
}
.flatpickr-day.selected,
.flatpickr-day.startRange,
.flatpickr-day.endRange,
.flatpickr-day.selected:hover,
.flatpickr-day.startRange:hover,
.flatpickr-day.endRange:hover {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: var(--hofs-on-brand) !important;
}

/* jQuery timepicker list — EM colours the selected/hovered rows blue #1980ec;
   retint to teal and warm the panel + ink. */
.ui-em_timepicker-wrapper {
  background: var(--base-3) !important;
  border-color: var(--hofs-line) !important;
}
.ui-em_timepicker-list li {
  color: var(--contrast) !important;
  font-family: var(--hofs-font-body) !important;
}
.ui-em_timepicker-list li:hover,
.ui-em_timepicker-list li.ui-em_timepicker-selected,
.ui-em_timepicker-list li.ui-em_timepicker-selected:hover {
  background: var(--accent) !important;
  color: var(--hofs-on-brand) !important;
}

/* --- Announcement band (inc/announcements.php + theme.js rotator) -------------
   Full-bleed band above the header. Each notice carries its own colour
   (--announce-bg) + an auto-picked legible text colour (--announce-fg). One shows
   at a time; the rotator toggles .is-current. No JS -> only the first shows.
   Reduced motion -> every active notice stacks (no auto-advance). */
.hofs-announce__item {
  display: none;
  background: var(--announce-bg, var(--accent));
  color: var(--announce-fg, #fff);
  padding: var(--hofs-space-3) var(--hofs-space-5);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(0.95rem * var(--hofs-font-scale));
  letter-spacing: 0.02em;
  text-align: center;
  line-height: 1.4;
}
.hofs-announce__item.is-current {
  display: block;
}
.hofs-announce__inner {
  max-width: 70rem;
  margin-inline: auto;
}
.hofs-announce__item a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* The band is full-bleed with 12px of vertical padding, so a 2px-offset ring on
   a notice link is painted ON THE BAND, not on the page — and the band colour is
   editor-chosen. The generic ring (:121-131) is a fixed --hofs-brand-text,
   which measures 1.09:1 against the default teal band and falls below the 3:1
   SC 1.4.11 / 2.4.7 floor for ~80% of possible band colours. Derive the ring
   from the band the same way the TEXT is derived: --announce-fg is the pole
   hofs_announce_text_color() measured at >= 4.5:1 against this exact band
   (inc/announcements.php), so >= 3:1 is guaranteed. (0,2,0) beats the generic
   `a:focus-visible` at (0,1,1). */
.hofs-announce__item a:focus-visible {
  outline-color: var(--announce-fg, #fff);
}
@media (prefers-reduced-motion: reduce) {
  .hofs-announce__item {
    display: block;
  }
}

/* --- CTA hero (template-parts/cta-hero.php) — teal gradient feature card -------
   The prototype's "Want to Get Involved?" band, generalised. A bold gradient card
   inside the shell; a white CTA pill for contrast on the teal. Reusable across
   landing pages + index heros. */
.hofs-cta-hero {
  background: var(--hofs-brand-gradient);
  color: var(--hofs-on-brand);
  border-radius: var(--hofs-radius-xl);
  padding: clamp(1.75rem, 4vw, 3rem);
  box-shadow: var(--hofs-shadow-md);
}
.hofs-cta-hero__inner {
  max-width: 46rem;
}
.hofs-cta-hero__eyebrow {
  font-family: var(--hofs-font-body);
  font-size: calc(0.78rem * var(--hofs-font-scale));
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 var(--hofs-space-3);
  color: var(--hofs-on-brand);
}
.hofs-cta-hero__title {
  font-family: var(--hofs-font-display);
  font-weight: 500;
  color: var(--hofs-on-brand);
  font-size: calc(var(--hofs-text-2xl) * var(--hofs-font-scale));
  line-height: 1.1;
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: balance;
}
.hofs-cta-hero__body {
  margin-top: var(--hofs-space-4);
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  line-height: 1.55;
  color: var(--hofs-on-brand);
}
.hofs-cta-hero__body > :first-child {
  margin-top: 0;
}
.hofs-cta-hero__body > :last-child {
  margin-bottom: 0;
}
.hofs-cta-hero__body a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.hofs-cta-hero__cta {
  margin-top: var(--hofs-space-5);
  background: var(--base-3);
  color: var(--hofs-brand-text);
}
.hofs-cta-hero__cta:hover {
  background: var(--base);
  color: var(--hofs-brand-dark);
}

/* ==========================================================================
   Hero photo banners and intro prose
   --------------------------------------------------------------------------
   Additive: these classes only engage when a Page Hero / CTA Hero block has a
   header image, or a page carries a .hofs-view-intro. Without them the heroes
   render from the base .hofs-hero / .hofs-cta-hero rules above.
   ========================================================================== */

/* --- Hero as a photo banner (image + ink-derived text backdrop) ------------ */
.hofs-hero--image,
body:not(.hofs-home-page) .hofs-hero--image {
  background-size: cover;
  background-repeat: no-repeat;
  border-radius: var(--hofs-radius-lg);
  border-bottom: 0;
  padding: clamp(2rem, 5vw, 3.75rem) clamp(1.5rem, 4vw, 2.75rem);
  overflow: hidden;
}
.hofs-hero--image .hofs-hero__inner {
  width: min(100%, 52rem);
  padding: clamp(1rem, 2.5vw, 1.5rem);
  border-radius: var(--hofs-radius);
  background: color-mix(in srgb, var(--hofs-hero-scrim-color) 72%, transparent);
}
.hofs-hero--image .hofs-hero__eyebrow,
.hofs-hero--image .hofs-hero__title,
.hofs-hero--image .hofs-hero__lede {
  color: var(--hofs-on-scrim);
}

/* --- CTA hero (Documents) with a photo behind the gradient card ------------ */
.hofs-cta-hero--image {
  background-size: cover;
  background-repeat: no-repeat;
}
.hofs-cta-hero--image,
.hofs-cta-hero--image .hofs-cta-hero__eyebrow,
.hofs-cta-hero--image .hofs-cta-hero__title,
.hofs-cta-hero--image .hofs-cta-hero__body {
  color: var(--hofs-on-scrim);
}

/* --- Accessibility escape hatch: reader signalled they want higher contrast --
   Two triggers:
     - prefers-contrast: more   — macOS "Increase contrast", iOS/Android same,
                                  Firefox increased-contrast setting.
     - forced-colors: active    — Windows High Contrast Mode; Firefox override.
   In this state, strip the design-intent opacity dimming (so the guarded
   `--hofs-on-brand` reaches the eye at its full contrast ratio), and swap
   hero photo backgrounds for the same solid gradient the non-image hero uses
   (so text is not riding on an unpredictable image). Same "respect the system
   signal" pattern the reduced-motion blocks throughout this file follow — no
   site-level toggle; the browser/OS already knows. */
@media (prefers-contrast: more), (forced-colors: active) {
  .hofs-cta-hero__eyebrow,
  .hofs-cta-hero__body,
  .hofs-hero--image .hofs-hero__lede,
  .hofs-cta-hero--image .hofs-cta-hero__eyebrow {
    opacity: 1;
  }
  /* Regular hero: fall back to the non-image variant's cream gradient
     (mirrors .hofs-hero at :337-341) and swap child text to the dark
     on-cream palette the non-image hero uses. */
  .hofs-hero--image {
    background: linear-gradient(160deg, var(--base), var(--base-3)) !important;
  }
  .hofs-hero--image .hofs-hero__eyebrow { color: var(--hofs-brand-text); }
  .hofs-hero--image .hofs-hero__title   { color: var(--contrast); }
  .hofs-hero--image .hofs-hero__lede    { color: var(--contrast-2); }
  /* CTA hero: fall back to the base .hofs-cta-hero brand gradient. Text
     stays on-brand white — engine-guaranteed against the gradient. */
  .hofs-cta-hero--image {
    background: var(--hofs-brand-gradient) !important;
  }
  /* Home pathway hero: swap the photo for the same brand gradient the
     .hofs-homehero--plain variant uses; hide the left-anchored scrim (it only
     exists to fight busy photos — with no photo, the gradient's contrast is
     guaranteed and the scrim adds pointless visual weight). */
  .hofs-homehero {
    background: var(--hofs-brand-gradient) !important;
  }
  .hofs-homehero__img,
  .hofs-homehero__scrim {
    display: none;
  }
}

/* --- Intro prose (Intro Text, above or below a generated list) ------------- */
.hofs-view-intro {
  margin: var(--hofs-space-6) 0;
  max-width: 70ch;
  font-size: calc(var(--hofs-text-md) * var(--hofs-font-scale));
  line-height: 1.6;
  color: var(--contrast-2);
}
.hofs-view-intro > :first-child {
  margin-top: 0;
}
.hofs-view-intro > :last-child {
  margin-bottom: 0;
}
.hofs-view-intro a {
  color: var(--hofs-brand-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Item 5 — persistent help chrome. Mobile: full-width fixed bottom bar. Desktop:
   compact pill bottom-right. brand-dark fill / on-brand text is the AA-guarded
   pair. z-index below the floatnav (9999); on mobile they sit at opposite edges
   so never overlap. No entrance transition (always present) → no reduced-motion
   entry needed. */
.hofs-helpbar {
  position: fixed;
  z-index: 9998;
  background: var(--hofs-brand-dark);
  color: var(--hofs-on-brand);
  box-shadow: var(--hofs-shadow-md);
}
.hofs-helpbar__link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--hofs-space-3);
  color: var(--hofs-on-brand);
  text-decoration: none;
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(1rem * var(--hofs-font-scale));
}
.hofs-helpbar__icon svg {
  display: block;
  width: 1.25em;
  height: 1.25em;
}
@media (min-width: 769px) {
  .hofs-helpbar {
    bottom: var(--hofs-space-5);
    right: var(--hofs-space-5);
    border-radius: var(--hofs-radius-pill);
  }
  .hofs-helpbar__link {
    padding: var(--hofs-space-3) var(--hofs-space-5);
  }
}
@media (max-width: 768px) {
  .hofs-helpbar {
    left: 0;
    right: 0;
    bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  .hofs-helpbar__link {
    padding: var(--hofs-space-4) var(--hofs-space-5);
  }
  /* Clear the fixed bar so it never covers page-bottom content. */
  body {
    padding-bottom: calc(var(--hofs-space-8) + env(safe-area-inset-bottom));
  }
}

/* "Find a Meeting" pill. Mirrors the help bar's pill treatment (shape, size,
   shadow, radius, typography); fill comes from the sibling guarded pair
   (--accent-2 / --hofs-on-accent) so the two pills read as one coordinated
   system while staying instantly distinguishable (accent vs brand).

   NAME COLLISION — read this before touching the fill. GP's global-color slug
   `accent` is fed by --hofs-brand (the TEAL) and `accent-2` by
   --hofs-accent (the ORANGE) — the frozen map at inc/gp-populate.php:90-91.
   The engine guards --hofs-on-accent against the ORANGE
   (inc/tokens/class-hofs-tokens.php:677-678), so it is AA-legible on
   --accent-2 and NOT on --accent. Pairing it with var(--accent) shipped a
   3.14:1 fill here; var(--accent-2) is the guarded partner at 6.27:1, the same
   pairing .hofs-btn--accent (:396) and .hofs-chip (:516) already use.
   The folded --hofs-accent / --hofs-brand are never emitted on the front
   end (empty string) — never reference them from this file.
   Desktop: bottom-LEFT, mirroring the help bar's bottom-right. Mobile: a compact
   FAB pill floating ABOVE the full-width help bar, right-aligned. The popover
   expands upward and rides the wrapper's raised stacking context above all fixed
   chrome when open. */
.hofs-meetpill {
  position: fixed;
  z-index: 9998;
}
.hofs-meetpill--open {
  z-index: 10000; /* lift pill + panel above the float nav (9999) while open */
}
.hofs-meetpill__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--hofs-space-3);
  padding: var(--hofs-space-3) var(--hofs-space-5);
  background: var(--accent-2);
  color: var(--hofs-on-accent);
  /* The label clears 4.5:1 on the orange, but SC 1.4.11 also asks 3:1 of the
     CONTROL'S BOUNDARY against its adjacent colour — and this pill is
     position:fixed over the body, measured rgb(244,239,231) = --base-2 at every
     scroll offset, NOT the lighter --base-3 of a card. Orange on --base-2 is
     2.15:1; the shadow supplies nothing. --hofs-border-strong is the guarded
     UI-contrast token (3.20:1 on --base-2) and is the same ring the stepper
     buttons wear (:907-924). */
  border: 1px solid var(--hofs-border-strong);
  border-radius: var(--hofs-radius-pill);
  box-shadow: var(--hofs-shadow-md);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  font-size: calc(1rem * var(--hofs-font-scale));
  cursor: pointer;
}
/* Same 0-1-1 trap as .hofs-floatnav__toggle (:360): GP's generic `button:hover`
   paint out-specifies the 0-1-0 rule above, so without this the brand-orange pill
   turned BRAND-DARK TEAL the moment it was hovered — and stayed teal after a tap
   on touch. Hold --accent-2 across every interactive state: it also preserves the
   two contrast ratios audited in the comment above (4.5:1 label, 3:1 boundary),
   which a darker hover fill would have silently invalidated. Feedback comes from
   the shadow instead of a colour change. */
.hofs-meetpill__toggle:hover,
.hofs-meetpill__toggle:focus,
.hofs-meetpill__toggle:active {
  background: var(--accent-2);
  color: var(--hofs-on-accent);
  box-shadow: var(--hofs-shadow-lg);
}

.hofs-meetpill__icon svg {
  display: block;
  width: 1.25em;
  height: 1.25em;
}
.hofs-meetpill__panel {
  position: absolute;
  bottom: calc(100% + var(--hofs-space-3));
  width: min(20rem, calc(100vw - 2 * var(--hofs-space-4)));
  display: flex;
  flex-direction: column;
  gap: var(--hofs-space-2);
  padding: var(--hofs-space-4);
  background: var(--base-3);
  color: var(--hofs-brand-text);
  border: 1px solid var(--hofs-line);
  border-radius: var(--hofs-radius-lg);
  box-shadow: var(--hofs-shadow-lg);
  opacity: 0;
  visibility: hidden; /* snaps (removes from tab + a11y tree when closed, like .hofs-floatnav) */
  transform: translateY(var(--hofs-space-2));
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.hofs-meetpill--open .hofs-meetpill__panel {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.hofs-meetpill__lead {
  margin: 0 0 var(--hofs-space-1);
  font-family: var(--hofs-font-body);
  font-size: calc(0.875rem * var(--hofs-font-scale));
  color: var(--hofs-brand-text);
}
.hofs-meetpill__app,
.hofs-meetpill__list {
  display: block;
  padding: var(--hofs-space-2) var(--hofs-space-3);
  border-radius: var(--hofs-radius-sm);
  font-family: var(--hofs-font-body);
  font-weight: 600;
  text-decoration: none;
}
.hofs-meetpill__app {
  color: var(--hofs-on-brand);
  background: var(--hofs-brand-dark);
}
.hofs-meetpill__list {
  color: var(--hofs-brand-text);
  background: var(--base-2);
  border: 1px solid var(--hofs-line);
}
/* Re-assert on-brand text through hover/focus. The global a:hover,a:focus rule
   (theme.css:101-103, color: brand-text, specificity 0,1,1) otherwise beats the
   single-class base rule (0,1,0) and paints the app links teal-on-teal — the
   first app link is auto-focused on open, so this defect shows immediately.
   This selector is 0,2,0, so it wins; token stays guarded on-brand. */
.hofs-meetpill__app:hover,
.hofs-meetpill__app:focus {
  color: var(--hofs-on-brand);
}
.hofs-meetpill__toggle:focus-visible,
.hofs-meetpill__app:focus-visible,
.hofs-meetpill__list:focus-visible {
  outline: 2px solid var(--hofs-brand-text);
  outline-offset: 2px;
}
@media (min-width: 769px) {
  .hofs-meetpill {
    bottom: var(--hofs-space-5);
    left: var(--hofs-space-5); /* mirror of help bar's bottom/right space-5 (theme.css:2235-2236) */
  }
  .hofs-meetpill__panel {
    left: 0;
  }
}
@media (max-width: 768px) {
  .hofs-meetpill {
    right: var(--hofs-space-4);
    /* Clear the full-width help bar: it pins to bottom:0 with ~space-8 of height
       (theme.css:2243-2256) plus the safe-area inset. Float this pill above it. */
    bottom: calc(var(--hofs-space-8) + var(--hofs-space-3) + env(safe-area-inset-bottom));
  }
  .hofs-meetpill__toggle {
    padding: var(--hofs-space-3) var(--hofs-space-4);
  }
  .hofs-meetpill__panel {
    right: 0;
  }
}
/* Guardrail: kill the popover transition for reduced-motion users (the only new
   transition this change introduces). Mirrors theme.css:259-263. */
@media (prefers-reduced-motion: reduce) {
  .hofs-meetpill__panel {
    transition: none;
  }
}

/* --- Site search (backlog item 5; inc/search.php + searchform.php) ----------
   Two surfaces, both NEW — nothing else in this file styled a text input, and
   the theme had no search affordance at all:

     .hofs-searchlink*   the chrome link, printed into GeneratePress's
                            `.menu-bar-items` by hofs_search_link()
                            (inc/search.php, generate_menu_bar_items @5).
     .hofs-searchform*   the one form, printed by searchform.php for EVERY
                            get_search_form() call site — our search.php, our
                            404.php, and GP's own content-404.php / no-results.php.

   Every other class those files emit is existing vocabulary and is already
   styled above: .hofs-hero (:329 / :1279), .hofs-btn--ghost (:399),
   .hofs-section (:406), .hofs-doclist / .hofs-doc (:668),
   .hofs-filter (:816, the facet chips). Nothing here is fixed or floating, so
   the 9998–10000 corridor (helpbar / floatnav / meetpill) is untouched and the
   mobile bottom edge keeps exactly one reservation (theme.css:2253-2256).

   Appended rather than filed under an L-banner: the L2…L6 headings are
   historical waves (L4 appears twice, at :847 and :1000) and override behaviour
   in this file is SOURCE ORDER — see the note at theme.css:69-72. */

/* Chrome link. Sibling of `.hofs-controls` inside GP's `.menu-bar-items`
   flex row, never a child of it (that group is role="group" aria-label="Display
   settings"), so its own margin supplies the gap — `.hofs-site-controls`
   at :887 is dead CSS (the emitted class is `.hofs-controls`).
   Like the A-/A/A+ stepper (:900-906) this is CHROME: its size is FIXED and does
   NOT track --hofs-font-scale, so the header does not reflow as a reader
   bumps the text size.

   It also wears the stepper's pill vocabulary verbatim (:907-924) — 36px box,
   1px solid --hofs-border-strong, --base-3 fill, --contrast-2 text, pill
   radius, no shadow — so the two controls read as one row rather than a bordered
   group with a bare link stapled to it. 36px x 44px (min-width 44px at ≤768px,
   content + 2 x space-3 above it) clears WCAG 2.2 SC 2.5.8's 24x24 floor.

   THE SELECTOR IS (0,3,0) ON PURPOSE, and it is the same GP-parent trap the
   :hover rule below guards against. GeneratePress ships two rules that beat a
   single-class (0,1,0) declaration:
     `.main-navigation a { display: block; font-weight: 400; font-size: 15px }`
        (0,1,1) — a bare `.hofs-searchlink` therefore computed display:BLOCK,
        which silently made its own align-items/justify-content/gap INERT and
        left the icon flush to the box top instead of centred; and
     `.main-navigation .menu-bar-items a { color: inherit }`
        (0,2,1) — which pins the link to the container's --contrast instead of
        the stepper's --contrast-2.
   Scoping to the two containers GP itself emits around BOTH copies of this link
   clears both. Restoring the intended display is the whole geometry fix — the
   internal centring does the rest, with no margins, transforms or height
   fudging, which would only re-break at other font scales. */
.main-navigation .menu-bar-items .hofs-searchlink {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--hofs-space-2);
  min-height: 36px;
  margin-right: var(--hofs-space-2);
  padding: 0 var(--hofs-space-3);
  background: var(--base-3);
  border: 1px solid var(--hofs-border-strong);
  border-radius: var(--hofs-radius-pill);
  font-family: var(--hofs-font-body);
  font-size: .95rem;
  font-weight: 600;
  line-height: 1;
  color: var(--contrast-2);
  text-decoration: none;
  transition: background-color .25s ease, color .25s ease, border-color .25s ease;
}
.hofs-searchlink__icon svg {
  display: block;
  width: 1.25em;
  height: 1.25em;
}
/* Teal fill on hover/focus, matching .hofs-font-size__btn:hover (:929-933).
   This selector is (0,2,0) ON PURPOSE: the global `a:hover, a:focus` rule at
   :101-104 is (0,1,1) and would otherwise beat a single-class rule and repaint
   the label brand-text over the teal fill. Same defect, same fix, as the meeting
   pill's app links at :2341-2349 — and the same trap the BASE rule above now
   guards against for `display` and `color` (GP's `.main-navigation a` at (0,1,1)
   and `.main-navigation .menu-bar-items a` at (0,2,1)). Three different parent
   rules, one specificity lesson: a bare `.hofs-searchlink` declaration cannot
   be trusted inside GP's nav. Carries the base rule's scope so it out-specifies
   it at (0,3,1) rather than relying on source order. */
.main-navigation .menu-bar-items .hofs-searchlink:hover,
.main-navigation .menu-bar-items .hofs-searchlink:focus {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--hofs-on-brand);
}

/* GP fires generate_menu_bar_items TWICE (desktop bar + mobile control wrapper),
   so this link is in the DOM twice and CSS decides which copy is visible. The
   stepper hides the mobile-bar copy and reveals the drawer copy (:278-285);
   search INVERTS that, deliberately — a cold arrival looking for search should
   not have to open the hamburger first. So: keep the mobile-bar copy beside the
   burger, hide the copy inside the slide-out drawer.

   This targets the LINK, not its `.menu-bar-items` container, so it never
   competes with the (1,4,1) drawer-reveal rule at :283-285 — that rule keeps
   revealing the container for the stepper, which is untouched here.

   The label is clipped rather than removed at this width: the burger already
   claims the row at 360px, and clip-path/`clip` (the .hofs-sr-only recipe,
   :874-885) keeps the text in the accessibility tree, so the icon-only control
   still has an accessible name.

   SCOPED TO .site-header.has-inline-mobile-toggle, and that scope is
   load-bearing. NOTE THE ANCHOR: GeneratePress puts `has-inline-mobile-toggle`
   on the SITE HEADER (`<header class="site-header has-inline-mobile-toggle"
   id="masthead">`), never on <body> — a `body.` prefix here matches nothing and
   the safeguard is inert (the drawer copy was hidden only by accident, because
   GP's own rule collapses its parent container). This
   rule is a HIDE, and it can only be safe when a SECOND copy is guaranteed to
   exist. GeneratePress renders #mobile-menu-control-wrapper — the copy this rule
   relies on staying visible — only when generate_has_inline_mobile_toggle() is
   true (nav location nav-float-right/-left AND flexbox structure), which is DB
   state, not repo state. Change the Navigation Location in the customizer and
   generate_menu_bar_items fires ONCE, inside .inside-navigation — and an
   unscoped hide would then delete the only search affordance a phone visitor
   has, silently. The stepper's equivalent (:278-285) is immune because it
   REVEALS rather than hides; this is the same protection expressed for a hide. */
@media (max-width: 768px) {
  .site-header.has-inline-mobile-toggle #site-navigation .inside-navigation > .menu-bar-items > .hofs-searchlink {
    display: none;
  }
  /* (0,3,0) to match the base rule above — a bare `.hofs-searchlink` here
     would be (0,1,0) and LOSE its padding back to the base rule. */
  .main-navigation .menu-bar-items .hofs-searchlink {
    min-width: 44px;
    padding: 0 var(--hofs-space-2);
  }
  .hofs-searchlink__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }
}

/* The form. In-flow only — never fixed — so a focused field is scrolled into
   view by the browser and can never be trapped under the mobile keyboard or
   behind the fixed help bar. Capped at a comfortable line so the field does not
   stretch the full 62rem shell. */
.hofs-searchform {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--hofs-space-3);
  max-width: 34rem;
  margin: 0 0 var(--hofs-space-6);
}
/* Permanently visible label (searchform.php ships no placeholder), on its own
   row above the field. Not micro-caps: this is read by someone who may be
   cognitively loaded, so it stays sentence-case at body weight. */
.hofs-searchform__label {
  flex: 0 0 100%;
  font-family: var(--hofs-font-body);
  font-size: calc(.95rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1.4;
  color: var(--contrast);
}
/* The theme's first text input. `appearance: none` strips Safari's native search
   chrome so the field takes the token surface, border and radius like every
   other bordered element here.

   The max() floor keeps the COMPUTED size at or above 1rem even at the A- end of
   the stepper's 0.75–1.375 band (theme.js:45-46), because iOS Safari zooms the
   viewport on focus for anything under 16px — while still honouring the reader's
   scale upward. min-height + height:auto (never a fixed height) so the box grows
   with the type instead of clipping at the 1.375x ceiling.

   (0,2,0), NOT a bare `.hofs-searchform__field`. GeneratePress ships TWO
   attribute-selector rules at (0,1,1) that beat a single class:
   `input[type="search"],… { border:1px solid; border-radius:0; padding:10px 15px }`
   (generatepress/assets/css/main.min.css) and, from the customizer's generated
   inline sheet, `input[type="search"],… { background-color: var(--base-2);
   border-color: var(--base) }`. At (0,1,0) the authored fill, border colour,
   radius and padding were ALL inert — the field painted --base-2 on --base-2
   with a ~1.08:1 edge, failing SC 1.4.11 for a UI component boundary. (0,1,1)
   would only TIE the inline sheet, whose position depends on DB state, so the
   fix goes to (0,2,0). Same GP-parent specificity trap the chrome link
   documents three times above; the field is the theme's first text input. */
.hofs-searchform .hofs-searchform__field {
  flex: 1 1 12rem;
  min-width: 0;
  appearance: none;
  height: auto;
  min-height: 48px;
  padding: var(--hofs-space-3) var(--hofs-space-4);
  font-family: var(--hofs-font-body);
  font-size: max(1rem, calc(1rem * var(--hofs-font-scale)));
  line-height: 1.4;
  color: var(--contrast);
  background: var(--base-3);
  border: 1px solid var(--hofs-border-strong);
  border-radius: var(--hofs-radius-sm);
}
/* Submit already carries .hofs-btn .hofs-btn--primary (:368-393), so it
   inherits the pill fill, the guarded on-brand text and the L5 transition +
   reduced-motion kill (:955-998). Only the height needs to agree with the field. */
.hofs-searchform__submit {
  flex: 0 0 auto;
  min-height: 48px;
}
/* One tap target per row on a phone. (0,2,0) to match the base rule above —
   a bare `.hofs-searchform__field` here is (0,1,0) and would lose its
   flex-basis back to it. */
@media (max-width: 768px) {
  .hofs-searchform .hofs-searchform__field {
    flex-basis: 100%;
  }
  .hofs-searchform__submit {
    width: 100%;
    justify-content: center;
  }
}
/* No focus rule is needed for the form: nothing here sits inside an
   overflow:hidden wrapper, so the global offset ring at :121-132 applies
   correctly and the H-6 inset variant (:134-145) would be wrong. The result rows
   DO need the inset variant and already have it (`.hofs-doc:focus-visible`).

   Guardrail: the chrome link's hover transition above is the only motion this
   feature introduces; the submit button's is already covered at :978-998. */
@media (prefers-reduced-motion: reduce) {
  /* (0,3,0) to match the base rule at :2448 — a bare `.hofs-searchlink` here
     is (0,1,0) and would lose the transition back to it, silently defeating the
     motion opt-out. Same GP-parent specificity trap, third occurrence. */
  .main-navigation .menu-bar-items .hofs-searchlink {
    transition: none;
  }
}

/* Pagination. THE MARKUP IS NOT WP CORE'S. `the_posts_pagination()` would emit
   `nav.navigation.pagination > .nav-links > a.page-numbers`, but GeneratePress
   filters `navigation_markup_template` and, for any $class containing
   'pagination', replaces the WHOLE template with a bare `<div class="nav-links">`
   (generatepress/inc/structure/post-meta.php:133, :145-151) — stripping the
   nav.pagination wrapper AND the screen-reader heading. GP re-adds them only
   inside generate_content_nav(), which neither search.php:172-174 nor
   index.php:67 calls. So `.pagination …` selectors match NOTHING here and these
   rules are scoped to what is actually emitted: a `.nav-links` div that is a
   direct child of `main.site-main`. (GP's post/comment navigation keeps its
   own `nav.post-navigation` / `.comment-navigation` wrapper, so its `.nav-links`
   is never a direct child of .site-main and is not caught by this.)

   Without this, each page number is a bare inline anchor with no padding —
   measured 10x24 CSS px at 1280 and 9x22 at 390, failing WCAG 2.2 SC 2.5.8
   Target Size (Minimum, AA) and even the 24x24 floor, with the spacing
   exception unavailable because adjacent numerals sit ~4px apart. Boxed to
   44px here.

   Not scoped to search: index.php:67 calls the same function, so the blog index
   is fixed by the same rule. The newsletter archive block prints the same
   `.nav-links` inside its block wrapper on a Page, so it is named too. */
.site-main > .nav-links,
.nav-links.hofs-events-pagination,
.nav-links.hofs-newsletter-pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--hofs-space-2);
  margin: var(--hofs-space-6) 0 0;
}
.nav-links .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--hofs-space-2);
  font-family: var(--hofs-font-body);
  font-size: calc(.95rem * var(--hofs-font-scale));
  font-weight: 600;
  line-height: 1;
  color: var(--contrast-2);
  text-decoration: none;
  border-radius: var(--hofs-radius-pill);
}
/* (0,2,0), so the global `a:hover, a:focus` at :101-104 — which is (0,1,1) —
   cannot repaint the label over the fill. Same defect, same fix, as :2341-2349. */
.nav-links a.page-numbers:hover,
.nav-links a.page-numbers:focus {
  color: var(--hofs-on-brand);
  background: var(--accent);
}
.nav-links .page-numbers.current {
  color: var(--hofs-on-brand);
  background: var(--accent);
}
.nav-links .page-numbers.dots {
  min-width: 0;
  padding: 0 var(--hofs-space-1);
}

/* SC 2.4.11 Focus Not Obscured (Minimum, AA). Below 768px the help bar is a
   full-width fixed bar at bottom:0 (:2243-2252) roughly 51px tall plus the
   safe-area inset. The `body { padding-bottom }` at :2253-2256 reserves space
   only at the END of the document; it does nothing for content scrolled beneath
   the bar mid-document. So when Tab moves focus to an element just below the
   fold — a ~56px `.hofs-doc` row in a long doc list, or a 44px page-number —
   the browser scrolls its bottom edge to the viewport bottom and the fixed bar
   covers it ENTIRELY, focus ring included. Partial obscuring is permitted;
   total obscuring is the failure condition.

   One declaration on the scroll container fixes every list in the theme, not
   just the search and 404 pages, and changes no markup. */
@media (max-width: 768px) {
  html {
    scroll-padding-bottom: calc(var(--hofs-space-8) + env(safe-area-inset-bottom));
  }
}

/* ============================================================================
   PRINT — service-worker rosters, schedules, packet indices (backlog item 4).

   AA service still runs on printed handouts at assemblies and district
   meetings. On Ctrl+P this FLATTENS the screen design to plain black-on-white
   paper: it strips chrome + nav rails, removes every gradient/fill/shadow/
   radius, unwraps the 62rem floating shell, turns the gradient hero into a
   simple underlined title, and — crucially — replaces the theme's flex/grid
   document rows with ordinary flowing blocks (the on-screen grid collapses to
   one-glyph-per-line when the printed URL is injected, exactly the squeeze the
   ≤480px rule already documents). Tab panels are revealed and native <details>
   are force-opened by a beforeprint listener (assets/js/theme.js), which also
   stamps .hofs-print-footer with the date. Zero markup change.
   ========================================================================== */

/* The freshness stamp is print-only; theme.js appends it and fills its text. */
.hofs-print-footer { display: none; }

@media print {
  /* Neutral paper margins so nothing rides the sheet edge. */
  @page { margin: 1.5cm; }

  /* Black-on-white, and strip every gradient / fill / elevation cue in one
     pass — the theme leans on gradients (hero, panel-fill) and soft shadows
     that mean nothing on paper and waste toner. */
  html,
  body { background: #fff !important; color: #000 !important; }
  *,
  *::before,
  *::after {
    background: transparent !important;
    background-image: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
    color: #000 !important;
    border-color: #999 !important;
  }

  /* --- Hide screen-only chrome + navigation rails ----------------------- */
  .hofs-announce,
  .site-header,
  #site-navigation,
  .main-navigation,
  .hofs-floatnav,
  .hofs-helpbar,
  .hofs-meetpill,
  .hofs-filter,
  .hofs-cnav,
  .hofs-tabs__list,
  .site-footer,
  .hofs-footer,
  .generate-back-to-top,
  form[role="search"],
  .hofs-doc__ext,
  .hofs-homehero__img,
  .hofs-pathway-group .sub-menu {
    display: none !important;
  }

  /* --- Unwrap the floating shell + flatten every card/panel to the page -- */
  body:not(.hofs-home-page) .site-main,
  .site-main,
  .site-content,
  .inside-article,
  .entry-content,
  .hofs-card,
  .hofs-event-card,
  .wp-block-group.is-style-hofs-panel,
  .hofs-doclist {
    max-width: none !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    border-radius: 0 !important;
    overflow: visible !important;
  }
  .site-main { padding: 0 !important; border: 0 !important; }

  /* Gradient hero → a plain underlined page title. */
  .hofs-hero,
  .hofs-cta-hero {
    padding: 0 0 0.35rem !important;
    margin: 0 0 1rem !important;
    border: 0 !important;
    border-bottom: 2px solid #000 !important;
    border-radius: 0 !important;
  }

  /* --- Reveal what the screen collapses --------------------------------- */
  .hofs-tabpanel[hidden],
  .hofs-tabpanel__title { display: block !important; }
  /* No-JS fallback for the beforeprint listener: a closed <details> hides its
     content through ::details-content, so reveal it there (own rule: an engine
     without the pseudo-element drops it and relies on the listener). */
  details::details-content { content-visibility: visible !important; }
  /* The Home banner photo was a background, which paper never printed; its
     <img> stays off too. The Home page buttons' drop-down lists are navigation,
     hidden with the other rails above, so every chevron prints closed. */
  .hofs-pathway-group[open] > .hofs-pathway .hofs-pathway__chevron {
    margin-block: 0 0.25em;
    transform: rotate(45deg);
  }

  /* --- Document rows: flow as ordinary blocks, NEVER the collapsing grid.
     The on-screen row is `display:flex` with a fixed icon + non-shrinking tag;
     inject a long URL and the title flex item squeezes to ~0 (one glyph per
     line). Block layout sidesteps it entirely: title, meta, tag, then the
     printed URL all stack/flow. ---------------------------------------------- */
  .hofs-doclist { border: 1px solid #999 !important; }
  .hofs-doc,
  .hofs-doc--actions {
    display: block !important;
    padding: 6px 8px !important;
    border: 0 !important;
  }
  .hofs-doclist li + li .hofs-doc { border-top: 1px solid #ccc !important; }
  .hofs-doc__icon {
    display: inline !important;
    width: auto !important;
    height: auto !important;
    border: 0 !important;
    margin-right: 0.35rem;
    font-size: 0.7rem !important;
  }
  .hofs-doc__title { display: block !important; }
  .hofs-doc__name { font-weight: 700 !important; }
  .hofs-doc__tag {
    display: inline-block !important;
    white-space: normal !important;
    border: 1px solid #999 !important;
    padding: 0 5px !important;
    margin-left: 0.4rem;
  }
  /* Action-pill rows → plain inline text links. */
  .hofs-doc__actions { display: block !important; margin-top: 2px; }
  .hofs-doc__action {
    display: inline !important;
    border: 0 !important;
    padding: 0 !important;
    margin: 0 1rem 0 0;
  }

  /* --- Links: underline + print external destinations inline ------------ */
  a { color: #000 !important; text-decoration: underline; }
  a[href^="http"]::after {
    content: " <" attr(href) ">";
    font-size: 0.8em;
    font-weight: 400;
    word-break: break-all;
  }
  /* In-page anchors, phone, and mail links already read as their own text. */
  a[href^="#"]::after,
  a[href^="tel:"]::after,
  a[href^="mailto:"]::after { content: "" !important; }

  /* --- Page-break discipline — only small units, never whole panels ------ */
  h1, h2, h3, h4 { break-after: avoid-page; }
  .hofs-doc,
  tr,
  li,
  .hofs-card,
  .hofs-event-card { break-inside: avoid; }
  thead { display: table-header-group; } /* repeat table headers across pages */
  img { max-width: 100% !important; }

  /* --- Freshness stamp (text filled by theme.js beforeprint) ------------ */
  .hofs-print-footer {
    display: block !important;
    margin-top: 1.2rem;
    padding-top: 0.4rem;
    border-top: 1px solid #000 !important;
    font-size: 0.8rem;
  }
}
