/*
 * liquid-kit · tokens.css — design tokens as plain :root custom properties.
 *
 * What:     single source of truth for colour, faces, radii, elevation, z-layers, the Liquid Glass
 *           material and motion. Plain CSS so any stack can use it; Tailwind v4 maps it in
 *           tailwind-theme.css; JS reads it with getComputedStyle.
 * Deps:     none. Load order: tokens.css -> tailwind-theme.css (optional) -> glass.css.
 * Adapt:    every value tagged BRIEF comes from the project's design brief (palette, faces). The
 *           shipped palette is a neutral placeholder and must never reach production unchanged.
 *           Glass, motion and radius values are tuned defaults: reparametrise to the brief but
 *           keep the NAMES, because glass.css, the React assets and Tailwind reference them.
 * Pitfalls: - Keep this file UNLAYERED (no @layer): Tailwind utilities point at these exact names
 *             and an unlayered :root is what makes them resolvable from JS and plain CSS.
 *           - One theme by default: the paper is light. The dark page palette at the end is used only
 *             when the brief ships two themes; it appears twice (media query + [data-theme]) on
 *             purpose, because light-dark() would drop colour tokens in Safari < 17.5.
 *           - Glass tone (light/dark) is flipped per ELEMENT in glass.css, because glass follows the
 *             content under it, not only the page theme.
 *           - If you change a glass k/b/a or ink value, redo the contrast bound (liquid-glass.md,
 *             "Contrast strategy") and let the audit's pixel-contrast gate confirm it.
 */

