/*
  Base layer: reset, the snap container, buttons, and shared content styles.
  Values come from tokens only.
*/

/*
  Everything here is scoped to .edo-overlay.

  Inside a WordPress theme our class names are not alone: WordPress puts `page`
  on the <body>, and bare `img` or `a` rules would restyle the client's entire
  site. The root class keeps us to ourselves, and as a bonus lifts specificity
  above the theme's single-element rules.
*/

.edo-overlay *, .edo-overlay *::before, .edo-overlay *::after { box-sizing: border-box; }

.edo-overlay {
  margin: 0;
  font-family: var(--font-body);
  font-weight: var(--weight-body);
  font-size: var(--size-body);
  line-height: var(--leading-body);
  color: var(--color-ink);
  background: var(--color-surface);
}

.edo-overlay img { max-width: 100%; display: block; }

.edo-overlay a { color: inherit; }

.edo-overlay :where(a, button, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 3px;
}

.edo-overlay .visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.edo-overlay .skip-link {
  position: absolute;
  left: var(--space-sm);
  top: -100%;
  z-index: 10;
  padding: var(--space-xs) var(--space-md);
  background: var(--color-surface);
  color: var(--color-ink);
  border-radius: var(--radius-sm);
}
.edo-overlay .skip-link:focus { top: var(--space-sm); }

/*
  The snap container.

  `proximity` rather than `mandatory` on purpose. Mandatory fights the user on
  any section taller than the viewport and on mobile where browser chrome
  resizes the viewport mid-scroll. Proximity still lands cleanly on each slide
  and stops short of trapping anyone.

  Snapping is also disabled outright for reduced-motion and for short
  viewports (landscape phones), where forced full-height slides are hostile.
*/
.edo-overlay.edo-page {
  scroll-snap-type: y proximity;
  overflow-y: auto;
  /* The parent page uses 100svh. Unlike dvh it does not change as mobile
     browser chrome hides, so sections stop resizing mid-scroll. */
  height: 100svh;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  .edo-overlay.edo-page { scroll-snap-type: none; scroll-behavior: auto; }
}

@media (max-height: 480px) {
  .edo-overlay.edo-page { scroll-snap-type: none; }
}

.edo-overlay .block {
  position: relative;
  display: flex;
  align-items: center;
  padding: var(--space-2xl) var(--gutter);
  scroll-margin-top: 0;
}

/* Full-viewport slides snap. Anything taller opts out so it can scroll. */
.edo-overlay .block.is-snap {
  min-height: 100svh;
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}

/*
  Free-scrolling sections still fill the screen.

  Jonah, 2026-08-28: every section should be at least a viewport tall. These
  opt out of *snapping* because they can outgrow the screen (the FAQ, the event
  map), not out of filling it, and `min-height` lets them do both.

  The partner strip is the deliberate exception below: it is a band that rides
  under the slide above it, not a slide.
*/
.edo-overlay .block.is-freescroll {
  scroll-snap-align: none;
  min-height: 100svh;
}

/*
  The quote slide and the partner strip share one screen.

  The strip is not a section in its own right on the parent, it sits at the
  foot of the slide above. Full height on both pushed it off the bottom, so the
  slide gives up exactly the strip's height. :has() is what lets the pair
  arrange themselves without a wrapper element or a class in the data.
*/
.edo-overlay .block--carousel.is-logos {
  --partner-band-h: 100px;
  min-height: var(--partner-band-h);
}

.edo-overlay .block.is-snap:has(+ .block--carousel.is-logos) {
  min-height: calc(100svh - 100px);
}

@media (max-width: 900px) {
  .edo-overlay .block--carousel.is-logos { --partner-band-h: 132px; }
  .edo-overlay .block.is-snap:has(+ .block--carousel.is-logos) {
    min-height: calc(100svh - 132px);
  }
}

/* ---------- Flow pages ---------- */

