/* DarkTiger motion library v1, 2026-09-23. Loads after tokens.css. Wrappers, never hand-animated per project.
   Rules that are law here: transform and opacity only; every effect has a reduced-motion variant and a
   mobile switch; nothing blocks first paint; space is reserved before animating so CLS stays at 0. */

/* Entrance wrappers. Add data-reveal to any element; motion.js adds .in when it enters the viewport.
   Without JS the element is simply visible, so the page is never blank if the script fails. */
[data-reveal] { opacity: 1; }
.js [data-reveal] { opacity: 0; transition: opacity var(--d-slow) var(--e-out), transform var(--d-slow) var(--e-out); will-change: opacity, transform; }
.js [data-reveal="up"]    { transform: translateY(var(--move-md)); }
.js [data-reveal="down"]  { transform: translateY(calc(var(--move-md) * -1)); }
.js [data-reveal="left"]  { transform: translateX(var(--move-md)); }
.js [data-reveal="right"] { transform: translateX(calc(var(--move-md) * -1)); }
.js [data-reveal="scale"] { transform: scale(.96); }
.js [data-reveal="blur"]  { filter: blur(8px); transition: opacity var(--d-slow) var(--e-out), filter var(--d-slow) var(--e-out); }
.js [data-reveal].in { opacity: 1; transform: none; filter: none; will-change: auto; }

/* Stagger container: children reveal in sequence. */
.js [data-stagger] > * { opacity: 0; transform: translateY(var(--move-sm)); transition: opacity var(--d-base) var(--e-out), transform var(--d-base) var(--e-out); }
.js [data-stagger].in > * { opacity: 1; transform: none; }
.js [data-stagger].in > *:nth-child(1) { transition-delay: calc(var(--stagger) * 0); }
.js [data-stagger].in > *:nth-child(2) { transition-delay: calc(var(--stagger) * 1); }
.js [data-stagger].in > *:nth-child(3) { transition-delay: calc(var(--stagger) * 2); }
.js [data-stagger].in > *:nth-child(4) { transition-delay: calc(var(--stagger) * 3); }
.js [data-stagger].in > *:nth-child(5) { transition-delay: calc(var(--stagger) * 4); }
.js [data-stagger].in > *:nth-child(n+6) { transition-delay: calc(var(--stagger) * 5); }

/* Hover interactions, pointer devices only so a tap never leaves an element stuck in a hover state. */
@media (hover: hover) and (pointer: fine) {
  [data-hover="lift"] { transition: transform var(--d-fast) var(--e-out), box-shadow var(--d-fast) var(--e-out); }
  [data-hover="lift"]:hover { transform: translateY(-4px); box-shadow: var(--sh-lg); }
  [data-hover="zoom"] { overflow: hidden; }
  [data-hover="zoom"] img { transition: transform var(--d-slow) var(--e-out); }
  [data-hover="zoom"]:hover img { transform: scale(1.04); }
  [data-hover="underline"] { background-image: linear-gradient(currentColor, currentColor); background-size: 0% 2px; background-repeat: no-repeat; background-position: 0 100%; transition: background-size var(--d-base) var(--e-out); text-decoration: none; }
  [data-hover="underline"]:hover { background-size: 100% 2px; }
  [data-hover="sweep"] { position: relative; overflow: hidden; z-index: 0; }
  [data-hover="sweep"]::before { content: ""; position: absolute; inset: 0; background: currentColor; opacity: .12; transform: translateX(-101%); transition: transform var(--d-base) var(--e-out); z-index: -1; }
  [data-hover="sweep"]:hover::before { transform: none; }
}

/* Marquee. Pauses on hover and off-screen, and holds still under reduced motion. */
.marquee { overflow: hidden; }
.marquee > * { display: flex; gap: var(--s-6); width: max-content; animation: dt-marquee var(--d-slowest) linear infinite; animation-duration: 30s; }
.marquee:hover > * { animation-play-state: paused; }
@keyframes dt-marquee { to { transform: translateX(-50%); } }

/* Count-up reserves its width first so nothing shifts. */
[data-count] { font-variant-numeric: tabular-nums; }

/* Everything off below the tablet breakpoint except the plain fade, and off entirely under reduced motion. */
@media (max-width: 768px) {
  .js [data-reveal]:not([data-reveal="fade"]) { transform: none; filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal], .js [data-stagger] > * { opacity: 1 !important; transform: none !important; filter: none !important; transition: none !important; }
  .marquee > * { animation: none; }
}
