/* ==========================================================================
   ANIMATIONS
   Only transform / opacity / filter are animated — never layout properties.
   Every decorative loop is gated behind prefers-reduced-motion: no-preference.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. SCROLL REVEAL  (driven by IntersectionObserver -> .is-in)
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px) scale(.985);
  transition: opacity var(--t-reveal) var(--ease-out),
              transform var(--t-reveal) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: transform, opacity;
}
[data-reveal="left"]  { transform: translateX(-38px); }
[data-reveal="right"] { transform: translateX(38px); }
[data-reveal="scale"] { transform: scale(.93); }
[data-reveal="fade"]  { transform: none; }

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Below 1024px the split layouts stack, so a horizontal entrance offset has
   nothing to travel across and only pushes content past the viewport edge.
   Fall back to the vertical reveal. */
@media (max-width: 1024px) {
  [data-reveal="left"],
  [data-reveal="right"] { transform: translateY(28px) scale(.985); }
}

/* Staggered children: set --i on each child */
[data-stagger] > * { --reveal-delay: calc(var(--i, 0) * 70ms); }

/* --------------------------------------------------------------------------
   2. HERO HEADLINE — per-word mask reveal
   -------------------------------------------------------------------------- */
.reveal-words { display: block; }
.reveal-words .word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: .08em;
  margin-bottom: -.08em;
}
.reveal-words .word > span {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 900ms var(--ease-out);
  transition-delay: calc(var(--w, 0) * 80ms + 180ms);
}
.reveal-words.is-in .word > span { transform: translateY(0); }

/* --------------------------------------------------------------------------
   3. FLOATING DECOR — drifting frame corners & mat swatches
   -------------------------------------------------------------------------- */
