/* ==========================================================================
   BASE — fonts, reset, document rhythm, layout primitives.
   ========================================================================== */

/* ---- Webfonts ------------------------------------------------------------
   Self-hosted, latin subset. No Google Fonts CDN: render-blocking, a third
   party connection, and a GDPR question for zero benefit. */

@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-var.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;      /* the width axis the hero signature runs on */
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Schibsted Grotesk";
  src: url("../fonts/schibsted-var.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "DM Mono";
  src: url("../fonts/dm-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* The signature script from the existing site. Used in exactly one place —
   the "Hi, I'm" line — which is what keeps it a flourish rather than a theme. */
@font-face {
  font-family: "Quentin";
  src: url("../fonts/quentin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Metric-matched fallbacks. Values derived from the real font tables
   (Archivo upm 1000 asc 878 desc -210; Schibsted upm 2048 asc 2000 desc -528)
   divided by the size-adjust ratio, so `swap` causes no layout shift. */
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans");
  size-adjust: 103.49%;
  ascent-override: 84.84%;
  descent-override: 20.29%;
  line-gap-override: 0%;
}

@font-face {
  font-family: "Schibsted Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Liberation Sans");
  size-adjust: 101.77%;
  ascent-override: 95.96%;
  descent-override: 25.33%;
  line-gap-override: 0%;
}

/* ---- Reset --------------------------------------------------------------- */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1.5rem);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  /* Matches the footer, not the old floating-card ground: with the page radius
     gone, over-scroll should reveal the footer's colour rather than a stray
     navy band. */
  background: var(--brand-deep);
  color: var(--text-primary);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Any class that sets `display` outranks the UA's `[hidden] { display: none }`,
   so the attribute silently stops working — which is exactly what happened to
   the stepped form's buttons. This restores it for every element. */
[hidden] { display: none !important; }

img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
p, h1, h2, h3, h4, li { overflow-wrap: break-word; }
ul[class], ol[class] { list-style: none; padding: 0; }

/* ---- Type ---------------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -.028em;
  text-wrap: balance;
}

h1 { font-size: var(--fs-xl); line-height: .98; letter-spacing: -.035em; }
h2 { font-size: var(--fs-l); }
h3 { font-size: var(--fs-m); line-height: 1.18; letter-spacing: -.02em; }
h4 { font-family: var(--font-text); font-size: var(--fs-title); font-weight: 600;
     line-height: 1.3; letter-spacing: -.01em; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .22em; }

/* The two-tone headline. The key phrase holds full contrast; the remainder
   drops to secondary. One class, used everywhere — not a one-off. */
.dim { color: var(--text-secondary); }

/* Section label: lowercase italic, not an uppercase tracked-out mono eyebrow. */
.label {
  font-family: var(--font-text);
  font-size: var(--fs-sm);
  font-style: italic;
  font-weight: 400;
  color: var(--text-muted);
  letter-spacing: 0;
  margin-bottom: var(--s4);
}

/* Monospace is fenced to places where the content genuinely IS data. */
.data {
  font-family: var(--font-mono);
  font-size: var(--fs-data);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.micro {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: .04em;
  color: var(--text-muted);
}

.lede {
  font-size: var(--fs-lede);
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 58ch;
}

.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--s4); }

/* ---- Layout primitives --------------------------------------------------- */

/* Full-bleed. `overflow: clip` (not hidden) keeps position:sticky alive. */
.page {
  background: var(--bg-base);
  overflow: clip;
  isolation: isolate;
}

.wrap {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}

.section { padding-block: var(--section-y); }

/* Bands. Each sets its own ground; none of them set vertical padding, so they
   can never fight .section over spacing. */
.band-base { background: var(--bg-base); }
.band-tint { background: var(--bg-tint); }
.band-warm { background: var(--bg-warm); }

.band-ink {
  background: var(--bg-ink);
  color: var(--ink-text);
}
.band-ink .label,
.band-ink .data,
.band-ink .micro { color: var(--ink-text-dim); }
.band-ink .dim,
.band-ink .lede   { color: var(--ink-text-dim); }

/* Asymmetric splits. Never 6/6 — a 50/50 split is the visual signature of a
   template, so the grid itself carries a point of view. */
.split-7-5, .split-5-6, .split-7-4 {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .split-7-5 { grid-template-columns: 7fr 5fr; }
  .split-5-6 { grid-template-columns: 5fr 6fr; }
  .split-7-4 { grid-template-columns: 7fr 4fr; }
}

.section-head { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head h2 { max-width: 20ch; }
.section-head .lede { margin-top: var(--s4); }

/* Centred heading block — the reference's dominant rhythm. Everything is
   centred as a unit, including the measure, so the text block stays optically
   balanced instead of just being centre-aligned ragged text. */
.section-head--mid {
  text-align: center;
  max-width: 46rem;
  margin-inline: auto;
}
.section-head--mid h2 { max-width: 22ch; margin-inline: auto; }
.section-head--mid .lede { margin-inline: auto; }

/* ---- Accessibility floor -------------------------------------------------- */

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip {
  position: absolute;
  left: var(--s4);
  top: var(--s4);
  z-index: 200;
  padding: var(--s3) var(--s4);
  background: var(--accent);
  color: var(--text-on-accent);
  border-radius: var(--r-sm);
  font-weight: 600;
  transform: translateY(-200%);
  transition: transform var(--t-state) var(--e-state);
}
.skip:focus-visible { transform: translateY(0); }

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

/* ---- Scroll reveal -------------------------------------------------------
   Opacity + transform only, so it stays on the compositor. Fires once: the
   observer unobserves after triggering, and .is-in is never removed. */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--t-enter) var(--e-enter),
              transform var(--t-enter) var(--e-enter);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

/* Without JS the observer never runs, so nothing would ever become visible.
   This is the safety net: no .js on <html> means no reveal at all. */
html:not(.js) .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}
