/* tokens.css
 The site's design tokens — every custom property, in one place. Loaded
 first on every page (before style.css), so all other stylesheets and
 the scene scripts can assume these exist. This file only declares
 tokens; base styles stay in style.css / dark.css.

 History: merged from the :root blocks of style.css, dark.css,
 index/index.css and about-us/about-us.css with values unchanged; then
 the 2026-08 color revision re-derived the palette from a three-spine
 OKLCH model around the brand orange (paper spine 87.5°, ink line
 67.5°→82.4°, brand hue 53.2°) — a softer alert and seventeen
 one-hex-digit alignments. The same month's sizing pass snapped every
 length onto the quarter grid — the standard is stated with the
 Spacing section below. */

:root {
	/* ── Brand — Piko orange ────────────────────────────────────
	   Sampled from the live site's meta-theme-color (#E8843C). The
	   scene scripts (story.js, problem.js, cards.js) paint from this
	   ramp too. */
	--piko-orange-50: #fcf3ea;
	--piko-orange-100: #fbe4cc;
	--piko-orange-200: #f6c99a;
	--piko-orange-300: #f1ad68;
	--piko-orange-400: #ed9852;
	--piko-orange-500: #e8843c;
	--piko-orange-600: #d06e28;
	--piko-orange-700: #a85822;
	--piko-orange-800: #7f421a;
	--piko-orange-900: #552c11;

	/* ── Neutrals — the warm ink-to-parchment axis ──────────────
	   The ramp's ends are the light pages' palette itself (950 =
	   --ink, 50 = --parchment); the steps between keep the old
	   charcoal ramp's lightness on the warm axis. */
	--ink-950: #1a1714;
	--ink-900: #23201d;
	--ink-800: #2e2b28;
	--ink-700: #433f3b;
	--ink-600: #5c5853;
	--ink-500: #79746e;
	--ink-400: #98938c;
	--ink-300: #b7b2ab;
	--ink-200: #d5d0c8;
	--ink-100: #e8e3da;
	--ink-50: #f4efe6;
	--white: #ffffff;

	/* ── Semantic color — the light pages' dialect ──────────────
	   The original style.css names, now aliased onto the ramps they
	   equal. NOTE: --amber is also baked into the CTA gorilla assets
	   (shared/cta-gorilla.webp / -static.png); if it changes,
	   regenerate them — see "CTA gorilla assets" in CLAUDE.md. */
	--parchment: var(--ink-50);
	--ink: var(--ink-950);
	--amber: var(--piko-orange-500);
	--rule: #d8cfbf;

	/* The homepage's paper tones (index + about-us). --paper-deep is
	   the tonal-fold cream — the half-tone-darker band. */
	--paper: var(--parchment);
	--paper-deep: #ece3d2;
	--ink-soft: var(--ink-600); /* muted warm ink (about-us roles/bios) */

	/* Semantic aliases from the delivered redesign */
	--brand-primary: var(--piko-orange-500);
	--text-on-brand: var(--white);

	/* ── Glass & veils ──────────────────────────────────────────
	   The translucent layers: nav bars and the demo dialog sit on
	   blurred glass; the parchment/ink veils are the dialog's text
	   and border tones at reduced strength. */
	/* Both bars are tinted with the page's own ground rather than
	   white/black: a foreign tint at any alpha shifts the bar off the
	   page it crosses, so the light bar read whiter than the parchment
	   and the dark one deeper than the ink. Tinting with the ground
	   means the bar is exactly the page where nothing has scrolled
	   under it, and veils (does not recolor) whatever has. It is also
	   what seats the bar against iOS Safari's chrome: Safari paints
	   the status-bar strip in the page's base background (theme-color
	   and the canvas are ignored), so only a bar that measures exactly
	   that color at rest meets the strip without a seam. */
	--glass-light: #f4efe666; /* light nav bar — --parchment at 40% */
	--glass-dark: #1a1714cc; /* dark nav bar (dark.css) — --ink-950 at 80% */
	--glass-dialog-light: #ffffff80;
	--glass-dialog-dark: #0008;
	--parchment-a82: #f4efe6d0; /* dark dialog text/border/hover fill */
	--ink-a63: #1a1714a0; /* light dialog placeholder */

	/* Parchment at half strength: the settled fragment/grid color of
	   the index composition (formerly a local --parchment override
	   scoped to .composition), and the dark dialog's placeholder. */
	--parchment-a50: #f4efe680;

	/* ── Artwork palette ────────────────────────────────────────
	   The SVG scenes' colors, read at runtime by the scene scripts
	   (pikoCards.tok and friends) — CSS itself doesn't reference
	   these. Paper tones sit deliberately close together: they mark
	   folds and panels with a hint of depth, and the cards stay
	   brighter than every page ground so documents lift off it. */
	--art-card: #f8f4e9; /* file-card paper */
	--art-card2: #f2ecdd; /* second paper tone: folds, DOC/XLS shells */
	--art-edge: #bfb399; /* hairline card outlines */
	--art-bar: #79715f; /* print bars (set-type lines) */
	--art-alert: #c1573e; /* alert accent (cards.js vocabulary) */
	--art-pend: #E8A44E; /* pending accent (cards.js vocabulary) */
	--art-well: #e9e1cd; /* image wells, table header bands */
	--art-mail: #e9e0cb; /* envelope body (unused slot, kept) */
	--art-kraft: #e9d6a8; /* manila stationery: envelope, folder front */
	--art-kraft2: #dcc48d; /* deeper manila: flap, folder back */

	/* story.js beat-3 data rows: unlit = deeper cream with muted
	   print bars, lit = near-white paper. */
	--art-row-paper: #fbf7ee;
	--art-row-cream: #e9e1cf;
	--art-row-seg: #a79c83;
	--art-row-seg-soft: #bfb49c;
	--art-row-seg-lit: #cfc5af;

	/* story.js beat-4 platform screen (the paper palette, one step
	   more composed). */
	--art-dash-shell: #eee7d7;
	--art-dash-card: #f5f0e4;
	--art-dash-panel: #e7dfcc;
	--art-dash-stroke: #c5bba5;
	--art-dash-stroke2: #dcd3bf;

	/* problem.js scenes */
	--art-glow: #e9dcbe; /* warm ambient pool over parchment */
	--art-lens-ground: #e5d8bb; /* magnifier backdrop, a half-step
	   deeper than the fold band (--paper-deep) it sits on */
	--art-miss: #8b8072; /* the lens ring while the hunt comes up empty */

	/* captives-teaser.js doc-ink pool: many sources, one warm range.
	   (Default ink and graphite come from the neutral ramp.) */
	--art-ink-sepia: #2a1d12;
	--art-ink-walnut: #241c18;
	--art-ink-graphite: var(--ink-900);
	--art-ink-aubergine: #2c1f1d;
	--art-ink-deep: #15110f;

	/* ── Shadows & blur ─────────────────────────────────────────
	   One shadow geometry for the nav bars (whisper-faint on light,
	   heavier on ink), a three-layer lift for the dialog, and the
	   single backdrop blur every glass surface shares. */
	--shadow-bar:
		0 1px 2px rgb(0 0 0 / 0.02),
		0 4px 8px rgb(0 0 0 / 0.02);
	--shadow-bar-dark:
		0 1px 2px rgb(0 0 0 / 0.2),
		0 4px 8px rgb(0 0 0 / 0.2);
	--shadow-dialog:
		0 1px 2px rgb(0 0 0 / 0.04),
		0 4px 12px rgb(0 0 0 / 0.06),
		0 24px 48px rgb(0 0 0 / 0.12);
	--glass-blur: 12px;

	/* ── Fonts ──────────────────────────────────────────────────
	   Faces are loaded via <link> in each page (an @import here
	   would serialize the font fetch behind this stylesheet).
	   index-look trial: --font-sans and --font-serif-display both
	   point at the homepage's EB Garamond (was Manrope / Playfair
	   Display), so the dark pages pick up the index serif without
	   per-rule edits. */
	--font-serif: "EB Garamond";
	--font-sans: "EB Garamond", "Adobe Garamond Pro", Garamond, Georgia, serif;
	--font-serif-display: "EB Garamond", "Adobe Garamond Pro", Garamond, Georgia, serif;
	--font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;

	/* ── Type scale ─────────────────────────────────────────────
	   A quarter-octave modular scale: each size is the previous
	   × ⁴√2 (≈1.19), rounded to tenths — a rounding that is exactly
	   closed under doubling, so every fourth step is ×2 (1.2→2.4,
	   1.4→2.8, 1.7→3.4, 2→4, 4→8). The full ladder:
	   1, 1.2, 1.4, 1.7, 2, 2.4, 2.8, 3.4, 4, 4.8, 5.6, 6.8, 8.
	   Fluid sizes clamp() between two rungs; the vw slope is a free
	   tuning parameter, not a size. Line-heights stay with their
	   rules (contextual): unitless in steps of 0.1, rem leading on
	   the spacing ladder. The root scale is html { font-size:
	   1.05rem } in style.css — the unit calibration every rem keys
	   off, and the one length outside the system. */
	/* Index hero pair: one clamp halved, so the deck stays exactly
	   half the hero at every width. Slopes converge at the 1600px
	   design width (1.05 × rem, as with --gutter); both floors bind
	   together at 960px, where the hero is still an 80px display. */
	--text-hero: clamp(4.8rem, 8.4vw, 8rem); /* index hero h1 */
	--text-deck: clamp(2.4rem, 4.2vw, 4rem); /* index hero h2 */
	--text-display: clamp(2.4rem, 4.6vw, 4rem); /* dark pages' display line */
	--text-display-quiet: clamp(2rem, 3.4vw, 2.8rem); /* about-us (a full sentence) */
	--text-heading: 2.4rem; /* section/step headings, usually accent orange */
	--text-lede: 1.7rem; /* ledes and supporting display copy */
	--text-body: 1.4rem; /* body copy beside art (~45ch at the measure) */
	/* One rung down, for body copy that shares a phone screen with
	   artwork: the scroll stories' steps have to fit between the scene
	   and the fold, and 1.4rem on a 390px screen is a desktop measure's
	   size in a third of its width. */
	--text-body-mobile: 1.2rem;
	/* CTA headline. The cap is the UA's 2em under the root
	   calibration (the "default-scale h1" the CTAs always used),
	   kept exact for identity at the design width. The 3.5vw slope
	   engages below ~1008px and shrinks the line just faster than
	   the gutter-bounded box narrows (text 0.71 × viewport vs the
	   box's 0.748), so the longest CTA line — the product page's,
	   719px at full size — stays on one line down to the mobile
	   threshold. The floor (the lede size) binds below ~815px and
	   lets the line wrap — two centered lines at display size beat
	   the old sub-body floor's one shrinking line on phones. */
	--text-cta: clamp(1.7rem, 3.5vw, 2.1rem);
	--text-control: 1.2rem; /* buttons, dialog inputs */
	--text-kicker: 1rem; /* uppercase eyebrows */
	--tracking-kicker: 0.2em;

	/* ── Spacing ────────────────────────────────────────────────
	   THE QUARTER GRID — the site's sizing standard. Every CSS
	   length is a multiple of 0.25rem, and spacing (margins,
	   paddings, gaps, strokes, offsets, radii) comes from the
	   doubling ladder below — {1, 1.5} × 2ⁿ quarters, each rung
	   1.33–1.5× the last. One-off distances in page CSS draw from
	   the same rungs: a raw length off the ladder is a bug, not a
	   choice. Content blocks (measures, art caps, column widths)
	   sit on a coarser stride — multiples of 4rem — with derived
	   sizes written as calc() of their parts. Standalone viewport
	   lengths are multiples of 5vh/5vw, layout percentages
	   multiples of 5%; clamp() endpoints obey the ladders, slopes
	   are free. Exempt: the 1px/2px line language, effects
	   (shadows, blurs, mask feathers), artwork-space values
	   (viewBox geometry, scene overlays), and JS-owned
	   placeholders (the story's 640vh scroll length). */
	--space-025: 0.25rem;
	--space-05: 0.5rem;
	--space-075: 0.75rem;
	--space-1: 1rem;
	--space-15: 1.5rem;
	--space-2: 2rem;
	--space-3: 3rem;
	--space-4: 4rem;
	--space-6: 6rem;
	--space-8: 8rem;
	--space-12: 12rem;

	/* The structural constants, on the ladder's rungs.
	   Fluid rungs share one convergence rule: the vw slope is
	   1.05 × the rem value (the root calibration), so every clamp
	   reaches its full size exactly at the 1600px design width —
	   identical from there up, proportional below. */
	/* The side gutter: 12rem from the design width up; below it the
	   fixed gutter would eat 40% of a 1000px window. */
	--gutter: clamp(var(--space-4), 12.6vw, var(--space-12));
	--gutter-mobile: var(--space-15); /* small screens, and the centered heroes' sides */
	--nav-height: var(--space-6);
	--logo-cap: var(--space-4);
	--stroke-section: var(--space-8); /* index sections' vertical stroke */
	--stroke-band: var(--space-6); /* lighter stroke: problem rows, team band */
	--stroke-cta: var(--space-4);
	/* One hero/overture stroke, top and bottom (the old top/bottom
	   pair differed by 4px — sub-perceptual, unified). The 7vh slope
	   governs between the rungs on all common desktop heights. */
	--stroke-hero: clamp(var(--space-2), 7vh, var(--space-6));
	--stroke-mobile: var(--space-3); /* stacked-column stroke on small screens */
	/* Index copy-to-art column gap: 8rem from the design width up
	   (slope 1.05 × rem again), proportional below. */
	--gap-columns: clamp(var(--space-3), 8.4vw, var(--space-8));
	/* Dark pages' text-to-art distance; converges to --gap-columns
	   at its widest, so the spread meets the index gap. */
	--gap-spread: clamp(var(--space-3), 7vw, var(--space-8));
	--gap-copy: var(--space-1); /* the .copy stacks' rhythm, site-wide */
	--gap-step: var(--space-075); /* tight title-to-body gap in step blocks */
	--measure: 32rem; /* the reading measure: ledes, rails, prose */
	--measure-wide: 40rem; /* the team band's centered paragraph */

	/* ── Shape & motion ─────────────────────────────────────────
	   1px hairline / 2px emphasis is the site's line language:
	   hairlines rule and frame; emphasis borders buttons and
	   underlines (device-px by design — exempt from the grid). */
	--hairline: 1px;
	--emphasis: 2px;
	--radius: var(--space-025); /* buttons, portraits — the grid unit */
	--radius-dialog: var(--space-1);
	--radius-pill: 999px; /* idiomatic full-round; exempt */
	--ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
	--duration-base: 180ms;
	--duration-ui: 0.25s; /* hover transitions: buttons, nav underlines */
	--duration-dialog: 0.5s; /* the demo dialog's fade */
}

