/* EtchPress Motion 1.9.0
   The keyframes and registered properties the motion items animate with. Install once as a global stylesheet
   (Etch: Styles, Stylesheets, New, paste). Every motion item stays visible in its finished state without it. */

/* easing tokens: ACSS 4's presets when the site has them (Effects > Easing in the dashboard tunes every item), strong house
   curves otherwise; the built-ins are too weak to feel intentional (motion-craft) */
:root { --ep-ease-out: var(--ease-snappy, cubic-bezier(0.23, 1, 0.32, 1)); --ep-ease-in-out: var(--ease-gentle, cubic-bezier(0.77, 0, 0.175, 1)); --ep-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); }

/* springs, sampled into linear() the way Motion feeds the Web Animations API (one point every 10 ms). A spring is a curve
   plus a settle time, so each has its duration token: use them together, transition: translate var(--ep-spring-time) var(--ep-spring).
   --ep-spring: stiffness 300, damping 35, critically damped, no overshoot: hover lifts, press releases, anything that lands.
   --ep-spring-snap: stiffness 520, damping 32 (ratio .70), a 4% overshoot: the small alive move, an arrow sliding in, a card rising. */
:root { --ep-spring-time: 390ms; --ep-spring: linear(0, 0.014, 0.049, 0.098, 0.156, 0.219, 0.283, 0.347, 0.409, 0.468, 0.523, 0.574, 0.621, 0.664, 0.703, 0.738, 0.77, 0.798, 0.823, 0.845, 0.865, 0.882, 0.897, 0.911, 0.922, 0.933, 0.942, 0.95, 0.956, 0.962, 0.967, 0.972, 0.976, 0.979, 0.982, 0.985, 0.987, 0.989, 0.99, 1); --ep-spring-snap-time: 430ms; --ep-spring-snap: linear(0, 0.024, 0.084, 0.169, 0.268, 0.372, 0.475, 0.574, 0.665, 0.745, 0.815, 0.874, 0.922, 0.961, 0.99, 1.012, 1.028, 1.038, 1.043, 1.045, 1.045, 1.042, 1.039, 1.034, 1.03, 1.025, 1.02, 1.016, 1.012, 1.009, 1.006, 1.004, 1.002, 1.001, 1, 0.999, 0.998, 0.998, 0.998, 0.998, 0.998, 0.998, 0.998, 1); }

/* registered properties, so they animate and interpolate */
@property --ep-n { syntax: "<integer>"; inherits: false; initial-value: 0; }
@property --ep-mx { syntax: "<percentage>"; inherits: false; initial-value: 50%; }
@property --ep-my { syntax: "<percentage>"; inherits: false; initial-value: 50%; }
@property --ep-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --ep-p { syntax: "<number>"; inherits: true; initial-value: 1; }  /* scroll progress, 0 to 1; 1 where nothing drives it, so the finished state shows */

