/* ============================================================================
   CODE QUEST — fx.css   [NEW FILE]

   The ambient atmosphere layer: aurora bloom, drifting particles, vignette,
   scanlines, and the reusable glass / glow / frame utilities that give every
   page the same material language.

   Performance rules this file obeys:
   - every animated property is transform, opacity or filter (compositor-only)
   - nothing here paints above z-index 0, so it can never intercept a click
   - all of it is switched off by prefers-reduced-motion at the bottom
   - the particle canvas is sized and throttled by js/core/fx.js, not by CSS
   ========================================================================== */

/* ============================================================================
   1. FX STAGE — the fixed container every ambient layer lives in
   ========================================================================== */

.cq-fx {
  position: fixed;
  inset: 0;
  z-index: var(--z-fx);
  overflow: hidden;
  pointer-events: none;
  contain: strict;
}

/* ---------- Aurora: three slow, huge, coloured blooms ---------- */

/* inset: 0, not a negative inset. The blooms inside are already far larger
   than the box and are positioned with their own negative offsets, so the
   layer has all the room it needs; a container wider than the viewport, on
   the other hand, gets counted in document.scrollWidth even though .cq-fx
   clips it — which reads as a horizontal overflow at 320px and 390px. */
.cq-fx__aurora {
  position: absolute;
  inset: 0;
  opacity: var(--fx-aurora-opacity);
  will-change: transform;
}

.cq-fx__aurora span {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(80px);
  mix-blend-mode: screen;
}

/* Cyan — top left, the largest */
.cq-fx__aurora span:nth-child(1) {
  width: 58vmax;
  height: 58vmax;
  top: -14%;
  left: -10%;
  background: radial-gradient(
    circle,
    rgba(63, 201, 247, 0.4) 0%,
    rgba(63, 201, 247, 0.14) 42%,
    transparent 70%
  );
  animation: cq-aurora-a 34s var(--ease-in-out-soft) infinite;
}

/* Violet — right, mid height */
.cq-fx__aurora span:nth-child(2) {
  width: 46vmax;
  height: 46vmax;
  top: 8%;
  right: -14%;
  background: radial-gradient(
    circle,
    rgba(157, 140, 255, 0.3) 0%,
    rgba(157, 140, 255, 0.1) 44%,
    transparent 70%
  );
  animation: cq-aurora-b 44s var(--ease-in-out-soft) infinite;
}

/* Gold — bottom, warms the lower third */
.cq-fx__aurora span:nth-child(3) {
  width: 52vmax;
  height: 52vmax;
  bottom: -20%;
  left: 24%;
  background: radial-gradient(
    circle,
    rgba(239, 189, 87, 0.2) 0%,
    rgba(239, 189, 87, 0.07) 46%,
    transparent 72%
  );
  animation: cq-aurora-c 52s var(--ease-in-out-soft) infinite;
}

@keyframes cq-aurora-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  33%      { transform: translate3d(6vw, 4vh, 0) scale(1.13); }
  66%      { transform: translate3d(-3vw, 7vh, 0) scale(0.94); }
}

@keyframes cq-aurora-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  40%      { transform: translate3d(-7vw, 6vh, 0) scale(1.18); }
  70%      { transform: translate3d(-2vw, -4vh, 0) scale(0.9); }
}

@keyframes cq-aurora-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(5vw, -6vh, 0) scale(1.15); }
}

/* ---------- Particle canvas: drawn by js/core/fx.js ---------- */

.cq-fx__particles {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.85;
  mix-blend-mode: screen;
}

/* ---------- Logic grid: a faint technical lattice, parallaxed ---------- */

.cq-fx__grid {
  position: absolute;
  /* inset: 0 for the same reason as the aurora — the lattice is a repeating
     tile, so it needs no bleed to drift over. */
  inset: 0;
  background-image:
    linear-gradient(rgba(122, 221, 255, 0.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(122, 221, 255, 0.055) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 0%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 40%, #000 0%, transparent 78%);
  will-change: transform;
}

/* ---------- Vignette: pulls focus to the middle of the screen ---------- */

.cq-fx__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 96% 78% at 50% 44%,
    transparent 42%,
    rgba(3, 6, 15, calc(var(--fx-vignette) * 0.55)) 78%,
    rgba(3, 6, 15, var(--fx-vignette)) 100%
  );
}

/* ---------- Horizon: a bright seam of energy low on the screen ---------- */

.cq-fx__horizon {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 12%;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(122, 221, 255, 0.22) 22%,
    rgba(122, 221, 255, 0.5) 50%,
    rgba(122, 221, 255, 0.22) 78%,
    transparent
  );
  filter: blur(0.5px);
  box-shadow: 0 0 34px rgba(63, 201, 247, 0.3);
  animation: cq-horizon-breathe 9s var(--ease-in-out-soft) infinite;
}

