/* ============================================================================
   @rainyseason/shell — DESIGN TOKENS

   The palette is nine names: three hardware neutrals (one white, two darks)
   and the six weathers (cloud = the white). Every grey is the white at an
   opacity, never a new colour. The only other colour is the race-kit pair,
   locked to labels.

   Brand layers (faces, accents, the SCENT stars): brands.css.
   Font files (@font-face): fonts.css. This file is values only.
   Sources: product/ui/shell.css + product/DESIGN.md.
   Colour values are locked — change only on explicit instruction.
   ============================================================================ */

:root {

  /* ── 1 · COLOUR ─────────────────────────────────────────────────────────
     THE STACK — nine colours, and nothing else on the site (William,
     2026-08-04): three neutrals + the six SCENT.TECH senses. Every other tone
     is one of these renamed for its job, or the white/off at an opacity —
     never a fresh swatch. */

  /* The three neutrals. */
  --vanta: #000000;   /* the ground — vanta black */
  --off:   #101010;   /* the one OFF tone — dormant hardware, unlit segments,
                         raised panels (the all-segments-off grey) */
  --white: #EFEFEF;   /* the one white — the ink, a lit segment, the cloud */

  /* The six senses — the SCENT.TECH palette, carried on the weather names.
     One sense per colour; the white above is structural, not one of the six. */
  --sun:          #014236;   /* sight */
  --hard-rain:    #3029E7;   /* intuition — rainyseason.cr's primary accent */
  --rain:         #DEFF7A;   /* taste */
  --thunder:      #046AEF;   /* sound */
  --snow:         #8B0012;   /* touch */
  --kit-hibiscus: #FF3F6B;   /* scent (a page may re-pin this to shift its scent hue) */
  --hibiscus:     var(--kit-hibiscus);

  /* THE SIX SENSES, ADDRESSABLE BY NAME (William, 2026-08-11). The palette above
     is carried on weather token names; these aliases let a colour be called by
     its SENSE — the way the senses are described — in the locked star order
     (star-order-locked). Same six values, no new colour: the six-colour lock
     holds. Reach for the sense name in new work; the weather names stay for the
     places that already read them.
        sight     #014236   ·  scent      #FF3F6B
        touch     #8B0012   ·  sound      #046AEF
        taste     #DEFF7A   ·  intuition  #3029E7  (the house accent) */
  --scent:     var(--hibiscus);    /* #FF3F6B */
  --sight:     var(--sun);         /* #014236 */
  --touch:     var(--snow);        /* #8B0012 */
  --sound:     var(--thunder);     /* #046AEF */
  --taste:     var(--rain);        /* #DEFF7A */
  --intuition: var(--hard-rain);   /* #3029E7 */

  /* The stack at work — the same nine, named for the job. */
  --g:      var(--vanta);   /* the ground */
  --ink:    var(--white);   /* the type */
  --lit:    var(--white);   /* a lit segment */
  --cloud:  var(--white);   /* the weather cloud */
  --unlit:  var(--off);     /* powered-down DSEG hardware */
  --wx-off: var(--off);     /* off weather segments / deselected card ink */
  --g-elev: var(--off);     /* raised panels + menus */

  /* THE 3D CLOUD'S OWN INK (William, 2026-08-09) — the extruded weather mark's
     cloud reads THIS, not --ink. --ink flips white↔black with the theme so text
     stays legible; the 3D cloud must NOT flip, so it is pinned to the vanta
     black in both themes. On the hero + private line stage (pinned #000, both
     origins) the dark chrome catches the studio rig on its edges — "the cloud
     is dark for sure but there's still some light hitting on it ... it just
     looks dope". The text keeps --ink (white in dark) so it never vanishes with
     the cloud. Palette-safe: this is the vanta black renamed for its job, not a
     tenth colour. */
  --wx3d-cloud: var(--vanta);

  /* THE PAGE PRIMARY — every page carries ONE primary colour from the six
     (William, 2026-08-06). The default is the house accent (hard rain); the
     per-surface map lives below the light-mode block, keyed on the
     body[data-surface] stamp nav.js writes on every page. First consumer:
     the bar clock's angel numbers (bar.css). */
  --page-primary: var(--hard-rain);

  /* THE SCENT SWEEP — the six sense colours as ONE gradient, defined once
     (William, 2026-08-08). Consumers: the stars-lit card stroke (content.css
     border-image, square cards) and rounded cards via the padding-box/
     border-box background pair (border-image ignores radius). */
  --scent-gradient: linear-gradient(135deg, var(--sun), var(--lit), var(--accent), var(--storm), var(--gold), var(--spark));

  /* The ink ladder — the white at four opacities plus two hairlines.
     NOT new colours: hierarchy comes from opacity, never grey swatches. */
  --ink-2:       rgba(239, 239, 239, 0.72);
  --ink-3:       rgba(239, 239, 239, 0.50);
  --ink-4:       rgba(239, 239, 239, 0.30);
  --line:        rgba(239, 239, 239, 0.12);
  --line-strong: rgba(239, 239, 239, 0.22);
  --line-2:      var(--line-strong);   /* the shared button (button.css) names its resting ring --line-2, as the private line does; alias it here */


  /* ── 2 · TYPOGRAPHY ─────────────────────────────────────────────────────
     Fira Code is the house voice; the other faces are brand-scoped and are
     applied by brands.css. UI copy consumes a size token — raw px is banned. */

  /* Families — names only; the files ship in fonts.css. */
  --font-code:  "Fira Code", ui-monospace, "SF Mono", Menlo, monospace;
  --font-mono:  "Fira Mono", ui-monospace, monospace;
  --font-brand: "Amarna", "Fira Code", serif;                  /* SCENT.TECH */
  --font-lcd:   "DSEG14 Classic Mini", "Fira Code", monospace; /* LCD / triathlon */
  --font:       var(--font-code);

  /* Weights — UI is 400/500 only; 500 is the house heavy. */
  --w-light:    300;
  --w-regular:  400;
  --w-medium:   500;

  /* The size ramp — the ONLY font sizes for UI copy (locked). */
  --t-tag:       8px;   /* below the eyebrow floor — the .foot-tag micro caps only (house law: footer title 14 / row 12 / tag 8) */
  --t-eyebrow:  10px;
  --t-caption:  11px;
  --t-small:    12px;
  --t-lede:     13px;
  --t-body:     14px;
  --t-label:    15px;
  --t-head:     16px;
  --t-title:    22px;
  --t-headline: 33px;
  --t-poster:   clamp(26px, 5vw, 40px);   /* full-bleed poster / section headings */
  --t-display:  clamp(22px, 3.4vw, 30px); /* quiet display — the home offer title */
  --t-hero:     clamp(22px, 5vw, 32px);   /* THE hero + section headline — the one true title clamp (was hand-typed 4×) */
  --t-path:     clamp(16px, 4vw, 22px);   /* file-path headings: home sections + .rs-path — one ramp step down from 22–26 (William, 2026-08-05) */
  --t-card:     clamp(16px, 4.2vw, 22px); /* card title — the file-path style at card scale */
  --t-card-sm:  clamp(14px, 3.6vw, 19px); /* card title, one step down (dense itinerary cards) */

  /* Heading roles — use the element; base.css maps these. */
  --t-h1: var(--t-title);
  --t-h2: var(--t-head);
  --t-h3: var(--t-lede);
  --t-h4: var(--t-eyebrow);

  /* Line-heights. */
  --lh-solid:   1;
  --lh-display: 1.15;
  --lh-title:   1.25;
  --lh-head:    1.3;
  --lh-body:    1.55;
  --lh-prose:   1.7;      /* reading-paragraph leading — the ONE prose line-height (was 1.6/1.65/1.7/1.78 hand-typed) */

  /* Tracking — the ONE ladder every letter-spacing snaps to; uppercase needs
     air, display wants tightening. Ten rungs, monotonic. Nothing off-ramp:
     the only non-token values allowed are 0 / normal / inherit (the null). */
  --track-tighter: -0.04em;  /* large display headings — the tightest */
  --track-tight:   -0.02em;  /* h1 + medium headings */
  --track-micro:    0.02em;  /* numerals, mono readouts, small caption body — the gentlest positive */
  --track-wordmark: 0.04em;
  --track-title:    0.06em;  /* the house heading tracking — the single most-repeated value */
  --track-head:     0.08em;
  --track-label:    0.1em;
  --track-caps:     0.12em;
  --track-eyebrow:  0.14em;
  --track-wide:     0.18em;  /* section eyebrows, LCD labels — the widest micro-caps */
  --track-otp:      0.55em;  /* the 2FA code field only — six digit SLOTS read one by one, not text */

  /* Word-spacing — the page runs tight between words. */
  --word-space:      -0.18em;
  --word-space-head: -0.28em;


  /* ── 3 · SPACE — the eights ─────────────────────────────────────────────
     (xs 6px is the one exception, for tight caps rows.) */
  --space-xs:  6px;
  --space-sm:  8px;
  --space-md:  12px;
  --space-lg:  16px;
  --space-xl:  24px;
  --space-2xl: 32px;
  --space-3xl: 40px;
  --space-4xl: 48px;


  /* ── 4 · RADIUS — one radius everywhere ─────────────────────────────────*/
  --r: 3.33pt;


  /* ── 5 · BORDER — 1px hairlines only ────────────────────────────────────*/
  --border:        1px solid var(--line);
  --border-strong: 1px solid var(--line-strong);


  /* ── 6 · LAYOUT ─────────────────────────────────────────────────────────*/
  --bar-wash:    rgba(241, 241, 241, 0.02); /* unused; kept for restore */
  --bar-surface: var(--g);                  /* chrome sits flush on the ground */
  --frame:            1280px;  /* the app-wide frame; past it, base ground */
  --content:          820px;   /* stage content measure */
  --rail:             22px;    /* the one left rail — glyph, menu and content all align to it */
  --bar-h:            60px;    /* the fixed menu bar (DESIGN.md; confirm vs 64) */
  --section-gap:      40px;
  --hit:              44px;    /* minimum touch target */
  --btn-h:            var(--hit); /* the ONE control height = the Apple minimum touch target, 44px (William, 2026-08-07); buttons + inputs */
  --curl-h:           36px;    /* the curl bar rides slimmer than a button — its own sleeker strip height (William, 2026-07-29) */
  --curl-icon:        14px;    /* the curl bar's copy glyph — sized at the token (one source → every curl bar), the bar itself stays --curl-h; matches the site's other copy icons. 16 → 20 → 24 → 22 → 16 → 14 (William) */
  --btn-stroke:       var(--line-strong); /* the default button resting ring everywhere — the white hairline at strong opacity (was a #272033 swatch, now on the nine-colour stack; William, 2026-08-04) */
  --wx3d-h:           min(38vh, 320px); /* stage 3D mark mount height — matched to the private line gate (.gate-3d) */
  --wx3d-seat:        48px;   /* THE ONE CLOUD SEAT (William, 2026-08-06): every mount's top margin — hero pad 24 + 48 = 72 = bar 64 + 8; fixed on every hero at every viewport, both origins */
  --hero-lift:        55px;    /* see next line for the 3D mark's own seat */
  --btn-symbol-rest:  33%;     /* THE resting opacity for everything on a button: stroke, label, symbol, and the curl bar with it (William, 2026-08-05: one knob, 15 read too low) */
  --hero-follow-gap:  96px;    /* THE LOCKED SEAT of the message that follows the hero body: the CHIP LINE (Costa Rica / Serving local and global clients) sits exactly this far above the button stack on every hero at every height; a dateline hangs 8px below it INSIDE the gap (re-seated lower from 135, William 2026-08-05 late: 135 read too high) */
  --wx3d-drop:        44px;    /* the cloud's own drop below the shared lift (raised from 22: clouds down another 22px, William 2026-08-06) */
  --hero-title-drop:  22px;    /* the hero's TEXT pieces (word + body copy) sit this much below the shared lift; buttons hold the floor, the cloud has its own drop (William, 2026-08-05) */    /* the 3D cloud sits this much BELOW the other floating hero pieces (William, 2026-08-05): title, eyebrow and buttons keep the full --hero-lift */    /* the hero's floating pieces — the 3D mark and the /path title — ride this much above their natural seats (William, 2026-08-05, raised from 33); both origins read this one value */
  --hero-cluster-w:   430px;   /* the hero copy cluster: never wider than a mobile viewport, on every hero (William, 2026-08-05) */
  --hero-copy-gap:    12px;    /* the /path word to the first line of hero copy — tight and identical on every hero (William, 2026-08-05) */
  /* THE button width + rhythm — the private line gate geometry (William,
     2026-07-29): its step column is max-width 460px with 20px side padding,
     so every button and curl bar runs full-width capped at 420px, stacked
     12px apart, landing on a 50px floor (21px pad + 29px reserve). */
  --btn-w-full:       420px;   /* the private line button width — the ONE width everywhere */
  --btn-w-half:       calc((var(--btn-w-full) - var(--space-md)) / 2);  /* half — two per row + a --space-md gap */
  --btn-gap:          12px;    /* the private line gate-step row gap */
  --btn-floor:        16px;    /* stage-hero bottom pad — the private line floor: the primary button is the LAST row of every gate step and sits 16px off the frame base (its 2026-08-05 law), so CTA rows align across origins */
  /* Section rhythm — the /network vertical scale, shared across content sections. */
  --rhythm-band:      clamp(64px, 13vh, 128px);   /* between sub-sections */
  --rhythm-lead:      clamp(32px, 6vh, 60px);     /* a title/head down to its content */
  --section-pad:      clamp(32px, 8vh, 88px) clamp(24px, 5vw, 48px) clamp(48px, 10vh, 96px);
  --section-gap:      clamp(56px, 8vh, 112px);   /* generous air BETWEEN sibling sections, on top of each section's own pad (William, 2026-07-31) */
  --prose-gap:        var(--space-lg);            /* the one gap between body paragraphs */
  /* Card air — one generous, responsive padding for every card, plus the inner
     gap between a card's title, body and CTA. The card-scale echo of
     --section-pad, so spacing inside cards stays uniform and roomy. */
  --card-pad:         clamp(20px, 3vw, 32px);
  --card-gap:         clamp(14px, 2vw, 20px);
  /* THE card width — every card in the app (products, individuals,
     experiences, networks) caps at this one trading-card measure
     (William, 2026-07-29). Rails clamp DOWN on phones, never up. */
  --card-w:           360px;
  /* THE section content column — a mobile-viewport width. Governs BOTH the
     justified body copy AND every section image/diagram (maps, art, glyphs,
     placeholders), so text and media line up in one measure on every screen.
     Trading cards keep their own narrower --card-w. */
  --read-w:           430px;
  /* THE card rail. A card uses the full available width on a phone and stops at
     the shared card measure on wider screens. Content may make it taller. */
  --rail-gap:         var(--space-xl);
  --rail-basis:       min(100%, var(--card-w));
  --card-min-h:       min(500px, calc(100vh - var(--bar-h) - (2 * var(--space-xl))));
  /* The overlapping PFP-badge law — ONE set of numbers for every card's
     weather-mark badge (was copy-pasted across shell/home/team). A card body's
     top padding clears the overhang: calc(var(--pfp-overhang) + var(--space-md)). */
  --pfp-badge:    104px;   /* the round PFP badge diameter */
  --pfp-overhang:  52px;   /* how far it straddles below the photo edge (badge bottom: -52) */
  --pfp-glyph:     62px;   /* the weather mark inside the badge */
  --pfp-ring:       4px;   /* the badge's ground-coloured ring */
  --wx-glyph:      52px;   /* THE weather-mark render size — menu-bar glyph, title lockup + home card badges all read it, so every weather mark on the page is one size */
  --bar-baseline:  20px;   /* the menu bar's shared ink baseline, measured UP from the bar's bottom edge. It IS the cloud's bottom edge (64px bar, 52px glyph centred, cloud ink bottom at 44 — measured, 2026-08-05); the DSEG readouts sit their digit baseline on this line */
  --card-photo:  16 / 10;  /* the one image plate ratio for every content card */
  --photo-scrim:    0.28;  /* THE PHOTOGRAPH DRESS (cards.css): the flat black wash over a real photo — drops it under the soft ceiling (William, 2026-08-06) */
  --photo-vignette: 0.55;  /* THE PHOTOGRAPH DRESS: edge-vignette strength — the photo recedes into the vanta ground like the globe and the map */
  --photo-grain:    0.06;  /* THE PHOTOGRAPH DRESS: film-grain opacity — the hero wash's own strength (William, 2026-08-06) */
  /* THE ONE GRAIN — the film-noise tile the hero wash and the photograph
     dress share (was inlined in hero.css; single-sourced 2026-08-06). */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* Breakpoints — the reference values media queries use. */
  --bp-sm: 560px;
  --bp-md: 760px;   /* the mobile→desktop threshold */
  --bp-lg: 900px;


  /* ── 7 · MOTION — one clock for the family ──────────────────────────────*/
  --dur-instant: 80ms;
  --dur-fast:    140ms;
  --dur-base:    200ms;
  --dur-slow:    460ms;   /* the torch's one clock */

  --ease:          cubic-bezier(0.22, 1, 0.36, 1);  /* the signature expo-out */
  --ease-out:      cubic-bezier(0.33, 1, 0.68, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);

  /* Scroll reveal — the one enter animation (mountReveal, nav.js). Rides --dur-slow + --ease. */
  --reveal-rise:     40px;    /* how far a section rises as it settles in */
  --reveal-stagger:  90ms;    /* delay step between staggered rail children */

  /* The story — word-level reading reveal (.rs-story: content.css + mountStory).
     The scroll is the clock; these set where on a block's traverse of the
     viewport the reading edge wakes, how far it walks, and how each word inks.
     Unitless percents of the traverse — both engine paths (the native scroll
     timeline and the driven fallback) read these same numbers. */
  --story-dim:   0.3;   /* unread words rest here — the --ink-4 rung of the block's own ink */
  --story-start: 10;    /* the first word inks this far into the block's traverse */
  --story-sweep: 32;    /* the edge walks the whole block across this much traverse */
  --story-word:  8;     /* one word's own fade window as the edge passes */

  /* The focus — block-level ink reveal (.rs-focus: content.css + mountFocus).
     ONE law for all copy: a text block rests dim and inks up to its target as
     it crosses the viewport, brightest while centred, easing back as it leaves
     — focus follows the scroll. The target carries the hierarchy: titles ink to
     --focus-title, body to --focus-body (× the block's own ink), so nothing is
     ever full white (soft-ink law). Both engine paths read these numbers. */
  --focus-dim:   0.4;   /* out-of-band rest — recessed but still legible */
  --focus-body:  0.86;  /* body copy's in-focus target */
  --focus-title: 1;     /* titles' in-focus target — the brighter anchor */


  /* ── 8 · Z-INDEX — a short named ladder ─────────────────────────────────*/
  --z-base:   1;
  --z-raised: 30;
  --z-menu:   40;
  --z-bar:    60;
  --z-top:    100;
}

