/* 1. TOKENS — reutiliza colores, radios, espaciado y sombras existentes. */
:root {
  --motion-fast: 300ms;
  --motion-base: 600ms;
  --motion-slow: 700ms;
  --motion-marquee: 36s;
  --motion-line-gap: 120ms;
  --motion-stagger: 100ms;
  --motion-route-gap: 80ms;
  --motion-zero: 0ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --motion-hero-y: 12px;
  --motion-reveal-y: 14px;
  --motion-photo-x: 12px;
  --motion-lift: -2px;
  --motion-city-x: 8px;
  --motion-photo-scale: 1.05;
  --motion-hover-scale: 1.04;
  --motion-pop-scale: 1.2;
  --motion-ring: 0 0 0 3px color-mix(in srgb, var(--color-primary) 20%, transparent);
  --motion-header-z: 6;
  --motion-progress-z: 7;
  --duration-shimmer: var(--motion-slow);
  --btn-motion: var(--motion-fast);
}
@media (min-width: 48rem) {
  :root { --motion-hero-y: 20px; --motion-reveal-y: 24px; --motion-photo-x: 20px; }
}

/* 2. HERO — neutraliza las entradas anteriores; sin JS todo queda visible. */
.hero h1, .hero .intro, .hero-actions, .hero-note, h1 em::after,
.route-strip i, .floating-wa::before { animation: none; }
.hero-line { display: inline-block; }
.js.motion-ready [data-hero-motion] {
  animation: hero-rise var(--motion-base) var(--ease-out) both;
  animation-delay: var(--entry-delay, var(--motion-zero));
}
.js.motion-ready .hero-photo[data-hero-motion] { animation-name: hero-photo-in; }
.js.motion-ready .hero-photo .hero-zoom {
  animation: hero-zoom var(--motion-slow) var(--ease-out) both;
  animation-delay: var(--entry-delay, var(--motion-zero));
}
.js.motion-ready h1 em::after {
  animation: underline-in var(--motion-base) var(--ease-out) both;
  animation-delay: var(--motion-line-gap);
}
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(var(--motion-hero-y)); }
  to { opacity: 1; transform: none; }
}
@keyframes hero-photo-in {
  from { opacity: 0; transform: translateX(var(--motion-photo-x)); }
  to { opacity: 1; transform: none; }
}
@keyframes hero-zoom {
  from { transform: scale(var(--motion-photo-scale)); }
  to { transform: scale(1); }
}
@keyframes underline-in { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* 3. MARQUESINA — dos grupos idénticos; copia fuera del árbol accesible. */
.route-strip.has-marquee { display: block; position: relative; padding-inline: var(--space-0); overflow: hidden; }
.marquee-track { display: flex; width: max-content; min-width: 200%; }
.marquee-group {
  display: flex; flex: 1 0 auto; align-items: center; justify-content: space-around;
  gap: var(--space-9); padding-inline: var(--space-9);
}
.marquee-group > span:first-child { font-size: var(--text-xs); letter-spacing: var(--tracking-small); }
.js.motion-ready .marquee-track { animation: marquee-run var(--motion-marquee) linear infinite; }
.route-strip:is(:hover, :focus-within, .is-paused) .marquee-track { animation-play-state: paused; }
.marquee-toggle {
  position: absolute; inset-inline-end: var(--space-1); top: var(--space-1);
  border: var(--border-thin) solid currentColor; border-radius: var(--radius-sm);
  background: var(--color-primary); color: var(--color-on-primary);
  width: var(--target-min); height: var(--target-min); padding: var(--space-0);
}
.marquee-toggle:focus-visible { outline-color: var(--color-focus-inverse); }
@keyframes marquee-run { to { transform: translateX(-50%); } }
/* También se usa al detectar un error de inicialización o cambiar la preferencia. */
html:not(.motion-ready) .marquee-track { width: auto; min-width: 0; }
html:not(.motion-ready) .marquee-group { flex-wrap: wrap; justify-content: center; }
html:not(.motion-ready) .marquee-group[aria-hidden],
html:not(.motion-ready) .marquee-toggle { display: none; }

/* 4. REVEAL — solo se oculta después de inicializar correctamente JS. */
.js.motion-ready .reveal:not(.is-visible) { opacity: 0; transform: translateY(var(--motion-reveal-y)); transition: none; }
.js.motion-ready .reveal.is-visible {
  transition: opacity var(--motion-base) var(--ease-out), transform var(--motion-base) var(--ease-out);
  transition-delay: var(--reveal-delay, var(--motion-zero));
}
.is-animating { will-change: transform, opacity; }
.js.motion-ready .reveal.motion-instant { opacity: 1; transform: none; transition: none; }

/* 5. RUTAS — los símbolos siguen siendo decorativos; nombres intactos. */
.route-mark.motion-route-mark { display: inline-flex; flex-direction: column; align-items: center; }
.route-line { display: block; transform-origin: top; }
.route-destination { display: block; }
.js.motion-ready .route:not(.is-visible) :is(.route-line, .route-destination) { transform: scaleY(0); }
.js.motion-ready .route.route-entering .route-line {
  animation: route-draw var(--motion-base) var(--ease-out) backwards;
  animation-delay: var(--reveal-delay, var(--motion-zero));
}
.js.motion-ready .route.route-entering .route-destination {
  animation: small-pop var(--motion-fast) var(--ease-out) backwards;
  animation-delay: calc(var(--reveal-delay, var(--motion-zero)) + var(--motion-fast));
}
@keyframes route-draw { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes small-pop { 0% { transform: scale(0); } 70% { transform: scale(var(--motion-pop-scale)); } 100% { transform: scale(1); } }

/* 6. PASOS — relleno por opacidad, sin transiciones de background-color. */
.step { position: relative; isolation: isolate; }
.step::before {
  content: ''; position: absolute; inset: var(--space-0); z-index: -1;
  border-radius: inherit; background: var(--color-primary); opacity: 0;
  transition: opacity var(--motion-base) var(--ease-out);
}
.process-grid > .is-visible .step { color: var(--color-on-primary); }
.process-grid > .is-visible .step::before { opacity: 1; }
.js.motion-ready .step-entering .step {
  animation: small-pop var(--motion-base) var(--ease-out) backwards;
  animation-delay: var(--reveal-delay, var(--motion-zero));
}

/* 7. MICROINTERACCIONES — sombras/anillos con opacity, nunca box-shadow animado. */
.button, .floating-wa { position: relative; transition: transform var(--motion-fast) var(--ease-out); }
.floating-wa { position: fixed; }
.button::before, .floating-wa::before {
  content: ''; position: absolute; inset: var(--space-0); border: 0;
  border-radius: inherit; box-shadow: var(--shadow-card); opacity: 0;
  pointer-events: none; transition: opacity var(--motion-fast) var(--ease-out);
}
.button:is(:hover, :focus-visible), .floating-wa:is(:hover, :focus-visible) { transform: translateY(var(--motion-lift)); }
.button:is(:hover, :focus-visible)::before, .floating-wa:is(:hover, :focus-visible)::before { opacity: 1; }
.button [data-arrow] { display: inline-block; transition: transform var(--motion-fast) var(--ease-out); }
.button:is(:hover, :focus-visible) [data-arrow] { transform: translateX(var(--space-1)); }
.city-row { position: relative; }
.city-row::after {
  content: ''; position: absolute; inset-inline: var(--space-0); bottom: calc(-1 * var(--border-thin));
  height: var(--border-thin); background: var(--color-primary); opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-out);
}
.city-row > span { transition: transform var(--motion-fast) var(--ease-out); }
.city-row:is(:hover, :focus-within)::after { opacity: 1; }
.city-row:is(:hover, :focus-within) > span { transform: translateX(var(--motion-city-x)); }
.photo-button { overflow: hidden; }
.photo-button img, .photo-expand { transition: transform var(--motion-base) var(--ease-out); }
.photo-button:focus-visible .photo-expand { transform: translateY(var(--motion-lift)); }
@media (hover: hover) {
  .photo-button:hover img { transform: scale(var(--motion-hover-scale)); }
  .photo-button:hover .photo-expand { transform: translateY(var(--motion-lift)); }
}
.field-shell { display: block; position: relative; margin-top: var(--space-2); }
.field-shell :is(input, textarea) { margin-top: var(--space-0); }
.field-shell::after {
  content: ''; position: absolute; inset: var(--space-0); pointer-events: none;
  border-radius: var(--radius-sm); box-shadow: var(--motion-ring); opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-out);
}
.field-shell:focus-within::after { opacity: 1; }
.field-shell :is(input, textarea):focus { border-color: var(--color-primary); }
/* Se conserva el outline global accesible y el borde de error. */
.field-shell :is(input, textarea)[aria-invalid="true"] { border-color: var(--color-error); }