/* Breakpoints cannot live in custom properties (media queries can't
   read var()). The site's mobile threshold is 900px, everywhere —
   the sizing pass folded product.css's 880px drift into it. */

/* ── Mobile overrides ───────────────────────────────────────────
   Below the threshold the index hero pair re-clamps (still one clamp
   halved, deck = hero / 2). The cap is the desktop floor, so type is
   continuous at 900px and holds full size down to ~520px; the slope
   keeps the longest line ("standardized,") ~10% inside the
   --gutter-mobile box at every phone width, and the floor only binds
   below ~300px. Deliberately not on the desktop convergence rule
   (slope = 1.05 × rem): converging at 900px would pin phones to the
   floor.

   The closing band and its run-up are a pair down here. The CTA was
   the last band still holding its desktop 4rem, which made the page's
   closing statement its tallest-padded one — 46% of the section's
   height on a 390px phone was padding. It now sits a rung BELOW the
   stroke every other band takes (--stroke-mobile: the problem rows,
   the story and team bands), and the band that leads into it takes a
   rung above: the same breath before the closing statement, moved out
   of the band and onto the page, so the CTA reads as tall as its
   neighbours instead of as the page's roomiest section. Redefining
   the token rather than the four CTAs' padding rules keeps the
   dialects in step and sidesteps the cascade: all three page sheets
   declare that padding after style.css at equal specificity. The
   run-up is a token for the same reason in reverse — the four last
   bands are page-specific boxes, and only a shared value keeps their
   feet identical.

   The bar comes down a rung with them. Its desktop 6rem is a band a
   phone pays for on every screen — fixed on the light pages, sticky
   on the dark ones, and subtracted from every 100svh hero — so down
   here it takes 4rem and the mark 3rem, which lands the logo at
   exactly the hamburger's box height: below the threshold the bar
   carries nothing but those two, one at each end, and they now read
   as a matched pair. Everything keyed to --nav-height (the sheet's
   anchor, the heroes, the story's pin) follows on its own. */
@media (max-width: 900px) {
	:root {
		--text-hero: clamp(2.8rem, 15.5vw, 4.8rem);
		--text-deck: clamp(1.4rem, 7.75vw, 2.4rem);
		--stroke-cta: var(--space-2);
		--stroke-cta-lead: var(--space-4); /* the last band's foot */
		--nav-height: var(--space-4);
		--logo-cap: var(--space-3);
	}
}
