/* Courtenay BAC & PAC — v4 presentation layer over Twenty Twenty-Five.
   Spec: docs/1-website-shell/redesign-plan.md, § Build brief.
   Grammar: warm paper, navy ink, square white cards (1px navy rule, 3px navy
   bottom edge), navy header and footer bands, gold for the PAC's ask, the
   active tab and the BAC/PAC tooltips. Libre Caslon Text for the wordmark,
   headings and big numbers; Source Serif 4 for everything else. No rounded
   corners, shadows, gradients or monospace.

   BUILD STATE (2026-10-09): every page is v4 — tokens, header, footer, the
   homepage, and the inner pages (the "Inner pages" section). The terminal
   theme's CSS and token names are gone from this sheet. */

:root {
  color-scheme: light;

  /* ---- v4 palette ---- */
  --paper: #F6F3EC;               /* page ground */
  --card: #FFFFFF;                /* cards, the Today board */
  --ink: #14264A;                 /* text */
  --quiet: #4F5B74;               /* secondary text on paper and white */
  --line: #14264A;                /* card rules: 1px, 3px bottom edge */
  --rule: rgba(20, 38, 74, 0.3);  /* hairlines inside text */
  --gold-pale: #FBEBA3;           /* a highlighted (PAC / BAC) meeting row */
  --tint: rgba(20, 38, 74, 0.05); /* a row or button under the pointer */
  --link: #14264A;
  --link-hover: #0B1733;
  --btn: #14264A;                 /* buttons on paper and white */
  --btn-ink: #FFFFFF;
  --btn-hover: #0B1733;
  --focus: #14264A;               /* focus ring on light surfaces: gold on paper is ~1.4:1, a ring needs 3:1 */
  --drawing: #14264A;             /* the line drawings, painted through alpha masks */
  --block-gold: #F5C400;          /* "Your school" play blocks: frame colours and their shaded sides */
  --block-gold-side: #B38A00;
  --block-blue: #3B5B9A;
  --block-blue-side: #253C68;
  --block-red: #A8402A;           /* the brick of the Assembly Hall photo, lifted a touch */
  --block-red-side: #6E2816;
  --block-edge: #14264A;          /* the blocks' ink line */

  /* the navy bands: header and footer */
  --band: #14264A;
  --band-ink: #FFFFFF;            /* wordmark, nav, links */
  --band-text: #D7DEEE;           /* footer body text */
  --band-fine: #A9B4CC;           /* footer fine print */
  --band-edge: rgba(255, 255, 255, 0.6);   /* outlined controls */
  --band-hover: rgba(255, 255, 255, 0.1);  /* their hover fill */
  --band-rule: rgba(255, 255, 255, 0.25);  /* the rule above the phone nav strip */
  --band-lift: 0 10px 26px -14px rgba(10, 18, 36, 0.6); /* that strip, pinned */

  /* scheme-fixed: identical in light and dark */
  --gold: #F5C400;                /* the PAC's ask, the active tab, BAC/PAC tooltips, the ring on navy */
  --on-gold: #14264A;             /* text on gold */

  --caslon: "Libre Caslon Text", Georgia, serif;
  --serif: "Source Serif 4", Georgia, serif;
  --wrap: 720px;                  /* reading column */
  --wide: 1120px;                 /* header, footer, homepage */


  --gold-ink: #8A6300;            /* gold as text on paper (a minutes row's "pending review") */
  --well: #E3E8F2;                /* an Instagram avatar before it loads */
}

/* Block-editor presets → scheme-aware tokens. theme.json keeps the light
   palette for the editor UI; the front end re-points the generated preset
   custom properties at our tokens so preset-classed markup (the header and
   footer's has-navy-background-color, content links via accent-3, …) follows
   the scheme. This sheet loads after the inline global-styles sheet, so this
   same-specificity :root wins the tie. */
:root {
  --wp--preset--color--base: var(--paper);
  --wp--preset--color--contrast: var(--ink);
  --wp--preset--color--navy: var(--band);
  --wp--preset--color--card: var(--card);
  --wp--preset--color--accent-1: var(--gold);
  --wp--preset--color--accent-2: var(--gold-pale);
  --wp--preset--color--accent-3: var(--link);
  --wp--preset--color--accent-4: var(--quiet);
  --wp--preset--color--accent-5: var(--rule);
}

/* ---------- Dark scheme ----------
   Night navy, warm paper-white ink, gold unchanged; navy buttons turn gold
   with navy text, and the line drawings turn paper-coloured through
   --drawing. Proposed on the canvas's Brand board, not mocked page by page:
   check on a phone. Two entry points, SAME payload:
     1. the media block  — follows the OS unless the visitor chose light;
     2. the [data-theme="dark"] block — the visitor's explicit choice
        (stamped on <html> by the footer toggle; see functions.php).
   `screen and` keeps print on paper. Tokens only, never component rules.
   KEEP THE TWO BLOCKS IDENTICAL. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #0F1A30;
    --card: #17243F;
    --ink: #EFEAE0;
    --quiet: #A9B4CC;
    --line: rgba(239, 234, 224, 0.3);
    --rule: rgba(239, 234, 224, 0.22);
    --gold-pale: rgba(245, 196, 0, 0.16);
    --tint: rgba(239, 234, 224, 0.07);
    --link: #EFEAE0;
    --link-hover: #F5C400;
    --btn: #F5C400;
    --btn-ink: #14264A;
    --btn-hover: #FFD43B;
    --focus: #F5C400;
    --drawing: #EFEAE0;
    --block-blue: #5B7DC2;
    --block-blue-side: #3A5891;
    --block-red: #C9583E;
    --block-red-side: #8F3A28;
    --block-gold-side: #A07B00;
    --block-edge: rgba(239, 234, 224, 0.55);
    --band: #0A1224;
    --band-lift: 0 10px 26px -12px rgba(0, 0, 0, 0.7);
    --gold-ink: #E0B020;
    --well: #1E2D4D;
  }
}
/* visitor's explicit choice — MUST mirror the media block above exactly */
@media screen {
  :root[data-theme="dark"] {
    color-scheme: dark;
    --paper: #0F1A30;
    --card: #17243F;
    --ink: #EFEAE0;
    --quiet: #A9B4CC;
    --line: rgba(239, 234, 224, 0.3);
    --rule: rgba(239, 234, 224, 0.22);
    --gold-pale: rgba(245, 196, 0, 0.16);
    --tint: rgba(239, 234, 224, 0.07);
    --link: #EFEAE0;
    --link-hover: #F5C400;
    --btn: #F5C400;
    --btn-ink: #14264A;
    --btn-hover: #FFD43B;
    --focus: #F5C400;
    --drawing: #EFEAE0;
    --block-blue: #5B7DC2;
    --block-blue-side: #3A5891;
    --block-red: #C9583E;
    --block-red-side: #8F3A28;
    --block-gold-side: #A07B00;
    --block-edge: rgba(239, 234, 224, 0.55);
    --band: #0A1224;
    --band-lift: 0 10px 26px -12px rgba(0, 0, 0, 0.7);
    --gold-ink: #E0B020;
    --well: #1E2D4D;
  }
}

/* ---------- Global ---------- */
/* Reserve the scrollbar gutter even on short pages, so the centered column
   doesn't shift sideways when navigating between scrolling and non-scrolling pages */
html { scrollbar-gutter: stable; }
/* Nothing may widen the document. A phone answers a too-wide page by widening
   its LAYOUT viewport to fit, and fixed elements size to that viewport, not to
   the screen: the pinned section nav runs past the visible right edge (its
   predecessor, a bar fixed along the BOTTOM, sat below the visible screen —
   the widened viewport grows taller too — until you scrolled). It is a silent
   failure: no scrollbar on a touch device, and the page looks fine.

   BOTH declarations are load-bearing, and only the pair works (measured in
   headless Chrome against a 16px overhang, 2026-09-01): the root's overflow is
   what propagates to the viewport, and an element whose overflow propagated is
   not itself a clipper — so `html` alone leaves nothing clipping, and `body`
   alone just propagates in html's place and does the same nothing. With html
   set, body keeps its own used value and becomes the box that actually clamps
   scrollWidth. `clip`, not `hidden`: no scroll container, so anchor scrolling
   and any future sticky are untouched. Fixed children are not clipped by it —
   body is not their containing block. */
html { overflow-x: clip; }
body { overflow-x: clip; }

::selection { background: var(--gold); color: var(--on-gold); }
/* Focus: a 3px ring, navy on light surfaces (gold on paper fails 3:1) and
   gold on the navy bands. Twenty Twenty-Five outlines every :focus in
   currentColor, mouse clicks included; keep rings for the keyboard. */
