/* Karnaf V3 motion layer (pairs with assets/js/motion.js). Transforms/opacity only.
   Hex drift uses the individual `translate`/`rotate` properties so the JS parallax
   (inline `transform`) composes on top of it instead of fighting it.
   Tune: --kv3-rise / --kv3-rv-dur (reveal), the per-hex --kv3-drift durations, kv3-drift-* amplitudes. */
:root{--kv3-rise:20px;--kv3-rv-dur:.75s;--kv3-m-ease:cubic-bezier(.22,.7,.2,1)}

@media (prefers-reduced-motion:no-preference){
  /* slow drift of the thin hex outlines (heroes) — replaces the old 9s kv3-float bob */
  html .kv3-hexes svg{animation:kv3-drift-a var(--kv3-drift,30s) ease-in-out infinite;will-change:transform}
  html .kv3-hexes .kv3-h1{--kv3-drift:34s;animation-delay:-4s}
  html .kv3-hexes .kv3-h2{--kv3-drift:23s;animation-name:kv3-drift-b;animation-delay:-9s}
  html .kv3-hexes .kv3-h3{--kv3-drift:27s;animation-direction:reverse;animation-delay:-15s}
  html .kv3-hexes .kv3-h4{--kv3-drift:39s;animation-name:kv3-drift-b;animation-direction:reverse;animation-delay:-21s}
  html .kv3-off .kv3-hexes svg{animation-play-state:paused}
  /* bento AI tile hex net + CTA band hex pattern: very slow drift */
  html .kv3-hexnet{animation:kv3-drift-b 40s ease-in-out infinite}
  html .kv3-cta::before{bottom:-97px;animation:kv3-cta-drift 70s linear infinite}
}
@keyframes kv3-drift-a{0%,100%{translate:0 0;rotate:0deg}25%{translate:14px -18px;rotate:5deg}50%{translate:-8px -30px;rotate:-3deg}75%{translate:-18px -10px;rotate:4deg}}
@keyframes kv3-drift-b{0%,100%{translate:0 0;rotate:0deg}33%{translate:-16px 14px;rotate:-6deg}66%{translate:12px 22px;rotate:3deg}}
@keyframes kv3-cta-drift{to{translate:0 -97px}}

/* reveal on scroll: hidden state exists only while html.kv3-motion is set by JS, and only on
   elements that were below the fold at load (.kv3-rv). JS removes both classes when done. */
html.kv3-motion .kv3-rv{opacity:0;translate:0 var(--kv3-rise)}
html.kv3-motion .kv3-rv.kv3-rv-in{animation:kv3-rv var(--kv3-rv-dur) var(--kv3-m-ease) both}
@keyframes kv3-rv{from{opacity:0;translate:0 var(--kv3-rise)}to{opacity:1;translate:0 0}}

/* count-up: ghost keeps the final width (no layout shift), screen readers read .kv3-cnt__sr */
.kv3-cnt{display:inline-grid;font-variant-numeric:tabular-nums}
.kv3-cnt>span{grid-area:1/1}
.kv3-cnt__g{visibility:hidden}
.kv3-cnt__sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* image parallax (bg slideshow): extra cover so the shifted image never shows an edge */
html.kv3-motion .kv3-band__img{scale:1.1}

/* project cards: tilt toward the pointer (vars set by JS, same model as the bento tiles) */
html.kv3-motion-fine .kv3-pcard{transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--lift,0px));transition:transform .5s var(--kv3-m-ease),color .2s}
html.kv3-motion-fine .kv3-pcard:hover{--lift:-4px}

/* image zoom on hover, harmonised to 1.05 */
html .kv3-pcard:hover .kv3-pc-media img,html .kv3-pcard:focus-visible .kv3-pc-media img,
html button.kv3-g-item:hover img,html button.kv3-g-item:focus-visible img,
html .kv3-tile:hover .kv3-t-media img,html .kv3-tile:focus-visible .kv3-t-media img,
html .kv3-t-photo:hover .kv3-ph,html .kv3-t-photo:focus-visible .kv3-ph,
html .kv3-t-ai:hover .kv3-ai-media--img img,html .kv3-t-ai:focus-visible .kv3-ai-media--img img{transform:scale(1.05)}

/* touch: short press feedback */
@media (hover:none){
  html.kv3-motion :is(.kv3-pcard,.kv3-feat,.kv3-tile,.kv3-g-item,.kv3-vmedia,.kv3-tq){transition:transform .35s var(--kv3-m-ease),scale .18s ease-out,box-shadow .35s,border-color .3s,color .3s}
  html.kv3-motion .kv3-press{scale:.98}
}

@media (prefers-reduced-motion:reduce){
  html.kv3-motion .kv3-rv{opacity:1;translate:none;animation:none}
  .kv3-band__img{scale:none}
}