/*
  Not every page is a deck.

  The campaign page is a deck: one idea per screen, full-viewport slides that
  snap. The Earth Hub and its sub-pages are ordinary pages, and measuring the
  parent on 2026-09-06 says so plainly -- at 1440x900 prod earth-hub is 3345px
  of document for seven sections: 260px of hero, then card rows of about 386px
  with 40px of padding under each. Ours was 900px a section, 6300px of page.

  Full height is also what caused the overlapping button. A .block centres its
  content, and a centred flex child that is TALLER than its box overflows
  equally out of both ends -- so on a short viewport the card grid escaped its
  own section and landed on top of the one below. Sizing to content cannot
  overlap, because there is nothing to overflow.

  The scroller stays: .edo-page keeps its own height and overflow, because the
  header's docking watches it rather than the window. Only the snapping and the
  viewport heights go.
*/
.edo-page.is-flow { scroll-snap-type: none; }

/*
  Section padding is --space-2xl, which is what the base .block already uses
  and what the scale was built for. This rule used to knock it down to
  --space-xl on flow pages, which put 96px between two white card rows that
  have no other separation from each other -- so five rows read as one wall.
  Steve, 2026-09-09: "it's all a bit too close together."
*/
.edo-page.is-flow .block,
.edo-page.is-flow .block.is-snap,
.edo-page.is-flow .block.is-freescroll {
  min-height: 0;
  align-items: flex-start;
  scroll-snap-align: none;
  padding-block: var(--space-2xl);
}

/*
  The hero still needs to read as a hero: the photograph wants room, and the
  page should not open on a thin strip. A floor rather than a fixed height, so
  a long heading pushes it taller instead of overflowing. The parent's is 260px
  at 900px tall, which is where the clamp comes from.
*/
.edo-page.is-flow .block--hero {
  min-height: clamp(240px, 30svh, 360px);
  align-items: center;
}

/*
  ...unless the section asks for the whole screen.

  A campaign page opens on one hero that should fill the viewport the way the
  parent's does, while every section under it is content-height. Before this,
  getting that hero meant making the whole page a deck, which put a screen of
  empty space under every short section -- Steve, 2026-09-28, on the 2027 page:
  "a little bit too much whitespace between the sections". Opt-in via `full` in
  the fixture, so no existing page moves.
*/
.edo-page.is-flow .block.is-full {
  min-height: 100svh;
  align-items: center;
}

/*
  The header is fixed over the page, and a flow hero is no longer tall enough
  for its centred content to clear it on its own. A deck slide never had this
  problem: at 100svh the middle of the section is nowhere near the bar.
*/
.edo-page.is-flow > .block:first-child {
  padding-top: calc(var(--header-h) + var(--header-peek) + var(--space-lg));
}

/*
  The header cluster needs more air on a flow page than on a deck slide.

  Measured 2026-09-09: eyebrow to heading was 8px and heading to cards 20px --
  against a heading that runs to three lines of the display face. On a deck
  those values are fine, because the section is a whole viewport and the air is
  all around the cluster. On a flow page the internal rhythm is the ONLY thing
  separating a label from its heading from its content, so it has to do more
  work. One step up the same scale, not new numbers.
*/
.edo-page.is-flow .block__eyebrow { margin-bottom: var(--space-sm); }
.edo-page.is-flow .block__heading { margin-bottom: var(--space-lg); }
.edo-page.is-flow .block__body { margin-bottom: var(--space-xl); }

/*
  The button under a card grid belongs to the grid above it, not to the section
  below. Pushing it away from the cards while the section padding grew would
  have left it floating between the two.
*/
.edo-page.is-flow .block__actions { margin-top: var(--space-lg); }

/* Section-nav is a strip on this page, not a slide. */
.edo-page.is-flow .block--section-nav { padding-block: var(--space-lg); }

.edo-overlay .block__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
}

/* Content order and rhythm: header, body copy, buttons. */
.edo-overlay .block__heading {
  color: inherit;
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--size-h2);
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-md);
  text-wrap: balance;
}

.edo-overlay .block__body {
  color: inherit;
  margin: 0 0 var(--space-lg);
  max-width: var(--container-narrow);
  font-size: var(--size-body);
}

/*
  A centred block has to centre the COLUMN, not only the text in it.

  `.block__body` is capped at 780px so a paragraph keeps a readable measure.
  Flush left that is right, and on a left-aligned hero it is what you want. But
  on the hub's nav row the inner is centred, so the text was centring inside a
  780px box that was itself pinned to the left of a 1200px container -- the
  paragraph sat 210px left of the middle while the chips under it were dead
  centre. It reads as a mistake because it is one.
*/
.edo-overlay .block--section-nav .block__body,
.edo-overlay .block--quote .block__body,
.edo-overlay .block.is-align-center .block__body {
  margin-inline: auto;
}

