/* =============================================================
   TA-DA CELEBRATIONS AI — ANIMATED FEATURE PAGE
   Layered ON TOP of tada-home.css (shared brand base).
   Only page-specific animation styles live here.
   Scoped under .tada-anim so it never touches the homepage.
   ============================================================= */

/* ---- FOUC guard -------------------------------------------------
   Elements that GSAP animates in start hidden ONLY when JavaScript is
   active (html.anim-js, set by an inline snippet before paint) AND the
   viewer allows motion. With no JS or reduced-motion, everything stays
   fully visible — the page is readable and complete without animation. */
@media (prefers-reduced-motion: no-preference) {
  html.anim-js .tada-anim [data-anim-el],
  html.anim-js .tada-anim [data-anim-hero],
  html.anim-js .tada-anim .anim-visual {
    opacity: 0;
  }
}

/* ---- Hero ---- */
.tada-anim .anim-hero {
  position: relative;
  overflow: hidden;          /* clip the celebration FX to the hero */
  /* Flatten to plain paper (override the homepage hero's violet radial tint) so the top of
     the hero matches the site background and doesn't read as a separate section. */
  background: var(--paper);
  min-height: min(92vh, 760px);
  display: flex;
  align-items: center;
}
.tada-anim .anim-hero .hero-inner { width: 100%; position: relative; z-index: 2; }

