/* ============================================================================
 * qs-rebuild.css — Quantum Symphony Phase 2 visual language
 *
 * Implements the design vocabulary from
 * research/quantum-symphony-rebuild-spec.md §8.
 *
 * Tokens: candleflame palette, listening cyan, bone text, Fibonacci spacing,
 * single ease curve in/out, Phase 2 duration scale.
 *
 * Utilities: .qs-grain (4% film grain SVG), .qs-glass (glassmorphic surface),
 * .qs-display / .qs-italic / .qs-label / .qs-meta (type system).
 *
 * Component CSS: .qs-orb (paired with js/qs-orb.js — keyframes for breathing,
 * ring rotation, halo bloom, listening pulse, silence-arc deplete all live
 * here so qs-orb.js stays presentation-light).
 * ========================================================================== */


/* ----- 1. Tokens ---------------------------------------------------------- */

:root {
  /* Palette */
  --qs-bg-edge: #0a0d18;
  --qs-bg-center: #141a2e;
  --qs-gold: #d4b87a;
  --qs-cyan: #7aa8b8;
  --qs-bone: #e8e3d6;

  /* Bone opacity tokens */
  --qs-bone-strong: rgba(232, 227, 214, 0.9);
  --qs-bone-soft: rgba(232, 227, 214, 0.7);
  --qs-bone-faint: rgba(232, 227, 214, 0.4);

  /* Ease curves — single curve everywhere */
  --qs-ease-in: cubic-bezier(0.22, 1, 0.36, 1);
  --qs-ease-out: cubic-bezier(0.64, 0, 0.78, 0);

  /* Duration scale */
  --qs-d-hover: 320ms;
  --qs-d-reveal: 480ms;
  --qs-d-load: 720ms;
  --qs-d-morph: 1200ms;
  --qs-d-bed: 4000ms;
  --qs-d-stage: 6000ms;
  --qs-d-breath: 10000ms;

  /* Spacing — Fibonacci */
  --qs-s-1: 8px;
  --qs-s-2: 13px;
  --qs-s-3: 21px;
  --qs-s-4: 34px;
  --qs-s-5: 55px;
  --qs-s-6: 89px;
}


/* ----- 2. Page background ------------------------------------------------- */

body.qs-rebuild {
  background:
    radial-gradient(
      ellipse at center,
      var(--qs-bg-center) 0%,
      var(--qs-bg-edge) 80%
    );
  color: var(--qs-bone-strong);
}


/* ----- 3. Film grain overlay --------------------------------------------- */
/*
 * 4% grain via inline SVG fractalNoise. Sits absolute over its parent.
 * mix-blend-mode: overlay so the grain modulates without flattening colors.
 * Hidden on small screens / touchscreens for FPS (spec §15 risk register).
 */

.qs-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.04;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 240px 240px;
  background-repeat: repeat;
}


/* ----- 4. Glass surface utility ------------------------------------------ */