:where(.wp-site-blocks *:focus):not(:focus-visible) { outline: none; }
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  box-shadow: none;
}
.cbp-header :focus-visible,
.cbp-footer :focus-visible { outline-color: var(--gold); }
.screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* BAC / PAC two-tone chips (in page content; restyled with the inner pages) */
.cbp-bac, .cbp-pac {
  display: inline-block;
  font-weight: 600;
  padding: 0.05em 0.32em;
  line-height: 1.3;
}
.cbp-bac { color: #14264A; background: var(--gold); }
.cbp-pac { color: var(--gold); background: #14264A; }

/* BAC / PAC expansion tooltips — gold, on hover / focus / tap.
   In content the_content wraps each chip in the trigger + tip (functions.php);
   the header wordmark carries its own two as buttons. The text stays real,
   translatable DOM text. */
.cbp-abbr { position: relative; cursor: help; }
button.cbp-abbr {
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; letter-spacing: inherit;
}
.cbp-abbr__tip {
  position: absolute;
  /* --cbp-tip-x is the nudge assets/bacpac-abbr.js measures, so a tip centred
     on a chip near the right margin slides back inside the screen instead of
     hanging off it — hidden is not gone, and an overhanging tip widens the
     document even while closed. 0 until (and unless) that script runs. It
     rides on `left`, not on the transform, so it is never in flight when the
     script measures. */
  left: calc(50% + var(--cbp-tip-x, 0px)); bottom: calc(100% + 12px);
  z-index: 40;
  width: max-content; max-width: min(16rem, 74vw);
  padding: 7px 11px;
  background: var(--gold); color: var(--on-gold);
  font-family: var(--serif); font-size: 0.875rem; font-weight: 700; font-style: normal;
  line-height: 1.25; letter-spacing: 0; text-transform: none;
  text-align: center; white-space: normal;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translate(-50%, 3px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0.15s;
}
.cbp-abbr__tip::after {
  content: ""; position: absolute; top: 100%;
  left: calc(50% - var(--cbp-tip-x, 0px));   /* arrow stays over the chip */
  transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--gold);
}
.cbp-abbr:hover .cbp-abbr__tip,
.cbp-abbr:focus-visible .cbp-abbr__tip,
.cbp-abbr.is-open .cbp-abbr__tip {
  opacity: 1; visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
@media (prefers-reduced-motion: reduce) {
  .cbp-abbr__tip,
  .cbp-abbr:hover .cbp-abbr__tip,
  .cbp-abbr:focus-visible .cbp-abbr__tip,
  .cbp-abbr.is-open .cbp-abbr__tip { transform: translateX(-50%); transition: opacity 0.12s ease; }
}

/* Downward variant — for triggers near the top of the page (the header
   wordmark), where there's no room for the tooltip to open upward. */
.cbp-abbr--down .cbp-abbr__tip { top: calc(100% + 12px); bottom: auto; }
.cbp-abbr--down .cbp-abbr__tip::after {
  top: auto; bottom: 100%;
  border-top-color: transparent; border-bottom-color: var(--gold);
}

/* ---------- Cross-document view transitions ----------
   Progressive enhancement: Chrome and current Safari can crossfade one
   page into the next instead of a hard cut. Unsupported browsers ignore the
   at-rule and load as before. Reduced-motion opts out entirely (the * rule
   later in this sheet does not match ::view-transition-* pseudos).

   The header is deliberately NOT named. A name only holds it still when
   the old page happened to be at the top: an off-screen named element is
   still captured and animated, so navigating from mid-page — the normal case
   on phones, where the nav pins to the top of the screen — sent the whole
   header sliding in from above. Unnamed, it rides the root crossfade,
   and since both headers are identical it reads as staying put anyway.

   One duration for every group, named ones included: the wildcard name
   selector landed in the same releases as cross-document transitions
   (Chrome 125+, Safari 18.2+), so nothing that runs the transition misses
   it and falls back to the UA's slower 0.25s. */
@view-transition {
  navigation: auto;
}
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
  animation-duration: 0.18s;
}
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ---------- Header: the navy band ----------
   Desktop: one row in the 1120px frame — backpack + wordmark on the left;
   nav, language and App on the right — wrapping to two rows below ~1,200px
   (measured with the real fonts: 1,111 of 1,120px). Phone (≤600px): three
   rows — (1) backpack | App + language, (2) the wordmark, (3) the nav strip
   that pins to the top on scroll. Three because two did not fit 390px: nav
   292px + language 80px > 358px, which would have widened the viewport.

   The DOM is the desktop order: .cbp-header__brand (mark, wordmark), then
   .cbp-header__right (the nav slot, the utilities). The phone grid lifts the
   pieces out of both groups with display: contents.

   Selectors the scripts need — keep them: .cbp-header .cbp-navwrap around
   nav.wp-block-navigation (nav-stick.js), .cbp-install + #cbp-install-hint
   (pwa-install.js), .cbp-abbr / .cbp-abbr__tip (bacpac-abbr.js),
   .gtranslate_wrapper select.gt_selector (lang-switch.js), and #cbp-top as the
   header's last element (the rel=expect render hold in functions.php). */
.cbp-header {
  /* one stacking context above the page: the tooltips, the iOS hint and the
     pinned strip paint over positioned page content; the lightbox (9999) wins */
  position: relative; z-index: 100;
  background: var(--band); color: var(--band-ink);
}
.cbp-header__in {
  box-sizing: content-box;   /* 1120px of content, as measured on the canvas; the padding sits outside it */
  max-width: var(--wide); margin: 0 auto;
  padding: 10px clamp(16px, 4vw, 40px);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  /* 16px, not more: the Spanish row (Inicio · Escuela … Español) needs
     1,115 of the 1,120px, and space-between spreads the two groups anyway */
  gap: 8px 16px;
}
/* group blocks hand their children a block-gap top margin — not here */
.cbp-header .cbp-header__in > *,
.cbp-header .cbp-header__right > *,
.cbp-header .cbp-header__utils > * { margin: 0; }

.cbp-header__brand { display: flex; align-items: center; min-height: 48px; }
.cbp-header a.cbp-brand__mark {
  display: inline-flex; align-items: center; flex: none;
  margin-right: 10px; line-height: 0;
}
.cbp-brand__mark svg { display: block; width: 40px; height: 40px; }
.cbp-header .cbp-wordmark {
  margin: 0;
  font-family: var(--caslon); font-size: 32px; font-weight: 700; line-height: 1.1;
  white-space: nowrap; color: var(--band-ink);
}
.cbp-header .cbp-wordmark a { color: inherit; text-decoration: none; }
/* BAC and PAC: buttons with a dotted gold underline that open the tooltips.
   Never shrink these to a small tag — the owner's rule. */
.cbp-wordmark .cbp-abbr {
  text-decoration: underline dotted var(--gold);
  text-decoration-thickness: 2px; text-underline-offset: 6px;
}

.cbp-header__right { display: flex; flex-wrap: wrap; align-items: center; gap: 0 16px; }

/* Nav: white words, the page you're on — or the section it sits in —
   underlined in gold. Keyed on aria-current: "page" from WordPress on English
   pages and from the translate mu-plugin on the Spanish twins (their nav links
   point at the twins, so core's own current-menu-item never matches there);
   "true" on the section's link from courtenay_v4_nav_section(). */
.cbp-header nav.wp-block-navigation { margin: 0; font-family: var(--serif); font-size: 16px; }
.cbp-header .wp-block-navigation .wp-block-navigation-item__content {
  display: inline-flex; align-items: center; min-height: 44px; box-sizing: border-box;
  padding: 3px 8px 0;
  border-bottom: 3px solid transparent;
  color: var(--band-ink); font-weight: 700; line-height: 1.2; text-decoration: none;
  transition: border-color 0.15s;
}
.cbp-header .wp-block-navigation .wp-block-navigation-item__content:hover { border-bottom-color: var(--band-edge); }
.cbp-header .wp-block-navigation .wp-block-navigation-item__content[aria-current] { border-bottom-color: var(--gold); }

.cbp-header__utils { display: flex; align-items: center; gap: 16px; }

/* Language button: GTranslate's own <select> (built client-side, hooked by
   lang-switch.js) stretched transparent over a face we draw. A native select
   is as wide as its longest option and shows the selected option's text, so
   it can't be the face itself: this one has to read "English" on a desktop
   and "EN" on a phone. The face ships English / Español as an EN/ES swap
   pair; lang-switch.js relabels it for the other 27 languages. */
.cbp-langbtn { position: relative; display: inline-flex; flex: none; }
.cbp-langbtn__face {
  display: inline-flex; align-items: center; gap: 6px;
  height: 40px; box-sizing: border-box; padding: 0 10px 0 8px;
  border: 1.5px solid var(--band-edge); border-radius: 3px;
  color: var(--band-ink); font-size: 15px; font-weight: 700; line-height: 1; white-space: nowrap;
  transition: background-color 0.15s, border-color 0.15s;
}
.cbp-langbtn__face::before,
.cbp-langbtn__face::after {
  content: ""; flex: none; display: block; background: currentColor;
}
.cbp-langbtn__face::before {
  width: 20px; height: 20px;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18'/%3E%3C/svg%3E") center / contain no-repeat;
}
.cbp-langbtn__face::after {
  width: 14px; height: 14px;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.cbp-langbtn__code { display: none; }
.cbp-langbtn .gtranslate_wrapper { position: absolute; inset: 0; }
.cbp-langbtn select.gt_selector {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none;
  border: 0; opacity: 0; cursor: pointer;
  font-size: 16px;   /* iOS zooms into a focused control under 16px, visible or not */
  color: #14264A; background: #fff;   /* the native option list, where a browser styles it from the select */
}
.cbp-langbtn:hover .cbp-langbtn__face { background-color: var(--band-hover); border-color: var(--band-ink); }
/* the select is invisible, so its focus ring goes on the face */
.cbp-langbtn:has(select:focus-visible) .cbp-langbtn__face { outline: 3px solid var(--gold); outline-offset: 3px; }

/* App button — the install control. Ships hidden; pwa-install.js reveals it
   only where installing is possible and the app isn't installed already.
   On iOS Safari a click opens the "Share → Add to Home Screen" hint. */
.cbp-install-wrap { position: relative; display: inline-flex; flex: none; }
.cbp-install {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 40px; box-sizing: border-box; padding: 0 12px 0 9px;
  border: 1.5px solid var(--band-edge); border-radius: 3px; background: transparent;
  color: var(--band-ink); font-family: var(--serif); font-size: 15px; font-weight: 700; line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s, border-color 0.15s;
}
.cbp-install:hover { background-color: var(--band-hover); border-color: var(--band-ink); }
/* It's revealed late — Chromium's beforeinstallprompt lands after the page
   paints. On a desktop it is the row's last item and the row is anchored
   right, so a late arrival would shove the nav and the language button 80px
   left on every page view. So the slot is always kept, just invisible until
   revealed (visibility: hidden is unfocusable and out of the accessibility
   tree, like display: none). The phone cure is different: see below. */
.cbp-install[hidden] { display: inline-flex; visibility: hidden; }
.cbp-install__ico {
  width: 20px; height: 20px; display: block; flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v10m0 0l-3.5-3.5M12 13l3.5-3.5'/%3E%3Cpath d='M5 16v2.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V16'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v10m0 0l-3.5-3.5M12 13l3.5-3.5'/%3E%3Cpath d='M5 16v2.5A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5V16'/%3E%3C/svg%3E") center / contain no-repeat;
}
.cbp-install__hint[hidden] { display: none; }
.cbp-install__hint {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 30;
  width: max-content; max-width: 15rem;
  padding: 8px 11px; border-radius: 8px;
  background: var(--paper); color: var(--ink);
  font-family: var(--serif); font-size: 14px; font-weight: 400; line-height: 1.4; white-space: normal;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.18);
}
.cbp-install__share {
  display: inline-block; width: 0.95em; height: 0.95em; vertical-align: -0.14em;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v11'/%3E%3Cpath d='M8.5 7.5 12 4l3.5 3.5'/%3E%3Cpath d='M7 11H5.5A1.5 1.5 0 0 0 4 12.5v6A1.5 1.5 0 0 0 5.5 20h13a1.5 1.5 0 0 0 1.5-1.5v-6A1.5 1.5 0 0 0 18.5 11H17'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v11'/%3E%3Cpath d='M8.5 7.5 12 4l3.5 3.5'/%3E%3Cpath d='M7 11H5.5A1.5 1.5 0 0 0 4 12.5v6A1.5 1.5 0 0 0 5.5 20h13a1.5 1.5 0 0 0 1.5-1.5v-6A1.5 1.5 0 0 0 18.5 11H17'/%3E%3C/svg%3E") center / contain no-repeat;
}

@media (max-width: 600px) {
  .cbp-header__in {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
    gap: 4px 8px; padding: 8px 16px 0;
  }
  .cbp-header__brand,
  .cbp-header__right { display: contents; }
  .cbp-header a.cbp-brand__mark { grid-area: 1 / 1; justify-self: start; min-width: 44px; min-height: 44px; margin: 0; }
  .cbp-brand__mark svg { width: 34px; height: 34px; }
  /* positioned so the iOS install hint anchors here, see below */
  .cbp-header__utils { grid-area: 1 / 2; gap: 8px; position: relative; }
  /* 28px fits the 358px row of a 390px phone (329px); vw-scaled below that
     so a 320px phone keeps it on one line too */
  .cbp-header .cbp-wordmark {
    grid-area: 2 / 1 / 3 / -1;
    display: flex; align-items: center; min-height: 44px;
    font-size: clamp(22px, 7.2vw, 28px);
  }
  .cbp-langbtn__face { gap: 4px; padding: 0 8px; font-size: 14px; }
  .cbp-langbtn__face::after { width: 12px; height: 12px; }
  .cbp-langbtn__name { display: none; }
  .cbp-langbtn__code { display: inline; }
  /* Icon + "App", as on the desktop, sized like the language button. It
     arrives late here too, so it sits LEFT of the language button: it fills
     the row's empty middle and nothing already on screen moves — no slot to
     reserve. */
  .cbp-install[hidden] { display: none; }
  .cbp-install { gap: 4px; padding: 0 10px 0 7px; font-size: 14px; }
  /* The iOS hint hangs from the row's right edge, not the button's: the
     button sits a language button in from the gutter, and a 262px hint
     right-aligned to it ran 58px off a 320px screen. Unpositioning the wrap
     hands the hint to .cbp-header__utils. */
  .cbp-install-wrap { order: -1; position: static; }

  /* Row 3: the four section words (Home is the backpack and the wordmark).
     Pinned to the top of the screen by nav-stick.js (.cbp-stuck) once it
     scrolls off; the slot keeps its height meanwhile so nothing jumps. */
  .cbp-header .cbp-navwrap { grid-area: 3 / 1 / 4 / -1; }
  .cbp-header nav.wp-block-navigation {
    border-top: 1px solid var(--band-rule);
    /* vw-scaled so Escuela · Crianza · Consejos · Calendario, and the longer
       machine-translated labels, share the one row on a 320px phone */
    font-size: clamp(13px, 3.85vw, 15px);
  }
  .cbp-header .cbp-nav-home { display: none; }
  .cbp-header .wp-block-navigation__container {
    width: 100%; flex-wrap: nowrap; justify-content: space-between; gap: 0;
  }
  .cbp-header .wp-block-navigation__container li { min-width: 0; margin: 0; }
  .cbp-header .wp-block-navigation .wp-block-navigation-item__content {
    padding: 3px 4px 0; text-align: center;
    overflow-wrap: anywhere;   /* never wider than its cell: a too-wide strip widens the phone's viewport */
  }
  /* Pinned: the same band, lifted off the page. Its own view-transition
     snapshot only while pinned — pinned on both pages it never moves and only
     the gold underline crossfades; in flow it rides the root crossfade (named
     there, it would slide down from the top of the old screen). */
  .cbp-header nav.wp-block-navigation.cbp-stuck {
    position: fixed; top: 0; left: 0; right: 0;
    z-index: 90;   /* above content, below the lightbox (9999) */
    background: var(--band);
    border-top: 0;
    padding: env(safe-area-inset-top) max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left));
    box-shadow: var(--band-lift);
    view-transition-name: cbp-tabbar;
  }
  /* Anchor jumps (acc-hash.js, /events/#meals) land under the pinned strip:
     its 44px plus a breath. */
  html { scroll-padding-top: calc(52px + env(safe-area-inset-top)); }
}

