/* =========================================================================
   text-animations — reusable per-character / per-word text reveal library
   93 CSS keyframe effects + base helper classes for text-animate.js
   Reimplemented & parameterised from the "100 Text Animations" gallery
   (kawai-text-animation.pages.dev). Colours are tokenised so effects
   inherit the host design instead of hard-coded white-on-black.
   ========================================================================= */

/* ---------- tokens (override per element or globally) ---------- */
:where([data-ta], .ta) {
  --ta-duration: 0.6s;
  --ta-step: 0.05s;          /* stagger between units */
  --ta-delay: 0s;            /* delay before the first unit */
  --ta-ease: cubic-bezier(0.22, 0.7, 0.2, 1);

  --ta-glow: #ffffff;        /* Glow In */
  --ta-neon: #22d3ee;        /* Pulse Neon */
  --ta-stroke: currentColor; /* Outline <-> Solid */
  --ta-c1: currentColor;     /* Color Shift */
  --ta-c2: #ff2d75;
  --ta-c3: #22d3ee;
  --ta-glitch-r: #ff2d55;    /* Glitch RGB */
  --ta-glitch-b: #00e5ff;
  --ta-shadow: rgba(0,0,0,0.35); /* Text Shadow Pop / Shadow First */
}

/* ---------- split units ---------- */
.ta__word {
  display: inline-block;
  white-space: nowrap;              /* a word never breaks between its letters */
}
.ta__u {
  display: inline-block;
  white-space: pre;                 /* keep spaces when splitting by char */
  will-change: transform, opacity, filter;
  backface-visibility: hidden;
}

/* Before JS arms the element the text is fully visible (no-JS safe).
   Once armed, units hide until their run starts. */
[data-ta].ta-armed .ta__u,
.ta.ta-armed .ta__u { opacity: 0; }

[data-ta].ta-run .ta__u,
.ta.ta-run .ta__u {
  animation-name: var(--ta-name, fadeIn);
  animation-duration: var(--ta-duration);
  animation-timing-function: var(--ta-ease);
  animation-fill-mode: both;
  animation-delay: calc(var(--ta-i, 0) * var(--ta-step) + var(--ta-delay));
}

/* whole-element effects (letter-spacing based): data-ta-by="none" */
[data-ta].ta-run.ta-whole,
.ta.ta-run.ta-whole {
  display: inline-block;
  animation-name: var(--ta-name, fadeIn);
  animation-duration: var(--ta-duration);
  animation-timing-function: var(--ta-ease);
  animation-fill-mode: both;
  animation-delay: var(--ta-delay);
}
[data-ta].ta-armed.ta-whole { opacity: 0; }

/* Safety fallback: force the final, readable state with no animation. Used when
   the effect can't be trusted to finish (throttled tab, no scroll, screenshot /
   print, slow device). Text must never stay invisible. */
[data-ta].ta-done .ta__u,
[data-ta].ta-done.ta-whole,
.ta.ta-done .ta__u,
.ta.ta-done.ta-whole {
  opacity: 1 !important;
  transform: none !important;
  filter: none !important;
  letter-spacing: normal !important;
  animation: none !important;
  transition: none !important;
}
[data-ta].ta-done .ta__cursor,
.ta.ta-done .ta__cursor { display: none; }

/* JS effects helpers */
.ta__cursor {
  display: inline-block;
  width: 0.08em;
  height: 1.1em;
  margin-left: 0.08em;
  background: currentColor;
  vertical-align: -0.15em;
  animation: taBlinkCursor 1s step-end infinite;
}
.ta__block {
  position: absolute; inset: 0;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
}

@media (prefers-reduced-motion: reduce) {
  [data-ta].ta-armed .ta__u, .ta.ta-armed .ta__u,
  [data-ta].ta-armed.ta-whole, .ta.ta-armed.ta-whole { opacity: 1; }
  [data-ta].ta-run .ta__u, .ta.ta-run .ta__u,
  [data-ta].ta-run.ta-whole, .ta.ta-run.ta-whole { animation: none !important; }
  .ta__cursor { animation: none; }
  .ta__block { display: none; }
}

