/*
  Token contract.

  Reskinning the site is a stated key feature, so this file is the only place
  block CSS is allowed to get a value from. Names are role-based on purpose:
  --color-accent, never --color-earthday-green. The same contract has to
  survive onto other EDO pages and onto whatever skin comes next.

  These are neutral defaults. A theme file (css/theme-*.css) overrides the
  values and nothing else. If a reskin ever needs to touch blocks.css, this
  contract has failed and should be extended instead.
*/

:root {
  /* Color roles */
  --color-surface: #ffffff;
  --color-surface-alt: #f4f6f4;
  --color-surface-invert: #101512;
  --color-ink: #16201a;
  --color-ink-muted: #5a6660;
  --color-ink-invert: #ffffff;
  --color-accent: #2b7a48;
  --color-accent-ink: #ffffff;
  --color-accent-alt: #e0562d;
  /* Category accents, for blocks that colour-code a set of items. */
  --color-accent-2: #2f6f8a;
  --color-accent-3: #4c7a52;
  --color-border: #d8ded9;
  --color-focus: #1d6fd0;

  /* Scrim over background photography, so text stays legible on any image */
  /* Lightened 2026-08-26: the hero photography was reading too dark. Still
     enough to hold white text, but the image is now the subject. */
  --scrim-dark: linear-gradient(180deg, rgba(0, 0, 0, 0.32), rgba(0, 0, 0, 0.18));
  --scrim-left: linear-gradient(90deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.1) 55%, rgba(0, 0, 0, 0) 100%);
  /* For a narrow screen, where a left fade has no room to be a fade:
     the copy spans the full width, so the protection has to as well. */
  --scrim-dark-strong: linear-gradient(180deg, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.45));
  --scrim-none: none;

  /*
    The alternative to a scrim, Jonah 2026-08-27: leave the photograph
    untouched and put the shadow on the type instead. Used wherever the picture
    is the subject and an overlay would flatten it.
  */
  --text-shadow-strong: 0 0 10px rgb(0 0 0 / 1);

  /* Type */
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: var(--font-body);
  --weight-body: 400;
  --weight-display: 900;
  /* One step down from the display weight, for the h3 tier. */
  --weight-h3: 800;
  --weight-card-title: 600;
  --leading-tight: 1.12;
  --leading-body: 1.6;

  /*
    Type scale, fluid so slides hold up between phone and desktop.

    Jonah, 2026-08-27, measured off the live page at a 1440 viewport:
    section h2 runs 47-57px, not the 34px this used to cap at, and the whole
    page read a size too small because of it. Headings are weight 900, the h3
    step is 800.
  */
  /*
    The hero heading. 56px at the top, which is where the live page's hero
    headings land (57px at a 1440 viewport). 72px was overshooting: it is the
    biggest type on the page and it was bigger than anything on the original.
  */
  --size-display: clamp(2.125rem, 1.3rem + 2.8vw, 3.5rem);
  /* The campaign line under the wordmark. It is the page's h1. */
  --size-h1: clamp(1.75rem, 1rem + 2.6vw, 3.25rem);
  /* Section headings top out at 48px. */
  --size-h2: clamp(1.75rem, 1.05rem + 2.4vw, 3rem);
  /* Sub-headings and stat figures top out at 38px. */
  --size-h3: clamp(1.375rem, 1rem + 1.5vw, 2.375rem);
  /* Parent site runs 22px body copy. Floor is 18px so it stays readable on
     phones rather than scaling a 22px design straight down. */
  --size-body: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --size-small: 0.875rem;
  /* The stat figures are the h3 step on the impact slide, so they share it. */
  --size-stat: var(--size-h3);
  /* Story card headlines, called out separately: 24px at 600. */
  --size-card-title: 1.5rem;

  /* Space */
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1.25rem;
  --space-lg: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4.5rem;

  /* Shape */
  --radius-sm: 4px;
  --radius-md: 10px;
  --radius-pill: 999px;
  --border-width: 2px;

  /* Layout */
  --container: 1200px;
  --container-narrow: 780px;
  /* Body copy on the full-bleed slides. Jonah, 2026-08-27. */
  --measure-wide: 1080px;
  --gutter: clamp(1rem, 0.5rem + 2.5vw, 3rem);

  /* Motion. Every duration routes through here so reduced-motion can zero it. */
  --motion-fast: 150ms;
  --motion-base: 300ms;
  --easing: cubic-bezier(0.2, 0, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-base: 0ms;
  }
}
