/* ============================================================
   CHARGED Initiative — main stylesheet
   Mobile-first: base styles target the 375px mobile spec
   (charged-mobile-homepage.html); min-width queries layer the
   desktop up. Tokens mirror DESIGN.md Part B / handoff §4.
   ============================================================ */

:root {
  /* Color — one canonical navy + one teal (duplicates collapsed) */
  --navy:         #003A63;  /* headings, nav, primary buttons, logo field */
  --nav-active:   #113C63;  /* nav hover/active — 11.35:1 on white, passes AA */
  --teal:         #44CFCB;  /* DECORATIVE ONLY — fails AA on white */
  --teal-dark:    #0F7E7A;  /* accessible teal for text/links — 4.9:1 on white, passes AA */
  --soft-teal:    #6FCCCA;  /* card outlines on navy sections */
  --ink:          #212121;  /* body text */
  --slate:        #557390;  /* muted/secondary text — 16px+ only (4.6:1, barely passes) */
  --white:        #FFFFFF;
  --gray-light:   #F2F2F2;  /* alternating section bg */
  --border:       #EEEEEE;
  --divider:      #CCCCCC;
  --input-border: #E1E1E1;
  --overlay:      rgba(51, 51, 51, 0.6);

  /* Type — single family: Poppins */
  --font: "Poppins", sans-serif;

  /* Layout */
  --container: 1280px;
  --gutter: 15px;

  /* Radius — pills per mockup; PENDING Annie sign-off (open decision #1) */
  --radius-button: 999px;
  --radius-card: 4px;
}

/* ---------- Base ---------- */
*,
*::before,
*::after { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

/* Body copy is 18px/1.7 site-wide (Kathy, 2026-08-04; was 16px/1.6).
   This is a reading site — people read, cite and forward the material —
   and the extra leading does as much work as the size. Component rules
   that carry prose were raised to match (.lead, .about__body p, .card p,
   .who__item p, .gi__lead, .resource-single__summary); UI chrome — nav,
   buttons, badges, form labels, card meta — deliberately did NOT move,
   so the gap between chrome and copy is now wider by design. */
body {
  font-family: var(--font);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.7;
  color: var(--ink);
  background: var(--white);
  overflow-x: hidden;
}

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

a { color: var(--navy); }
a:hover { color: var(--teal-dark); }

/* Deliberate, evenly-stepped semantic scale (desktop baseline per handoff §4;
   mobile steps hero/section sizes via component classes, not element defaults). */
h1 { font-size: 36px; font-weight: 700; line-height: 1.2;  color: var(--navy); }
h2 { font-size: 28px; font-weight: 700; line-height: 1.2;  color: var(--navy); }
h3 { font-size: 22px; font-weight: 600; line-height: 1.25; color: var(--navy); }
/* h4-h6 raised with the 18px body copy (2026-08-04). They were 18/16/14,
   which put h5 and h6 BELOW body size once it moved — an inverted scale.
   None of the three appear in a template; they exist for block-editor
   Pages, so an editor could reach them. h1-h3 are unchanged: they're
   overridden per component (hero, page-header, .section-title) and
   already clear body copy comfortably. */
h4 { font-size: 21px; font-weight: 600; line-height: 1.3;  color: var(--navy); }
h5 { font-size: 19px; font-weight: 700; line-height: 1.4;  color: var(--navy); }
h6 { font-size: 18px; font-weight: 700; line-height: 1.4;  color: var(--navy); }

.small { font-size: 14px; line-height: 1.5; }

.container { max-width: var(--container); margin-inline: auto; padding-inline: 24px; }

/* ---------- Accessibility helpers ---------- */
.screen-reader-text {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  border: 0;
  white-space: nowrap;
}

.skip-link:focus {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 200;
  width: auto; height: auto;
  margin: 0;
  padding: 12px 20px;
  clip-path: none;
  background: var(--navy);
  color: var(--white);
  font-weight: 700;
  text-decoration: none;
}

/* Visible focus ring everywhere — the live site's focus state was too subtle. */
:focus-visible { outline: 3px solid var(--teal-dark); outline-offset: 2px; }
.bg-navy :focus-visible,
.mobile-menu :focus-visible,
.site-footer :focus-visible { outline-color: var(--white); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block;
  text-align: center;
  font-family: var(--font);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  text-decoration: none;
  padding: 14px 30px; /* ≥44px tall — touch target minimum */
  border: 2px solid;
  border-radius: var(--radius-button);
  background: none;
  cursor: pointer;
}
.btn--navy  { color: var(--navy);  border-color: var(--navy); }
.btn--navy:hover  { background: var(--navy); color: var(--white); }
.btn--white { color: var(--white); border-color: var(--white); }
.btn--white:hover { background: var(--white); color: var(--navy); }
.btn--block { display: block; width: 100%; }
.btn--nav { padding: 10px 22px; font-size: 16px; }

/* ---------- Site header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 12px 18px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

/* height:auto + max-height is deliberate: with a fixed `height` the
   global `img { max-width: 100% }` shrinks the width on narrow screens
   while the height stays pinned, squashing the wordmark (measured 275×80
   at 375px against an intrinsic 500×126). Capping height instead lets it
   scale proportionally. */
.site-logo,
.custom-logo { max-height: 80px; height: auto; width: auto; max-width: 100%; }

/* Desktop inline nav — hidden on mobile, shown ≥1024px */
.site-nav--desktop { display: none; }

.site-nav .menu {
  display: flex;
  align-items: center;
  gap: 28px;
  list-style: none;
}
.site-nav--desktop .menu a {
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-decoration: none;
  /* 0.55, not the 0.5 originally specced: 50% black composites to #808080
     = 3.95:1 on white, under the 4.5:1 AA floor for 16px text (16px bold
     is NOT "large text" — that starts at 18.66px bold). 0.55 = #737373 =
     4.74:1, passes, and is visually near-identical. */
  color: rgba(0, 0, 0, 0.55);
  padding: 10px 0;
  border-bottom: 2px solid transparent;
}
.site-nav--desktop .menu a:hover,
.site-nav--desktop .menu .current-menu-item a { color: var(--nav-active); }
.site-nav--desktop .menu .current-menu-item a { border-bottom-color: var(--nav-active); }

/* ---------- Hamburger ---------- */
.hamburger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  min-width: 44px;  /* touch target */
  min-height: 44px;
  align-items: center;
  background: none;
  border: none;
  cursor: pointer;
}
.hamburger span {
  display: block;
  width: 26px;
  height: 3px;
  border-radius: 2px;
  background: var(--navy);
}

/* ---------- Mobile menu overlay ---------- */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 100;
  height: 100dvh;
  overflow-y: auto;
  background: var(--navy);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease;
}
.mobile-menu.open { opacity: 1; pointer-events: auto; }
.mobile-menu[hidden] { display: none; }

.mobile-menu__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.mobile-menu__wordmark { font-weight: 700; font-size: 24px; color: var(--white); }
.mobile-menu__close {
  min-width: 44px;
  min-height: 44px;
  background: none;
  border: none;
  color: var(--white);
  font-size: 32px;
  line-height: 1;
  cursor: pointer;
}

