/* =========================================================================
   ANTHONY WOTRING — Experience layer
   An interaction system layered on top of styles.css.
   Everything here is additive, GPU-friendly, and fully gated behind
   pointer/reduced-motion so touch + a11y users get the clean native site.
   ========================================================================= */

/* ---------- 0. Engine base ---------- */
:root{
  --veil: #0c0b09;          /* deep ink for transition curtain */
  --grain-opacity: 0.045;
}

/* Smooth-scroll wrapper (created by JS, only on capable devices) */
#exp-scroll{
  position: fixed;
  top: 0; left: 0;
  width: 100%;
  will-change: transform;
  backface-visibility: hidden;
}
html.exp-smooth{ scroll-behavior: auto; }      /* JS owns the easing now */
html.exp-smooth body{ overflow-x: clip; }

/* ---------- 1. Film grain + ambient light ---------- */
.exp-grain{
  position: fixed; inset: -120% ;
  z-index: 60;
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
  will-change: transform;
}
@media (prefers-reduced-motion: no-preference){
  .exp-grain{ animation: grainShift 0.6s steps(4) infinite; }
}
@keyframes grainShift{
  0%{transform:translate3d(0,0,0)}    25%{transform:translate3d(-3%,1%,0)}
  50%{transform:translate3d(2%,-2%,0)} 75%{transform:translate3d(-1%,2%,0)}
  100%{transform:translate3d(1%,-1%,0)}
}

/* faint light that drifts with the cursor — sits behind everything */
.exp-ambient{
  position: fixed; inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(42vw 42vw at var(--mx,50%) var(--my,32%),
      rgba(228,224,215,0.55), rgba(228,224,215,0) 70%);
  opacity: 0;
  transition: opacity 1.2s ease;
  mix-blend-mode: normal;
}
.exp-ambient.is-live{ opacity: 1; }

/* ---------- 2. Scroll progress ---------- */
.exp-progress{
  position: fixed; top: 0; left: 0;
  height: 2px; width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: var(--ink);
  z-index: 120;
  pointer-events: none;
}

/* ---------- 3. Transition veil / preloader ---------- */
.exp-veil{
  position: fixed; inset: 0;
  z-index: 200;
  background: var(--veil);
  color: var(--paper);
  display: grid;
  place-items: center;
  transform: translateY(0);
  will-change: transform;
}
.exp-veil[hidden]{ display: none; }
.exp-veil__inner{
  display: flex; flex-direction: column; align-items: center; gap: 1.4rem;
  transform: translateY(0);
}
.exp-veil__mark{
  width: clamp(46px, 6vw, 74px);
  opacity: 0.96;
  filter: invert(1) brightness(1.6);
  animation: veilMark 1.6s var(--ease) infinite alternate;
}
@keyframes veilMark{ from{transform:translateY(0) rotate(0)} to{transform:translateY(-6px) rotate(-3deg)} }
.exp-veil__count{
  font-family: var(--mono);
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  color: rgba(248,247,244,0.5);
}
.exp-veil__bar{
  width: clamp(120px, 18vw, 230px);
  height: 1px;
  background: rgba(248,247,244,0.18);
  position: relative; overflow: hidden;
}
.exp-veil__bar i{
  position: absolute; inset: 0 100% 0 0;
  background: var(--paper);
  transition: right 0.2s linear;
}
.exp-veil.is-lifting{
  transition: transform 0.9s cubic-bezier(0.76,0,0.24,1);
  transform: translateY(-100%);
}
.exp-veil.is-covering{
  transition: transform 0.55s cubic-bezier(0.76,0,0.24,1);
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce){
  .exp-veil__mark{ animation: none; }
}

/* ---------- 4. Custom cursor ---------- */
body.exp-cursor{ cursor: none; }
body.exp-cursor a,
body.exp-cursor button,
body.exp-cursor .magnetic{ cursor: none; }
body.exp-cursor input,
body.exp-cursor textarea,
body.exp-cursor select{ cursor: auto; }