/* entrances: each starts from a hidden state and ends at the element's own styles */
@keyframes ep-rise { from { opacity: 0; translate: 0 1.25rem; } }
@keyframes ep-fade { from { opacity: 0; } }
@keyframes ep-blur { from { opacity: 0; filter: blur(12px); } }
@keyframes ep-scale { from { opacity: 0; scale: .94; } }
@keyframes ep-wipe-up { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes ep-wipe-down { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes ep-wipe-left { from { clip-path: inset(0 0 0 100%); } to { clip-path: inset(0 0 0 0); } }
@keyframes ep-wipe-right { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes ep-zoom-out { from { scale: 1.15; } to { scale: 1; } }

/* a bar crosses the element: covers left to right (45% of the time), then uncovers; what sits under it shows once covered */
@keyframes ep-sweep { from { translate: -101% 0; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } 45% { translate: 0 0; animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } to { translate: 101% 0; } }
@keyframes ep-appear-mid { 0%, 45% { opacity: 0; } 46%, 100% { opacity: 1; } }
@keyframes ep-wipe-right-late { 0%, 45% { clip-path: inset(0 100% 0 0); } 100% { clip-path: inset(0 0 0 0); } }
@keyframes ep-circle { from { clip-path: circle(0% at 50% 50%); } to { clip-path: circle(75% at 50% 50%); } }
@keyframes ep-block { from { background-size: 100% .14em; } to { background-size: 100% 100%; } }

/* fills and sweeps: a background that grows across the element */
@keyframes ep-fill { from { background-size: 0% 100%; } to { background-size: 100% 100%; } }

/* continuous */
@keyframes ep-shine { from { translate: -160% 0; } to { translate: 260% 0; } }
@keyframes ep-drift-a { from { translate: -24% -16%; scale: .9; opacity: .8; } to { translate: 28% 18%; scale: 1.4; opacity: 1; } }
@keyframes ep-drift-b { from { translate: 22% 18%; scale: 1.3; opacity: 1; } to { translate: -26% -18%; scale: .8; opacity: .75; } }
/* the dusk palette's wave (Aurora band 1.1.0, drawn by our designer): two glows rise and swell a little, 15 and 14 seconds, alternating */
@keyframes ep-dusk-a { from { translate: 0 0; scale: 1; } to { translate: 6% -3%; scale: 1.05; } }
@keyframes ep-dusk-b { from { translate: 0 0; scale: 1; } to { translate: -6% -4%; scale: 1.05; } }
/* the hero glow's three orbs (Alejandra's fondo cyan-verde and fondo claro, October 5, 2026): 4, 3 and 4.5 seconds, alternating */
@keyframes ep-mix-left { from { translate: 0 0; scale: 1; } to { translate: 10% -5%; scale: 1.1; } }
@keyframes ep-mix-center { from { translate: -10% 5%; scale: .9; } to { translate: 10% -2%; scale: 1.2; } }
@keyframes ep-mix-right { from { translate: 0 0; scale: 1; } to { translate: -10% -5%; scale: 1.1; } }
@keyframes ep-spin { to { --ep-angle: 360deg; } }
@keyframes ep-marquee { to { translate: -50% 0; } }

/* scroll-driven states */
@keyframes ep-progress { from { --ep-p: 0; } to { --ep-p: 1; } }
@keyframes ep-count { from { --ep-n: 0; } to { --ep-n: var(--ep-to, 100); } }
@keyframes ep-stack { to { scale: var(--ep-stack-scale, .92); } }
@keyframes ep-dim { to { opacity: var(--ep-dim, .35); } }
@keyframes ep-underline { from { background-size: 0% .14em; } to { background-size: 100% .14em; } }
@keyframes ep-fill-down { from { background-size: 100% 0%; } to { background-size: 100% 100%; } }
@keyframes ep-focus { 0% { opacity: var(--ep-dim, .3); } 35%, 65% { opacity: 1; } 100% { opacity: var(--ep-dim, .3); } }

/* Alejandra's glow buttons (1.5.0, September 28, 2026): a breathing ring, a diagonal shine crossing, a sign's flicker, a flowing gradient;
   each reads the button's --gb-accent (its light) with --primary as the fallback */
@keyframes ep-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklch, var(--gb-accent, var(--primary)) 45%, transparent), 0 8px 24px -6px color-mix(in oklch, var(--gb-accent, var(--primary)) 35%, transparent); } 50% { box-shadow: 0 0 0 12px color-mix(in oklch, var(--gb-accent, var(--primary)) 0%, transparent), 0 8px 32px -4px color-mix(in oklch, var(--gb-accent, var(--primary)) 60%, transparent); } }
@keyframes ep-sweep-x { from { translate: 0 0; } to { translate: 350% 0; } }
@keyframes ep-flicker { 0%, 89%, 91%, 94%, 100% { box-shadow: 0 0 6px color-mix(in oklch, var(--gb-accent, var(--primary)) 60%, transparent), 0 0 18px color-mix(in oklch, var(--gb-accent, var(--primary)) 35%, transparent), inset 0 0 8px color-mix(in oklch, var(--gb-accent, var(--primary)) 25%, transparent); opacity: 1; } 90% { box-shadow: 0 0 2px color-mix(in oklch, var(--gb-accent, var(--primary)) 30%, transparent); opacity: .65; } 93% { box-shadow: 0 0 3px color-mix(in oklch, var(--gb-accent, var(--primary)) 40%, transparent); opacity: .75; } }
@keyframes ep-flow { to { background-position: -200% 0; } }

/* text effects (1.6.0, September 30, 2026): a line rising from behind its own mask (Line reveal), and a band of light crossing text
   (Shimmer text; the band crosses as the background position runs from 100% to 0) */
@keyframes ep-line-up { from { translate: 0 110%; } }
@keyframes ep-shimmer { from { background-position: 100% 0; } to { background-position: 0% 0; } }

/* 1.9.0 (October 7, 2026): parallax waves and rising dust, for Neon tide */
@keyframes ep-sea-wave { 0%, 100% { transform: translate3d(-10%, 10%, 0) scale(1) rotate(-5deg); } 50% { transform: translate3d(10%, -15%, 0) scale(1.1) rotate(5deg); } }
@keyframes ep-sea-up { 0% { transform: translateY(0); opacity: 0; } 15%, 85% { opacity: calc(var(--o, .5) * var(--ep-sea-ok, 1)); } 100% { transform: translateY(-120vh); opacity: 0; } }
@keyframes ep-sea-swing { from { transform: translateX(calc(var(--sw, 30px) * -1)); } to { transform: translateX(var(--sw, 30px)); } }