@keyframes cq-horizon-breathe {
  0%, 100% { opacity: 0.45; transform: scaleX(0.94); }
  50%      { opacity: 0.9;  transform: scaleX(1); }
}

/* ============================================================================
   2. PARALLAX — js/core/fx.js writes --px / --py (range roughly -1 … 1)
   Each depth step multiplies those by a different amount.
   ========================================================================== */

.cq-parallax {
  --px: 0;
  --py: 0;
}

[data-parallax] {
  transform: translate3d(
    calc(var(--px, 0) * var(--fx-parallax-depth) * var(--depth, 1)),
    calc(var(--py, 0) * var(--fx-parallax-depth) * var(--depth, 1)),
    0
  );
  transition: transform 700ms var(--ease-out-expo);
  will-change: transform;
}

[data-parallax='near']  { --depth: 0.4; }
[data-parallax='mid']   { --depth: 1; }
[data-parallax='far']   { --depth: 2.1; }
[data-parallax='deep']  { --depth: 3.4; }

/* ============================================================================
   3. GLASS — the panel material, as utilities
   ========================================================================== */

.cq-glass {
  background: var(--glass-fill);
  border: var(--border-hair) solid var(--glass-edge);
  box-shadow: var(--elev-2), var(--glass-lip);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.25);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.25);
}

.cq-glass--strong {
  background: var(--glass-fill-strong);
  border-color: var(--glass-edge-hi);
  box-shadow: var(--elev-3), var(--glass-lip-strong);
  backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.3);
  -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.3);
}

.cq-glass--soft {
  background: var(--glass-fill-soft);
  box-shadow: var(--elev-1), var(--glass-lip);
  backdrop-filter: blur(12px) saturate(1.15);
  -webkit-backdrop-filter: blur(12px) saturate(1.15);
}

/* ============================================================================
   4. FRAME — the donghua "energy corner" treatment.
   A hairline top seam plus four L-shaped corner brackets. Applied to any
   element that should read as a piece of the world's interface.
   ========================================================================== */

.cq-frame {
  position: relative;
}

/* Top seam: light catching the upper lip of the panel. */
.cq-frame::before {
  content: '';
  position: absolute;
  inset-inline: 12%;
  top: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--cyan-400) 30%,
    var(--gold-300) 70%,
    transparent
  );
  opacity: 0.7;
  pointer-events: none;
}

/* Corner brackets, drawn with a conic-free technique so they stay crisp. */
.cq-frame__corners {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
}

.cq-frame__corners span {
  position: absolute;
  width: 16px;
  height: 16px;
  border: var(--border-thin) solid var(--cyan-400);
  opacity: 0.55;
  transition: opacity var(--dur-mid) var(--ease-out-expo),
    width var(--dur-mid) var(--ease-out-expo),
    height var(--dur-mid) var(--ease-out-expo);
}

.cq-frame__corners span:nth-child(1) {
  top: 7px; left: 7px;
  border-right: 0; border-bottom: 0;
  border-top-left-radius: 5px;
}
.cq-frame__corners span:nth-child(2) {
  top: 7px; right: 7px;
  border-left: 0; border-bottom: 0;
  border-top-right-radius: 5px;
}
.cq-frame__corners span:nth-child(3) {
  bottom: 7px; left: 7px;
  border-right: 0; border-top: 0;
  border-bottom-left-radius: 5px;
}
.cq-frame__corners span:nth-child(4) {
  bottom: 7px; right: 7px;
  border-left: 0; border-top: 0;
  border-bottom-right-radius: 5px;
}

/* Brackets extend on hover — a small, cheap sign of interactivity. */
.cq-frame:hover > .cq-frame__corners span,
.cq-frame:focus-within > .cq-frame__corners span {
  opacity: 0.95;
  width: 22px;
  height: 22px;
}

.cq-frame--gold .cq-frame__corners span {
  border-color: var(--gold-400);
}

/* ============================================================================
   5. GLOW UTILITIES
   ========================================================================== */

.cq-glow-cyan { box-shadow: var(--glow-cyan-md); }
.cq-glow-cyan-lg { box-shadow: var(--glow-cyan-lg); }
.cq-glow-gold { box-shadow: var(--glow-gold-md); }
.cq-glow-gold-lg { box-shadow: var(--glow-gold-lg); }

/* A soft radial bloom placed behind an element (button, core, title). */
.cq-bloom {
  position: relative;
  isolation: isolate;
}

.cq-bloom::after {
  content: '';
  position: absolute;
  inset: -45%;
  z-index: -1;
  background: radial-gradient(
    circle,
    rgba(63, 201, 247, 0.3) 0%,
    rgba(63, 201, 247, 0.08) 40%,
    transparent 68%
  );
  pointer-events: none;
  animation: cq-bloom-breathe 5.5s var(--ease-in-out-soft) infinite;
}

