/* ============================================================
   Catalyst Bridge — Texture layer (texture.css)
   The single fastest lift from "AI slop" to "designed with care".
   Zero dependencies, pure CSS + one inline SVG grain. No particle
   libs (tsParticles is banned), no runtime JS, near-zero weight.

   Load order:  design.css -> brand.css -> kit.css -> texture.css
   Everything here is brand-tinted from --brand-* tokens, so it
   changes per client automatically and never fights a direction.

   Backdrops sit at z-index:0 behind content; content must sit at
   z-index:1+. All decorative, so aria-hidden + pointer-events:none.
   Reduced-motion safe: everything is static.
   ============================================================ */

:root {
  /* Grain tile — greyscale fractal noise, tiles seamlessly. */
  --tex-grain-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  --tex-grain-opacity: 0.07;   /* per-direction tuned below */
  --tex-grain-size: 170px;
  --tex-mesh-strength: 55%;     /* how saturated the brand blobs read */
  --tex-mesh-fade: 62%;         /* how far each blob reaches before transparent */
}

/* ---- Brand-tinted mesh backdrop -------------------------------
   <div class="tex-mesh" aria-hidden="true"></div> behind a hero/section.
   Three soft radial blobs off the brand palette over the page surface. */
.tex-mesh {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  background-color: var(--surface-page, #f4f4f5);
  background-image:
    radial-gradient(46% 58% at 14% 16%,
      color-mix(in oklab, var(--brand-primary, #3a3a3c) var(--tex-mesh-strength), transparent) 0%,
      transparent var(--tex-mesh-fade)),
    radial-gradient(40% 52% at 88% 10%,
      color-mix(in oklab, var(--brand-accent, var(--brand-primary, #3a3a3c)) calc(var(--tex-mesh-strength) - 8%), transparent) 0%,
      transparent calc(var(--tex-mesh-fade) - 6%)),
    radial-gradient(54% 64% at 80% 94%,
      color-mix(in oklab, var(--brand-primary-700, var(--brand-primary, #3a3a3c)) calc(var(--tex-mesh-strength) - 14%), transparent) 0%,
      transparent var(--tex-mesh-fade));
}

/* ---- Grain overlay --------------------------------------------
   Add `tex-grain` to any positioned element (or the .tex-mesh) to
   drop a film-grain layer over it. Blends into whatever is beneath. */
.tex-grain::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image: var(--tex-grain-url);
  background-size: var(--tex-grain-size) var(--tex-grain-size);
  opacity: var(--tex-grain-opacity);
  mix-blend-mode: overlay;
}

/* ---- Technical grid backdrop (D3 / D5) ------------------------ */
.tex-grid {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(color-mix(in oklab, var(--brand-primary, #3a3a3c) 10%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in oklab, var(--brand-primary, #3a3a3c) 10%, transparent) 1px, transparent 1px);
  background-size: 48px 48px;
  -webkit-mask-image: radial-gradient(80% 80% at 50% 40%, #000 40%, transparent 100%);
          mask-image: radial-gradient(80% 80% at 50% 40%, #000 40%, transparent 100%);
}

/* ---- Halftone dots (D6 / D7) ---------------------------------- */
.tex-halftone {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(color-mix(in oklab, var(--brand-primary, #3a3a3c) 22%, transparent) 1.4px, transparent 1.6px);
  background-size: 14px 14px;
  opacity: 0.5;
}

/* ---- Soft vignette (depth on dark / photographic sections) ---- */
.tex-vignette::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(120% 120% at 50% 40%, transparent 55%, rgba(0,0,0,0.28) 100%);
}

/* ---- Hero atmosphere helper -----------------------------------
   <div class="hero__atmos tex-mesh tex-grain" aria-hidden="true"></div>
   as the first child of a .hero puts brand mesh + grain behind it.
   Keep .hero__inner at z-index:2 (kit.css already does). */
.hero__atmos { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }

/* ============================================================
   Per-direction texture character. Each direction wants a
   different amount and kind of texture, tuned by tokens so the
   same .tex-* classes read correctly under any data-direction.
   ============================================================ */

/* D1 Brutalist — raw, heavier grain, no soft mesh blur. */
[data-direction="d1-brutalist"] { --tex-grain-opacity: 0.11; --tex-mesh-strength: 30%; }

/* D2 Editorial — restrained warm paper grain, barely-there mesh. */
[data-direction="d2-editorial"] { --tex-grain-opacity: 0.05; --tex-mesh-strength: 26%; --tex-mesh-fade: 70%; }

/* D3 Swiss Tech — precise, low grain; pairs with .tex-grid. */
[data-direction="d3-swiss-tech"] { --tex-grain-opacity: 0.04; --tex-mesh-strength: 34%; }

/* D4 Organic Wellness — the showcase: soft generous brand mesh + gentle grain. */
[data-direction="d4-organic-wellness"] { --tex-grain-opacity: 0.06; --tex-mesh-strength: 60%; --tex-mesh-fade: 66%; }

/* D5 Future HUD — glow mesh over dark; grain reads as sensor noise. */
[data-direction="d5-future-hud"] { --tex-grain-opacity: 0.10; --tex-mesh-strength: 48%; --tex-mesh-fade: 58%; }

/* D6 Newsprint — paper grain + optional halftone. */
[data-direction="d6-newsprint"] { --tex-grain-opacity: 0.08; --tex-mesh-strength: 20%; }

/* D7 Y2K Pop — punchy mesh, visible grain. */
[data-direction="d7-y2k-pop"] { --tex-grain-opacity: 0.09; --tex-mesh-strength: 66%; --tex-mesh-fade: 60%; }

/* D8 Heritage — aged paper; kit.css already adds body noise, keep mesh soft. */
[data-direction="d8-heritage"] { --tex-grain-opacity: 0.06; --tex-mesh-strength: 34%; }

/* Honour reduced-transparency / forced-colours: drop decorative layers. */
@media (prefers-reduced-transparency: reduce) {
  .tex-grain::after, .tex-halftone, .tex-vignette::before { display: none; }
}
@media (forced-colors: active) {
  .tex-mesh, .tex-grid, .tex-halftone { background: Canvas; }
  .tex-grain::after, .tex-vignette::before { display: none; }
}
