/*
Theme Name: PTA Foundry Theme
Theme URI: https://ptafoundry.org
Description: The PTA Foundry theme. Self-contained classic theme with no external parent; site identity, palette, and page copy come from the PTA Foundry plugin's per-site settings (defaults ship as Henry PTA's black and gold).
Author: PTA Foundry
Version: 1.34.7
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
Text Domain: ptafoundry
*/

/* ============================================================
   Webfonts: self-hosted, matching the PTA's social-graphic style.
   Bebas Neue and Yellowtail, both SIL Open Font License, via
   fontsource builds of the Google Fonts originals.
   ============================================================ */
@font-face {
  font-family: "PTA Display";
  src: url("assets/fonts/bebas-neue-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "PTA Script";
  src: url("assets/fonts/yellowtail-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   Default palette: Henry PTA black + gold (overridden per site via pta_palette)
   ============================================================ */
:root {
  --pta-primary: #f4b41c;
  --pta-primary-bright: #ffc845;
  --pta-secondary: #d99a00;
  /* Text ON the primary fill, and the muted divider gray. Both are real
     palette tokens; the plugin's inline :root overrides this fallback. */
  --pta-on-primary: #141414;
  --pta-neutral: #c9c3b4;
  --pta-black: #141414;
  --pta-ink: #1f1f1f;
  --pta-cream: #fbf6ec;
  --pta-white: #ffffff;
  --pta-gray: #6b6b6b;
  --pta-line: #e7e2d6;

  --pta-font: "Helvetica Neue", Arial, "Segoe UI", system-ui, sans-serif;
  --pta-font-display: "PTA Display", "Arial Narrow", sans-serif;
  --pta-radius: 10px;
  --pta-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
  /* Small elements: buttons, social tiles, the banner's copy panels. Tighter
     and a touch darker than the card shadow, because a 24px blur under a 58px
     button reads as a smudge rather than a raised edge. The plugin overrides
     all three from the brand's depth setting. */
  --pta-shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.16);
  /* Fuller-width layouts by request: use most of the viewport, capped for
     very large monitors. Everything keying off this token widens together. */
  --pta-maxw: min(1440px, 94vw);

  /* Section grounds. Deliberately separate from the chrome tokens: a dark
     content band is not the header. */
  --pta-section-dark: var(--pta-black);
  --pta-on-section-dark: var(--pta-white);
  --pta-on-section-dark-muted: color-mix(in srgb, var(--pta-white) 78%, transparent);
  --pta-section-tint: #f4f4f4;

  /* Hero artwork when a site has supplied none: its own colours, not another
     school's photograph. */
  --pta-hero-fallback: linear-gradient(135deg, var(--pta-black) 0%, var(--pta-secondary) 55%, var(--pta-primary) 140%);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Canvas matches the chrome so navigating between pages doesn't flash a
     different colour before the next page's header paints. */
  background-color: var(--pta-chrome);
}

body {
  margin: 0;
  font-family: var(--pta-font);
  color: var(--pta-ink);
  background: var(--pta-white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; }

/* Links, EXCEPT anything that is really a button.
   A button is an <a>, so the plain link colours were landing on buttons too.
   That was invisible on .pta-btn only because it carries !important on color,
   and it bit the Block Editor's buttons hard: `a:hover` is (0,1,1) while the
   hover that theme.json emits is `:root :where(...)`, which is (0,1,0), so the
   global rule won and a white label on a blue fill turned black on hover.
   Excluding buttons here fixes the whole class of it rather than one button. */
a { color: var(--pta-secondary); }
/* The darken-on-hover belongs to CONTENT links only. Chrome contexts (nav,
   footer, social tiles) sit on dark or brand-colour grounds where black is
   unreadable, and this rule's :not() chain out-specifies their own :hover
   rules (0,4,1 vs 0,1,2), which is exactly how every site's nav links were
   turning black on hover. */
a:not(.pta-btn):not(.wp-element-button):not(.wp-block-button__link):not(.pta-nav a):not(.pta-site-footer a):not(.pta-social-link):not(.pta-menu-toggle):hover {
  color: var(--pta-black);
}

h1, h2, h3, h4 {
  /* The display face's own weight, NOT a blanket 800. Every one of these
     fonts ships a single weight (Bebas 400, Oswald 500), so asking for 800
     found no matching face and the browser faked a bold by thickening the
     glyphs: doubled, shadow-like edges on every heading, on both sites. */
  font-weight: var(--pta-font-display-weight, 700);
  line-height: 1.15;
  color: var(--pta-black);
  /* Negative tracking suits a normal-width bold face and fights a condensed
     display one, which is what all of these are. The heading groups below set
     their own positive tracking; this is the sane default for the rest. */
  letter-spacing: 0.01em;
}

.pta-container {
  width: 100%;
  max-width: var(--pta-maxw);
  margin: 0 auto;
  padding: 0 20px;
}

/* ============================================================
   Header
   ============================================================ */
.pta-site-header {
  background: var(--pta-chrome);
  border-bottom: 4px solid var(--pta-chrome-accent);
  position: sticky;
  top: 0;
  z-index: 100;
}
.pta-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 20px;
}
.pta-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
}
.pta-brand img { height: 56px; width: auto; display: block; }
.pta-brand-text { display: flex; flex-direction: column; line-height: 1.05; }
.pta-brand-name {
  color: var(--pta-on-chrome);
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.pta-brand-tag {
  color: var(--pta-chrome-accent);
  font-size: 0.72rem;
  font-style: italic;
  letter-spacing: 0.02em;
}

/* Nav */
.pta-nav ul {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
}
.pta-nav a {
  color: var(--pta-on-chrome);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 8px 14px;
  border-radius: 6px;
  /* Never break a nav label mid-phrase ("Staff Favorite / Things"); below
     the drawer breakpoint the whole nav becomes the off-canvas menu. */
  white-space: nowrap;
}
.pta-nav a:hover,
.pta-nav .current-menu-item > a {
  /* The chrome's own accent, which each chrome preset picks to READ on that
     chrome: bright primary on dark, on-primary on a brand-colour bar, deep
     secondary on light. Choosing one accent for all three is how you get a
     2.89:1 nav link on a blue brand. */
  color: var(--pta-chrome-accent);
  background: color-mix(in srgb, var(--pta-on-chrome) 10%, transparent);
}

/* Dropdown sub-menus (desktop): open on hover, and on keyboard focus via
   :focus-within so tabbing through the menu reaches every child link. */
.pta-nav li {
  position: relative;
}
.pta-nav ul ul {
  display: none;
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  min-width: 220px;
  flex-direction: column;
  align-items: stretch;
  background: var(--pta-chrome);
  border: 1px solid var(--pta-secondary);
  border-radius: var(--pta-radius);
  box-shadow: var(--pta-shadow);
  padding: 6px;
  gap: 2px;
  z-index: 1003;
}
.pta-nav li:hover > ul,
.pta-nav li:focus-within > ul {
  display: flex;
}
/* Invisible bridge over the 10px gap so hover doesn't drop while the
   mouse travels from the nav item down into the panel. */
.pta-nav ul ul::before {
  content: "";
  position: absolute;
  top: -12px;
  left: 0;
  right: 0;
  height: 12px;
}
.pta-nav ul ul a {
  display: block;
  padding: 10px 14px;
}

/* Third-level flyout: opens beside the dropdown panel. The generic
   li:hover / li:focus-within open rules above cover every depth. */
.pta-nav ul ul ul {
  top: 0;
  left: 100%;
  margin-left: 2px;
}
/* If the flyout would run off the right edge of the viewport (rightmost
   nav items), flip it to open leftward instead. */
.pta-nav > ul > li:nth-last-child(-n+2) ul ul {
  left: auto;
  right: 100%;
  margin-left: 0;
  margin-right: 2px;
}
/* Same guard for the LEVEL-2 panel itself: right-align it under the last
   two nav items so it never runs off the viewport (which also summoned a
   horizontal scrollbar). */
.pta-nav > ul > li:nth-last-child(-n+2) > ul {
  left: auto;
  right: 0;
}

/* Dropdown indicator: a Font Awesome glyph that tips over like an animated
   caret when its menu opens. Which glyph is per-site config (--pta-nav-icon,
   printed by pta_assets): Henry are the Hawks and wear a feather, Cox are the
   Comets and wear a meteor. A mascot is identity, not a hardcoded default. */
.pta-nav .menu-item-has-children > a::after {
  content: var(--pta-nav-icon, "\f52d");
  font-family: "Font Awesome 7 Free";
  font-weight: 900;
  font-style: normal;
  font-size: 0.78em;
  line-height: 1;
  display: inline-block;
  margin-left: 7px;
  vertical-align: 0;
  /* The chrome accent, matching the nav links beside it. */
  color: var(--pta-chrome-accent);
  transition: transform 0.25s ease, color 0.15s ease;
}
/* Every transform below COMPOSES with --pta-nav-icon-transform, the site's
   chosen resting orientation, so turning the icon to match a school's logo
   never fights the open animation. */
.pta-nav .menu-item-has-children > a::after {
  transform: var(--pta-nav-icon-transform, none);
}
/* Open states: the icon tips over with the menu, caret-style. */
.pta-nav > ul > .menu-item-has-children:hover > a::after,
.pta-nav > ul > .menu-item-has-children:focus-within > a::after {
  /* The spin direction comes from the site config: mirrored icons rotate
     backwards on screen, so their entries supply -90deg to still LOOK
     like a clockwise drop. Fallback is rotate(0deg), never the keyword
     none: "none rotate(90deg)" is invalid and drops the declaration. */
  transform: var(--pta-nav-icon-transform, rotate(0deg)) rotate(var(--pta-nav-icon-hover-rotate, 90deg));
}
/* Inside dropdown panels: flyout opens to the side. */
.pta-nav ul ul .menu-item-has-children > a::after {
  float: right;
  margin-top: 3px;
}
.pta-nav ul ul .menu-item-has-children:hover > a::after,
.pta-nav ul ul .menu-item-has-children:focus-within > a::after {
  transform: var(--pta-nav-icon-transform, rotate(0deg)) rotate(var(--pta-nav-icon-hover-rotate, 90deg));
}
/* Where the flyout flips leftward (rightmost nav items), mirror the
   feather and its spin so the motion points the same way the menu opens. */
.pta-nav > ul > li:nth-last-child(-n+2) ul .menu-item-has-children > a::after {
  transform: var(--pta-nav-icon-transform, rotate(0deg)) scaleX(-1);
  float: left;
  margin-left: 0;
  margin-right: 7px;
}
.pta-nav > ul > li:nth-last-child(-n+2) ul .menu-item-has-children:hover > a::after,
.pta-nav > ul > li:nth-last-child(-n+2) ul .menu-item-has-children:focus-within > a::after {
  transform: var(--pta-nav-icon-transform, rotate(0deg)) scaleX(-1) rotate(90deg);
}

/* Sits on the dark header beside the nav links, so it matches them: white
   label. The plain primary put a blue label on a blue bar (2.89:1 for Cox);
   the outline keeps the brand edge in the bright primary, which reads there. */
.pta-menu-toggle {
  display: none;
  background: transparent;
  border: 2px solid var(--pta-chrome-accent);
  color: var(--pta-on-chrome);
  border-radius: 6px;
  padding: 6px 10px;
  font-weight: 700;
  cursor: pointer;
}
.pta-menu-toggle:hover,
.pta-menu-toggle:focus-visible {
  color: var(--pta-chrome-accent);
  background: color-mix(in srgb, var(--pta-on-chrome) 10%, transparent);
}

/* Drawer close button + backdrop: hidden on desktop, shown in the mobile @media. */
.pta-nav-overlay { display: none; }

/* Submenu toggle buttons exist only for the drawer's collapsed-submenu mode;
   desktop navigation opens on hover/focus and never shows them. */
.pta-submenu-toggle { display: none; }
/* Same reasoning: the drawer background is the dark brand colour. */
.pta-nav-close {
  display: none;
  background: transparent;
  border: 0;
  color: var(--pta-on-chrome);
  font-size: 1.5rem;
  line-height: 1;
  padding: 4px 12px;
  cursor: pointer;
}
.pta-nav-close:hover,
.pta-nav-close:focus-visible { color: var(--pta-chrome-accent); }

/* Kill drawer/overlay transitions during window resize, so the drawer doesn't
   animate into view when the viewport crosses the mobile breakpoint. */
.pta-resizing .pta-nav,
.pta-resizing .pta-nav-overlay { transition: none; }

/* ============================================================
   Home dashboard sections
   ============================================================ */
.pta-home-heading {
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  font-weight: var(--pta-font-display-weight, 400);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-align: center;
  font-size: clamp(1.6rem, 3.2vw, 2.2rem);
  margin: 0 0 6px;
}
.pta-home-more {
  text-align: center;
  margin: 26px 0 0;
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Get Involved: three big doors. */
.pta-home-trio {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
  max-width: var(--pta-maxw);
  margin: 10px auto 0;
}
@media (min-width: 760px) {
  .pta-home-trio { grid-template-columns: repeat(3, 1fr); }
}
.pta-home-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 26px 22px;
  border-radius: var(--pta-radius);
  background: var(--pta-chrome);
  border: 2px solid var(--pta-secondary);
  text-decoration: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.pta-home-panel:hover {
  transform: translateY(-3px);
  box-shadow: var(--pta-shadow);
}
.pta-home-panel-title {
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  font-size: 1.6rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pta-chrome-accent);
}
.pta-home-panel-note {
  color: var(--pta-on-chrome-muted);
  font-size: 0.95rem;
}
.pta-home-panel--gold {
  background: var(--pta-primary);
  border-color: var(--pta-black);
}
/* This panel is filled with the primary, so its text takes the on-primary
   token. The old near-black + rgba(0,0,0,.75) pair assumed a light fill and
   measured 2.89:1 on a blue brand. */
.pta-home-panel--gold .pta-home-panel-title { color: var(--pta-on-primary); }
.pta-home-panel--gold .pta-home-panel-note { color: var(--pta-on-primary); opacity: 0.82; }

/* This month's staff birthdays. */
.pta-home-birthdays {
  list-style: none;
  padding: 0;
  margin: 14px auto 0;
  max-width: 560px;
  display: grid;
  gap: 8px;
}
.pta-home-birthdays li {
  display: flex;
  align-items: center;
  gap: 12px;
}
.pta-home-bday-day {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--pta-black);
  /* Bright primary, not plain primary, for the same reason the initials tiles
     and the nav use it: plain primary on the near-black disc is 2.89:1 for a
     blue brand (Cox), under the bar even for large bold text. */
  color: var(--pta-primary-bright);
  font-weight: 800;
}

/* Quick links block. */
.pta-home-links {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  max-width: var(--pta-maxw);
  margin: 10px auto 0;
}
@media (min-width: 700px) {
  .pta-home-links { grid-template-columns: repeat(3, 1fr); }
}
.pta-home-links h3 {
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  font-weight: var(--pta-font-display-weight, 400);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-bottom: 2px solid var(--pta-primary);
  padding-bottom: 4px;
  margin: 0 0 10px;
}
.pta-home-links ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 6px;
}

