.site-header {
  background: var(--c-surface);
  border-block-end: 1px solid var(--c-border);
  position: sticky;
  top: 0;
  z-index: 50;
}

.site-header__inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-4);
  min-height: 72px;
  padding-block: var(--s-3);
}

/* --- brand ---------------------------------------------------------------- */

.brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  text-decoration: none;
  color: inherit;
  margin-inline-end: auto;
}

.brand__name {
  font-size: var(--t-lg);
  font-weight: var(--fw-bold);
  letter-spacing: 0.02em;
  line-height: 1.1;
}

.brand__tagline {
  font-size: var(--t-xs);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--c-ink-muted);
}

/* --- navigation ----------------------------------------------------------- */

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  /* 44px minimum: the WCAG target size, and the difference between a button
     that feels solid under a thumb and one that feels sloppy. */
  min-height: 44px;
  padding-inline: var(--s-3);
  background: none;
  color: var(--c-ink);
  border: 1px solid var(--c-border);
  border-radius: var(--radius);
  cursor: pointer;
  order: 3;
}

.nav-toggle__label {
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
}

/* One header row on a 375px phone (#9). There are 343px between the gutters,
   and the EU lockup takes 166 of them at the 36px it may not go below. The
   rest is found here: the wordmark drops to 28px tall (about 102px wide, see
   --logo-max-h-brand-mobile), the gaps halve, and the menu button shows only
   its icon. 102 + 8 + 166 + 8 + 44 is 328.

   The word "Menu" stays in the button for screen readers, clipped rather than
   removed, and the script still swaps it to "Close", so the accessible name is
   unchanged. At 320px the row still wraps, which flex-wrap handles; that width
   is the reflow test, not a phone anyone sells.

   Up to 36em, not 30em. The logos used to step up to 48px at 30em, and with
   the label back as well the row needed about 523px at 480, so it wrapped
   again from 480 to about 540: a large phone held sideways, or a small
   tablet. The step now happens at 36em (576px), the first width where the
   full-size row fits, and the compact header holds until then. */
@media (max-width: 35.999em) {
  .site-header__inner {
    gap: var(--s-2);
  }

  .nav-toggle {
    min-width: 44px;
    padding-inline: 0;
  }

  .nav-toggle__label {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    width: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
  }
}

/* Search, the last menu item. Icon and label side by side in the phone panel;
   the desktop rule below keeps only the icon. */
.nav__link--search {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}

.nav__link--search svg {
  flex: none;
}

.nav-toggle[aria-expanded="true"] {
  background: var(--c-ink);
  color: var(--c-bg);
  border-color: var(--c-ink);
}

/* One icon, two paths: hamburger closed, cross open. */
.nav-toggle__cross { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__cross { display: block; }

/* The menu gap, declared on the nav and consumed by the list inside it, never
   on the same rule (check-css-tokens.mjs). The search icon's centring margin
   reads it too. */
.site-nav {
  --nav-gap: var(--s-5);
}

.nav__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--nav-gap);
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav__link {
  display: inline-block;
  padding-block: var(--s-2);
  color: var(--c-ink);
  text-decoration: none;
  border-block-end: 2px solid transparent;
}

.nav__link:hover {
  border-block-end-color: var(--c-border);
}

/* The current page, or the section a page sits in (aria-current="page" on the
   page itself, "true" on its section, so a screen reader is not told a news
   article is the News page). The bar is the ink, 14.15:1 on the header. It was
   the brand orange, 2.33:1, under the 3:1 a state indicator needs (1.4.11),
   and the team had asked to "deepen the orange… it makes accessibility
   harder"; orange stays on the link underlines, where it is decoration. The
   weight stays at medium: bold widens the labels, and the desktop row has no
   room to give at 1024px. */
.nav__link[aria-current] {
  color: var(--c-ink);
  font-weight: var(--fw-medium);
  border-block-end-color: var(--c-ink);
}

/* --- dropdown submenus: Resources and Team ------------------------------- */