.float {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  will-change: transform;
}
.float--corner {
  width: clamp(56px, 7vw, 104px);
  aspect-ratio: 1;
  border: 1.5px solid rgba(163,143,46,.5);
  border-right: 0;
  border-bottom: 0;
}
.float--corner.is-flipped { border: 1.5px solid rgba(163,143,46,.5); border-left: 0; border-top: 0; }
.float--swatch {
  width: clamp(70px, 9vw, 130px);
  aspect-ratio: 3 / 4;
  background: linear-gradient(150deg, var(--linen), #EFE8DA);
  border: 1px solid rgba(26,23,25,.14);
  box-shadow: var(--shadow-md);
}
.float--ring {
  width: clamp(120px, 16vw, 260px);
  aspect-ratio: 1;
  border: 1px solid rgba(205,191,72,.24);
  border-radius: 50%;
}

@media (prefers-reduced-motion: no-preference) {
  @keyframes drift-a {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
    50%      { transform: translate3d(10px, -18px, 0) rotate(3deg); }
  }
  @keyframes drift-b {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
    50%      { transform: translate3d(-14px, 14px, 0) rotate(-4deg); }
  }
  @keyframes drift-c {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50%      { transform: translate3d(0, -20px, 0) scale(1.04); }
  }
  .float--a { animation: drift-a 11s var(--ease-inout) infinite; }
  .float--b { animation: drift-b 14s var(--ease-inout) infinite; }
  .float--c { animation: drift-c  9s var(--ease-inout) infinite; }

  /* Attention pulse on the mobile call/WhatsApp buttons */
  @keyframes attn {
    0%, 88%, 100% { box-shadow: 0 0 0 0 rgba(205,191,72,0); }
    92%           { box-shadow: 0 0 0 8px rgba(205,191,72,.28); }
  }
  @keyframes attn-wa {
    0%, 88%, 100% { box-shadow: 0 0 0 0 rgba(37,211,102,0); }
    92%           { box-shadow: 0 0 0 8px rgba(37,211,102,.3); }
  }
  .mobile-bar__call { animation: attn 8s ease-in-out infinite; }
  .mobile-bar__wa   { animation: attn-wa 8s ease-in-out 1.2s infinite; }

  /* Spinner */
  @keyframes spin { to { transform: rotate(360deg); } }
  .btn.is-loading .spinner { animation: spin 700ms linear infinite; }

  /* Scroll cue */
  @keyframes cue {
    0%   { transform: translateY(0);     opacity: 0; }
    28%  { opacity: 1; }
    100% { transform: translateY(22px);  opacity: 0; }
  }
  .scroll-cue__dot { animation: cue 2.1s var(--ease-inout) infinite; }

  /* Preloader mark */
  @keyframes pl-draw { to { stroke-dashoffset: 0; } }
  @keyframes pl-glow { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
}

/* --------------------------------------------------------------------------
   4. PARALLAX — JS writes --py / --px, CSS applies the transform
   -------------------------------------------------------------------------- */
[data-parallax] {
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
  will-change: transform;
}

/* --------------------------------------------------------------------------
   5. 3D TILT — JS writes --rx / --ry
   -------------------------------------------------------------------------- */
.tilt-scene { perspective: 1200px; }
[data-tilt] {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateZ(0);
  transition: transform var(--t-slow) var(--ease-out);
  transform-style: preserve-3d;
}
[data-tilt].is-tilting { transition: transform 90ms linear; }

/* --------------------------------------------------------------------------
   6. FLIP re-layout for filtered grids
   -------------------------------------------------------------------------- */
.flip-item {
  transition: opacity 380ms var(--ease-out), transform 420ms var(--ease-out);
}
.flip-item.is-hiding { opacity: 0; transform: translateY(16px) scale(.96); }
.flip-item.is-showing {
  animation: flip-in 460ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes flip-in {
  from { opacity: 0; transform: translateY(20px) scale(.95); }
  to   { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   7. SCROLL CUE
   -------------------------------------------------------------------------- */
.scroll-cue {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--mist);
}
.scroll-cue__track {
  position: relative;
  width: 1px; height: 46px;
  background: linear-gradient(180deg, var(--line-strong), transparent);
  overflow: hidden;
}
.scroll-cue__dot {
  position: absolute;
  top: 0; left: -1.5px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--gilt);
}

/* --------------------------------------------------------------------------
   8. PRELOADER
   -------------------------------------------------------------------------- */
.preloader {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-toast) + 1);
  display: grid;
  place-items: center;
  background: var(--bone);
  transition: opacity 520ms var(--ease-out), visibility 520ms;
}
.preloader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
.preloader svg { width: 120px; height: 120px; }
.preloader rect {
  fill: none;
  stroke: var(--gilt);
  stroke-width: 1.5;
  stroke-dasharray: 400;
  stroke-dashoffset: 400;
  animation: pl-draw 900ms var(--ease-out) forwards;
}
.preloader circle { fill: var(--gilt); animation: pl-glow 1.3s ease-in-out infinite; }

/* --------------------------------------------------------------------------
   9. CUSTOM CURSOR (pointer-fine devices only)
   -------------------------------------------------------------------------- */
.cursor {
  position: fixed;
  top: 0; left: 0;
  z-index: var(--z-toast);
  width: 30px; height: 30px;
  margin: -15px 0 0 -15px;
  border: 1px solid rgba(163,143,46,.7);
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(var(--cx, 0), var(--cy, 0), 0) scale(var(--cs, 1));
  transition: opacity 260ms ease, width 240ms var(--ease-out),
              height 240ms var(--ease-out), background-color 240ms ease;
  will-change: transform;
  mix-blend-mode: difference;
}
.cursor.is-active { opacity: 1; }
.cursor.is-hover {
  background: rgba(205,191,72,.22);
  width: 54px; height: 54px;
  margin: -27px 0 0 -27px;
}

/* --------------------------------------------------------------------------
   10. PAGE TRANSITION CURTAIN
   -------------------------------------------------------------------------- */
.curtain {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 1);
  background: var(--grad-ink);
  transform: scaleY(0);
  transform-origin: bottom;
  pointer-events: none;
  transition: transform 520ms var(--ease-inout);
}
.curtain.is-out { transform: scaleY(1); transform-origin: bottom; }

/* --------------------------------------------------------------------------
   11. REDUCED MOTION — the hard override
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Kill parallax, tilt and drift entirely */
  [data-parallax] { transform: none !important; }
  [data-tilt]     { transform: none !important; }
  .float          { display: none !important; }
  .cursor         { display: none !important; }
  .curtain        { display: none !important; }

  /* Reveals become plain fades that are always visible */
  [data-reveal] { opacity: 1; transform: none !important; }
  .reveal-words .word > span { transform: none !important; }
  .frame::after { transition: none; }
  .tilt:hover .tilt__lift { transform: none; }
  .frame:hover .frame__inner img,
  .card:hover .card__media img { transform: none; }
}