/* Board teaser inherits the roster cards; just cap its width. */
.pta-bm--teaser {
  max-width: var(--pta-maxw);
  margin: 10px auto 0;
}

/* ============================================================
   Footer columns
   ============================================================ */
.pta-footer-cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 26px;
  text-align: left;
  padding: 8px 0 22px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--pta-chrome-line);
}
@media (min-width: 620px) {
  .pta-footer-cols { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 980px) {
  .pta-footer-cols { grid-template-columns: repeat(4, 1fr); }
}
.pta-footer-col h3 {
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  font-weight: var(--pta-font-display-weight, 400);
  font-size: 1.1rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pta-chrome-accent);
  margin: 0 0 10px;
}
.pta-footer-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 7px;
}
.pta-footer-col a {
  color: var(--pta-on-chrome-muted);
  text-decoration: none;
  font-size: 0.94rem;
}
.pta-footer-col a:hover {
  /* Same reasoning as the nav: this is a link on the dark footer. */
  color: var(--pta-chrome-accent);
}

/* ============================================================
   Page-title banner: the social-graphic strip
   ============================================================ */
.pta-title-banner {
  position: relative;
  background: var(--pta-chrome);
  border-top: 2px solid var(--pta-chrome-accent);
  border-bottom: 2px solid var(--pta-chrome-accent);
  padding: 44px 24px 40px;
  margin: 0 0 36px;
  text-align: center;
  overflow: hidden;
}
/* Angled stripe accents at the band edges.
   --pta-chrome-accent, not --pta-primary. This band IS the chrome, and on a
   site whose chrome preset is `brand` the two are the same colour: Cox's
   stripes, sparkles and ribbon all painted rgb(37,102,182) on an
   rgb(37,102,182) band and simply were not there. The accent token is the one
   each preset picks to READ on its own chrome, which is why the nav uses it. */