.cq-bloom--gold::after {
  background: radial-gradient(
    circle,
    rgba(239, 189, 87, 0.32) 0%,
    rgba(239, 189, 87, 0.09) 40%,
    transparent 68%
  );
}

@keyframes cq-bloom-breathe {
  0%, 100% { opacity: 0.55; transform: scale(0.94); }
  50%      { opacity: 1;    transform: scale(1.06); }
}

/* ============================================================================
   6. SHEEN — a slow diagonal light sweep across a surface
   ========================================================================== */

.cq-sheen {
  position: relative;
  overflow: hidden;
}

.cq-sheen::after {
  content: '';
  position: absolute;
  top: -120%;
  left: -60%;
  width: 40%;
  height: 340%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 255, 255, 0.1) 45%,
    rgba(255, 255, 255, 0.16) 50%,
    rgba(255, 255, 255, 0.1) 55%,
    transparent 100%
  );
  transform: rotate(16deg);
  pointer-events: none;
  animation: cq-sheen-sweep 7s var(--ease-in-out-soft) infinite;
}

@keyframes cq-sheen-sweep {
  0%        { left: -60%; opacity: 0; }
  12%       { opacity: 1; }
  45%, 100% { left: 130%; opacity: 0; }
}

/* On-hover sweep only — used on cards, so it fires on intent not on a timer. */
.cq-sheen--hover::after {
  animation: none;
  left: -60%;
  opacity: 0;
  transition: left 850ms var(--ease-out-expo), opacity 250ms linear;
}

.cq-sheen--hover:hover::after {
  left: 130%;
  opacity: 1;
}

/* ============================================================================
   7. SCANLINE — for stealth / security / debugging scenes
   ========================================================================== */

.cq-scan {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  border-radius: inherit;
}

.cq-scan::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  height: 26%;
  background: linear-gradient(
    180deg,
    transparent,
    rgba(63, 201, 247, 0.14) 46%,
    rgba(122, 221, 255, 0.2) 50%,
    rgba(63, 201, 247, 0.14) 54%,
    transparent
  );
  animation: cq-scan-sweep 5s var(--ease-in-out-soft) infinite;
}

@keyframes cq-scan-sweep {
  0%   { transform: translateY(-120%); opacity: 0; }
  25%  { opacity: 1; }
  100% { transform: translateY(420%); opacity: 0; }
}

/* ============================================================================
   8. DATA RAIN — thin falling streaks, used behind debugging content
   ========================================================================== */

.cq-rain {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0.5;
  border-radius: inherit;
}

.cq-rain span {
  position: absolute;
  top: -30%;
  width: 1px;
  height: 30%;
  background: linear-gradient(180deg, transparent, var(--cyan-300), transparent);
  animation: cq-rain-fall linear infinite;
}

@keyframes cq-rain-fall {
  to { transform: translateY(460%); }
}

/* ============================================================================
   9. REDUCED MOTION — everything ambient stops. The mood stays; the movement
   goes. Layers are kept (dialled down via tokens) so pages do not change
   composition when the setting is on.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .cq-fx__aurora span,
  .cq-fx__horizon,
  .cq-bloom::after,
  .cq-sheen::after,
  .cq-scan::after,
  .cq-rain span {
    animation: none !important;
  }

  .cq-sheen::after,
  .cq-scan::after,
  .cq-rain {
    display: none !important;
  }

  [data-parallax] {
    transform: none !important;
    transition: none !important;
  }
}

/* The learner's own preference, stored in progress and applied to <html>. */
html[data-reduced-motion='true'] .cq-fx__aurora span,
html[data-reduced-motion='true'] .cq-fx__horizon,
html[data-reduced-motion='true'] .cq-bloom::after,
html[data-reduced-motion='true'] .cq-sheen::after,
html[data-reduced-motion='true'] .cq-scan::after,
html[data-reduced-motion='true'] .cq-rain span {
  animation: none !important;
}

html[data-reduced-motion='true'] .cq-sheen::after,
html[data-reduced-motion='true'] .cq-scan::after,
html[data-reduced-motion='true'] .cq-rain {
  display: none !important;
}

html[data-reduced-motion='true'] [data-parallax] {
  transform: none !important;
  transition: none !important;
}

/* ============================================================================
   10. PRINT — the certificate must carry none of this
   ========================================================================== */

@media print {
  .cq-fx,
  .cq-scan,
  .cq-rain {
    display: none !important;
  }

  .cq-glass,
  .cq-glass--strong,
  .cq-glass--soft {
    background: #fff !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
  }

  .cq-frame::before,
  .cq-bloom::after,
  .cq-sheen::after {
    display: none !important;
  }
}
