/* fx-bg · per-section interactive backgrounds. Pair with fx-bg.js.
   Everything sits under the content (z-index -1 inside an isolated section). */
.fx-bg-host { position: relative; isolation: isolate; }
.fx-bg { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; contain: strict; }
.fx-bg canvas { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; display: block; }
/* off screen (fx-bg.js adds .is-idle): CSS keyframes stop, so nothing ticks for a layer nobody sees */
.fx-bg.is-idle::before, .fx-bg.is-idle::after, .fx-bg.is-idle i { animation-play-state: paused; }
/* every background fades out at the section edges so neighbours never collide */
.fx-bg { -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent); mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent); }
/* …or, over a flat colour, the same fade from two strips (fx-bg.js decides): no offscreen GPU pass */
.fx-bg.fx-bg--edges { -webkit-mask-image: none; mask-image: none; }
.fx-bg .fx-bg__edge { position: absolute; z-index: 1; left: 0; right: 0; inline-size: auto; block-size: 12%; }
.fx-bg .fx-bg__edge--t { top: 0; background: linear-gradient(180deg, var(--fx-edge), transparent); }
.fx-bg .fx-bg__edge--b { top: auto; bottom: 0; background: linear-gradient(0deg, var(--fx-edge), transparent); }

/* ---- spotlight (modes): fine grid lit around the cursor ---------------------
   The lamp is a small pre-masked square that fx-bg.js moves with transforms; the
   grid inside it is moved back the other way so the lines stay put. Nothing is
   repainted while it moves (compositor only). */
.fx-bg--spotlight, .fx-bg--shield { container-type: size; }
.fx-bg i { position: absolute; display: block; left: 0; top: 0; }
.fx-bg__move { inline-size: 100cqw; block-size: 100cqh; will-change: transform; }
.fx-sl__spot {
  inline-size: 760px; block-size: 760px; overflow: hidden; will-change: transform;            /* 2 × 380 px */
  transform: translate3d(calc(50cqw - 380px), calc(40cqh - 380px), 0);
  -webkit-mask-image: radial-gradient(circle 380px at 50% 50%, #000, transparent 75%);
  mask-image: radial-gradient(circle 380px at 50% 50%, #000, transparent 75%);
}
.fx-sl__grid {
  inline-size: 100%; block-size: 100%;
  background-image:
    linear-gradient(rgba(255,255,255,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.07) 1px, transparent 1px);
  background-size: 44px 44px; background-position: center;
}
.fx-sl__glow {
  inline-size: 600px; block-size: 600px; will-change: transform;                              /* 2 × 300 px */
  transform: translate3d(calc(50cqw - 300px), calc(40cqh - 300px), 0);
  background: radial-gradient(circle 300px at 50% 50%, rgb(var(--orange-rgb) / .13), transparent 70%);
  opacity: .55; transition: opacity .6s;
}
.fx-bg--spotlight.is-on .fx-sl__glow { opacity: 1; }

/* ---- shield (privacy): hexes with a few locks, drifting, under a vignette --
   The whole pattern shows at 12 %; a 1040 px lamp (moved with transforms, like
   the spotlight) adds the rest near the cursor: 100 % at the centre, 35 % at
   60 % of the radius. Both copies drift together (same keyframes, same start). */
.fx-bg .fx-sh__pat {
  left: -104px; top: -104px; inline-size: calc(100cqw + 208px); block-size: calc(100cqh + 208px); will-change: transform;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='104' viewBox='0 0 120 104'%3E%3Cg fill='none' stroke='%23fff' stroke-opacity='.08' stroke-width='1'%3E%3Cpath d='M30 2h60l30 50-30 50H30L0 52z'/%3E%3C/g%3E%3Cg fill='none' stroke='%23ff6a00' stroke-opacity='.22' stroke-width='1.3' stroke-linecap='round'%3E%3Crect x='53' y='50' width='14' height='11' rx='2.5'/%3E%3Cpath d='M56 50v-3.5a4 4 0 0 1 8 0V50'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 120px 104px;
  animation: fx-bg-drift 60s linear infinite;
}
.fx-sh__base { opacity: .12; }
.fx-sh__spot {
  inline-size: 1040px; block-size: 1040px; overflow: hidden; will-change: transform;          /* 2 × 520 px */
  transform: translate3d(calc(50cqw - 520px), calc(50cqh - 520px), 0);
  -webkit-mask-image: radial-gradient(circle 520px at 50% 50%, rgba(0,0,0,.88) 0%, rgba(0,0,0,.23) 60%, transparent 100%);
  mask-image: radial-gradient(circle 520px at 50% 50%, rgba(0,0,0,.88) 0%, rgba(0,0,0,.23) 60%, transparent 100%);
}
.fx-bg--shield::after { content: ""; position: absolute; inset: 0; background: radial-gradient(120% 90% at 50% 50%, transparent 40%, rgba(0,0,0,.55) 100%); }
@keyframes fx-bg-drift { to { transform: translate3d(120px, 104px, 0); } }

/* ---- mesh (FAQ): three soft fields breathing very slowly ------------------- */
.fx-bg--mesh { --mx: 50%; --my: 50%; }
.fx-bg--mesh::before, .fx-bg--mesh::after { content: ""; position: absolute; border-radius: 50%; will-change: transform; }
.fx-bg--mesh::before {
  inline-size: 70vmax; aspect-ratio: 1; inset-block-start: -30%; inset-inline-start: -15%;
  background: radial-gradient(closest-side, rgb(var(--orange-rgb) / .16), rgba(217,79,0,.06) 55%, transparent 72%);
  animation: fx-bg-mesh1 34s ease-in-out infinite alternate;
}
.fx-bg--mesh::after {
  inline-size: 60vmax; aspect-ratio: 1; inset-block-end: -35%; inset-inline-end: -12%;
  background: radial-gradient(closest-side, rgba(255,255,255,.05), rgba(232,93,0,.07) 45%, transparent 72%);
  animation: fx-bg-mesh2 42s ease-in-out infinite alternate;
}
@keyframes fx-bg-mesh1 { to { transform: translate3d(18%, 14%, 0) scale(1.15); } }
@keyframes fx-bg-mesh2 { to { transform: translate3d(-16%, -10%, 0) scale(.9); } }

@media (prefers-reduced-motion: reduce) {
  .fx-bg::before, .fx-bg::after, .fx-bg i { animation: none !important; transition: none !important; }
}