.pta-title-banner::before,
.pta-title-banner::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 130px;
  background: repeating-linear-gradient(
    -55deg,
    var(--pta-chrome-accent) 0 10px,
    transparent 10px 34px
  );
  opacity: 0.28;
  pointer-events: none;
}
.pta-title-banner::before { left: -20px; }
.pta-title-banner::after { right: -20px; transform: scaleX(-1); }
/* Faded hawk watermark, right of center. */
.pta-title-banner-inner {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 18px;
}
.pta-title-banner-inner::before {
  content: "";
  position: absolute;
  right: -110px;
  top: 50%;
  width: 150px;
  height: 150px;
  transform: translateY(-50%);
  background: var(--pta-banner-logo, none) center / contain no-repeat;
  opacity: 0.12;
  pointer-events: none;
}
.pta-title-banner-heading {
  margin: 0;
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  font-weight: var(--pta-font-display-weight, 400);
  font-size: clamp(2.4rem, 5.5vw, 3.6rem);
  letter-spacing: 0.05em;
  line-height: 1;
  text-transform: uppercase;
  /* Chrome-aware, not white: the banner sits ON the chrome, so on a light
     chrome a hardcoded white heading is 1:1 against its own background. */
  color: var(--pta-on-chrome, #fff);
}
/* Angled ribbon under the title, like the graphic's gold bars. Same accent
   token as the stripes above, for the same reason. */
.pta-title-banner-ribbon {
  display: block;
  width: 130px;
  height: 9px;
  margin: 16px auto 0;
  background: var(--pta-chrome-accent);
  transform: skewX(-24deg);
}
/* Sparkle flourishes beside the page title. Font Awesome rather than an
   inlined SVG: the old one baked in Henry's gold, so every other PTA wore a
   gold sparkle regardless of its own palette. */
.pta-sparkle {
  flex: none;
  font-family: "Font Awesome 7 Free";
  font-weight: 900;
  font-style: normal;
  font-size: 18px;
  line-height: 1;
  color: var(--pta-chrome-accent);
}
.pta-sparkle::before { content: "\f005"; }

/* ---- The art variant: the page header cut from the home banner ----
   Same ground, same mark tiled across it, same wash, same divider. The tile is
   sized `contain`, so this shorter band shrinks the mark and repeats it more
   often than the banner does, with nothing to configure. */
.pta-title-banner--art {
  background-color: var(--pta-hero-ground, var(--pta-chrome));
  background-image:
    var(--pta-hero-wash, none),
    var(--pta-hero-tile, none);
  background-repeat: no-repeat, var(--pta-hero-tile-repeat, repeat-x);
  background-size: cover, var(--pta-hero-tile-size, contain);
  background-position: center, center var(--pta-hero-tile-offset, 24%);
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 180px;
  padding: 30px 24px;
  margin: 0 0 36px;
}
/* The panel both art bands put their copy on. Shared, because the page-title
   banner and the single-activity header sit one click apart and a panel on one
   with bare text on the other looks like two different sites.
   The divider eats into the band from below, so it needs room to sit clear of
   the ridgeline rather than being sliced by it. */
.pta-title-banner--art .pta-title-banner-panel,
.pta-act-detail-head--art .pta-act-detail-head-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto 26px;
  padding: 0.5em 0.8em;
  border-radius: var(--pta-radius, 5px);
  background: color-mix(in srgb, var(--pta-white) 88%, transparent);
  box-shadow: var(--pta-shadow);
}
/* 88%, not the 70% the Divi original used. The panel is only as light as what
   shows through it, and the brand colour on a 70% panel over this navy
   measured 3.27:1: past the large-text floor and nowhere near the normal one.
   At 88% the worst case (panel over the darkest part of the ground) measures
   4.50:1, so it clears the normal-text bar outright, and the title is large
   text anyway. Still reads as translucent. */
.pta-title-banner--art .pta-title-banner-heading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  color: var(--pta-primary);
  text-shadow: none;
}
.pta-title-banner-mark {
  flex: none;
  width: auto;
  height: 1.05em;
  display: block;
}
@media (max-width: 600px) {
  .pta-title-banner--art { min-height: 140px; padding: 22px 16px; }
  .pta-title-banner--art .pta-title-banner-panel { margin-bottom: 18px; }
}

/* The single-activity header wears the same ground. It is NOT a page-title
   banner (it carries a date tile, a when/where line and lens chips, so it
   keeps its own markup), but it sits one click from pages that are, and a
   flat chrome bar next to a tiled one reads as an unfinished page. The plugin
   sets the artwork variables and the --art class; everything else is here,
   because the ground is the theme's business. */
.pta-act-detail-head--art {
  position: relative;
  background-color: var(--pta-hero-ground, var(--pta-chrome));
  background-image:
    var(--pta-hero-wash, none),
    var(--pta-hero-tile, none);
  background-repeat: no-repeat, var(--pta-hero-tile-repeat, repeat-x);
  background-size: cover, var(--pta-hero-tile-size, contain);
  background-position: center, center var(--pta-hero-tile-offset, 24%);
  padding-bottom: 64px;   /* room for the ridgeline to cut in */
}
/* On the panel the copy reads dark, the same way the page title does. The
   white-with-a-text-shadow it used on flat chrome is unreadable here: the
   comets run straight through the letterforms. */
.pta-act-detail-head--art .pta-act-detail-title {
  color: var(--pta-primary);
  text-shadow: none;
}
.pta-act-detail-head--art .pta-act-detail-when {
  color: var(--pta-ink);
  text-shadow: none;
}

/* Display font across section headings for social-style cohesion. */
.pta-bm-heading,
.pta-ft-group-title,
.pta-bm-chairrole-title,
.pta-section h2,
.pta-content h2,
.pta-entry-title {
  font-family: var(--pta-font-display, "PTA Display", "Arial Narrow", sans-serif);
  /* The chosen face's own weight, not a flat 400. Bebas and Anton are 400,
     Oswald is 500; asking every one of them for 400 left Oswald with no
     matching face and the browser synthesised one, which is most of why these
     read as soft. */
  font-weight: var(--pta-font-display-weight, 400);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  /* A SIZE. This group had none, so every heading outside a home-page section
     inherited the browser's default h2 and rendered at 24px against prod's
     32px. A condensed display face at 24px is also where "blurry" comes from:
     the strokes are too fine to resolve. The .pta-section h2 rule below still
     wins for home-page bands, which set their own scale. */
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.2;
  /* Prod is rgba(0,0,0,0.75), softer than the solid near-black these were
     using. Derived from the ink token so it follows the palette, and it still
     measures over 9:1 on white. */
  color: color-mix(in srgb, var(--pta-ink) 82%, transparent);
}

