/* =============================================================
   Layout — JSHW

   The page frame: header and nav (including the mobile panel),
   the main content column, generic section spacing, and the footer.
   Everything that positions a page rather than styles a thing in it.

   Structure only. Every value is a token from tokens.css — no
   hard-coded hex, spacing or type values in here (see CLAUDE.md).

   Load order: 3rd, after base.css. See the stylesheet block in
   _includes/layouts/base.njk for the full order and why it matters.
   ============================================================= */

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

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  padding: var(--space-s) var(--container-gutter);
  max-width: var(--container-max);
  margin-inline: auto;
}

.site-header__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  text-decoration: none;
}

.site-header__wordmark {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-lg);
  color: var(--color-text);
}

.nav-toggle {
  display: none;
  align-items: center;
  gap: var(--space-3xs);
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-s);
  padding: var(--space-xs) var(--space-s);
  font-size: var(--text-sm);
  min-height: var(--target-comfortable);
  cursor: pointer;
}

.nav-toggle__icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  border-top: 2px solid currentcolor;
  box-shadow: 0 0.35em 0 0 currentcolor, 0 0.7em 0 0 currentcolor;
}

.site-nav__list {
  display: flex;
  gap: var(--space-m);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav__list a {
  color: var(--color-text);
  text-decoration: none;
  font-weight: var(--weight-medium);
  padding: var(--space-3xs) 0;
  border-bottom: 2px solid transparent;
}

.site-nav__list a:hover,
.site-nav__list a[aria-current="page"] {
  border-bottom-color: var(--color-brand);
}

@media (max-width: 640px) {
  /* Without this, .site-nav stays a flex item in the same nowrap row as
     the logo and toggle — width:100% below just shrinks it to whatever
     space is left, instead of moving to its own line. Found by actually
     opening the menu at a real mobile width: it rendered as a narrow
     column floating top-right, overlapping the hero content underneath
     it rather than pushing it down. */
  .site-header {
    flex-wrap: wrap;
  }

  .nav-toggle {
    display: inline-flex;
  }

  .site-nav {
    display: none;
    width: 100%;
  }

  .site-nav.is-open {
    display: block;

    /* Reads as a distinct panel now that it sits on its own line,
       not page content bleeding into the header row. */
    border-top: 1px solid var(--color-border);
    margin-top: var(--space-s);
  }

  .site-nav__list {
    flex-direction: column;
    gap: var(--space-3xs);
    padding: var(--space-s) 0;
  }

  /* Full-width, min-44px tap targets for the stacked mobile list —
     the horizontal-inline version above stays compact since desktop
     nav is a mouse target, not a touch one. Measured before this fix:
     30px tall and only as wide as the link text (e.g. 43×30 for
     "Home") — under both Apple's 44pt and Android's 48dp touch-target
     guidance, and with items only 8px apart, adjacent short links were
     genuinely mis-tappable. */
  .site-nav__list a {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: var(--target-comfortable);
    padding: var(--space-2xs) 0;
  }
}

/* --- Main content --------------------------------------------- */

main {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-l) var(--container-gutter) var(--space-3xl);
}

/* --- Section spacing ------------------------------------------------ */

/* `.section` sits at (0,1,0) — the same specificity as .hero, .notice,
   .card-grid and .photo, which all also set max-width. Safe because no
   element in any template carries .section alongside one of those; it is
   always a wrapper around them. `.section > :first-child` at (0,2,0)
   outranks their margin shorthands regardless of file order. */
.section {
  margin: var(--space-2xl) 0;
  max-width: none;
}

.section > :first-child {
  margin-top: 0;
}

/* --- Footer ------------------------------------------------------ */

/* Real extracted footer: dark navy background, near-white text —
   see tokens.css --color-brand-strong / --color-text-inverse. Not the
   generic light footer this started as. Contained, not full-bleed —
   matches how .site-header and main already just centre a column
   rather than introducing a new full-width-background pattern. */
.site-footer {
  background: var(--color-brand-strong);
  padding: var(--space-l) var(--container-gutter);
  max-width: var(--container-max);
  margin-inline: auto;
  display: grid;
  gap: var(--space-l);
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  font-size: var(--text-sm);
  color: var(--color-text-inverse);
}

.site-footer h2 {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-brand);
  margin: 0 0 var(--space-2xs);
}

/* (0,1,1), equal to `a:hover` in base.css and deliberately winning over
   it — footer links keep their inverse colour on hover. Depends on this
   file loading AFTER base.css; see base.njk. */
.site-footer a {
  color: var(--color-text-inverse);
}

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3xs);
}

.site-footer__copyright {
  grid-column: 1 / -1;
  margin: 0;
  padding-top: var(--space-m);
  border-top: 1px solid var(--color-border);
}

.icon {
  vertical-align: -0.15em;
}

/* --- Report layout (/insights/ articles) --------------------------
   `main` is a centred, padded column (see "Main content" above) — every
   other page on this site is happy inside it. The report masthead and
   mid-article pull-quote band are the one place this site needs a full-
   bleed colour band, because that's the strongest, most legible way to
   mark "this is a different kind of page" against the plain brochure
   pages either side of it in the nav. `calc(50% - 50vw)` breaks a band
   out of any ancestor's centred max-width, however deep it's nested —
   the standard, boring way to do this without a wrapping-element hack. */
.report-band {
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--container-gutter), calc(50vw - var(--container-max) / 2 + var(--container-gutter)));
}

.report-masthead {
  padding-block: var(--space-2xl) var(--space-xl);
  background: var(--color-brand-strong);
  color: var(--color-text-inverse);
  border-bottom: 3px solid var(--color-brand);
}

.report-masthead :is(h1, p) {
  color: var(--color-text-inverse);
}

.report-band--pull {
  padding-block: var(--space-xl);
  background: var(--color-brand-strong);
  color: var(--color-text-inverse);
}

.report-band--pull :is(h2, p, blockquote) {
  color: var(--color-text-inverse);
}

/* The closing "through-line" band — the last section of every article.
   Same ground and inverse text as .report-band--pull, so a piece opens
   dark, has one dark beat in the middle, and closes dark: the argument
   lands on the same surface it was set up on, and the two dark bands
   bracket the evidence between them.

   The top border repeats the masthead's bottom border exactly (3px solid
   var(--color-brand)) so the closer reads as that headline's bookend
   rather than a third, unrelated block.

   The selector carries `.report-body > .section` deliberately. That rule
   sets `border-top: 1px solid var(--color-border)` on every section and
   sits at (0,2,0); a bare `.report-band--closer` at (0,1,0) would lose to
   it and leave a grey hairline above the band instead of the brand rule.

   padding-top is left to `.report-body > .section` (--space-2xl) on
   purpose rather than restated here — that is where .report-band--pull's
   own top padding comes from too, so both bands sit on the same 64/48
   rhythm. Only padding-bottom needs setting: a plain .section has none,
   which on a coloured band would crop the text against the fold. */
.report-body > .section.report-band--closer {
  padding-bottom: var(--space-xl);
  background: var(--color-brand-strong);
  color: var(--color-text-inverse);
  border-top: 3px solid var(--color-brand);
}

.report-band--closer :is(h2, p, blockquote) {
  color: var(--color-text-inverse);
}

/* The body of an article: same section rhythm as brochure pages
   (.section, reused as-is), but articles are read start to finish, so a
   rule between sections reads better than the brochure pages' plain gap. */
.report-body > .section {
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-2xl);
}

.report-body > .section:first-child {
  border-top: 0;
  padding-top: 0;
}

.report-colophon {
  margin-top: var(--space-2xl);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.report-colophon p {
  max-width: none;
}
