/* ============================================================
   Kwirkz.net - Design tokens
   Single source of truth for the marketing site.
   Values mirror DESIGN-TOKENS.md. Change them here, not inline.

   Audited 2026-07-18 against the ui-ux-pro-max rule set
   (.claude/skills/ui-ux-pro-max/SKILL.md). Priority 1 of that
   rule set is contrast at 4.5:1 for text and 3:1 for UI shapes.
   Several brand values did not clear it. The hue was preserved
   and the lightness was lowered until each pair passed. Every
   ratio quoted below is computed, not estimated.
   ============================================================ */

/* The display face ships as woff2 first because woff2 carries its own
   Brotli compression inside the file. A raw TrueType file only gets
   compressed if the host happens to gzip the font/ttf content type, and
   plenty of hosts do not, so its delivered weight was a hosting accident
   rather than a decision. Measured on this exact file: 30,620 bytes raw,
   17,079 gzipped, 12,876 as woff2. The ttf stays as a second src purely
   for browsers too old to read woff2, and no such browser reaching this
   site would render the rest of the page correctly anyway. */
@font-face{
  font-family:"Curse Casual";
  src:url("../fonts/CurseCasual.woff2") format("woff2"),
      url("../fonts/CurseCasual.ttf") format("truetype");
  font-weight:400 900;
  font-display:swap;
}

