/* ==========================================================================
   EYEDIA — Motion layer
   Driven by assets/js/motion.js. Every effect is transform/opacity only, so it
   stays on the compositor. Everything collapses gracefully when the visitor
   prefers reduced motion, or when JavaScript never runs.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Scroll reveals

   Elements only hide once JS confirms it is running (html.js-motion). Without
   it every reveal stays visible, so the page degrades to a plain document.
   -------------------------------------------------------------------------- */

.js-motion [data-reveal] {
  opacity: 0;
  will-change: transform, opacity;
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out),
    clip-path 1s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js-motion [data-reveal="up"]    { transform: translate3d(0, 34px, 0); }
.js-motion [data-reveal="down"]  { transform: translate3d(0, -34px, 0); }
.js-motion [data-reveal="left"]  { transform: translate3d(-40px, 0, 0); }
.js-motion [data-reveal="right"] { transform: translate3d(40px, 0, 0); }
.js-motion [data-reveal="scale"] { transform: scale(0.94); }
.js-motion [data-reveal="fade"]  { transform: none; }

/* Wipe reveal — the panel uncovers itself from the bottom up. */
.js-motion [data-reveal="clip"] {
  clip-path: inset(0 0 100% 0);
  transform: none;
}

/* Text that rises out of its own baseline, one line at a time. */
.js-motion [data-reveal="mask"] {
  transform: none;
}

.js-motion [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

/*
 * Failsafe state, set by the bootstrap in <head> when content is still hidden
 * and the page is visible — meaning the motion layer did not do its job.
 * The transition has to go with it: transitions are suspended along with frames,
 * so .is-revealed alone would leave the element stuck at opacity 0.
 */
.reveal-instant [data-reveal],
.reveal-instant .split-word {
  transition: none !important;
  animation: none !important;
}

/*
 * Applied per element by the watchdog when a reveal was marked done but never
 * painted — a transition that died mid-flight because the tab lost its frames.
 * Scoped to the affected element so the rest of the page keeps animating.
 */
.js-motion [data-reveal].reveal-now,
.js-motion [data-reveal].reveal-now .split-word {
  transition: none !important;
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
}

/* --------------------------------------------------------------------------
   Split text — words rise and fade in, one after another

   Deliberately no overflow mask: clipping each word to its own box is prettier
   in Latin but crops the tall ascenders and deep descenders of Cairo on the
   Arabic side. A rise-and-fade reads the same and is safe in both scripts.
   -------------------------------------------------------------------------- */

.js-motion .split-word {
  display: inline-block;
  opacity: 0;
  transform: translate3d(0, 0.45em, 0);
  transition:
    opacity 0.7s var(--ease-out),
    transform 0.9s var(--ease-out);
  transition-delay: var(--word-delay, 0ms);
  will-change: transform, opacity;
}

.js-motion .is-revealed .split-word,
.js-motion .is-revealed.split-line .split-word {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   Custom cursor
   Only shown on devices with a real pointer.
   -------------------------------------------------------------------------- */

.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10000;
  pointer-events: none;
  display: none;
  mix-blend-mode: difference;
  /* Stays hidden until the pointer first moves — otherwise it is parked in the
     middle of the page on load, looking like a stray dot. */
  opacity: 0;
  transition: opacity 0.3s var(--ease-out);
}

/*
 * Hiding the OS pointer also hides the user's own pointer-size and contrast
 * settings, so it is gated on a fine pointer, no reduced-motion preference and
 * no forced-colors (high-contrast) mode. Text fields keep their native caret —
 * losing the I-beam while typing is a real usability cost for no visual gain.
 */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) and (forced-colors: none) {
  .js-motion .cursor { display: block; }

  .js-motion.has-cursor body,
  .js-motion.has-cursor a,
  .js-motion.has-cursor button,
  .js-motion.has-cursor select,
  .js-motion.has-cursor [data-cursor] {
    cursor: none;
  }

  .js-motion.has-cursor input,
  .js-motion.has-cursor textarea {
    cursor: auto;
  }
}

.cursor__dot,
.cursor__ring {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 50%;
  transform: translate3d(-50%, -50%, 0);
  will-change: transform;
}

.cursor__dot {
  width: 6px;
  height: 6px;
  background: var(--gold-pale);
  transition: width 0.25s var(--ease-out), height 0.25s var(--ease-out), opacity 0.25s var(--ease-out);
}

.cursor__ring {
  width: 34px;
  height: 34px;
  border: 1px solid rgba(199, 161, 122, 0.65);
  transition: width 0.35s var(--ease-out), height 0.35s var(--ease-out),
    border-color 0.35s var(--ease-out), background-color 0.35s var(--ease-out);
}

.cursor__label {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate3d(-50%, -50%, 0);
  font-family: "Space Grotesk", monospace;
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #0a0a0a;
  opacity: 0;
  white-space: nowrap;
  transition: opacity 0.25s var(--ease-out);
}

/* Hovering something interactive: the ring swells and fills. */
.cursor.is-active .cursor__ring {
  width: 64px;
  height: 64px;
  background: rgba(199, 161, 122, 0.9);
  border-color: transparent;
}
.cursor.is-active .cursor__dot { opacity: 0; }
.cursor.is-active .cursor__label { opacity: 1; }