.site-nav--mobile .menu {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 6px 0;
}
.site-nav--mobile .menu a {
  display: block;
  color: var(--white);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-decoration: none;
  padding: 17px 22px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.mobile-menu__cta { padding: 22px; }

/* ---------- Sections ---------- */
section { padding: 46px 24px; }

.section-title { font-weight: 300; line-height: 1; }  /* thin Poppins per Part B */
h2.section-title { font-size: 32px; }

/* Leads keep slightly tighter leading than body copy — they're one or two
   lines, and 1.7 reads gappy at that length. */
.lead { font-size: 18px; line-height: 1.6; }

.bg-navy { background: var(--navy); color: var(--white); }
.bg-navy h2, .bg-navy h3 { color: var(--white); }
.bg-gray  { background: var(--gray-light); }
.bg-white { background: var(--white); }
.center { text-align: center; }

/* ---------- Hero + credibility band ---------- */
.hero {
  position: relative;
  padding: 40px 24px 34px;
  /* Flat navy until hero_bg_image is set — matches the archive header bands
     and the footer. An inline background-image overrides the image part only. */
  background: var(--navy);
  background-size: cover;
  background-position: center;
}
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
}
.hero--image::after { background: var(--overlay); }  /* scrim over photos for AA; no scrim on flat navy */
.hero > * { position: relative; z-index: 1; }
/* Fluid, so "affordably and reliably" (held together by non-breaking
   spaces in the headline — see charged_home_defaults()) fits on one line
   at every phone width instead of overflowing. The joined phrase is 381px
   at 32px against 327px of usable width at 375px, so a flat 32px would
   spill 54px past the container.
   6.6vw, not the 7vw first used: `vw` counts the scrollbar but the content
   box does not, so on a desktop window at 375px with classic scrollbars the
   usable width drops to ~312px and 7vw consumed the entire margin. 6.6vw
   leaves ~17px spare in that worst case and still fits every real phone.
   Caps at Annie's 32px from ~485px up; 1024px+ overrides to 40px. */
.hero h1 { font-weight: 600; font-size: clamp(20px, 6.6vw, 32px); line-height: 1.4; color: var(--white); }
.hero__ctas { display: flex; flex-direction: column; gap: 14px; margin-top: 26px; }

.partners {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 22px 30px;
  margin-top: 42px;
}
.partners__item { text-decoration: none; }
.partners__wordmark { color: var(--white); font-weight: 700; letter-spacing: 0.5px; font-size: 22px; line-height: 1.15; }
.partners__logo { max-height: 32px; width: auto; }  /* matches .site-footer__logo (Annie, 2026-07-29) */

.hero__stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 34px;
  margin-top: 26px;
  list-style: none;
}
.hero__stats li { color: var(--white); font-weight: 700; font-size: 15px; letter-spacing: 0.5px; }

/* ---------- Image placeholders (dev fallbacks) ---------- */
.ph { display: flex; align-items: center; justify-content: center; color: var(--white); }
.ph-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  opacity: 0.7;
}
.ph-circle { border-radius: 50%; margin-inline: auto; }