/* Small viewport units account for mobile browser chrome. Browsers without
   svh keep the vh value above. */
@supports (height: 100svh) {
  :root {
    --card-min-h: min(500px, calc(100svh - var(--bar-h) - (2 * var(--space-xl))));
  }
}


/* ── LIGHT MODE ─────────────────────────────────────────────────────────────
   Toggled by .is-light on <html>. The ground and ink flip; in light every
   dark tone goes full black — hierarchy from size and weight alone. */
html.is-light {
  --g:           #EFEFEF;
  --ink:         #000000;
  --ink-2:       #000000;
  --ink-3:       #000000;
  --ink-4:       #000000;
  --line:        #000000;
  --line-strong: #000000;
  --off:         #C8C8C8;   /* the OFF tone mirrored onto the light ground */
  --unlit:       var(--off);
  --lit:         #000000;
  --cloud:       var(--ink);
  --g-elev:      var(--off);
  --bar-wash:    rgba(0, 0, 0, 0.03);
  --bar-surface: var(--g);
}


/* ── PAGE PRIMARY — the per-surface map ─────────────────────────────────────
   Every page has one primary colour (William, 2026-08-06). Surfaces not named
   here read the :root default (hard rain, the house accent). A brand's
   surfaces follow its locked slot (2026-08-04): scent · hibiscus,
   greater + triathlon · sun, coffee · rain. nav.js wire() stamps
   data-surface on <body>; add a row here to give a new surface its colour. */
body[data-surface="retreat"],
body[data-surface="netScent"]     { --page-primary: var(--hibiscus); } /* SCENT.TECH */
body[data-surface="coffee"]       { --page-primary: var(--rain); }     /* Community Coffee */
body[data-surface="endurance"],
body[data-surface="netTriathlon"],
body[data-surface="netGreater"]   { --page-primary: var(--sun); }      /* triathlon.tech + greater */


/* ── MIGRATION SHIMS — the old names, so nothing breaks while pages move to
   the weather names. DELETE this block once the migration lands. */
:root {
  --accent: var(--hard-rain);
  --storm:  var(--rain);
  --spark:  var(--thunder);
  --gold:   var(--snow);
}
