/* ==========================================================================
   Korjin — design tokens
   --------------------------------------------------------------------------
   Two layers, and the distinction matters:

   1. BRAND CONSTANTS (--korjin-*) are the four colours from the brand guide.
      They never change. Do not use them directly in components.

   2. SEMANTIC TOKENS describe a ROLE (ground, ink, rule, accent-surface).
      Components only ever reference these. Because both brand directions
      resolve the same role names, every section works in both without edits.

   The ground direction is set by data-ground="cream" | "dark" on <html>.
   This is a BRAND DIRECTION toggle for client review, not an OS dark mode —
   it is an explicit, persisted choice and deliberately ignores
   prefers-color-scheme, so a demo never flips underneath you.

   RULE: never write a literal colour in a component stylesheet. One hex in
   the wrong place and the toggle stops resolving on that element.
   ========================================================================== */

:root {
  /* -- brand constants — from Korjin_Final.pdf p13 ------------------------ */
  --korjin-cream: #f6ecda;
  --korjin-black: #222222;
  --korjin-oxblood: #752d2c;
  --korjin-gold: #c5a15f;

  /* -- type ---------------------------------------------------------------
     Displace 2.0 (display) and Brooklyn (body) are licensed and not bundled.
     Marcellus and Jost stand in: inscriptional sharpness, geometric humanist. */
  --font-display: "Marcellus", "Cormorant Garamond", Georgia, serif;
  --font-body: "Jost", "Avenir Next", "Segoe UI", system-ui, sans-serif;

  /* ONE KNOB FOR THE WHOLE SITE.
     Every size below — and every rem in every component sheet — is expressed
     against the root, and base.css sets the root to `--type-scale * 100%`.
     So this multiplier reproduces what browser zoom does to type, without
     touching layout widths. 1 = the original 15px body, which read as too
     small in a real browser; 1.2 is the client's own 120% zoom, adopted as
     the default. Change this number, not the steps below.
     Verified clean (no overflow, 14 pages × both grounds × 390/768/1440) up
     to 1.2. CEILING IS 1.25 — there the shop page's .builder__panel overflows
     a 390px viewport. Past 1.2, fix that panel first.
     Because the root is a PERCENTAGE, a visitor who has raised their browser's
     default font size still gets that on top — an absolute px root would
     silently override them. */
  --type-scale: 1.2;

  /* px values in the comments are at --type-scale: 1.2 on a 16px default. */
  --step--1: 0.8125rem; /* 15.6px — captions, fine print */
  --step-0: 0.9375rem; /*  18px   — body (was 15px at scale 1) */
  --step-1: 1.0625rem; /*  20.4px — lead paragraphs */
  --step-2: clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);
  --step-3: clamp(1.5rem, 1.25rem + 1.2vw, 2rem);
  --step-4: clamp(1.875rem, 1.4rem + 2.2vw, 2.875rem);
  --step-5: clamp(2.25rem, 1.5rem + 3.6vw, 4rem);
  --step-6: clamp(3rem, 1.2rem + 7.6vw, 7.25rem);

  /* Micro-type floor. These two carry every tracked uppercase label on the
     site. They exist because ~26 components had hardcoded 0.5625–0.625rem
     (9–10px) labels — small enough that 0.24em tracking was doing the work
     legibility should have been. Nothing renders below --label-xs. */
  --label-xs: 0.6875rem; /* 13.2px — badges, meta rows, table heads */
  --label-size: 0.75rem; /* 14.4px — section eyebrows, nav, buttons */
  --label-track: 0.24em;

  --leading-tight: 1.04;
  --leading-snug: 1.18;
  --leading-body: 1.65;

  /* -- space --------------------------------------------------------------- */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;
  --sp-10: 8rem;

  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --section-y: clamp(3.5rem, 8vw, 7rem);
  --measure: 62ch;
  --max-w: 1440px;

  /* -- motion -------------------------------------------------------------- */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 180ms;
  --dur: 320ms;
  --dur-slow: 620ms;

  /* Raised from 68px when the bar took the root mark + wordmark lockup rather
     than the wordmark alone. Every sticky offset on the site is derived from
     this, so the sub-navs and pinned panels follow on their own. */
  /* Reduced from 84px (client request, 10 Sep). Every sticky offset on the
     site derives from this token, so the sub-navs and pinned panels follow on
     their own — no other value needs touching. */
  --header-h: 72px;
  /* Announcement height, reserved before <korjin-header> hydrates. Without
     this the whole page shifts down on first paint (measured CLS 0.247).
     Derived, not measured, so it follows --type-scale on its own and turning
     that knob can never reintroduce the shift:
       .announce padding 0.375rem × 2        = 0.7500rem
       --label-xs 0.6875rem × --leading-body 1.65 = 1.1344rem
     Re-derive only if .announce's padding, font-size or leading changes.
     Reduced 10 Sep with the bar itself; leaving the old 2.3625rem here would
     reserve more space than the bar occupies and open a gap under it. */
  --announce-h: 1.8844rem;
  --z-header: 60;
  --z-drawer: 90;
  --z-toast: 110;
}

