/* ============================================================
   Ride X — motion layer (shared, all pages)
   Premium choreography layered on top of the base primitives.
   Every rule is gated behind html.rx-motion (JS present + no
   reduced-motion preference), an arm class added by motion.js,
   or a native reduced-motion media query — so the default
   document stays complete, static, and readable.
   Load order: tokens → base → page css → motion.css.
   This file may re-tune base *motion* values, never content.
   ============================================================ */

:root {
  /* entrance curve with a gentle overshoot — settles exactly at 1 */
  --ease-spring: linear(
    0, 0.012 1.1%, 0.048 2.3%, 0.104 3.6%, 0.29 6.6%, 0.584 11%,
    0.789 14.4%, 0.867 16.1%, 0.931 17.9%, 0.979 19.7%, 1.013 21.6%,
    1.034 23.6%, 1.044 25.8%, 1.043 28.4%, 1.021 35.4%, 1.002 42.2%,
    0.995 48.8%, 0.996 60.4%, 1 79.9%, 1
  );
}

/* ============================================================
   1. Cross-document view transitions (MPA page-to-page fade)
   Native, no JS. The topbar and WhatsApp bar persist while the
   page body crossfades with a small vertical drift.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }

  .topbar { view-transition-name: rx-topbar; }
  .wabar  { view-transition-name: rx-wabar; }

  ::view-transition-old(root) { animation: rx-vt-leave 0.24s var(--ease-inout) both; }
  ::view-transition-new(root) { animation: rx-vt-enter 0.5s 0.04s var(--ease-out) both; }
}
@keyframes rx-vt-leave { to { opacity: 0; translate: 0 -0.75rem; } }
@keyframes rx-vt-enter { from { opacity: 0; translate: 0 1rem; } }

/* ============================================================
   2. Topbar — hide on scroll down, return on scroll up,
   plus a hairline route-progress indicator along its base.
   ============================================================ */
html.rx-motion .topbar {
  transition:
    background-color 0.35s ease,
    border-color 0.35s ease,
    transform 0.55s var(--ease-out);
}
html.rx-motion .topbar.topbar--hidden { transform: translateY(-102%); }
/* never hide while the menu is open or anything inside has focus */
html.menu-open .topbar,
.topbar:focus-within { transform: none !important; }

.topbar__progress {
  position: absolute;
  inset-block-end: -1px;
  inset-inline: 0;
  block-size: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}
[dir="rtl"] .topbar__progress { transform-origin: 100% 50%; }

/* ============================================================
   3. Mobile menu — shutter reveal + staggered links,
   burger ⇄ close morph. Keyed entirely off the classes
   main.js already toggles; zero JS changes required.
   ============================================================ */
html.rx-motion .mobilemenu {
  display: flex;
  visibility: hidden;
  clip-path: inset(0 0 100% 0);
  transition:
    clip-path 0.55s var(--ease-inout),
    visibility 0s 0.55s;
}
html.rx-motion .mobilemenu.is-open {
  visibility: visible;
  clip-path: inset(0 0 0% 0);
  transition:
    clip-path 0.6s var(--ease-inout),
    visibility 0s 0s;
}
html.rx-motion .mobilemenu__links a {
  opacity: 0;
  translate: 0 1.25rem;
  transition: opacity 0.4s var(--ease-out), translate 0.4s var(--ease-out);
}
html.rx-motion .mobilemenu.is-open .mobilemenu__links a {
  opacity: 1;
  translate: 0 0;
  transition-duration: 0.6s, 0.6s;
  transition-delay: calc(0.14s + var(--mi, 0) * 0.055s);
}
.mobilemenu__links a:nth-child(1) { --mi: 0; }
.mobilemenu__links a:nth-child(2) { --mi: 1; }
.mobilemenu__links a:nth-child(3) { --mi: 2; }
.mobilemenu__links a:nth-child(4) { --mi: 3; }
.mobilemenu__links a:nth-child(5) { --mi: 4; }
.mobilemenu__links a:nth-child(6) { --mi: 5; }
.mobilemenu__links a:nth-child(7) { --mi: 6; }
html.rx-motion .mobilemenu__foot {
  opacity: 0;
  translate: 0 1rem;
  transition: opacity 0.45s var(--ease-out), translate 0.45s var(--ease-out);
}
html.rx-motion .mobilemenu.is-open .mobilemenu__foot {
  opacity: 1;
  translate: 0 0;
  transition-delay: 0.5s;
}