/* ---------- About ---------- */
.about .section-title { margin-bottom: 26px; }
.about__circle {
  width: 210px;
  height: 210px;
  margin-bottom: 28px;
  background: linear-gradient(160deg, #e8a06b, #c77a86 45%, #6a6f9c);
}
.about__image { border-radius: 50%; width: 210px; height: 210px; object-fit: cover; margin: 0 auto 28px; }
.about__body { text-align: left; }
.about__body p { font-size: 18px; line-height: 1.7; margin-bottom: 18px; }
.about__body p:last-child { margin-bottom: 30px; }

/* ---------- Card grids (How CHARGED works / Solutions) ---------- */
.how .section-title,
.solutions .section-title { margin-bottom: 12px; }
.lead { margin-bottom: 30px; }
.lead--on-navy { color: #cdd7e0; }

.card-stack {
  display: flex;
  flex-direction: column;
  gap: 22px;
  text-align: left;
}
.card {
  display: flex;
  flex-direction: column;
  padding: 28px 24px;
  border: 2px solid var(--soft-teal);
  border-radius: var(--radius-card);
}
.card h3 { font-weight: 700; font-size: 24px; line-height: 1.12; color: var(--white); margin-bottom: 14px; }
.card p { font-size: 18px; line-height: 1.65; color: #e4eaef; margin-bottom: 24px; }
.btn--card { align-self: flex-start; padding: 12px 22px; font-size: 13px; margin-top: auto; }
/* Placeholder chip for a card whose destination doesn't exist yet. Muted and
   with no hover state so it reads as "not yet", not as a button someone is
   failing to click. It's a <span>, so there's no focus or cursor state to
   suppress — the muting is purely so it doesn't look interactive. */
.btn--soon { opacity: 0.5; cursor: default; }
.btn--soon:hover { background: none; color: var(--white); }
.solutions__all { margin-top: 34px; }

/* ---------- Who CHARGED is for ---------- */
.who .section-title { margin-bottom: 14px; }
.who__header .lead { margin-bottom: 34px; }
.who__photo {
  width: 190px;
  height: 190px;
  margin: 0 auto 34px;
  border-radius: 50%;
  object-fit: cover;
}
/* Mobile spec: only the first photo shows below tablet */
@media (max-width: 767.98px) {
  .who__media > .who__photo:nth-child(n + 2) { display: none; }
}
.who__list { text-align: left; }
.who__item { padding: 24px 0; border-top: 1px solid var(--divider); }
.who__item h3 { font-weight: 700; font-size: 22px; line-height: 1.15; margin-bottom: 8px; }
.who__item p { font-size: 18px; line-height: 1.65; }

/* ---------- Latest Resources ---------- */
.resources .section-title { margin-bottom: 14px; }
.res-stack {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
/* Carousel controls exist only at tablet+ (mobile keeps the vertical stack) */
.res-carousel__btn,
.res-dots { display: none; }
.res-card {
  aspect-ratio: 4 / 5;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 14px;
  padding: 28px;
  text-align: center;
  text-decoration: none;
  border-radius: var(--radius-card);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  background-size: cover;
  background-position: center;
}
/* .res-card__title removed 2026-07-27: the homepage cards now show the real
   cover art, which already carries the title, so the overlaid white text was
   duplicating it. The title still ships as .screen-reader-text in
   section-resources.php to keep each card link accessibly named. */
.resources__all { margin-top: 32px; }

/* ---------- Testimonials (stands in for Solutions until Phase 2) ---------- */
.testimonials .section-title { margin-bottom: 12px; }
.testi-stack {
  display: flex;
  flex-direction: column;
  gap: 22px;
}
/* Carousel controls exist only at tablet+ (mobile keeps the vertical stack) */
.testi-carousel__btn,
.testi-dots { display: none; }
.testi-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 44px 28px 30px;
  border-radius: var(--radius-card);
  text-align: left;
  overflow: hidden;
}
/* Mobile-first base. The big 28px quote / 55px inset / 550px mark are the
   DESKTOP treatment and live in the 768px block — at 375px the 55px inset
   (on top of the card's own 28px padding) leaves a ~160px text column, so
   28px type wrapped at ~5 characters and ran the card ~900px tall. The
   inset only exists to clear the prev/next arrows, which are display:none
   on mobile, so mobile doesn't need it at all. */
.testi-card__mark {
  position: absolute;
  top: -34px;
  left: 10px;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 200px;
  line-height: 1;
  color: var(--white);
  opacity: 0.1;
  pointer-events: none;
}
.testi-card__quote {
  position: relative;
  font-size: 19px;
  line-height: 1.6;
  color: var(--white);
  max-width: 100%;
  margin-bottom: 22px;
}
/* With no attribution beneath it the quote is the card's last child, and
   that 22px would sit on top of the card's own 30px bottom padding. */
.testi-card__quote:last-child { margin-bottom: 0; }
/* Attribution is a row: circular headshot, then the name/title stack beside
   it. Drops back to text-only automatically when no headshot is set — the
   photo span simply isn't rendered. */
.testi-card__attribution { position: relative; display: flex; flex-direction: row; align-items: center; gap: 14px; }
.testi-card__photo {
  flex: 0 0 auto;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.08);
}
.testi-card__photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Top-weighted, not centred: a square crop of a portrait headshot centres
     on the chest and decapitates the subject. All three supplied photos sit
     face-high, so `top` frames every one of them without per-image cropping. */
  object-position: center top;
}
/* min-width:0 so a long organization name wraps instead of forcing the row wider. */
.testi-card__byline { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.testi-card__name { font-weight: 700; font-size: 15px; font-style: normal; color: var(--white); }
.testi-card__role { font-size: 13px; color: #cdd7e0; }

/* ---------- Get Involved ---------- */
/* Clears the sticky header when the nav's Get Involved link (#get-involved)
   jumps here, so the section heading doesn't land underneath it. */
#get-involved { scroll-margin-top: 120px; }
.get-involved .section-title { font-size: 36px; margin-bottom: 18px; }
.gi__lead { font-size: 18px; line-height: 1.7; margin-bottom: 30px; }

.form { display: flex; flex-direction: column; gap: 18px; }
.form label { display: block; font-weight: 700; font-size: 15px; color: var(--navy); margin-bottom: 7px; }
.form .opt { color: #5f6b76; font-weight: 600; }
.form input,
.form textarea {
  width: 100%;
  border: 1px solid var(--input-border);
  background: var(--white);
  border-radius: 0;
  padding: 12px;
  font-size: 15px;
  font-family: var(--font);
}
.form input { height: 46px; }
.form textarea { resize: vertical; }
.form button[type="submit"] { align-self: flex-start; }

/* WPForms — restyle to match the mockup form (scoped to the section) */
.charged-gi .wpforms-container .wpforms-field { padding: 9px 0; }
.charged-gi .wpforms-container .wpforms-field-label {
  font-weight: 700;
  font-size: 15px;
  color: var(--navy);
  margin-bottom: 7px;
}
.charged-gi .wpforms-container .wpforms-field-sublabel { font-size: 13px; color: #5f6b76; }
.charged-gi .wpforms-container input[type="text"],
.charged-gi .wpforms-container input[type="email"],
.charged-gi .wpforms-container textarea {
  max-width: 100%;
  width: 100%;
  border: 1px solid var(--input-border);
  background: var(--white);
  border-radius: 0;
  padding: 12px;
  height: auto;
  min-height: 46px;
  font-size: 15px;
  font-family: var(--font);
  color: var(--ink);
}
.charged-gi .wpforms-container input:focus,
.charged-gi .wpforms-container textarea:focus {
  outline: 3px solid var(--teal-dark);
  outline-offset: 1px;
  border-color: var(--navy);
  box-shadow: none;
}
.charged-gi .wpforms-container button[type="submit"] {
  display: inline-block;
  font-family: var(--font);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  padding: 14px 30px;
  line-height: 1.6; /* WPForms forces 14px; theme buttons inherit 1.6 — this evens the heights */
  height: auto !important; /* WPForms pins height:41px via --wpforms-button-size-height */
  /* !important: WPForms' modern stylesheet paints the submit filled blue via its
     own CSS vars, out-cascading these — without it the button doesn't match .btn--navy */
  color: var(--navy) !important;
  background: none !important;
  border: 2px solid var(--navy);
  border-radius: var(--radius-button);
  cursor: pointer;
}
.charged-gi .wpforms-container button[type="submit"]:hover {
  background: var(--navy) !important;
  color: var(--white) !important;
}
/* Error/confirmation states: never color-only (a11y) */
.charged-gi .wpforms-container label.wpforms-error {
  display: block;
  margin-top: 6px;
  font-size: 14px;
  font-weight: 600;
  color: #B3261E;
}

/* Per Annie's comp: no required asterisks — optional fields are marked
   "(optional)" instead. Inputs keep required/aria-required, so AT still
   announces requiredness. */
.charged-gi .wpforms-container .wpforms-required-label { display: none; }
.charged-gi .wpforms-container .wpforms-field-label:not(:has(.wpforms-required-label))::after,
.charged-gi .form > div:not(:has([required])) label::after {
  content: " (optional)";
  color: #6b7c8d;
  font-weight: 600;
}
.charged-gi .form .opt { display: none; }  /* fallback form: CSS marker replaces the span */

.charged-gi .wpforms-container textarea,
.charged-gi .form textarea { min-height: 260px; }

/* ============================================================
   About page (flexible-Page block patterns — inc/block-patterns.php)
   Annie's About design (2026-08-03): Mission / Impact / How it works /
   People & Partners. Sections are section.bg-* > .inner, so width and
   container alignment come from the shared section rules.
   ============================================================ */
.about-section .section-title { margin-bottom: 26px; }

/* No measure cap anywhere in About — Kathy (2026-08-03, extended 08-04 to
   the Impact bullets): body copy runs the full container width, flush with
   the Impact stat box's right edge, which is how the comp reads. */
.about-mission p { margin-bottom: 18px; }
.about-mission p:last-child { margin-bottom: 0; }
.about-mission__lead { font-weight: 700; }

/* Impact — photo band. Same layering contract as .page-header__ph:
   __ph is the image layer (flat navy until an image is set), the scrim
   ::after exists on the --image state only, content stacks above. */
.about-impact { position: relative; overflow: hidden; }
.about-impact__ph {
  position: absolute;
  inset: 0;
  background: var(--navy);
  background-size: cover;
  background-position: center;
}
.about-impact__ph--image::after {
  /* Heavier than the page-header scrim: this band holds body text, so it
     carries the contrast for everything on it.
     Lifted 0.85 -> 0.78 -> 0.72 across two rounds of Annie's feedback
     (2026-08-04). ⚠ 0.72 IS THE FLOOR — do not go lower. Measured against
     the worst case, a pure-white photo pixel: white text 6.1:1 (AA needs
     4.5) and the teal stat-box outline 3.2:1 (UI components need 3). The
     OUTLINE is the binding constraint, not the text — it fails at about
     0.69 while the text survives to 0.62, so the stat box would quietly
     stop meeting AA long before anything looked unreadable. To brighten
     further, lighten the source photo instead of thinning this wash, then
     re-run the numbers (scratchpad/contrast.js). */
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 42, 71, 0.72);
}
.about-impact .inner { position: relative; z-index: 1; }

.about-impact__stats {
  display: grid;
  /* 165px, not 140: the labels' line breaks are hardcoded <br>s in page
     content, and the widest resulting line ("ADVANCED ENERGY") needs 159px
     at 15px/700 + 0.8px tracking. A 140px floor let the grid build columns
     too narrow to hold it, so that one label wrapped to 3 lines while its
     neighbours sat at 1-2 — a ragged row inside the teal outline. Measure
     the widest <br>-delimited segment again if the label type changes. */
  grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
  gap: 24px 16px;
  margin: 30px 0;
  padding: 26px 20px;
  border: 3px solid var(--soft-teal);  /* was 1px; +2px per Kathy 2026-08-03 */
  list-style: none;
  text-align: center;
}
.about-impact__num { display: block; font-size: 36px; font-weight: 700; line-height: 1.1; }
.about-impact__label {
  display: block;
  margin-top: 6px;
  font-size: 15px;      /* 13 -> 14 (2026-08-03) -> 15, the site's UI-chrome size */
  font-weight: 700;     /* reverses the 300 "thin" of 2026-08-03, per Kathy 2026-08-05 */
  line-height: 1.3;     /* was inheriting body's 1.7, which read gappy on the
                           two-line labels (Advanced Energy / Companies) */
  letter-spacing: 0.8px;
  text-transform: uppercase;
}
/* No measure cap — the bullets run the full container width, matching the
   stat box's outline directly above them (Kathy, 2026-08-04). */
.about-impact__list { padding-left: 22px; }
.about-impact__list li { margin-bottom: 14px; }
.about-impact__list li:last-child { margin-bottom: 0; }

/* How it works — circle photo with the copy flowing around it at 768px+
   (Kathy 2026-08-03: the text runs straight down and passes under the
   image if it's long enough, rather than sitting in a fixed column).
   The float is contained by .inner below so it can't escape the section.
   Circle shape is CSS over a square image — don't pre-crop circles.
   Mobile keeps it centred and stacked: a floated 300px image at 375px
   would leave a ~40px ribbon of text beside it. */
.about-how .inner { display: flow-root; }
.about-how__circle {
  width: 100%;
  max-width: 300px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 auto 28px;
}
.about-how__text p { margin-bottom: 18px; }
.about-how__text p:last-child { margin-bottom: 0; }
/* 18px, matching the gap between the two paragraphs above it — at 30px it
   read as a double return rather than the next paragraph in the same flow. */
.about-how__closing { margin-top: 18px; }

/* People & Partners */
.about-people__intro { margin-bottom: 34px; }
.about-people h3 { margin-bottom: 20px; }
.about-people__logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 28px 56px;
  margin-bottom: 44px;
}
.about-people__logo { max-height: 56px; width: auto; }
.about-people__committee-intro { margin-bottom: 26px; }
.about-people__list { padding-left: 22px; }
.about-people__list li { margin-bottom: 12px; }
.about-people__list li:last-child { margin-bottom: 0; }
.about-people__list strong { color: var(--navy); }

/* Tablet+: Name|Email and Organization|"I am a…" side by side,
   message + submit full width (Annie's comp) */
@media (min-width: 768px) {
  .charged-gi .wpforms-container .wpforms-field-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: 24px;
  }
  .charged-gi .wpforms-container .wpforms-field-textarea { grid-column: 1 / -1; }

  .charged-gi .form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px 24px;
  }
  .charged-gi .form > div:has(textarea),
  .charged-gi .form > button[type="submit"] { grid-column: 1 / -1; }
  .charged-gi .form > button[type="submit"] { justify-self: start; }
}

/* ---------- Footer ---------- */
.site-footer {
  background: var(--navy);
  padding: 40px 24px 34px;
  text-align: center;
}
.site-footer__partners {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 22px 34px;
  margin-bottom: 30px;
}
.site-footer__partner { text-decoration: none; }
.site-footer__logo { max-height: 32px; width: auto; }
.site-footer__wordmark { color: var(--white); font-weight: 700; letter-spacing: 0.5px; font-size: 18px; }
.site-footer__copyright {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: #6d8296;
}

/* ============================================================
   Page header band (Resources archive/single breadcrumb banner)
   ============================================================ */
.page-header { padding: 38px 24px; text-align: center; }
.page-header--navy { background: var(--navy); color: var(--white); }
.page-header--navy h1 { color: var(--white); font-weight: 300; margin-bottom: 10px; }
/* Fixed-height variant — Resources archive + About hero only (NOT the
   single-resource band, which stays content-driven height). */
.page-header--fixed { height: 300px; display: flex; flex-direction: column; justify-content: center; }
/* Photo variant — full-bleed image behind the title/breadcrumb (About
   hero, Resources archive). Pair with .page-header__ph (the image/
   placeholder layer) and wrap the title/breadcrumb in .page-header__content
   so it stacks above the photo. */
.page-header--photo { position: relative; overflow: hidden; }
.page-header__ph {
  position: absolute;
  inset: 0;
  /* No image set yet: a flat navy band, the same --navy as the footer
     (2026-07-28, Kathy — replaced a teal dev gradient + "Photo placeholder"
     label). This is still the image layer, not a substitute for it: an
     inline background-image overrides only the image part of the shorthand,
     so real photos drop in with no markup change. */
  background: var(--navy);
  background-size: cover;
  background-position: center;
}
.page-header__ph--image::after {
  /* Scrim only over a real photo, so the title stays AA against it. Kept off
     the flat-navy state deliberately — darkening #003A63 by 15–55% would
     stop it matching the footer, which is the point of the placeholder. */
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(18, 45, 60, 0.15), rgba(18, 45, 60, 0.55));
}
.page-header__content { position: relative; z-index: 1; }
/* Single-resource band: same look as the archive h1, but the page's real
   h1 is the resource title below the band, so this is a styled <p>. */
