/* ============================================================
   NumeroLuck — shared interaction & motion layer
   Loaded by every calculator page. Pure CSS + the tiny helper in
   nl-motion.js; no framework, no animation library (these pages are
   vanilla HTML, so React-only libraries like Framer Motion don't apply).

   Fixes, in the order they were diagnosed:
     1. reveals were `display:none` toggles — nothing could animate in
     2. buttons had no :active/press feedback on 7 of 8 pages
     3. a 93ms long task blocked the thread during report render
     4. 21 backdrop-filter layers + 3 fixed blur(120px) blobs were
        re-sampling the page on every paint
     5. primary CTAs looked frozen during network calls
     6. cards appeared all at once, with no stagger
   ============================================================ */

/* ---- 2. Press + hover feedback on every interactive control ---- */
.btn, .navbtn, .paybtn, .gbtn, button, .dashaTab {
  transition: transform .16s cubic-bezier(.22,.61,.36,1),
              box-shadow .2s ease, background-color .2s ease,
              opacity .2s ease, border-color .2s ease;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;            /* removes the 300ms mobile tap delay */
}
.btn:active, .paybtn:active, .gbtn:active, .navbtn:active, .dashaTab:active {
  transform: translateY(1px) scale(.985);
}
.btn:hover  { filter: brightness(1.06); }
.navbtn:hover, .dashaTab:hover { filter: brightness(1.12); }
button:disabled, .btn:disabled { opacity: .6; cursor: progress; transform: none; filter: none; }

/* Keyboard focus must stay visible everywhere. */
:where(a, button, select, input, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--vio2, #a78bfa);
  outline-offset: 3px;
  border-radius: 8px;
}

/* ---- 5. Busy state for a CTA waiting on the network ---- */
.nl-busy { position: relative; color: transparent !important; pointer-events: none; }
.nl-busy::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  animation: nlSpin .6s linear infinite;
}
@keyframes nlSpin { to { transform: rotate(360deg); } }

/* ---- 1 & 6. Animatable reveals + stagger ----
   `.hidden` stays display:none (every page's JS depends on it), so
   nl-motion.js tags an element with .nl-enter the moment the class is
   removed. The element is already displayed by then, so the keyframes run. */
@keyframes nlFade { from { opacity: 0 } to { opacity: 1 } }
@keyframes nlRise { from { opacity: 0; transform: translateY(12px) } to { opacity: 1; transform: none } }

.nl-enter { animation: nlFade .22s ease both; }
.nl-enter > * { animation: nlRise .42s cubic-bezier(.22,.61,.36,1) both; }
.nl-enter > *:nth-child(1) { animation-delay: .02s }
.nl-enter > *:nth-child(2) { animation-delay: .07s }
.nl-enter > *:nth-child(3) { animation-delay: .12s }
.nl-enter > *:nth-child(4) { animation-delay: .17s }
.nl-enter > *:nth-child(5) { animation-delay: .22s }
.nl-enter > *:nth-child(n+6) { animation-delay: .26s }

/* ---- 6b. Toast had no transition at all ---- */
.toast {
  animation: nlToastIn .3s cubic-bezier(.22,.61,.36,1) both;
  will-change: transform, opacity;
}
@keyframes nlToastIn {
  from { opacity: 0; transform: translateX(-50%) translateY(14px) scale(.96) }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1) }
}
.toast.nl-out { animation: nlToastOut .25s ease both; }
@keyframes nlToastOut {
  from { opacity: 1; transform: translateX(-50%) translateY(0) }
  to   { opacity: 0; transform: translateX(-50%) translateY(10px) }
}

/* ---- 3. Stop off-screen sections from being painted ----
   The paid report is ~19,000px tall with 3,000 nodes. content-visibility
   lets the browser skip layout+paint for anything off-screen; the
   intrinsic-size hint keeps the scrollbar honest so it doesn't jump.
   MUST be disabled for print, or skipped sections export blank to PDF. */
#fullReport > .card, #resultPage > .card, .dashaYear {
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}
.pwin { content-visibility: auto; contain-intrinsic-size: auto 190px; }

/* ---- 4. Cheaper compositing ----
   Every .card carried backdrop-filter: blur(10px) — 21 stacked layers, each
   re-sampling what's behind it on every paint, over three position:fixed
   blur(120px) blobs. The blobs are replaced by a static radial gradient
   painted once into the body background; the glass effect is kept only on
   modals, where there are at most two at a time and it actually reads. */
.glow { display: none !important; }
body {
  background-image:
    radial-gradient(620px 620px at 8% -6%,  rgba(91,33,182,.34), transparent 70%),
    radial-gradient(560px 560px at 104% 32%, rgba(49,46,129,.32), transparent 70%),
    radial-gradient(520px 520px at 26% 104%, rgba(112,26,117,.28), transparent 70%);
  background-attachment: fixed;
  background-repeat: no-repeat;
}
.card { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
.overlay { backdrop-filter: blur(4px); }

/* Promote only what actually moves. */
.btn, .navbtn, .paybtn, .toast { will-change: transform; }

/* ---- Accessibility: motion is decoration, never the message ---- */
@media (prefers-reduced-motion: reduce) {
  .nl-enter, .nl-enter > *, .toast { animation: none !important; }
  .btn, .navbtn, .paybtn, .gbtn, button, .dashaTab { transition: none !important; }
  .btn:active, .paybtn:active, .gbtn:active, .navbtn:active { transform: none; }
  .nl-busy::after { animation-duration: 1.6s; }
}

/* ---- Print: undo everything that could hide or shift content ---- */
@media print {
  #fullReport > .card, #resultPage > .card, .dashaYear, .pwin {
    content-visibility: visible !important;
    contain-intrinsic-size: auto !important;
  }
  .nl-enter, .nl-enter > * { animation: none !important; opacity: 1 !important; transform: none !important; }
  body { background-image: none !important; }
  .toast, .nl-busy { display: none !important; }
}