/* A <details>, so click, Enter, Space, focus and the accessibility tree come
   from the browser and need no script. A hover menu was not an option: it
   cannot be opened on a touch screen, and it punishes anyone who cannot hold a
   pointer still. */
.nav__menu {
  position: relative;
}

/* display:flex on a summary also removes the default disclosure triangle in
   Chrome and Safari; the other two lines cover Firefox and older WebKit. We
   draw our own caret below, which has to rotate with the state. */
.nav__summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
  list-style: none;
}

.nav__summary::-webkit-details-marker {
  display: none;
}

/* Drawn from two borders rather than a glyph: a character would be read out by
   a screen reader, and the summary's name is the section, not "triangle". */
.nav__summary::after {
  content: "";
  inline-size: 0.45em;
  block-size: 0.45em;
  border-inline-end: 2px solid currentColor;
  border-block-end: 2px solid currentColor;
  transform: translateY(-0.15em) rotate(45deg);
  transition: transform 120ms ease-out;
}

.nav__menu[open] > .nav__summary::after {
  transform: translateY(0.1em) rotate(225deg);
}

/* The summary is not a link, so it cannot carry aria-current. The section is
   marked with the same ink bar an aria-current link gets. */
.nav__summary[data-current-section] {
  font-weight: var(--fw-medium);
  border-block-end-color: var(--c-ink);
}