/* Plugin module pages (Favorite Things, Board Members) render their own
   layout inside the page container. Under a foreign theme the plugin centres
   these itself; under this theme it defers to us, so we have to actually do
   it or every group heading sits hard against the left edge. */
.pta-ft-group-title,
.pta-ft-section-title,
.pta-ft-bd-month-title {
  text-align: center;
}
.pta-ft-list,
.pta-ft-groups,
.pta-bm {
  margin-left: auto;
  margin-right: auto;
}

/* Script accent for the tagline, echoing the social graphics' swash. */
.pta-brand-tag,
.pta-footer-tag,
.pta-tagline {
  font-family: "PTA Script", cursive;
  font-style: normal;
}

/* ============================================================
   Buttons
   ============================================================ */
.pta-btn {
  display: inline-block;
  background: var(--pta-primary);
  /* The palette's own text-on-primary token, not the near-black. Black on a
     gold fill happens to work (Henry, 9.99:1) but on a blue one it is 2.89:1,
     so every button on a dark-brand site was failing. Identical for Henry. */
  color: var(--pta-on-primary) !important;
  font-weight: 800;
  text-decoration: none;
  padding: 14px 28px;
  border-radius: var(--pta-radius);
  border: 2px solid var(--pta-primary);
  box-shadow: var(--pta-shadow-sm);
  transition: transform 0.08s ease, background 0.15s ease, box-shadow 0.15s ease;
  letter-spacing: 0.02em;
  /* Label and hover mark stay on one line. */
  white-space: nowrap;
}
/* Darken on hover rather than brighten. Brightening the fill while the label
   stays on-primary drops a blue brand to 3.04:1; the secondary holds 9.15
   for Cox and 7.52 for Henry. */
.pta-btn:hover {
  background: var(--pta-secondary);
  border-color: var(--pta-primary-bright);
  /* Rise and cast further: the shadow is what makes the 1px move read as a
     lift rather than as a jitter. */
  transform: translateY(-2px);
  box-shadow: var(--pta-shadow);
}
.pta-btn:active {
  transform: translateY(0);
  box-shadow: var(--pta-shadow-sm);
}
/* Hover mark: a Font Awesome glyph that slides in on the RIGHT of the label.
   The glyph is a brand setting (--pta-btn-icon), so a PTA picks its own.
   It sits in the normal inline flow rather than being absolutely positioned,
   which is what keeps it on the text baseline at any button size: the Divi
   original was absolutely positioned with its own line-height and drifted low
   the moment the button's type changed. */
.pta-btn::after {
  content: var(--pta-btn-icon, none);
  font-family: "Font Awesome 7 Free";
  font-weight: 900;
  font-size: 0.85em;
  display: inline-block;
  /* The space is reserved ALWAYS, and only opacity and transform animate.
     Growing the width on hover animates LAYOUT: the button changes size, the
     label reflows, and a label that only just fitted wraps to a second line
     the moment you point at it. Nothing here changes the box, so the button
     is the same size hovered or not and the mark simply appears. */
  width: 1em;
  margin-left: 0.4em;
  opacity: 0;
  transform: translateX(-0.3em);
  transition: opacity 0.28s ease, transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.pta-btn:hover::after,
.pta-btn:focus-visible::after {
  opacity: 1;
  transform: translateX(0);
}
@media (prefers-reduced-motion: reduce) {
  .pta-btn::after { transition: none; }
}
.pta-btn--lg { font-size: 1.15rem; padding: 18px 40px; }
.pta-btn--ghost {
  background: transparent;
  color: var(--pta-white) !important;
  border-color: var(--pta-white);
}
.pta-btn--ghost:hover {
  background: var(--pta-white);
  color: var(--pta-black) !important;
}
/* On light sections the white ghost button disappears; use the ink outline. */
.pta-section:not(.pta-section--dark) .pta-btn--ghost {
  color: var(--pta-black) !important;
  border-color: var(--pta-black);
}
/* Hover fills it dark, so the label needs the BRIGHT primary: plain primary
   on the dark fill is 2.89:1 for a blue brand. */
.pta-section:not(.pta-section--dark) .pta-btn--ghost:hover {
  background: var(--pta-black);
  color: var(--pta-primary-bright) !important;
}

/* ============================================================
   Forms (site-wide control layer)
   ------------------------------------------------------------
   Every text-like control inside page content inherits the brand
   look from the theme, so modules never restyle inputs ad hoc.
   Modules only add LAYOUT (grids, cards) on top of this.
   ============================================================ */
.pta-page input[type="text"],
.pta-page input[type="email"],
.pta-page input[type="url"],
.pta-page input[type="tel"],
.pta-page input[type="search"],
.pta-page input[type="number"],
.pta-page input[type="password"],
.pta-page input[type="date"],
.pta-page textarea,
.pta-page select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 1.02rem;
  color: var(--pta-ink);
  background: var(--pta-white);
  border: 1.5px solid #cfc8b8;
  border-radius: var(--pta-radius);
  padding: 13px 16px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.pta-page input:focus,
.pta-page textarea:focus,
.pta-page select:focus {
  outline: none;
  border-color: var(--pta-primary);
  box-shadow: 0 0 0 4px rgba(244, 180, 28, 0.25);
}
.pta-page ::placeholder {
  color: #a89f8c;
  opacity: 1;
}
.pta-page label {
  font-weight: 600;
  color: var(--pta-ink);
}
/* Buttons: every button is clickable, so every button gets the pointer,
   never rely on per-button styling for that. Fix the browser's system font
   without clobbering .pta-btn's weight/size (the `font` shorthand would
   reset both). */
.pta-page button,
.pta-btn {
  cursor: pointer;
}
.pta-page button {
  font-family: inherit;
}
/* File inputs: brand the picker button instead of the browser's grey chip. */
.pta-page input[type="file"] {
  font: inherit;
  color: var(--pta-gray);
}
.pta-page input[type="file"]::file-selector-button {
  cursor: pointer;
  background: var(--pta-primary);
  color: var(--pta-on-primary);
  border: 2px solid var(--pta-primary);
  border-radius: var(--pta-radius);
  font: inherit;
  font-weight: 800;
  padding: 10px 18px;
  margin-right: 12px;
  transition: background 0.15s ease;
}
.pta-page input[type="file"]::file-selector-button:hover {
  background: var(--pta-primary-bright);
  border-color: var(--pta-primary-bright);
}

/* Helper + fine-print text under fields. */
.pta-form-help {
  color: var(--pta-gray);
  font-size: 0.95rem;
  margin: 8px 0 0;
}
/* A generic white content card, matching the module card look. */
.pta-card {
  background: var(--pta-white);
  border: 1px solid var(--pta-line);
  border-radius: var(--pta-radius);
  /* The brand's own depth, not a hardcoded 5% smudge. At 0.05 the card read
     as a flat rectangle with a hairline border and nothing lifted off the
     page, which is most of why the whole thing looked flat. */
  box-shadow: var(--pta-shadow);
  padding: 26px 30px;
}

/* ============================================================
   Hero (home)
   ============================================================ */
/* The banner art is per-site: --pta-hero-image, from the hero_image_id config.
   A site WITHOUT its own artwork gets --pta-hero-fallback, a gradient in its
   own palette, never a photograph. The theme used to fall back to a bundled
   hero-banner.jpg, which is Henry's badge and hawk over Henry Middle School,
   so every other PTA put another school's building on its own front page.
   The banner art (badge + streaks + school) is baked into hero-banner.jpg and
   painted by ::after, capped at 1280px and centered over a black base.
   Desktop: the message sits on the RIGHT (clearing the baked-in badge) and the
   in-message logo is hidden. Mobile (<=768px): ::after reframes to the school so
   the badge scrolls off-screen, the in-message logo shows, and content centers.
   Content + button always show. */
.pta-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  justify-content: center;      /* centers the 1280 stage */
  min-height: clamp(460px, 60vh, 560px);
  color: var(--pta-on-chrome);
  text-align: center;
  border-bottom: 4px solid var(--pta-primary);
  background: var(--pta-chrome);   /* fills the sides beyond the 1280 banner */
}
/* A shaped divider is already the bottom edge. Drawing the accent rule as well
   put a blue line straight across the page under Cox's white mountain ridge. */