:root {
  color-scheme: light dark;

  /* ---------- Palette (BRIEF: replace all; 4-6 brand colours in oklch) ----------
   * The paper is a step darker than white: light glass is brighter than the page, so it reads as
   * glass; on pure white it reads as grey plastic. Raised content (cards, panels) sits lighter than
   * the page with a --color-line hairline; sunken wells (tracks, fields) sit darker. */
  --color-bg: #eceff3; /* BRIEF: keep it a step darker than white */
  --color-bg-raised: #f8f9fb; /* BRIEF */
  --color-bg-sunken: #e3e7ec; /* BRIEF */
  --color-ink: oklch(0.21 0.015 255); /* BRIEF */
  --color-ink-muted: oklch(0.44 0.015 255); /* BRIEF: keep >= 4.5:1 on --color-bg */
  --color-ink-faint: oklch(0.58 0.012 255); /* BRIEF: 3:1 only, never body text */
  --color-line: oklch(0.21 0.015 255 / 0.12); /* BRIEF */
  --color-line-strong: oklch(0.21 0.015 255 / 0.24); /* BRIEF */
  --color-accent: oklch(0.52 0.11 170); /* BRIEF: the ONE tinted primary action uses this */
  --color-accent-ink: oklch(0.99 0 0); /* BRIEF: label on accent, >= 4.5:1 */
  --color-positive: oklch(0.55 0.13 150); /* BRIEF */
  --color-negative: oklch(0.55 0.19 27); /* BRIEF */
  --color-caution: oklch(0.72 0.14 75); /* BRIEF */
  --color-focus: oklch(0.55 0.16 250); /* BRIEF: must differ from accent where accent is a fill */
  --color-selection: color-mix(in oklab, var(--color-accent) 24%, transparent);

  /* ---------- Faces (BRIEF: see typography.md; e.g. var(--font-geologica) from next/font) ---------- */
  --font-display: "Brief Display Face", sans-serif; /* BRIEF */
  --font-text: "Brief Text Face", sans-serif; /* BRIEF */
  --font-mono: "Brief Mono Face", monospace; /* BRIEF */

  /* ---------- Radii ----------
   * Concentric rule (WWDC25 356): inner radius = max(outer - padding, --radius-min). Never reuse
   * the outer radius inside a padded container; uneven corner gaps are the tell of a template.
   * --radius-island is Apple's Dynamic Island corner (44 pt). --squircle-scale compensates for
   * corner-shape: squircle looking tighter than a round corner at the same radius (tune by eye;
   * the factor is a starting point, not a measured constant). */
  --radius-min: 6px;
  --radius-xs: 6px;
  --radius-sm: 10px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --radius-2xl: 36px;
  --radius-island: 44px;
  --radius-pill: 9999px;
  --squircle-scale: 1.4;

  /* ---------- Elevation (low-chroma, layered: a tight contact shadow + a soft ambient one) ---------- */
  --shadow-1: 0 0.5px 1px rgb(0 0 0 / 0.06), 0 1px 3px rgb(0 0 0 / 0.06);
  --shadow-2: 0 1px 2px rgb(0 0 0 / 0.06), 0 6px 16px -6px rgb(0 0 0 / 0.14);
  --shadow-3: 0 1px 2px rgb(0 0 0 / 0.08), 0 16px 36px -14px rgb(0 0 0 / 0.24);
  --shadow-4: 0 2px 4px rgb(0 0 0 / 0.08), 0 32px 64px -24px rgb(0 0 0 / 0.36);
  /* Size = thickness (WWDC25 219): bigger glass casts deeper, softer shadows. Fitted to Apple's
   * pixels: soft, low, offset down, never a dark ring (the ring is the 0.5 px edge line). */
  --shadow-glass-control: 0 1px 2px rgb(0 0 0 / 0.05), 0 10px 28px rgb(0 0 0 / 0.09);
  --shadow-glass-bar: 0 2px 6px rgb(0 0 0 / 0.07), 0 8px 24px rgb(0 0 0 / 0.1);
  --shadow-glass-sheet: 0 4px 12px rgb(0 0 0 / 0.07), 0 36px 72px -16px rgb(0 0 0 / 0.28);
  --shadow-glass-island: 0 1px 3px rgb(0 0 0 / 0.1), 0 10px 26px rgb(0 0 0 / 0.14);

  /* ---------- Z-layers (use these, never ad-hoc 9999) ---------- */
  --z-below: -1;
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 20;
  --z-scroll-edge: 30;
  --z-nav: 40;
  --z-island: 50;
  --z-popover: 60;
  --z-sheet: 70;
  --z-toast: 80;
  --z-modal: 90;

  /* ---------- Liquid Glass material ----------
   * Numbers come from pixel measurements of Apple's own imagery (glass-lab, Sept 2026): blur is LOW
   * on bars (sigma ~2-3 pt: content stays recognisable, only its contrast drops) and high only on
   * big panels; the glass is defined by its rim (dark 0.5 px outer edge + 1 px specular inside it)
   * and by lensing in a thin rim band, not by a milky fill.
   * Surfaces: control = icon buttons / thumbs, bar = nav / segmented / toolbars with labels,
   * sheet = text-heavy panels, island = the Dynamic-Island-style status pill.
   * Safari clamps blur radii under ~1.4 px, so no surface goes lower than 2 px. */
  --glass-blur-control: 2.5px;
  --glass-blur-bar: 3.5px;
  --glass-blur-sheet: 14px;
  --glass-blur-island: 4px;
  --glass-blur-clear: 2px;
  /* Blur drains chroma; saturate() restores it so the glass keeps the backdrop's hue. */
  --glass-saturate-control: 1.5;
  --glass-saturate-bar: 1.9;
  --glass-saturate-sheet: 1.8;
  --glass-saturate-island: 1.8;
  --glass-saturate-clear: 1.4;
  /* Dynamic-range bound: k = contrast(), b = brightness(), a = veil alpha of the tone's tint.
   * contrast(k) maps v -> k*v + (1-k)/2, brightness(b) -> b*v, the veil -> a*t + (1-a)*v, so every
   * backdrop channel lands in a known range WHATEVER the content is.
   * Light b is tuned for the #eceff3 paper: at b 1.08-1.2 the light glass came out DARKER than the
   * paper (a bar of #e2e3e5 over #eceff3: grey plastic). A higher b lifts the whole range, so the
   * glass reads brighter than the page and every dark-content bound improves.
   * Worked limits (sRGB, ink #0b0b0f; the audit's pixel-contrast gate is the proof):
   *   bar     light k .6  b 1.26 a .26: paper -> #f6f8fa; black -> 0.447 (ink 4.1:1, 5.9:1 at
   *           adapt 1). Pure black is NOT covered at adapt 0: the adaptive tint raises the veil or
   *           flips the glass to dark there (data-glass-on="auto").
   *   sheet   light k .5  b 1.3  a .34: paper -> #f3f4f6; black -> 0.555 (ink 5.9:1 over anything).
   *   control light k .74 b 1.16 a .10: paper -> #f2f5f8; icons >= 3:1 over mid-tones; near-clear.
   *   island  light k .5  b 1.32 a .26: paper -> #f4f5f7; black -> 0.504 (ink 5.0:1 over ANY
   *           backdrop, 6.8:1 at adapt 1);
   *           dark  k .7  b .5   a .34: white -> 0.305 (#f5f5f7 >= 7.6:1 over any backdrop).
   *           Translucent in both tones: the backdrop's hue and pattern stay visible and bend at
   *           the rim. Legibility comes from the adaptive tint (tone + --glass-adapt below), the
   *           label weight and a soft halo, NEVER from an opaque or near-black fill.
   *   dark tone (k/b *-dark-*): the page under dark glass stays dark (Apple over dark: <= 2% veil);
   *           white content -> 0.33 (bar), white text >= 7:1. */
  --glass-k-control: 0.74;
  --glass-k-bar: 0.6;
  --glass-k-sheet: 0.5;
  --glass-k-island: 0.5;
  --glass-k-dark-control: 0.8;
  --glass-k-dark-bar: 0.8;
  --glass-k-dark-sheet: 0.7;
  --glass-k-dark-island: 0.7;
  --glass-b-light-control: 1.16;
  --glass-b-light-bar: 1.26;
  --glass-b-light-sheet: 1.3;
  --glass-b-light-island: 1.32;
  --glass-a-light-control: 0.1;
  --glass-a-light-bar: 0.26;
  --glass-a-light-sheet: 0.34;
  --glass-a-light-island: 0.26;
  --glass-b-dark-control: 0.55;
  --glass-b-dark-bar: 0.52;
  --glass-b-dark-sheet: 0.5;
  --glass-b-dark-island: 0.5;
  --glass-a-dark-control: 0.24;
  --glass-a-dark-bar: 0.34;
  --glass-a-dark-sheet: 0.4;
  --glass-a-dark-island: 0.34;
  /* Adaptive tint strength: liquid-glass.js (and LiquidGlass.tsx) sample the luminance under an
   * auto-tone surface and write --glass-adapt 0 / 0.5 / 1 on it: 0 when the backdrop is far from
   * the ink (white under light glass), 1 when it is close (mid-dark content under light glass).
   * The veil grows by up to this much alpha. It only ever ADDS legibility on top of the bound. */
  --glass-adapt-a: 0.14;
  --glass-tint-rgb-light: 255 255 255;
  --glass-tint-rgb-dark: 18 18 24;
  --glass-ink-light: #0b0b0f; /* BRIEF: may lean toward the palette; recheck the bound */
  --glass-ink-dark: #f5f5f7; /* BRIEF: same */
  /* Vibrancy-style labels: secondary text is the ink at reduced alpha, so it picks up a trace of
   * the backdrop's hue instead of turning into a flat grey. Halo = the soft shadow that keeps thin
   * strokes off busy content (light tone: a white halo under dark ink; dark tone: a dark one). */
  --glass-label-2-alpha: 0.8;
  --glass-halo-light: 0 0 1px rgb(255 255 255 / 0.5), 0 0.5px 2px rgb(255 255 255 / 0.4);
  --glass-halo-dark: 0 1px 2px rgb(0 0 0 / 0.4);
  /* Rim (iOS/macOS 27: darker thin outer edge, brighter and tighter specular).
   * Specular: 1 px line just inside a 0.5 px dark hairline. Primary arc toward the key light
   * (top for bars, 10-12 o'clock for round controls), secondary on the far side at ~60%, and
   * nothing on the sides. Where the arc sits and how far it runs is geometry, written per shape by
   * liquid-glass.js / useLightSource.ts (--glass-rim-g / -p / -f, see rimGeometry). */
  --glass-spec-a-light: 0.92;
  --glass-spec-b-light: 0.55;
  --glass-spec-a-dark: 0.6;
  --glass-spec-b-dark: 0.36;
  --glass-edge-light: rgb(0 0 0 / 0.2);
  --glass-edge-dark: rgb(0 0 0 / 0.55);
  /* Inner rim glow (the bevel catching light): ~6 px band, top > bottom > sides (Apple, over dark:
   * top .43, bottom .33, sides .15; halved over light, where the 1 px line does the work). */
  --glass-glow-w: 6px;
  --glass-glow-top-light: 0.26;
  --glass-glow-bottom-light: 0.16;
  --glass-glow-side-light: 0.05;
  --glass-glow-top-dark: 0.2;
  --glass-glow-bottom-dark: 0.13;
  --glass-glow-side-dark: 0.05;
  /* Proximity light: the travelling rim hot spot and the "illuminate from within" glow. It reacts
   * only while a pointer is within max(160 px, 0.75 x diagonal) of the surface and rests at the
   * static key light otherwise (never a page-wide cursor tracker).
   * --glass-spot-size is the fallback radius; the runtime writes clamp(28px, 0.55 x short side,
   * 120px) per surface so on a small control only the arc nearest the pointer lights.
   * Interior glow: bars / sheets .2, controls .08, the island .1. */
  --glass-spot-size: 60px;
  --glass-spot-a: 0.85;
  --glass-spot-ring: 2px;
  --glass-near-glow: 0.2;
  --glass-near-glow-control: 0.08;
  --glass-near-glow-island: 0.1;
  --glass-press-glow: 0.34;
  --glass-press-scale: 0.035;
  /* Lens tier: edge-only displacement. Band = clamp(4px, 12% of min(w,h), 14px) (Apple: 10-15%).
   * The band samples INWARD along the rim normal (Blink clips the backdrop to the border box, so
   * outward samples read nothing): straight edges bow toward the rim like a convex bezel.
   * Profile d = D(1 - s/band)^power; D is capped so the steepest slope pD/band stays
   * <= --glass-lens-slope (0.8): content bends, it never folds into mirrored chevrons.
   * Per-channel offset (R > G > B) up to --glass-lens-chroma, rim band only. */
  --glass-lens-band: 0.12;
  --glass-lens-power: 1.5;
  --glass-lens-slope: 0.8;
  --glass-lens-chroma: 1.2px;
  /* Opaque fallbacks: Floor tier / Reduce Transparency, and Increase Contrast (black or white). */
  --glass-floor-light: #f4f6f9; /* BRIEF: light glass over the paper, so the Floor tier matches Frost */
  --glass-floor-dark: oklch(0.25 0.01 255); /* BRIEF */
  --glass-floor-hc-light: #fff;
  --glass-floor-hc-dark: #000;
  /* Fills for elements that sit ON glass (HIG: fills, not more glass). */
  --glass-fill-light: rgb(0 0 0 / 0.07);
  --glass-fill-dark: rgb(255 255 255 / 0.12);
  --glass-tint-primary-mix: 82%; /* accent share in the single tinted primary */
  --glass-pad: 8px; /* default padding for the concentric inner radius */
  /* 6% white fractal noise; kills blur banding on large sheets. Opt-in per surface. */
  --glass-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .06 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* ---------- Ambient: the layer under the glass (react/Ambient.tsx, css/chrome.css .lk-ambient) ----------
   * Glass needs something to refract or it reads as grey plastic. Two soft glows of the key light
   * spill from the top corners, where the floating chrome sits. A hairline grid is opt-in
   * (<Ambient texture="grid" />, the line tokens below). Static on purpose: a moving backdrop
   * re-filters every glass surface each frame. */
  --ambient-a: oklch(0.72 0.12 170 / 0.16); /* BRIEF: a hue from the palette (top-left glow) */
  --ambient-b: oklch(0.62 0.14 285 / 0.13); /* BRIEF: a second hue (top-right glow) */
  --ambient-line: oklch(0.21 0.015 255 / 0.055); /* texture="grid" only: the ink at ~5 % */
  --ambient-pitch: 32px;

  /* ---------- Motion (twins of react/motion-tokens.ts) ---------- */
  --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1); /* enters */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); /* big reveals */
  --ease-in-out-cubic: cubic-bezier(0.65, 0, 0.35, 1); /* on-screen A to B */
  --ease-in-quart: cubic-bezier(0.5, 0, 0.75, 0); /* leaving the screen */
  /* Apple springs as linear() curves (duration 0.5, k 158). The shape depends only on bounce;
   * always pair a curve with its settle time below. Browsers without linear() fall back to ease. */
  --ease-spring-0: linear(0, 0.036, 0.12, 0.225, 0.334, 0.438, 0.533, 0.616, 0.687, 0.747, 0.797, 0.838, 0.871, 0.898, 0.92, 0.937, 0.951, 0.961, 0.97, 0.977, 0.982, 0.986, 0.989, 0.992, 0.994, 0.995, 0.996, 0.997, 0.998, 0.998, 0.999, 1);
  --ease-spring-15: linear(0, 0.034, 0.116, 0.222, 0.336, 0.449, 0.553, 0.646, 0.725, 0.792, 0.846, 0.889, 0.923, 0.949, 0.968, 0.982, 0.992, 0.998, 1.002, 1.005, 1.006, 1.006, 1.006, 1.006, 1.005, 1.004, 1.004, 1.003, 1.002, 1.002, 1.001, 1);
  --ease-spring-20: linear(0, 0.032, 0.111, 0.216, 0.33, 0.444, 0.552, 0.648, 0.731, 0.801, 0.858, 0.904, 0.939, 0.965, 0.984, 0.998, 1.006, 1.012, 1.014, 1.015, 1.015, 1.014, 1.012, 1.01, 1.009, 1.007, 1.006, 1.004, 1.003, 1.002, 1.002, 1);
  --ease-spring-30: linear(0, 0.047, 0.16, 0.304, 0.455, 0.597, 0.722, 0.825, 0.905, 0.963, 1.003, 1.028, 1.041, 1.046, 1.045, 1.04, 1.034, 1.027, 1.02, 1.014, 1.009, 1.005, 1.002, 1, 0.999, 0.998, 0.998, 0.998, 0.998, 0.998, 0.999, 1);
  --dur-spring-0: 734ms; /* = spring.smooth */
  --dur-spring-15: 696ms; /* = spring.snappy */
  --dur-spring-20: 674ms; /* = spring.island */
  --dur-spring-30: 818ms; /* = spring.bouncy */
  --dur-press: 80ms;
  --dur-hover: 160ms;
  --dur-exit: 150ms;
  --dur-enter: 220ms;
  --dur-move: 400ms;
  --dur-hero: 1100ms;
  --stagger-step: 40ms;
  --stagger-max: 240ms;
}