/* burger morph: crossfade + quarter-turn between the two glyphs */
html.rx-motion .menubtn { position: relative; }
html.rx-motion .menubtn svg {
  transition: opacity 0.28s ease, transform 0.45s var(--ease-out);
}
html.rx-motion .menubtn .icon-close {
  display: block;
  position: absolute;
  inset: 0;
  margin: auto;
  opacity: 0;
  transform: rotate(-90deg) scale(0.6);
}
html.rx-motion .menubtn[aria-expanded="true"] .icon-close {
  opacity: 1;
  transform: rotate(0deg) scale(1);
}
html.rx-motion .menubtn .icon-open { display: block; }
html.rx-motion .menubtn[aria-expanded="true"] .icon-open {
  opacity: 0;
  transform: rotate(90deg) scale(0.6);
}

/* ============================================================
   4. Masked line reveals (built by motion.js)
   Headlines split into measured lines; each line rises out of
   its own clipped wrapper. The wrapper padding keeps Arabic
   and Latin descenders un-clipped; motion.js unwraps back to
   plain text after the reveal completes.
   ============================================================ */
html.rx-motion .rx-ln {
  display: block;
  overflow: clip;
  padding-block: 0.12em 0.3em;
  margin-block: -0.12em -0.3em;
}
html.rx-motion .rx-ln__in {
  display: block;
  translate: 0 calc(100% + 0.34em);
  transition: translate 0.95s var(--ease-out);
  transition-delay: calc(var(--ln-base, 0s) + var(--ln-i, 0) * 0.09s);
  will-change: translate;
}
html.rx-motion .is-lined .rx-ln__in { translate: 0 0; }

/* ============================================================
   5. Scroll-scrubbed word emphasis (built by motion.js)
   Words brighten in reading order as the passage scrolls
   through the viewport. --pw is smoothed by motion.js.
   ============================================================ */
html.rx-motion [data-wordscrub].ws-armed .ws-w {
  opacity: calc(0.14 + 0.86 * clamp(0, var(--pw, 1) * (var(--wn, 1) + 2) - var(--wi, 0), 1));
}

/* ============================================================
   6. Inner-page hero entrance (pure CSS, runs on load)
   ============================================================ */
html.rx-motion .pagehero .crumbs { animation: rx-fade 0.6s var(--ease-out) 0.08s both; }
html.rx-motion .pagehero .eyebrow { animation: rx-fade 0.6s var(--ease-out) 0.2s both; }
html.rx-motion .pagehero .eyebrow::before {
  animation: rx-rule 0.7s var(--ease-inout) 0.28s both;
  transform-origin: 0 50%;
}
html[dir="rtl"].rx-motion .pagehero .eyebrow::before { transform-origin: 100% 50%; }
html.rx-motion .pagehero .lead { animation: rx-rise 0.7s var(--ease-out) 0.52s both; }
@keyframes rx-fade { from { opacity: 0; } }
@keyframes rx-rise { from { opacity: 0; translate: 0 1rem; } }
@keyframes rx-rule { from { transform: scaleX(0); } }

/* ============================================================
   7. Section micro-choreography (site-wide)
   ============================================================ */

/* the eyebrow's red rule draws in as its section reveals
   (both when the eyebrow sits inside a revealed block and when
   it carries data-reveal itself via group staggering) */
html.rx-motion [data-reveal] .eyebrow::before,
html.rx-motion .eyebrow[data-reveal]::before {
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.8s var(--ease-inout) calc(var(--reveal-delay, 0s) + 0.15s);
}
html[dir="rtl"].rx-motion [data-reveal] .eyebrow::before,
html[dir="rtl"].rx-motion .eyebrow[data-reveal]::before { transform-origin: 100% 50%; }
html.rx-motion [data-reveal].in-view .eyebrow::before,
html.rx-motion .eyebrow[data-reveal].in-view::before { transform: scaleX(1); }

/* photography settles from a slight zoom as it reveals */
html.rx-motion [data-reveal] .media-grade:not(.fleetsel__media) img,
html.rx-motion .media-grade[data-reveal]:not(.fleetsel__media) img {
  scale: 1.07;
  transition: scale 1.4s var(--ease-out) 0.05s;
}
html.rx-motion [data-reveal].in-view .media-grade:not(.fleetsel__media) img,
html.rx-motion .media-grade[data-reveal].in-view:not(.fleetsel__media) img {
  scale: 1;
}

/* ============================================================
   8. Chrome micro-interactions
   ============================================================ */

/* topbar links: underline draws from the reading edge on hover */
html.rx-motion .topbar__links a:not([aria-current])::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.35s var(--ease-out);
}
html[dir="rtl"].rx-motion .topbar__links a:not([aria-current])::after {
  transform-origin: 100% 50%;
}
html.rx-motion .topbar__links a:not([aria-current]):hover::after,
html.rx-motion .topbar__links a:not([aria-current]):focus-visible::after {
  transform: scaleX(1);
}