.edo-overlay .block__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin: 0;
}

/*
  Buttons.

  Jonah, 2026-08-27, two rules:

    1. Colour is the button's identity, not its state. Hover grows the button
       instead of recolouring it, so a row of buttons never changes palette
       under the cursor.

    2. Orange is the Donate colour and nothing else. Everything else is navy
       with white type. `primary` is therefore the navy one, because the
       general case should be what an editor gets by default, and `donate` is
       the exception that has to be chosen deliberately.

  The outline button still has to work on both light sections and dark heroes,
  so its colours are variables the dark blocks override rather than one fixed
  pair that is only legible half the time.
*/

.edo-overlay .btn {
  display: inline-block;
  /* Jonah, 2026-08-28: everything a step larger, matching the live site. */
  padding: 0.9rem 2rem;
  border-radius: var(--radius-pill);
  border: var(--border-width) solid transparent;
  font-family: var(--font-body);
  font-weight: var(--weight-display);
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transform-origin: center;
  transition: transform var(--motion-fast) var(--easing);
}

/*
  The growth. transform rather than padding or font-size so it cannot reflow
  the row it sits in, and scoped to devices with a real pointer: on touch there
  is no hover, and the sticky :hover some mobile browsers apply after a tap
  would leave a button stuck at 105%.
*/
@media (hover: hover) {
  .edo-overlay .btn:hover { transform: scale(1.06); }
}
.edo-overlay .btn:focus-visible { transform: scale(1.06); }

/*
  Except where a button is really a full-width link row -- the closing
  panel's GIVE / SIGN UP lines. 6% of a 600px row is 36px, and the row burst
  out of its panel on hover (Steve, 2026-10-11). Those signal hover by colour.
*/
.edo-overlay .block--cta-band:has(.block__social) .block__panel .btn:hover,
.edo-overlay .block--cta-band:has(.block__social) .block__panel .btn:focus-visible { transform: none; }

/* Growing is motion. Someone who asked for less of it gets none. */
@media (prefers-reduced-motion: reduce) {
  .edo-overlay .btn:hover,
  .edo-overlay .btn:focus-visible { transform: none; }
}

/* The default. Navy with white type. */
.edo-overlay .btn--primary,
.edo-overlay .btn--secondary {
  background: var(--color-ink);
  border-color: var(--color-ink);
  color: #ffffff;
}

/* Donate, and only Donate. Orange, everywhere it appears, including the header. */
.edo-overlay .btn--donate {
  background: var(--color-accent-alt);
  border-color: var(--color-accent-alt);
  color: #ffffff;
}

/*
  White. For a filled button that has to sit on a busy or light photograph
  where navy would not separate -- the partner strip and the quote slide.
*/
.edo-overlay .btn--white {
  background: #ffffff;
  border-color: #ffffff;
  color: var(--color-ink);
}

/*
  Outline. Defaults suit a light section; hero and cta-band override the pair.
*/
.edo-overlay .btn--outline {
  --btn-outline-ink: var(--color-ink);

  background: transparent;
  border-color: var(--btn-outline-ink);
  color: var(--btn-outline-ink);
}

.edo-overlay .btn--text {
  padding-inline: 0;
  border-radius: 0;
  border: 0;
  border-bottom: var(--border-width) solid currentColor;
  background: none;
  color: var(--color-accent-alt);
}
.edo-overlay .btn--text:hover,
.edo-overlay .btn--text:focus-visible { color: var(--color-ink); }

/*
  Escape hatch for a section that is marked snap but has outgrown the viewport
  at the current size. JS adds this class, because whether a section overflows
  depends on rendered text and screen size, not on anything we can know in the
  data. Without it the user can never reach the bottom of that section.
*/
/*
  Only the snapping is released, not the height.

  This used to drop min-height to auto as well, which collapsed the section to
  its content. That fought Jonah's "every section is a full viewport" (a stale
  measurement left sections at 450px on a 900px screen) and it never helped
  anyway: min-height cannot make a section overflow, only content can. A
  section taller than the screen is already taller than its min-height, so
  removing the min-height changes nothing about the overflow and everything
  about the sections that were flagged by mistake.
*/
.edo-overlay .block.is-snap.is-overflowing {
  scroll-snap-align: none;
}

