/* ==========================================================================
   ESSOR BUSINESS HUB — DESIGN TOKENS
   The single source of truth for every colour, type, spacing, radius,
   shadow and motion value used across the site.

   This file is linked by every real page (not the dead draft variants).
   No page may define its own :root block or hardcode a value this file
   already provides. See /docs/BRAND-GUIDELINE.md for the human-readable
   version of this system, and /CLAUDE.md for the rule that keeps this
   file authoritative.

   Canonical source: homepage-established-v5.html, confirmed 2026-09-18 as
   the most recently evolved page. Where other real pages had drifted from
   it (stale --t-h2, old --header-h/--cut, a warm-cream variant on three
   pages), this file adopts the homepage's values and the drifted pages are
   corrected to match — see BRAND-GUIDELINE.md "Resolved inconsistencies".
   ========================================================================== */

:root{
  /* ---- Type families ------------------------------------------------------
     Added 2026-09-20 on Odri's decision: Poppins is the one display face
     site-wide, wordmark included; the previous display face is retired everywhere.
     Until today no page referenced a family token — each page hardcoded the
     family names, which is how the homepage drifted onto Poppins through a
     page-local @font-face alias while the other eight pages stayed on the
     old face, unnoticed for days. Every font-family in a live page now
     resolves to one of these two, and audit-brand-consistency.sh check 6
     fails on any literal family name or any page-local @font-face. Each
     page's Google Fonts <link> loads Poppins 600/700/800 and Schibsted
     Grotesk 400-700 (+italic); the fallbacks below cover the gap while they
     load. */
  --font-display:"Poppins",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-body:"Schibsted Grotesk",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* ---- Brand colour ---------------------------------------------------- */
  --violet:#5B21B6; --violet-deep:#2B0876;
  --orange:#FF7A1A; --orange-hi:#FFA24D; --orange-deep:#F2600A;
  --orange-grad:linear-gradient(135deg,var(--orange-hi) 0%,var(--orange) 55%,var(--orange-deep) 100%);
  /* magenta: midpoint sampled from the real logomark orb (violet -> magenta -> orange sweep).
     Accent-only — never a flat fill or text colour on its own, only as an ingredient in
     --orb-grad wherever the site borrows the logo's orb motif (badges, dots, icon fills). */
  --magenta:#D6209E;
  --orb-grad:linear-gradient(135deg,var(--violet) 0%,var(--magenta) 52%,var(--orange) 100%);

  /* ---- Title accent -----------------------------------------------------------
     The one accent word in every promoted section title and in the hero H1.
     2026-09-20: tried violet-on-cream / magenta-on-dark ("B") for an hour; Odri:
     "the color of the header is now all random everywhere", so the accent is
     the orange gradient on every field again, and the BUTTONS moved to violet
     instead (see --btn-grad) so orange reads as brand accent and violet as
     action. One pair, same everywhere; pages must not override it per field. */
  --accent-a:var(--orange-hi); --accent-b:var(--orange-deep); --accent-line:var(--orange);
  /* ---- Button fill (2026-09-20, Odri: "make the buttons purple") --------------
     Every .btn is violet with cream type; the flat nav/hero/mobile skins use
     --btn-flat / --btn-flat-hover. Orange is no longer a button colour. */
  --btn-grad:linear-gradient(135deg,var(--violet) 0%,var(--violet-deep) 100%);
  --btn-flat:var(--violet); --btn-flat-hover:var(--violet-deep); --btn-ink:var(--cream);
  /* On a dark or violet field a violet button disappears (Odri, 2026-09-20: "the button on purple
     background must convert to white"): every .btn inside a section that is not .cream-field
     (the chapters, Stack, Testimonials, Build It In 10's dark sections) uses this skin instead. */
  --btn-on-dark:var(--cream); --btn-on-dark-ink:var(--violet-deep);

  /* ---- Neutrals ---------------------------------------------------------- */
  --ink:#0F0B1A; --ink-2:#1B1430; --cream:#FFFFFF;

  /* ---- Category accents ---------------------------------------------------
     The 8 service categories (Sales, Marketing, Finance, Projects,
     Collaboration, Operations, Support, Apps) each get one fixed accent,
     used on the homepage's service rack tabs. Originally 6 of the 8 had
     their own distinct hue (green/blue/pink/teal/red/indigo) alongside the
     2 brand colours — audited 2026-09-18 as "deliberate, not stray
     one-offs." Revisited 2026-09-20: with all 8 visible in the same list,
     6 extra hues next to the 2 brand colours read as busy/off-brand next to
     the rest of the page's disciplined violet/orange language, especially
     once the page stopped showing them all at rest (see BRAND-GUIDELINE.md
     services-tabs note). 7 of the 8 now alias to the brand pair, alternating
     — no category lost its own identity slot (still 8 distinct token names,
     still swappable independently), it just draws from 2 colours instead
     of 8. --cat-support is the one exception, kept on its own literal red:
     --error aliases to it (see below) for the booking page's real
     validation/API-failure text, and that semantic red must not silently
     become brand violet just because this token also feeds a tab colour. */
  --cat-sales:var(--violet);
  --cat-marketing:var(--orange);
  --cat-finance:var(--violet);
  --cat-projects:var(--orange);
  --cat-collab:var(--violet);
  --cat-ops:var(--orange);
  --cat-support:#DC2626;
  --cat-apps:var(--orange);
  --cat-support-wash:rgba(220,38,38,.12);

  /* ---- Signature wheel palette (2026-09-24) -----------------------------------
     The six-part "where is your business stuck" wheel (resources.html hero, its mini
     copy in How it works, and the resources-sales.html hero) is the one object on the
     site where six hues sit together on purpose: it is the site's signature visual,
     and each part keeps its colour everywhere the wheel appears. Jewel tones in one
     band, anchored on the two brand hues that already exist (Sales = --violet, the
     live part; Marketing = --magenta, the logomark's own midpoint): ~70% saturation,
     31 to 48% lightness, every one 4.6:1 or better under cream labels (checked, not
     assumed). Orange stays the "you are here" marker and is never a wedge fill;
     --error red is deliberately not in the family (raspberry sits at hue 338, a berry,
     not a warning). These are NOT the --cat-* service-rack accents above, which
     alternate violet/orange for the homepage tabs and stay untouched. Each -deep
     partner is the same hue sunk toward --ink, the hub-side end of the wedge's tonal
     gradient (Sales reuses --violet-deep so it matches --btn-grad exactly). */
  --wheel-idea:#187D91;              /* 01 Business idea: teal */
  --wheel-marketing:var(--magenta);  /* 02 Marketing: magenta */
  --wheel-sales:var(--violet);       /* 03 Sales: violet, the live one */
  --wheel-operations:#234FC7;        /* 04 Operations: sapphire */
  --wheel-financials:#18864F;        /* 05 Financials: emerald */
  --wheel-admin:#B31E55;             /* 06 Admin: raspberry */
  --wheel-idea-deep:color-mix(in srgb,var(--wheel-idea) 58%,var(--ink));
  --wheel-marketing-deep:color-mix(in srgb,var(--wheel-marketing) 58%,var(--ink));
  --wheel-sales-deep:var(--violet-deep);
  --wheel-operations-deep:color-mix(in srgb,var(--wheel-operations) 58%,var(--ink));
  --wheel-financials-deep:color-mix(in srgb,var(--wheel-financials) 58%,var(--ink));
  --wheel-admin-deep:color-mix(in srgb,var(--wheel-admin) 58%,var(--ink));

  /* ---- Status ---------------------------------------------------------
     One error-state colour, added 2026-09-18 for the booking page's slot
     API failure/validation messages — the site's first real error-copy
     need. Reuses --cat-support rather than minting a new red: same red,
     named for its actual job here instead of the category system.
     2026-09-20: kept --cat-support on its own literal red (see above) when
     the other 7 category accents were consolidated to violet/orange, so
     this alias still resolves to genuine error-red, not brand violet. */
  --error:var(--cat-support);

  /* ---- Contextual aliases (hero-styled treatments reused outside .hero) - */
  --hero-gold:var(--orange); --hero-gold-deep:var(--orange-deep); --hero-ink:var(--violet-deep);

  /* ---- Opacity ramps ------------------------------------------------------
     Two families: white-based (for text/lines on the dark ink background)
     and ink-based (for text/lines on cream/light surfaces, inside
     .cream-field). Each has a matching washed/soft/strong step for the two
     brand accents, replacing ~40 ad hoc rgba() alphas found hardcoded
     across the site (violet alone had 14+ distinct alphas). */
  --mute:rgba(255,255,255,.66); --line:rgba(255,255,255,.28); --line-soft:rgba(255,255,255,.14);
  --ghost:rgba(255,255,255,.32);
  --ink-mute:rgba(15,11,26,.64); --ink-line:rgba(15,11,26,.22); --ink-ghost:rgba(15,11,26,.2);
  --ink-faint:rgba(15,11,26,.08);
  --violet-wash:rgba(91,33,182,.12); --violet-soft:rgba(91,33,182,.25); --violet-strong:rgba(91,33,182,.34);
  --orange-wash:rgba(255,122,26,.15);
  /* --grid-line: the one-pixel drafting-grid texture drawn over every dark field (hero, each of
     the three Pain / Pivot / Built-for chapter blocks, About's violet block). Added 2026-09-19: the
     texture had been hand-rolled as rgba(255,255,255,.035)/.045 in five places and sits well below
     --line-soft (.14), so it is a genuinely distinct step, not a near-duplicate. Texture only —
     never a border or text colour. */
  --grid-line:rgba(255,255,255,.04);

  /* ---- Type scale ---------------------------------------------------------
     12 named steps. --t-hero is new (2026-09-18): the hero H1 had its own
     literal clamp() distinct from every other step; promoted to a token
     rather than merged into --t-h2, to avoid changing its rendered size.
     Responsive override lives on the token itself (see @media below),
     following the same pattern already used for the rest of the scale.
     --t-title is new (2026-09-20): the homepage's promoted section titles
     (the two-word eyebrow that became each section's headline — "Sound
     familiar?", "What we do", "Start here"...) first shipped at --t-h2 and
     the owner called 64px too big: it sat within 6px of the 70px hero H1, so
     the hero stopped being the one loudest thing on the page. The next step
     down, --t-h3 (28px), is the subtitle directly beneath it, so the title
     needs a step of its own between the two — 46px cap is ~2/3 of the hero
     and ~1.6x the subtitle, not within 10% of either neighbour. Used by the
     "eyebrow promoted" section-title rule on every live page (2026-09-20, Odri:
     the homepage's title device is the site's, not a homepage-only one). */
  --t-giant:clamp(120px,16vw,220px);
  --t-display:clamp(52px,9.5vw,152px);
  --t-hero:clamp(38px,4.8vw,70px);
  --t-h2:clamp(32px,4.6vw,64px);
  --t-title:clamp(32px,4vw,46px);
  --t-h3:28px;
  --t-lead:22px;
  --t-body:18px;
  --t-label:14px;
  --t-tiny:13px;
  --t-micro:11px;
  --t-nano:9px;

  /* ---- Font-weight roles ---------------------------------------------------
     Added 2026-09-20: audited every font-weight in the homepage (115 declarations) and found 5 raw
     literal values (400/500/600/700/800) used as raw numbers everywhere, with no token — the one gap
     left after the --t-* size scale above was fully tokenized. Not arbitrary: each value already does
     one consistent job (confirmed by reading every usage, not assumed) — --fw-heavy is the Poppins
     display face's only weight (headings, stat numbers, card titles); --fw-bold is the body
     face's bold (buttons, chips, labels, nav, inline <b>/<strong> emphasis); --fw-semibold is demoted
     subtext under a promoted eyebrow-title plus a few semi-bold inline spans; --fw-medium is small
     muted secondary/metadata text; --fw-regular is the plain reset on a couple of muted spans. Naming
     them here closes the compliance gap without changing any rendered weight — see BRAND-GUIDELINE.md
     for the per-role usage note. */
  --fw-regular:400;
  --fw-medium:500;
  --fw-semibold:600;
  --fw-bold:700;
  --fw-heavy:800;

  /* ---- Line-height & letter-spacing roles ---------------------------------
     Collapses 17 raw line-height and 21 raw letter-spacing values found
     hardcoded across the site into named roles tied to text function. */
  --lh-tight:1;      /* numerals, giant display */
  --lh-snug:1.1;      /* large display headlines */
  --lh-heading:1.2;    /* h2/h3 */
  --lh-label:1.3;      /* labels, tight copy */
  --lh-body:1.5;      /* reading paragraphs */
  --ls-tight:-.02em;    /* headings — negative tracking scales with size; this
                            is the merged mid-cluster (-.015/-.02/-.025em) */
  --ls-body:0;
  --ls-label:.08em;    /* small uppercase labels */
  --ls-wide:.1em;      /* widest eyebrow/badge treatment */

  /* ---- Spacing scale --------------------------------------------------- */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
  --gut:clamp(24px,5vw,72px);
  /* --cut: the diagonal section-cut angle — the ONE angle every section seam on the page chains with
     (see BRAND-GUIDELINE.md §4 "Section seams"). Restored site-wide on 2026-09-19 (third pass, owner's
     call) after a same-day experiment with flat seams and ink bands. A section that starts on the
     diagonal pulls itself up by margin-top:calc(-1 * var(--cut)) and clips its own top with the same
     value; the section above keeps --cut of spare bottom padding. A clip-path that uses --cut must
     always be paired with the matching negative margin. --cut-close (4.5vw) stays retired: the closing
     chains with the standard angle, mirrored. */
  --cut:3.2vw;

  /* ---- Layout ------------------------------------------------------------ */
  --max:1360px;
  --max-narrow:900px;
  --max-article:760px;
  --header-h:60px;
  /* --node: the diamond node that marks a point on a connector — the violet square rotated 45deg
     sitting on Process's dashed step connectors, and (2026-09-19) on the FAQ's vertical rail, one
     per question. Was a literal 14px on .step::after; named once it had a second user. Not on the
     --sp scale on purpose: 12 reads as a dot, 16 as a box; 14 is the size the device was tuned at. */
  --node:14px;

  /* ---- Radius ------------------------------------------------------------ */
  --r-sm:4px; --r-md:6px; --r-lg:12px; --r-xl:20px; --r-pill:999px; --r-circle:50%;

  /* ---- Elevation shadows ---------------------------------------------------
     One soft-float scale for resting cards/photos/mockups, sized to how
     "far off the page" each tier reads. Small UI badges keep their own
     bespoke shadow rather than being forced onto this scale. */
  --shadow-float-sm:0 10px 20px rgba(0,0,0,.18);
  --shadow-float-md:0 16px 30px rgba(0,0,0,.24);
  --shadow-float-lg:0 28px 54px rgba(0,0,0,.34);

  /* The layered "premium floating card" shadow recipe — inset top highlight +
     hairline border + tight contact shadow + big soft glow. Reused (not
     copy-pasted) wherever a card needs to read as premium. Two variants: one
     for cream/white cards, one for dark violet cards on a dark field. */
  --shadow-card-lift:inset 0 1px 0 rgba(255,255,255,.75),0 0 0 1px rgba(15,11,26,.08),0 1px 2px rgba(15,11,26,.16),0 10px 22px -8px rgba(15,11,26,.4),0 30px 60px -18px rgba(15,11,26,.5);
  --shadow-card-dark:inset 0 1px 0 rgba(255,255,255,.07),0 0 0 1px rgba(0,0,0,.35),0 2px 4px rgba(0,0,0,.3),0 14px 28px -10px rgba(43,8,118,.55),0 34px 64px -20px rgba(0,0,0,.6);

  /* ---- Motion -------------------------------------------------------------
     Two durations (fast interactive, medium reveal) and one named easing —
     the cubic-bezier curve already reused 8x across the file's bespoke
     hero-graphic animations. Keyframes themselves stay page-local: they're
     one-off illustrative motion, not a reusable component system. */
  --dur-fast:.18s;
  --dur-med:.3s;
  --ease-out-strong:cubic-bezier(.2,.7,.2,1);
  /* --dur-stagger: the per-row delay for a staggered list reveal, added 2026-09-18 for the mobile
     menu sheet (each row lands a beat after the one above instead of the whole list snapping in).
     Not derivable from the two durations above: --dur-fast per row would take over a second across
     seven rows. Used as calc(var(--i) * var(--dur-stagger)) on the row's transition-delay. */
  --dur-stagger:.04s;
}

@media (max-width:1100px){
  :root{ --t-hero:clamp(38px,10.4vw,64px); }
}