/* the brand dot gives a small hop on hover */
.brandmark .dot { display: inline-block; }
html.rx-motion .brandmark:hover .dot { animation: rx-dot-hop 0.5s var(--ease-out); }
@keyframes rx-dot-hop { 30% { translate: 0 -0.2em; } }

/* footer link nudge toward the reading direction */
html.rx-motion .site-footer .footer-col a {
  display: inline-block;
  transition: translate 0.3s var(--ease-out), color 0.2s ease;
}
html.rx-motion .site-footer .footer-col a:hover { translate: 3px 0; }
html[dir="rtl"].rx-motion .site-footer .footer-col a:hover { translate: -3px 0; }

/* buttons: crisper press + icon life (magnetic drift comes from JS) */
html.rx-motion .btn { transition-property: background-color, border-color, color, translate, scale; }
html.rx-motion .btn:active { scale: 0.985; }
html.rx-motion .btn .btn__icon { transition: transform 0.35s var(--ease-spring); }
html.rx-motion .btn:hover .btn__icon { transform: scale(1.12) rotate(-4deg); }

/* carousel controls: tactile press */
html.rx-motion .carousel__btn svg { transition: transform 0.3s var(--ease-out); }
html.rx-motion .carousel__btn:active svg { transform: scale(0.82); }

/* WhatsApp bar: spring entrance instead of a plain ease */
html.rx-motion .wabar { transition: translate 0.75s var(--ease-spring); }

/* langswitch: subtle lift, matching buttons */
html.rx-motion .langswitch { transition: border-color 0.25s ease, background-color 0.25s ease, translate 0.25s var(--ease-out); }
html.rx-motion .langswitch:hover { translate: 0 -1px; }

/* ============================================================
   9. Fleet-style tab strip: sliding red pill (armed by motion.js)
   Falls back to the base red-tab styling when JS is absent.
   ============================================================ */
[data-tabs][data-ind] .tabs__list { position: relative; }
[data-tabs][data-ind] .tabs__tab { position: relative; z-index: 1; background: transparent; }
[data-tabs][data-ind] .tabs__tab[aria-selected="true"] {
  background: transparent;
  border-color: transparent;
  color: #fff;
}
.tabs__ind {
  position: absolute;
  z-index: 0;
  border-radius: 999px;
  background: var(--red);
  transition:
    transform 0.5s var(--ease-spring),
    width 0.5s var(--ease-spring),
    height 0.5s var(--ease-spring);
  pointer-events: none;
}
.tabs__ind.no-anim { transition: none; }

/* ============================================================
   11. Footer sign-off wordmark — the letters hop in a wave when
   the footer scrolls in (motion.js adds .is-in, then removes it so
   hover can retrigger) and again on hover. The red dot gets an
   extra springy double-bounce. rx-motion is set in the head even
   without main/motion.js, so the hover wave works with no JS too;
   only the scroll-in wave needs motion.js.
   ============================================================ */
.footer-sign > :nth-child(1) { --i: 0; }
.footer-sign > :nth-child(2) { --i: 1; }
.footer-sign > :nth-child(3) { --i: 2; }
.footer-sign > :nth-child(4) { --i: 3; }
.footer-sign > :nth-child(6) { --i: 4; }
.footer-sign > :nth-child(7) { --i: 5; }

@keyframes fsign-hop {
  0% { transform: translateY(0); }
  45% { transform: translateY(-0.32em); }
  100% { transform: translateY(0); }
}
@keyframes fsign-hop-dot {
  0% { transform: translateY(0) scale(1); }
  40% { transform: translateY(-0.46em) scale(1.14); }
  72% { transform: translateY(0) scale(1); }
  86% { transform: translateY(-0.12em); }
  100% { transform: translateY(0); }
}

html.rx-motion .footer-sign__l,
html.rx-motion .footer-sign__dot { will-change: transform; }
html.rx-motion .footer-sign.is-in .footer-sign__l,
html.rx-motion .footer-sign:hover:not(.is-in) .footer-sign__l {
  animation: fsign-hop 0.55s var(--ease-out) calc(var(--i, 0) * 0.045s);
}
html.rx-motion .footer-sign.is-in .footer-sign__dot,
html.rx-motion .footer-sign:hover:not(.is-in) .footer-sign__dot {
  animation: fsign-hop-dot 0.7s var(--ease-out) calc(var(--i, 0) * 0.045s);
}

/* ============================================================
   10. Reduced motion — belt and braces on top of base.css:
   kill this layer's own long-running effects explicitly.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .topbar__progress { display: none; }
  .tabs__ind { transition: none; }
}
