/* ==========================================================================
   tokens.css — the single source of every design decision.
   Nothing in this file renders anything; it only declares values.
   Palette is authored in oklch() so lightness steps are perceptually even,
   and derived colours use color-mix() so a change here propagates everywhere.

   Direction (artist pass): warm paper + ink + one earthy accent (madder red).
   No glows, no glass, no gradient fills — the light comes from the page, not
   from the chrome. Every token name is unchanged so no component breaks.
   ========================================================================== */

/*
  Cascade layer order.

  Declared once, in the first stylesheet the document loads. Layer order beats
  selector specificity, so a utility always wins over a component and a
  component always wins over base — regardless of how specific the selectors
  are or which file came later. That is what removes the need for the
  !important and selector-padding this project previously relied on.
*/
@layer reset, tokens, base, components, utilities;

@layer tokens {
  :root {
    color-scheme: light;

    /* ── Surface ramp ──────────────────────────────────────────────────────
       Paper. Lightness steps stay evenly spaced (~0.03 L apart) so a card
       reads as a sheet laid on a sheet rather than as elevation. Hue is warm
       (70°) and chroma is a whisper — white paper, not cream paint. */
    --bg-core:     oklch(0.958 0.008 80);   /* paper */
    --bg-sunken:   oklch(0.925 0.010 80);   /* the desk under it */
    --bg-surface:  oklch(0.980 0.006 85);   /* a lighter sheet */
    --bg-raised:   oklch(0.995 0.003 85);   /* lifted card face */
    --bg-overlay:  oklch(0.900 0.012 78);   /* recessed well */

    /* Glass. The frosted look is retired; the token remains so any surface
       still asking for it resolves to a plain paper fill and no blur. */
    --glass-bg:     var(--bg-surface);
    --glass-blur:   none;
    --glass-blur-veil: none;

    /* ── Paper grain ───────────────────────────────────────────────────────
       A single fractal-noise SVG tiled as a background. Kept deliberately
       faint: it should read as the tooth of the paper under a thumbnail,
       never as a visible pattern. Fixed size, so it costs nothing to scroll. */
    --paper-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .30 0 0 0 0 .24 0 0 0 0 .17 0 0 0 .06 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
    --paper-rule: linear-gradient(90deg, transparent, var(--line-strong) 18%, var(--line-strong) 82%, transparent);

    /* ── Text ──────────────────────────────────────────────────────────────
       Ink, in three dilutions. `--text` on `--bg-core` measures ~13.5:1 and
       `--text-muted` ~5.6:1 — both clear WCAG AA for body copy with headroom,
       which matters more here than on the old dark chrome because muted ink is
       most of the captions and labels. */
    --text:        oklch(0.250 0.014 60);
    --text-soft:   oklch(0.400 0.016 60);
    --text-muted:  oklch(0.500 0.018 60);
    --text-faint:  oklch(0.640 0.014 65);

    /* ── Accent ────────────────────────────────────────────────────────────
       Madder red, the one pigment. Expressed at several lightnesses so it can
       carry a link, a rule and a pressed button without a second hue entering
       the page. The glow/halo names survive as TRANSPARENT so every legacy
       rule that paints with them paints nothing. */
    --accent:         oklch(0.505 0.140 33);
    --accent-bright:  oklch(0.580 0.150 36);
    --accent-deep:    oklch(0.410 0.125 30);
    /* Legacy name, remapped onto the accent so any old gradient collapses
       to a flat madder fill instead of reintroducing violet. */
    --accent-violet:  oklch(0.505 0.140 33);
    --accent-glow:    transparent;
    --accent-halo:    transparent;
    --accent-ring:    var(--accent);

    /* Sap green — the second earth pigment, for success and "public" states. */
    --accent-alt:     oklch(0.470 0.090 150);

    /* ── Lines & states ────────────────────────────────────────────────────
       A pencil line: warm grey at ~62% lightness, opaque. Hairlines here are
       real strokes rather than colour-mixed light, because ink on paper does
       not brighten with the surface under it. */
    --line:        oklch(0.860 0.012 78);
    --line-strong: oklch(0.760 0.016 75);
    --line-glow:   var(--line);

    --danger:      oklch(0.500 0.170 27);
    --danger-soft: color-mix(in oklab, var(--danger) 14%, transparent);
    --success:     oklch(0.470 0.090 150);

    /* ── Motion ────────────────────────────────────────────────────────────
       Soft ease-out. The old curve was ease-out-expo — a hard launch that
       reads as machinery. This one departs gently and settles early, which is
       what "slow and physical" means: the eye should never see a snap. */
    --ease-out:    cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --ease-linear: linear;

    --t-instant: 0.12s;
    --t-fast:    0.20s;
    --t:         0.35s;
    --t-slow:    0.50s;
    --t-veil:    0.60s;

    /* ── Radius ──────────────────────────────────────────────────────────
       Paper is cut, not moulded. Corners are square; the only concession is a
       single hairline of softness so a 1px border does not alias on glass. */
    --radius-xs:  2px;
    --radius-sm:  2px;
    --radius:     2px;
    --radius-lg:  3px;
    --radius-pill: 2px;    /* legacy name — a pill would be a tech cue */

    /* ── Elevation ─────────────────────────────────────────────────────────
       Warm shadows, short throws, low alpha: a framed print resting on a wall
       a centimetre proud, lit from above. Never a coloured bleed — the glow
       layer this file used to carry is gone. */
    --shadow-sm:   0 1px 1px rgb(62 44 26 / 0.07),
                   0 2px 6px -2px rgb(62 44 26 / 0.10);
    --shadow:      0 1px 1px rgb(62 44 26 / 0.08),
                   0 10px 24px -12px rgb(62 44 26 / 0.32);
    /* Resting elevation for an interactive surface. Deliberately shallow: a
       grid at rest must read as flat, or the whole page looks hovered. */
    --shadow-rest: 0 1px 1px rgb(62 44 26 / 0.06),
                   0 4px 10px -6px rgb(62 44 26 / 0.18);
    --shadow-lift: 0 1px 1px rgb(62 44 26 / 0.10),
                   0 18px 34px -14px rgb(62 44 26 / 0.40);
    /* Legacy name. Fixed at transparent so no rule can paint a halo. */
    --shadow-glow: none;
    --shadow-inset-top: inset 0 1px 0 0 rgb(255 255 255 / 0.65);

    /* ── Typography ────────────────────────────────────────────────────────
       Fraunces for headings — a characterful, slightly wonky serif that reads
       as set type rather than as an interface. DM Sans for everything the
       visitor operates. Caveat is reserved for one or two hand-written notes.

       Fluid scale. Each step interpolates between a 320px floor and a 1440px
       ceiling, so headings grow with the viewport without a media query. The
       display sizes are larger than the old scale at the top end: a monograph
       title is allowed to be big. */
    --font-body:    'DM Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-display: 'Fraunces', 'Cormorant Garamond', ui-serif, Georgia, 'Times New Roman', serif;
    --font-hand:    'Caveat', 'Segoe Script', cursive;
    --font-mono:    'DM Sans', ui-sans-serif, system-ui, sans-serif;

    --step--1: clamp(0.7500rem, 0.73rem + 0.10vw, 0.8125rem);
    --step-0:  clamp(0.9375rem, 0.90rem + 0.19vw, 1.0625rem);
    --step-1:  clamp(1.1250rem, 1.05rem + 0.38vw, 1.3750rem);
    --step-2:  clamp(1.5000rem, 1.30rem + 1.00vw, 2.2500rem);
    --step-3:  clamp(1.8750rem, 1.45rem + 2.10vw, 3.2500rem);
    --step-4:  clamp(2.5000rem, 1.60rem + 4.50vw, 5.2500rem);
    --step-5:  clamp(3.0000rem, 1.70rem + 6.50vw, 7.0000rem);

    /* Metadata voice: year, medium, size, tags. Small, letterspaced, upper —
       the caption card beside a work on a gallery wall. */
    --label-size:   0.6875rem;
    --label-tracking: 0.14em;

    --leading-tight: 1.12;
    --leading-snug:  1.35;
    --leading-body:  1.7;
    --measure:       68ch;    /* comfortable reading width */
    /* Narrower measure for prose that sits beside other chrome. Both sit in
       the 60–75ch band; a monograph column should never run the full width. */
    --measure-prose: 62ch;
    /* Cap on a text block's line count is handled by the author; this is the
       upper bound so a 4K monitor does not produce 140-character lines. */
    --tracking-display: -0.01em;

    /* ── Space ─────────────────────────────────────────────────────────── */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;

    /* ── Layout ────────────────────────────────────────────────────────── */
    --shell-max:    1500px;
    --sidebar-w:    17rem;
    --header-h:     4rem;
    --gallery-gap:  clamp(1.5rem, 3vw, 2.75rem);
    /* The passe-partout mat around a print, and the width of its frame edge. */
    --mat:          clamp(0.75rem, 1.4vw, 1.25rem);
    --frame:        1px;

    /* WCAG 2.5.8 minimum interactive target. */
    --tap-min: 44px;

    --z-base:    1;
    --z-sticky:  30;
    --z-drawer:  40;
    --z-overlay: 80;
    --z-toast:   100;
  }

  /* ── Reduced motion ──────────────────────────────────────────────────────
     Collapse every duration token to a hair above zero. Components keep their
     transitions, so they still change state — they just arrive instantly. */
  @media (prefers-reduced-motion: reduce) {
    :root {
      --t-instant: 0.01ms;
      --t-fast:    0.01ms;
      --t:         0.01ms;
      --t-slow:    0.01ms;
      --t-veil:    0.01ms;
    }
  }

  /* ── Increased contrast ──────────────────────────────────────────────────
     On paper the work is to DARKEN, not to lighten: hairlines get closer to
     ink and muted text drops toward the body colour. */
  @media (prefers-contrast: more) {
    :root {
      --line:        oklch(0.620 0.018 70);
      --line-strong: oklch(0.480 0.020 65);
      --text-muted:  oklch(0.380 0.016 60);
      --text-faint:  oklch(0.480 0.016 62);
      --accent:      oklch(0.440 0.150 32);
    }
  }

  /* ── Forced colours (Windows High Contrast) ──────────────────────────────
     Give back control of the palette to the OS, but keep the focus ring. */
  @media (forced-colors: active) {
    :root {
      --line: CanvasText;
      --accent: Highlight;
    }
  }
}
