/* ==========================================================================
   Zahin Sultan portfolio v3 : motion.css  (companion of js/motion.js)
   Tokens come from base.css only. Load AFTER the page stylesheet.

   Hidden-state gate (no flash, no layout shift, no dead content):
     1. Elements that JS will animate are hidden with opacity / clip-path ONLY
        (never display, never size) while  html.js  is set, motion is allowed
        (prefers-reduced-motion: no-preference) and motion.js has not taken over
        yet (html:not(.motion-ok)).
     2. As soon as motion.js starts (fonts ready + first paint) it sets the real
        start state inline on each element and adds  html.motion-ok  in the SAME
        task, so the CSS hiding hands over to the inline state with no frame between.
     3. If motion.js never starts: a CSS-only animation force-shows everything
        after 3.5s, and motion.js adds html.motion-failed after 3s if anything
        throws or a library is missing. Both paths end with all content visible.
     4. No JS (no html.js)  or  reduced motion: nothing is ever hidden.
   ========================================================================== */

@keyframes m-failsafe { to { opacity: 1; } }
@keyframes m-failsafe-clip { to { clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: no-preference) {
  html.js:not(.motion-ok):not(.motion-failed) :is(
    [data-reveal],
    [data-reveal-stagger] > *,
    [data-lines],
    [data-words],
    [data-chars],
    [data-count],
    [data-scramble]:not([data-scramble="hover"])
  ) {
    opacity: 0;
    animation: m-failsafe 0.01s linear 3.5s forwards;
  }
  html.js:not(.motion-ok):not(.motion-failed) [data-img-reveal] {
    clip-path: inset(100% 0 0 0);
    animation: m-failsafe-clip 0.01s linear 3.5s forwards;
  }
}

/* Hard failure: show everything, kill every start state set by JS */
html.motion-failed :is(
  [data-reveal],
  [data-reveal-stagger] > *,
  [data-lines],
  [data-words],
  [data-chars],
  [data-count],
  [data-scramble],
  [data-words] .word,
  [data-chars] .char
) {
  opacity: 1 !important;
  transform: none !important;
  translate: none !important;
}
html.motion-failed [data-img-reveal] { clip-path: none !important; }
html.motion-failed [data-img-reveal] :is(img, video) { transform: none !important; }
html.motion-failed .js .reveal, html.motion-failed.js .reveal { opacity: 1; transform: none; }
html.motion-failed .m-line,
html.motion-failed .m-line * { color: inherit !important; -webkit-text-fill-color: currentColor !important; text-decoration-color: currentColor !important; }
html.motion-failed .m-cw { clip-path: none !important; }
html.motion-failed .m-lc, html.motion-failed .m-curtain, html.motion-failed .m-cursor { display: none !important; }
html.motion-failed.has-cursor, html.motion-failed.has-cursor * { cursor: auto !important; }
html.motion-failed [data-fill-scrub] .m-fill { display: none; }

/* ---------- Lenis (smooth scroll) ---------- */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto !important; }
html.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
html.lenis.lenis-scrolling iframe { pointer-events: none; }

/* ---------- Top-layer helper (popover) ----------
   Cursor and page-transition curtain live in the top layer so they sit above
   <dialog> (showModal) too. Reset the UA popover box. */
.m-top {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  overflow: visible;
  pointer-events: none;
}

/* ---------- Custom cursor ---------- */
.m-cursor { z-index: 2147483000; }
.m-cursor__canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.m-cursor__label {
  position: absolute;
  left: 0;
  top: 0;
  translate: -50% -50%;
  scale: 0.4;
  opacity: 0;
  padding: 0.5em 1em;
  border-radius: 0;
  background: var(--blue);
  color: var(--white);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.005em;
  white-space: nowrap;
  transition: opacity 0.2s var(--ease), scale 0.3s var(--ease), background-color 0.2s var(--ease), color 0.2s var(--ease);
  will-change: transform;
}
.m-cursor__label.is-on { opacity: 1; scale: 1; }
.m-cursor__label.is-light { background: var(--white); color: var(--blue); }