:root[data-theme="light"] {
  color-scheme: light;
}

/* Dark palette: only when the brief ships two themes. With one theme, put data-theme="light" on
 * <html> (or delete both dark blocks). Declared twice so both the OS setting and an explicit
 * data-theme work. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --color-bg: oklch(0.17 0.01 255); /* BRIEF */
    --color-bg-raised: oklch(0.22 0.012 255); /* BRIEF */
    --color-bg-sunken: oklch(0.14 0.01 255); /* BRIEF */
    --color-ink: oklch(0.96 0.005 255); /* BRIEF */
    --color-ink-muted: oklch(0.76 0.01 255); /* BRIEF */
    --color-ink-faint: oklch(0.6 0.01 255); /* BRIEF */
    --color-line: oklch(0.96 0.005 255 / 0.12); /* BRIEF */
    --color-line-strong: oklch(0.96 0.005 255 / 0.22); /* BRIEF */
    --color-accent: oklch(0.74 0.12 170); /* BRIEF */
    --color-accent-ink: oklch(0.18 0.02 170); /* BRIEF */
    --color-positive: oklch(0.74 0.14 150); /* BRIEF */
    --color-negative: oklch(0.7 0.17 27); /* BRIEF */
    --color-caution: oklch(0.82 0.13 80); /* BRIEF */
    --color-focus: oklch(0.75 0.14 250); /* BRIEF */
    --shadow-1: 0 0.5px 1px rgb(0 0 0 / 0.3), 0 1px 3px rgb(0 0 0 / 0.3);
    --shadow-2: 0 1px 2px rgb(0 0 0 / 0.3), 0 6px 16px -6px rgb(0 0 0 / 0.45);
    --shadow-3: 0 1px 2px rgb(0 0 0 / 0.35), 0 16px 36px -14px rgb(0 0 0 / 0.55);
    --shadow-4: 0 2px 4px rgb(0 0 0 / 0.35), 0 32px 64px -24px rgb(0 0 0 / 0.65);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --color-bg: oklch(0.17 0.01 255); /* BRIEF */
  --color-bg-raised: oklch(0.22 0.012 255); /* BRIEF */
  --color-bg-sunken: oklch(0.14 0.01 255); /* BRIEF */
  --color-ink: oklch(0.96 0.005 255); /* BRIEF */
  --color-ink-muted: oklch(0.76 0.01 255); /* BRIEF */
  --color-ink-faint: oklch(0.6 0.01 255); /* BRIEF */
  --color-line: oklch(0.96 0.005 255 / 0.12); /* BRIEF */
  --color-line-strong: oklch(0.96 0.005 255 / 0.22); /* BRIEF */
  --color-accent: oklch(0.74 0.12 170); /* BRIEF */
  --color-accent-ink: oklch(0.18 0.02 170); /* BRIEF */
  --color-positive: oklch(0.74 0.14 150); /* BRIEF */
  --color-negative: oklch(0.7 0.17 27); /* BRIEF */
  --color-caution: oklch(0.82 0.13 80); /* BRIEF */
  --color-focus: oklch(0.75 0.14 250); /* BRIEF */
  --shadow-1: 0 0.5px 1px rgb(0 0 0 / 0.3), 0 1px 3px rgb(0 0 0 / 0.3);
  --shadow-2: 0 1px 2px rgb(0 0 0 / 0.3), 0 6px 16px -6px rgb(0 0 0 / 0.45);
  --shadow-3: 0 1px 2px rgb(0 0 0 / 0.35), 0 16px 36px -14px rgb(0 0 0 / 0.55);
  --shadow-4: 0 2px 4px rgb(0 0 0 / 0.35), 0 32px 64px -24px rgb(0 0 0 / 0.65);
}
