html.lenis,
html.lenis body {
  height: auto;
}

.lenis:not(.lenis-autoToggle).lenis-stopped {
  overflow: clip;
}

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal] {
  overscroll-behavior: contain;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

.lenis.lenis-autoToggle {
  transition-property: overflow;
  transition-duration: 1ms;
  transition-behavior: allow-discrete;
}

/* R2: Lenis locks the page while the menu is open. Body stays visible, so the sticky bar keeps its place. */
html.lenis-stopped body { overflow: visible }

/* R5: reveal targets wait, hidden, until motion-core.js takes over (or the 3 s head-script timer fires). */
html.em-wait [data-reveal], html.em-wait [data-reveal-stagger] > :not(.steps-line), html.em-wait .cmp-cell { opacity: 0 }

/* R4: CSS loops rest off screen, in a hidden tab and while paused. */
:is(.em-off, html.em-hidden, html.em-paused) .em-css-loop, :is(.em-off, html.em-hidden, html.em-paused) .em-css-loop::after, .em-css-loop.em-off, .em-css-loop.em-off::after { animation-play-state: paused !important }

/* R42: the pause button keeps its space but stays hidden and unfocusable until motion runs. */
.motion-toggle { display: inline-flex; visibility: hidden }
html.em-ready .motion-toggle { visibility: visible }
@media (prefers-reduced-motion: reduce) { .motion-toggle { display: none } }
html.em-paused .i-pause, html:not(.em-paused) .i-play { display: none }

/* R19: service picture layers fade in when sections.js adds em-on. */
.svc-vis :is(video, .svc-tint, .svc-fallback) { transition: opacity 250ms var(--ease-out-quart) }
.svc-vis .em-on { opacity: 1 }

/* R7 (D55): the hero entrance runs from the stylesheet, once. em-intro-done (1.9 s after load, or the first pause) ends it. */
@media (prefers-reduced-motion: no-preference) {
  html:not(.em-paused):not(.em-intro-done) .hero h1 .w > span { animation: em-rise 0.9s var(--ease-out-quart) both; animation-delay: calc(var(--i) * 60ms) }
  html:not(.em-paused):not(.em-intro-done) .hero h1 .sweep { background-color: rgba(255,255,255,.5); animation: em-sweep 0.8s var(--ease-in-out) 1s both }
  html:not(.em-paused):not(.em-intro-done) .hero .pill { animation: em-fade-up 0.8s var(--ease-out-quart) 0.3s both }
  html:not(.em-paused):not(.em-intro-done) .hero-ctas { animation: em-fade-up 0.8s var(--ease-out-quart) 0.5s both }
}
@keyframes em-rise { from { transform: translateY(100%) } to { transform: none } }
@keyframes em-sweep { from { transform: translateX(-100%) } 99% { transform: translateX(250%); opacity: 1 } to { transform: translateX(250%); opacity: 0 } }
@keyframes em-fade-up { from { opacity: 0; transform: translateY(16px) } to { opacity: 1; transform: none } }

/* R13: the logo strip; hover or focus inside holds it. */
html.em-ready .logo-track { animation: em-marquee 40s linear infinite }
.logo-marquee:is(:hover, :focus-within) .logo-track { animation-play-state: paused }
@keyframes em-marquee { to { transform: translateX(-50%) } }

/* R18: a solid blue copy, uncovered by --fill, over grey words. */
html.em-ready .fill-base { color: var(--text-3) }
html.em-ready .fill-top { display: block; color: var(--blue); clip-path: inset(0 calc(100% - var(--fill) * 1%) 0 0); pointer-events: none; -webkit-user-select: none; user-select: none }

/* R23: a badge turns blue when the line reaches it. */
/* D69: the active step lifts and its badge and marker fill; pause makes them snap */
html.em-ready [data-steps] .n { transition: color 250ms var(--ease-out-quart), border-color 250ms var(--ease-out-quart), background-color 250ms var(--ease-out-quart) }
html.em-ready [data-steps] .card { transition: transform 250ms var(--ease-out-quart), box-shadow 250ms var(--ease-out-quart) }
html.em-ready [data-steps] > .step::after { transition: background-color 250ms var(--ease-out-quart), border-color 250ms var(--ease-out-quart) }
html.em-paused [data-steps] :is(.n, .card), html.em-paused [data-steps] > .step::after { transition: none }
/* The path waits, hidden, until its step cards have arrived (em-in), then fades in. */
html.em-ready [data-steps].em-in .steps-line { transition: opacity 250ms var(--ease-out-quart) }
html.em-ready [data-steps]:not(.em-in) .steps-line { opacity: 0 }

/* R27: the closing card's rings turn; its canvas sits behind the content. */
html.em-ready .cta-card .ring { animation: em-spin 60s linear infinite; transform-origin: 50% 50% }
html.em-ready .cta-card .ring.b { animation-duration: 80s; animation-direction: reverse }
@keyframes em-spin { to { transform: rotate(360deg) } }
.cta-card > canvas.em-particles { position: absolute; inset: 0; z-index: 0; pointer-events: none }

/* R30 (D37): on a phone the booking button waits until the hero buttons have gone. */
@media (max-width: 767px) {
  html:is(.em-wait, .em-ready) .sticky-cta { transform: translateY(calc(100% + 48px)); visibility: hidden; transition: transform 250ms var(--ease-out-quart), visibility 0s linear 250ms }
  html:is(.em-wait, .em-ready) .sticky-cta.show { transform: none; visibility: visible; transition: transform 250ms var(--ease-out-quart), visibility 0s linear 0s }
}
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  html:is(.em-wait, .em-ready) .sticky-cta { transform: none; opacity: 0; visibility: hidden; transition: opacity 200ms var(--ease-out-quart), visibility 0s linear 200ms }
  html:is(.em-wait, .em-ready) .sticky-cta.show { opacity: 1; visibility: visible; transition: opacity 200ms var(--ease-out-quart), visibility 0s linear 0s }
}