.page-header__title { font-size: 36px; line-height: 1.2; font-weight: 300; color: var(--white); margin-bottom: 10px; }
.breadcrumb { font-size: 14px; }
.breadcrumb a { color: #cdd7e0; text-decoration: underline; }
.breadcrumb a:hover { color: var(--white); }
.breadcrumb span[aria-current] { color: var(--white); font-weight: 600; }

/* ============================================================
   Resource archive — filter sidebar + results list
   Mobile-first: sidebar renders inline (always visible, fully
   functional without JS). resource-filter.js adds .js-ready to
   .resource-archive__inner, which is what makes the collapsible
   drawer behavior below 1024px active — so a no-JS visitor always
   sees a working, uncollapsed filter form.
   ============================================================ */
.resource-archive { padding: 32px 24px 60px; }
.resource-archive__inner { display: flex; flex-direction: column; gap: 32px; }

.resource-filters__toggle {
  display: none;
  align-self: flex-start;
  padding: 10px 22px;
  font-family: var(--font);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--navy);
  background: var(--white);
  border: 2px solid var(--navy);
  border-radius: var(--radius-button);
  cursor: pointer;
}

.resource-sidebar { width: 100%; }

/* Collapsible drawer, JS-only (see block comment above) — a no-JS
   visitor never gets this class added, so the sidebar just stays
   visible in normal flow with no toggle button to fail to operate. */
@media (max-width: 1023.98px) {
  .resource-archive__inner.js-ready .resource-filters__toggle {
    display: inline-flex;
    margin-bottom: 4px;
  }
  .resource-archive__inner.js-ready .resource-sidebar {
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.2s ease;
  }
  .resource-archive__inner.js-ready .resource-sidebar.is-open {
    max-height: none;
    overflow: visible;
    opacity: 1;
    padding-top: 6px;
  }
}

.resource-filters__group {
  margin-bottom: 26px;
  padding: 0;
  border: 0;
}
.resource-filters__label {
  display: block;
  font-weight: 700;
  font-size: 15px;
  color: var(--navy);
  margin-bottom: 10px;
}

