/* InvestIdealHome — motion.css
   Visual half of /js/motion.js. Hidden states apply only once motion.js has set html.motion-ready
   AND the visitor has not asked for reduced motion. Without JS, or with reduced motion, all
   content is simply visible. Only transform, opacity and clip-path are animated. */

/* ---------- Page enter: <main> drifts up and fades in (CSS only, no loading curtain) ---------- */
@media (prefers-reduced-motion: no-preference) {
  main:not(.admin-main) {
    /* backwards, not both: a filled transform animation would keep making <main> the containing
       block for position:fixed descendants (sticky bars, trays, drawers) after it finishes. */
    animation: motion-page-in 0.8s var(--ease-out) backwards;
  }
}
@keyframes motion-page-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {

  /* ---------- Reveal: [data-reveal="up|fade|left|right|scale|clip"] (empty = up) ----------
     Every data-reveal element sets all of its own variables (base rule first, then the type
     rules), so a nested reveal never inherits a neighbour's offset. */
  html.motion-ready [data-reveal] {
    --reveal-x: 0px;
    --reveal-y: 36px;
    --reveal-s: 1;
    --reveal-o: 0;
    --reveal-dur: 1.2s;
  }
  html.motion-ready [data-reveal="left"]  { --reveal-x: -40px; --reveal-y: 0px; --reveal-dur: 1.3s; }
  html.motion-ready [data-reveal="right"] { --reveal-x: 40px;  --reveal-y: 0px; --reveal-dur: 1.3s; }
  html.motion-ready [data-reveal="scale"] { --reveal-x: 0px;   --reveal-y: 0px; --reveal-s: 0.94; --reveal-dur: 1.3s; }
  html.motion-ready [data-reveal="fade"]  { --reveal-x: 0px;   --reveal-y: 0px; --reveal-dur: 1.1s; }
  html.motion-ready [data-reveal="clip"]  { --reveal-x: 0px;   --reveal-y: 0px; --reveal-o: 1; --reveal-dur: var(--dur-xslow); }

  html.motion-ready [data-reveal]:not(.is-revealed) {
    opacity: var(--reveal-o);
    transform: translate3d(var(--reveal-x), var(--reveal-y), 0) scale(var(--reveal-s));
  }

  /* The transition (and will-change) exists only while revealing. Afterwards the element carries
     neither, so its own hover/press styles and magnetic offsets behave normally. */
  html.motion-ready [data-reveal].is-revealing {
    transition-property: opacity, transform, clip-path;
    transition-duration: var(--reveal-dur);
    transition-timing-function: var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform, clip-path;
  }

  /* Stagger children: their own delay plus index x step (both written by motion.js). */
  html.motion-ready [data-motion-stagger-item][data-reveal].is-revealing {
    transition-delay: calc(var(--reveal-delay, 0ms) + var(--stagger-index, 0) * var(--stagger-step, 0ms));
  }

  /* Clip: a wrapper whose clip-path opens from the bottom while its image settles from 1.18x. */
  html.motion-ready [data-reveal="clip"]:not(.is-revealed) { clip-path: inset(100% 0 0 0); }
  html.motion-ready [data-reveal="clip"].is-revealed { clip-path: inset(0); }
  html.motion-ready [data-reveal="clip"].is-revealed:not(.is-revealing) { clip-path: none; }
  html.motion-ready [data-reveal="clip"]:not(.is-revealed) img { transform: scale(1.18); }
  html.motion-ready [data-reveal="clip"].is-revealing img {
    transition-property: transform;
    transition-duration: var(--reveal-dur);
    transition-timing-function: var(--ease-out);
    transition-delay: var(--reveal-delay, 0ms);
  }

  /* ---------- Split headings: [data-split] ---------- */
  html.motion-ready [data-motion-split] { --split-step: 45ms; }
  .split-word {
    display: inline-block;
    vertical-align: top;
    overflow: hidden;                       /* the mask */
    padding: 0.06em 0.08em 0.14em;          /* room for descenders and italic overhang */
    margin: -0.06em -0.08em -0.14em;        /* ...without changing the line layout */
  }
  .split-word__inner {
    display: inline-block;
    transition-property: transform;
    transition-duration: 1.1s;
    transition-timing-function: var(--ease-out);
    transition-delay: calc(var(--i, 0) * var(--split-step, 45ms));
  }
  html.motion-ready [data-motion-split]:not(.is-revealed) .split-word__inner {
    transform: translate3d(0, 110%, 0);
  }
  html.motion-ready [data-motion-split].is-revealing .split-word__inner { will-change: transform; }

  /* ---------- Parallax: [data-parallax] (JS sets translate3d; will-change only while scrolling) ---------- */
  html.is-scrolling [data-motion-parallax] { will-change: transform; }
}

/* ---------- Counters: keep digits from jittering while they count ---------- */
[data-count-to] { font-variant-numeric: tabular-nums; }

/* ---------- Cursor follower: [data-cursor] on fine pointers only (element added by JS) ---------- */
.motion-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: var(--z-cursor);
  width: 84px;
  height: 84px;
  pointer-events: none;
}
.motion-cursor.is-visible { will-change: transform; }
.motion-cursor__dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding-left: var(--tracking-wide);      /* balances the trailing letter-spacing */
  border-radius: 50%;
  background: var(--gold);
  color: var(--ink);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  transform: scale(0);
  opacity: 0;
}
.motion-cursor.is-visible .motion-cursor__dot { transform: scale(1); opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .motion-cursor__dot {
    transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur) var(--ease-out);
  }
}