:root{
  /* ---- brand ---- */
  --navy:#1C1362;
  --navy-700:#150E48;
  --navy-50:#EDEBF7;

  /* Grass is the brand green. It is DECORATIVE ONLY.
     White on #43B649 is 2.62:1 and #43B649 on cream is 2.51:1, so it
     fails both the 4.5:1 text floor and the 3:1 shape floor. It may
     fill a bar, a bullet or a dot that carries no text and no meaning
     on its own. It may never carry white text and it may never be the
     only thing separating two surfaces. */
  --grass:#43B649;

  /* The three working greens. Use these, not --grass, for anything
     legible. Each keeps the brand hue and only drops in lightness. */
  --grass-ink:#308234;    /* fills that carry WHITE text. 4.81:1 */
  --grass-text:#297F2F;   /* GREEN text on light surfaces. 4.61:1 on grass-50, 4.82:1 on cream */
  --grass-900:#2C7730;    /* deepest. gradient ends and hover on grass-ink. 5.54:1 */

  /* Small green type sitting ON a liquid glass pane. The pane is only
     80% opaque, so a constellation node behind it lifts the effective
     background to about #DCD9EB, and at that point --grass-text falls to
     4.32:1. This is the one green dark enough to hold 4.5:1 there. Used
     by the section kickers and the phase labels, both 12 to 16px, both
     over glass. On a solid surface prefer --grass-text, which is lighter
     and closer to the brand. */
  --grass-kicker:#216726;

  --grass-50:#ECF8ED;     /* green pill and chip backgrounds */
  --grass-border:#CDEBCF; /* was hardcoded in site.css. now a token */
  --arrow-neon:#39E703;   /* logo arrow only. tiny accents, never large fills */
  --mint:#7CD98A;         /* green accent on dark backgrounds */

  /* ---- neutrals ---- */
  --ink:#14162B;
  --ink-2:#4B4E66;
  /* ink-3 was #797C92, which read 4.11:1 on white and 3.81:1 on the
     field background. Both fail. Darkened until the tightest pairing
     (on --field) clears 4.5:1. Now 5.00:1 on white, 4.63:1 on field. */
  --ink-3:#6C6E84;
  --line:#E7E8F0;
  --field:#F5F6FB;
  --cream:#FBFAF6;
  --paper:#FFFFFF;

  /* ---- feedback. these were hardcoded in site.css ---- */
  --error-border:#D5573B;
  --error-text:#C0392B;   /* 5.44:1 on white */

  /* ---- accent tints, used by the pillar tiles ---- */
  --tint-amber-bg:#FFEAD8;  --tint-amber-fg:#C2521F;
  --tint-gold-bg:#FFF2CC;   --tint-gold-fg:#977200;
  --tint-violet-bg:#EADBF3; --tint-violet-fg:#7656A2;

  /* ---- semantic roles ----
     The ui-ux-pro-max rule `color-semantic` asks components to name a
     role, not a brand colour. Restyling then happens here rather than
     in forty selectors. The brand names above stay for the places that
     genuinely mean "the Kwirkz navy". */
  --color-primary:var(--navy);
  --color-primary-hover:var(--navy-700);
  --color-on-primary:#FFFFFF;
  --color-secondary:var(--grass-ink);
  --color-secondary-hover:var(--grass-900);
  --color-on-secondary:#FFFFFF;
  --color-surface:var(--paper);
  --color-surface-sunken:var(--cream);
  --color-on-surface:var(--ink);
  --color-on-surface-muted:var(--ink-2);
  --color-on-surface-faint:var(--ink-3);
  --color-border:var(--line);
  --color-ring:var(--navy);
  --color-error:var(--error-text);
  --color-error-border:var(--error-border);

  /* ---- type families ----
     RESTORED 2026-07-18. The audit pass that added the scale below
     dropped these three, and site.css references them in 14 places,
     so every heading, label and paragraph on the site fell back to
     Times. See DESIGN.md, "Typography": the role separation is the
     most rule-bound part of this design. Do not remove these without
     rewriting those 14 call sites first. */
  --display:"Curse Casual","Nunito",system-ui,sans-serif;
  --heading:"Nunito",system-ui,sans-serif;
  --body:"DM Sans",system-ui,sans-serif;

  /* ---- type scale ----
     The site had grown 11px, 11.5px, 12.5px, 13.5px and 15.5px sizes
     with no system behind them, which the rule `font-scale` calls out.
     Nothing sits below 12px now. The audience here is the one least
     able to absorb 11px fine print. */
  --fs-caption:12px;
  --fs-label:13px;
  --fs-sm:14px;
  --fs-base:16px;   /* also the iOS auto-zoom floor for form fields */
  --fs-md:17px;
  --fs-lg:18px;
  --fs-xl:21px;
  --fs-2xl:24px;

  --lh-tight:1.15;
  --lh-body:1.55;

  /* ---- liquid glass ----
     The scrim that carries copy over the neural canvas. This is Liquid
     Glass, not Glassmorphism, and the difference is the whole point:
     frosted glass is a heavy uniform blur that turns the backdrop milky
     and grey. Liquid glass barely blurs at all. It stays CLEAR and
     instead bends the light, so the constellation reads as a real thing
     seen through a real pane rather than as fog.

     Four ingredients carry that read, and none of them is blur:
       saturate  pushes the navy and grass behind the pane back to full
                 strength. Frosting drains colour, glass concentrates it.
       brightness a touch of gather, the way a lens pools light
       specular   a bright top edge and a dark bottom edge. This is the
                 single strongest cue that a surface is glass, and it is
                 what frosted panels lack
       sheen      one diagonal highlight sweeping the pane

     The tint alpha is a HARD FLOOR, not a taste setting. Dropping the
     blur means a constellation node stays sharp behind the copy instead
     of being smeared toward cream, so the tint is the only thing left
     holding text contrast. Worst case is a navy node at the canvas's
     own .7 opacity sitting directly behind a line of body copy. At .80
     that pairing measures 5.7:1 for --ink-2. Below about .74 it breaks.
     If you lower this, re-measure before shipping. */
  --glass-tint:251,250,246;       /* cream, as channels, so alpha can vary */
  --glass-alpha:.80;
  --glass-alpha-solid:.93;        /* where backdrop-filter is unavailable */
  --glass-blur:3px;               /* clear, not frosted. was 7px of fog */
  --glass-saturate:185%;
  --glass-brightness:1.04;
  --glass-edge:rgba(255,255,255,.62);      /* the rim */
  --glass-specular:rgba(255,255,255,.92);  /* the lit top edge */
  --glass-refract:rgba(28,19,98,.07);      /* navy pooling at the bottom edge */
  --glass-lift:0 10px 34px -20px rgba(28,19,98,.30);
  /* Liquid Glass moves at 400 to 600ms, slower than UI micro-motion,
     because it reads as a material settling rather than a control
     responding. */
  --glass-morph:520ms;

  /* ---- radius ---- */
  --r-field:12px;
  --r:16px;
  --r-lg:24px;
  --r-pill:999px;

  /* ---- shadow ---- */
  --shadow-sm:0 1px 2px rgba(20,22,43,.05), 0 4px 14px -6px rgba(20,22,43,.10);
  --shadow-md:0 8px 24px -14px rgba(28,19,98,.22);
  --shadow-lg:0 30px 70px -28px rgba(20,22,43,.30);

  /* ---- motion ----
     Rule `duration-timing` puts micro-interactions at 150 to 300ms and
     `motion-consistency` asks every animation to share one rhythm.
     The site was running 80ms to 140ms transitions, which read as a
     snap rather than a response. */
  --dur-fast:150ms;
  --dur:200ms;
  --dur-slow:280ms;
  --ease-out:cubic-bezier(.22,.61,.36,1);
  --ease-in:cubic-bezier(.55,.06,.68,.19);

  /* ---- layout ---- */
  --wrap:1140px;
  --gutter:24px;
  --tap:44px;       /* the tap-target floor. Apple HIG 44pt, Material 48dp */

  /* ---- z-index scale ----
     Rule `z-index-management`. Declared once so nothing invents a 9999. */
  --z-base:0;
  --z-raised:10;
  --z-sticky:50;
  --z-overlay:100;
}

/* Safe-area aware gutter. On a notched phone in landscape the system
   inset is non-zero and full-bleed content would otherwise sit under the
   rounded corner or the camera housing. The plain --gutter is the
   fallback for every browser without env() support. */
:root{
  --gutter-safe-l:var(--gutter);
  --gutter-safe-r:var(--gutter);
}
@supports(padding:max(0px)){
  :root{
    --gutter-safe-l:max(var(--gutter), env(safe-area-inset-left));
    --gutter-safe-r:max(var(--gutter), env(safe-area-inset-right));
  }
}