/* Dev readout for ?debug=1. Never rendered without it. */
.edo-overlay .edo-debug {
  position: fixed;
  right: var(--space-sm);
  bottom: var(--space-sm);
  z-index: 20;
  max-width: 380px;
  max-height: 45vh;
  overflow: auto;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-surface-invert);
  color: var(--color-ink-invert);
  border-radius: var(--radius-md);
  font-size: var(--size-small);
  line-height: 1.45;
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.3);
}
.edo-overlay .edo-debug ul { margin: var(--space-xs) 0; padding-left: 1.1em; }
.edo-overlay .edo-debug code { opacity: 0.75; }
.edo-overlay .edo-debug nav a {
  display: inline-block;
  margin-right: var(--space-xs);
  padding: 2px var(--space-xs);
  border: 1px solid currentColor;
  border-radius: var(--radius-sm);
  text-decoration: none;
}

/* ---------- Site header ---------- */

/*
  Page chrome, fixed over the snap container rather than scrolling with it.

  The docking behaviour is Jonah's, 2026-08-27. Everything below describes
  *state*; app.js only decides which state is on. Keeping the geometry here
  means the header still looks right in the half-second before JS runs, and
  looks right forever if JS never runs.

  --header-h is declared rather than measured because the docked transform has
  to be a pure CSS transition. Measuring it in JS and writing it back would
  mean a layout read on every scroll frame.
*/
/*
  Declared on .edo-overlay rather than on .site-header itself, because content
  needs them too: on a flow page the first section has to start below the bar
  instead of behind it, and it cannot read a variable scoped to a sibling.
*/
.edo-overlay {
  --header-h: 72px;
  /* "Just a few pixels" of the bar left showing when docked. It lands on the
     bar's orange bottom rule, so the sliver reads as a tab and not a seam. */
  /* Jonah, 2026-08-28: half again as deep, so the docked strip reads. */
  --header-peek: 8px;
}

.edo-overlay .site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 30;
  /*
    The header box still covers the top of the screen while the shell is docked
    away, so it must not intercept clicks meant for the slide underneath. The
    parts that ARE interactive turn this back on individually.
  */
  pointer-events: none;
}

/*
  The shell is what moves, not <header>. A transformed element is the
  containing block for its position:fixed children, so transforming <header>
  dragged the hot zone off screen with it and undocking-on-hover could never
  fire again.
*/
.edo-overlay .site-header__shell {
  position: relative;
  pointer-events: auto;
  transition: transform var(--motion-base) var(--easing);
}

.edo-overlay .site-header.is-docked .site-header__shell {
  transform: translateY(calc(var(--header-peek) - var(--header-h)));
}

.edo-overlay .site-header__bar {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  height: var(--header-h);
  padding-inline: var(--gutter);
  background: var(--color-surface);
  border-bottom: var(--header-peek) solid var(--color-accent-alt);
}

.edo-overlay .site-header__logo {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  margin-right: auto;
}
/*
  As much of the bar as the mark can take without the bar growing. 56px inside
  a 72px bar leaves 8px of breathing room top and bottom, which is the least
  that still looks deliberate.
*/
.edo-overlay .site-header__logo img {
  width: auto;
  height: 56px;
}

/* ---------- Header nav ---------- */

.edo-overlay .nav {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.edo-overlay .nav--stack {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
}

.edo-overlay .nav__link,
.edo-overlay .nav__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--size-small);
  letter-spacing: var(--tracking-display, 0.03em);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-ink);
  cursor: pointer;
}
.edo-overlay .nav__link:hover,
.edo-overlay .nav__summary:hover { color: var(--color-accent-alt); }

/* The default marker would sit next to our own chevron. */
.edo-overlay .nav__summary { list-style: none; }
.edo-overlay .nav__summary::-webkit-details-marker { display: none; }
.edo-overlay .nav__summary::marker { content: ""; }

.edo-overlay .nav__chevron {
  width: 0.7em;
  height: 0.7em;
  transition: transform var(--motion-fast) var(--easing);
}
.edo-overlay .nav__group[open] > .nav__summary .nav__chevron { transform: rotate(180deg); }

