/* ══════════════════════════════════════════════════════════════════════════
   Design tokens — the one place any of these are declared

   Transcribed from refs/Project_Components/Design_Tokens_0825.png (the
   Button section is ahead of the sheet), and drawn back out of this file,
   live, by docs/tokens.html. Loaded by
   index.html, work.html and about.html, and it is the only sheet all three
   share: index.html carries the shader and its own shelf, the other two carry
   the paper module system out of css/page.css, and the tokens are the whole
   of what they have in common.

   Values are mobile-first. The desktop step is the one media query at the
   bottom and it is the only place any of these are redefined — with the
   single exception of --paper/--ink, which the paper-page renderers set per
   project (js/project.js, js/about.js).
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  /* ── Palette ───────────────────────────────────────────────────────────
     Colour is the content's job. Photographs, project colourways and the
     index shader are what carry hue here; the chrome around them — the WORK
     button, the ripple, the chips, the focus rings — is ink
     on paper or cream on ink and nothing else. A control that competes with
     the work it frames is a control in the wrong colour.

     --paper and --ink are the pair that moves: work.html's renderer sets them
     per project from the entry's `bg`/`ink`, which is the "background colour
     changes" beat of the tile-to-detail transition; about.html sets them
     once, because that page is one long stack and not six of them. Anything
     that should stay legible across every colourway reaches for --ink rather
     than naming a colour, and that is why the chrome does. */
  --paper: #FFFFFF;
  --ink: #14140F;
  /* The fixed near-black, for the surfaces that must not follow a project:
     index.html's contact card and the outer edge of the water poster. Same
     value as --ink's default and deliberately so — one black in the palette,
     two names because only one of them is allowed to be overwritten. */
  --base: #14140F;
  --cream: #F5F2EC;
  /* Reserved for content — editorial accents inside a project, not chrome.
     The UI marks itself by weight and luminance instead, which is what keeps
     it out of the way of the work. */
  --tan: #C8B89A;
  /* The water. The shader page, the wash that hands over to it (body.leaving
     in css/page.css, #veil in index.html) — and the upstream ripple, which is
     a drawing of water and the one piece of chrome that keeps a colour. */
  --pine: #40504D;
  /* index.html's error state, and the only warm signal colour on the site. */
  --orange: #D4622A;
  /* Placeholder frame fill, for the slots whose media has not been shot or
     exported yet. Warm rather than grey so an unfinished page still sits
     inside the palette. */
  --ph-fill: #E9E5DC;

  /* ── Type ──────────────────────────────────────────────────────────── */
  --font: "Urbanist", "Helvetica Neue", system-ui, sans-serif;
  /* The one family that is not Urbanist, and the only token that reaches for
     it. Georgia rather than a generic `serif` behind it: the fallback carries
     the headline for as long as the swap takes, and it is a page's first
     line, so it should already be the right shape when it lands. */
  --font-expressive: "Averia Serif Libre", Georgia, "Times New Roman", serif;
  /* Nav Links: index.html's WORK / ABOUT edge labels. Bebas Neue ships one
     weight (400) and is caps-only by design, so the labels need nothing else
     to read as a set. The face is inlined in index.html, subset to the
     letters those two words use — it is not loaded anywhere else, so this
     token only works for those words on that page. "Bebas Neue Fallback" is
     Impact resized there to Bebas's widths. */
  --font-nav: "Bebas Neue", "Bebas Neue Fallback", Impact, sans-serif;

  --display-size: 42px;   /* Black 900 · 120% */
  --display-expressive-size: 28px;  /* Averia Serif Libre 700 · 120% */
  --heading-size: 26px;   /* Bold 700 · 120% */
  --body-size: 16px;      /* Medium 500 · 130% */
  --caption-size: 12px;   /* SemiBold 600 · 130% — same at both breakpoints */
  --nav-size: 16px;       /* Nav Link (deprecated): Bold 700 · 100% · 14% tracking — both bps; the noscript send still uses it */
  --nav-links-size: 28px; /* Nav Links: Bebas Neue 400 · 100% · 5% tracking — both bps */
  --chip-size: 12px;      /* Bold 700 */
  --footer-links-size: 32px; /* Footer Links: Bold 700 · 130% · 0% tracking */

  /* ── Layout ────────────────────────────────────────────────────────────
     --mod-inset is the side margin every *inset* paper module shares;
     measured off the comps at ~9% of the frame. --cap-pad is the caption's
     one and only offset, so a caption is never further from its image than
     this. --spacer is the gap under every module. index.html uses none of
     these — it has no modules — but they are tokens, and tokens live here. */
  --mod-inset: 20px;
  --mod-gap: 20px;
  --cap-pad: 8px;
  --spacer: 3rem;
  /* The footer's top and bottom padding, and the gap above it — one number
     for all three, so the band sits in as much air as it holds. */
  --footer-pad: 64px;

  /* The nav icon's margin. Its one job is to be the same number on every
     page: the glyph's right edge has to land identically on all three or the
     nav-icon view transition flies across the viewport instead of morphing
     in place. */
  --gutter: 34px;
  /* How far the up-a-level ripple's 4rem box sits in from the right. The box
     is half a rem wider than its 3rem glyph on each side, so insetting it
     past the gutter is what lands the artwork — not its padding — on the
     margin. See .upstream for why it is applied against 100vw rather than as
     a plain `right`. */
  --slot-inset: max(calc(var(--gutter) - 0.5rem), env(safe-area-inset-right));

  /* ── The close control ─────────────────────────────────────────────
     One shape for every way out of an overlay — today, index.html's contact
     card. Two numbers, because both are load-bearing.

     44px is the target, not the glyph. It is WCAG 2.5.5's enhanced size and
     Apple's HIG minimum, which is the same thing said twice — a control sized
     for a thumb rather than a cursor. The glyph rides at half that and the
     rest is reach.

     The ring is what makes the target visible instead of implied. Cream at
     half alpha, against SC 1.4.11's 3:1 for a component boundary: 4.89:1
     measured, composited, on the near-black. Anything brighter turns a way out into a feature. */
  --close-size: 44px;
  --close-ring: rgba(245, 242, 236, 0.5);

  /* ── Button ────────────────────────────────────────────────────────────
     The pill: work.html's WORK button today. Set in the nav face so it reads
     as one family with index.html's edge labels, and coloured ink and cream
     (the palette's chrome pair, used directly) rather than anything of its
     own. Same at both breakpoints: it is chrome, and stays one size. 48px
     tall clears the 44px target above with room for the type. */
  --button-size: 18px;      /* Bebas Neue 400 · 100% */
  --button-tracking: 0.05em;
  --button-height: 48px;
  --button-pad-x: 40px;
  --button-radius: 999px;
  --button-gap: 8px;        /* label to glyph, when the glyph is shown */
  --button-shadow: 0 8px 28px rgba(20, 20, 15, 0.22), 0 1px 3px rgba(20, 20, 15, 0.2);
  --button-shadow-hover: 0 12px 32px rgba(20, 20, 15, 0.26), 0 1px 3px rgba(20, 20, 15, 0.2);
}

@media (min-width: 768px) {
  :root {
    --display-size: 64px;
    --display-expressive-size: 40px;
    --heading-size: 32px;
    --body-size: 18px;
    /* The button tokens do not step up here (see ── Button). --nav-links-size
       does — the edge labels are the homepage's only type and carry it at
       desktop size. */
    --nav-links-size: 32px;
    --footer-links-size: 48px;
    --footer-pad: 128px;
    --cap-pad: 16px;
    --mod-inset: 9vw;
    --mod-gap: 3vw;
    --gutter: 40px;
  }
}

/* Text for crawlers and screen readers that the design states in pictures
   instead — index.html's page heading is the one use. Clipped, not
   display:none, so it stays in the accessibility tree. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