/* Each facet (Topic/Type/Audience) is a collapsible accordion, chevron
   flips on toggle. Collapsing is gated behind .js-ready (see comment on
   filter-sidebar.php); without it every panel just renders open with an
   inert (but harmless) toggle button. */
/* padding-top removed (Annie, 2026-07-29): on a fieldset with a real <legend>,
   top padding renders BELOW the legend — it was adding 20px under each facet
   heading, not above it. Removing it makes heading→first-checkbox equal the
   28px box-to-box rhythm; space above headings is unchanged (it comes from
   the previous group's padding-bottom). */
.resource-filters__group--collapsible { padding-top: 0; }
/* Divider between groups, on the <fieldset>'s own bottom edge — NOT on
   .resource-filters__options (border-top on the fieldset itself doesn't
   work either: verified live that a full-width <legend> straddles and
   paints over a fieldset's border-block-start, hiding it). Putting
   padding/border on .resource-filters__options was also wrong: that's
   the element .js-ready collapses via max-height, and box-sizing:
   border-box can't shrink padding+border below their own size, so a
   collapsed group floored out at 21px instead of 0 — clipped content
   still visibly peeking through. The fieldset's own bottom edge isn't
   part of that collapsing box, so it has neither problem. */
.resource-filters__group--collapsible:not(:last-of-type) {
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
.resource-filters__legend {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0 0 14px;
}
.resource-filters__facet-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: 10px;
  padding: 0;
  font-family: var(--font);
  font-weight: 700;
  font-size: 18px;
  color: var(--navy);
  background: none;
  border: 0;
  text-align: left;
}
.js-ready .resource-filters__facet-toggle { cursor: pointer; }
.resource-filters__chevron { flex-shrink: 0; color: var(--navy); transition: transform 0.15s ease; }
.resource-filters__facet-toggle[aria-expanded="true"] .resource-filters__chevron { transform: rotate(180deg); }

.js-ready .resource-filters__options {
  overflow: hidden;
  max-height: 1200px;
  transition: max-height 0.2s ease;
}
.js-ready .resource-filters__group--collapsible.is-collapsed .resource-filters__options {
  max-height: 0;
}

#resource-search {
  width: 100%;
  height: 46px;
  padding: 0 14px;
  font-family: var(--font);
  font-size: 15px;
  border: 1px solid var(--input-border);
  border-radius: 0;
}
#resource-search:focus { outline: 3px solid var(--teal-dark); outline-offset: 1px; }

.resource-filters__checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}
.resource-filters__checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--navy);
}
.resource-filters__checkbox label {
  display: flex;
  flex: 1;
  justify-content: space-between;
  gap: 10px;
  font-size: 15px;
  cursor: pointer;
}
.resource-filters__count { color: var(--slate); font-size: 14px; }

/* min-height + inline-flex, not plain inline-block: this is a standalone
   link (no inline-text exemption) and at 14px/1.6 it was a ~22px tap
   target — under the project's 44px minimum, and it's the only escape
   hatch from a bad filter state on touch. */
.resource-filters__clear,
.event-filters__clear {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: underline;
  color: var(--navy);
}

.resource-results__count {
  font-size: 15px;
  color: var(--slate);
  margin-bottom: 20px;
}
.resource-results__count strong { color: var(--ink); }

.resource-list { display: flex; flex-direction: column; gap: 24px; }
/* Real prose shown in place of results, not UI chrome — tracks body copy. */
.resource-list__empty { font-size: 18px; color: var(--slate); padding: 20px 0; }
.resource-list[aria-busy="true"] { opacity: 0.6; }

.resource-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
}
/* Resource thumbnails are PDF/report COVERS — portrait, US-Letter ratio
   (612x792 = 17/22 = 0.77), not landscape photos. A 16/9 or 4/3 frame
   crops the top and bottom off every one of them. object-fit: contain
   guarantees the whole cover is visible whatever its ratio; the desktop
   frame below is set to 17/22 so the common case fills it exactly with
   no letterboxing at all. If a landscape photo is ever used as a
   thumbnail it will letterbox rather than crop — deliberate, since a
   cropped document cover loses its title. */
.resource-card__media {
  display: block;
  aspect-ratio: 4 / 3;
  background-size: cover;
  background-position: center;
  background-color: var(--gray-light);
}
.resource-card__media img { width: 100%; height: 100%; object-fit: contain; }
.resource-card__body { padding: 20px; }
.resource-card__title { font-size: 20px; margin-bottom: 8px; }
.resource-card__title a { color: var(--navy); text-decoration: none; }
.resource-card__title a:hover { text-decoration: underline; }
.resource-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  font-size: 14px;
  color: var(--slate);
  margin-bottom: 12px;
}
.resource-card__tag {
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--navy);
  background: var(--gray-light);
}
/* 17px, not the 18px body size (Kathy, 2026-08-04): on the Resource
   Library this excerpt is what answers "is this relevant to me", so it's
   reading text rather than card chrome — but it stays one step below body
   copy and well below the 20px card title, keeping the card's own
   hierarchy. resource-filter.js renders the same class, so the live
   filtered results can't drift from the server-rendered ones. */
.resource-card__excerpt { font-size: 17px; line-height: 1.6; margin-bottom: 16px; }
.resource-card__cta { padding: 10px 22px; font-size: 13px; }

/* ============================================================
   Single Resource — layout per Annie's resource-detail mockup
   ============================================================ */
.resource-single__layout { padding: 40px 24px 70px; display: flex; flex-direction: column; gap: 40px; }

.resource-single__header { margin-bottom: 30px; }
.resource-single__title { font-size: 30px; font-weight: 300; margin-bottom: 12px; }
.resource-single__byline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  font-size: 16px;
  font-weight: 600;
  color: var(--slate);
}
.resource-single__byline a { color: var(--slate); }
.resource-single__byline a:hover { color: var(--teal-dark); }

/* Cover + summary intro: stacked on mobile, two-col ≥768px */
.resource-single__intro { display: flex; flex-direction: column; gap: 28px; margin-bottom: 36px; }
.resource-single__cover img { width: 100%; height: auto; }
.resource-single__cover-placeholder { width: 100%; aspect-ratio: 4 / 5; }
/* One step above body copy — raised with it (18px body) so the summary
   still reads as a lead rather than matching the prose below it. */
.resource-single__summary { font-size: 19px; line-height: 1.7; color: var(--ink); margin-bottom: 26px; }
.resource-single__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

.resource-single__content { padding-top: 32px; border-top: 1px solid var(--divider); margin-bottom: 36px; }
.resource-single__content :is(h2, h3) { margin-top: 1.4em; margin-bottom: 0.5em; }
.resource-single__content p { margin-bottom: 1em; line-height: 1.6; }
/* Global reset zeroes list padding — restore the indent for body-copy lists */
.resource-single__content :is(ul, ol) { padding-left: 1.5em; margin-bottom: 1em; }
.resource-single__content li { margin-bottom: 0.5em; line-height: 1.6; }

.resource-single__section-heading { font-size: 18px; margin-bottom: 10px; }

/* Citation lives in the right sidebar (Kathy's call over the mockup's
   inline placement) — the permalink URL must wrap in the narrow column. */
.resource-single__citation-text {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink);
  margin-bottom: 14px;
  overflow-wrap: anywhere;
}
.resource-single__citation-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.resource-single__copy {
  padding: 8px 18px;
  font-family: var(--font);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--navy);
  background: var(--white);
  border: 2px solid var(--navy);
  border-radius: var(--radius-button);
  cursor: pointer;
}
.resource-single__copy-status { font-size: 13px; color: var(--teal-dark); font-weight: 600; }