/* ==========================================================================
   Direction A — cream leads (brand guide's own ground, survey's "60% modern
   minimal"). No longer the default: the client asked for the site to open
   dark, with cream as the switch. Still a full first-class direction —
   ground.js honours a stored "cream" and this block wins on specificity.
   ========================================================================== */
:root[data-ground="cream"] {
  color-scheme: light;

  --ground: #f6ecda;
  --ground-raised: #fbf5e9;
  --ground-sunken: #efe0c6;
  --ground-inverse: #222222;

  --ink: #221f1c;
  --ink-muted: #5a4e40;
  --ink-faint: #6f6252;   /* 5.1:1 on cream — #8a7a66 measured 3.55 */
  --ink-inverse: #f6ecda;

  --rule: #dfcdaa;
  --rule-strong: #c9b48c;

  --accent-surface: #752d2c;
  --accent-surface-hover: #5f2423;
  --accent-on: #f6ecda;
  --accent-text: #752d2c;

  --gold-line: #c5a15f;
  --gold-text: #7a5919;   /* 4.9:1 on the sunken cream — #8a6520 measured 4.07 */
  /* Brand gold on the oxblood band is only 3.98:1 — below AA at label sizes.
     This lifted gold clears 5.2:1 on #752D2C while still reading as gold. */
  --gold-on-accent: #d9bc85;

  /* full-bleed bands, used to break the page rhythm */
  --band-dark: #222222;
  --band-dark-ink: #f6ecda;
  --band-dark-rule: #3b332b;
  --band-accent: #752d2c;
  --band-accent-ink: #f6ecda;

  --focus: #752d2c;
  --shadow-soft: 0 1px 2px rgb(34 31 28 / 6%), 0 12px 28px -18px rgb(34 31 28 / 30%);
  --scrim: rgb(34 31 28 / 46%);

  /* Wash laid over full-bleed hero photography. The photo carries the frame, so
     the copy runs cream over it in both directions and the veil is what buys
     that its contrast — directional where copy overlays the image, flat where
     the layout stacks and the wash is only seating the photo into the page. */
  /* The falloff is placed, not eyeballed: it holds through the copy column
     (~38% of the frame) and is spent by 58%, before the roots begin. Measured
     against the photograph itself, this clears AA for every hero text colour —
     see docs/05-verification.md §1.1. Shallower and the eyebrow fails. */
  --hero-veil:
    linear-gradient(103deg,
      rgb(24 17 13 / 84%) 0%,
      rgb(24 17 13 / 72%) 38%,
      rgb(24 17 13 / 32%) 58%,
      rgb(24 17 13 / 8%) 100%),
    linear-gradient(to bottom, rgb(24 17 13 / 0%) 62%, rgb(24 17 13 / 34%) 100%);

  /* Narrow viewports crop the frame to a column, so the copy can't sit beside
     the roots — it sits under them, and the falloff turns vertical to match. */
  --hero-veil-vertical:
    linear-gradient(to bottom,
      rgb(24 17 13 / 26%) 0%,
      rgb(24 17 13 / 44%) 28%,
      rgb(24 17 13 / 91%) 50%,
      rgb(24 17 13 / 96%) 100%);

  /* The fixed parallax band. Deeper and flatter than the hero veil: its copy
     is centred over the middle of the frame rather than held in a corner, so
     there is no quiet region to place it in and the whole image has to carry
     cream type at AA. */
  --plx-veil:
    linear-gradient(to bottom,
      rgb(24 17 13 / 62%) 0%,
      rgb(24 17 13 / 76%) 50%,
      rgb(24 17 13 / 88%) 100%);
}