html.has-cursor, html.has-cursor * { cursor: none !important; }
/* the native cursor stays for text entry; the dot hides itself there */
html.has-cursor :is(
  input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"], [type="reset"], [type="range"], [type="file"], [type="color"]),
  textarea,
  [contenteditable=""],
  [contenteditable="true"]
) { cursor: text !important; }
html.has-cursor select { cursor: default !important; }
html.has-cursor ::backdrop { cursor: none !important; }

/* ---------- Letter roll ([data-roll]) ----------
   Each letter is a window 1.24em tall (clip-path, so the inline baseline stays
   the text baseline) with a second copy of the letter stacked under it. */
.m-w { display: inline-block; white-space: nowrap; text-decoration: inherit; }
.m-c {
  display: inline-block;
  position: relative;
  height: 1.24em;
  margin-block: -0.12em; /* the window never makes the line taller */
  line-height: 1.24em;
  clip-path: inset(0);
  vertical-align: baseline;
  text-decoration: inherit;
}
.m-l {
  display: block;
  position: relative;
  height: 1.24em;
  line-height: 1.24em;
  text-decoration: inherit;
  transition: transform 0.42s cubic-bezier(0.65, 0, 0.35, 1);
  transition-delay: calc(var(--i, 0) * 0.018s);
}
.m-l::after {
  content: attr(data-c);
  position: absolute;
  left: 0;
  top: 100%;
  white-space: pre;
  text-decoration: inherit;
}
[data-roll]:focus-visible .m-l { transform: translateY(-100%); }
@media (hover: hover) {
  [data-roll]:hover .m-l { transform: translateY(-100%); }
}

/* ---------- Line curtain ([data-lines]) ---------- */
.m-line { position: relative; }
.m-line:not(.m-on),
.m-line:not(.m-on) * {
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
  text-decoration-color: transparent !important;
}
.m-lc {
  position: absolute;
  inset: -0.08em -0.04em;
  background: var(--blue);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
  will-change: transform;
}
.m-lc--light { background: var(--white); }

/* ---------- Word scrub ([data-words]) ---------- */
[data-words] { transform-origin: 0% 50%; }

/* ---------- Char rise ([data-chars]) ---------- */
.m-cw { clip-path: inset(-0.3em -0.1em var(--m-cb, 0em) -0.1em); }

/* ---------- Counters and scramble ---------- */
[data-count] { font-variant-numeric: tabular-nums; }
.m-scr { white-space: inherit; }

/* ---------- Fill scrub ([data-fill-scrub]) ---------- */
[data-fill-scrub] .m-fl { position: relative; }
[data-fill-scrub] .m-fill {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  white-space: nowrap;
  color: var(--blue);
  pointer-events: none;
  clip-path: inset(0 100% 0 0);
  user-select: none;
}
[data-fill-scrub].m-fill--dark { color: rgba(255, 255, 255, 0.4); }
[data-fill-scrub].m-fill--dark .m-fill { color: var(--white); }

/* ---------- Magnet ---------- */
/* GSAP moves these every frame: the base .btn transform transition would fight it */
[data-magnet] {
  transition-property: background-color, color, border-color, opacity !important;
  will-change: transform;
}

/* ---------- Page transition curtain ---------- */
.m-curtain {
  z-index: 2147482999;
  background: var(--blue);
  clip-path: circle(0px at 50% 50%);
}
.m-curtain.is-blocking { pointer-events: auto; }
html.m-navigating { cursor: progress; }

/* ---------- Reduced motion: nothing moves, nothing hides ---------- */
@media (prefers-reduced-motion: reduce) {
  .m-curtain, .m-cursor { display: none !important; }
  .m-c, .m-l { clip-path: none; height: auto; margin: 0; line-height: inherit; transition: none; }
  .m-l::after { display: none; }
  [data-roll]:hover .m-l, [data-roll]:focus-visible .m-l { transform: none; }
  [data-magnet] { transform: none !important; }
  html.has-cursor, html.has-cursor * { cursor: auto !important; }
}
