/* ============================================================================
   motion-premium.css — additive motion + FPS layer (2026-06-11)
   Loads LAST (after marketing-focus.css). Transform/opacity/translate channels
   only; every motion rule is gated behind prefers-reduced-motion and, where it
   matters, @supports. FPS rules are pure render-cost wins with no visual delta.
   Sources: 2-agent motion/FPS audit (receipts in #proj-eccentrx channel).
   ============================================================================ */

/* ---- FPS 1: atlas grid backdrop blur kill --------------------------------
   .atlas-card ships backdrop-filter: blur(16px) ×227 simultaneous backdrop
   roots — the single biggest GPU cost in the app, re-filtered every scroll
   frame, while the card already sits on a near-opaque gradient. Replace with
   a solid tint (mirrors the prefers-reduced-transparency precedent). */
#atlas .atlas-grid .atlas-card,
.atlas-grid .atlas-card {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  background-color: rgba(8, 14, 20, 0.92);
}

/* ---- FPS 2: render-skip off-screen atlas cards ---------------------------
   227 cards laid out on every grid mount; min-height 280px gives the exact
   intrinsic size. Off-screen cards skip render entirely. */
.atlas-grid .atlas-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 280px;
}

/* ---- FPS 3: render-skip home below-fold sections -------------------------
   The v118 content-visibility rule only matches `.section` siblings of main;
   the home route's below-fold blocks are nested inside .home-intro under
   different class names and get no render skipping today. */
