/* ============================================================================
   PULSE ID · MOTION SYSTEM — motion.css
   ----------------------------------------------------------------------------
   SINGLE SOURCE OF TRUTH for every animation on the site.
   Pair file: motion.js (the engine) · Spec: MOTION.md · Catalog: motion.manifest.json

   WHY THIS FILE EXISTS
   The reference site (roqt.com.br) is built in Framer — its animations are
   generated at runtime by JavaScript and DO NOT exist as CSS @keyframes or
   transitions. A DOM capture therefore contains ZERO extractable animation.
   So we DEFINE our motion here, declaratively, so it can be recognized, audited
   and ported (e.g. into the Astro codebase) by reading ONE module.

   HOW IT WORKS
   - All effects are gated behind `html.motion`, a class set synchronously by
     motion.js before first paint. If JS is off, nothing is hidden (SEO/no-JS safe).
   - Effects are triggered by motion.js adding `.in` once an element scrolls into
     view (IntersectionObserver). CSS only declares the from/to states + timing.

   TWO WAYS TO APPLY AN ANIMATION (pick either; they're equivalent)
   1. Declarative attribute  → data-anim="reveal"          (preferred for new work)
   2. Utility class           → class="reveal"             (legacy, still supported)

   STAGGER
   - Put data-anim-stagger on a CONTAINER → motion.js sets --i on each child and
     adds .in as the container enters view. Children animate in sequence.
   - Tune step with data-anim-stagger="90" (ms). Default 70ms.

   COUNT-UP NUMBERS
   - <span class="count" data-to="90" data-prefix="+" data-suffix="%"></span>
   - Optional data-dec="1" for decimals (pt-BR formatting, e.g. 3,5).

   EASING TOKEN
   --ease-out: the house easing for every reveal. Change once, applies everywhere.
   ============================================================================ */

:root {
  --ease-out: cubic-bezier(.16, .84, .44, 1);
  --motion-dur: 1.05s;    /* default reveal duration (slower, more cinematic) */
  --motion-rise: 34px;    /* default travel distance for reveal */
  --motion-stagger: 110ms;/* default per-child stagger step (JS reads this too) */
}

/* ----------------------------------------------------------------------------
   1 · REVEAL FAMILY — fade + directional travel, played once on scroll-in
   Targets:  [data-anim="reveal"] | .reveal   (and reveal-left/right/scale/blur)
   Trigger:  motion.js adds .in when ≥16% visible
   ---------------------------------------------------------------------------- */
html.motion [data-anim^="reveal"],
html.motion .reveal {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-dur) var(--ease-out),
              transform var(--motion-dur) var(--ease-out);
  will-change: opacity, transform;
}
html.motion [data-anim="reveal-up"]    { transform: translateY(var(--motion-rise)); }
html.motion [data-anim="reveal-down"]  { transform: translateY(calc(-1 * var(--motion-rise))); }
html.motion [data-anim="reveal-left"]  { transform: translateX(var(--motion-rise)); }
html.motion [data-anim="reveal-right"] { transform: translateX(calc(-1 * var(--motion-rise))); }
html.motion [data-anim="reveal-scale"] { transform: scale(.94); }
html.motion [data-anim="reveal-blur"]  { filter: blur(10px); }

/* Settled state — one rule clears every reveal variant */
html.motion [data-anim^="reveal"].in,
html.motion .reveal.in {
  opacity: 1;
  transform: none;
  filter: none;
}

/* SETTLE FAILSAFE — motion.js adds .motion-settled ~1.4s after reveal.
   Guarantees full visibility even where CSS transitions never advance
   (throttled/offscreen render contexts). No-op once a normal fade finished. */
html.motion .reveal.motion-settled,
html.motion [data-anim].motion-settled,
html.motion .stagger.motion-settled > *,
html.motion [data-anim-stagger].motion-settled > * {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
  transition: none !important;
}