.edo-overlay .nav__group { position: relative; }

.edo-overlay .nav__dropdown {
  position: absolute;
  top: calc(100% + var(--space-sm));
  right: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 15rem;
  margin: 0;
  padding: var(--space-xs) 0;
  list-style: none;
  background: var(--color-surface);
  border-top: 3px solid var(--color-accent-alt);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.18);
}

.edo-overlay .nav__dropdown .nav__link {
  padding: var(--space-xs) var(--space-md);
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--size-small);
  white-space: nowrap;
}
.edo-overlay .nav__dropdown .nav__link:hover {
  background: var(--color-surface-alt);
  color: var(--color-accent-alt);
}

/* Donate. Smaller than a content button: this one sits in a 72px bar. */
.edo-overlay .site-header .nav__button {
  padding: 0.55rem var(--space-md);
  font-size: var(--size-small);
}

/* ---------- Hamburger ---------- */

.edo-overlay .site-header__burger {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-accent-alt);
  cursor: pointer;
}

/*
  Three bars from one element: the middle is the box, the outer two are its
  pseudo-elements. Fewer nodes to keep in step when it animates to a cross.
*/
.edo-overlay .site-header__burger-bars,
.edo-overlay .site-header__burger-bars::before,
.edo-overlay .site-header__burger-bars::after {
  display: block;
  width: 26px;
  height: 3px;
  background: currentColor;
  transition: transform var(--motion-fast) var(--easing),
              opacity var(--motion-fast) var(--easing);
}
.edo-overlay .site-header__burger-bars { position: relative; }
.edo-overlay .site-header__burger-bars::before,
.edo-overlay .site-header__burger-bars::after {
  content: "";
  position: absolute;
  left: 0;
}
.edo-overlay .site-header__burger-bars::before { top: -8px; }
.edo-overlay .site-header__burger-bars::after { top: 8px; }

.edo-overlay .site-header__burger[aria-expanded="true"] .site-header__burger-bars { background: transparent; }
.edo-overlay .site-header__burger[aria-expanded="true"] .site-header__burger-bars::before { transform: translateY(8px) rotate(45deg); }
.edo-overlay .site-header__burger[aria-expanded="true"] .site-header__burger-bars::after { transform: translateY(-8px) rotate(-45deg); }

/* ---------- Hamburger panel ---------- */

/*
  Absolutely positioned so the header's own height stays exactly --header-h.
  If the panel were in flow, opening it would change the height the docked
  transform is calculated from and the header would slide off screen.
*/
.edo-overlay .site-header__panel {
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  max-height: calc(100svh - var(--header-h));
  overflow-y: auto;
  padding: var(--space-lg) var(--gutter);
  background: var(--color-surface);
  box-shadow: 0 14px 30px rgb(0 0 0 / 0.18);
}
.edo-overlay .site-header__panel[hidden] { display: none; }

.edo-overlay .site-header__panel .nav__link {
  font-size: var(--size-h3);
  text-transform: none;
}

/* ---------- Docking affordances ---------- */

/*
  Desktop: hovering the top edge undocks. Live only while docked, or it would
  sit over the first slide's content and eat clicks meant for the page.
*/
.edo-overlay .site-header__hotzone {
  position: fixed;
  inset: 0 0 auto;
  /* Deeper than the sliver so the top edge is forgiving to aim at. */
  height: 48px;
  /*
    Above the shell, and therefore above the tap handle, which otherwise sits
    on top of this and eats the hover it exists to catch. On touch the media
    query below never applies, so the handle still gets the tap.
  */
  z-index: 2;
  pointer-events: none;
}
@media (hover: hover) {
  .edo-overlay .site-header.is-docked .site-header__hotzone { pointer-events: auto; }
}

/*
  Mobile: the sliver itself is the tap target. It overhangs the bar so there is
  a real 24px target rather than five pixels, and like the hot zone it is only
  live while docked.
*/
.edo-overlay .site-header__handle {
  position: absolute;
  top: calc(100% - var(--header-peek));
  right: 0;
  left: 0;
  height: 24px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: none;
}
.edo-overlay .site-header.is-docked .site-header__handle { pointer-events: auto; }