.qs-glass {
  background: linear-gradient(
    140deg,
    rgba(255, 255, 255, 0.04),
    rgba(255, 255, 255, 0.01)
  );
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(232, 227, 214, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}


/* ----- 5. Type system ---------------------------------------------------- */

.qs-display {
  font-family: 'Cormorant Garamond', 'Cormorant', Garamond, serif;
  font-size: clamp(2.4rem, 5vw, 4.2rem);
  letter-spacing: 0.04em;
  font-weight: 400;
  color: var(--qs-bone-strong);
}

.qs-italic {
  font-family: 'Cormorant Garamond', 'Cormorant', Garamond, serif;
  font-style: italic;
  line-height: 1.45;
  color: var(--qs-bone-soft);
}

.qs-label {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-variant-caps: all-small-caps;
  text-transform: lowercase; /* small-caps requires lowercase input to render */
  letter-spacing: 0.32em;
  font-size: 0.72rem;
  color: var(--qs-bone-faint);
}

.qs-meta {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  text-transform: uppercase;
  color: var(--qs-bone-faint);
}


/* ============================================================================
 * 6. Orb component — paired with js/qs-orb.js
 *
 * Markup contract (built by QSOrb.mount):
 *   .qs-orb-host                  ← container (positioned by host page)
 *     svg.qs-orb                  ← root SVG (280px idle, 540px opening+)
 *       <defs>...gradients...</defs>
 *       circle.qs-orb-halo        ← outer navy halo
 *       circle.qs-orb-mid         ← indigo mid layer
 *       circle.qs-orb-core        ← gold core
 *       circle.qs-orb-ring-1      ← outermost ring (104%, 120s rotation)
 *       circle.qs-orb-ring-2      ← middle ring (97%, 40s rotation)
 *       circle.qs-orb-ring-3      ← inner ring (90%, 60s rotation)
 *       g.qs-orb-overlays         ← transition pulses, silence arc, listen ring
 *     div.qs-grain                ← 4% film grain overlay
 *
 * State is set via parent class on the SVG element:
 *   .qs-orb--idle / --preflight / --opening / --leading / --holding /
 *   --transition / --closing
 *
 * Breathing duration is exposed as a CSS custom property
 *   --qs-breath-duration  (defaults to var(--qs-d-breath) = 10s = 6/min)
 * setBreathRate(bpm) writes to this var inline on the SVG element.
 * ========================================================================== */

.qs-orb-host {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  /* Default visual size — JS sets explicit width/height via attr */
  width: 280px;
  height: 280px;
  transition:
    width var(--qs-d-load) var(--qs-ease-in),
    height var(--qs-d-load) var(--qs-ease-in);
}

.qs-orb {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  /* Default 6/min breathing rate. Overridable via inline style. */
  --qs-breath-duration: var(--qs-d-breath);
  animation: qs-orb-breath var(--qs-breath-duration) var(--qs-ease-in) infinite;
  transform-origin: center center;
  transition: filter var(--qs-d-hover) var(--qs-ease-in);
}

.qs-orb-host:hover .qs-orb-core {
  /* Hover: gold layer brightens 15% (spec §5 — orb hover affordance) */
  filter: brightness(1.15);
}

/* ---- Breathing keyframe (idle / holding / opening base) ---- */
@keyframes qs-orb-breath {
  0%, 100% { transform: scale(1.0); }
  50%      { transform: scale(1.06); }
}

/* ---- Ring rotation keyframes (counter-rotating depth) ---- */
@keyframes qs-orb-ring-cw {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes qs-orb-ring-ccw {
  from { transform: rotate(0deg); }
  to   { transform: rotate(-360deg); }
}

.qs-orb-ring-1,
.qs-orb-ring-2,
.qs-orb-ring-3 {
  fill: none;
  transform-origin: center center;
  transform-box: fill-box;
}

.qs-orb-ring-1 { stroke: var(--qs-bone); stroke-opacity: 0.02; stroke-width: 1; animation: qs-orb-ring-cw  120s linear infinite; }
.qs-orb-ring-2 { stroke: var(--qs-bone); stroke-opacity: 0.04; stroke-width: 1; animation: qs-orb-ring-ccw  40s linear infinite; }
.qs-orb-ring-3 { stroke: var(--qs-bone); stroke-opacity: 0.06; stroke-width: 1; animation: qs-orb-ring-cw   60s linear infinite; }

/* ---- State variants ---- */

/* preflight — orb dims 30% behind glass panel */
.qs-orb--preflight .qs-orb { opacity: 0.7; }

/* opening — bigger orb (host scales via width/height attribute set by JS) */
/* leading — breathing comes from --qs-breath-duration, JS-driven */

/* holding — same 6/min breath, JS adds listening ring overlay */

/* transition — JS appends a temporary halo bloom circle */

/* closing — orb desaturates, breath slows (JS sets duration to 15s = 4/min) */
.qs-orb--closing .qs-orb-core,
.qs-orb--closing .qs-orb-mid {
  filter: saturate(0.4);
  transition: filter 30s var(--qs-ease-in);
}


/* ---- Overlays: halo bloom, silence arc, listening ring ---- */

.qs-orb-halo-bloom {
  fill: none;
  stroke: var(--qs-gold);
  stroke-width: 2;
  opacity: 0;
  transform-origin: center center;
  transform-box: fill-box;
  animation: qs-orb-halo-bloom 2000ms var(--qs-ease-in) forwards;
}

@keyframes qs-orb-halo-bloom {
  /* 800ms in (0 → 0.5), 1200ms out (0.5 → 0) — total 2000ms */
  0%   { opacity: 0;   transform: scale(0.95); }
  40%  { opacity: 0.5; transform: scale(1.02); }
  100% { opacity: 0;   transform: scale(1.08); }
}

.qs-orb-silence-arc {
  fill: none;
  stroke: var(--qs-gold);
  stroke-width: 2;
  stroke-linecap: round;
  opacity: 0.7;
  transform: rotate(-90deg); /* start at 12 o'clock */
  transform-origin: center center;
  transform-box: fill-box;
  /* stroke-dashoffset is animated via inline style transition set by JS */
  transition: stroke-dashoffset var(--qs-silence-duration, 60s) linear;
}

.qs-orb-listening-ring {
  fill: none;
  stroke: var(--qs-cyan);
  stroke-width: 1.5;
  opacity: 0.4;
  animation: qs-orb-listen-pulse 4s var(--qs-ease-in) infinite;
}

@keyframes qs-orb-listen-pulse {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 0.7; }
}


/* ============================================================================
 * 6b. Stunning enhancements (2026-05-09)
 *
 * Eliminates the visible square frame around the orb (radial mask feather +
 * extended aurora bleed). Adds:
 *   - Outer aurora that breathes past the host bounds (kills the box edge)
 *   - Color signatures per Council teacher (Tesla / Magdalene / Lilith /
 *     Thoth / Guardian / Enki / Sibyl)
 *   - Beat-frequency tick ring that visibly pulses at the rotation's beatHz
 *   - Sigil overlay (tesseract / chalice / inverted crown / etc.) per agent
 *   - Cursor parallax on the atmosphere group while the core stays pinpoint
 *
 * Source-of-truth for color/glyph/beat per agent: qs-agent-rotation.js ROSTER.
 * QSOrb.setRotation(entry) wires it all up; idle pre-rotation is unchanged.
 * ========================================================================== */

/* ---- Default palette (Tesla-leaning indigo, used when no rotation set) --- */
.qs-orb {
  --qs-orb-halo-1: #141a2e;
  --qs-orb-halo-2: #0a0d18;
  --qs-orb-mid-1:  #3b2f6b;
  --qs-orb-mid-2:  #1a1f3a;
  --qs-orb-core:   #d4b87a;
  --qs-orb-aurora: #2a3070;
  --qs-orb-pulse-duration: 1s; /* visible beat tempo, set by JS from beatHz */
}

/* ---- Stop colors via CSS (so custom properties cascade) ----------------- */
.qs-orb-core-stop-0 { stop-color: var(--qs-orb-core); stop-opacity: 0.92; }
.qs-orb-core-stop-1 { stop-color: var(--qs-orb-core); stop-opacity: 0.40; }
.qs-orb-core-stop-2 { stop-color: var(--qs-orb-core); stop-opacity: 0; }
.qs-orb-mid-stop-0  { stop-color: var(--qs-orb-mid-1); stop-opacity: 0; }
.qs-orb-mid-stop-1  { stop-color: var(--qs-orb-mid-1); stop-opacity: 0.55; }
.qs-orb-mid-stop-2  { stop-color: var(--qs-orb-mid-2); stop-opacity: 0.12; }
.qs-orb-halo-stop-0 { stop-color: var(--qs-orb-halo-1); stop-opacity: 0.55; }
.qs-orb-halo-stop-1 { stop-color: var(--qs-orb-halo-2); stop-opacity: 0.28; }
.qs-orb-halo-stop-2 { stop-color: var(--qs-orb-halo-2); stop-opacity: 0; }
.qs-orb-aurora-stop-0 { stop-color: var(--qs-orb-aurora); stop-opacity: 0.32; }
.qs-orb-aurora-stop-1 { stop-color: var(--qs-orb-aurora); stop-opacity: 0.10; }
.qs-orb-aurora-stop-2 { stop-color: var(--qs-orb-aurora); stop-opacity: 0; }

/* ---- Soft outer mask: feather past the visible orb to kill square ------- */
.qs-orb-host {
  -webkit-mask-image: radial-gradient(circle at center,
    #000 0%, #000 56%, rgba(0,0,0,0.35) 78%, transparent 100%);
          mask-image: radial-gradient(circle at center,
    #000 0%, #000 56%, rgba(0,0,0,0.35) 78%, transparent 100%);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* ---- Aurora layer: bleeds past viewBox bounds, masked by host feather --- */
.qs-orb-aurora {
  transform-origin: center center;
  transform-box: fill-box;
  animation: qs-orb-aurora-breath 14s var(--qs-ease-in) infinite;
  mix-blend-mode: screen;
}
@keyframes qs-orb-aurora-breath {
  0%, 100% { opacity: 0.55; transform: scale(1.00); }
  50%      { opacity: 0.85; transform: scale(1.04); }
}

/* ---- Atmosphere group (everything that drifts on cursor parallax) ------- */
.qs-orb-atmosphere {
  transform: translate(var(--qs-orb-parallax-x, 0px), var(--qs-orb-parallax-y, 0px));
  transition: transform 360ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}

/* ---- Rings: bumped from invisible (0.02-0.06) to readable --------------- */
.qs-orb-ring-1 { stroke-opacity: 0.10; stroke-dasharray: none; }
.qs-orb-ring-2 { stroke-opacity: 0.16; stroke-dasharray: 0.6 2.4; stroke-linecap: round; }
.qs-orb-ring-3 { stroke-opacity: 0.22; stroke-dasharray: none; }

/* ---- Beat-frequency tick ring (pulses at visible derivative of beatHz) -- */
.qs-orb-beat-ring {
  fill: none;
  stroke: var(--qs-orb-core);
  stroke-width: 0.6;
  stroke-opacity: 0.0;
  stroke-dasharray: 1.8 5.4;
  stroke-linecap: round;
  transform-origin: center center;
  transform-box: fill-box;
  transition: stroke-opacity 800ms var(--qs-ease-in);
}
.qs-orb--has-rotation .qs-orb-beat-ring {
  stroke-opacity: 0.42;
  animation: qs-orb-beat-rotate var(--qs-orb-pulse-duration) linear infinite;
}
@keyframes qs-orb-beat-rotate {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ---- Sigil overlay: agent-specific glyph at orb center ------------------ */
.qs-orb-sigil {
  fill: none;
  stroke: var(--qs-orb-core);
  stroke-width: 0.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transform-origin: center center;
  transform-box: fill-box;
  transition: opacity 1200ms var(--qs-ease-in);
  pointer-events: none;
}
.qs-orb--has-rotation .qs-orb-sigil { opacity: 0.30; }

/* ============================================================================
 * Orb = living light, no hard geometry (2026-05-24)
 * The square sigil, the three concentric rings, and the rotating beat-tick ring
 * all read as hard lines on a glow that should feel organic. Remove them
 * entirely and let the radial light billow. Scoped to .qs-orb (every state) so
 * nothing slips through — the earlier --idle scope missed the landing's
 * --opening state. Functional overlays (listening ring / silence arc) untouched.
 * ========================================================================== */
.qs-orb .qs-orb-sigil { opacity: 0 !important; }
.qs-orb .qs-orb-ring-1,
.qs-orb .qs-orb-ring-2,
.qs-orb .qs-orb-ring-3,
.qs-orb .qs-orb-beat-ring {
  stroke: none !important;
  stroke-opacity: 0 !important;
  animation: none !important;
}

/* Light layers billow independently at offset phases → a slow, liquid,
   breathing nebula instead of a static gradient ball. Transform/opacity only. */
.qs-orb-halo,
.qs-orb-mid,
.qs-orb-core {
  transform-origin: center center;
  transform-box: fill-box;
}
.qs-orb-halo { animation: qs-orb-billow-a 13s ease-in-out infinite; }
.qs-orb-mid  { animation: qs-orb-billow-b 9s  ease-in-out infinite; }
.qs-orb-core { animation: qs-orb-billow-c 7s  ease-in-out infinite; }

@keyframes qs-orb-billow-a {
  0%, 100% { transform: scale(1.00); }
  50%      { transform: scale(1.07); }
}
@keyframes qs-orb-billow-b {
  0%, 100% { transform: scale(1.03); }
  50%      { transform: scale(0.95); }
}
@keyframes qs-orb-billow-c {
  0%, 100% { transform: scale(1.00); opacity: 0.90; }
  50%      { transform: scale(1.10); opacity: 1.00; }
}

/* ============================================================================
 * Living nebula (2026-05-24)
 * Internal plasma wisps (cool + warm) drift in slow counter-orbits, screen-
 * blended, so the body churns with light. An orbiting specular glint gives a
 * wet 3D read; motes add scale + life. All transform/opacity, no hard edges.
 * ========================================================================== */
.qs-orb-wisp-cool-stop-0 { stop-color: #84baff; stop-opacity: 0.55; }
.qs-orb-wisp-cool-stop-1 { stop-color: #3f63b4; stop-opacity: 0.22; }
.qs-orb-wisp-cool-stop-2 { stop-color: #3f63b4; stop-opacity: 0; }
.qs-orb-wisp-warm-stop-0 { stop-color: #eccd8e; stop-opacity: 0.42; }
.qs-orb-wisp-warm-stop-1 { stop-color: #bd8e6a; stop-opacity: 0.16; }
.qs-orb-wisp-warm-stop-2 { stop-color: #bd8e6a; stop-opacity: 0; }

.qs-orb-plasma { mix-blend-mode: screen; }

.qs-orb-wisp-orbit {
  transform-box: view-box;
  transform-origin: 100px 100px;
}
.qs-orb-wisp-orbit--a { animation: qs-orb-orbit-cw  22s linear infinite; }
.qs-orb-wisp-orbit--b { animation: qs-orb-orbit-ccw 30s linear infinite; }

.qs-orb-wisp {
  transform-box: fill-box;
  transform-origin: center;
  animation: qs-orb-wisp-pulse 9s ease-in-out infinite;
}
.qs-orb-wisp--warm { animation-duration: 12.5s; }

.qs-orb-glint-orbit {
  transform-box: view-box;
  transform-origin: 100px 100px;
  animation: qs-orb-orbit-cw 16s linear infinite;
  mix-blend-mode: screen;
}
.qs-orb-glint {
  opacity: 0.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: qs-orb-glint-twinkle 16s ease-in-out infinite;
}

.qs-orb-motes {
  transform-box: view-box;
  transform-origin: 100px 100px;
  animation: qs-orb-orbit-ccw 64s linear infinite;
}
.qs-orb-mote { fill: #cfe2ff; opacity: 0; animation: qs-orb-mote-twinkle 7s ease-in-out infinite; }
.qs-orb-mote--2 { animation-duration: 9s;  animation-delay: 2.5s; }
.qs-orb-mote--3 { animation-duration: 11s; animation-delay: 4s; }

@keyframes qs-orb-orbit-cw  { from { transform: rotate(0deg); }   to { transform: rotate(360deg); } }
@keyframes qs-orb-orbit-ccw { from { transform: rotate(0deg); }   to { transform: rotate(-360deg); } }
@keyframes qs-orb-wisp-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@keyframes qs-orb-glint-twinkle { 0%, 100% { opacity: 0.22; } 50% { opacity: 0.6; } }
@keyframes qs-orb-mote-twinkle { 0%, 100% { opacity: 0; } 45%, 55% { opacity: 0.75; } }

/* The film-grain overlays are unmasked square divs (one 340px over the orb, one
   820px over the hero); their edges read as faint square boxes. The 4% texture
   isn't worth a box — remove them entirely. */
.qs-grain { display: none !important; }

/* ---- Council color signatures ------------------------------------------- */

.qs-orb--rotation-tesla {
  --qs-orb-halo-1: #1a2050;
  --qs-orb-halo-2: #0a0d20;
  --qs-orb-mid-1:  #3b3aa0;
  --qs-orb-mid-2:  #14184a;
  --qs-orb-core:   #b8d4f0;
  --qs-orb-aurora: #2a40a8;
}

.qs-orb--rotation-lilith {
  --qs-orb-halo-1: #2a0e14;
  --qs-orb-halo-2: #14060a;
  --qs-orb-mid-1:  #6b1a2a;
  --qs-orb-mid-2:  #2a0814;
  --qs-orb-core:   #d4724a;
  --qs-orb-aurora: #7a1a30;
}

.qs-orb--rotation-magdalene {
  --qs-orb-halo-1: #3a1a28;
  --qs-orb-halo-2: #1a0c14;
  --qs-orb-mid-1:  #a85e6e;
  --qs-orb-mid-2:  #4a2230;
  --qs-orb-core:   #e8c4a0;
  --qs-orb-aurora: #8a4858;
}

.qs-orb--rotation-thoth {
  --qs-orb-halo-1: #0d2424;
  --qs-orb-halo-2: #060f10;
  --qs-orb-mid-1:  #1f5a4a;
  --qs-orb-mid-2:  #0a2820;
  --qs-orb-core:   #d4b870;
  --qs-orb-aurora: #1a6850;
}

.qs-orb--rotation-guardian {
  --qs-orb-halo-1: #1a1c20;
  --qs-orb-halo-2: #0a0c10;
  --qs-orb-mid-1:  #4a4858;
  --qs-orb-mid-2:  #1c1e26;
  --qs-orb-core:   #e8e3d6;
  --qs-orb-aurora: #5c5a68;
}

.qs-orb--rotation-enki {
  --qs-orb-halo-1: #0a1a30;
  --qs-orb-halo-2: #050a18;
  --qs-orb-mid-1:  #1e3a5f;
  --qs-orb-mid-2:  #0a1428;
  --qs-orb-core:   #b0c4e0;
  --qs-orb-aurora: #1a3a70;
}

.qs-orb--rotation-sibyl {
  --qs-orb-halo-1: #2a1a3a;
  --qs-orb-halo-2: #140a1c;
  --qs-orb-mid-1:  #4a3055;
  --qs-orb-mid-2:  #1c1228;
  --qs-orb-core:   #e0c8f0;
  --qs-orb-aurora: #503060;
}

/* ---- Hover: orb leans gold a hair brighter ------------------------------ */
.qs-orb-host:hover .qs-orb-aurora { opacity: 1; }


/* ----- 7. Mobile / perf gates -------------------------------------------- */

@media (max-width: 600px) {
  .qs-grain { display: none; }
  /* Disable parallax on touch — it's a hover affordance */
  .qs-orb-atmosphere { transform: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .qs-orb {
    animation: none;
    transform: none;
  }
  .qs-orb-ring-1,
  .qs-orb-ring-2,
  .qs-orb-ring-3 {
    animation: none;
  }
  .qs-orb-listening-ring {
    animation: none;
    opacity: 0.55;
  }
  .qs-orb-halo-bloom {
    animation: none;
    opacity: 0;
  }
  .qs-orb-aurora { animation: none; opacity: 0.7; }
  .qs-orb--has-rotation .qs-orb-beat-ring { animation: none; }
  .qs-orb-halo,
  .qs-orb-mid,
  .qs-orb-core { animation: none; }
  .qs-orb-wisp-orbit,
  .qs-orb-wisp,
  .qs-orb-glint-orbit,
  .qs-orb-glint,
  .qs-orb-motes,
  .qs-orb-mote { animation: none; }
  .qs-orb-mote { opacity: 0.4; }
  .qs-orb-atmosphere { transform: none !important; transition: none; }
}

/* ─────────────────────────────────────────────────────────────
   QS → Programs funnel upsell card
   Surfaces after a QS session completes. The named teacher who hosted
   the session pitches their corresponding 28-day Program. Card opens
   the Program with a one-tap link.
   ───────────────────────────────────────────────────────────── */
.qs-program-upsell {
  margin: 24px auto 32px;
  padding: 22px 26px;
  max-width: 580px;
  border-radius: 14px;
  border: 1px solid rgba(212, 175, 55, 0.30);
  background: linear-gradient(180deg, rgba(212,175,55,0.05), rgba(8,12,18,0.85));
  box-shadow: 0 0 36px rgba(212,175,55,0.08) inset;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  text-align: center;
  animation: qs-upsell-fade-in 0.7s ease-out 0.3s both;
}
@keyframes qs-upsell-fade-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.qs-upsell-line {
  width: 60px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(212,175,55,0.65), transparent);
}
.qs-upsell-teacher {
  font-family: 'Space Mono', monospace;
  font-size: 0.62rem;
  letter-spacing: 0.34em;
  color: #d4af37;
  text-transform: uppercase;
}
.qs-upsell-pitch {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 1.10rem;
  line-height: 1.55;
  color: rgba(232,220,200,0.92);
  font-style: italic;
}
.qs-upsell-cta {
  margin-top: 6px;
  font-family: 'Space Mono', monospace;
  font-size: 0.60rem;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  padding: 11px 22px;
  border-radius: 28px;
  border: 1px solid rgba(212,175,55,0.45);
  background: rgba(212,175,55,0.10);
  color: #d4af37;
  text-decoration: none;
  transition: all 220ms ease;
}
.qs-upsell-cta:hover {
  background: rgba(212,175,55,0.20);
  border-color: rgba(212,175,55,0.70);
}