.exp-cur{
  position: fixed; top: 0; left: 0;
  z-index: 210;
  pointer-events: none;
  will-change: transform;
}
.exp-cur__ring{
  position: fixed; top: 0; left: 0;
  width: 42px; height: 42px;
  margin: -21px 0 0 -21px;
  border: 1.6px solid var(--cur-c, #fff);
  border-radius: 999px;
  display: grid; place-items: center;
  mix-blend-mode: var(--cur-blend, difference);
  background: transparent;
  transition:
    width 0.42s var(--ease), height 0.42s var(--ease),
    margin 0.42s var(--ease), background 0.4s var(--ease),
    border-color 0.4s var(--ease), opacity 0.4s var(--ease);
  will-change: transform;
}
/* difference blend with PURE white = a true inversion (photographic negative)
   of whatever is behind the cursor. When experience.js detects a solid
   backdrop it overrides --cur-c / --cur-blend to a CLEAN black-or-white invert. */
.exp-cur__dot{
  position: fixed; top: 0; left: 0;
  width: 8px; height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 999px;
  background: var(--cur-c, #fff);
  mix-blend-mode: var(--cur-blend, difference);
  will-change: transform;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), background 0.25s var(--ease);
}
.exp-cur__label{
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
  white-space: nowrap;
}

/* state: hovering a link — small magnetic ring */
.exp-cur.is-link .exp-cur__ring{ width: 58px; height: 58px; margin:-29px 0 0 -29px; }
.exp-cur.is-link .exp-cur__dot{ opacity: 0; }

/* state: hovering a project — filled pill with label, no blend */
.exp-cur.is-view .exp-cur__ring{
  width: 96px; height: 96px; margin:-48px 0 0 -48px;
  background: var(--ink);
  border-color: var(--ink);
  mix-blend-mode: normal;
}
.exp-cur.is-view .exp-cur__dot{ opacity: 0; }
.exp-cur.is-view .exp-cur__label{ opacity: 1; transform: scale(1); }

/* state: hovering a CTA — solid disc with arrow */
.exp-cur.is-cta .exp-cur__ring{
  width: 66px; height: 66px; margin:-33px 0 0 -33px;
  background: var(--ink);
  border-color: var(--ink);
  mix-blend-mode: normal;
}
.exp-cur.is-cta .exp-cur__dot{ opacity: 0; }
.exp-cur.is-cta .exp-cur__label{ opacity: 1; transform: scale(1); font-size: 1rem; letter-spacing: 0; }

/* state: hovering an image to inspect */
.exp-cur.is-inspect .exp-cur__ring{
  width: 84px; height: 84px; margin:-42px 0 0 -42px;
  background: rgba(12,11,9,0.82);
  border-color: transparent;
  mix-blend-mode: normal;
}
.exp-cur.is-inspect .exp-cur__dot{ opacity: 0; }
.exp-cur.is-inspect .exp-cur__label{ opacity: 1; transform: scale(1); }

.exp-cur.is-hidden .exp-cur__ring,
.exp-cur.is-hidden .exp-cur__dot{ opacity: 0; }

/* ---------- 5. Hero cinematic build ---------- */
.exp-line{ display: block; }
.exp-line__in{
  display: block;
  transform: translateY(0.5em);
  opacity: 0;
  will-change: transform, opacity;
}
.exp-armed .exp-line__in{
  transition: transform 1s cubic-bezier(0.22,1,0.36,1), opacity 1s var(--ease);
  transition-delay: var(--ld, 0ms);
}
.exp-armed.is-revealed .exp-line__in{ transform: translateY(0); opacity: 1; }

/* hero depth wrapper for mouse parallax */
.exp-depth{ will-change: transform; }

/* ---------- 6. Signature scroll moment (word build) ---------- */
.exp-word{
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.exp-word__in{
  display: inline-block;
  transform: translateY(108%);
  opacity: 0.2;
  will-change: transform, opacity;
  transition: transform 0.9s cubic-bezier(0.22,1,0.36,1),
              opacity 0.9s var(--ease);
  transition-delay: var(--wd, 0ms);
}
.exp-words.is-in .exp-word__in{ transform: translateY(0); opacity: 1; }

/* ---------- 7. Project cards: depth + direction-aware ---------- */
@media (hover: hover) and (pointer: fine) and (min-width: 1025px){
  .card .media{
    transition: transform 0.5s var(--ease), box-shadow 0.6s var(--ease);
    transform-style: preserve-3d;
    will-change: transform;
  }
  .card:hover .media{
    box-shadow: 0 40px 80px -42px rgba(10,10,10,0.5);
  }
  /* inner image gets an independent depth shift (set via JS vars) */
  .card .media__zoom{
    transition: transform 0.5s var(--ease);
  }
  .card.is-tilting .media,
  .card.is-tilting .media__zoom{ transition: transform 0.12s linear; }

  /* direction-aware wash that follows the entry edge */
  .card .media__wash{
    position: absolute; inset: 0; z-index: 2;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(10,10,10,0) 40%, rgba(10,10,10,0.34));
    opacity: 0;
    transition: opacity 0.5s var(--ease);
  }
  .card:hover .media__wash{ opacity: 1; }

  /* floating gallery tag that animates in on hover */
  .card .media__float{
    position: absolute; left: 1.1rem; bottom: 1.1rem; z-index: 3;
    display: flex; align-items: center; gap: 0.6rem;
    font-family: var(--mono);
    font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--paper);
    transform: translateY(12px);
    opacity: 0;
    transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
  }
  .card:hover .media__float{ opacity: 1; transform: translateY(0); }
  .card .media__float .dotted{
    width: 26px; height: 1px; background: rgba(248,247,244,0.6);
  }
}

/* the meta line draws its top border on reveal */
@media (prefers-reduced-motion: no-preference){
  .eyebrow .line{ transform: scaleX(0); transform-origin: left; transition: transform 1.1s var(--ease) 0.1s; }
  .eyebrow.is-in .line{ transform: scaleX(1); }
}

/* ---------- 8. Motion toggle (injected into nav) ---------- */
.exp-motion{
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--sans);
  font-size: var(--fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-weight: 500;
  color: var(--warm-gray);
  padding: 0.35em 0;
  transition: color 0.35s var(--ease);
  will-change: transform;
}
.exp-motion:hover{ color: var(--ink); }
.exp-motion__dot{
  width: 7px; height: 7px; border-radius: 999px;
  border: 1px solid currentColor;
  background: transparent;
  transition: background 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.exp-motion.is-on{ color: var(--ink); }
.exp-motion.is-on .exp-motion__dot{
  background: var(--ink);
  box-shadow: 0 0 0 3px rgba(10,10,10,0.08);
}
@media (max-width: 760px){
  .exp-motion{ font-size: 1rem; letter-spacing: 0.04em; }
  .exp-motion__dot{ width: 9px; height: 9px; }
}

/* ---------- 9. Reduced-motion / touch resets ---------- */
@media (prefers-reduced-motion: reduce){
  .exp-grain{ display: none; }
  .exp-line__in,
  .exp-word__in{ transform: none !important; opacity: 1 !important; }
}