/* Related resources: bordered box with topic eyebrow (mockup) */
.resource-single__related { border: 1px solid var(--divider); padding: 26px 24px; }
.resource-single__related-eyebrow {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 2px;
}
.resource-single__related-heading { font-size: 26px; font-weight: 400; margin-bottom: 22px; }
.resource-single__related-list { list-style: none; display: grid; gap: 22px; }
.resource-single__related-item { border-left: 2px solid var(--divider); padding-left: 16px; }
.resource-single__related-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 6px;
}
/* Raised with body copy — at 17px this title rendered smaller than the
   prose around it once body went to 18px. */
.resource-single__related-title { font-size: 19px; font-weight: 600; line-height: 1.35; }
.resource-single__related-title a { color: var(--navy); text-decoration: none; }
.resource-single__related-title a:hover { text-decoration: underline; }

/* Sidebar: share (moved from the mockup's inline section) + audience */
.resource-single__sidebar { display: flex; flex-direction: column; gap: 32px; }
.resource-single__share-blurb { font-size: 15px; margin-bottom: 14px; }
.resource-single__share .resource-single__copy { display: inline-block; text-decoration: none; }
.resource-single__share .resource-single__copy-status { display: block; margin-top: 8px; }
.resource-single__audience ul { list-style: none; font-size: 15px; }
.resource-single__audience li { padding: 6px 0; border-bottom: 1px solid var(--border); }

/* ============================================================
   Event archive + single (archive-event.php, single-event.php,
   template-parts/event/*)
   Mobile-first: sidebar/results stack, card grid 1-up, meta bar wraps.

   The sidebar (search field + accordion facet) mirrors
   template-parts/resource/filter-sidebar.php rather than sharing a
   component, to avoid destabilising the already-verified Resources
   filter. It is a CLOSE copy, not identical — the deliberate deltas:
     - Events has one facet, Resources has three (so the
       :not(:last-of-type) divider rule below never matches today; it's
       kept so a second facet works without a CSS change).
     - Events adds a sort control and a search submit button.
     - Events auto-submits on change (full reload); Resources
       re-renders over REST.
   `.event-filters__clear` intentionally shares the Resources rule.

   Divider lives on the <fieldset>'s own bottom edge — not a border-top
   there (a full-width <legend> straddles and hides a fieldset's
   border-top) and not on .event-filters__options (that's the element JS
   collapses via max-height, and box-sizing:border-box can't shrink
   padding+border below their own size, so a "collapsed" panel would
   floor out non-zero with clipped content still peeking through).
   ============================================================ */
.event-archive { padding: 32px 24px 60px; }
.event-archive__inner { display: flex; flex-direction: column; gap: 32px; }
.event-sidebar { width: 100%; }

/* Sidebar/form structure and typography deliberately match
   .resource-filters__* exactly (same rules, .event- prefix) — see
   template-parts/event/filter-sidebar.php. */
.event-filters__group { margin-bottom: 26px; padding: 0; border: 0; }
.event-filters__label { display: block; font-weight: 700; font-size: 15px; color: var(--navy); margin-bottom: 10px; }
.event-filters__search { display: flex; }
#event-search {
  flex: 1;
  min-width: 0;
  height: 46px;
  padding: 0 14px;
  font-family: var(--font);
  font-size: 15px;
  border: 1px solid var(--input-border);
  border-right: 0;
  border-radius: 0;
}
#event-search:focus { outline: 3px solid var(--teal-dark); outline-offset: 1px; }
.event-filters__search-btn {
  flex-shrink: 0;
  width: 46px;   /* 46px square keeps the tap target at the 44px minimum */
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--white);
  background: var(--navy);
  border: 1px solid var(--navy);
  border-radius: 0;
  cursor: pointer;
}
.event-filters__search-btn:hover { background: var(--nav-active); }

.event-filters__group--collapsible { padding-top: 0; } /* mirrors .resource-filters fix — see comment there */
.event-filters__group--collapsible:not(:last-of-type) {
  padding-bottom: 20px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.3);
}
.event-filters__legend { display: block; width: 100%; padding: 0; margin: 0 0 14px; }
.event-filters__facet-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: 10px;
  padding: 0;
  font-family: var(--font);
  font-weight: 700;
  font-size: 18px;
  color: var(--navy);
  background: none;
  border: 0;
  text-align: left;
}
.js-ready .event-filters__facet-toggle { cursor: pointer; }
.event-filters__chevron { flex-shrink: 0; color: var(--navy); transition: transform 0.15s ease; }
.event-filters__facet-toggle[aria-expanded="true"] .event-filters__chevron { transform: rotate(180deg); }
.js-ready .event-filters__options { overflow: hidden; max-height: 1200px; transition: max-height 0.2s ease; }
.js-ready .event-filters__group--collapsible.is-collapsed .event-filters__options { max-height: 0; }
.event-filters__checkbox { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.event-filters__checkbox input[type="checkbox"] { width: 20px; height: 20px; flex-shrink: 0; accent-color: var(--navy); }
.event-filters__checkbox label { display: flex; flex: 1; justify-content: space-between; gap: 10px; font-size: 15px; cursor: pointer; }
.event-filters__count { color: var(--slate); font-size: 14px; }
/* .event-filters__clear is styled with .resource-filters__clear above —
   identical treatment, so it shares the rule rather than duplicating it. */

/* Results column: count + sort bar (no equivalent on Resources, so this
   one control stays without a Resources-side pattern to mirror). */
.event-results__bar { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 18px; }
.event-results__count { font-size: 14px; color: var(--slate); }
.event-results__sort {
  height: 40px;
  padding: 0 12px;
  font-family: var(--font);
  font-size: 14px;
  color: var(--navy);
  border: 1px solid var(--input-border);
  border-radius: 0;
  background: var(--white);
}

.event-grid { display: grid; grid-template-columns: 1fr; gap: 28px; }
.event-grid__empty { color: var(--slate); }

.event-card { display: block; text-decoration: none; color: inherit; }
/* Badges are siblings of the thumbnail link (not children — see
   event-card.php), so the wrapper is what they position against. */
.event-card__media-wrap { position: relative; }
.event-card__media {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-card);
  overflow: hidden;
  background-size: cover;
  background-position: center;
  text-decoration: none;
}
.event-card__media img { width: 100%; height: 100%; object-fit: cover; }
.event-card__badges { position: absolute; top: 14px; left: 14px; display: flex; gap: 8px; }
.event-card__badge {
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--navy);
  background: var(--gray-light);
  border-radius: 3px;
}
.event-card__badge--type { color: var(--navy); background: var(--soft-teal); }
.event-card__body { padding-top: 18px; }
.event-card__title { font-weight: 700; font-size: 20px; line-height: 1.3; margin-bottom: 8px; }
.event-card__title a { color: var(--navy); text-decoration: none; }
.event-card__title a:hover { text-decoration: underline; }
.event-card__date { display: block; font-size: 14px; color: var(--slate); }

/* "Coming soon" placeholder card (archive-event.php renders it only while
   no events are published). Muted so it reads as "not yet" rather than as
   something the visitor is failing to click — and it genuinely isn't
   clickable: the markup has no <a> at all, so there's no focus or cursor
   state to suppress, same call as .btn--soon on the homepage. Left at one
   column so a single placeholder doesn't stretch across the full grid. */