.nav__sublist {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Mobile: the nav collapses, the EU lockup does NOT. It stays in the always
   visible bar, because the visibility rules cover mobile versions too. */
@media (max-width: 63.999em) {
  /* Emblem before the button, so the hamburger keeps the far-right corner
     where a thumb expects it. */
  .eu-lockup { order: 2; }

  /* The panel does not animate its height.
     An earlier version grew the container from `grid-template-rows: 0fr` to
     `1fr` while the list inside stayed a flex column. Flex items shrink by
     default, so every row was squeezed flat and then snapped to size as the
     track grew, which is what made opening the menu look broken. Animating
     only opacity and a small offset touches no layout, so nothing can squash. */
  .site-nav {
    display: none;
    order: 10;
    flex-basis: 100%;
    /* Full-bleed out of the container's gutters, so the separators run edge to
       edge instead of floating in from the sides. */
    margin-inline: calc(var(--gutter) * -1);
    border-block-start: 1px solid var(--c-border);
    background: var(--c-surface);
    /* Six items plus the header must never exceed the viewport on a small
       phone: the panel scrolls rather than pushing the page around. */
    max-height: calc(100vh - 72px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* display:none also keeps the links out of the tab order while hidden,
     without the visibility juggling the animated version needed. */
  .site-nav[data-open="true"] {
    display: block;
    animation: nav-panel-in 160ms ease-out;
  }

  @keyframes nav-panel-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* Plain block flow, not a flex column: rows cannot be compressed by their
     container, whatever height it happens to have. */
  .nav__list {
    display: block;
  }

  .nav__link {
    display: flex;
    align-items: center;
    /* Full-width row, 48px tall: the whole strip is the tap target, not just
       the width of the word. */
    min-height: 48px;
    padding-inline: var(--gutter);
    padding-block: 0;
    /* One separator, not the two competing borders this had before. */
    border-block-end: 1px solid var(--c-border);
    border-inline-start: 3px solid transparent;
  }

  .nav__list li:last-child .nav__link {
    border-block-end: none;
  }

  .nav__link:hover {
    background: var(--c-surface-alt);
    border-block-end-color: var(--c-border);
  }

  .nav__link[aria-current] {
    background: var(--c-surface-alt);
    border-inline-start-color: var(--c-ink);
    border-block-end-color: var(--c-border);
  }

  .nav__link:focus-visible {
    outline-offset: -3px;
  }

  /* The submenu expands in place inside the panel rather than floating. The
     indent is what says these sit under the parent; the parent keeps its own
     full-width row above them. */
  .nav__summary {
    justify-content: space-between;
  }

  .nav__link--child {
    padding-inline-start: calc(var(--gutter) + var(--s-5));
    background: var(--c-surface-alt);
  }

  /* The panel's last row owns the closing edge. With a submenu open, that row
     is a child link, not the last top-level item. */
  .nav__list > li:last-child .nav__menu[open] .nav__sublist li:last-child .nav__link {
    border-block-end: none;
  }
}

@media (min-width: 64em) {
  .nav-toggle {
    display: none;
  }

  /* Icon only on desktop, a 44px target, with "Search" kept as its accessible
     name. Clipped, not removed, the same way the phone menu button keeps
     "Menu". */
  /* Centred both ways, measured from screenshots rather than judged by eye.

     Down: the eye centres an icon on the middle of the lowercase letters, the
     x-height, which sits below the middle of a line box. Centring the icon in
     its box left it 3.5px above the labels. So the link is a text box like its
     neighbours, with the same padding and line height, and the icon sits in
     the line with vertical-align: middle, which CSS defines as the baseline
     plus half the x-height: the labels' optical centre in whatever font
     renders them.

     Across: the menu is pushed right against the emblem, so a margin on the
     icon's left only moves the other items further left; the end margin is
     what moves it. Measured without it, the glyph has the menu gap plus 15px
     to its left (its 12px padding, the end of "News") and a constant 36px to
     its right (its padding, the header's 16px gap, the emblem's white plate).
     An end margin of the difference, gap minus 21px, makes the two equal:
     31px each side below 75em, 39px above. */
  .nav__search {
    margin-inline-end: calc(var(--nav-gap) - 21px);
  }

  /* 12 + 20 + 12: a 44px target built from even padding, so the icon is in
     the middle of its box by construction rather than by alignment rules. */
  .nav__link--search {
    display: inline-block;
    padding-inline: calc((44px - 20px) / 2);
  }

  .nav__link--search svg {
    display: inline-block;
    vertical-align: middle;
  }

  .nav__search-label {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    width: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
  }

  .site-nav {
    display: block;
    max-height: none;
    overflow: visible;
  }

  .nav__list {
    display: flex;
  }

  /* Floats over the page, so it needs a surface, an edge and a stacking order.
     z-index 50 clears the page banner, which is full-bleed and pulls up into
     the header's space. */
  .nav__sublist {
    position: absolute;
    inset-block-start: 100%;
    inset-inline-start: 0;
    z-index: 50;
    min-inline-size: 14rem;
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-raised);
    /* The rows run edge to edge and the panel clips them, so a hovered row at
       the top or bottom follows the panel's own corner instead of painting a
       square into it. .nav__link has no radius of its own, which is correct for
       the full width rows of the mobile panel and was wrong here.

       Clipping rather than giving each row its own radius, because the current
       page is marked with a 3px bar on the leading edge and a border on a
       rounded box curves into a sliver. */
    overflow: hidden;
  }

  /* A row, not an inline word: the whole width is the target. The bar moves to
     the leading edge, because a bottom border inside a floating panel reads as
     a divider between items rather than as state. */
  .nav__link--child {
    display: block;
    padding: var(--s-2) var(--s-4);
    border-block-end: none;
    border-inline-start: 3px solid transparent;
  }

  /* Inside the row, because the panel's overflow: hidden cut off the outside
     of a 3px ring offset 2px beyond it (2.4.7). The same as the phone panel. */
  .nav__link--child:focus-visible {
    outline-offset: -3px;
  }

  .nav__link--child:hover {
    background: var(--c-surface-alt);
  }

  .nav__link--child[aria-current="page"] {
    background: var(--c-surface-alt);
    border-inline-start-color: var(--c-ink);
  }
}

/* The desktop row is full at 1024px. The search icon cost about 60px of the 34
   it had to spare, and Team becoming a dropdown like Resources adds its
   chevron, about 15px more. Below 75em the gaps between menu items narrow from
   24px to 12px, which gives back about 70 across the six gaps; from 75em there
   is room for the full gap again. The search icon's centring margin is
   written in terms of --nav-gap, so it stays centred at either gap. */
@media (min-width: 64em) and (max-width: 74.999em) {
  .site-nav {
    --nav-gap: var(--s-3);
  }
}