.pta-hero--divided { border-bottom: 0; }
/* The banner art + legibility scrim, capped at 1280 and centered. A horizontal
   mask feathers its left/right edges into the black base, so on screens wider
   than 1280 the banner fades out instead of stretching. */
.pta-hero::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 1280px;
  z-index: -1;
  background:
    linear-gradient(90deg, transparent 28%, rgba(0,0,0,0.50) 64%, rgba(0,0,0,0.72) 100%),
    var(--pta-hero-image, var(--pta-hero-fallback)) center center / cover no-repeat;
}
/* Only past the 1280 cap (where black margins appear) feather the banner's
   edges into the base; below that the banner fills edge-to-edge unchanged. */
@media (min-width: 1281px) {
  .pta-hero::after {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  }
}
/* Stage caps the message width and pins it to the right of the banner. */
.pta-hero-stage {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 44px clamp(24px, 5vw, 72px);
}
.pta-hero-inner { max-width: 560px; }
.pta-hero img.pta-hero-logo {
  display: none;               /* desktop: the badge is already in the banner art */
  width: 120px;
  height: auto;
  margin: 0 auto 14px;
  filter: drop-shadow(0 6px 20px rgba(0,0,0,0.6));
}
.pta-hero h1 {
  color: var(--pta-on-chrome);
  font-size: clamp(2rem, 5.2vw, 3.1rem);
  margin: 0 0 6px;
  text-shadow: 0 2px 18px rgba(0,0,0,0.6);
}
.pta-hero .pta-tagline {
  color: var(--pta-primary);
  font-style: italic;
  font-size: clamp(1rem, 2.4vw, 1.35rem);
  margin: 0 0 12px;
}
.pta-hero .pta-hero-rule {
  display: block;
  width: 64px; height: 4px;
  margin: 0 auto 16px;
  background: var(--pta-primary);
  border-radius: 2px;
}
.pta-hero .pta-hero-cry {
  color: var(--pta-primary);
  font-weight: 800;
  font-size: clamp(1.25rem, 3vw, 1.85rem);
  margin: 0 0 10px;
  text-shadow: 0 2px 16px rgba(0,0,0,0.5);
}
.pta-hero .pta-hero-lead {
  max-width: 600px;
  margin: 0 auto 24px;
  color: rgba(255,255,255,0.88);
  font-size: clamp(0.98rem, 2vw, 1.1rem);
  text-shadow: 0 1px 10px rgba(0,0,0,0.5);
}
.pta-hero .pta-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
}
/* Mobile: focus the banner on the school (badge scrolls off-screen), full-bleed
   (no 1280 cap or edge fade), center the message, and show the in-message logo
   since the baked-in badge is gone. */
@media (max-width: 768px) {
  .pta-hero { min-height: clamp(500px, 78vh, 640px); }
  .pta-hero::after {
    max-width: none;
    background:
      linear-gradient(180deg, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.30) 42%, rgba(0,0,0,0.62) 100%),
      var(--pta-hero-image, var(--pta-hero-fallback)) 84% center / cover no-repeat;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .pta-hero-stage { justify-content: center; padding: 40px 22px 46px; }
  .pta-hero-inner { max-width: 480px; margin: 0 auto; }
  .pta-hero img.pta-hero-logo { display: block; }
}

/* ============================================================
   Sections / cards
   ============================================================ */
.pta-section { padding: 56px 0; }
.pta-section--cream { background: var(--pta-cream); }

/* Quiet tint: the step between white and dark. Cooler than --pta-cream, which
   is a warm parchment and reads yellow beside a blue brand. */
.pta-section--tint { background: var(--pta-section-tint); }

/* Dark strip, used by the home sections carrying full-bleed media (a Facebook
   wall reads better against dark than against cream). Text is inverted here so
   anything dropped inside inherits readable colour instead of the body ink.

   Its ground is --pta-section-dark, NOT the chrome. Chrome is the header and
   the footer; a dark CONTENT band is not chrome, and tying the two together
   meant that choosing brand chrome turned the masonry band, the join band and
   the footer all into one flat colour. A site is entitled to a blue header and
   dark content bands. */
.pta-section--dark {
  background: var(--pta-section-dark);
  color: var(--pta-on-section-dark);
}
.pta-section--dark h1,
.pta-section--dark h2,
.pta-section--dark h3 {
  color: var(--pta-on-section-dark);
}
/* Doubled `.pta-section` on the lead is deliberate. The generic
   `.pta-section .pta-section-lead` further down sets --pta-gray, and at equal
   (0,2,0) specificity the later rule wins: the join band's copy measured
   #6b6b6b on #191d33, which is 2.91:1 and fails 4.5:1 outright. (0,3,0) here
   settles it on specificity rather than on which rule happens to come last. */
.pta-section.pta-section--dark .pta-section-lead,
.pta-section--dark p {
  color: var(--pta-on-section-dark-muted);
}
.pta-section--dark a:not(.pta-btn) {
  color: var(--pta-primary-bright);
}

/* Full-bleed: the section's own child manages its width (feed plugins ship
   their own grid), so we contribute the strip and the vertical rhythm only. */
.pta-section--flush { padding-left: 0; padding-right: 0; }

/* Two editorial cards side by side, stacking on narrow screens. */
.pta-home-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
  align-items: start;
}

/* Closing join call: copy left, button right, stacked on phones. */
.pta-home-join-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
/* Same doubling, same reason: the generic lead rule below centres it, so the
   heading sat flush left with its own paragraph centred underneath. */
.pta-home-join .pta-home-heading,
.pta-section.pta-home-join .pta-section-lead {
  text-align: left;
  margin-left: 0;
}
.pta-home-join-cta { margin: 0; }
.pta-home-join-cta > p { margin: 0; }
/* Button above, social row beneath it, both flush right against the copy. */
.pta-home-join-cta .pta-social { justify-content: flex-end; }

/* ---- Facebook feed height cap: STUB, goes with the carousel ----
   Smash Balloon's carousel sizes itself to its TALLEST slide, so one portrait
   photo makes the whole band enormous even when every other image is
   landscape. That is the plugin's behaviour, not ours, and the real fix is the
   replacement carousel.

   The same cap lives in divi-bridge.css scoped to #et-boc, which reached the
   Divi home page only. The composed page is not builder content, so it
   inherited none of it and the carousel measured 908px against a 526px
   reference. This copy is the one that survives: divi-bridge.css is deleted
   when Divi goes.

   Scoped to cff- classes so nothing else on the page is affected, and `cover`
   crops the overflow rather than squashing the photo. */
.pta-section [class*="cff"] img {
  max-height: 23em;
  object-fit: cover;
}

/* ---- Social accounts ----
   A row of Font Awesome brand marks, one per account the PTA has configured. */
.pta-social {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0 0;
  padding: 0;
}
/* One tile treatment for every network, not each in its own brand colour.
   A row of Facebook blue, Instagram pink and X black is three logos competing
   with the page rather than a set of links; matching them makes the row read
   as one control and lets the PTA's own palette stay in charge. Sized to
   prod's 64px, which is also a generous touch target. */
