/* ─── The site light source ────────────────────────────────────────────────
   ONE definition of the top-of-page glow + dot field, shared by:
     • the static pages  — via `@import` in static-theme.css (body::before)
     • the React landing — via <link> in index.html, applied as `.site-light`
   Both load this file, so the landing hero and the marketing pages are lit by
   the same light. Change it here and it changes everywhere.

   Composition — a light source, not a centred blob:
     RIM   a tight bright band at the very top edge, where light enters
     KEY   the main source, left of centre, pushed above the edge so only its
           lower falloff is on screen
     FILL  cooler + dimmer, offset right, in the cyan the dot field fades
           toward — two hues read as one light with depth; one hue reads flat
     DOTS  the 14px teal lattice, held at 6% so it's atmosphere, not pattern

   Two details doing most of the work:

   1. `in oklab` interpolation, fading to a zero-alpha version of the SAME
      colour — never the `transparent` keyword. `transparent` is sRGB
      transparent-BLACK, so a teal→transparent ramp passes through muddy grey
      on the way out and fringes the edge of the glow. This is the single most
      common tell of a stock CSS glow.

   2. Falloff is multi-stop and front-loaded (bright core, long thin tail),
      approximating inverse-square. A two-stop ramp falls off linearly, which
      is what makes a glow look flat and stuck-on.
   ────────────────────────────────────────────────────────────────────────── */

:root {
  /* The glow. Shared verbatim by the hero and the static pages — this is the
     part that must look identical everywhere. */
  --site-glow:
    /* RIM — the edge the light enters through. Taller and dimmer than a true
       specular rim so it blends into the key instead of banding against it. */
    radial-gradient(
        ellipse 1280px 190px at 46% -30px in oklab,
        oklch(0.86 0.12 182 / 0.16) 0%,
        oklch(0.84 0.12 184 / 0.09) 45%,
        oklch(0.82 0.11 186 / 0) 100%
      )
      no-repeat,
    /* KEY — the main source. Tall and wide, pushed well above the edge so the
       page only sees its long lower falloff, never the hot core. */
    radial-gradient(
        ellipse 1320px 980px at 38% -20% in oklab,
        oklch(0.82 0.12 181 / 0.17) 0%,
        oklch(0.79 0.11 183 / 0.1) 26%,
        oklch(0.76 0.09 186 / 0.05) 48%,
        oklch(0.73 0.07 189 / 0.018) 68%,
        oklch(0.7 0.06 192 / 0) 88%
      )
      no-repeat,
    /* FILL — cooler, dimmer, offset right. Gives the light depth; a single hue
       reads flat no matter how well it falls off. */
    radial-gradient(
        ellipse 1120px 820px at 76% -26% in oklab,
        oklch(0.8 0.09 208 / 0.1) 0%,
        oklch(0.77 0.08 212 / 0.05) 34%,
        oklch(0.74 0.06 215 / 0.016) 60%,
        oklch(0.72 0.05 218 / 0) 84%
      )
      no-repeat;

  /* The dot lattice, in pure CSS. Static pages only — see the note below. */
  --site-dots: radial-gradient(circle at center, rgba(43, 212, 189, 0.06) 1.5px, transparent 1.6px)
    0 0 / 14px 14px;

  /* ── Primary button surface — the Figma "designed light source" bevel ──────
     One definition, consumed by every primary button on the site:
       • React  — primaryCta / iconButton (src/lib/button-hover.ts), via
                  Tailwind `shadow-[var(--thq-btn-shadow)]`
       • static — .thq-cta (the nav CTA on all 18 pages, static-chrome.css)
       • test   — .btn-primary (public/test/index.html)
     All three load this file (index.html <link>, static-theme.css @import), so
     the button catches light identically everywhere. Change it here, changes
     everywhere.

     The stack, top layer first, matching the Figma node exactly:
       inset top rim   — a crisp 1px white bevel where the light hits the edge
       inset top glow   — a soft 24px white wash down the upper half (the gloss)
       inset bottom     — a 1px dark edge, so the pill reads as a raised solid
       + two neutral drop shadows — the elevation that lifts it off the page.
     Neutral drops, not a teal glow: elevation reads premium; a coloured haze
     reads as the stock "AI glow". */
  --thq-btn-shadow:
    inset 0 1px 0.5px 0 rgba(255, 255, 255, 0.25),
    inset 0 24px 24px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0.5px 0 rgba(0, 0, 0, 0.25),
    0 1px 1px 0 rgba(0, 0, 0, 0.14),
    0 3px 2px 0 rgba(0, 0, 0, 0.07);

  /* Hover — the pill lifts (the transform lives with each consumer), so only
     the two OUTER drop-shadow layers grow. The three inset (bevel) layers are
     kept byte-identical to the base above on purpose: during the transition the
     browser only has to re-interpolate the cheap outer drops, not re-rasterise
     the 24px inset blur every frame. That per-frame inset re-raster is what made
     the hover flicker on weaker GPUs. */
  --thq-btn-shadow-hover:
    inset 0 1px 0.5px 0 rgba(255, 255, 255, 0.25),
    inset 0 24px 24px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0.5px 0 rgba(0, 0, 0, 0.25),
    0 4px 8px -1px rgba(0, 0, 0, 0.18),
    0 10px 20px -4px rgba(0, 0, 0, 0.12);
}

/* GLOW ONLY. Used by the landing hero, which draws its dots with the real
   <DotField> canvas instead — those dots are cursor-interactive (they bulge
   away from the pointer), and the CSS lattice cannot do that. Stacking both
   would double the dots, so the hero takes the glow and nothing else. */
.site-glow {
  background: var(--site-glow);
}

/* GLOW + CSS DOTS. The static marketing pages, which have no canvas and no
   reason to ship the effects engine for a texture nobody reads as interactive.
   Painted on body::before — see static-theme.css. */
.site-light,
:root {
  --site-light-bg: var(--site-glow), var(--site-dots);
}

.site-light {
  background: var(--site-light-bg);
}