/* ==========================================================================
   Direction B — dark leads (continuous with the current live store), and the
   default. The bare :root carries it so the page is still correct if ground.js
   never runs; [data-ground="cream"] above out-specifies it when it does.
   ========================================================================== */
:root,
:root[data-ground="dark"] {
  color-scheme: dark;

  --ground: #1a1613;
  --ground-raised: #241f1a;
  --ground-sunken: #120f0d;
  --ground-inverse: #f6ecda;

  --ink: #f1e5cf;
  --ink-muted: #bfae95;
  --ink-faint: #948269;   /* 4.9:1 on dark ground — #8c7b66 measured 4.40 */
  --ink-inverse: #221f1c;

  --rule: #3a312a;
  --rule-strong: #4e4238;

  /* lifted so the button still reads as a surface against a dark ground */
  --accent-surface: #8a3634;
  --accent-surface-hover: #9d403d;
  --accent-on: #f6ecda;
  --accent-text: #c86f6a;

  --gold-line: #c5a15f;
  --gold-text: #c5a15f;
  --gold-on-accent: #d9bc85;

  /* The dark band is the GROUND here, not a deeper shade of it.

     #0f0d0b against the #1a1613 ground is eleven units — far enough apart to
     see a hard horizontal seam above and below every banded section, not far
     enough for the band to read as a deliberate surface. It looked like a
     rendering artefact rather than a design move, which is exactly what the
     client called out on the protocol section.

     Cream keeps its band: #222222 on #F6ECDA is a real contrast and the
     rhythm the layout was built around. On this ground the rhythm comes from
     the oxblood accent band, the section padding, and the headings instead.
     .band-dark still carries its own ink and rule tokens, so nothing inside
     one changes — only the seam goes. */
  --band-dark: #1a1613;
  --band-dark-ink: #f6ecda;
  --band-dark-rule: #2b241e;
  --band-accent: #752d2c;
  --band-accent-ink: #f6ecda;

  --focus: #c5a15f;
  --shadow-soft: 0 1px 2px rgb(0 0 0 / 40%), 0 14px 34px -18px rgb(0 0 0 / 70%);
  --scrim: rgb(10 8 7 / 66%);

  /* A cream-keyed photograph would blow out against this ground; the same veil
     runs deeper here so the image reads as lit from the page, not pasted on. */
  --hero-veil:
    linear-gradient(103deg,
      rgb(10 8 6 / 88%) 0%,
      rgb(10 8 6 / 78%) 38%,
      rgb(10 8 6 / 44%) 58%,
      rgb(10 8 6 / 24%) 100%),
    linear-gradient(to bottom, rgb(10 8 6 / 0%) 55%, rgb(10 8 6 / 58%) 100%);

  --hero-veil-vertical:
    linear-gradient(to bottom,
      rgb(10 8 6 / 40%) 0%,
      rgb(10 8 6 / 58%) 28%,
      rgb(10 8 6 / 92%) 50%,
      rgb(10 8 6 / 97%) 100%);

  --plx-veil:
    linear-gradient(to bottom,
      rgb(10 8 6 / 68%) 0%,
      rgb(10 8 6 / 80%) 50%,
      rgb(10 8 6 / 92%) 100%);
}

/* Suppress transitions during a theme swap so the whole page doesn't crossfade. */
:root[data-theme-switching] *,
:root[data-theme-switching] *::before,
:root[data-theme-switching] *::after {
  transition: none !important;
}

/* ==========================================================================
   Phone overrides
   ========================================================================== */

/* One knob, because tracking is what breaks the phone layout — not any one
   component. 0.24em adds ~3.5px to every character, so a 16-character button
   label carries 56px of pure letter-spacing. On a 390px screen that was enough
   to wrap "Start the ritual", "All articles", even "Cart (1)" in the header,
   and to push the announcement to three lines. It also drove the header
   collision: the wordmark had nowhere to sit because the cart button beside it
   was half again as wide as its text needed.

   0.13em still reads as tracked caps at these sizes and buys back roughly a
   third of every label's width. On :root so it reaches every component that
   uses the token — which is all of them. */
@media (max-width: 700px) {
  :root {
    --label-track: 0.13em;
  }
}