.pta-social-link {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 10px;
  color: var(--pta-white);
  text-decoration: none;
  background: var(--pta-black);
  box-shadow: var(--pta-shadow-sm);
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}
.pta-social-link:hover,
.pta-social-link:focus-visible {
  background: var(--pta-primary);
  color: var(--pta-on-primary);
  transform: translateY(-2px);
  box-shadow: var(--pta-shadow);
}
.pta-social-icon {
  font-size: 1.6rem;
  line-height: 1;
}
@media (max-width: 600px) {
  .pta-social-link { width: 52px; height: 52px; }
  .pta-social-icon { font-size: 1.3rem; }
}
.pta-section h2 {
  font-size: clamp(1.6rem, 3.5vw, 2.2rem);
  margin: 0 0 8px;
  text-align: center;
}
.pta-section .pta-section-lead {
  text-align: center;
  max-width: 720px;
  margin: 0 auto 36px;
  color: var(--pta-gray);
  font-size: 1.08rem;
}
.pta-brand-rule {
  width: 64px; height: 4px; background: var(--pta-primary);
  border: 0; margin: 14px auto 24px; border-radius: 2px;
}
/* The invite under the sponsor logos. Its own rule rather than a utility
   because the plugin owns the band above it and never loads Tailwind. */
.pta-sponsors-cta { margin: 40px 0 0; text-align: center; }

/* Generic page content */
/* No padding on the article itself. Full-bleed bands (title banner, 404 hero,
   page-builder sections, the home hero) must meet the header and the footer
   edge to edge; padding here put a white stripe above and below every one of
   them. The breathing room belongs to reading-width content, so it lives on
   the container instead, and only when that container actually opens or ends
   the page. */
.pta-page { padding: 0; }
.pta-page > .pta-container:first-child { padding-top: 48px; }
.pta-page > .pta-container:last-child { padding-bottom: 64px; }
.pta-page .pta-entry-title { text-align: center; margin-bottom: 8px; }
/* Center the 404 / "nothing here" fallback message under its centered title. */
.pta-page > .pta-container > .pta-section-lead { text-align: center; }
.pta-content { max-width: min(1100px, 100%); margin: 0 auto; }
.pta-content h2 { margin-top: 1.6em; }
.pta-content img { border-radius: var(--pta-radius); }

/* ---- Core Block Editor buttons ----
   Pages built in the block editor use core's button, not .pta-btn, and it was
   getting none of the same treatment: no depth, no motion, and no hover state
   at all, so the stylesheet's global a:hover took over and turned a white
   label black on a blue fill. Colours and hover live in theme.json so the
   editor canvas agrees; what cannot be expressed there is here.

   :where() keeps the specificity at zero so a per-button colour chosen in the
   editor still wins. */
:where(.wp-block-button__link) {
  box-shadow: var(--pta-shadow-sm);
  transition: transform 0.08s ease, background 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}
.wp-block-button__link:hover,
.wp-block-button__link:focus-visible {
  /* Stated here as well as in theme.json. theme.json emits its hover through
     :where(), which is zero-specificity by design, so anything at (0,1,1) or
     above outranks it. Belt and braces on the one property whose failure is a
     black label on a dark fill. */
  color: var(--pta-on-primary);
  transform: translateY(-2px);
  box-shadow: var(--pta-shadow);
}
.wp-block-button__link:active {
  transform: translateY(0);
  box-shadow: var(--pta-shadow-sm);
}

/* The outline variant. Core paints it from currentColor, which left it in the
   near-black body colour rather than the brand, and gave it no hover at all:
   the one button on the page that did nothing when you pointed at it. It fills
   in on hover, the same move .pta-btn--ghost makes. */
.wp-block-button.is-style-outline > .wp-block-button__link {
  color: var(--pta-primary);
  border-color: currentColor;
  box-shadow: none;
}
.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-outline > .wp-block-button__link:focus-visible {
  background-color: var(--pta-primary);
  border-color: var(--pta-primary);
  color: var(--pta-on-primary);
  box-shadow: var(--pta-shadow);
}
/* On a dark band the brand outline can disappear; use the band's own text
   colour, matching how .pta-btn--ghost behaves there. */
.pta-section--dark .wp-block-button.is-style-outline > .wp-block-button__link {
  color: var(--pta-on-section-dark);
}

/* ============================================================
   Footer
   ============================================================ */
.pta-site-footer {
  background: var(--pta-chrome);
  color: var(--pta-on-chrome-muted);
  padding: 40px 20px;
  text-align: center;
  border-top: 4px solid var(--pta-chrome-accent);
}
.pta-site-footer a {
  color: var(--pta-chrome-accent);
  text-decoration: none;
  border-radius: 6px;
  transition: background 0.15s ease, color 0.15s ease;
}
/* A highlight rather than only an underline: the footer links are the site's
   social and contact routes, and an underline alone is easy to miss against a
   coloured chrome. The wash is derived from the chrome's own text colour, so
   it works on dark, brand and light chrome alike. */