/* ---------- Footer: the navy band ----------
   Says who runs the site — parents, not the school or CPS — so it carries no
   school address or phone. The dark-mode toggle sits at its left edge. */
.cbp-footer { background: var(--band); color: var(--band-text); }
.cbp-footer__in {
  box-sizing: content-box;
  max-width: var(--wide); margin: 0 auto;
  padding: 24px clamp(16px, 4vw, 40px) 32px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  font-family: var(--serif); font-size: 15px; line-height: 1.5; text-align: center;
}
.cbp-footer .cbp-footer__in > * { margin: 0; }
.cbp-footer a { color: var(--band-ink); }
.cbp-footer a:hover { color: var(--band-ink); text-decoration-thickness: 2px !important; }
.cbp-footer .cbp-footer__name {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--caslon); font-size: 20px; font-weight: 700; line-height: 1.2;
  color: var(--band-ink);
}
.cbp-footer__name svg { display: block; flex: none; width: 28px; height: 28px; }
.cbp-footer .cbp-footer__about { max-width: 40em; }
.cbp-footer__official,
.cbp-footer__nav a {
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
  vertical-align: top;   /* no baseline gap under the 44px target */
  font-weight: 700;
}
.cbp-footer__nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 0 20px; }
.cbp-footer .cbp-footer__credit { font-size: 13px; font-style: italic; color: var(--band-fine); }

/* Colours: a three-way switch at the footer's left edge — match my device (the default), light,
   dark — three outlined 44px squares joined like the header's buttons, the chosen one filled.
   Icons only (a half-filled circle, a sun, a moon), labelled in both languages for screen readers
   and on hover. Ships hidden; scheme-toggle.js reveals it once wired (no JS = no dead control,
   and the site still follows the device from CSS). */
