/* ==========================================================================
   OCEAN TRADEBIZ — Motion
   Principles: subtle, purposeful, interruptible. Everything here is
   progressive: content is fully visible without JavaScript, and
   prefers-reduced-motion users get a static experience.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* ---------- Scroll reveal ----------
   main.js adds .reveal-init only to elements that start below the fold,
   then .is-visible when they enter the viewport. */
.reveal-init[data-reveal] {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
  will-change: opacity, transform;
}

.reveal-init[data-reveal="up"] {
  transform: translate3d(0, 34px, 0);
}

.reveal-init[data-reveal="left"] {
  transform: translate3d(-40px, 0, 0);
}

.reveal-init[data-reveal="right"] {
  transform: translate3d(40px, 0, 0);
}

.reveal-init[data-reveal="zoom"] {
  transform: scale(0.94);
}

/* Image reveals use a curtain that wipes off the frame rather than clipping the
   frame itself. Clipping the observed element gives it an empty intersection
   rectangle, so its own IntersectionObserver can never fire and it would stay
   hidden for good — and a clipped lazy <img> may never be fetched either. */
.reveal-init[data-reveal="image"] {
  position: relative;
  opacity: 1;
}

.reveal-init[data-reveal="image"]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: var(--color-grey-2);
  transform-origin: 50% 100%;
  transition: transform 1.2s var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
  pointer-events: none;
}