/* Double class, not `.event-grid--soon` alone: the 768px and 1024px blocks
   set .event-grid to 2- and 3-up LATER in this file, so at equal
   specificity they'd win and the single placeholder would be squeezed into
   a third of the row. Same cascade trap the event rules hit in July. */
.event-grid.event-grid--soon { grid-template-columns: 1fr; max-width: 420px; }
.event-card--soon .event-card__media--soon {
  aspect-ratio: 4 / 3;
  background: var(--gray-light);
  border: 1px dashed #c9d2da;
  border-radius: var(--radius-card);
}
.event-card--soon .event-card__title { color: var(--slate); font-weight: 600; }

/* ---------- Single event ---------- */
/* .event-hero reuses .page-header/.page-header--navy (same classes as
   the Resources archive/single band and the About hero) rather than its
   own box model — this is what makes the horizontal margins/padding
   match those pages automatically (including the 1024px/1280px
   step-ups below), and page-header--navy h1 is already font-weight:300,
   which is the "light, not bold" heading weight requested. Only the
   eyebrow badge and title's own size/measure are custom here. */
.event-hero__eyebrow {
  display: inline-block;
  margin-bottom: 16px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--navy);
  background: var(--white);
  border-radius: 3px;
}
.event-hero__title { font-size: 32px; line-height: 1.25; max-width: 46ch; margin-inline: auto; }

.event-meta { background: var(--gray-light); padding: 24px; }
.event-meta__inner { display: flex; flex-direction: column; gap: 18px; }
.event-meta__details { display: flex; flex-direction: column; gap: 12px; }
.event-meta__item { display: flex; align-items: center; gap: 10px; font-size: 15px; color: var(--navy); }
.event-meta__item svg { flex-shrink: 0; color: var(--teal-dark); }
.event-meta__register { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; }

/* .event-single-body: same mechanism as .resource-single__layout — own
   padding at each breakpoint, landing on the exact same logo-aligned
   formula at 1280px+ (see that breakpoint block) — not the 800px
   block-editor "constrained layout" column (that was the About bug). */
.event-single-body { padding: 40px 24px 70px; }
.event-single__content :is(h2, h3) { margin-top: 1.4em; margin-bottom: 0.5em; }
.event-single__content p { margin-bottom: 1em; line-height: 1.6; }
.event-single__content :is(ul, ol) { padding-left: 1.5em; margin-bottom: 1em; }
.event-single__content li { margin-bottom: 0.5em; line-height: 1.6; }

/* ============================================================
   Breakpoints — layer desktop up (handoff §7)
   ============================================================ */

