/* ==========================================================================
   Base: reset, typography, accessibility primitives
   ========================================================================== */

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

/* The hidden attribute must win. Any component that sets a display value
   (grid, flex) silently defeats the UA stylesheet's [hidden] rule, which turns
   every JS `el.hidden = true` into a no-op. This one line prevents a whole
   category of bug. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchored headings clear the sticky header instead of hiding under it. */
  scroll-padding-top: calc(var(--header-h, 76px) + var(--space-m));
}

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--ink-body);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: var(--leading-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* The mobile dock is fixed over the page; this keeps the last section
     reachable above it, including the notch inset on modern handsets. */
  padding-bottom: 0;
  overflow-x: clip;
}

@media (max-width: 63.99em) {
  body { padding-bottom: calc(var(--dock-h, 68px) + env(safe-area-inset-bottom, 0px)); }
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-display);
  color: var(--ink-strong);
  font-weight: 800;
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
}

h1 { font-size: var(--step-5); line-height: var(--leading-tight); }
h2 { font-size: var(--step-4); line-height: var(--leading-tight); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }
h5, h6 { font-size: var(--step-0); }

p, ul, ol, dl, blockquote, figure, table, pre { margin: 0 0 var(--space-s); }
p { text-wrap: pretty; }
p:last-child, ul:last-child, ol:last-child { margin-bottom: 0; }

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--dur-fast) var(--ease-out);
}
a:hover { color: var(--accent-hover); }

img, picture, video, svg { display: block; max-width: 100%; height: auto; }

strong, b { font-weight: 700; color: var(--ink-strong); }

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: var(--space-l) 0;
}

table { border-collapse: collapse; width: 100%; }

button, input, select, textarea { font: inherit; color: inherit; }

:target { scroll-margin-top: calc(var(--header-h, 76px) + var(--space-m)); }

/* --------------------------------------------------------------------------
   Focus.
   Two rings, drawn in opposite polarities, so the indicator survives on the
   white page, on the navy sections, and over photography. Never removed.
   -------------------------------------------------------------------------- */
:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--focus-outer);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--focus-inner), 0 0 0 6px var(--focus-outer);
  border-radius: var(--radius-xs);
}

.u-invert :focus-visible {
  --focus-inner: var(--navy-900);
  --focus-outer: #FFFFFF;
}

/* --------------------------------------------------------------------------
   Accessibility utilities
   -------------------------------------------------------------------------- */

/* Visually hidden but present for assistive technology. */
.u-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Same, until focused, at which point it becomes visible. */
.u-sr-focusable:focus,
.u-sr-focusable:focus-visible {
  position: static;
  width: auto; height: auto;
  margin: 0;
  overflow: visible;
  clip-path: none;
  white-space: normal;
}

.c-skiplink {
  position: fixed;
  top: var(--space-2xs);
  left: var(--space-2xs);
  z-index: var(--z-skip);
  padding: var(--space-2xs) var(--space-s);
  background: var(--navy-800);
  color: #FFFFFF;
  font-weight: 700;
  border-radius: var(--radius-s);
  transform: translateY(-200%);
  transition: transform var(--dur-fast) var(--ease-out);
}
.c-skiplink:focus-visible { transform: translateY(0); }

/* --------------------------------------------------------------------------
   Fit-to-width headings.
   The CSS half is a viewport-derived best guess that renders acceptably with
   JavaScript disabled. fit-heading.js then measures the real glyph width and
   overwrites --fit-size and --fit-track inline for an exact fill.
   -------------------------------------------------------------------------- */
.u-fit {
  display: block;
  font-size: var(--fit-size, clamp(1.75rem, 8.2vw, 9rem));
  letter-spacing: var(--fit-track, var(--tracking-display));
  line-height: 1.06;
  white-space: nowrap;
  max-width: 100%;
  /* Horizontal clip only; see .u-fit__line for why the vertical axis must
     stay visible. */
  overflow-x: clip;
  overflow-y: visible;
}

/* Multi-line fitted headings: each line is its own fitted block.
 *
 * max-width is load-bearing. The line is white-space: nowrap, so without a cap
 * it sizes its own parent, the fitter then measures that inflated width and
 * solves against it, and the pair settle at a width far wider than the
 * viewport. That feedback loop is invisible where the container has a definite
 * width from a grid track and appears the moment it does not. Capping the line
 * breaks the loop, so the container width stays the real one. */
.u-fit__line {
  display: block;
  max-width: 100%;
  font-size: var(--fit-size, inherit);
  letter-spacing: var(--fit-track, var(--tracking-display));
  white-space: nowrap;

  /* Clip horizontally only.
   *
   * A plain `overflow: clip` also clips vertically, and at the tight leading a
   * display heading wants, the line box is shorter than the glyphs. The tail
   * of a y, g or p falls outside it and gets sliced off. That is invisible on
   * "Manufacturers" and obvious on "AutoGyro". Pairing clip with visible on
   * the other axis is legal precisely because clip does not force a scroll
   * container the way hidden does. */
  overflow-x: clip;
  overflow-y: visible;

  /* Leading that actually contains the descenders. Below about 1.02 the glyph
     extent exceeds the line box in most grotesques. */
  line-height: 1.06;
}

/* Until the fitter has run, the heading is laid out but not yet exact. This
   avoids a visible resize snap on slower devices. */
.u-fit:not([data-fitted]) { visibility: visible; }

/* --------------------------------------------------------------------------
   Print. Editorial pages are genuinely printed by owners and instructors.
   -------------------------------------------------------------------------- */
@media print {
  .c-header, .c-dock, .c-a11y, .c-megamenu, .c-footer__newsletter { display: none !important; }
  body { padding: 0; color: #000; background: #fff; }
  .u-fit { font-size: 24pt !important; white-space: normal; letter-spacing: normal; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
}
