/* ============================================================
   ANIMATIONS.CSS — 20 preset entrance animations.
   10 basic + 10 premium (high-end / top-tier feel).
   Each element gets `data-tpr-anim="<name>"`, plus `.tpr-in-view`
   when it enters the viewport (added by animations.js).
   ============================================================ */

[data-tpr-anim] { opacity: 0; will-change: transform, opacity, filter, clip-path; }
[data-tpr-anim="none"] { opacity: 1; }
[data-tpr-anim].tpr-in-view { opacity: 1; }

/* -------- 1. BASIC (10) -------- */

[data-tpr-anim="fade-in"] { transition: opacity .25s ease; }

[data-tpr-anim="fade-up"] { transform: translateY(14px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="fade-up"].tpr-in-view { transform: translateY(0); }

[data-tpr-anim="fade-down"] { transform: translateY(-14px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="fade-down"].tpr-in-view { transform: translateY(0); }

[data-tpr-anim="slide-left"] { transform: translateX(20px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="slide-left"].tpr-in-view { transform: translateX(0); }

[data-tpr-anim="slide-right"] { transform: translateX(-20px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="slide-right"].tpr-in-view { transform: translateX(0); }

[data-tpr-anim="slide-up"] { transform: translateY(20px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="slide-up"].tpr-in-view { transform: translateY(0); }

[data-tpr-anim="slide-down"] { transform: translateY(-20px); transition: opacity .28s ease, transform .28s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="slide-down"].tpr-in-view { transform: translateY(0); }

[data-tpr-anim="zoom-in"] { transform: scale(.92); transition: opacity .26s ease, transform .26s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="zoom-in"].tpr-in-view { transform: scale(1); }

[data-tpr-anim="zoom-out"] { transform: scale(1.08); transition: opacity .26s ease, transform .26s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="zoom-out"].tpr-in-view { transform: scale(1); }

[data-tpr-anim="bounce-in"] { transform: scale(.9); transition: opacity .22s ease, transform .3s cubic-bezier(.34,1.56,.64,1); }
[data-tpr-anim="bounce-in"].tpr-in-view { transform: scale(1); }


/* -------- 2. PREMIUM / HIGH-END (10) -------- */

/* Blur-in — Apple / Linear style */
[data-tpr-anim="blur-in"] { filter: blur(8px); transform: translateY(8px); transition: opacity .3s ease, filter .3s ease, transform .3s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="blur-in"].tpr-in-view { filter: blur(0); transform: translateY(0); }

/* Clip reveal — text unmasked from the bottom */
[data-tpr-anim="clip-reveal"] { clip-path: inset(0 0 100% 0); transform: translateY(12px); transition: clip-path .38s cubic-bezier(.77,0,.175,1), transform .38s cubic-bezier(.77,0,.175,1), opacity .2s ease; }
[data-tpr-anim="clip-reveal"].tpr-in-view { clip-path: inset(0 0 0 0); transform: translateY(0); }

/* Gradient sweep — animated diagonal sheen, transform-only so it never
   forces a repaint (background-position would repaint every frame —
   this moves a pre-painted gradient layer via translate3d instead,
   same technique as the .s-card sweep, so it stays cheap on weak GPUs). */
[data-tpr-anim="gradient-sweep"] { position: relative; overflow: hidden; transition: opacity .5s ease; }
[data-tpr-anim="gradient-sweep"].tpr-in-view::after {
  content: ""; position: absolute; top: 0; left: 0; width: 60%; height: 100%; pointer-events: none;
  background: linear-gradient(115deg, transparent 0%, transparent 30%, rgba(255,255,255,.55) 50%, transparent 70%, transparent 100%);
  transform: translate3d(-170%, 0, 0) skewX(-12deg);
  animation: tprSheen 2.2s ease-in-out infinite;
  will-change: transform;
}
@keyframes tprSheen { 0% { transform: translate3d(-170%,0,0) skewX(-12deg); } 100% { transform: translate3d(280%,0,0) skewX(-12deg); } }

/* Letter cascade — each character fades up in sequence.
   editor-bridge.js and cms-loader.js split textContent into
   <span class="tpr-letter"> tokens when this animation is set. */
@keyframes tprLetterUp { from { opacity: 0; transform: translateY(0.8em); } to { opacity: 1; transform: translateY(0); } }
[data-tpr-anim="letter-cascade"] { opacity: 1; }
[data-tpr-anim="letter-cascade"] .tpr-letter { display: inline-block; opacity: 0; transform: translateY(0.8em); }
[data-tpr-anim="letter-cascade"].tpr-in-view .tpr-letter { animation: tprLetterUp .3s cubic-bezier(.16,1,.3,1) forwards; animation-delay: calc(var(--i, 0) * 8ms); }

/* Split reveal — two halves slide open like a curtain (uses ::before) */
[data-tpr-anim="split-reveal"] { position: relative; overflow: hidden; transition: opacity .4s ease; }
[data-tpr-anim="split-reveal"]::before,
[data-tpr-anim="split-reveal"]::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 50%;
  background: currentColor; opacity: .12; transition: transform .35s cubic-bezier(.77,0,.175,1);
  pointer-events: none;
}
[data-tpr-anim="split-reveal"]::before { left: 0; }
[data-tpr-anim="split-reveal"]::after  { right: 0; }
[data-tpr-anim="split-reveal"].tpr-in-view::before { transform: translateX(-101%); }
[data-tpr-anim="split-reveal"].tpr-in-view::after  { transform: translateX(101%); }

/* Tilt-in — 3D perspective drop */
[data-tpr-anim="tilt-in"] { transform: perspective(900px) rotateX(12deg) translateY(12px); transform-origin: 50% 100%; transition: opacity .28s ease, transform .34s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="tilt-in"].tpr-in-view { transform: perspective(900px) rotateX(0) translateY(0); }

/* Skew-in — editorial magazine feel */
[data-tpr-anim="skew-in"] { transform: translateX(-16px) skewX(-8deg); transition: opacity .28s ease, transform .3s cubic-bezier(.16,1,.3,1); }
[data-tpr-anim="skew-in"].tpr-in-view { transform: translateX(0) skewX(0); }

/* Elastic — spring settle, luxury product feel */
[data-tpr-anim="elastic"] { transform: scale(.7) rotate(-6deg); transition: opacity .18s ease, transform .38s cubic-bezier(.5,1.7,.4,1); }
[data-tpr-anim="elastic"].tpr-in-view { transform: scale(1) rotate(0); }

/* Breathe — subtle looping scale, used by Apple product tiles */
@keyframes tprBreathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.025); } }
[data-tpr-anim="breathe"] { transition: opacity .5s ease; }
[data-tpr-anim="breathe"].tpr-in-view { animation: tprBreathe 4.5s ease-in-out infinite; }

/* Shimmer border — animated gradient outline, Vercel/Stripe style */
@keyframes tprShimmerBorder { 0% { background-position: 0 0; } 100% { background-position: 300% 0; } }
[data-tpr-anim="shimmer-border"] { position: relative; transition: opacity .4s ease; }
[data-tpr-anim="shimmer-border"].tpr-in-view {
  background-image: linear-gradient(var(--tpr-shimmer-bg, #fff), var(--tpr-shimmer-bg, #fff)),
                    linear-gradient(115deg, #00e5ff, #6a5cff, #ff5cf1, #00e5ff);
  background-origin: border-box; background-clip: padding-box, border-box;
  background-size: auto, 300% 100%;
  border: 2px solid transparent; border-radius: 12px;
  animation: tprShimmerBorder 4s linear infinite;
}


/* -------- Editor helpers -------- */

/* When admin hovers the animation name in the sidebar, we add
   `.tpr-preview-anim` to force a replay regardless of scroll state. */
[data-tpr-anim].tpr-preview-anim { animation-play-state: running; }

/* High-refresh (120/144Hz) friendly motion — shorter frames, GPU-composited */
@media (prefers-reduced-motion: no-preference) {
  .reveal, .reveal-r, .reveal-l, .reveal-scale {
    transition-duration: 0.26s;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  .hero-cta-card, .s-card, .contact-card, .why-card, .r-card {
    transition-duration: 0.22s;
    transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
}
/* Prefer compositor layers for animated elements */
.hero-slideshow, .hero-slide, .contact-card, .hero-cta-card {
  transform: translateZ(0);
  backface-visibility: hidden;
}