@media (min-width: 768px) {
  /* tablet: 2-up card grids */
  .card-stack { flex-direction: row; flex-wrap: wrap; }
  .card { flex: 1 1 calc(50% - 11px); }

  /* Event grid: 2-up at tablet (3-up lands at 1024px alongside the
     sidebar going side-by-side — see the 1024px block).
     NOTE: these three MUST live in this 768px block, not the earlier one
     at line ~546 — the .event-* base rules are declared after that block,
     so at equal specificity they'd win and these would silently no-op. */
  .event-grid { grid-template-columns: 1fr 1fr; }

  /* Event meta bar: details left, Register button right */
  .event-meta__inner { flex-direction: row; align-items: center; justify-content: space-between; }
  .event-meta__details { flex-direction: row; gap: 28px; }

  /* Testimonials desktop treatment (see the base rules' note): large
     quote, and the 55px inset that clears the carousel arrows, which
     only exist at this breakpoint and up. */
  .testi-card__mark { top: -82px; left: 18px; font-size: 550px; }
  /* 1.6, not 1.75: at 28px the looser value gave 49px leading, which read as
     gappy on a 3-4 line quote and matches the mobile base (also 1.6). */
  .testi-card__quote { font-size: 28px; line-height: 1.6; padding-inline: 55px; }
  .testi-card__attribution { padding-inline: 55px; gap: 18px; }
  .testi-card__photo { width: 76px; height: 76px; }

  /* About: image left, heading + text + CTA right (tablet and up).
     DOM order (h2, media, body, btn) is preserved for mobile stacking;
     the grid re-places it. */
  .about .inner {
    display: grid;
    grid-template-columns: minmax(220px, 300px) 1fr;
    gap: 18px 64px;
    align-items: center;
    text-align: left;
  }
  .about .inner > .section-title { grid-column: 2; text-align: left; }
  .about__media { grid-column: 1; grid-row: 1 / span 3; }
  .about__circle,
  .about__image { width: 100%; max-width: 300px; height: auto; aspect-ratio: 1 / 1; margin: 0; }
  .about__body { grid-column: 2; }
  .about__body p:last-child { margin-bottom: 12px; }
  .about .inner > .btn { grid-column: 2; justify-self: start; }

  /* About page: How-it-works circle left / copy right; Steering
     Committee intro left / member list right. NOTE: these must stay in
     this later 768px block — the about-* base rules are declared above
     it, so an earlier block would lose the cascade at equal specificity. */
  /* Float, not a grid: the copy wraps beside the circle and keeps running
     underneath it once it clears the bottom. Same image size and gutter
     as the homepage About section (.about__image), per Kathy. The closing
     paragraph deliberately does NOT clear — it's part of the same flow. */
  .about-how__circle { float: left; margin: 0 64px 24px 0; }
  /* Even halves of the section width, not a narrow label column: the
     "CHARGED Steering Committee" heading and copy take one half, the
     member list the other (Kathy, 2026-08-04). The People & Partners
     intro above spans the full width, so these read as half of that. */
  .about-people__committee {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px 64px;
    align-items: start;
  }
  .about-people__committee-intro { margin-bottom: 0; }

  /* Who CHARGED is for: narrower inset container (comp uses ~1040px,
     not the full 1280px container other sections use) */
  .who .inner { max-width: 1040px; margin-inline: auto; }

  /* 3-image column left, role list right. Grid's default align-items:
     stretch makes .who__media exactly as tall as the text column
     (the taller of the two); the media column then uses flex
     space-between so the photos' top/bottom flush with the first/last
     list item and any extra height becomes gap between photos, instead
     of the photos overshooting past the last item (comp behavior).
     Photo max-width must stay well under (text height / 3), or the
     photos become the row's height driver instead of the text — with
     our built copy that's ~630px / 3, so photos are capped at 180px,
     not the ~360px first tried, which stacked with zero gap and forced
     the whole row to 1080px. */
  .who__grid {
    display: grid;
    grid-template-columns: minmax(150px, 200px) 1fr;
    gap: 24px 64px;
    text-align: left;
  }
  .who__media {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
  }
  .who__photo {
    width: 100%;
    max-width: 180px;
    height: auto;
    aspect-ratio: 1 / 1;
    margin: 0;
    flex-shrink: 0;
  }
  .who__item:first-child { border-top: 0; padding-top: 0; }

  /* Latest Resources: scroll-snap carousel with arrows + dot pager */
  .res-carousel { position: relative; }
  .res-track {
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none;
  }
  .res-track::-webkit-scrollbar { display: none; }
  .res-card { flex: 0 0 calc(50% - 11px); scroll-snap-align: start; }

  .res-carousel__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--white);
    color: var(--navy);
    border: 2px solid var(--navy);
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  }
  .res-carousel__btn:hover { background: var(--navy); color: var(--white); }
  .res-carousel__btn[disabled] { opacity: 0.35; cursor: default; }
  .res-carousel__btn[disabled]:hover { background: var(--white); color: var(--navy); }
  .res-carousel__btn--prev { left: -14px; }
  .res-carousel__btn--next { right: -14px; }

  .res-dots {
    display: flex;
    justify-content: center;
    gap: 4px;
    margin-top: 22px;
  }
  .res-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
  }
  .res-dot span { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--navy); }
  .res-dot[aria-current="true"] span { background: var(--navy); }

  /* Testimonials: same carousel pattern as Latest Resources (and the same
     shared initCardCarousel() in main.js), differing only in one card per
     slide instead of 2/3-up, and white dot styling to read on the navy
     band. The prev/next buttons are identical to .res-carousel__btn. */
  .testi-carousel { position: relative; }
  .testi-track {
    flex-direction: row;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scrollbar-width: none;
  }
  .testi-track::-webkit-scrollbar { display: none; }
  .testi-card { flex: 0 0 100%; scroll-snap-align: start; }

  .testi-carousel__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--white);
    color: var(--navy);
    border: 2px solid var(--navy);
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  }
  .testi-carousel__btn:hover { background: var(--navy); color: var(--white); }
  .testi-carousel__btn[disabled] { opacity: 0.35; cursor: default; }
  .testi-carousel__btn[disabled]:hover { background: var(--white); color: var(--navy); }
  .testi-carousel__btn--prev { left: -14px; }
  .testi-carousel__btn--next { right: -14px; }

  .testi-dots {
    display: flex;
    justify-content: center;
    gap: 4px;
    margin-top: 22px;
  }
  .testi-dot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
  }
  .testi-dot span { width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--white); }
  .testi-dot[aria-current="true"] span { background: var(--white); }

  /* Resource card: thumbnail left, body right (tablet and up) */
  .resource-card { flex-direction: row; }
  /* 17/22 = the US-Letter cover ratio, so covers fill the frame exactly.
     Widened 220 -> 260px; height follows the ratio (~336px). */
  .resource-card__media { flex: 0 0 260px; aspect-ratio: 17 / 22; align-self: flex-start; }
  .resource-card__body { flex: 1; }

  /* Single resource: two-column (main content + share/audience sidebar) */
  .resource-single__layout { flex-direction: row; align-items: flex-start; gap: 56px; }
  .resource-single__main { flex: 1; min-width: 0; }
  .resource-single__sidebar { flex: 0 0 260px; }

  /* Intro: cover left, summary + buttons right (mockup) */
  .resource-single__intro { flex-direction: row; }
  .resource-single__cover { flex: 0 0 280px; }
  .resource-single__intro-text { flex: 1; min-width: 0; }

  /* Related resources box: two entries per row (mockup) */
  .resource-single__related-list { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1024px) {
  section { padding: 72px 40px; }
  .site-header { padding: 16px 40px; }

  /* Resource pages: match .site-header's own horizontal padding exactly
     (not the generic `section` rule above — page-header/resource-archive/
     resource-single__layout all have their own more specific padding
     rules that would otherwise keep winning), so the sidebar/header/
     content left edge lines up with the logo. */
  .page-header,
  .resource-archive,
  .resource-single__layout,
  .event-archive,
  .event-single-body,
  .event-meta { padding-left: 40px; padding-right: 40px; }

  /* Resource archive: sidebar + results side by side; below this,
     resource-filter.js's .js-ready class (added on script init) turns
     the sidebar into a collapsible drawer — no-JS visitors never lose
     access to it, since without .js-ready it just stays in normal flow. */
  .resource-archive__inner { flex-direction: row; align-items: flex-start; gap: 48px; }
  .resource-sidebar { flex: 0 0 260px; }
  .resource-results { flex: 1; min-width: 0; }
  .resource-filters__toggle { display: none !important; }

  /* Event archive: same sidebar + results layout as Resources; 3-up grid */
  .event-archive__inner { flex-direction: row; align-items: flex-start; gap: 48px; }
  .event-sidebar { flex: 0 0 260px; }
  .event-results { flex: 1; min-width: 0; }
  .event-grid { grid-template-columns: repeat(3, 1fr); }

  .hamburger { display: none; }
  .site-nav--desktop { display: flex; align-items: center; gap: 32px; }

  h2.section-title { font-size: 36px; }

  /* Hero: text-left block, CTA row */
  .hero { padding: 88px 40px 64px; }
  /* 620px, not 720px, is what puts "system" on the second line and gives
     the three-line break Kathy wanted (2026-08-04):
         Preparing the distribution
         system for electrification —
         affordably and reliably.
     Measured at this 40px size, the window that produces it is 553-679px:
     below 553 the second line can't hold "system for electrification —",
     at 680 or above "system" climbs back onto the first line. Binding that
     phrase with non-breaking spaces instead would overflow mobile, where
     it needs 359px against 327px of room — hence a width, not a join. */
  .hero h1 { font-size: 40px; max-width: 620px; }
  .hero__ctas { flex-direction: row; }
  .partners { margin-top: 56px; }  /* stays centered — full-width band under the hero text */

  /* About: larger image column on desktop */
  .about .inner { grid-template-columns: minmax(260px, 380px) 1fr; gap: 18px 90px; }
  .about__circle,
  .about__image { max-width: 380px; }

  /* How CHARGED works / Solutions: single row (3-up) or 2×2 */
  .how .card-stack { flex-wrap: nowrap; }
  .how .card { flex: 1; }
  .solutions .card { flex: 1 1 calc(50% - 11px); }

  /* Who CHARGED is for: comp doesn't grow the photos at desktop —
     same ~180px column, just wider gutters to match the section's
     gap scale at this breakpoint. */
  .who__grid { grid-template-columns: minmax(150px, 200px) 1fr; gap: 24px 90px; }

  /* About page: same image size and gutter as the homepage About circle.
     Body copy stays on the site's shared scale — a 22px About-only size
     was tried on 2026-08-03 to reproduce the comp's line wraps and
     reverted the same day; the comp reads larger only because Annie's
     content column is narrower than our container. */
  .about-how__circle { max-width: 380px; margin-right: 90px; }
  .about-people__committee { gap: 24px 90px; }

  /* Latest Resources: 3-up per carousel page */
  .res-card { flex-basis: calc((100% - 44px) / 3); }

  /* Get Involved: intro-left + form-right */
  .get-involved .inner { display: flex; gap: 64px; }
  .gi__intro { flex: 0 0 40%; }
  .gi__form { flex: 1; }
}

@media (min-width: 1280px) {
  .site-header { padding-inline: max(40px, calc((100% - var(--container)) / 2)); }
  section > .inner { max-width: var(--container); margin-inline: auto; }

  /* Same formula as .site-header, same reasoning as the 1024px block above. */
  .page-header,
  .resource-archive,
  .resource-single__layout,
  .event-archive,
  .event-single-body,
  .event-meta { padding-inline: max(40px, calc((100% - var(--container)) / 2)); }
}

/* Respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .mobile-menu { transition: none; }
  .res-track,
  .testi-track { scroll-behavior: auto; }
  /* Accordion open/close + chevron spin are motion too. */
  .resource-filters__options,
  .event-filters__options,
  .resource-filters__chevron,
  .event-filters__chevron { transition: none; }
}
