/* ───────────────────────────────────────────────────────────
   cinematic.css — styles for the shared cinematic layer.
   Pairs with cinematic.js. Nothing here hides content on its
   own: all pre-animation states are set at runtime by GSAP, so
   reduced-motion / no-JS visitors always see the full page.
   ─────────────────────────────────────────────────────────── */

/* masked word split — .cn-m clips, .cn-w slides up out of it */
.cn-m{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.06em;margin-bottom:-.06em;}
.cn-w{display:inline-block;will-change:transform;}

/* cursor tilt + specular sheen (dynamic light follows the pointer) */
.cn-tilt{transform-style:preserve-3d;will-change:transform;position:relative;}
.cn-tilt::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:2;
  background:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),rgba(255,244,224,.20),rgba(255,255,255,.05) 42%,transparent 68%);
  opacity:0;transition:opacity .45s ease;mix-blend-mode:soft-light;}
.cn-tilt:hover::after{opacity:1;}

/* WebGL film grain + drifting light overlay */
.cn-grain{position:fixed;inset:0;z-index:8000;pointer-events:none;
  mix-blend-mode:overlay;opacity:.38;}

/* Three.js dust motes */
.cn-motes{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none;}
.cn-motes-fixed{position:fixed;inset:0;z-index:1;}

@media (prefers-reduced-motion:reduce){
  .cn-grain,.cn-motes,.cn-motes-fixed{display:none !important;}
  .cn-tilt::after{display:none !important;}
}
@media (max-width:760px){
  .cn-grain{opacity:.26;}
}