.reveal-init[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

.reveal-init[data-reveal="image"].is-visible::after {
  transform: scaleY(0);
}

/* ---------- Hero ---------- */
@keyframes ot-kenburns {
  from {
    transform: scale(1.14) translate3d(0, 0, 0);
  }
  to {
    transform: scale(1.02) translate3d(-1%, 0, 0);
  }
}

/* Hero copy rises into place without fading. An element whose first paint
   happens at opacity 0 is permanently excluded from Largest Contentful Paint,
   which would drop the page's biggest text out of the metric — so above-the-fold
   headlines animate transform only. The slide itself still cross-fades. */
@keyframes ot-rise-solid {
  from {
    transform: translate3d(0, 28px, 0);
  }
  to {
    transform: none;
  }
}

@keyframes ot-rise {
  from {
    opacity: 0;
    transform: translate3d(0, 28px, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.hero__slide.is-active .hero__media img,
.hero__slide.is-leaving .hero__media img {
  animation: ot-kenburns 9s var(--ease-out) forwards;
}

.hero__slide.is-active .hero__content > * {
  animation: ot-rise-solid 0.9s var(--ease-out) both;
}

.hero__slide.is-active .hero__content > :nth-child(1) { animation-delay: 0.3s; }
.hero__slide.is-active .hero__content > :nth-child(2) { animation-delay: 0.45s; }
.hero__slide.is-active .hero__content > :nth-child(3) { animation-delay: 0.6s; }
.hero__slide.is-active .hero__content > :nth-child(4) { animation-delay: 0.75s; }

.hero__aside {
  animation: ot-fade 1.2s 1s var(--ease-out) both;
}

@keyframes ot-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Page hero entrance */
.page-hero__media img {
  animation: ot-settle 1.8s var(--ease-out) both;
}

@keyframes ot-settle {
  from {
    transform: scale(1.08);
  }
  to {
    transform: scale(1);
  }
}

.page-hero__content > * {
  animation: ot-rise-solid 0.9s var(--ease-out) both;
}

.page-hero__content > :nth-child(1) { animation-delay: 0.15s; }
.page-hero__content > :nth-child(2) { animation-delay: 0.3s; }
.page-hero__content > :nth-child(3) { animation-delay: 0.45s; }
.page-hero__content > :nth-child(4) { animation-delay: 0.6s; }
.page-hero__content > :nth-child(5) { animation-delay: 0.75s; }

/* ---------- Mobile nav items ---------- */
@keyframes ot-slide-in {
  from {
    opacity: 0;
    transform: translate3d(24px, 0, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.mobile-nav.is-open .mobile-nav__list li {
  animation: ot-slide-in 0.5s var(--ease-out) both;
}

.mobile-nav.is-open .mobile-nav__list li:nth-child(1) { animation-delay: 0.12s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(2) { animation-delay: 0.17s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(3) { animation-delay: 0.22s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(4) { animation-delay: 0.27s; }
.mobile-nav.is-open .mobile-nav__list li:nth-child(5) { animation-delay: 0.32s; }

/* Hamburger morph */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  transform: translateY(7px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  width: 24px;
  transform: translateY(-7px) rotate(-45deg);
}

/* ---------- Highlights: characters rise into place ---------- */
.highlight__value.is-armed .char {
  display: inline-block;
  transform: translate3d(0, 110%, 0);
  transition: transform 0.9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 45ms + var(--d, 0ms));
}

.highlight__value.is-armed.is-visible .char {
  transform: none;
}

/* ---------- Markets map ---------- */
@keyframes ot-pulse {
  0% {
    transform: scale(1);
    opacity: 0.9;
  }
  100% {
    transform: scale(3.4);
    opacity: 0;
  }
}

.origin__pulse {
  animation: ot-pulse 2.4s var(--ease-out) infinite;
}

.markets-map.is-armed .route {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset 1.8s var(--ease-out), opacity var(--dur), stroke-width var(--dur);
}

.markets-map.is-armed .market-dot {
  opacity: 0;
  transition: opacity 0.5s var(--ease-out), fill var(--dur);
}

.markets-map.is-armed.is-visible .route {
  stroke-dashoffset: 0;
}

.markets-map.is-armed.is-visible .market-dot {
  opacity: 1;
}

.markets-map.is-armed .route-group[data-region="middle-east"] .route,
.markets-map.is-armed .route-group[data-region="middle-east"] .market-dot {
  transition-delay: 0.2s;
}

.markets-map.is-armed .route-group[data-region="asia-international"] .route,
.markets-map.is-armed .route-group[data-region="asia-international"] .market-dot {
  transition-delay: 0.6s;
}

.markets-map.is-armed .route-group[data-region="western"] .route,
.markets-map.is-armed .route-group[data-region="western"] .market-dot {
  transition-delay: 1s;
}

.markets-map.is-armed.is-visible.is-settled .route,
.markets-map.is-armed.is-visible.is-settled .market-dot {
  transition-delay: 0s;
}

/* ---------- Packaging marks reveal ---------- */
.pack-grid.is-armed .pack-item {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}

.pack-grid.is-armed.is-visible .pack-item {
  opacity: 1;
  transform: none;
}

.pack-grid.is-armed .pack-item:nth-child(2) { transition-delay: 0.05s; }
.pack-grid.is-armed .pack-item:nth-child(3) { transition-delay: 0.1s; }
.pack-grid.is-armed .pack-item:nth-child(4) { transition-delay: 0.15s; }
.pack-grid.is-armed .pack-item:nth-child(5) { transition-delay: 0.2s; }
.pack-grid.is-armed .pack-item:nth-child(6) { transition-delay: 0.25s; }
.pack-grid.is-armed .pack-item:nth-child(7) { transition-delay: 0.3s; }
.pack-grid.is-armed .pack-item:nth-child(8) { transition-delay: 0.35s; }

/* ---------- Spinner ---------- */
@keyframes ot-spin {
  to {
    transform: rotate(360deg);
  }
}

.btn.is-loading .spinner {
  animation: ot-spin 0.8s linear infinite;
}

/* ---------- Form success entrance ---------- */
.form-success {
  animation: ot-rise 0.7s var(--ease-out) both;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  .reveal-init[data-reveal] {
    opacity: 1;
    transform: none;
    clip-path: none;
  }

  .reveal-init[data-reveal="image"]::after {
    display: none;
  }

  .hero__media img,
  .page-hero__media img {
    animation: none !important;
    transform: none !important;
  }

  .origin__pulse {
    animation: none !important;
    opacity: 0.4;
  }

  .card:hover,
  .value-card:hover,
  .product-card:hover,
  .btn:hover {
    transform: none;
  }
}