/* Nothing should slide anywhere for a reader who asked for less motion: the
   header just is where it is. */
@media (prefers-reduced-motion: reduce) {
  .edo-overlay .site-header__shell { transition: none; }
}

/*
  Mobile keeps every control, because "almost identical behaviour on desktop
  and mobile" was the note. Only the sizes change, and the dropdown goes
  full-bleed rather than hanging off a 320px bar.
*/
@media (max-width: 720px) {
  .edo-overlay .site-header { --header-h: 60px; }
  .edo-overlay .site-header__logo img { height: 44px; }
  .edo-overlay .site-header__bar { gap: var(--space-sm); }
  .edo-overlay .nav { gap: var(--space-sm); }
  .edo-overlay .nav__link,
  .edo-overlay .nav__summary { font-size: 0.75rem; }
  .edo-overlay .site-header .nav__button { padding: var(--space-xs) var(--space-sm); }
  .edo-overlay .site-header__burger { width: 2.25rem; }

  .edo-overlay .site-header .nav__dropdown {
    position: fixed;
    top: var(--header-h);
    right: 0;
    left: 0;
    min-width: 0;
  }
  .edo-overlay .site-header .nav__dropdown .nav__link {
    padding: var(--space-sm) var(--gutter);
    white-space: normal;
  }
}

/* Very narrow phones: the wordmark is the first thing that has to give. */
@media (max-width: 380px) {
  .edo-overlay .site-header__logo img { height: 36px; }
}

/* ---------- Overlay header ---------- */

/*
  Transparent over the hero photograph, solid once the reader scrolls. Set per
  page with `header.overlay`; js/app.js adds .is-solid past 24px.

  The bar keeps its height and its layout throughout -- only paint changes --
  so nothing under it moves when the background arrives. The transition is on
  background and border alone for the same reason.
*/
.edo-overlay .site-header--overlay .site-header__bar {
  background: transparent;
  border-bottom-color: transparent;
  transition: background var(--motion-med, 240ms) var(--easing),
              border-color var(--motion-med, 240ms) var(--easing);
}
.edo-overlay .site-header--overlay.is-solid .site-header__bar {
  background: var(--color-surface);
  border-bottom-color: var(--color-accent-alt);
}

/*
  A gradient under the transparent bar, so white type is legible whatever the
  photograph is doing up there. The mountains hero is pale sky at the top and
  the nav all but vanished into it. This is what nationalparks.org does, and
  it is the reason their white nav reads over any image.

  A pseudo-element rather than a background on the bar itself, because opacity
  animates and background-image does not -- this way it fades out as the solid
  background fades in, instead of popping.
*/
.edo-overlay .site-header--overlay .site-header__bar { position: relative; }
.edo-overlay .site-header--overlay .site-header__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom, rgb(0 0 0 / 0.55), rgb(0 0 0 / 0));
  pointer-events: none;
  transition: opacity var(--motion-med, 240ms) var(--easing);
}
.edo-overlay .site-header--overlay.is-solid .site-header__bar::after { opacity: 0; }

/* White type while there is a photograph behind it. */
.edo-overlay .site-header--overlay:not(.is-solid) :is(.nav__link, .nav__summary) {
  color: var(--color-ink-invert);
}
.edo-overlay .site-header--overlay:not(.is-solid) .nav__chevron { color: var(--color-ink-invert); }

/*
  The logo swaps file rather than colour. Both are in the markup; only one is
  ever displayed, so there is no flash while the other loads.
*/
.edo-overlay .site-header__logo-img--light { display: none; }
.edo-overlay .site-header--overlay:not(.is-solid) .site-header__logo-img { display: none; }
.edo-overlay .site-header--overlay:not(.is-solid) .site-header__logo-img--light { display: block; }

/* The burger's bars are drawn in currentColor, so they follow the nav. */
.edo-overlay .site-header--overlay:not(.is-solid) .site-header__burger { color: var(--color-ink-invert); }

@media (prefers-reduced-motion: reduce) {
  .edo-overlay .site-header--overlay .site-header__bar { transition: none; }
}