/* ----------------------------------------------------------------------------
   2 · STAGGER — children animate in sequence inside a marked container
   Container: [data-anim-stagger] | .stagger
   motion.js writes --i (child index) and adds .in to the container.
   ---------------------------------------------------------------------------- */
html.motion [data-anim-stagger] > *,
html.motion .stagger > * {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-dur) var(--ease-out),
              transform var(--motion-dur) var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--motion-stagger));
  will-change: opacity, transform;
}
html.motion [data-anim-stagger].in > *,
html.motion .stagger.in > * {
  opacity: 1;
  transform: none;
}

/* Hero intro: copy children stagger in on load (index drives delay) */
html.motion .hero-copy > .reveal { transition-delay: calc(.04s + var(--i, 0) * 80ms); }
html.motion .hero-visual.reveal  { transition-delay: .18s; }

/* ----------------------------------------------------------------------------
   3 · BAR GROW — data-viz bars rise from their baseline (hero + Soluções charts)
   Targets:  any .chart inside an element that gets .in
   ---------------------------------------------------------------------------- */
html.motion .in .chart .col,
html.motion .chart.in .col {
  transform-origin: bottom;
  animation: barGrow .85s var(--ease-out) both;
}
html.motion .chart .col { transform: scaleY(0); transform-origin: bottom; }
html.motion .in .chart .col:nth-child(1) { animation-delay: .30s; }
html.motion .in .chart .col:nth-child(2) { animation-delay: .37s; }
html.motion .in .chart .col:nth-child(3) { animation-delay: .44s; }
html.motion .in .chart .col:nth-child(4) { animation-delay: .51s; }
html.motion .in .chart .col:nth-child(5) { animation-delay: .58s; }
html.motion .in .chart .col:nth-child(6) { animation-delay: .65s; }
html.motion .in .chart .col:nth-child(7) { animation-delay: .72s; }
html.motion .in .chart .col:nth-child(8) { animation-delay: .79s; }
@keyframes barGrow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* ----------------------------------------------------------------------------
   4 · COUNT-UP — numbers tick from 0 to data-to (logic in motion.js)
   tabular-nums keeps the width stable so layout doesn't jump while counting.
   ---------------------------------------------------------------------------- */
.count { font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------------------------
   5 · MARQUEE — continuous horizontal logo/tech scroll (for a logo wall)
   Markup: <div class="marquee"><div class="marquee-track"> …items… (duplicated) </div></div>
   Pure CSS, runs always (not scroll-gated). Pauses on hover.
   ---------------------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  padding-block: 6px;
}
.marquee-track { display: flex; align-items: center; gap: 0.85rem; width: max-content; animation: marquee 38s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ----------------------------------------------------------------------------
   6 · NAV — gains shadow depth once the page is scrolled (solidity cue)
   motion.js toggles .scrolled past 8px.
   ---------------------------------------------------------------------------- */
.nav.scrolled { box-shadow: 0 1px 0 rgba(15,23,42,.05), 0 10px 34px -20px rgba(15,23,42,.30); }

/* ----------------------------------------------------------------------------
   ACCESSIBILITY — prefers-reduced-motion
   We do NOT kill everything (that made reveals invisible + counters instant).
   Opacity fades and number counting are vestibular-safe; only LARGE motion
   (translate/scale travel, blur, looping marquee, growing bars) is removed.
   So a gentle fade-in still plays for everyone.
   ---------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.motion [data-anim^="reveal"],
  html.motion .reveal,
  html.motion [data-anim-stagger] > *,
  html.motion .stagger > * {
    transform: none !important;   /* no travel / scale */
    filter: none !important;      /* no blur */
    /* opacity transition kept → still fades in softly */
  }
  html.motion .chart .col { transform: none !important; animation: none !important; }
  .marquee-track { animation-play-state: paused !important; }
  html { scroll-behavior: auto !important; }
}