/* =========================================================================
   Keyframes (93)
   ========================================================================= */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { transform: translateY(100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes slideDown { from { transform: translateY(-100%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes slideLeft { from { transform: translateX(-100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes slideRight { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes scaleIn { from { transform: scale(0); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes blurIn { from { filter: blur(12px); opacity: 0; transform: scale(1.1); } to { filter: blur(0); opacity: 1; transform: scale(1); } }
@keyframes glowIn { 0% { opacity: 0; text-shadow: 0 0 0 transparent; } 50% { opacity: 1; text-shadow: 0 0 20px var(--ta-glow); } 100% { opacity: 1; text-shadow: 0 0 0 transparent; } }
@keyframes bounceIn { 0% { transform: translateY(-50px); opacity: 0; animation-timing-function: cubic-bezier(0.8, 0, 1, 1); } 50% { transform: translateY(15px); opacity: 1; animation-timing-function: cubic-bezier(0, 0, 0.2, 1); } 75% { transform: translateY(-5px); opacity: 1; animation-timing-function: cubic-bezier(0.8, 0, 1, 1); } 100% { transform: translateY(0); opacity: 1; } }
@keyframes flipIn { from { transform: perspective(400px) rotateX(-90deg); opacity: 0; transform-origin: bottom; } to { transform: perspective(400px) rotateX(0deg); opacity: 1; transform-origin: bottom; } }
@keyframes rotateIn { from { transform: rotate(-180deg) scale(0); opacity: 0; } to { transform: rotate(0) scale(1); opacity: 1; } }
@keyframes dropIn { 0% { transform: translateY(-200%); opacity: 0; } 60% { transform: translateY(20%); opacity: 1; } 80% { transform: translateY(-10%); opacity: 1; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes swing { 0% { opacity: 0; transform: rotate(15deg); } 20% { opacity: 1; transform: rotate(15deg); } 40% { transform: rotate(-10deg); opacity: 1; } 60% { transform: rotate(5deg); opacity: 1; } 80% { transform: rotate(-5deg); opacity: 1; } 100% { transform: rotate(0deg); opacity: 1; } }
@keyframes pulse { 0% { transform: scale(1); opacity: 0; } 50% { transform: scale(1.2); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes flash { 0%, 50%, 100% { opacity: 1; } 25%, 75% { opacity: 0; } }
@keyframes shakeX { 0%, 100% { transform: translateX(0); opacity: 0; } 10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); opacity: 1; } 20%, 40%, 60%, 80% { transform: translateX(10px); opacity: 1; } }
@keyframes shakeY { 0%, 100% { transform: translateY(0); opacity: 0; } 10%, 30%, 50%, 70%, 90% { transform: translateY(-10px); opacity: 1; } 20%, 40%, 60%, 80% { transform: translateY(10px); opacity: 1; } }
@keyframes tada { 0% { transform: scale(1); opacity: 0; } 10%, 20% { transform: scale(0.9) rotate(-3deg); opacity: 1; } 30%, 50%, 70%, 90% { transform: scale(1.1) rotate(3deg); opacity: 1; } 40%, 60%, 80% { transform: scale(1.1) rotate(-3deg); opacity: 1; } 100% { transform: scale(1) rotate(0); opacity: 1; } }
@keyframes jello { 0% { transform: translate(0); opacity: 0; } 11.1% { transform: skewX(-12.5deg) skewY(-12.5deg); opacity: 1; } 22.2% { transform: skewX(6.25deg) skewY(6.25deg); opacity: 1; } 33.3% { transform: skewX(-3.125deg) skewY(-3.125deg); opacity: 1; } 44.4% { transform: skewX(1.5625deg) skewY(1.5625deg); opacity: 1; } 55.5% { transform: skewX(-0.78125deg) skewY(-0.78125deg); opacity: 1; } 66.6% { transform: skewX(0.390625deg) skewY(0.390625deg); opacity: 1; } 77.7% { transform: skewX(-0.1953125deg) skewY(-0.1953125deg); opacity: 1; } 100% { transform: translate(0); opacity: 1; } }
@keyframes rubberBand { 0% { transform: scale(1); opacity: 0; } 30% { transform: scaleX(1.25) scaleY(0.75); opacity: 1; } 40% { transform: scaleX(0.75) scaleY(1.25); opacity: 1; } 50% { transform: scaleX(1.15) scaleY(0.85); opacity: 1; } 65% { transform: scaleX(0.95) scaleY(1.05); opacity: 1; } 75% { transform: scaleX(1.05) scaleY(0.95); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes wave { 0%, 100% { transform: translateY(0); opacity: 1; } 50% { transform: translateY(-15px); opacity: 1; } }
@keyframes stretch { 0% { transform: scaleX(1); opacity: 0; } 50% { transform: scaleX(1.5); opacity: 1; } 100% { transform: scaleX(1); opacity: 1; } }
@keyframes squeeze { 0% { transform: scaleY(1); opacity: 0; } 50% { transform: scaleY(0.5); opacity: 1; } 100% { transform: scaleY(1); opacity: 1; } }
@keyframes colorShift { 0% { color: var(--ta-c1); opacity: 0; } 33% { color: var(--ta-c2); opacity: 1; } 66% { color: var(--ta-c3); opacity: 1; } 100% { color: var(--ta-c1); opacity: 1; } }
@keyframes zoomIn { 0% { transform: scale(0); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes zoomOut { 0% { transform: scale(2); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
@keyframes rollIn { 0% { transform: translateX(-100%) rotate(-120deg); opacity: 0; } 100% { transform: translateX(0) rotate(0); opacity: 1; } }
@keyframes glitch { 0% { transform: translate(0); opacity: 0; } 10% { transform: translate(-2px, 2px); opacity: 1; } 20% { transform: translate(-2px, -2px); opacity: 1; } 30% { transform: translate(2px, 2px); opacity: 1; } 40% { transform: translate(2px, -2px); opacity: 1; } 50% { transform: translate(-2px, 2px); opacity: 1; } 60% { transform: translate(-2px, -2px); opacity: 1; } 70% { transform: translate(2px, 2px); opacity: 1; } 80% { transform: translate(2px, -2px); opacity: 1; } 90% { transform: translate(-2px, 2px); opacity: 1; } 100% { transform: translate(0); opacity: 1; } }
@keyframes focusIn { 0% { filter: blur(12px); transform: scale(1.5); opacity: 0; } 100% { filter: blur(0); transform: scale(1); opacity: 1; } }
@keyframes fallDown { 0% { transform: translateY(-50px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes riseUp { 0% { transform: translateY(50px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes popIn { 0% { transform: scale(0.5); opacity: 0; } 80% { transform: scale(1.2); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes slitInV { 0% { transform: scaleY(0); opacity: 0; } 100% { transform: scaleY(1); opacity: 1; } }
@keyframes slitInH { 0% { transform: scaleX(0); opacity: 0; } 100% { transform: scaleX(1); opacity: 1; } }
@keyframes rollInTop { 0% { transform: translateY(-50px) rotate(-120deg); opacity: 0; } 100% { transform: translateY(0) rotate(0); opacity: 1; } }
@keyframes rollInBottom { 0% { transform: translateY(50px) rotate(120deg); opacity: 0; } 100% { transform: translateY(0) rotate(0); opacity: 1; } }
@keyframes bounceInLeft { 0% { transform: translateX(-50px); opacity: 0; } 60% { transform: translateX(10px); opacity: 1; } 80% { transform: translateX(-5px); opacity: 1; } 100% { transform: translateX(0); opacity: 1; } }
@keyframes bounceInRight { 0% { transform: translateX(50px); opacity: 0; } 60% { transform: translateX(-10px); opacity: 1; } 80% { transform: translateX(5px); opacity: 1; } 100% { transform: translateX(0); opacity: 1; } }
@keyframes rotateInY { 0% { transform: perspective(400px) rotateY(90deg); opacity: 0; } 100% { transform: perspective(400px) rotateY(0deg); opacity: 1; } }
@keyframes rotateInX { 0% { transform: perspective(400px) rotateX(90deg); opacity: 0; } 100% { transform: perspective(400px) rotateX(0deg); opacity: 1; } }
@keyframes flicker { 0%, 2%, 4%, 8%, 12%, 16%, 20% { opacity: 0; } 1%, 3%, 5%, 9%, 13%, 17%, 21%, 100% { opacity: 1; } }
@keyframes blurInRight { 0% { transform: translateX(50px); filter: blur(10px); opacity: 0; } 100% { transform: translateX(0); filter: blur(0); opacity: 1; } }
@keyframes blurInLeft { 0% { transform: translateX(-50px); filter: blur(10px); opacity: 0; } 100% { transform: translateX(0); filter: blur(0); opacity: 1; } }
@keyframes flyInUp { 0% { transform: translateY(200px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes flyInDown { 0% { transform: translateY(-200px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes wobble { 0% { transform: translateX(0%); } 15% { transform: translateX(-15%) rotate(-5deg); opacity: 1; } 30% { transform: translateX(10%) rotate(3deg); } 45% { transform: translateX(-10%) rotate(-3deg); } 60% { transform: translateX(5%) rotate(2deg); } 75% { transform: translateX(-2%) rotate(-1deg); } 100% { transform: translateX(0%); opacity: 1; } }
@keyframes trackingInExpand { 0% { letter-spacing: -0.5em; opacity: 0; } 100% { letter-spacing: normal; opacity: 1; } }
@keyframes trackingInContract { 0% { letter-spacing: 1em; opacity: 0; } 100% { letter-spacing: normal; opacity: 1; } }
@keyframes skewInUp { 0% { transform: translateY(100%) skewY(20deg); opacity: 0; } 100% { transform: translateY(0) skewY(0deg); opacity: 1; } }
@keyframes skewInDown { 0% { transform: translateY(-100%) skewY(-20deg); opacity: 0; } 100% { transform: translateY(0) skewY(0deg); opacity: 1; } }
@keyframes skewInLeft { 0% { transform: translateX(-100%) skewX(30deg); opacity: 0; } 100% { transform: translateX(0) skewX(0deg); opacity: 1; } }
@keyframes skewInRight { 0% { transform: translateX(100%) skewX(-30deg); opacity: 0; } 100% { transform: translateX(0) skewX(0deg); opacity: 1; } }
@keyframes unfoldV { 0% { transform: rotateX(-90deg); opacity: 0; } 100% { transform: rotateX(0deg); opacity: 1; } }
@keyframes unfoldH { 0% { transform: rotateY(-90deg); opacity: 0; } 100% { transform: rotateY(0deg); opacity: 1; } }
@keyframes outlineSolid { 0% { -webkit-text-stroke: 1px var(--ta-stroke); color: transparent; opacity: 0; } 50% { -webkit-text-stroke: 1px var(--ta-stroke); color: transparent; opacity: 1; } 100% { -webkit-text-stroke: 0 transparent; color: currentColor; opacity: 1; } }
@keyframes solidOutline { 0% { -webkit-text-stroke: 0 transparent; color: currentColor; opacity: 0; } 50% { -webkit-text-stroke: 0 transparent; color: currentColor; opacity: 1; } 100% { -webkit-text-stroke: 1px var(--ta-stroke); color: transparent; opacity: 1; } }
@keyframes smokeIn { 0% { transform: translateY(-20px) scale(1.5); filter: blur(20px); opacity: 0; } 100% { transform: translateY(0) scale(1); filter: blur(0); opacity: 1; } }
@keyframes smokeOut { 0% { transform: translateY(0) scale(1); filter: blur(0); opacity: 1; } 100% { transform: translateY(-20px) scale(1.5); filter: blur(20px); opacity: 0; } }
@keyframes slotDrop { 0% { transform: translateY(-300%); filter: blur(5px); opacity: 0; } 50% { transform: translateY(20%); filter: blur(2px); opacity: 1; } 100% { transform: translateY(0); filter: blur(0); opacity: 1; } }
@keyframes elasticScale { 0% { transform: scale(0); opacity: 0; } 60% { transform: scale(1.3); opacity: 1; } 80% { transform: scale(0.9); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes glitchRGB { 0% { text-shadow: 2px 0 0 var(--ta-glitch-r), -2px 0 0 var(--ta-glitch-b); opacity: 0; } 20% { text-shadow: -2px 0 0 var(--ta-glitch-r), 2px 0 0 var(--ta-glitch-b); opacity: 1; } 40% { text-shadow: 2px 0 0 var(--ta-glitch-r), -2px 0 0 var(--ta-glitch-b); } 60% { text-shadow: -2px 0 0 var(--ta-glitch-r), 2px 0 0 var(--ta-glitch-b); } 80% { text-shadow: 1px 0 0 var(--ta-glitch-r), -1px 0 0 var(--ta-glitch-b); } 100% { text-shadow: 0 0 0 transparent; opacity: 1; } }
@keyframes waterDrop { 0% { transform: translateY(-100px) scale(0.1, 2); opacity: 0; } 50% { transform: translateY(0) scale(1.5, 0.5); opacity: 1; } 100% { transform: translateY(0) scale(1, 1); opacity: 1; } }
@keyframes antiGravity { 0% { transform: translateY(0); opacity: 0; } 50% { opacity: 1; transform: translateY(-20px); } 100% { transform: translateY(-50px); opacity: 0; } }
@keyframes fallingLeaves { 0% { transform: translate(0, -50px) rotate(0deg); opacity: 0; } 50% { transform: translate(20px, 0) rotate(45deg); opacity: 1; } 100% { transform: translate(-20px, 50px) rotate(90deg); opacity: 0; } }
@keyframes slingshot { 0% { transform: perspective(600px) translateZ(-500px) scale(0.1); opacity: 0; } 60% { transform: perspective(600px) translateZ(100px) scale(1.2); opacity: 1; } 100% { transform: perspective(600px) translateZ(0) scale(1); opacity: 1; } }
@keyframes giantSlide { 0% { transform: translateX(-200%) scale(3); opacity: 0; } 100% { transform: translateX(0) scale(1); opacity: 1; } }
@keyframes staircase { 0% { transform: translateY(50px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }
@keyframes shadowFirst { 0% { text-shadow: 0 50px 20px var(--ta-shadow); opacity: 0; color: transparent; } 50% { text-shadow: 0 0 5px var(--ta-shadow); opacity: 1; color: transparent; } 100% { text-shadow: 0 0 0 transparent; color: currentColor; opacity: 1; } }
@keyframes cubeFlipX { 0% { transform: perspective(400px) rotateX(-90deg) translateZ(50px); opacity: 0; } 100% { transform: perspective(400px) rotateX(0deg) translateZ(0); opacity: 1; } }
@keyframes cubeFlipY { 0% { transform: perspective(400px) rotateY(-90deg) translateZ(50px); opacity: 0; } 100% { transform: perspective(400px) rotateY(0deg) translateZ(0); opacity: 1; } }
@keyframes speedDash { 0% { transform: translateX(-200%) skewX(-45deg); opacity: 0; } 70% { transform: translateX(10%) skewX(-10deg); opacity: 1; } 100% { transform: translateX(0) skewX(0deg); opacity: 1; } }
@keyframes heartbeatBurst { 0% { transform: scale(0.5); opacity: 0; } 30% { transform: scale(1.2); opacity: 1; } 50% { transform: scale(0.9); opacity: 1; } 70% { transform: scale(1.1); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes movieCredits { 0% { transform: translateY(50px); opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } 100% { transform: translateY(-50px); opacity: 0; } }
@keyframes springyText { 0% { transform: scaleY(0); transform-origin: bottom; opacity: 0; } 50% { transform: scaleY(1.5); opacity: 1; } 75% { transform: scaleY(0.8); } 100% { transform: scaleY(1); opacity: 1; } }
@keyframes flipBounce { 0% { transform: perspective(400px) rotateX(90deg); opacity: 0; } 50% { transform: perspective(400px) rotateX(-20deg); opacity: 1; } 75% { transform: perspective(400px) rotateX(10deg); opacity: 1; } 100% { transform: perspective(400px) rotateX(0deg); opacity: 1; } }
@keyframes rotate3DIn { 0% { transform: perspective(500px) rotate3d(1, 1, 1, 90deg); opacity: 0; } 100% { transform: perspective(500px) rotate3d(0, 0, 0, 0deg); opacity: 1; } }
@keyframes squeezeExpand { 0% { letter-spacing: -0.5em; opacity: 0; transform: scaleY(0.1); } 50% { letter-spacing: 0.2em; transform: scaleY(1.2); opacity: 1; } 100% { letter-spacing: normal; transform: scaleY(1); opacity: 1; } }
@keyframes zipIn { 0% { transform: scale(0); opacity: 0; } 80% { transform: scale(1.1) rotate(10deg); opacity: 1; } 100% { transform: scale(1) rotate(0deg); opacity: 1; } }
@keyframes blurDrop { 0% { transform: translateY(-50px); filter: blur(10px); opacity: 0; } 100% { transform: translateY(0); filter: blur(0); opacity: 1; } }
@keyframes blurRise { 0% { transform: translateY(50px); filter: blur(10px); opacity: 0; } 100% { transform: translateY(0); filter: blur(0); opacity: 1; } }
@keyframes swingIn { 0% { transform: rotateX(-100deg); transform-origin: top; opacity: 0; } 100% { transform: rotateX(0deg); transform-origin: top; opacity: 1; } }
@keyframes swingOut { 0% { transform: rotateX(0deg); transform-origin: top; opacity: 1; } 100% { transform: rotateX(-100deg); transform-origin: top; opacity: 0; } }
@keyframes pendulum { 0% { transform: rotate(10deg); transform-origin: top; opacity: 0; } 50% { transform: rotate(-5deg); transform-origin: top; opacity: 1; } 100% { transform: rotate(0deg); transform-origin: top; opacity: 1; } }
@keyframes pulseNeon { 0%, 100% { text-shadow: 0 0 5px var(--ta-glow), 0 0 10px var(--ta-glow), 0 0 20px var(--ta-neon); opacity: 1; } 50% { text-shadow: 0 0 2px var(--ta-glow), 0 0 5px var(--ta-glow), 0 0 10px var(--ta-neon); opacity: 0.5; } }
@keyframes flipInX { 0% { transform: perspective(400px) rotateX(90deg); opacity: 0; } 100% { transform: perspective(400px) rotateX(0deg); opacity: 1; } }
@keyframes flipInY { 0% { transform: perspective(400px) rotateY(90deg); opacity: 0; } 100% { transform: perspective(400px) rotateY(0deg); opacity: 1; } }
@keyframes boomerang { 0% { transform: perspective(600px) translateZ(-500px) rotate(45deg); opacity: 0; } 50% { transform: perspective(600px) translateZ(100px) rotate(-10deg); opacity: 1; } 100% { transform: perspective(600px) translateZ(0) rotate(0deg); opacity: 1; } }
@keyframes spaceIn { 0% { transform: perspective(600px) scale(0.2) translateZ(-1000px); opacity: 0; } 100% { transform: perspective(600px) scale(1) translateZ(0); opacity: 1; } }
@keyframes perspectiveIn { 0% { transform: perspective(800px) translateZ(300px); opacity: 0; } 100% { transform: perspective(800px) translateZ(0); opacity: 1; } }
@keyframes trackingInExpandFwd { 0% { letter-spacing: -0.5em; transform: perspective(700px) translateZ(-700px); opacity: 0; } 100% { letter-spacing: normal; transform: perspective(700px) translateZ(0); opacity: 1; } }
@keyframes trackingOutContractBck { 0% { letter-spacing: normal; transform: perspective(500px) translateZ(0); opacity: 1; } 100% { letter-spacing: -0.5em; transform: perspective(500px) translateZ(-500px); opacity: 0; } }
@keyframes textShadowPop { 0% { text-shadow: 0 0 var(--ta-shadow), 0 0 var(--ta-shadow); transform: translate(0, 0); opacity: 0; } 100% { text-shadow: 1px 1px var(--ta-shadow), 2px 2px var(--ta-shadow), 3px 3px var(--ta-shadow), 4px 4px var(--ta-shadow); transform: translate(-4px, -4px); opacity: 1; } }
@keyframes flickerIn { 0% { opacity: 0; } 10% { opacity: 1; } 20% { opacity: 0; } 30% { opacity: 1; } 40% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 1; } }

/* JS-effect keyframes */
@keyframes taBlinkCursor { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
@keyframes taSpotlightSweep { 0% { background-position: 200% center; } 100% { background-position: -200% center; } }
