/* Motion — view transitions, marquee, misc animation surfaces Only transform / opacity / clip-path / cheap filters are animated. */

/* Native cross-document view transitions, progressive enhancement only. Ignored on file:// and in browsers without support; navigation never blocks. */
@view-transition {
navigation: auto; }
::view-transition-old(root) { animation: vtOut 180ms var(--e-in) both; }
::view-transition-new(root) { animation: vtIn 320ms var(--e-out) both; }

@keyframes vtOut {
to { opacity: 0; transform: translateY(-8px); } }

@keyframes vtIn {
from { opacity: 0; transform: translateY(10px); } }

@media (prefers-reduced-motion: reduce) {
@view-transition {
navigation: none; }
::view-transition-old(root),
::view-transition-new(root) { animation: none; }
}

/* Header logo and the hero share a name so the brand stays put across pages */
.brand img { view-transition-name: ud-brand; }

/* Magnetic CTA (desktop only, subtle) — JS writes --mx/--my */
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
.magnetic { transform: translate3d(var(--mx, 0px), var(--my, 0px), 0); transition: transform 300ms var(--e-out); }
.magnetic.is-pulling { transition: transform 90ms linear; }
}

@media (prefers-reduced-motion: reduce) {
.magnetic { transform: none !important; }
}

/* Stroke-draw for line icons and the footer wordmark */
.js [data-draw-stroke] path,
.js [data-draw-stroke] circle,
.js [data-draw-stroke] rect,
.js [data-draw-stroke] line,
.js [data-draw-stroke] polyline,
.js [data-draw-stroke] text { stroke-dasharray: var(--dash, 1000); stroke-dashoffset: var(--dash, 1000); }
.js [data-draw-stroke].is-drawn path,
.js [data-draw-stroke].is-drawn circle,
.js [data-draw-stroke].is-drawn rect,
.js [data-draw-stroke].is-drawn line,
.js [data-draw-stroke].is-drawn polyline,
.js [data-draw-stroke].is-drawn text { stroke-dashoffset: 0; transition: stroke-dashoffset 1.2s var(--e-out); }

@media (prefers-reduced-motion: reduce) {
.js [data-draw-stroke] path,
.js [data-draw-stroke] circle,
.js [data-draw-stroke] rect,
.js [data-draw-stroke] line,
.js [data-draw-stroke] polyline,
.js [data-draw-stroke] text { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
}

/* Parallax layers — JS sets --py; never animates layout properties */
.parallax { will-change: transform; transform: translate3d(0, var(--py, 0px), 0); }

@media (prefers-reduced-motion: reduce) {
.parallax { transform: none !important; will-change: auto; } }


/* Press feedback — applied broadly so touch always answers within 100ms */
.chip:active,
.msg__action:active,
.shot:active,
.ccard__copy:active { transform: scale(0.96); }

/* Reveal helper for gallery batches */
.js .shot[data-batch] { opacity: 0; transform: translate3d(0, 16px, 0); }
.js .shot[data-batch].is-in { opacity: 1; transform: none; transition: opacity 500ms var(--e-out), transform 500ms var(--e-out); }

@media (prefers-reduced-motion: reduce) {
.js .shot[data-batch] { opacity: 1 !important; transform: none !important; }
}

/* === ROUND 2 === */
:root {
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
}
/* global film grain — fixed, inert, never intercepts a click */
.grain { position: fixed; inset: 0; z-index: 3; pointer-events: none; background-image: var(--grain); background-size: 180px 180px; opacity: .035; mix-blend-mode: overlay; }
@media (prefers-reduced-motion: reduce) { .grain { display: none; } }
/* === /ROUND 2 === */
