/* ==========================================================================
   JF Filtr V2 — design tokens

   The system is built on restraint. Two neutrals carry almost the whole page;
   colour appears only where it means something:

     ink / paper   the page itself — near-black on white, nothing decorative
     aqua          filtered air: links, controls, the clean side of a diagram
     ochre         contaminant: dust particles in artwork, never a control
     black         the showcase — product moments, the way a stage goes dark

   Only this file may hold a raw colour value.
   ========================================================================== */

:root {
  /* ---------- LAYER 1: primitives ------------------------------------ */

  /* Paper — the neutral ramp. Cool-tinted so it never reads as beige. */
  --c-white: #ffffff;
  --c-paper-50: #fbfbfd;
  --c-paper-100: #f5f5f7;
  --c-paper-200: #ededf0;
  --c-paper-300: #d2d2d7;

  /* Ink */
  --c-ink-900: #1d1d1f;
  --c-ink-700: #424245;
  --c-ink-500: #6e6e73;
  --c-ink-400: #86868b;

  /* Stage — the dark showcase. True black, the way a product page goes dark. */
  --c-stage-950: #000000;
  --c-stage-900: #0a0a0c;
  --c-stage-800: #16161a;
  --c-stage-700: #232327;
  --c-stage-fg: #f5f5f7;
  --c-stage-fg-dim: #a1a1a6;
  --c-stage-fg-faint: #6e6e73;

  /* Aqua — filtered air. Deep enough to hold AA on paper, bright on stage. */
  --c-aqua-200: #9fe8f0;
  --c-aqua-300: #5fd4e2;
  --c-aqua-400: #26b6c7;
  --c-aqua-600: #0a7c88;
  --c-aqua-700: #076570;

  /* Ochre — contaminant. Artwork only. */
  --c-ochre-400: #d8a24f;
  --c-ochre-600: #a56a2b;

  /* Status */
  --c-danger: #b3261e;
  --c-danger-on-dark: #ff8a80;
  --c-ok: #0f7b52;
  --c-ok-on-dark: #5fd8a4;

  /* ---------- Type ---------------------------------------------------- */

  /* On Apple hardware this resolves to SF Pro, on Windows 11 to Segoe UI
     Variable — both are the system's own display face, which is exactly the
     quality a webfont substitute keeps failing to reach. Inter Tight is the
     fallback everywhere else. */
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI Variable Display',
                  'Segoe UI', 'Inter Tight', system-ui, sans-serif;
  --font-text: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI Variable Text',
               'Segoe UI', 'Inter Tight', system-ui, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'JetBrains Mono', 'Cascadia Mono', Menlo, monospace;

  /* Display sizes carry negative tracking that tightens as they grow — the
     single strongest signal of the look being imitated here. */
  --fs-mega: clamp(2.9rem, 7.4vw, 5.9rem);
  --fs-xxl: clamp(2.3rem, 5.2vw, 3.9rem);
  --fs-xl: clamp(1.85rem, 3.6vw, 2.7rem);
  --fs-lg: clamp(1.3rem, 2vw, 1.65rem);
  --fs-md: 1.3125rem;   /* 21px — the Apple sub-headline size */
  --fs-body: 1.0625rem; /* 17px */
  --fs-sm: 0.9375rem;
  --fs-xs: 0.8125rem;
  --fs-micro: 0.75rem;

  --tr-mega: -0.022em;
  --tr-xxl: -0.019em;
  --tr-xl: -0.016em;
  --tr-lg: -0.012em;
  --tr-flat: 0;
  --tr-wide: 0.05em;
  --tr-eyebrow: 0.12em;

  /* ---------- 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: 2.75rem;  --sp-8: 3.5rem;
  --sp-9: 5rem;     --sp-10: 7rem;    --sp-11: 9.5rem;  --sp-12: 13rem;

  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-pill: 980px;

  --wrap: 1120px;
  --wrap-narrow: 800px;
  --measure: 62ch;

  /* ---------- Motion --------------------------------------------------- */

  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 160ms;
  --dur-base: 320ms;
  --dur-slow: 700ms;

  --z-base: 1;
  --z-raised: 10;
  --z-nav: 100;
  --z-top: 200;

  /* ---------- LAYER 2: semantic (paper, the default) ------------------- */

  --bg: var(--c-white);
  --bg-sunken: var(--c-paper-100);
  --bg-card: var(--c-white);
  --bg-inset: var(--c-paper-100);

  --text: var(--c-ink-900);
  --text-2: var(--c-ink-500);
  --text-3: var(--c-ink-400);

  --line: var(--c-paper-300);
  --line-soft: var(--c-paper-200);

  --accent: var(--c-aqua-600);
  --accent-hover: var(--c-aqua-700);
  --accent-on: var(--c-white);
  --accent-wash: rgb(10 124 136 / 0.07);

  --contaminant: var(--c-ochre-400);
  --contaminant-deep: var(--c-ochre-600);

  --focus: var(--c-aqua-600);
  --danger: var(--c-danger);
  --ok: var(--c-ok);

  /* Shadows stay soft and low-contrast; a hard shadow reads as cheap. */
  --shadow-sm: 0 1px 3px rgb(0 0 0 / 0.06), 0 1px 2px rgb(0 0 0 / 0.04);
  --shadow-md: 0 4px 16px -4px rgb(0 0 0 / 0.1), 0 2px 6px -2px rgb(0 0 0 / 0.05);
  --shadow-lg: 0 24px 60px -20px rgb(0 0 0 / 0.16), 0 8px 24px -12px rgb(0 0 0 / 0.08);
  --shadow-product: 0 40px 80px -30px rgb(20 30 40 / 0.28);
  /* drop-shadow() takes no spread, so the product render needs its own value. */
  --shadow-drop: 0 26px 38px rgb(18 28 36 / 0.16);

  /* ---------- LAYER 3: component --------------------------------------- */

  --nav-bg: rgb(255 255 255 / 0.72);
  --nav-line: rgb(0 0 0 / 0.08);

  --btn-fg: var(--accent-on);
  --btn-bg: var(--accent);
  --btn-bg-hover: var(--accent-hover);
  --btn-ghost-fg: var(--accent);
  --btn-ghost-line: var(--line);
  --btn-disabled-bg: var(--c-paper-200);
  --btn-disabled-fg: var(--c-ink-400);

  --field-bg: var(--c-white);
  --field-line: var(--c-paper-300);
  --field-line-focus: var(--accent);
  --field-placeholder: var(--c-ink-400);

  --card-line: var(--line-soft);
  --sheet-line: var(--line-soft);
  --sheet-hover: var(--c-paper-50);

  /* The product frame needs its own pair: the surface tokens are too close to
     the page background for a metal flange to read against it. */
  --frame-lit: var(--c-paper-100);
  --frame-shade: var(--c-paper-300);

  /* Filter media in the 3D render. Real pocket media is an off-white
     non-woven, so the fabric only carries a hint of the aqua — a saturated
     pocket reads as plastic, not as a product photograph. */
  --product-fabric: #dae8ea;
  --product-metal: #b6bec8;
}