:where(.market-product-proof, .market-trust-receipt, .market-final-cta,
  .home-presale-section, .strand-b-founder-proof, .strand-b-not-list,
  .floor-receipt-board, .repdeck-company-contract, .repdeck-problem-strip,
  .session-phone-brief) {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

/* ---- MOTION 1: section reveals ride the spring ----------------------------
   18 home sections use .reveal with a flat 0.65s ease; the damped-spring
   token --ease-spring already exists in the v137 layer but is unused here.
   Zero-specificity so the existing system still owns everything else. */
@media (prefers-reduced-motion: no-preference) {
  :where(.reveal) {
    transition: opacity 0.5s ease, transform 0.7s var(--ease-spring, ease);
  }
}

/* ---- MOTION 2: plans grid gets the premium hover --------------------------
   .price-card (the revenue surface) was excluded from the Cycle-4 3D hover
   group and had only a flat -3px nudge. Same triple gate as Cycle 4. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  :where(.price-card) {
    transition: transform 0.4s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)),
      box-shadow 0.4s ease;
  }
  :where(.price-card):hover {
    transform: translateY(-6px) scale3d(1.015, 1.015, 1);
    box-shadow: 0 18px 40px rgba(16, 30, 60, 0.16);
  }
}

/* ---- MOTION 3: scroll-driven card reveals, widened ------------------------
   The v137 view()-timeline reveal covers only .tool-card. Self-contained
   keyframes (translate/opacity channels) so existing hover transforms and the
   atlas scrub system — which reserve the `transform` channel — still win. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    :where(.choose-card, .price-card, .faq-item, .atlas-card) {
      animation: mpCardIn linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 50%;
    }
  }
}
@keyframes mpCardIn {
  from { opacity: 0.25; translate: 0 22px; }
  to { opacity: 1; translate: 0 0; }
}

/* ---- MOTION 4: nav link micro-feedback ------------------------------------
   Most-hovered element on the page had the least feedback. Independent
   `translate` channel — no layout shift, composes with color transitions. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :where(.navlinks a) { transition: color 0.15s, background-color 0.15s, translate 0.3s var(--ease-snap, ease); }
  :where(.navlinks a):hover { translate: 0 -1px; }
}

/* ---- BRAND FIX: live-session LOG SET button --------------------------------
   styles.css:23433 paints .session-log with raw retired-neon var(--rep-lime)
   (#c8ff2d) !important — the most-pressed button in the product was the last
   neon element left, clashing with the clinical-blue brand. Same filled brand
   treatment as every other primary action; white on #2563eb = 4.6:1 on the
   dark cockpit. Loads last, so !important here wins the tie. */
.session-log,
.btn.btn-primary.session-log {
  background: #2563eb !important;
  background-image: none !important;
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
  border-color: #2563eb !important;
}
.session-log:hover { background: #1d4ed8 !important; border-color: #1d4ed8 !important; }
.session-log:focus-visible { outline: 2px solid #ffffff; outline-offset: 2px; } /* a11y: #93c5fd was 2.87:1 on #2563eb (<3.0 UI); white = 5.17:1 on the button + high on the dark page */
/* live-session-focus.css pins the lime with an ID selector (1,2,1 + !important):
   `body.session-active #sessLog:not(:disabled)`. Match it from the later sheet. */
body.session-active #sessLog:not(:disabled) {
  background: #2563eb !important;
  border-color: #2563eb !important;
  color: #ffffff !important;
  -webkit-text-fill-color: #ffffff !important;
}
.session-body[data-session-panel] .session-log {
  background: #2563eb !important;
  border-color: #2563eb !important;
  color: #ffffff !important;
}

/* ---- LEGIBILITY FIX: live-session swap quick-picks -------------------------
   .session-swap-result-btn span rendered a ~9.5px line box for 12.5px text
   (overflow: hidden) — exercise names visibly cut in half in the live-session
   Plan panel. Force a real line box; ellipsis behavior unchanged. */
.session-swap-result-btn span {
  height: auto !important;
  min-height: 1.25em !important;
  line-height: 1.25 !important;
}

/* ---- PERF RESCUE: closed overlays must not paint ---------------------------
   The closed settings drawer remains a fixed flex layer with blur(16px) while
   translated offscreen. The idle fatigue overlay remains a full-viewport fixed
   layer even though its blur is already active-only. Hide both closed states
   without using display:none so their committed open/active owners remain
   reachable. */
.settings-drawer:not(.open),
.fatigue-overlay:not(.fatigue-active) {
  visibility: hidden !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ---- A11Y FIX: reduced-motion badge centering -----------------------------
   The universal reduced-motion gate sets transform: none on *, which also
   strips the LAYOUT-positioning translateX(-50%) that centers the
   "FIRST 500 ONLY" / "RECOMMENDED" badges — misaligned chrome for exactly
   the audience the gate protects. Static re-assert, zero motion. */
@media (prefers-reduced-motion: reduce) {
  .price-card-founders::before,
  .pricing-card.is-premium::before {
    transform: translateX(-50%) !important;
  }
}

/* ---- MOTION 5: CTA Magnetic Lift & Glow ------------------------------------
   Primary action buttons get a physics-based magnetic push on hover. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .home-primary-actions .home-cta-main {
    transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease !important;
  }
  .home-primary-actions .home-cta-main:hover {
    transform: scale(1.04) translateY(-3px) !important;
    box-shadow: 0 12px 30px rgba(37, 99, 235, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.4) !important;
  }
}

/* ---- MOTION 6: Interactive Card 3D Lift ------------------------------------
   Funnel cards and product loop stages gain a 3D tangibility on hover. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .choose-card,
  .market-loop-stage {
    transition: transform 0.4s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)), box-shadow 0.4s ease !important;
  }
  .choose-card:hover,
  .market-loop-stage:hover {
    transform: translateY(-5px) rotateX(2deg) rotateY(-2deg) !important;
    box-shadow: 0 24px 48px rgba(0, 0, 0, 0.3) !important;
    z-index: 2;
  }
}

/* ---- MOTION 7: Continuous Presale Shimmer ----------------------------------
   Eye-catching reflection for the "Founders List" or presale badges. */
@keyframes continuousShimmer {
  0% { background-position: 200% center; }
  100% { background-position: -200% center; }
}
@media (prefers-reduced-motion: no-preference) {
  .presale-badge {
    background: linear-gradient(90deg, transparent 25%, rgba(255, 255, 255, 0.4) 50%, transparent 75%) !important;
    background-size: 200% auto !important;
    animation: continuousShimmer 3s linear infinite !important;
  }
}

/* ---- MOTION 8: PR-aware session recap burst -------------------------------
   Finishing a session with at least one PR earns one restrained two-ring
   release around the recap card. Keyframes stay compositor-only. */
.session-recap-panel.has-pr .session-recap-card::before,
.session-recap-panel.has-pr .session-recap-card::after {
  content: "";
  position: absolute;
  inset: -10px;
  border: 2px solid rgba(37, 99, 235, 0.72);
  border-radius: 20px;
  opacity: 0;
  pointer-events: none;
}
.session-recap-panel.has-pr .session-recap-card::after {
  inset: -4px;
  border-color: rgba(255, 196, 0, 0.66);
}
@media (prefers-reduced-motion: no-preference) {
  .session-recap-panel.has-pr.open .session-recap-card::before {
    animation: sessionRecapPrBurst 0.9s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
  }
  .session-recap-panel.has-pr.open .session-recap-card::after {
    animation: sessionRecapPrBurst 1.05s var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) 0.08s both;
  }
}
@keyframes sessionRecapPrBurst {
  0% { opacity: 0; transform: scale(0.94); }
  32% { opacity: 0.9; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
  .session-recap-panel.has-pr .session-recap-card::before,
  .session-recap-panel.has-pr .session-recap-card::after {
    animation: none !important;
    opacity: 0 !important;
    transform: none !important;
  }
}