/*
  A long nav collapses to the burger; a short one does not.

  The header was built to keep every control on mobile, which was right when
  the nav was two items -- a campaign dropdown and Donate. The full site menu
  is eight, and at 375px it ran straight off the side of the screen.

  `:has()` counts the items so this only bites where it is needed: pages on the
  full site menu collapse, the 2026 and 2027 campaign microsites keep the
  behaviour Jonah signed off. Give is exempt because it is the one thing that
  must never be behind a tap, and it is already a button.

  Browsers without :has() simply keep the old behaviour rather than breaking.
*/
@media (max-width: 1100px) {
  .edo-overlay .site-header__nav:has(.nav__item:nth-child(4)) .nav__item:not(.nav__item--button) {
    display: none;
  }
}

/*
  And the reverse: wide enough that the full menu is showing inline, the
  burger only repeats it (Steve, 2026-10-12). Short campaign navs keep it,
  because there it is the only way to the rest of the site.
*/
@media (min-width: 1101px) {
  .edo-overlay .site-header:has(.site-header__nav .nav__item:nth-child(4)) .site-header__burger {
    display: none;
  }
}

/*
  Square corners on every button, site-wide on the converted pages: the
  rounded pill was dropped (Steve, 2026-10-12). Header buttons included.
*/
.edo-overlay .btn,
.edo-overlay .site-header .btn,
.edo-overlay .nav__button {
  border-radius: 0;
}

/* ---------- Mobile menu panel ---------- */
/*
  One list in one style -- bold caps with an orange caret, as the previous
  site's menu had (Steve, 2026-10-13: "the text and style of the links is
  better") -- and a group opens in place, pushing the rest down, instead of
  popping a fixed dropdown OVER the panel. Give stays in the bar, not here.
*/
.edo-overlay .site-header__panel {
  padding-block: var(--space-md) var(--space-lg);
  background: #f7f8fa;
}
.edo-overlay .site-header__panel .nav--stack { align-items: flex-start; gap: 4px; }
.edo-overlay .site-header__panel .nav__item--button { display: none; }
.edo-overlay .site-header .site-header__panel .nav--stack > .nav__item > :is(.nav__link, .nav__group > .nav__summary) {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 6px 0;
  font-family: 'Montserrat', var(--font-display), sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: normal;
}
.edo-overlay .site-header__panel .nav__summary { cursor: pointer; list-style: none; }
.edo-overlay .site-header__panel .nav__summary::-webkit-details-marker { display: none; }
/* The caret: a small solid orange triangle. */
.edo-overlay .site-header__panel .nav__chevron { display: none; }
.edo-overlay .site-header__panel .nav__summary::after {
  content: "";
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--color-accent-alt, #ff7c1e);
  transition: transform .2s ease;
}
.edo-overlay .site-header__panel .nav__group[open] > .nav__summary::after { transform: rotate(180deg); }
.edo-overlay .site-header__panel .nav__dropdown,
.edo-overlay .site-header .site-header__panel .nav__dropdown {
  position: static;
  inset: auto;
  min-width: 0;
  margin: 0 0 8px;
  padding: 0 0 0 16px;
  border: 0;
  box-shadow: none;
  background: none;
  transform: none;
}
.edo-overlay .site-header .site-header__panel .nav__dropdown .nav__link {
  min-height: 36px;
  padding: 6px 0;
  font-size: 14px;
  font-weight: 500;
  text-transform: none;
  white-space: normal;
}
/* Top-level items, plain links (Store) and group headers alike, one style.
   The rule above could only ever reach plain links, so Store came out at a
   different size from its neighbours (Steve, 2026-10-13). */
.edo-overlay .site-header .site-header__panel .nav--stack > .nav__item > .nav__link,
.edo-overlay .site-header .site-header__panel .nav--stack > .nav__item > .nav__group > .nav__summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 0;
  padding: 6px 0;
  font-family: 'Montserrat', var(--font-display), sans-serif;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
/* A touch larger with a little more air (Steve, 2026-10-13). */
.edo-overlay .site-header .site-header__panel .nav--stack > .nav__item > .nav__link,
.edo-overlay .site-header .site-header__panel .nav--stack > .nav__item > .nav__group > .nav__summary {
  font-size: 17px;
  padding: 9px 0;
}
.edo-overlay .site-header .site-header__panel .nav__dropdown .nav__link { font-size: 15px; padding: 8px 0; }