/* ---------- Stage scope ---------------------------------------------------
   Product showcases go dark. Every component token resolves through the
   semantic layer, so a section only has to declare .stage — nothing needs a
   second rule set. */

.stage {
  --bg: var(--c-stage-950);
  --bg-sunken: var(--c-stage-900);
  --bg-card: var(--c-stage-800);
  --bg-inset: var(--c-stage-800);

  --text: var(--c-stage-fg);
  --text-2: var(--c-stage-fg-dim);
  --text-3: var(--c-stage-fg-faint);

  --line: var(--c-stage-700);
  --line-soft: var(--c-stage-800);

  --accent: var(--c-aqua-300);
  --accent-hover: var(--c-aqua-200);
  --accent-on: var(--c-stage-950);
  --accent-wash: rgb(95 212 226 / 0.12);

  --focus: var(--c-aqua-300);
  --danger: var(--c-danger-on-dark);
  --ok: var(--c-ok-on-dark);

  --shadow-sm: 0 1px 3px rgb(0 0 0 / 0.5);
  --shadow-md: 0 8px 28px -10px rgb(0 0 0 / 0.7);
  --shadow-lg: 0 30px 70px -24px rgb(0 0 0 / 0.85);
  --shadow-product: 0 50px 100px -40px rgb(0 0 0 / 0.9);
  --shadow-drop: 0 30px 50px rgb(0 0 0 / 0.75);

  --btn-disabled-bg: var(--c-stage-700);
  --btn-disabled-fg: var(--c-stage-fg-faint);

  --field-bg: var(--c-stage-800);
  --field-line: var(--c-stage-700);
  --field-placeholder: var(--c-stage-fg-faint);

  --card-line: var(--c-stage-700);
  --sheet-line: var(--c-stage-700);
  --sheet-hover: var(--c-stage-800);

  --frame-lit: var(--c-stage-700);
  --frame-shade: var(--c-stage-800);

  /* Lifted against black, and tinted a little further toward the aqua so the
     media still reads as the clean side of the filter. */
  --product-fabric: #a8d9e0;
  --product-metal: #97a1ad;
}