.pta-site-footer a:hover,
.pta-site-footer a:focus-visible {
  color: var(--pta-on-chrome);
  background: color-mix(in srgb, var(--pta-on-chrome) 14%, transparent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.pta-footer-col a {
  display: inline-block;
  padding: 2px 8px;
  margin-left: -8px;
}
.pta-footer-tag { color: var(--pta-chrome-accent); font-style: italic; margin-top: 6px; }
.pta-footer-legal {
  /* The same muted token as the rest of the footer rather than a second,
     fainter level: at 58% this measured 3.03:1 on Cox's brand-colour chrome,
     and it is small text, so it needs the full 4.5. Size alone sets it apart. */
  color: var(--pta-on-chrome-muted);
  font-size: 0.85rem;
  margin-top: 10px;
}

/* ============================================================
   Print: strip site chrome everywhere. The off-canvas drawer is a
   fixed full-height black panel; print rendering ignores its
   off-screen transform and paints it over the page, so hide it.
   ============================================================ */
@media print {
  .pta-site-header,
  .pta-site-footer,
  .pta-nav,
  .pta-nav-overlay,
  .pta-menu-toggle {
    display: none !important;
  }
  /* The html canvas is painted black for overscroll on screen; on paper
     that black floods everything past the content. */
  html,
  body {
    background: #fff !important;
  }
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 1150px) {
  .pta-menu-toggle { display: inline-block; }

  /* Primary nav becomes an off-canvas drawer sliding in from the right. */
  .pta-nav {
    position: fixed;
    top: 0;
    right: 0;
    height: 100dvh;
    width: 90%;
    background: var(--pta-chrome);
    border-left: 4px solid var(--pta-primary);
    transform: translateX(100%);
    transition: transform 0.3s ease;
    /* Pin a stable compositing layer so the browser doesn't tear it down at
       the end of the slide transition (which flashed the viewport white). */
    will-change: transform;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    z-index: 1002;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
  }
  .pta-nav.is-open { transform: translateX(0); }

  .pta-nav-close { display: block; align-self: flex-end; }
  .pta-nav ul { flex-direction: column; align-items: stretch; padding: 8px 8px 24px; }
  .pta-nav a { display: block; padding: 12px 16px; }

  /* In the drawer, sub-menus render inline as an always-visible indented
     list (no hover on touch) with a gold guide line. */
  .pta-nav ul ul {
    display: flex;
    position: static;
    min-width: 0;
    background: transparent;
    border: 0;
    border-left: 2px solid var(--pta-secondary);
    border-radius: 0;
    box-shadow: none;
    margin-left: 16px;
    padding: 0 0 0 4px;
  }
  .pta-nav ul ul a { font-size: 0.9em; padding: 10px 16px; }
  .pta-nav ul ul::before { display: none; }
  /* Third level in the drawer: same static nested-list treatment, one
     indent deeper; undo the desktop flyout offsets. */
  /* Each level steps FURTHER in than its parent. This used to indent 12px
     against the second level's 16px, so the third level's guide line drifted
     back toward its parent's and the nesting read as one flat list. */
  .pta-nav ul ul ul {
    margin-left: 22px;
    margin-right: 0;
    left: auto;
    right: auto;
  }
  /* The desktop rule that flips flyouts leftward under the last two nav items
     is more specific than the one above (0,2,4 vs 0,1,3), so it leaked into
     the drawer and zeroed the indent there, which is why the third tier under
     the RIGHTMOST menus (Resources -> School Links) sat almost on top of its
     parent's guide line. Nothing flies out in a drawer, so undo it here at
     matching specificity. */
  .pta-nav > ul > li:nth-last-child(-n+2) ul ul {
    margin-left: 16px;
    margin-right: 0;
    left: auto;
    right: auto;
  }
  .pta-nav > ul > li:nth-last-child(-n+2) ul ul ul {
    margin-left: 22px;
  }
  /* Drawer lists render fully expanded, so pointer glyphs would imply a
     toggle that does not exist. */
  .pta-nav .menu-item-has-children > a::after { display: none; }

  /* ---- Collapsed-submenu mode (per-site setting: Settings > Mobile menu).
     Long menus made the always-expanded drawer scroll forever, so a site can
     start every submenu closed behind a real toggle button that nav.js
     injects. The parent link itself still navigates on first tap. ---- */
  body.pta-mobile-submenus-closed .pta-nav ul ul { display: none; }
  body.pta-mobile-submenus-closed .pta-nav li.pta-submenu-open > ul { display: flex; }
  body.pta-mobile-submenus-closed .pta-nav .menu-item-has-children { position: relative; }
  body.pta-mobile-submenus-closed .pta-nav .menu-item-has-children > a { margin-right: 52px; }
  body.pta-mobile-submenus-closed .pta-nav .pta-submenu-toggle {
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    width: 48px;
    height: 44px;
    border: 0;
    background: transparent;
    cursor: pointer;
    color: var(--pta-chrome-accent);
  }
  body.pta-mobile-submenus-closed .pta-nav .pta-submenu-toggle::before {
    content: var(--pta-nav-icon, "\f52d");
    font-family: "Font Awesome 7 Free";
    font-weight: 900;
    font-style: normal;
    font-size: 0.9em;
    line-height: 1;
    display: inline-block;
    transform: var(--pta-nav-icon-transform, none);
    transition: transform 0.25s ease;
  }
  body.pta-mobile-submenus-closed .pta-nav .pta-submenu-open > .pta-submenu-toggle::before {
    transform: var(--pta-nav-icon-transform, rotate(0deg)) rotate(var(--pta-nav-icon-hover-rotate, 90deg));
  }

  /* Full-screen dimmed backdrop behind the drawer (dialog-style). */
  .pta-nav-overlay {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease;
    z-index: 1001;
  }
  .pta-nav-overlay.is-open { opacity: 1; visibility: visible; }

  body.pta-nav-open { overflow: hidden; }
}

/* ============================================================
   404: page not found

   Shares the title banner's treatment (dark band, brand rules,
   angled stripes, logo watermark) so a lost visitor still knows
   whose site they are on. Copy is config; this is only its shape.
   ============================================================ */
.pta-404-hero {
  position: relative;
  background: var(--pta-chrome);
  border-top: 2px solid var(--pta-primary);
  border-bottom: 2px solid var(--pta-primary);
  padding: 64px 24px 56px;
  margin: 0 0 40px;
  text-align: center;
  overflow: hidden;
}
/* The site's own artwork, when it has one, sits behind at low contrast so
   the text keeps its ratio no matter what image a PTA uploads. */
.pta-404-hero--image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--pta-404-image) center / cover no-repeat;
  opacity: 0.35;
  pointer-events: none;
}
/* No image: fall back to the same angled brand stripes the title banner
   uses, so an unconfigured site still looks deliberate. */
.pta-404-hero:not(.pta-404-hero--image)::before,
.pta-404-hero:not(.pta-404-hero--image)::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 130px;
  background: repeating-linear-gradient(
    -55deg,
    var(--pta-primary) 0 10px,
    transparent 10px 34px
  );
  opacity: 0.28;
  pointer-events: none;
}
.pta-404-hero:not(.pta-404-hero--image)::before { left: -20px; }
.pta-404-hero:not(.pta-404-hero--image)::after { right: -20px; transform: scaleX(-1); }

.pta-404-inner {
  position: relative;
  z-index: 1;
  max-width: 720px;
  margin: 0 auto;
}

/* Oversized, low-contrast, and aria-hidden: decoration, not the heading. */
.pta-404-code {
  font-family: var(--pta-font-display);
  font-size: clamp(4rem, 14vw, 9rem);
  line-height: 0.9;
  margin: 0 0 8px;
  letter-spacing: 0.08em;
  /* Bright primary, not plain primary: this sits on the dark band, where a
     blue brand's plain primary is 2.89:1 (Cox). Decoration, but it should
     still read as brand rather than mud. */
  color: var(--pta-chrome-accent);
  opacity: 0.55;
}

.pta-404-heading {
  font-family: var(--pta-font-display);
  font-size: clamp(1.6rem, 4vw, 2.6rem);
  color: var(--pta-on-chrome);
  margin: 0 0 14px;
  letter-spacing: 0.03em;
}
.pta-404-lead {
  color: var(--pta-chrome-accent);
  font-size: 1.12rem;
  font-weight: 600;
  margin: 0 0 10px;
}
.pta-404-body {
  color: var(--pta-on-chrome);
  opacity: 0.86;
  margin: 0;
}

.pta-404-content {
  max-width: 640px;
  margin: 0 auto 56px;
  text-align: center;
}
.pta-404-subheading {
  font-family: var(--pta-font-display);
  font-size: 1.25rem;
  margin: 0 0 18px;
}

