{"version":3,"file":"GSRC_Motion.BLcsWCiv.mjs","names":["React.useState","_Fragment"],"sources":["https:/framerusercontent.com/modules/li5UVCo6mgVjcfeMqKrG/xYDmjIMYIckJqoPlf9OV/GSRC_Motion.js"],"sourcesContent":["import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from\"react/jsx-runtime\";import*as React from\"react\";import{useMotionValue,useSpring,useScroll,useVelocity,useTransform}from\"framer-motion\";// GSRC motion overrides. 2026-10-17: Magnetic, Tilt and Velocity skew retired (pass-through), see bottom.\n// GSRC motion overrides. Apply to canvas layers in Framer (Code Overrides → Motion).\n// Every effect is skipped for visitors who ask for reduced motion. Magnetic, Tilt and\n// Velocity skew are also skipped on touch devices (no cursor, and the skew fights iOS\n// momentum scrolling). Hero exit and Drift are plain scroll effects and run everywhere.\n// Still on reduced motion freezes a Framer ticker for reduced-motion visitors.\nconst reduced=()=>typeof window!==\"undefined\"&&window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;const finePointer=()=>typeof window!==\"undefined\"&&window.matchMedia(\"(pointer: fine)\").matches;// Magnetic: the element leans slightly toward the cursor and springs back.\n// Kept small on purpose (max 6px) and measured from the resting position: the first\n// version read the already-moved rect and pulled up to ~20px, so buttons chased the\n// cursor past their own edge, which felt broken.\nconst MAG_MAX=6;const clamp=v=>Math.max(-MAG_MAX,Math.min(MAG_MAX,v));function magneticRetired(Component){return props=>{const x=useMotionValue(0);const y=useMotionValue(0);const sx=useSpring(x,{stiffness:260,damping:22,mass:.4});const sy=useSpring(y,{stiffness:260,damping:22,mass:.4});const move=e=>{if(!finePointer()||reduced())return;const r=e.currentTarget.getBoundingClientRect();// Undo the current offset so the maths always uses the resting centre.\nconst cx=r.left-sx.get()+r.width/2;const cy=r.top-sy.get()+r.height/2;x.set(clamp((e.clientX-cx)*.12));y.set(clamp((e.clientY-cy)*.2));};const leave=()=>{x.set(0);y.set(0);};return /*#__PURE__*/_jsx(Component,{...props,onMouseMove:e=>{move(e);props.onMouseMove?.(e);},onMouseLeave:e=>{leave();props.onMouseLeave?.(e);},style:{...props.style,x:sx,y:sy}});};}// Tilt: a card tips toward the cursor in 3D.\nfunction tiltRetired(Component){return props=>{const rx=useMotionValue(0);const ry=useMotionValue(0);const srx=useSpring(rx,{stiffness:180,damping:18});const sry=useSpring(ry,{stiffness:180,damping:18});const move=e=>{if(!finePointer()||reduced())return;const r=e.currentTarget.getBoundingClientRect();const px=(e.clientX-r.left)/r.width-.5;const py=(e.clientY-r.top)/r.height-.5;// 4deg max (was 10): enough to feel alive without making the panel's button hard to hit.\nry.set(px*8);rx.set(-py*8);};const leave=()=>{rx.set(0);ry.set(0);};return /*#__PURE__*/_jsx(Component,{...props,onMouseMove:e=>{move(e);props.onMouseMove?.(e);},onMouseLeave:e=>{leave();props.onMouseLeave?.(e);},style:{...props.style,rotateX:srx,rotateY:sry,transformPerspective:900}});};}// Velocity skew: the layer leans with scroll speed, like motion blur on a fast pan.\nfunction velocitySkewRetired(Component){return props=>{const{scrollY}=useScroll();const v=useVelocity(scrollY);const raw=useTransform(v,[-3e3,0,3e3],[4,0,-4],{clamp:true});const skewY=useSpring(raw,{stiffness:260,damping:40});// Decided after mount so the server and first client render match.\nconst[on,setOn]=React.useState(false);React.useEffect(()=>setOn(finePointer()&&!reduced()),[]);return /*#__PURE__*/_jsx(Component,{...props,style:{...props.style,skewY:on?skewY:0}});};}// Hero exit: content drifts up and fades as the first screen scrolls away.\nexport function withHeroExit(Component){return props=>{const{scrollY}=useScroll();const y=useTransform(scrollY,[0,700],[0,-140]);const opacity=useTransform(scrollY,[0,520],[1,0]);if(reduced())return /*#__PURE__*/_jsx(Component,{...props});return /*#__PURE__*/_jsx(Component,{...props,style:{...props.style,y,opacity}});};}// Still on reduced motion: apply to a Framer ticker. Visitors who ask for reduced motion get a\n// static row instead of an endless scroll (WCAG 2.2.2). Pure CSS keyed on the layer's name, so the\n// server HTML is already still and nothing jumps after load. The ticker's JS keeps writing an inline\n// transform; the !important rule wins over it.\nexport function withStillOnReducedMotion(Component){return props=>{const name=props[\"data-framer-name\"]||props.name||\"Ticker\";const sel=`[data-framer-name=\"${String(name).replace(/\"/g,'\\\\\"')}\"]`;const css=`@media (prefers-reduced-motion: reduce){${sel},${sel} *{transform:none!important;animation:none!important;transition:none!important}}`;return /*#__PURE__*/_jsxs(_Fragment,{children:[/*#__PURE__*/_jsx(\"style\",{dangerouslySetInnerHTML:{__html:String(css).replace(/<\\//g,\"<\\\\/\")}}),/*#__PURE__*/_jsx(Component,{...props})]});};}// Slow drift for big background type.\nexport function withDrift(Component){return props=>{const{scrollY}=useScroll();const x=useTransform(scrollY,[0,4e3],[0,-400]);if(reduced())return /*#__PURE__*/_jsx(Component,{...props});return /*#__PURE__*/_jsx(Component,{...props,style:{...props.style,x}});};}// ---- 2026-10-14 UI/UX pass ----\n// Hide on scroll: apply to the sticky top bar (live bar + header). It slides away while the\n// visitor scrolls down and comes back the moment they scroll up. Always shown near the top.\nexport function withHideOnScroll(Component){return props=>{const[hidden,setHidden]=React.useState(false);React.useEffect(()=>{let last=window.scrollY;let ticking=false;const onScroll=()=>{if(ticking)return;ticking=true;requestAnimationFrame(()=>{const y=window.scrollY;const d=y-last;if(y<160)setHidden(false);else if(d>6)setHidden(true);else if(d<-6)setHidden(false);last=y;ticking=false;});};window.addEventListener(\"scroll\",onScroll,{passive:true});return()=>window.removeEventListener(\"scroll\",onScroll);},[]);return /*#__PURE__*/_jsx(Component,{...props,onFocusCapture:e=>{setHidden(false);props.onFocusCapture?.(e);},style:{...props.style,transform:hidden?\"translateY(-100%)\":\"translateY(0)\",transition:reduced()?\"none\":\"transform .35s cubic-bezier(.22,1,.36,1)\"}});};}// Active nav: apply to the header's links frame. The link to the current page gets a red tab\n// underneath (the timing-tower motif) and aria-current=\"page\". Framer already marks current links\n// with data-framer-page-link-current; the pathname check is the fallback.\nconst NAV_CSS=`[data-gsrc-nav] a{position:relative}\r\n[data-gsrc-nav] a[aria-current=\"page\"]::after,[data-gsrc-nav] a[data-framer-page-link-current]::after{content:\"\";position:absolute;left:0;right:0;bottom:-8px;height:3px;border-radius:2px;background:var(--token-610260a3-7adf-4aed-a65b-f226ce3a949f,#FF2727)}`;export function withActiveNav(Component){return props=>{React.useEffect(()=>{const here=window.location.pathname.replace(/\\/$/,\"\")||\"/\";document.querySelectorAll(\"[data-gsrc-nav] a[href]\").forEach(a=>{const href=(a.getAttribute(\"href\")||\"\").replace(/^\\.\\//,\"/\").split(\"#\")[0].replace(/\\/$/,\"\");if(!href||href.startsWith(\"http\")||href.startsWith(\"mailto\"))return;const path=href.startsWith(\"/\")?href:\"/\"+href;if(path!==\"/\"&&(here===path||here.startsWith(path+\"/\")))a.setAttribute(\"aria-current\",\"page\");});},[]);return /*#__PURE__*/_jsxs(_Fragment,{children:[/*#__PURE__*/_jsx(\"style\",{dangerouslySetInnerHTML:{__html:String(NAV_CSS).replace(/<\\//g,\"<\\\\/\")}}),/*#__PURE__*/_jsx(Component,{...props,\"data-gsrc-nav\":\"\"})]});};}// Show after hero: apply to the phone action bar. Hidden until the visitor has scrolled past the\n// first screen, and hidden again over the footer so it never covers the footer links.\nexport function withShowAfterHero(Component){return props=>{const[show,setShow]=React.useState(false);React.useEffect(()=>{const onScroll=()=>{const y=window.scrollY;const nearEnd=y+window.innerHeight>document.documentElement.scrollHeight-420;setShow(y>window.innerHeight*.8&&!nearEnd);};onScroll();window.addEventListener(\"scroll\",onScroll,{passive:true});window.addEventListener(\"resize\",onScroll);return()=>{window.removeEventListener(\"scroll\",onScroll);window.removeEventListener(\"resize\",onScroll);};},[]);return /*#__PURE__*/_jsx(Component,{...props,style:{...props.style,transform:show?\"translateY(0)\":\"translateY(140%)\",// visibility (not aria-hidden) so a hidden bar's buttons can't be tabbed to.\nvisibility:show?\"visible\":\"hidden\",transition:reduced()?\"none\":show?\"transform .35s cubic-bezier(.22,1,.36,1), visibility 0s\":\"transform .35s cubic-bezier(.22,1,.36,1), visibility 0s linear .35s\"}});};}// withMagnetic: retired in the 2026-10-17 design pass (motion budget). Kept as a pass-through so the\n// overrides already applied on the canvas keep working; the old effect is magneticRetired above.\nexport function withMagnetic(Component){return Component;}// withTilt: retired in the 2026-10-17 design pass (motion budget). Kept as a pass-through so the\n// overrides already applied on the canvas keep working; the old effect is tiltRetired above.\nexport function withTilt(Component){return Component;}// withVelocitySkew: retired in the 2026-10-17 design pass (motion budget). Kept as a pass-through so the\n// overrides already applied on the canvas keep working; the old effect is velocitySkewRetired above.\nexport function withVelocitySkew(Component){return Component;}\nexport const __FramerMetadata__ = {\"exports\":{\"withHideOnScroll\":{\"type\":\"reactHoc\",\"name\":\"withHideOnScroll\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withHeroExit\":{\"type\":\"reactHoc\",\"name\":\"withHeroExit\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withMagnetic\":{\"type\":\"reactHoc\",\"name\":\"withMagnetic\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withStillOnReducedMotion\":{\"type\":\"reactHoc\",\"name\":\"withStillOnReducedMotion\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withTilt\":{\"type\":\"reactHoc\",\"name\":\"withTilt\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withActiveNav\":{\"type\":\"reactHoc\",\"name\":\"withActiveNav\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withDrift\":{\"type\":\"reactHoc\",\"name\":\"withDrift\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withShowAfterHero\":{\"type\":\"reactHoc\",\"name\":\"withShowAfterHero\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withVelocitySkew\":{\"type\":\"reactHoc\",\"name\":\"withVelocitySkew\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./GSRC_Motion.map"],"mappings":"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"}