/* 8. HEADER Y PROGRESO — altura reservada; padding cambia sin animarse. */
.header-shell { position: sticky; top: 0; z-index: var(--motion-header-z); height: var(--header-reserved); pointer-events: none; }
.header-shell .header { position: relative; background: var(--color-bg); pointer-events: auto; }
.header-shell .header::after {
  content: ''; position: absolute; inset: var(--space-0); pointer-events: none;
  box-shadow: var(--shadow-soft); opacity: 0; transition: opacity var(--motion-fast) var(--ease-out);
}
.header-shell .header.is-scrolled { padding-block: var(--space-3); }
.header-shell .header.is-scrolled::after { opacity: 1; }
.scroll-progress {
  position: fixed; inset-inline: var(--space-0); top: 0; z-index: var(--motion-progress-z);
  height: var(--outline-width); background: var(--color-primary);
  transform: scaleX(0); transform-origin: left; pointer-events: none;
}
.js { scroll-padding-top: calc(var(--header-reserved, var(--space-12)) + var(--space-5)); }

/* 9. MOVIMIENTO REDUCIDO — aplica también si cambia durante la sesión. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal, [data-hero-motion], .hero-zoom { opacity: 1 !important; transform: none !important; }
  .button:is(:hover, :focus-visible), .floating-wa:is(:hover, :focus-visible),
  .city-row:is(:hover, :focus-within) > span, .photo-button:hover img,
  .photo-button:is(:hover, :focus-visible) .photo-expand { transform: none; }
  .marquee-track { transform: none; width: auto; min-width: 0; }
  .marquee-group { flex-wrap: wrap; justify-content: center; }
  .marquee-group[aria-hidden], .marquee-toggle, .scroll-progress { display: none; }
  .is-animating { will-change: auto; }
}