.pta-404-links {
  list-style: none;
  margin: 0 0 32px;
  padding: 0;
  display: grid;
  gap: 12px;
}
.pta-404-links a {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 14px;
  padding: 14px 18px;
  border: 2px solid var(--pta-line);
  border-radius: var(--pta-radius);
  background: var(--pta-white);
  color: var(--pta-ink);
  text-decoration: none;
  font-weight: 600;
  text-align: left;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.pta-404-links a:hover,
.pta-404-links a:focus-visible {
  /* Darken toward secondary rather than brighten: white-on-bright hits
     3.04:1 on a blue brand, which fails. */
  border-color: var(--pta-secondary);
  background: var(--pta-cream);
  color: var(--pta-ink);
  transform: translateY(-1px);
}
.pta-404-links i {
  color: var(--pta-secondary);
  width: 1.4em;
  text-align: center;
  flex: none;
}

.pta-404-content .search-form {
  display: flex;
  gap: 8px;
  margin: 0 0 28px;
}
.pta-404-content .search-form label { flex: 1; }
.pta-404-content .search-field {
  width: 100%;
  padding: 12px 14px;
  border: 2px solid var(--pta-line);
  border-radius: var(--pta-radius);
  font: inherit;
}
.pta-404-content .search-field:focus {
  outline: none;
  border-color: var(--pta-primary);
}
.pta-404-content .search-submit {
  padding: 12px 20px;
  border: 0;
  border-radius: var(--pta-radius);
  background: var(--pta-primary);
  color: var(--pta-on-primary);
  font-weight: 700;
  cursor: pointer;
}
.pta-404-content .search-submit:hover { background: var(--pta-secondary); color: var(--pta-white); }

.pta-404-closing {
  color: var(--pta-gray);
  font-style: italic;
  margin: 0;
}
.pta-404-closing i {
  color: var(--pta-primary);
  margin: 0 6px;
  /* The Divi original wanted twinkling sparkles and never got the CSS. */
  animation: pta-twinkle 2.4s ease-in-out infinite;
}
.pta-404-closing i:last-child { animation-delay: 1.2s; }

@keyframes pta-twinkle {
  0%, 100% { opacity: 0.35; transform: scale(0.9); }
  50%      { opacity: 1;    transform: scale(1.1); }
}
@media (prefers-reduced-motion: reduce) {
  .pta-404-closing i { animation: none; opacity: 1; }
}

/* ============================================================
   Block styles: the reusable pieces an officer picks from the
   sidebar. Registered in functions.php; this is what they look
   like. Icons come from the design system so a page never has to
   carry icon markup a future editor can break.
   ============================================================ */

/* Checklist: for "what your membership pays for" style lists. */
.is-style-pta-check {
  list-style: none;
  padding-left: 0;
}
.is-style-pta-check > li {
  position: relative;
  padding-left: 1.9em;
  margin-bottom: 0.5em;
}
.is-style-pta-check > li::before {
  content: "\f00c"; /* fa-check */
  font-family: "Font Awesome 7 Free";
  font-weight: 900;
  position: absolute;
  left: 0;
  top: 0.1em;
  color: var(--pta-primary);
  font-size: 0.9em;
}

/* Brand markers: the site's own mascot glyph as the bullet, so a plain list
   still reads as this PTA's. Same token the nav indicator uses. */
.is-style-pta-brand-marker {
  list-style: none;
  padding-left: 0;
}
.is-style-pta-brand-marker > li {
  position: relative;
  padding-left: 1.9em;
  margin-bottom: 0.5em;
}
.is-style-pta-brand-marker > li::before {
  content: var(--pta-nav-icon, "\f005");
  font-family: "Font Awesome 7 Free";
  font-weight: 900;
  position: absolute;
  left: 0;
  top: 0.1em;
  color: var(--pta-secondary);
  font-size: 0.85em;
}

/* Card: a white panel that lifts off the page, matching the board and
   activity cards so a hand-written page sits in the same visual family. */
.is-style-pta-card {
  background: var(--pta-white);
  border: 1px solid var(--pta-line);
  border-top: 5px solid var(--pta-primary);
  border-radius: var(--pta-radius);
  box-shadow: var(--pta-shadow-lift);
  padding: 28px 30px;
  margin-bottom: 28px;
}
.is-style-pta-card > *:first-child { margin-top: 0; }
.is-style-pta-card > *:last-child { margin-bottom: 0; }

/* Callout: a quieter tinted panel for an aside or a caveat. */
.is-style-pta-callout {
  background: var(--pta-cream);
  border-left: 5px solid var(--pta-secondary);
  border-radius: var(--pta-radius);
  padding: 20px 24px;
  margin-bottom: 28px;
}
.is-style-pta-callout > *:first-child { margin-top: 0; }
.is-style-pta-callout > *:last-child { margin-bottom: 0; }

/* ============================================================
   Hero: the banner recipe
   A coloured ground with the PTA's own mark tiled across it, a
   gradient wash over the top, and a shaped divider below. This
   is Cox's, and it lived only inside Divi until now.
   ============================================================ */
.pta-hero--banner {
  position: relative;
  background-color: var(--pta-hero-ground, var(--pta-black));
  /* Wash over tile over ground. The wash sits on top so the mark reads as
     texture rather than as a row of logos. */
  background-image:
    var(--pta-hero-wash, none),
    var(--pta-hero-tile, none);
  background-repeat: no-repeat, var(--pta-hero-tile-repeat, repeat-x);
  background-size: cover, var(--pta-hero-tile-size, contain);
  background-position: center, center var(--pta-hero-tile-offset, 24%);
  min-height: clamp(320px, 34vw, 420px);
}
/* The banner carries its own ground, so it must not inherit the photo
   recipe's image stack. BOTH halves of that stack: the stage, and .pta-hero
   ::after, which is where the photo recipe actually paints. Turning off only
   the stage left ::after painting the photo fallback gradient plus its
   right-hand darkening scrim straight over the tiled mark, which is why Cox's
   comets came out washed and the right of the banner went almost black. */
.pta-hero--banner .pta-hero-stage { background: none; }
.pta-hero--banner::after { content: none; }

/* ---- Banner copy: panels, not a scrim ----
   A tiled mark is busy across the whole width, so a corner gradient cannot
   make a paragraph readable over it. Each block gets its own translucent
   panel instead, which is what this banner used for years before it moved
   out of Divi. Both panels take brand tokens, so they follow the palette. */
.pta-hero--banner .pta-hero-stage {
  justify-content: flex-start;
  align-items: center;
}
.pta-hero--banner .pta-hero-inner {
  max-width: min(1080px, 100%);
  width: 100%;
  text-align: left;
}
.pta-hero--banner .pta-hero-greeting {
  display: flex;
  align-items: center;
  gap: 0.4em;
  margin: 0 0 clamp(18px, 3vw, 34px);
  padding: 0.3em 0.55em;
  border-radius: var(--pta-radius, 5px);
  /* Light panel, dark type: the reverse of the rest of the banner, which is
     what makes the greeting the first thing read rather than one more bright
     shape among the artwork. */
  background: color-mix(in srgb, var(--pta-white) 72%, transparent);
  box-shadow: var(--pta-shadow);
  color: var(--pta-hero-ground, var(--pta-black));
  font-family: var(--pta-font-display, inherit);
  font-size: clamp(1.6rem, 4.4vw, 3.4rem);
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 1.1;
  text-shadow: none;
}
.pta-hero--banner .pta-hero-mark {
  flex: none;
  width: auto;
  height: 1.25em;
  display: block;
}
/* Lead and button on one line, the button hugging the right of the panel row
   the way it does on the printed banner. Wraps on narrow screens. */
.pta-hero--banner .pta-hero-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(16px, 3vw, 40px);
}
.pta-hero--banner .pta-hero-lead {
  flex: 1 1 26em;
  max-width: 46em;
  margin: 0;
  padding: 0.75em 0.9em;
  border-radius: var(--pta-radius, 5px);
  /* 92%, not the 80% the Divi original used. A translucent panel is only as
     dark as what shows through it, and the artwork has near-white highlights:
     at 80% the white type over them measured 3.97:1, under the 4.5 floor. At
     92% the worst case is 4.92:1 and the panel still reads as translucent. */
  background: color-mix(in srgb, var(--pta-primary) 92%, transparent);
  box-shadow: var(--pta-shadow);
  color: var(--pta-on-primary);
  font-size: clamp(0.98rem, 1.5vw, 1.2rem);
  text-shadow: none;
}
.pta-hero--banner .pta-hero-cta {
  flex: none;
  justify-content: flex-start;
  margin: 0;
}
/* The banner's button inverts: a white slab with the brand colour as the
   label. On artwork this dense a brand-filled button is just another coloured
   shape, while white reads as the one thing to press. */
.pta-hero--banner .pta-hero-cta .pta-btn {
  background: var(--pta-white);
  border-color: var(--pta-white);
  color: var(--pta-primary) !important;
}
.pta-hero--banner .pta-hero-cta .pta-btn:hover {
  background: var(--pta-cream);
  border-color: var(--pta-cream);
}
@media (max-width: 768px) {
  .pta-hero--banner .pta-hero-stage { justify-content: center; }
  .pta-hero--banner .pta-hero-greeting { justify-content: center; text-align: center; }
  .pta-hero--banner .pta-hero-row { justify-content: center; }
  .pta-hero--banner .pta-hero-cta { width: 100%; justify-content: center; }
}

/* Divider: sits at the foot of the banner and paints in the colour of the
   section that follows, via currentColor on the wrapper. */
.pta-hero-divider {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px; /* -1 kills the hairline gap sub-pixel rounding leaves */
  line-height: 0;
  pointer-events: none;
  color: var(--pta-white);
}
.pta-hero-divider svg {
  display: block;
  width: 100%;
  height: clamp(38px, 5vw, 70px);
}
/* When the band under the hero is not white, the divider follows it. */
.pta-hero--banner + .pta-section--tint .pta-hero-divider,
.pta-hero-divider--tint { color: var(--pta-section-tint); }
.pta-hero-divider--dark { color: var(--pta-section-dark); }
