/* ═══════════════════════════════════════════════════════════════════════════
   Orcyx site — atmosphere. Hand-maintained (see apps/site/AGENTS.md).

   WHY THIS EXISTS. The pages read flat: a near-black field, hairline cards
   and captures that are mostly blur (operator, 2026-09-24: "it looks really
   dull"). This sheet is the shared light for every page — an aurora fixed
   behind the content, a grain overlay that breaks the digital flatness, lit
   card surfaces with a colour-tinted depth shadow, and the live theme's
   colour washed over the spotlit captures. convert-comps.mjs links it on
   every generated page and help-pages.mjs on the help/legal/docs set,
   AFTER each page's own <style>, so an equal-specificity rule here wins.

   RULES
   - Every colour is a color-mix() of --accent / --fg / --bg / --card. The
     theme picker retokens :root live (site.js setThemeVars) and this sheet
     must follow it on all 65 themes, the light ones included — never a flat
     hex here.
   - --accent-2 is the accent turned 42° in OKLCH (relative colour syntax).
     A browser without it falls back to the accent itself through
     var(--accent-2, var(--accent)); nothing may DEPEND on the second hue.
   - Nothing here takes pointer events, changes layout, or writes
     [data-reveal]'s inline opacity/transform (site.js reveals() owns those).
   - Card rules key off the comps' own inline signature
     (background:var(--card) + border:1px solid var(--bf)) because the comps
     carry no class names. A card whose inline style changes drops out of the
     treatment; it never breaks. The build steps ([data-steps] > *) are
     excluded: the landing helmet paints their own accent line.
   - Every !important below exists to beat an inline style, and only for
     that. Do not add one to beat another stylesheet.
   ═══════════════════════════════════════════════════════════════════════════ */

@supports (color: oklch(from red l c h)) {
  :root { --accent-2: oklch(from var(--accent) l c calc(h + 42)); }
}

/* ── Aurora: one broad wash top-left and one low band bottom-right, both
   elongated and centred off-canvas. Never two round pools side by side: the
   pair read as a face (operator, 2026-09-24: "looks like an eye"). ────────
   body isolates so z-index:-1 sits above the body background and below every
   section (the sections that are positioned carry z-index:2 already).
   Every comp opens with a full-page <div style="min-height:100vh;
   background:var(--bg)…"> that repainted the same --bg html/body already
   paint, over the aurora: it never reached the screen on any page
   (2026-09-24, pixel-identical with the layer removed). The wrapper goes
   clear so the wash shows; the field underneath is still body's --bg.
   No filter: the gradients already fade to transparent and the layer's edges
   sit off-canvas, so blur(40px) changed no pixel by more than 3/255. Without
   it the visible wash costs the same LCP the hidden, blurred one did (home,
   mobile lab: median 1,896 vs 1,892 ms cold, 730 vs 722 ms warm GPU cache). */
body > div[style^="min-height:100vh;background:var(--bg)"] { background: transparent !important; }
body { position: relative; isolation: isolate; }
body::before {
  content: "";
  position: fixed;
  inset: -24vh -12vw;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(95% 55% at 12% -8%, color-mix(in srgb, var(--accent) 22%, transparent) 0%, transparent 70%),
    radial-gradient(120% 34% at 110% 108%, color-mix(in srgb, var(--accent-2, var(--accent)) 14%, transparent) 0%, transparent 70%);
  transform: translate3d(0, 0, 0);
  animation: orx-aurora 32s ease-in-out infinite alternate;
}
@keyframes orx-aurora {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(3vw, -2vh, 0) scale(1.06); }
  100% { transform: translate3d(-2vw, 2vh, 0) scale(1.02); }
}

/* ── Grain: a fixed noise overlay above the content, under the sticky header
   (z-index 100) and the palette veil (9999). overlay blend reads on paper
   themes too; the opacity keeps it a texture, not a fog. ──────────────────── */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: .07;
  mix-blend-mode: overlay;
}

/* ── Cards: a surface lit from the top, a hairline that catches that light,
   and a depth shadow in the accent instead of plain black. Hover swaps the
   hairline to the accent; the comps' own hover lift (transform) still runs. */
[style*="background:var(--card)"][style*="border:1px solid var(--bf)"]:not([data-steps] > *) {
  border-color: transparent !important;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--fg) 7%, var(--card)) 0%, var(--card) 46%) padding-box,
    linear-gradient(180deg, color-mix(in srgb, var(--fg) 26%, transparent), color-mix(in srgb, var(--fg) 8%, transparent) 55%, color-mix(in srgb, var(--fg) 10%, transparent)) border-box !important;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 7%, transparent),
    0 1px 2px rgba(0, 0, 0, .35),
    0 26px 52px -30px color-mix(in srgb, var(--accent) 36%, #000) !important;
}
[style*="background:var(--card)"][style*="border:1px solid var(--bf)"]:not([data-steps] > *):hover {
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--fg) 7%, var(--card)) 0%, var(--card) 50%) padding-box,
    linear-gradient(180deg, color-mix(in srgb, var(--accent) 62%, transparent), color-mix(in srgb, var(--accent) 16%, transparent) 62%, color-mix(in srgb, var(--accent-2, var(--accent)) 24%, transparent)) border-box !important;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 9%, transparent),
    0 1px 2px rgba(0, 0, 0, .35),
    0 30px 60px -28px color-mix(in srgb, var(--accent) 50%, #000) !important;
}

/* ── Motion + small screens ────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
}
