/* ============================================================================
   WAMcares — tokens.  Direction: THE TABLE (Track B, ministry register).

   LAYER 1 is the only place a hex literal lives. Every other layer refers to
   Layer 1 by name. Retheming the site means editing Layer 1 and nothing else.

   The ground is sampled from WAM's own photographs. The BLUES ARE SAMPLED
   FROM THE LOGO, 2026-09-02, on Patrick's instruction that the logo is the
   colour palette.

   This matters, because the values this file previously called "WAM Blue" and
   "Deep Navy" were taken off the old website, not off the mark. The logo
   files in /brand/ carry #099ED1, #0F4878, #43C5DF and #7A8596. Nothing in
   them is #153F5D or #0C2742. That is why the old dark blue read as the other
   site's colour: it was the other site's colour.

   TOKENS ARE PROVISIONAL. No brand palette or typeface has ever been
   confirmed for WAM. Re-run tools/contrast.py after any Layer 1 edit.
   ========================================================================= */

:root {

  /* -- LAYER 1 · raw palette ---------------------------------------------- */

  /* Ground. Warm ivory, lifted out of the tan the client read as "brown".
     The previous ground was #EFE1C6 and the page carried tan ground, tan
     fold, brown ink, brown rules, an olive band and a heavy weave: six
     brown decisions compounding. Light and warm is the brief; the colour
     now comes from the photographs, which are full of WAM blue, hi-vis
     yellow and Levantine sun, not from the earth under them. */
  --raw-cloth:        #FBF6EC;
  --raw-cloth-fold:   #F4EBDA;   /* the shaded fold, barely a step          */
  --raw-cloth-edge:   #E3D5BC;   /* hairline rules between rows             */
  --raw-cloth-seam:   #C9A96A;   /* the governing seam, warm gold           */
  --raw-cloth-edge-hc:#BCA478;   /* the same rules under prefers-contrast   */
  --raw-cloth-seam-hc:#9A7B3F;
  --raw-indigo-edge-hc:#6FA2C2;

  /* Brand. Read directly out of /brand/blue-horizontal.svg.                 */
  --raw-wam-cyan:     #099ED1;   /* the mark's primary. Never used as text  */
  --raw-wam-blue:     #0F4878;   /* the mark's deep blue                    */
  --raw-wam-sky:      #43C5DF;   /* the mark's highlight                    */
  --raw-wam-gray:     #7A8596;   /* the mark's grey. Available, unused      */

  --raw-indigo:       #0F4878;   /* the field: logo deep blue               */
  --raw-indigo-deep:  #0B3A61;   /* one step deeper, for the page head,
                                    the footer and the triptych ground      */
  --raw-indigo-edge:  #2E7FB0;   /* rules on a blue field                   */

  /* The single action colour. Cobalt, 2026-09-02: the client asked for the
     orange buttons to be blue. Terracotta #B4531E / #97400F / #9C4517 /
     #F0B183 is retired. Four values, each measured; re-run tools/contrast.py
     after any edit here.

     THE GOLD SEAM STAYS GOLD. --raw-cloth-seam is a rule, not a button, and
     with the action colour now cool it is the only warm thing left on the
     cloth ground. Turning it blue as well produces the unrelieved-blue page
     the client's own feedback objected to. */
  --raw-action:       #0F4878;   /* logo deep blue. White label     8.74:1  */
  --raw-action-deep:  #0F4878;   /* the same blue as TEXT on cloth  8.74:1  */
  --raw-action-hover: #0A3559;   /* the action, pressed                     */
  --raw-action-lift:  #43C5DF;   /* logo highlight as TEXT on a field
                                    4.62:1 on the blue, 5.69:1 deeper       */
  /* On a blue field a deep-blue button disappears, so the action inverts to
     the mark's cyan with ink type: the block reads 3.09:1 against the field
     and the label 6.0:1 against the block. Both values are the logo's.     */
  --raw-action-on-field:      #099ED1;
  --raw-action-on-field-text: #0D111D;

  /* Ink. Warm brown-black, never neutral gray on a warm ground.             */
  --raw-ink:          #23201C;
  --raw-ink-soft:     #5A5148;   /* secondary text on cloth                 */
  --raw-light:        #FBF7F0;
  --raw-light-soft:   #D9CDBB;   /* secondary text on olive/indigo          */

  /* -- LAYER 2 · semantic roles -------------------------------------------- */

  --ground:            var(--raw-cloth);
  --ground-fold:       var(--raw-cloth-fold);
  --field-blue:        var(--raw-indigo);
  --field-indigo:      var(--raw-indigo-deep);

  --text:              var(--raw-ink);
  --text-soft:         var(--raw-ink-soft);
  --text-accent:       var(--raw-action-deep);
  --text-on-field:     var(--raw-light);
  --text-on-field-soft:var(--raw-light-soft);
  --text-on-field-accent: var(--raw-action-lift);

  --seam:              var(--raw-cloth-edge);
  --seam-strong:       var(--raw-cloth-seam);
  --seam-field:        var(--raw-indigo-edge);
  --seam-indigo:       var(--raw-indigo-edge);

  --action:            var(--raw-action);
  --action-hover:      var(--raw-action-hover);
  /* A stamped month is cloth showing through the field: a value change that
     survives grayscale, where filled-terracotta-on-olive measured 1.55:1 and
     out-massed the one control the story depends on. */
  --stamp:             var(--raw-cloth);
  --stamp-text:        var(--raw-ink);
  --action-text:       var(--raw-light);

  /* -- LAYER 3 · type ------------------------------------------------------ */

  --font-display: 'Alegreya', 'Iowan Old Style', Palatino, Georgia, serif;
  --font-body:    'Alegreya Sans', ui-sans-serif, system-ui, -apple-system,
                  'Segoe UI', Roboto, sans-serif;

  /* One scale, four display steps. The old system had six plus a mono
     record voice; the extra steps were read as busyness, not as hierarchy. */
  --fs-d1:   clamp(2.6rem, 1.30rem + 5.0vw, 5.25rem);
  /* The voice steps. The verse leads the page, the conviction closes the
     programs, and both are display type in the same ramp as the headings. */
  --fs-voice:    clamp(1.95rem, 1.20rem + 2.5vw, 3.05rem);
  --fs-voice-sm: clamp(1.75rem, 1.05rem + 2.6vw, 3.15rem);
  --fs-equation: clamp(1.50rem, 1.15rem + 1.5vw, 2.15rem);
  --fs-figure:   clamp(1.90rem, 1.50rem + 1.4vw, 2.60rem);
  --fs-d2:   clamp(1.95rem, 1.42rem + 2.1vw, 3.00rem);
  --fs-d3:   clamp(1.35rem, 1.22rem + 0.5vw, 1.60rem);
  --fs-lead: clamp(1.20rem, 1.11rem + 0.38vw, 1.45rem);
  --fs-body: 1.0625rem;   /* 17px. Floor is 16; prose never goes below.      */
  --fs-small:0.9375rem;   /* 15px. Captions and notes, never body prose.     */

  --lh-d1: 0.99;  --lh-d2: 1.07;  --lh-d3: 1.25;
  --lh-lead: 1.42; --lh-body: 1.62;

  /* Leading falls as size rises; tracking tightens as size rises.           */
  --tr-d1: -0.021em;  --tr-d2: -0.015em;  --tr-d3: -0.008em;  --tr-body: 0;

  --measure:        66ch;
  --measure-narrow: 52ch;

  /* -- LAYER 4 · space ----------------------------------------------------- */

  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;

  /* Radius. Referenced by .stage__pause since 4 September and never declared,
     so that control computed to square corners with no error (the same silent
     failure as --seam-inset). 3px is the design system's stated radius. */
  --radius:    3px;

  --shell:     72rem;
  --shell-pad: clamp(1.25rem, 4vw, 3.5rem);
  --band-pad:  clamp(3.5rem, 7vw, 7rem);

  /* -- LAYER 5 · motion ---------------------------------------------------- */

  /* One easing curve. There is no spring engine in this direction: state
     changes here are discrete, and a declared spring nothing consumes is
     decoration in the token layer. */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* -- LAYER 6 · material -------------------------------------------------- */

  /* Depth is a sheet lying on cloth: offset plus soft blur, tinted from the
     ink so the shadow is warm brown rather than gray. No zero-blur block. */
  --lift: 0 1px 2px -1px color-mix(in oklab, var(--raw-ink) 18%, transparent),
          0 8px 22px -12px color-mix(in oklab, var(--raw-ink) 30%, transparent);
  --lift-photo:
          0 2px 4px -2px color-mix(in oklab, var(--raw-ink) 22%, transparent),
          0 18px 44px -20px color-mix(in oklab, var(--raw-ink) 38%, transparent);

  /* The cloth's weave. Fine turbulence, generated rather than striped:
     stripes alias into moire at 2x device pixel ratios.

     Painted as a background layer on each ground, NOT as one fixed underlay.
     The underlay version reached only the body: every field band painted over
     it, so three of the four grounds measured a flat 0.000 standard deviation,
     and being fixed it slid against the content on scroll. Two strengths,
     because the same turbulence reads far hotter on a dark field than on sand. */
  --weave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23w)' opacity='0.20'/%3E%3C/svg%3E");
  --weave-field: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='w'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23w)' opacity='0.16'/%3E%3C/svg%3E");

  /* -- LAYER 7 · single-source content values ------------------------------ */

  /* The country count is unreconciled across WAM's published assets. A funder
     reviewer has already flagged inconsistent country lists once. It renders
     from ONE value, so no two places on the site can disagree. */
  --wam-country-count: "[COUNTRY COUNT PENDING RECONCILIATION]";
}

/* The single-source value, rendered wherever it is referenced. When JS has
   written the real value as a text node, the generated copy stands down. */
[data-wam="country-count"]::after { content: var(--wam-country-count); }
[data-wam="country-count"][data-resolved="true"]::after { content: none; }

/* Accessibility preferences are resolved in the token layer, never patched
   into a component. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Prose already sits above 7:1 on every ground, so raised contrast collapses
   the secondary text into the primary and strengthens the rules, which are
   the only elements deliberately close to their background. */
@media (prefers-contrast: more) {
  :root {
    --text-soft:          var(--raw-ink);
    --text-on-field-soft: var(--raw-light);
    --seam:               var(--raw-cloth-edge-hc);
    --seam-strong:        var(--raw-cloth-seam-hc);
    --seam-field:         var(--raw-indigo-edge-hc);
    --seam-indigo:        var(--raw-indigo-edge-hc);
  }
}