.cbp-scheme[hidden] { display: none; }
.cbp-footer .cbp-scheme { align-self: flex-start; }
.cbp-scheme { display: inline-flex; }
.cbp-scheme__btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; box-sizing: border-box; margin: 0; padding: 0;
  border: 1.5px solid var(--band-edge); border-radius: 0; background: transparent;
  color: var(--band-ink); cursor: pointer;
  transition: background-color 0.15s, color 0.15s;
}
.cbp-scheme__btn + .cbp-scheme__btn { margin-left: -1.5px; }
.cbp-scheme__btn:first-child { border-radius: 3px 0 0 3px; }
.cbp-scheme__btn:last-child { border-radius: 0 3px 3px 0; }
.cbp-scheme__btn:hover { background-color: var(--band-hover); }
.cbp-scheme__btn[aria-pressed="true"] { background-color: var(--band-ink); color: var(--band); }
.cbp-scheme__btn:focus-visible { position: relative; z-index: 1; }
.cbp-scheme__btn::before {
  content: ""; width: 20px; height: 20px; display: block;
  background: currentColor;
  -webkit-mask: var(--ico) center / contain no-repeat;
          mask: var(--ico) center / contain no-repeat;
}
.cbp-scheme__btn--system { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8'%3E%3Ccircle cx='12' cy='12' r='8.5'/%3E%3Cpath d='M12 3.5a8.5 8.5 0 0 0 0 17z' fill='%23000' stroke='none'/%3E%3C/svg%3E"); }
.cbp-scheme__btn--light { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2m0 16v2M4.9 4.9l1.4 1.4m11.4 11.4 1.4 1.4M2 12h2m16 0h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4'/%3E%3C/svg%3E"); }
.cbp-scheme__btn--dark { --ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5z'/%3E%3C/svg%3E"); }

@media (max-width: 600px) {
  .cbp-footer__in { padding: 24px 20px 36px; gap: 8px; }
  .cbp-footer__nav { gap: 0 18px; }
}

/* ---------- Homepage: main.cbp-home (templates/front-page.html, homepage.html) ----------
   The canvas's Phone · v4 and Desktop · v4 boards (redesign-plan.md § Build brief →
   Homepage). Keyed on .cbp-home, the template's class, not on page-id-6: the Spanish twin
   has the homepage template but neither the home body class nor its own page id.
   Phone first, top to bottom: the Today board, the callout slot, Your school (3 x 2
   tiles), Parenting, On Instagram, Coming up. From 880px (where the top row is sure to
   fit side by side) the callout sits beside the board, the tiles go 6 x 1 and the cards
   take the desktop sizes; Parenting + Instagram and Coming up share a row from ~1,000px,
   where their flex bases fit.
   Drawings are alpha masks (assets/drawings/*.webp, Pearson Scott Foresman and
   Openclipart line art) painted in --drawing — navy on paper, paper at night — so they
   need no blend mode; inside the gold cards they take the gold cards' navy.
   The board's and the callout's days ship in the markup and the plugin's script reveals
   one (mu-plugins/courtenay-bacpac-home.php), so [hidden] must win over every display. */
.cbp-home {
  box-sizing: content-box;
  max-width: var(--wide); margin: 0 auto;
  padding: 16px clamp(16px, 4vw, 40px) 40px;
}
.cbp-home :where(.is-layout-flow) > * { margin-block: 0; }
.cbp-home .wp-block-post-content { display: flex; flex-direction: column; gap: 32px; }
.cbp-home [hidden] { display: none !important; }

/* drawings */
.cbp-pic {
  display: block; flex: none;
  background-color: var(--drawing);
  -webkit-mask: var(--pic) center / contain no-repeat;
          mask: var(--pic) center / contain no-repeat;
}
.cbp-pic--apple, .cbp-tile--menu { --pic: url("drawings/apple.webp"); }
.cbp-pic--calendar { --pic: url("drawings/calendar.webp"); }
.cbp-tile--everyday { --pic: url("drawings/globe.webp"); }
/* Call the office: a cell phone (Openclipart #1631, Johnny Automatic, CC0), in place of the
   candlestick telephone (owner, 2026-10-09) */
.cbp-tile--call { --pic: url("drawings/cellphone.webp"); }
/* Aspen (grades, absences): a laptop (Openclipart #1597, Johnny Automatic, public domain), in
   place of the child in bed when "Report an absence" became the Aspen tile (owner, 2026-10-10) */
.cbp-tile--aspen { --pic: url("drawings/laptop.webp"); }
.cbp-tile--enroll { --pic: url("drawings/hiker.webp"); }
.cbp-tile--staff { --pic: url("drawings/owl.webp"); }
/* the School hub's other four (/school/): a volleyball (Openclipart #256746, spacefem, CC0; it
   replaced PSF's batter on 2026-10-09 because the school has no baseball, owner), a nurse
   listening to a child's chest (PSF Stethoscope), the scales of justice (PSF Balance - Scales of
   Justice), and a handshake (Openclipart #181647, liftarn, public domain) */
.cbp-tile--sports { --pic: url("drawings/volleyball.webp"); }
.cbp-tile--support { --pic: url("drawings/nurse.webp"); }
.cbp-tile--rights { --pic: url("drawings/scales.webp"); }
.cbp-tile--councils { --pic: url("drawings/handshake.webp"); }
/* Parenting: the homepage's rows and the Parenting hub's tiles (page 7). Physical Health is a
   plate of food (Openclipart #8677, Johnny Automatic, CC0): nutrition, in place of PSF's croquet
   player (owner, 2026-10-09). */
.cbp-row--academic, .cbp-tile--academic { --pic: url("drawings/microscope.webp"); }
.cbp-row--emotional, .cbp-tile--emotional { --pic: url("drawings/brain.webp"); }
.cbp-row--social, .cbp-tile--social { --pic: url("drawings/seesaw.webp"); }
.cbp-row--health, .cbp-tile--health { --pic: url("drawings/plate.webp"); }

/* -- top row: the Today board + the callout slot (the PAC's ask, today's events, or art) */
.cbp-home-top { display: flex; flex-wrap: wrap; align-items: stretch; gap: 12px 20px; }
.cbp-home-top > .cbp-board { flex: 2 1 480px; min-width: 0; }
.cbp-home-top > .cbp-ask,
.cbp-home-top > .cbp-callout { flex: 1 1 280px; min-width: 0; }

/* The board: a white card with a double rule. Its inside switches to the wide layout by
   its own width (weather and lunch side by side), so a full-width board on a tablet
   gets it too. Both day words ship (Today / Tomorrow) and the --next class picks one. */
.cbp-board {
  container: cbp-board / inline-size;
  box-sizing: border-box; padding: 4px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
}
.cbp-board__in {
  box-sizing: border-box; height: 100%;
  display: flex; flex-direction: column; gap: 12px;
  padding: 12px 16px 16px; border: 1px solid var(--line);
}
.cbp-board .cbp-board__date {
  margin: 0; text-align: center;
  font-family: var(--serif); font-size: 12px; font-weight: 700; line-height: 1.4;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--quiet);
}
.cbp-board .cbp-next,
.cbp-callout .cbp-next { display: none; }
.cbp-board--next .cbp-now,
.cbp-callout--next .cbp-now { display: none; }
.cbp-board--next .cbp-next,
.cbp-callout--next .cbp-next { display: inline; }

.cbp-board__row { flex: 1; display: flex; flex-direction: column; gap: 12px; }
.cbp-board__wx { display: block; color: inherit; text-decoration: none; }
.cbp-board__sky { display: flex; align-items: center; gap: 12px; }
/* cbp_wx_icon() draws at 15px with a 2-unit stroke; CSS stroke-width on the root
   outranks the attribute and inherits, so the line art matches the drawings */
.cbp-board__sky .cbp-wx__icon { flex: none; width: 64px; height: 64px; color: var(--ink); stroke-width: 1.7; }
.cbp-board__sky .cbp-wx__icon g { stroke-width: 2.8; }
.cbp-board__temp {
  font-family: var(--caslon); font-size: 58px; font-weight: 700; line-height: 0.9;
  letter-spacing: -0.02em; font-variant-numeric: lining-nums;
}
.cbp-board__wxtext { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.cbp-board__noon { font-weight: 700; }
.cbp-board__range { font-size: 14px; color: var(--quiet); }
.cbp-board__src { font-size: 13px; font-style: italic; color: var(--quiet); }
.cbp-board__wx:hover .cbp-board__src { text-decoration: underline; }
.cbp-board__wx + .cbp-board__day { padding-top: 12px; border-top: 1px solid var(--rule); }
.cbp-board__cell { display: flex; align-items: center; gap: 12px; color: inherit; text-decoration: none; }
.cbp-board__cell .cbp-pic { width: 64px; height: 64px; }
.cbp-board__txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cbp-board__eyebrow {
  font-size: 12px; font-weight: 700; line-height: 1.4;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--quiet);
}
.cbp-board__lunch { font-family: var(--caslon); font-size: 19px; line-height: 1.25; }
.cbp-board__more { font-size: 14px; font-style: italic; text-decoration: underline; text-underline-offset: 3px; }
.cbp-board__cell--lunch:hover .cbp-board__more { text-decoration-thickness: 2px; }
.cbp-board__off { font-family: var(--caslon); font-size: 22px; font-weight: 700; line-height: 1.2; }
.cbp-board__reason { font-size: 15px; font-style: italic; }
@container cbp-board (min-width: 540px) {
  .cbp-board__in { padding: 12px 20px 16px; }
  .cbp-board .cbp-board__date { letter-spacing: 0.2em; }
  .cbp-board__row { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0; }
  .cbp-board__wx { flex: 3 1 300px; padding: 8px 0; }
  .cbp-board__sky { gap: 14px; }
  .cbp-board__sky .cbp-wx__icon { width: 80px; height: 80px; }
  .cbp-board__temp { font-size: 72px; }
  .cbp-board__day { flex: 2 1 240px; padding: 8px 0; }
  .cbp-board__wx + .cbp-board__day { padding: 8px 0 8px 20px; border-top: 0; border-left: 1px solid var(--line); }
  .cbp-board__cell { gap: 14px; }
  .cbp-board__cell .cbp-pic { width: 72px; height: 72px; }
  .cbp-board__txt { gap: 3px; }
  .cbp-board__lunch { font-size: 20px; }
  .cbp-board__off { font-size: 24px; }
}

/* The gold cards: the PAC's ask (an HTML block on Home, the only place the page may
   shout) and today's events. Gold and navy in both schemes. */
.cbp-ask,
.cbp-callout__event {
  box-sizing: border-box; margin: 0; padding: 14px 16px;
  border: 1px solid var(--on-gold); background: var(--gold); color: var(--on-gold);
}
.cbp-ask :focus-visible,
.cbp-callout__event:focus-visible { outline-color: var(--on-gold); }
.cbp-ask {
  display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; gap: 8px 12px;
}
.cbp-ask::before {
  content: ""; grid-row: 1 / span 2; width: 56px; height: 56px;
  background-color: var(--on-gold);
  -webkit-mask: url("drawings/pigeon.webp?v=2") center / contain no-repeat;
          mask: url("drawings/pigeon.webp?v=2") center / contain no-repeat;
}
.cbp-ask p { margin: 0; }
.cbp-ask p:empty, .cbp-ask a:empty { display: none; }
.cbp-ask__text { font-family: var(--caslon); font-size: 18px; line-height: 1.3; }
.cbp-ask__go a {
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px;
  padding: 0 18px; background: #14264A; color: #FFFFFF; font-weight: 700; text-decoration: none;
}
.cbp-ask__go a:hover { background: #0B1733; color: #FFFFFF; }

.cbp-callout { display: flex; flex-direction: column; }
.cbp-callout__event { flex: 1 0 auto; display: flex; align-items: center; gap: 12px; text-decoration: none; }
.cbp-callout__event .cbp-pic { width: 56px; height: 56px; background-color: var(--on-gold); }
.cbp-callout__txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cbp-callout__when { font-size: 12px; font-weight: 700; line-height: 1.4; letter-spacing: 0.16em; text-transform: uppercase; }
.cbp-callout__title { font-family: var(--caslon); font-size: 19px; font-weight: 700; line-height: 1.25; }
.cbp-callout__note,
.cbp-callout__also { font-size: 14px; font-style: italic; }
.cbp-callout__event:hover .cbp-callout__title { text-decoration: underline; }

/* Student art: the painting fills the card, one small navy label in the corner. */
.cbp-callout__art {
  /* flex-basis auto, not 0: the image is absolutely placed, so with a zero basis the
     card's content height — and so the card — would be 0 in the phone's column */
  position: relative; display: block; flex: 1 0 auto; height: 220px; overflow: hidden;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-callout__art img {
  position: absolute; inset: 0; display: block;
  width: 100%; height: 100%; max-width: none; object-fit: cover;
}
.cbp-callout__label {
  position: absolute; left: 10px; bottom: 10px; padding: 5px 9px;
  background: #14264A; color: #FFFFFF;
  font-size: 12px; font-weight: 700; line-height: 1.2; letter-spacing: 0.16em; text-transform: uppercase;
}

/* -- section headings: Caslon, with a line drawing before the words — Your school: a protractor
   (PSF, lines thickened; it replaced the abacus on 2026-10-09, owner, and the class keeps the
   abacus name because Home's content and its Spanish twin carry it); Parenting: a sprout (the
   owner's growing-plant idea; the Inglenook fireside was unreadable small); Coming up: a school hand bell, lying on its side as drawn. Bigger than the boards'
   56px so they read (owner, 2026-10-09). Tried and dropped the same day: drawings several
   times this size tucked behind the cards, and glass cards. */
.cbp-sec { margin: 0; min-width: 0; }
/* Block, not flex: a heading's words may carry a notranslate span ("On Instagram"), and
   flex would turn every text run into its own item with a gap between them. */
.cbp-home .cbp-sec__h {
  display: block; margin: 0 0 12px;
  font-family: var(--caslon); font-size: 24px; font-weight: 700; line-height: 1.2; color: var(--ink);
}
.cbp-sec__h--abacus { --pic: url("drawings/protractor.webp"); --pic-w: 93px; --pic-h: 62px; }
.cbp-sec__h--sprout { --pic: url("drawings/sprout.webp");    --pic-w: 38px;  --pic-h: 72px; }
.cbp-sec__h--bell   { --pic: url("drawings/bell-side.webp"); --pic-w: 116px; --pic-h: 49px; }
/* The section headings link to their pages (/parenting/, /events/; owner, 2026-10-09), and the
   drawing rides on the link, so tapping the picture goes there too. No underline until hovered.
   Your school's heading has no visible words since the Assembly Hall picture (see below); its link
   is the "More about the school" line under the blocks. */
.cbp-sec__h a { color: inherit; text-decoration: none; }
.cbp-sec__h a:hover { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
.cbp-sec__h--abacus > a::before,
.cbp-sec__h--abacus > .cbp-sr::before,   /* Home's wordless heading (see the Assembly Hall picture) */
.cbp-sec__h--sprout > a::before,
.cbp-sec__h--bell > a::before {
  content: ""; display: inline-block; vertical-align: middle; margin: -0.15em 12px 0 0;
  width: var(--pic-w); height: var(--pic-h);
  background-color: var(--drawing);
  -webkit-mask: var(--pic) center / contain no-repeat;
          mask: var(--pic) center / contain no-repeat;
}
.cbp-home .cbp-sec__h--abacus { text-align: center; }
.cbp-sec__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 0 12px; }
.cbp-home .cbp-sec__head .cbp-sec__h { margin: 0; }
@media (max-width: 360px) {
  .cbp-sec__h--bell { --pic-w: 96px; --pic-h: 41px; }   /* "Próximamente" + the bell in 288px */
}
.cbp-sec__all { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; font-style: italic; color: var(--link); }

/* -- The Assembly Hall picture (owner, 2026-10-09): the school's own front — the carved sign, the
   three mosaic arches and the doors — stands behind Your school's blocks, in the owner's coloured-
   pencil drawing (doors already the blocks' slate blue), cropped from just under the cornice to the
   top step. The one full-colour picture the theme paints (assets/art/, not an alpha mask): it is a
   scene, not a motif, and the mosaics are the point. The drawing's own torn brick edge does the
   fading at the sides: its cream sheet is cut to transparency (docs/1-website-shell/
   assembly-hall-cutout.py, which also makes the two files), so the edge sits on paper by day and on
   navy at night with no halo. Chosen over eleven other cuts; this one for the mosaics between the
   blocks (below).
   Geometry, all width maths so it needs no script: the picture rides on the heading (its ::after,
   starting where the heading ends), is as wide as the section up to 951px, and its height follows
   the crop (2124 x 918). The heading's bottom margin is the room the picture needs above the
   blocks. Desktop: picture height minus the overlap, a tile's width + 2px (the picture ends 2px
   under the blocks' feet, 8px above the captions, so the words always sit on paper). Phones: the
   picture's door line (row 464 of 918), so the blocks stand where the doors start and the three
   arches stay whole above them. Percent margins resolve against the width, which is what makes
   this work.
   951px is not a round number on purpose. The four mosaic columns beside the doors sit at 213, 781,
   1356 and 1906 of the crop's 2124, and the five 18px gaps between the six blocks sit at fixed
   places in the 1120px row (centres 189px apart). At 951px the two outer columns land exactly in
   the two end gaps, 38px wide against the 18px gap, so the gaps are solid mosaic; the fit holds
   from 930 to 975px. The inner pair is 289px apart at that scale, so no centred width can reach
   them. If the tile gap or the row width ever changes, re-fit: the gap centres are at
   80 + n(tile + 18) - 9 for n = 1..5 on a 1280 screen.
   Phones get a 700px file (63 KB), desktop a 1200px one (163 KB). Source:
   docs/assets/images/assemblyhall-colored-pencil-theme-blue.png. */
.cbp-home .cbp-sec--school .cbp-sec__h--abacus > .cbp-sr::before { display: none; }
.cbp-home .cbp-sec--school .cbp-sec__h {
  position: relative;
  margin-bottom: calc(min(100%, 951px) * 0.21845);
}
/* No words above the picture (owner, 2026-10-09): the carved sign is the heading. The h2 stays —
   the picture rides on it and screen readers still hear "Your school" (a .cbp-sr span, no link) —
   and the School-hub link lives under the blocks instead ("More about the school", a .cbp-sec__go
   line in Home's HTML block), where the other sections keep theirs. A hidden link over the carved
   sign was tried and taken out the same day (owner). */
.cbp-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.cbp-home .cbp-sec--school .cbp-sec__h::after {
  content: ""; position: absolute; z-index: -1; top: 100%; left: 50%; transform: translateX(-50%);
  width: min(100%, 951px); aspect-ratio: 2124 / 918; pointer-events: none;
  background: url("art/assembly-hall-s.webp?v=2") center top / 100% auto no-repeat;
  /* soft top and bottom: the cut brick fades in over the first 4%, and the last 10px fade out; the
     sides are the drawing's own torn edge */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 4%, #000 calc(100% - 10px), transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 4%, #000 calc(100% - 10px), transparent 100%);
}
/* Families on metered connections skip the picture and get the words back */
@media (prefers-reduced-data: reduce) {
  .cbp-home .cbp-sec--school .cbp-sec__h { margin-bottom: 12px; }
  .cbp-home .cbp-sec--school .cbp-sec__h::after { display: none; }
  .cbp-home .cbp-sec--school .cbp-sec__h--abacus > .cbp-sr::before { display: inline-block; }
  .cbp-home .cbp-sec--school .cbp-sr { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; }
}

/* -- Play blocks: Your school on Home, and the School hub's tiles (/school/) (owner, 2026-10-09).
   Each tile is a toy block seen face-on: a coloured frame around a white face with the drawing on
   it, and a solid shaded side to the lower right (stacked hard shadows, so it reads as a cube, not
   a floating card); the label and its line sit under the block like a caption. Gold, red and blue
   (primary colours for a primary school; the red is the Assembly Hall's brick) in the order
   G R B R B G, so no two neighbours match in the 6 x 1 desktop row or a 3 x 2 grid.
   Hover lifts the block a little; pressing pushes it flat. ::after is the block, ::before the
   drawing on it. Every .cbp-tile is a block, except on the Parenting hub (page 7), whose four
   tiles wear Home's Parenting rows instead (they undo the block below). */
.cbp-home .cbp-tiles--quick {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px 12px;
  margin: 0; padding: 0;
}
/* The School hub: 3 x 2, blocks capped at Home's desktop size so six don't fill the screen */
.cbp-page .cbp-tiles {
  display: grid; grid-template-columns: repeat(3, minmax(0, 176px)); justify-content: center;
  gap: 22px 14px; margin: 28px 0 8px; padding: 0;
}
.cbp-tile {
  --depth: 6px; --frame: 8px; --block: var(--block-gold); --block-side: var(--block-gold-side);
  position: relative; display: block; box-sizing: border-box; min-height: 0;
  /* the block's height: padding % is of the tile's own width, the block is that minus its side */
  padding: calc(100% - var(--depth) + var(--depth) + 8px) 0 0;
  color: var(--ink); text-align: center; text-decoration: none;
}
.cbp-tile:nth-child(2), .cbp-tile:nth-child(4) { --block: var(--block-red); --block-side: var(--block-red-side); }
.cbp-tile:nth-child(3), .cbp-tile:nth-child(5) { --block: var(--block-blue); --block-side: var(--block-blue-side); }
.cbp-tile::after {
  content: ""; position: absolute; top: 0; left: 0; z-index: 0;
  width: calc(100% - var(--depth)); aspect-ratio: 1; box-sizing: border-box;
  border: 1px solid var(--block-edge); background: var(--card);
  box-shadow:
    inset 2px 2px 0 rgba(255, 255, 255, 0.4),   /* a bevel on the frame's lit edges */
    inset 0 0 0 var(--frame) var(--block),
    inset 0 0 0 calc(var(--frame) + 1px) var(--block-edge),
    1px 1px 0 var(--block-side), 2px 2px 0 var(--block-side), 3px 3px 0 var(--block-side),
    4px 4px 0 var(--block-side), 5px 5px 0 var(--block-side), 6px 6px 0 var(--block-side),
    6px 6px 0 1px var(--block-edge);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.cbp-tile::before {
  content: ""; position: absolute; top: 0; left: 0; z-index: 1;
  display: block; width: calc(100% - var(--depth)); height: auto; aspect-ratio: 1; margin: 0;
  background-color: var(--drawing);
  -webkit-mask: var(--pic) center / 62% 62% no-repeat;
          mask: var(--pic) center / 62% 62% no-repeat;
  transition: transform 0.12s ease;
}
.cbp-tile:hover::after,
.cbp-tile:hover::before { transform: translate(-2px, -2px); }
.cbp-tile:hover::after {
  box-shadow:
    inset 2px 2px 0 rgba(255, 255, 255, 0.4),
    inset 0 0 0 var(--frame) var(--block),
    inset 0 0 0 calc(var(--frame) + 1px) var(--block-edge),
    1px 1px 0 var(--block-side), 2px 2px 0 var(--block-side), 3px 3px 0 var(--block-side),
    4px 4px 0 var(--block-side), 5px 5px 0 var(--block-side), 6px 6px 0 var(--block-side),
    7px 7px 0 var(--block-side), 8px 8px 0 var(--block-side),
    8px 8px 0 1px var(--block-edge);
}
.cbp-tile:active::after,
.cbp-tile:active::before { transform: translate(var(--depth), var(--depth)); }
.cbp-tile:active::after {
  box-shadow: inset 2px 2px 0 rgba(255, 255, 255, 0.4), inset 0 0 0 var(--frame) var(--block), inset 0 0 0 calc(var(--frame) + 1px) var(--block-edge);
}
.cbp-tile b { display: block; margin: 0; font-family: var(--caslon); font-size: 15px; font-weight: 700; line-height: 1.15; }
.cbp-tile:hover b { text-decoration: underline; text-underline-offset: 3px; }
.cbp-tile .cbp-tile__sub { display: block; margin: 3px 0 0; font-size: 12px; line-height: 1.3; color: var(--quiet); }
.cbp-tile__sub span { display: inline; margin: 0; font-size: inherit; color: inherit; }

/* -- the two columns: Parenting + Instagram, and Coming up */
.cbp-home-cols { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 32px 44px; }
.cbp-home-main { flex: 1 1 520px; min-width: 0; display: flex; flex-direction: column; gap: 32px; }
.cbp-home-cols > .cbp-sec--coming { flex: 1 1 360px; }

/* Parenting: one card of four rows, a drawing beside a title and one line. The Parenting hub
   (page 7) wears the same card: its .cbp-tiles / .cbp-tile links take these rules, and undo the
   play block's absolute drawing and its block (the last group). */
.cbp-rows,
body.page-id-7 .cbp-tiles {
  display: flex; flex-direction: column;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
body.page-id-7 .cbp-tiles { margin: 8px 0 0; gap: 0; }
.cbp-row,
body.page-id-7 .cbp-tile {
  display: grid; grid-template-columns: 70px minmax(0, 1fr); align-content: center; gap: 2px 12px;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
  color: var(--ink); text-align: left; text-decoration: none;
}
.cbp-row:last-child,
body.page-id-7 .cbp-tile:last-child { border-bottom: 0; }
.cbp-row::before,
body.page-id-7 .cbp-tile::before {
  content: ""; grid-row: 1 / span 2; align-self: center; width: 70px; height: 70px;
  background-color: var(--drawing);
  -webkit-mask: var(--pic) center / contain no-repeat;
          mask: var(--pic) center / contain no-repeat;
}
.cbp-row b,
body.page-id-7 .cbp-tile b { align-self: end; font-family: var(--caslon); font-size: 18px; font-weight: 700; line-height: 1.2; }
.cbp-row span,
body.page-id-7 .cbp-tile .cbp-tile__sub { align-self: start; margin: 0; font-size: 14px; font-style: italic; line-height: 1.4; color: var(--quiet); }
.cbp-row:hover b,
body.page-id-7 .cbp-tile:hover b { text-decoration: underline; text-underline-offset: 3px; }
body.page-id-7 .cbp-tile::before { position: static; aspect-ratio: auto; transform: none; }
body.page-id-7 .cbp-tile::after { content: none; }

/* On Instagram: the cards themselves are styled in the Instagram section below */
.cbp-sec--ig .cbp-sec__head { align-items: baseline; }
.cbp-home .cbp-ig-blocked { font-size: 13px; font-style: italic; color: var(--quiet); }
.cbp-home .cbp-ig-stack { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* Coming up: [cbp_school_calendar strip="4" layout="dates"], PAC / BAC meetings in pale gold */
.cbp-cal--dates {
  list-style: none; margin: 0; padding: 0;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-cal--dates .cbp-cal__item {
  display: flex; align-items: center; gap: 14px; margin: 0;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.cbp-cal--dates .cbp-cal__item:last-child { border-bottom: 0; }
.cbp-cal--dates .is-meeting { background: var(--gold-pale); }
.cbp-cal__dblock { flex: none; width: 52px; display: flex; flex-direction: column; align-items: center; line-height: 1; }
.cbp-cal__mon { font-size: 11px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--quiet); }
.cbp-cal__dnum { margin-top: 2px; font-family: var(--caslon); font-size: 26px; font-weight: 700; font-variant-numeric: lining-nums; }
.cbp-cal__what { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cbp-cal--dates .cbp-cal__title { font-weight: 700; line-height: 1.3; }
.cbp-cal__when { font-size: 15px; font-style: italic; color: var(--quiet); }
.cbp-cal--dates .is-meeting .cbp-cal__mon,
.cbp-cal--dates .is-meeting .cbp-cal__when { color: var(--ink); }
.cbp-sec__go { display: flex; flex-direction: column; gap: 4px; margin: 14px 0 0; }
.cbp-sec__btn {
  display: flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 22px;
  background: var(--btn); color: var(--btn-ink); font-weight: 700; text-decoration: none;
}
.cbp-sec__btn:hover { background: var(--btn-hover); color: var(--btn-ink); }
.cbp-sec__go .cbp-sec__all { justify-content: center; }

@media (min-width: 880px) {
  .cbp-home { padding-top: 28px; padding-bottom: 56px; }
  .cbp-home .wp-block-post-content { gap: 44px; }
  .cbp-home-main { gap: 36px; }
  .cbp-home .cbp-sec__h { font-size: 28px; }
  .cbp-sec--school .cbp-sec__h { margin-bottom: 14px; }
  /* the Assembly Hall picture: overlap = a tile's width + 2px (six tiles, five 18px gaps) */
  .cbp-home .cbp-sec--school .cbp-sec__h { margin-bottom: calc(min(100%, 951px) * 0.43220 - ((100% - 90px) / 6 + 2px)); }
  .cbp-home .cbp-sec--school .cbp-sec__h::after { background-image: url("art/assembly-hall.webp?v=2"); }
  .cbp-sec__h--abacus { --pic-w: 117px; --pic-h: 78px; }
  .cbp-sec__h--sprout { --pic-w: 46px;  --pic-h: 88px; }
  .cbp-sec__h--bell   { --pic-w: 140px; --pic-h: 88px; } /* drawn 59px tall, centred in the sprout's 88px, so the two cards side by side start level */

  .cbp-ask { grid-template-columns: minmax(0, 1fr); align-content: center; gap: 10px; padding: 18px 20px; }
  .cbp-ask::before { grid-row: auto; width: 64px; height: 64px; }
  .cbp-ask__text { font-size: 20px; }
  .cbp-ask__go a { min-height: 46px; padding: 0 22px; }
  .cbp-callout__event { flex-direction: column; align-items: flex-start; justify-content: center; gap: 8px; padding: 18px 20px; }
  .cbp-callout__event .cbp-pic { width: 64px; height: 64px; }
  .cbp-callout__title { font-size: 22px; }
  .cbp-callout__note,
  .cbp-callout__also { font-size: 15px; }
  .cbp-callout__art { height: auto; min-height: 230px; }

  .cbp-home .cbp-tiles--quick { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px 18px; }
  .cbp-home .cbp-tile { --frame: 10px; padding-top: calc(100% + 10px); }
  .cbp-home .cbp-tile b { font-size: 17px; }
  .cbp-home .cbp-tile .cbp-tile__sub { font-size: 13px; }

  .cbp-rows,
  body.page-id-7 .cbp-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
  .cbp-row,
  body.page-id-7 .cbp-tile { grid-template-columns: 76px minmax(0, 1fr); padding: 12px 16px; }
  .cbp-row:nth-child(-n+2),
  body.page-id-7 .cbp-tile:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
  .cbp-row:nth-child(n+3),
  body.page-id-7 .cbp-tile:nth-child(n+3) { border-bottom: 0; }
  .cbp-row::before,
  body.page-id-7 .cbp-tile::before { width: 76px; height: 76px; }
  .cbp-row b,
  body.page-id-7 .cbp-tile b { font-size: 19px; }

  .cbp-cal--dates .cbp-cal__item { padding: 12px 16px; }
  .cbp-sec__go { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 20px; }
  .cbp-sec__btn { display: inline-flex; }
}

/* ---------- Inner pages: templates/page.html and single-cbp_minutes.html ----------
   The homepage's grammar carried into every other page (redesign-plan.md, § Build approach):
   a plain Caslon title and its intro line, Caslon section headings, and the content's own
   components as white cards with navy rules and a 3px bottom edge. No ghost photos, no "//",
   no monospace; the emoji that open many headings are stripped on output (functions.php).
   Content is styled where it already is — the .cbp-* markup the pages and mu-plugins emit — so
   no page was rewritten for v4. Headings sit in :where() so a component's own heading class
   (.cbp-cal__month, .cbp-ledger__year, .cbp-meals__block-h) wins with one class. */
.cbp-page .wp-block-post-title,
.cbp-page .wp-block-query-title {
  margin: 0 0 8px;
  font-family: var(--caslon); font-size: 32px; font-weight: 700; line-height: 1.15; color: var(--ink);
}
.cbp-page .entry-content { margin-top: 0; }
.cbp-lead { margin: 0 0 28px; font-size: 19px; line-height: 1.5; color: var(--quiet); }
.cbp-lead strong { font-weight: 700; color: var(--ink); }

:where(.cbp-page) h2 {
  margin: 40px 0 12px;
  font-family: var(--caslon); font-size: 24px; font-weight: 700; line-height: 1.2; color: var(--ink);
}
:where(.cbp-page) h3 {
  margin: 28px 0 6px;
  font-family: var(--caslon); font-size: 20px; font-weight: 700; line-height: 1.25; color: var(--ink);
}
:where(.cbp-page) h4 { margin: 20px 0 4px; font-size: 18px; font-weight: 700; line-height: 1.3; }
/* a long page's sections (Every Day has ten) divide with a hairline, like a card's rows */
/* (not the first heading, nor one straight under an h2) */
:where(.cbp-page .entry-content > .cbp-prose) > :not(h2) + h3 { padding-top: 24px; border-top: 1px solid var(--rule); }
/* the "· big school decisions" tag after a council's name */
.cbp-prose h3 em { font-family: var(--serif); font-size: 0.8em; font-style: italic; font-weight: 400; color: var(--quiet); }

.cbp-prose { line-height: 1.6; }
.cbp-prose > :first-child { margin-top: 0; }
.cbp-prose p { margin: 10px 0; }
.cbp-prose ul, .cbp-prose ol { margin: 10px 0 14px; padding-left: 1.3em; }
.cbp-prose li { margin: 6px 0; }
.cbp-prose li::marker { color: var(--ink); }
.cbp-prose strong { font-weight: 700; }
.cbp-prose hr { margin: 24px 0; border: 0; border-top: 1px solid var(--rule); }
.cbp-page .entry-content a:where(:not([class])) {
  color: var(--link); overflow-wrap: anywhere;
  text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.cbp-page .entry-content a:where(:not([class])):hover { color: var(--link-hover); text-decoration-thickness: 2px; }

/* Source quotes: the excerpt as reading text behind a navy rule; the last <p>, the
   "Source, title" line, small and quiet (memory: one quote per blockquote) */
.cbp-prose blockquote {
  margin: 20px 0; padding: 2px 0 2px 16px;
  border-left: 3px solid var(--line); color: var(--ink);
}
.cbp-prose blockquote p { margin: 8px 0; }
.cbp-prose blockquote p:first-child { margin-top: 0; }
.cbp-prose blockquote p:last-child { margin-bottom: 0; }
.cbp-prose blockquote p:last-child:not(:first-child) { font-size: 15px; font-style: italic; line-height: 1.45; color: var(--quiet); }

/* "Verified September 2026" — the content types it in lower case */
.cbp-verified { margin: 36px 0 0; font-size: 14px; font-style: italic; color: var(--quiet); }
.cbp-verified::first-letter { text-transform: uppercase; }
.cbp-verified:lang(en) { text-transform: capitalize; }

/* BAC / PAC chips in text (the Minutes page's intro): gold and navy in both schemes */
.cbp-bac, .cbp-pac { display: inline-block; padding: 0 0.3em; font-weight: 700; line-height: 1.35; }
.cbp-bac { color: #14264A; background: var(--gold); }
.cbp-pac { color: #FFFFFF; background: #14264A; }

/* A button typed in the editor (none published today): the homepage's navy button */
.wp-block-button__link {
  display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 0 22px;
  border: 0; border-radius: 0; background: var(--btn); color: var(--btn-ink);
  font-family: var(--serif); font-size: 17px; font-weight: 700; text-decoration: none;
}
.wp-block-button__link:hover { background: var(--btn-hover); color: var(--btn-ink); }

/* -- At a glance on /school/: hours, address, office, email, principal — a card of rows */
.cbp-glance {
  margin: 0 0 8px; padding: 0;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-glance > div { display: grid; gap: 2px; padding: 10px 16px; border-bottom: 1px solid var(--line); }
.cbp-glance > div:last-child { border-bottom: 0; }
.cbp-glance dt { font-size: 12px; font-weight: 700; line-height: 1.4; letter-spacing: 0.16em; text-transform: uppercase; color: var(--quiet); }
.cbp-glance dd { margin: 0; line-height: 1.45; overflow-wrap: anywhere; }
@media (min-width: 600px) {
  .cbp-glance > div { grid-template-columns: 9em minmax(0, 1fr); align-items: baseline; gap: 0 16px; }
}

/* -- Accordions (.cbp-acc): a white card whose title opens it. The Parenting topics, the
   Calendars page's sections, the minutes ledger and the meals list all use them. */
.cbp-acc {
  margin: 12px 0;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-acc > summary {
  display: flex; align-items: baseline; gap: 12px;
  box-sizing: border-box; min-height: 48px; padding: 12px 16px;
  list-style: none; cursor: pointer;
  font-family: var(--caslon); font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--ink);
}
.cbp-acc > summary::-webkit-details-marker { display: none; }
.cbp-acc > summary::before,
.cbp-acc--link::before {
  content: "+"; flex: none; width: 17px; text-align: center;
  font-family: var(--caslon); font-size: 24px; font-weight: 400; line-height: 1;
}
.cbp-acc[open] > summary::before { content: "\2212"; }
.cbp-acc > summary:hover { background: var(--tint); }
.cbp-acc[open] > summary { border-bottom: 1px solid var(--line); }
.cbp-acc__body { padding: 8px 16px 20px; }
/* An accordion inside an accordion (the meals list on the Calendars page): lighter edge */
.cbp-acc__body .cbp-acc { border-bottom-width: 1px; }
/* Smooth roll-out: interpolate-size lets height:auto animate through ::details-content.
   Browsers without it snap open; reduced motion is honoured by the rule at the foot. */
:root { interpolate-size: allow-keywords; }
.cbp-acc::details-content {
  block-size: 0; overflow: hidden; opacity: 0;
  transition: block-size .34s ease, opacity .3s ease, content-visibility .34s allow-discrete;
}
.cbp-acc[open]::details-content { block-size: auto; opacity: 1; }

/* The Calendars page: three sections and a link out, each a title over a quiet line */
.cbp-cals > summary,
.cbp-acc--link { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: 2px 12px; }
.cbp-cals > summary::before,
.cbp-acc--link::before { grid-row: 1 / span 2; }
.cbp-cals__title { min-width: 0; }
.cbp-cals__note { font-family: var(--serif); font-size: 15px; font-style: italic; font-weight: 400; color: var(--quiet); }
.cbp-acc--link {
  box-sizing: border-box; min-height: 48px; padding: 12px 16px;
  font-family: var(--caslon); font-size: 18px; font-weight: 700; line-height: 1.3;
  color: var(--ink); text-decoration: none;
}
.cbp-acc--link::before { content: "\2192"; font-size: 20px; }
.cbp-acc--link:hover { background: var(--tint); }
.cbp-acc--link:hover .cbp-cals__title { text-decoration: underline; text-underline-offset: 3px; }

/* -- Calendar lists: under v4 the full calendar, the meetings list and [cbp_next_meeting] print
   the homepage's "Coming up" rows (.cbp-cal--dates, styled with the homepage above) — one card
   per month, PAC / BAC meetings in pale gold. */
.cbp-page .cbp-cal--dates { margin: 12px 0; }
.cbp-cal__month { margin: 24px 0 0; font-family: var(--caslon); font-size: 20px; font-weight: 700; line-height: 1.25; }
.cbp-cal__month:first-of-type { margin-top: 8px; }
.cbp-cal__desc { font-size: 15px; color: var(--quiet); }
.cbp-cal__sync, .cbp-cal__empty, .cbp-next__empty, .cbp-ledger__empty, .cbp-meals__empty {
  margin: 16px 0 0; font-size: 15px; font-style: italic; color: var(--quiet);
}
/* Subscribe strip, at the top of each calendar: a small label, three buttons, the feed's address */
.cbp-cal__subscribe { display: grid; gap: 8px; margin: 4px 0 16px; }
.cbp-cal__sub { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
.cbp-cal__sub-h { flex-basis: 100%; font-size: 12px; font-weight: 700; line-height: 1.4; letter-spacing: 0.16em; text-transform: uppercase; color: var(--quiet); }
.cbp-cal__btns { display: flex; flex-wrap: wrap; gap: 8px; }
.cbp-cal__btn {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; box-sizing: border-box;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font-size: 16px; font-weight: 700; text-decoration: none;
}
.cbp-cal__btn:hover { background: var(--btn); border-color: var(--btn); color: var(--btn-ink); }
.cbp-cal__url { flex-basis: 100%; min-width: 0; }
.cbp-cal__url code { padding: 0; background: none; font-family: var(--serif); font-size: 13px; color: var(--quiet); word-break: break-all; }
@media print {
  .cbp-cal__btns { display: none; } /* the raw URL still prints — the useful part on paper */
}

/* -- School meals, the whole list ([cbp_meals view="full"]): a day per row, today in pale gold */
.cbp-meals { margin: 12px 0; }
.cbp-meals[hidden] { display: none; }
.cbp-meals__day > summary { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 12px; }
.cbp-meals__day > summary::before { grid-row: 1 / span 2; }
.cbp-meals__date { font-size: 17px; }
.cbp-meals__headline { min-width: 0; font-family: var(--serif); font-size: 15px; font-style: italic; font-weight: 400; color: var(--quiet); }
.cbp-meals__day.is-today > summary { background: var(--gold-pale); }
.cbp-meals__block + .cbp-meals__block { margin-top: 16px; }
.cbp-meals__block-h { margin: 0 0 4px; font-family: var(--serif); font-size: 12px; font-weight: 700; line-height: 1.4; letter-spacing: 0.16em; text-transform: uppercase; color: var(--quiet); }
.cbp-meals__line { margin: 0 0 4px; line-height: 1.5; }
.cbp-meals__heading { margin-right: 4px; font-style: italic; color: var(--quiet); }
.cbp-meals__sides { margin: 6px 0 0; font-size: 15px; font-style: italic; color: var(--quiet); }
.cbp-meals__more { margin: 16px 0 0; font-size: 15px; }

/* -- Meetings & Minutes: the ledger, one accordion per meeting under its school year */
.cbp-ledger__year { margin: 28px 0 0; font-family: var(--caslon); font-size: 20px; font-weight: 700; }
.cbp-ledger .cbp-acc > summary {
  display: grid; grid-template-columns: auto auto minmax(0, 1fr); align-items: center; gap: 4px 14px;
  font-family: var(--serif); font-size: 16px; font-weight: 400; line-height: 1.4;
}
.cbp-ledger .cbp-acc > summary::before,
.cbp-ledger__date { grid-row: 1 / span 2; }
.cbp-ledger__date.cbp-cal__dblock { width: 44px; }
.cbp-ledger__chips { display: flex; gap: 6px; }
.cbp-ledger__topics { min-width: 0; }
.cbp-ledger__chip {
  display: inline-block; padding: 1px 6px;
  font-size: 12px; font-weight: 700; line-height: 1.4; letter-spacing: 0.12em;
}
.cbp-ledger__chip--pac { color: #FFFFFF; background: #14264A; box-shadow: 0 0 0 1px var(--line); }
.cbp-ledger__chip--bac { color: #14264A; background: var(--gold); }
.cbp-ledger__status { font-style: italic; color: var(--gold-ink); }
.cbp-ledger__foot { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 20px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); font-size: 15px; }
.cbp-ledger__foot a, .cbp-ledger__share { display: inline-flex; align-items: center; min-height: 44px; }
.cbp-ledger__share {
  padding: 0; border: 0; background: none; color: var(--link); cursor: pointer;
  font: inherit; text-decoration: underline; text-underline-offset: 3px;
}

/* A digest: the ledger's open row and the single minutes page (mu-plugins/courtenay-bacpac-minutes.php) */
.cbp-min__crumb { margin: 0 0 12px; font-size: 15px; font-style: italic; }
.cbp-min__crumb--bottom { margin: 40px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); }
.cbp-min__meta { margin: 0 0 4px; padding-bottom: 8px; border-bottom: 1px solid var(--rule); font-size: 15px; color: var(--quiet); }
.cbp-min__meta strong { color: var(--ink); }
.cbp-min__attend { margin: 0 0 16px; font-size: 15px; font-style: italic; color: var(--quiet); }
.cbp-min h3 { margin: 22px 0 4px; font-family: var(--caslon); font-size: 18px; font-weight: 700; line-height: 1.3; }
.cbp-min ul { margin: 6px 0 12px; padding-left: 1.2em; }
.cbp-min li { margin: 4px 0; }
.cbp-min__next { margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--rule); }
.cbp-min__note { margin-top: 24px; font-size: 14px; color: var(--quiet); }

/* -- The Councils page's money card ([cbp_parent_funds], mu-plugins/courtenay-bacpac-funds.php):
   what the PAC has left to spend, the bar, the report's date, a row per budget line, the BAC's own
   money apart, and the way to a meeting. It sits inside the page's .cbp-prose, hence the doubled
   classes where the prose's own list and paragraph rules would win. */
.cbp-funds {
  margin: 28px 0 8px; padding: 14px 16px 16px;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-funds .cbp-funds__h { margin: 0 0 10px; font-size: 19px; }
.cbp-funds p { margin: 0; }
.cbp-funds__total { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.cbp-funds__big { font-family: var(--caslon); font-size: 44px; font-weight: 700; line-height: 1.05; font-variant-numeric: lining-nums; }
.cbp-funds__of { color: var(--quiet); }
.cbp-funds__bar { display: block; height: 10px; margin: 12px 0 6px; border: 1px solid var(--line); background: var(--paper); }
.cbp-funds__used { display: block; height: 100%; background: var(--ink); }
.cbp-funds__asof, .cbp-funds__bacdate { font-size: 14px; font-style: italic; color: var(--quiet); }
.cbp-funds .cbp-funds__lines { margin: 14px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.cbp-funds .cbp-funds__line {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px;
  margin: 0; padding: 8px 0; border-bottom: 1px solid var(--rule);
}
.cbp-funds .cbp-funds__line:last-child { border-bottom: 0; }
.cbp-funds__name { display: flex; flex-direction: column; min-width: 0; }
.cbp-funds__cap { font-size: 14px; font-style: italic; color: var(--quiet); }
.cbp-funds__cap strong { font-style: normal; color: var(--ink); }
.cbp-funds__amt { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cbp-funds .cbp-funds__bac { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.cbp-funds__pending { font-style: italic; color: var(--quiet); }
.cbp-funds .cbp-funds__ideas { margin-top: 10px; }
.cbp-funds__ideas a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 700; }
@media (min-width: 880px) {
  .cbp-funds { padding: 18px 20px 20px; }
  .cbp-funds .cbp-funds__h { font-size: 21px; }
  .cbp-funds__big { font-size: 52px; }
}

/* -- Search box, search results and "page not found" (templates/search.html, 404.html).
   The search block loses the parent theme's pills: a square navy-ruled field and the navy button.
   Results are one card of rows (title, a line of the page), like Home's Parenting card. The 404
   carries the hiker — someone finding their way — and the five sections. */
.wp-block-search.cbp-search { margin: 20px 0 8px; }
.cbp-search .wp-block-search__inside-wrapper { display: flex; gap: 8px; max-width: 32em; padding: 0; border: 0; }
.cbp-search .wp-block-search__input {
  flex: 1 1 auto; min-width: 0; min-height: 48px; box-sizing: border-box; padding: 0 14px;
  border: 1px solid var(--line); border-radius: 0; background: var(--card); color: var(--ink);
  font-family: var(--serif); font-size: 17px;
}
.cbp-search .wp-block-search__button {
  flex: none; min-height: 48px; margin: 0; padding: 0 22px;
  border: 0; border-radius: 0; background: var(--btn); color: var(--btn-ink);
  font-family: var(--serif); font-size: 17px; font-weight: 700; cursor: pointer;
}
.cbp-search .wp-block-search__button:hover { background: var(--btn-hover); }
.cbp-results { margin-top: 24px; }
.cbp-results .cbp-results__list {
  margin: 0; padding: 0; list-style: none;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-results__list > li { margin: 0; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.cbp-results__list > li:last-child { border-bottom: 0; }
.cbp-page .cbp-results__title { margin: 0; font-size: 19px; }
.cbp-results__title a { color: var(--ink); text-decoration: none; }
.cbp-results__title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.cbp-results__excerpt { margin: 4px 0 0; }
.cbp-results__excerpt p { margin: 0; font-size: 15px; line-height: 1.45; color: var(--quiet); }
.cbp-results__pages { margin-top: 16px; font-weight: 700; }
.cbp-results__pages a { display: inline-flex; align-items: center; min-height: 44px; }
.cbp-results__none { font-style: italic; color: var(--quiet); }
.cbp-lost::before {
  content: ""; display: block; width: 120px; height: 120px; margin: 0 0 16px;
  background-color: var(--drawing);
  -webkit-mask: url("drawings/hiker.webp") left center / contain no-repeat;
          mask: url("drawings/hiker.webp") left center / contain no-repeat;
}
.cbp-lost__links { display: flex; flex-wrap: wrap; gap: 0 22px; margin: 16px 0 0; }
.cbp-lost__links a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 700; color: var(--link); }

/* -- Video: a 16:9 frame with a navy rule */
.cbp-video {
  position: relative; width: 100%; aspect-ratio: 16 / 9; overflow: hidden;
  margin: 12px 0 8px; border: 1px solid var(--line); background: #000;
}
.cbp-video iframe,
.cbp-video video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.cbp-figcaption { margin: 6px 0 16px; font-size: 14px; font-style: italic; line-height: 1.45; color: var(--quiet); }
.cbp-figcaption strong { font-style: normal; color: var(--ink); }

/* -- YouTube playlist ([cbp_playlist]): the player, a previous / next bar, then the list as one
   card of rows. No iframe until the family taps play (the thumbnail is a facade). */
.cbp-pl { margin: 16px 0 24px; }
.cbp-pl__stage { position: relative; aspect-ratio: 16 / 9; overflow: hidden; border: 1px solid var(--line); background: #000; }
.cbp-pl__frame, .cbp-pl__hero { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.cbp-pl__hero { display: block; background-size: cover; background-position: center; }
.cbp-pl__hero[hidden] { display: none; }
.cbp-pl__hero::after {  /* a dark foot, so the title reads over any thumbnail */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 45%;
  background: linear-gradient(transparent, rgba(10, 18, 36, 0.8));
}
/* play: a navy square with a white triangle; gold with a navy one on hover */
.cbp-pl__playbtn {
  position: absolute; top: 50%; left: 50%; width: 64px; height: 64px;
  transform: translate(-50%, -50%);
  background: #14264A; outline: 2px solid #FFFFFF;
  transition: background-color 0.15s;
}
.cbp-pl__playbtn::after {
  content: ""; position: absolute; top: 50%; left: 54%; transform: translate(-50%, -50%);
  border: 12px solid transparent; border-right: 0; border-left: 19px solid #FFFFFF;
}
.cbp-pl__hero:hover .cbp-pl__playbtn,
.cbp-pl__hero:focus-visible .cbp-pl__playbtn { background: var(--gold); }
.cbp-pl__hero:hover .cbp-pl__playbtn::after,
.cbp-pl__hero:focus-visible .cbp-pl__playbtn::after { border-left-color: #14264A; }
.cbp-pl__herotitle {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; padding: 10px 14px;
  color: #FFFFFF; font-size: 16px; font-weight: 700; line-height: 1.35;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.cbp-pl__bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 12px 0; }
.cbp-pl__nav {
  min-height: 44px; padding: 0 16px; border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font-family: var(--serif); font-size: 15px; font-weight: 700; cursor: pointer;
}
.cbp-pl__nav:hover:not(:disabled) { background: var(--btn); border-color: var(--btn); color: var(--btn-ink); }
.cbp-pl__nav:disabled { opacity: 0.4; cursor: default; }
.cbp-pl__count { font-size: 15px; font-style: italic; color: var(--quiet); white-space: nowrap; font-variant-numeric: tabular-nums; }
.cbp-pl__rail {
  max-height: 22rem; overflow-y: auto; scrollbar-width: thin;
  margin: 0; padding: 0; list-style: none;
  border: 1px solid var(--line); border-bottom-width: 3px; background: var(--card);
}
.cbp-pl__rail li { margin: 0; border-bottom: 1px solid var(--rule); }
.cbp-pl__rail li:last-child { border-bottom: 0; }
.cbp-pl__item { display: flex; align-items: center; gap: 12px; padding: 8px 12px; color: var(--ink); text-decoration: none; }
.cbp-pl__item:hover { background: var(--tint); }
.cbp-pl__item.is-active { background: var(--gold-pale); }
.cbp-pl__thumb { flex: 0 0 78px; position: relative; }
.cbp-pl__thumb img { display: block; width: 78px; height: 44px; object-fit: cover; background: var(--tint); }
.cbp-pl__num {
  position: absolute; right: 0; bottom: 0; padding: 1px 5px;
  background: #14264A; color: #FFFFFF; font-size: 11px; font-weight: 700; line-height: 1.35;
}
.cbp-pl__item.is-active .cbp-pl__num { background: var(--gold); color: #14264A; }
.cbp-pl__meta { min-width: 0; }
.cbp-pl__t { display: block; font-size: 15px; font-weight: 700; line-height: 1.35; }
.cbp-pl__item:hover .cbp-pl__t { text-decoration: underline; text-underline-offset: 3px; }
.cbp-pl__dur { display: block; margin-top: 2px; font-size: 13px; font-style: italic; color: var(--quiet); font-variant-numeric: tabular-nums; }

/* -- A zoomable content image (figure.cbp-figure > a.cbp-zoom) and the lightbox it opens */
.cbp-figure { margin: 16px 0 8px; }
.cbp-figure .cbp-zoom { position: relative; display: block; cursor: zoom-in; border: 1px solid var(--line); background: var(--card); }
.cbp-figure .cbp-zoom img { display: block; width: 100%; height: auto; }
.cbp-figure .cbp-zoom::after {  /* "enlarge", shown on hover and keyboard focus */
  content: "\2922"; position: absolute; top: 8px; right: 8px;
  display: grid; place-items: center; width: 32px; height: 32px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink); font-size: 16px; line-height: 1;
  opacity: 0; transition: opacity .15s ease; pointer-events: none;
}
.cbp-figure .cbp-zoom:hover::after,
.cbp-figure .cbp-zoom:focus-visible::after { opacity: 1; }
html.cbp-lightbox-lock { overflow: hidden; }
.cbp-lightbox[hidden] { display: none; }
.cbp-lightbox { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; padding: clamp(10px, 3vw, 32px); }
.cbp-lightbox:not(.is-open) { pointer-events: none; }
.cbp-lightbox__backdrop { position: absolute; inset: 0; background: rgba(10, 18, 36, 0.85); opacity: 0; transition: opacity .2s ease; }
.cbp-lightbox.is-open .cbp-lightbox__backdrop { opacity: 1; }
.cbp-lightbox__frame {
  position: relative; display: flex; flex-direction: column; margin: 0;
  max-width: min(1200px, 96vw); max-height: 92vh; overflow: hidden;
  border: 1px solid var(--line); background: var(--card);
  opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease;
}
.cbp-lightbox.is-open .cbp-lightbox__frame { opacity: 1; transform: none; }
.cbp-lightbox__scroll { overflow: auto; cursor: zoom-in; -webkit-overflow-scrolling: touch; }
.cbp-lightbox__img { display: block; width: 100%; height: auto; }
.cbp-lightbox.is-zoomed .cbp-lightbox__scroll { cursor: zoom-out; }
.cbp-lightbox.is-zoomed .cbp-lightbox__img { width: auto; max-width: none; }
.cbp-lightbox__caption { padding: 10px 14px; border-top: 1px solid var(--line); font-size: 14px; font-style: italic; color: var(--quiet); }
.cbp-lightbox__caption[hidden] { display: none; }
.cbp-lightbox__close {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  display: grid; place-items: center; width: 44px; height: 44px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font-size: 26px; line-height: 1; cursor: pointer;
}
.cbp-lightbox__close:hover { background: var(--btn); color: var(--btn-ink); }

@media (min-width: 880px) {
  .cbp-page .wp-block-post-title,
  .cbp-page .wp-block-query-title { font-size: 40px; }
  .cbp-lead { font-size: 20px; }
  :where(.cbp-page) h2 { font-size: 28px; }
  :where(.cbp-page) h3 { font-size: 21px; }
  .cbp-page .cbp-tile b { font-size: 17px; }
  .cbp-page .cbp-tile .cbp-tile__sub { font-size: 13px; }
}

/* ---------- EN/ES swap blocks ----------
   For content we have in BOTH hand-written English and Spanish (e.g. the
   Colorín Colorado conference checklists). Mark the pair:
     <div class="cbp-lang-en">…</div>
     <div class="cbp-lang-es notranslate" lang="es">…</div>
   Works on inline <span> pairs too (e.g. the header nav's "links"/"enlaces"
   label, where Google alone turned the bare word "links" into golf).
   Default (and every non-Spanish language): the EN block shows and gets
   machine-translated by GTranslate like the rest of the page; the ES block
   stays hidden (notranslate keeps Google's hands off the human Spanish).
   When the visitor switches the site to Spanish, Google's widget rewrites
   <html lang="es">, and these rules swap the blocks — verified live
   2026-08-30 (widget also adds html.translated-ltr). `revert` = the
   element's own UA default: block for divs, inline for spans. */
.cbp-lang-es { display: none; }
html[lang^="es"] .cbp-lang-es { display: revert; }
html[lang^="es"] .cbp-lang-en { display: none; }

/* ---------- Instagram ([cbp_instagram]): one large newest post per account ----------
   v4 (owner picked auto-load, 2026-10-08, from /ig-test-v4.html). The
   token-free profile embed (instagram.com/<user>/embed/) is laid out at ~3x
   the card's inner width, so its 3-column grid has tiles as wide as the card;
   the iframe is pulled up by the embed's header height and the card clips to
   the first tile. Instagram crops every grid tile to a square, so a tall (4:5)
   post loses a little top and bottom: that is the embed, not this crop.

   Measured 2026-10-08 (frames 690-1290px wide, which every 3x card is):
   tile = (frame - 2) / 3, first tile's top = 158px (school: name + handle +
   counts) / 137px (Friends: no display name). The crops below are those + 1px
   overscan; the width makes the tile ~2px wider than the card, so subpixel
   rounding never shows a white edge. If Instagram redesigns the embed header
   these drift: a sliver of Instagram's header at the top = raise the crop;
   the top of the photo cut off = lower it. Measurements and weights:
   docs/1-website-shell/redesign-plan.md, § Done.

   The blocked note (.cbp-ig-blocked) is in Home's content, inside
   section.cbp-ig-section. */
.cbp-ig-section .cbp-ig-blocked { display: none; }
.cbp-ig-section:has(.cbp-ig-fig.is-blocked) .cbp-ig-blocked { display: inline; }
.cbp-ig-stack { display: grid; grid-template-columns: 1fr; gap: 20px; margin: 0; }
.cbp-ig-fig { margin: 0; container-type: inline-size; display: flex; flex-direction: column; gap: 8px; }
.cbp-ig-head { display: flex; align-items: center; gap: 10px; min-height: 44px; color: var(--ink); text-decoration: none; line-height: 1.25; }
.cbp-ig-head__pic { width: 40px; height: 40px; display: block; flex: none; border-radius: 50%; border: 1px solid var(--line); background: var(--well); }
.cbp-ig-head strong { display: block; }
.cbp-ig-head span span { display: block; font-size: 14px; font-style: italic; color: var(--quiet); }
.cbp-ig {
  overflow: hidden; background: var(--card);
  border: 1px solid var(--line); border-bottom-width: 3px;
  /* interpolate-size: allow-keywords (set on :root for the accordions) lets
     the 0 -> auto reveal animate; browsers without it just pop the card in */
  transition: height 0.35s ease, border-width 0.35s ease;
}
.cbp-ig iframe {
  display: block; border: 0; max-width: none;
  /* inner width = 100cqw - 2px (side borders); 3 x that + 8px */
  width: 1076px; width: calc(300cqw + 2px);
  height: calc(var(--ig-crop) + 100cqw - 2px);
  margin-top: calc(-1 * var(--ig-crop));
}
.cbp-ig-fig--tigers .cbp-ig  { --ig-crop: 159px; }
.cbp-ig-fig--friends .cbp-ig { --ig-crop: 138px; }
@media (min-width: 601px) { .cbp-ig-head__pic { width: 44px; height: 44px; } }
/* No big empty box, ever (see assets/instagram-embed.js): the card is held
   collapsed while its embed loads (.is-pending) and stays collapsed when the
   browser blocks instagram.com (.is-blocked): just the avatar + handle rows,
   still working profile links. height:0 rather than display:none so the
   inserted iframe keeps a real layout width while clipped. */
.cbp-ig-fig.is-pending .cbp-ig,
.cbp-ig-fig.is-blocked .cbp-ig { height: 0; border-width: 0; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  /* navigation:none up top means there is no transition to join, so drop the
     one remaining name rather than pay for a needless stacking context; must
     live down here, after the phone block, to outrank the pinned strip's name */
  .cbp-header nav.wp-block-navigation.cbp-stuck { view-transition-name: none; }
}


/* Parent polls ([cbp_poll], mu-plugins/courtenay-bacpac-poll.php): a square card like the money
   card, one fieldset per question, rows tall enough to tap. A poll that shares its results paints
   each choice's share (--share, set by cbp-poll/poll.js) behind its label once someone answers. */
.cbp-poll {
  margin: 24px 0;
  padding: 20px;
  background: var(--card);
  border: 1px solid var(--line);
  border-bottom-width: 3px;
}
.cbp-poll [hidden] { display: none !important; }
.cbp-poll p { margin: 0; }
.cbp-poll .cbp-poll__intro { margin: 0 0 12px; }
.cbp-poll .cbp-poll__q { min-width: 0; margin: 20px 0 0; padding: 0; border: 0; }
.cbp-poll .cbp-poll__ask {
  margin: 0 0 8px;
  padding: 0;
  font-family: var(--caslon);
  font-size: 19px;
  line-height: 1.3;
}
.cbp-poll .cbp-poll__hint {
  display: block;
  margin-top: 2px;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--quiet);
}
.cbp-poll .cbp-poll__opt {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--rule);
  cursor: pointer;
}
.cbp-poll .cbp-poll__opt + .cbp-poll__opt { border-top: 0; }
/* Hover only where there is a pointer: on a phone the tapped row keeps :hover and would hide its gold. */
@media (hover: hover) {
  .cbp-poll:not(.is-done):not(.is-closed) .cbp-poll__opt:not(:has(input:checked)):hover { background: var(--tint); }
}
.cbp-poll .cbp-poll__opt:has(input:checked) { background: var(--gold-pale); }
.cbp-poll .cbp-poll__opt input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--btn);
}
.cbp-poll.is-done .cbp-poll__opt,
.cbp-poll.is-closed .cbp-poll__opt { cursor: default; }
.cbp-poll .cbp-poll__ts:not(:empty) { margin-top: 16px; }
.cbp-poll .cbp-poll__actions { margin-top: 16px; }
.cbp-poll .cbp-poll__send {
  min-height: 44px;
  padding: 10px 22px;
  border: 0;
  border-radius: 0;
  background: var(--btn);
  color: var(--btn-ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.cbp-poll .cbp-poll__send:hover { background: var(--btn-hover); }
.cbp-poll .cbp-poll__send:disabled { opacity: 0.6; cursor: progress; }
.cbp-poll .cbp-poll__note { margin-top: 10px; font-size: 15px; color: var(--quiet); }
.cbp-poll .cbp-poll__msg { margin-top: 12px; font-weight: 600; }
.cbp-poll .cbp-poll__again {
  min-height: 44px;
  margin-top: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--link);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
/* Results: the share behind the label, the reader's own pick edged in gold. */
.cbp-poll.is-results .cbp-poll__opt::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  z-index: -1;
  width: var(--share, 0%);
  background: var(--gold-pale);
}
.cbp-poll.is-results .cbp-poll__opt:has(input:checked) { background: none; box-shadow: inset 4px 0 0 var(--gold); }
.cbp-poll .cbp-poll__pct { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Editors only: why families can't see the poll yet. */
.cbp-poll__admin { padding: 8px 12px; border: 1px dashed var(--line); color: var(--quiet); font-size: 15px; }