/* ===== Hero celebration FX (balloons + confetti + sparkles + bokeh), behind the text ===== */
.tada-anim .hero-fx {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  /* Fade the FX into the paper at the top & bottom so the clipped edges don't
     read as a hard line dividing the hero from the rest of the page. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 15%, #000 85%, transparent 100%);
}
/* soft blurred color orbs drifting for depth */
.tada-anim .fx-bokeh {
  position: absolute;
  border-radius: 50%;
  filter: blur(44px);
  opacity: .22;
  animation: fxBokeh var(--d, 26s) ease-in-out infinite alternate;
}
@keyframes fxBokeh {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(var(--dx, 40px), var(--dy, -30px)) scale(1.18); }
}
/* balloons rising with a gentle sway (outer = rise, inner = sway) */
.tada-anim .fx-balloon {
  position: absolute;
  bottom: -22%;
  width: var(--bw, 44px);
  height: calc(var(--bw, 44px) * 1.25);
  opacity: var(--op, .45);
  animation: fxRise var(--d, 18s) linear infinite;
  animation-delay: var(--delay, 0s);
}
.tada-anim .fx-balloon i {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50% 50% 48% 48%;
  background: radial-gradient(circle at 34% 28%, rgba(255,255,255,.55), var(--c, #EC4583));
  animation: fxSway var(--sway, 6s) ease-in-out infinite alternate;
}
.tada-anim .fx-balloon i::after {   /* string */
  content: "";
  position: absolute;
  top: 100%; left: 50%;
  width: 1px; height: 42px;
  background: rgba(43, 26, 36, .16);
  transform: translateX(-50%);
}
@keyframes fxRise { from { transform: translateY(0); } to { transform: translateY(-138vh); } }
@keyframes fxSway { from { transform: translateX(-8px) rotate(-4deg); } to { transform: translateX(8px) rotate(4deg); } }
/* confetti slowly drifting down */
.tada-anim .fx-confetti {
  position: absolute;
  top: -8%;
  width: var(--cw, 8px);
  height: calc(var(--cw, 8px) * .5);
  background: var(--c, #7C39D3);
  opacity: var(--op, .55);
  border-radius: 1px;
  animation: fxFall var(--d, 12s) linear infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes fxFall {
  from { transform: translateY(0) translateX(0) rotate(0deg); }
  to   { transform: translateY(118vh) translateX(var(--dx, 20px)) rotate(560deg); }
}
/* tiny twinkling glints */
.tada-anim .fx-sparkle {
  position: absolute;
  width: var(--sw, 6px);
  height: var(--sw, 6px);
  border-radius: 50%;
  background: radial-gradient(circle, var(--c, #7C39D3), transparent 70%);
  animation: fxTwinkle var(--d, 3s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}
@keyframes fxTwinkle {
  0%, 100% { opacity: 0; transform: scale(.4); }
  50%      { opacity: .85; transform: scale(1); }
}
/* one-time load-burst piece (GSAP-driven) */
.tada-anim .fx-burst { position: absolute; width: 9px; height: 9px; border-radius: 1px; }

/* Calm, static hero when the viewer prefers reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .tada-anim .hero-fx { display: none; }
}

/* ===== Sticky-stacked feature cards (native port of the sticky-scroll deck) =====
   Each feature section pins at a staggered offset inside .stack-wrap, so the earlier
   cards' name-tabs stay peeking above the current fully-visible card. Enabled on desktop
   via body.stack-on (added by JS). Tune with --stack-top / --stack-step. */
.tada-anim .feat-tab { display: none; }   /* hidden unless stacking is active */

/* --- Sticky stack: now enabled on ALL widths (mobile spacing by default,
       roomier on desktop via the min-width override below). --- */
.tada-anim.stack-on .anim-feature {
  position: relative;                /* desktop: JS translateY drives the rolling window */
  z-index: calc(var(--stack-i, 0) + 1);
  background: var(--paper);          /* opaque so it covers the card beneath */
  padding-top: 12px;
  will-change: transform;
}
/* MOBILE: use the browser's NATIVE position:sticky instead of JS positioning. Native sticky
   runs on the compositor thread, so it can't lag/jitter the way JS scroll-pinning does on
   phones. Each card pins just below the nav and the next card slides up to cover it. */
@media (max-width: 899px) {
  .tada-anim.stack-on .anim-feature {
    position: sticky;
    top: 60px;                       /* just below the fixed nav (~58px) */
    will-change: auto;
    transform: none !important;      /* ignore any stale JS transform on mobile */
  }
}
/* the peeking name-tab (feature name), generated by JS at the top of each section */
.tada-anim.stack-on .feat-tab {
  display: block;
  width: min(1180px, 92%);
  margin: 0 auto 12px;
  padding: 8px 16px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .92rem;
  color: #fff;
  border-radius: 999px;
  background: linear-gradient(100deg, var(--tada-primary) 0%, var(--tada-pink) 60%, var(--tada-magenta) 100%);
  box-shadow: 0 8px 22px -12px rgba(43, 26, 36, .4);
  text-shadow: 0 1px 2px rgba(43, 26, 36, .25);
}
/* the name lives in the tab now — hide the in-card eyebrow to avoid showing it twice */
.tada-anim.stack-on .anim-feature .feature-copy .eyebrow { display: none; }

/* Lever B — lightly compact the stacked cards so a whole card fits on screen (so the slide-up
   isn't cut). Only padding + line-heights are trimmed; font sizes and videos stay full size. */
.tada-anim.stack-on .anim-feature .feature { padding: clamp(18px, 2.4vw, 34px); }
.tada-anim.stack-on .anim-feature .h-display { line-height: 1.14; }
.tada-anim.stack-on .anim-feature .beat { line-height: 1.45; }

/* roomier stacking + larger tab on desktop */
@media (min-width: 900px) {
  .tada-anim.stack-on .anim-feature { padding-top: 14px; }
  .tada-anim.stack-on .feat-tab { margin-bottom: 16px; padding: 9px 22px; font-size: 1.05rem; }
}

/* Mobile: compact the stacked cards (tighter spacing, smaller video/type) so each pinned
   card fits the short viewport and its CTA isn't cut off before the next card covers it. */
@media (max-width: 899px) {
  .tada-anim.stack-on .anim-feature .feature { padding: 16px; gap: 14px; }
  .tada-anim.stack-on .anim-feature .h-display { font-size: 1.3rem; line-height: 1.2; }
  .tada-anim.stack-on .anim-feature .beat { font-size: .9rem; line-height: 1.45; margin: 0; }
  .tada-anim.stack-on .anim-feature .micro-cta { margin-top: 4px; }
  .tada-anim.stack-on .anim-feature .feature-visual { width: 74%; margin-inline: auto; }
}

/* Hero opening question — larger, highlighted subheading (animated page only). */
.tada-anim .hero-question {
  font-size: clamp(1.25rem, 2.4vw, 1.7rem);
  font-weight: 700;
  line-height: 1.3;
  color: var(--tada-primary);
  max-width: 30ch;
}

/* Scroll cue — a soft bouncing chevron under the hero CTA */
.tada-anim .scroll-cue {
  width: 26px;
  height: 42px;
  margin: 46px auto 0;
  border: 2px solid rgba(106, 98, 133, .45);
  border-radius: 999px;
  position: relative;
}
.tada-anim .scroll-cue span {
  position: absolute;
  left: 50%;
  top: 9px;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  border-radius: 50%;
  background: var(--rose);
}
@media (prefers-reduced-motion: no-preference) {
  .tada-anim .scroll-cue span { animation: cueDrop 1.7s ease-in-out infinite; }
}
@keyframes cueDrop {
  0%   { transform: translateY(0);    opacity: 0; }
  30%  { opacity: 1; }
  70%  { transform: translateY(16px); opacity: 0; }
  100% { transform: translateY(16px); opacity: 0; }
}

/* ---- Intro lead-in (reused "Hub" head) ---- */
.tada-anim .anim-intro { padding-block: clamp(56px, 8vw, 96px) clamp(20px, 3vw, 34px); }

/* Contrast-safe brand gradient for TEXT on the cream paper background.
   The standard --tada-orange stop is ~2:1 on paper (fails WCAG 3:1 for large
   text); a deeper burnt-orange end keeps the warm brand look while every glyph
   stays >=3:1. Applied to the Hub heading AND the hero accent line. */
.tada-anim .anim-intro .h-display,
.tada-anim .line-accent {
  background: linear-gradient(100deg, var(--tada-primary) 0%, var(--tada-pink) 45%, #D9531F 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Hub brand/logo video banner — full width under the intro text.
   Rounded + soft shadow (no gradient border: the clip is already gradient). */
.tada-anim .anim-intro .hub-video {
  margin-top: clamp(28px, 4vw, 48px);
  will-change: transform, opacity;
}
.tada-anim .anim-intro .hub-video .anim-video {
  box-shadow: 0 24px 60px -34px rgba(43, 26, 36, .42);
}

/* ---- Animated feature sections ---- */
/* Tighter vertical rhythm so the cards read as a stacked list. */
.tada-anim .anim-feature { overflow: clip; padding-block: clamp(16px, 2.4vw, 30px); }
.tada-anim .anim-feature:last-of-type { padding-bottom: clamp(56px, 8vw, 96px); }

/* Each feature stands on its own: original paper background kept, distinguished
   by a rounded border in the signature brand gradient (violet -> pink -> orange).
   The padding-box/border-box trick lets the gradient border keep rounded corners. */
.tada-anim .anim-feature .feature {
  position: relative;
  background:
    linear-gradient(var(--paper), var(--paper)) padding-box,
    linear-gradient(120deg, var(--tada-primary) 0%, var(--tada-pink) 52%, var(--tada-orange) 100%) border-box;
  border: 2px solid transparent;
  border-radius: var(--radius-lg);
  box-shadow: 0 16px 44px -32px rgba(43, 26, 36, .26);
  padding: clamp(24px, 3.6vw, 52px);
}

/* ===== Interactive glowing border — vanilla port of the Aceternity GlowingEffect =====
   Same conic-gradient-through-a-moving-mask technique, brand colors, driven by GSAP
   (not the `motion` lib). Purely additive over the static border above. Enabled only when
   JS adds `glow-on` to <body> (fine pointer + motion allowed) — never on touch/reduced-motion. */
.tada-anim.glow-on .anim-feature .feature {
  --glow-start: 0;      /* arc angle, animated toward the cursor */
  --glow-active: 0;     /* 0 = hidden, 1 = visible (near cursor) */
  --glow-spread: 60;    /* arc width in degrees (wider = more of the border glows) */
  --glow-w: 2px;        /* glow border thickness */
}
/* Two shared layers: a crisp arc (::after) + a blurred bloom/halo (::before) so the glow
   is clearly visible even on the light cream background. */
.tada-anim.glow-on .anim-feature .feature::before,
.tada-anim.glow-on .anim-feature .feature::after {
  content: "";
  position: absolute;
  border-radius: inherit;
  pointer-events: none;
  opacity: var(--glow-active);
  transition: opacity .3s ease;
  background:
    radial-gradient(circle, var(--tada-teal) 12%, transparent 22%),
    radial-gradient(circle at 40% 40%, var(--tada-orange) 8%, transparent 18%),
    radial-gradient(circle at 60% 60%, var(--tada-violet) 12%, transparent 22%),
    radial-gradient(circle at 40% 60%, var(--tada-blue) 12%, transparent 22%),
    repeating-conic-gradient(from 236.84deg at 50% 50%,
      var(--tada-teal) 0%,
      var(--tada-blue) calc(20% / 5),
      var(--tada-violet) calc(40% / 5),
      var(--tada-pink) calc(60% / 5),
      var(--tada-orange) calc(80% / 5),
      var(--tada-teal) calc(100% / 5));
  background-attachment: fixed;
  mask-clip: padding-box, border-box;
  mask-composite: intersect;
  mask-image:
    linear-gradient(#0000, #0000),
    conic-gradient(from calc((var(--glow-start) - var(--glow-spread)) * 1deg),
      #0000 0deg, #fff, #0000 calc(var(--glow-spread) * 2deg));
  -webkit-mask-image:
    linear-gradient(#0000, #0000),
    conic-gradient(from calc((var(--glow-start) - var(--glow-spread)) * 1deg),
      #0000 0deg, #fff, #0000 calc(var(--glow-spread) * 2deg));
  -webkit-mask-clip: padding-box, border-box;
  -webkit-mask-composite: source-in;
}
/* Crisp bright arc riding the border. */
.tada-anim.glow-on .anim-feature .feature::after {
  inset: calc(-1 * var(--glow-w));
  border: var(--glow-w) solid transparent;
  filter: saturate(1.5) brightness(1.12);
}
/* Soft blurred bloom behind it — this is what makes the glow read as a "glimmer". */
.tada-anim.glow-on .anim-feature .feature::before {
  inset: calc(-1 * var(--glow-w) - 5px);
  border: calc(var(--glow-w) + 5px) solid transparent;
  filter: saturate(1.5) brightness(1.15) blur(9px);
  opacity: calc(var(--glow-active) * 0.9);
}
.tada-anim .anim-feature .anim-visual { will-change: transform, opacity; }

/* Founder feature image, once dropped in */
.tada-anim .anim-img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
}

/* Founder feature CLIP (10s Pixar-style loop), once dropped in.
   Autoplay/pause is handled by JS on scroll; poster shows before play
   and under reduced-motion. */
.tada-anim .anim-video {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;   /* reserve space -> no layout shift (CLS) before metadata loads */
  object-fit: cover;
  display: block;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-soft);
  background: var(--paper-2);
}

/* "Coming Soon" badge for not-yet-live features */
.tada-anim .soon-badge {
  display: inline-block;
  margin-bottom: 12px;
  padding: 3px 12px;
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tada-primary-deep);
  background: var(--tada-amber);
  border-radius: 999px;
}

/* Device-smart app CTA (populated by initAppLinks in tada-anim.js) */
.tada-anim .app-cta { display: inline-flex; }
.tada-anim .app-btn { display: inline-flex; align-items: center; gap: 9px; }
.tada-anim .app-btn .store-ic { width: 18px; height: 18px; flex: none; display: block; }
.tada-anim .app-btn .store-ic + .store-ic { margin-left: -4px; }   /* tuck the two logos together */
/* desktop: two store badges side by side (badge styling comes from tada-home.css) */
.tada-anim .app-cta--badges { display: inline-flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.tada-anim .store-badge.is-soon { opacity: .65; cursor: default; }

/* Placeholder slot shown until a real image is added */
.tada-anim .anim-img-ph {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  display: grid;
  place-items: center;
  text-align: center;
  color: #fff;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.3;
  background:
    linear-gradient(120deg, rgba(124,57,211,.9) 0%, rgba(236,69,131,.88) 55%, rgba(255,138,76,.85) 100%);
}
.tada-anim .anim-img-ph span { padding: 18px; text-shadow: 0 2px 10px rgba(43,26,36,.28); }

/* ---- Scaffold note (temporary) ---- */
.tada-anim .scaffold-note {
  text-align: center;
  color: var(--ink-soft);
  font-size: .95rem;
  max-width: 60ch;
  margin-inline: auto;
  padding: 16px 22px;
  border: 1px dashed rgba(91,60,220,.35);
  border-radius: var(--radius);
  background: rgba(238,234,254,.5);
}