.cursor.is-down .cursor__ring { transform: translate3d(-50%, -50%, 0) scale(0.82); }

/* --------------------------------------------------------------------------
   Magnetic buttons
   -------------------------------------------------------------------------- */

[data-magnetic] {
  will-change: transform;
}

/* --------------------------------------------------------------------------
   Tilt cards
   -------------------------------------------------------------------------- */

[data-tilt] {
  transform-style: preserve-3d;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   Scroll progress
   -------------------------------------------------------------------------- */

.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: 1100;
  background: transparent;
  pointer-events: none;
}
.scroll-progress__bar {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, var(--gold), var(--gold-pale));
  will-change: transform;
}
.is-rtl .scroll-progress__bar { transform-origin: right center; }

/* --------------------------------------------------------------------------
   Hero ambience
   -------------------------------------------------------------------------- */

@keyframes eyedia-drift {
  0%,
  100% { transform: translateY(0); opacity: 0.5; }
  50%  { transform: translateY(-26px); opacity: 0.9; }
}

.js-motion .hero__grid-line {
  animation: eyedia-drift 9s var(--ease-in-out) infinite;
}
.js-motion .hero__grid-line:nth-child(2) { animation-delay: -2.2s; }
.js-motion .hero__grid-line:nth-child(3) { animation-delay: -4.4s; }
.js-motion .hero__grid-line:nth-child(4) { animation-delay: -6.6s; }

/* Scroll cue — a spark running down the rule. */
@keyframes eyedia-scroll-cue {
  0%   { transform: translateY(-100%); }
  100% { transform: translateY(100%); }
}
.hero__scroll-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gold-pale);
  animation: eyedia-scroll-cue 2.1s var(--ease-in-out) infinite;
}

/* Shopping calls to action: a quiet periodic nudge, then a clear response to
   hover or keyboard focus. The whole block is omitted for reduced motion. */
@keyframes eyedia-cart-idle {
  0%,
  78%,
  100% { transform: translateX(0) rotate(0); }
  84%  { transform: translateX(var(--cart-idle-travel, 3px)) rotate(-5deg); }
  90%  { transform: translateX(var(--cart-idle-return, -1px)) rotate(3deg); }
}

@keyframes eyedia-cart-roll {
  0%   { transform: translateX(0) rotate(0); }
  38%  { transform: translateX(var(--cart-travel, 7px)) rotate(-6deg); }
  64%  { transform: translateX(var(--cart-travel, 7px)) rotate(5deg); }
  100% { transform: translateX(0) rotate(0); }
}

@media (prefers-reduced-motion: no-preference) {
  .btn--cart .btn__cart-icon,
  .section-title__icon--cart i {
    animation: eyedia-cart-idle 4.2s var(--ease-in-out) infinite;
    will-change: transform;
  }

  .btn--cart:hover .btn__cart-icon,
  .btn--cart:focus-visible .btn__cart-icon,
  .section-title__icon--cart:hover i,
  .section-title__icon--cart:focus-visible i {
    animation: eyedia-cart-roll 0.68s var(--ease-out) both;
  }

  .is-rtl .btn--cart,
  .is-rtl .section-title__icon--cart {
    --cart-travel: -7px;
    --cart-idle-travel: -3px;
    --cart-idle-return: 1px;
  }
}

/* --------------------------------------------------------------------------
   Ken Burns
   The slow push happens only while the band is on screen.
   -------------------------------------------------------------------------- */

@keyframes eyedia-kenburns {
  0%   { scale: 1; }
  100% { scale: 1.12; }
}

.js-motion [data-kenburns].is-inview {
  animation: eyedia-kenburns 14s var(--ease-in-out) alternate infinite;
}

/* --------------------------------------------------------------------------
   Marquee
   -------------------------------------------------------------------------- */

@keyframes eyedia-marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

.marquee {
  overflow: hidden;
  border-block: 1px solid var(--line-soft);
  padding: 1rem 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  gap: 3rem;
  width: max-content;
  animation: eyedia-marquee var(--marquee-duration, 34s) linear infinite;
  will-change: transform;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 0.8rem;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.75rem;
  font-family: "Space Grotesk", var(--font-body);
  white-space: nowrap;
}
.marquee__item i { color: var(--gold); }

/* --------------------------------------------------------------------------
   Reduced motion — strip everything back to instant, legible states
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .js-motion [data-reveal],
  .js-motion [data-reveal].is-revealed {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }

  .split-word {
    transform: none !important;
    transition: none !important;
  }

  .js-motion .hero__grid-line,
  .js-motion [data-kenburns].is-inview,
  .hero__scroll-line::after,
  .btn--cart .btn__cart-icon,
  .section-title__icon--cart i,
  .marquee__track {
    animation: none !important;
  }

  .btn--cart:hover .btn__cart-icon,
  .btn--cart:focus-visible .btn__cart-icon,
  .section-title__icon--cart:hover,
  .section-title__icon--cart:focus-visible,
  .section-title__icon--cart:hover i,
  .section-title__icon--cart:focus-visible i {
    transform: none !important;
  }

  .js-motion .cursor { display: none !important; }
  .js-motion.has-cursor body,
  .js-motion.has-cursor a,
  .js-motion.has-cursor button { cursor: auto !important; }

  .paralex img { transform: none !important; }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}
