/* ============================================================
   tokens.css — the single source of truth for the brand.
   Change a value here and it changes everywhere on the site.
   ============================================================ */

@font-face{font-family:"Harry Obese";src:url("../fonts/harry-obese.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Harry Fat";src:url("../fonts/harry-fat.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Harry Thin";src:url("../fonts/harry-thin.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 29";src:url("../fonts/knockout-29-junior-lightweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 30";src:url("../fonts/knockout-30-junior-welterweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 49";src:url("../fonts/knockout-49-lightweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 69";src:url("../fonts/knockout-69-full-lightweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 90";src:url("../fonts/knockout-90-ultimate-welterweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"Knockout 70";src:url("../fonts/knockout-70-full-welterweight.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}

:root{
  /* --- ground -------------------------------------------------
     Committed single theme. The cream is specified, so it is
     painted explicitly rather than inherited from the viewer. */
  --ground:#FDF2E8;
  /* Preview cards sit ~6% below white so the screenshots — which are mostly white
     UI — read as objects on a surface rather than dissolving into it. Warm, to sit
     with the cream ground. Holds the lightest edge (forest 600) at 3.93:1, over the
     3:1 bar for the display type it carries. Do not darken past ~#E7E7E7, where
     that pair reaches 3.78:1. */
  --card-ground:#EFEBE4;
  --shadow-shot:drop-shadow(0 2px 5px rgba(0,0,0,.28));

  /* Interactive cards. --shade is the darkening agent for hover: mixing a card's
     own --edge toward it keeps the hue and only drops lightness, which also lifts
     contrast, so a hover state can never fail a bar its rest state passed.
     --focus-ring is black rather than a brand colour: it has to read the same against
     blue, green and orange cards, and neutral is the only thing that does. 17.68:1 on
     the card ground and 19.05:1 on the page ground, far past the 3:1 of WCAG 2.4.13. */
  --shade:#000000;
  --paper:#FFFFFF;       /* pure white: only the high-contrast setting (css/playground.css) uses it */
  --focus-ring:#000000;
  --shadow-card:0 1px 2px rgba(21,50,26,.06);
  --shadow-card-lift:0 6px 16px rgba(21,50,26,.18);


  /* about me. All three colours measured on --ground (#FDF2E8): "about" in orange 700
     is 6.61:1 and "me" in apricot 600 is 4.59:1, both clearing the 4.5:1 that AAA asks
     of large text. apricot 500 was the natural warmth here but lands at 3.29:1 — it
     passes AA large and fails AAA, so this use goes one stop darker. The rule is a
     non-text graphic needing 3:1; orange 500 gives 3.40:1.
     --about-enter/-settle are shares of viewport height: progress starts when the
     section top crosses the first and completes at the second. */
  --about-word-a:var(--orange-700);
  --about-word-b:var(--apricot-600);
  --about-rule-ink:var(--orange-500);
  --about-rule-w:2px;          /* matches .tl-line, so the bar reads continuous */
  --about-rule-h:clamp(90px,13vw,190px);
  /* 0, not a partial length: any non-zero minimum leaves a stub of orange drawn
     before the scroll ever starts, which reads as a stray mark rather than as the
     rail continuing. The rule draws itself entirely from the scroll. */
  --about-rule-min:0;
  --about-rule-gap:clamp(.5rem,1.1vw,.9rem);   /* rule to heading, and the photos' top offset */
  /* The bio and the rule under the heading share one colour by design, so this token
     moves both. forest 900 is 12.67:1 on the ground — body copy is normal-size text,
     so the bar is the 7:1 AAA asks of it, not the 4.5:1 the display words answer to.
     forest 700 reads warmer but lands at 5.92:1 and would clear AA only. */
  --about-bio-ink:var(--forest-900);
  --about-enter:.85;
  --about-settle:.50;
  /* The section is the last thing before the footer, so without runway beneath it the
     heading can never reach the settle line and the scrub stalls short of landing. */
  --about-runway:28vh;
  /* The timeline's rail column and gutter. About reuses both so its rule lands on the
     exact x of the craft media rail above it — one gridline, not two guesses. */
  /* Polaroids in the about section. --panel is the warm white of the print border;
     the frame is deliberately bottom-heavy, which is what reads as "polaroid" more
     than any amount of tilt does. */
  --polaroid-pad:clamp(.5rem,1vw,.75rem);
  --polaroid-chin:clamp(1.6rem,3.2vw,2.6rem);
  --polaroid-shadow:0 10px 22px rgba(21,50,26,.20);
  /* The tilt lifts a polaroid's corner above its own frame, and display caps sit below
     their line box. Both push the stack visually high against "about"; this brings the
     photo's top edge back onto the letters. Optical, not structural. */
  --polaroid-nudge:7px;

  /* Footer. The ground is the green the wordmark opens on, so the page closes where it
     began. Everything on it is measured against forest 900: cream text 12.67:1, the
     bird's legs 5.21:1, its beak 7.66:1. Note the footer overrides --focus-ring —
     the site's black ring is 1.50:1 here and would be invisible. */
  --footer-ground:var(--forest-900);
  --footer-ink:var(--apricot-50);
  /* The wordmark ghosted into the footer — decorative only, so it is deliberately
     far below any contrast bar and hidden from assistive tech. */
  --footer-ghost:9%;

  /* How far the upper polaroid sits right of the lower one, as a share of their
     column. Proportional rather than a pixel clamp: a fixed step reads as a clear
     offset on a narrow desktop and as nothing at all on a wide one. The frames are
     narrowed by the same amount, so the whole stagger happens inside the column and
     can never reach the page edge or #about's overflow-x:clip. */
  --polaroid-stagger:10%;
  /* One width for all three prints, so they read as one set rather than three
     separately-sized objects. Sized in vw rather than as a share of a column,
     because the pair and the side print sit in columns of different widths. */
  /* ~17.5% down from clamp(190px,21vw,340px) — desktop-only; the pair and the
     side print were overpowering the text column next to them. */
  --polaroid-w:clamp(160px,17.5vw,280px);
  --rail-col:clamp(34px,4vw,52px);
  --tl-gap:calc(clamp(.75rem,1.6vw,1.4rem) + 20px);
  /* Mobile-only rail column — narrower than --rail-col, which stays reserved for
     the desktop 3-column grids. Single source for .tl-group's mobile columns
     and #about's mobile rail, so they can't drift apart. */
  --rail-col-m:clamp(28px,6vw,40px);
  /* Where content starts, left edge to left edge, once the rail is out of the
     way on mobile: the rail's own column plus the same gutter the timeline
     already uses between its rail and its cards. */
  --content-gutter-m:calc(var(--rail-col-m) + var(--tl-gap));
  --panel:#FFF8F0;
  --scrim:color-mix(in srgb,color-mix(in srgb,var(--forest-900) 30%,black) 94%,transparent);   /* lightbox backdrop: the forest hue, pushed near-black so the enlarged image is the only bright thing */

  /* --- ink ---------------------------------------------------- */
  --ink:#15321A;          /* kiln/forest 900 */
  --muted:#37683F;        /* kiln/forest 700 */
  --rule:rgba(21,50,26,.16);
  --accent:#37683F;       /* kiln/forest 700 — 5.92:1 on cream, clears AA */

  /* --- kiln / forest scale ------------------------------------ */
  --forest-50:#EFF7F0;  --forest-100:#DFEFE0; --forest-200:#C3DFC6;
  --forest-300:#A1CAA6; --forest-400:#7EB185; --forest-500:#609869;
  --forest-600:#498052; --forest-700:#37683F; --forest-800:#264D2D;
  --forest-900:#15321A;

  /* --- the wordmark's scroll walk -----------------------------
     Five stops, dark to light. --n5 is the CONTRAST FLOOR:
     on the cream ground, 400 measures 2.24:1 and fails the 3:1
     bar for display type. 500 is the first stop that clears it.
     Do not lighten --n5 past 500. */
  --n1:var(--forest-900);
  --n2:var(--forest-800);
  --n3:var(--forest-700);
  --n4:var(--forest-600);
  --n5:var(--forest-500);

  /* --- kiln / orange scale ------------------------------------ */
  --orange-50:#FEF1EC;  --orange-100:#FEE3D8; --orange-200:#FEC9B4;
  --orange-300:#FBA584; --orange-400:#EA8259; --orange-500:#D36333;
  --orange-600:#B74A16; --orange-700:#983702; --orange-800:#732701;
  --orange-900:#4B1701;

  /* Marker highlight. 400 is the darkest orange that keeps forest 900
     at AA for body text on top of it (5.21:1). 500 drops to 3.73:1
     and fails. Do not darken past 400. */
  --highlight:var(--orange-400);

  /* --- kiln / apricot ----------------------------------------- */
  --apricot-50:#FDF2E8;  --apricot-100:#FBE6D0; --apricot-200:#F4CFA8;
  --apricot-300:#E7B27A; --apricot-400:#D39349; --apricot-500:#BC7715;
  --apricot-600:#9D6105; --apricot-700:#7F4E04; --apricot-800:#603902;
  --apricot-900:#3E2401;

  /* --- kiln / inkblue ----------------------------------------- */
  --inkblue-50:#EEF5FF;  --inkblue-100:#DEEBFE; --inkblue-200:#BFD8FE;
  --inkblue-300:#97C0FC; --inkblue-400:#71A3ED; --inkblue-500:#5289D9;
  --inkblue-600:#3B70BE; --inkblue-700:#2A5A9F; --inkblue-800:#1B427A;
  --inkblue-900:#0D2952;

  /* --- kiln / neutral ----------------------------------------- */
  --neutral-50:#F7F4ED;  --neutral-100:#ECE9E2; --neutral-200:#D9D6CF;
  --neutral-300:#C1BDB6; --neutral-400:#A5A29A; --neutral-500:#8B8881;
  --neutral-600:#747169; --neutral-700:#5D5B54; --neutral-800:#46433D;
  --neutral-900:#2C2A24;

  /* --- the work banner ----------------------------------------
     Ticker text is apricot 50 on the 600 stripe: 4.48:1. That value
     is the same cream as the page ground, so the names read as the
     background punched through the blue. */
  --stripe-top:var(--inkblue-900);
  --stripe-mid:var(--inkblue-600);
  --stripe-bot:var(--inkblue-300);
  --stripe-text:var(--apricot-50);

  /* --- type --------------------------------------------------- */
  --display:"Harry Obese",ui-sans-serif,sans-serif;   /* the wordmark */
  --display-alt:"Harry Fat",ui-sans-serif,sans-serif; /* headings */
  --label:"Harry Thin",ui-sans-serif,sans-serif;      /* eyebrows, captions */
  --body:"Knockout 29",ui-sans-serif,sans-serif;      /* roles, hero */
  --statement:"Knockout 49",ui-sans-serif,sans-serif; /* the intro statement */
  /* Running text. Knockout 30 is Junior Welterweight — the narrowest width
     in the family. Chosen for the brand voice; size and leading are held up
     to compensate. --body-wide (Knockout 90, Ultimate) and var(--ui) are both
     still available if the measure proves too tight. */
  --body-text:"Knockout 30",ui-sans-serif,sans-serif;
  --body-wide:"Knockout 90",ui-sans-serif,sans-serif;
  --statement-strong:"Knockout 70",ui-sans-serif,sans-serif; /* the name */
  --ui:ui-sans-serif,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;

  /* --- the banner's type pair ---------------------------------
     The ticker and the heading sit one Fibonacci step apart. Ratios
     of adjacent Fibonacci terms converge on phi, so the step is
     expressed as phi and holds at every width; at the desktop
     default the pair lands on roughly 34px / 55px, which are
     adjacent terms. Change --tick-size and the heading follows. */
  --fib-step:1.618;
  --tick-size:clamp(1.75rem,3vw,2.9rem);

  /* --- rhythm ------------------------------------------------- */
  --step:clamp(1.5rem,4vw,3rem);
}
