/* Base: element defaults only. Anything with a class lives in a component file. */
*, *::before, *::after { box-sizing: border-box; }

html { scrollbar-gutter: stable; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-height) + var(--space-base)); }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-normal);
  color: var(--color-text-primary);
  background: var(--color-background);
  overflow-wrap: break-word;
  text-rendering: optimizeLegibility;
}
body.menu-open { overflow: hidden; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-heading);
  text-wrap: balance;
}
h1 { font-size: var(--text-3xl); line-height: var(--line-height-tight); }
h2 { font-size: var(--text-2xl); line-height: var(--line-height-tight); }
h3 { font-size: var(--text-xl); line-height: var(--line-height-snug); }
h4 { font-size: var(--text-lg); line-height: var(--line-height-snug); letter-spacing: 0; }

p { margin: 0; max-width: var(--measure); text-wrap: pretty; }
ul, ol { margin: 0; padding: 0; }
img { display: block; max-width: 100%; height: auto; }
strong { font-weight: var(--font-weight-semibold); }

a { color: var(--color-link); text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: 1px; transition: color var(--duration-fast) var(--ease); }
a:hover { color: var(--color-link-hover); text-decoration-thickness: 2px; }

/* One focus style everywhere: outline survives forced-colors mode; 3px orange-ink ≥ 4.6:1 on every light surface, orange 4.6–5.5:1 on dark. */
:focus-visible { outline: var(--focus-width) solid var(--color-focus); outline-offset: var(--focus-offset); }
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--color-action); color: var(--color-text-on-action); }

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

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--space-base); top: var(--space-base); z-index: var(--z-skip-link);
  padding: var(--space-snug) var(--space-base); border-radius: var(--radius-sm);
  background: var(--color-action); color: var(--color-text-on-action); font-weight: var(--font-weight-semibold);
  transform: translateY(-200%); transition: transform var(--duration-fast) var(--ease);
}
.skip-link:focus { transform: none; }

/* Inline SVG icons inherit text colour and size from their context. */
.icon { width: 1.25em; height: 1.25em; flex: none; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Scroll reveal is enhancement only: hidden state applies just when JS has loaded (html.js). */
.js .reveal { opacity: 0; transform: translateY(var(--reveal-distance)); transition: opacity var(--duration-slow) var(--ease), transform var(--duration-slow) var(--ease); }
.js .reveal.is-visible { opacity: 1; transform: none; }
/* Safety net: if site.js never runs (html.js but no html.js-ready), revealed content appears anyway after 2.5s. */
.js:not(.js-ready) .reveal { animation: reveal-fallback 0s 2.5s forwards; }
@keyframes reveal-fallback { to { opacity: 1; transform: none; } }
/* Lists styled without bullets keep their list semantics (build.py adds role="list"). */
