{"version":3,"file":"SmoothScrollControl.BAVsxiYa.mjs","names":["__esmMin","init_ssg_sandbox_shims","init_npm_react_18_3_1","p","c","init_jsx_runtime","ce","window","RenderTarget","addPropertyControls","init_framer_BWFVvmND","ControlType","startEngine","opts","smoothTouch","doc","target","current","lastAppliedY","rafId","running","lastTime","tau","smoothness","maxScroll","clamp","v","apply","rounded","y","step","time","dt","diff","alpha","startLoop","shouldLetNativeHandle","el","node","oy","atTop","atBottom","deltaY","onWheel","delta","wheelStrength","onKey","keyboard","tag","vh","handled","onScroll","onResize","SmoothScrollControl","props","onCanvas","enabled","badgeStyle","init_SmoothScrollControl"],"sources":["https:/framerusercontent.com/modules/3xQjmSVQlIuTzOXxuMdb/zfCn88Zdx6wUeNLLFBAn/SmoothScrollControl.js"],"sourcesContent":["// SmoothScrollControl.tsx — Custom smooth scroll for Cohestra\n// A self-contained, dependency-free smoothness controller.\n// It eases the REAL native scroll position (window.scrollTo), so position:sticky,\n// fixed headers and anchor jumps keep working — unlike transform-based smoothers.\n//\n// This is a standalone alternative to the marketplace \"Smooth Scroll\" component.\n// Both can live in the project at once; enable only ONE per page while testing.\nimport{jsx as _jsx,jsxs as _jsxs}from\"react/jsx-runtime\";import{useEffect}from\"react\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";// Starts the smoothing engine and returns a cleanup function.\nfunction startEngine(opts){const{smoothness,wheelStrength,keyboard,smoothTouch}=opts;// Respect user + device preferences — fall back to native scrolling.\nconst reduceMotion=window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;if(reduceMotion)return()=>{};const isTouch=window.matchMedia(\"(pointer: coarse)\").matches;if(isTouch&&!smoothTouch)return()=>{};const doc=document.documentElement;let target=window.scrollY;let current=window.scrollY;let lastAppliedY=window.scrollY// last position WE set — used to ignore our own scroll events\n;let rafId=0;let running=false;let lastTime=0;// \"smoothness\" (0.2–2) maps to a catch-up time constant in ms.\n// Bigger value = longer glide = smoother/heavier feel.\nconst tau=Math.max(45,smoothness*150);const maxScroll=()=>Math.max(0,doc.scrollHeight-window.innerHeight);const clamp=v=>Math.min(Math.max(v,0),maxScroll());const apply=y=>{const rounded=Math.round(y);window.scrollTo(0,rounded);lastAppliedY=rounded;};const step=time=>{if(!lastTime)lastTime=time;// Cap dt so returning to a backgrounded tab doesn't cause a jump.\nconst dt=Math.min(64,time-lastTime);lastTime=time;const diff=target-current;if(Math.abs(diff)<.4){current=target;apply(current);running=false;lastTime=0;return;}// Frame-rate independent exponential damping (works on 60/120/144Hz).\nconst alpha=1-Math.exp(-dt/tau);current+=diff*alpha;apply(current);rafId=requestAnimationFrame(step);};const startLoop=()=>{if(running)return;running=true;lastTime=0;rafId=requestAnimationFrame(step);};// Let genuinely-scrollable inner areas (modals, dropdowns, code blocks) keep\n// native scrolling. Also honors an explicit opt-out via [data-native-scroll].\nconst shouldLetNativeHandle=(node,deltaY)=>{let el=node;while(el&&el!==document.body&&el!==doc){if(el.nodeType===1){if(el.hasAttribute(\"data-native-scroll\"))return true;const s=getComputedStyle(el);const oy=s.overflowY;if((oy===\"auto\"||oy===\"scroll\")&&el.scrollHeight>el.clientHeight){const atTop=el.scrollTop<=0;const atBottom=el.scrollTop+el.clientHeight>=el.scrollHeight-1;if(deltaY<0&&!atTop)return true;if(deltaY>0&&!atBottom)return true;}}el=el.parentElement;}return false;};const onWheel=e=>{if(e.ctrlKey)return;// pinch-to-zoom\nif(shouldLetNativeHandle(e.target,e.deltaY))return;let delta=e.deltaY;if(e.deltaMode===1)delta*=16// deltaMode: lines\n;else if(e.deltaMode===2)delta*=window.innerHeight// deltaMode: pages\n;e.preventDefault();target=clamp(target+delta*wheelStrength);startLoop();};const onKey=e=>{if(!keyboard)return;const t=e.target;const tag=t?.tagName||\"\";if(/INPUT|TEXTAREA|SELECT/.test(tag)||t?.isContentEditable)return;const vh=window.innerHeight;let handled=true;switch(e.key){case\"ArrowDown\":target=clamp(target+90);break;case\"ArrowUp\":target=clamp(target-90);break;case\"PageDown\":target=clamp(target+vh*.9);break;case\"PageUp\":target=clamp(target-vh*.9);break;case\" \":target=clamp(target+(e.shiftKey?-1:1)*vh*.9);break;case\"Home\":target=clamp(0);break;case\"End\":target=clamp(maxScroll());break;default:handled=false;}if(handled){e.preventDefault();startLoop();}};// Adopt scroll changes we didn't cause (scrollbar drag, hash navigation, etc.).\n// Scroll events fire asynchronously, so we can't rely on a sync flag — instead we\n// compare against the last position we set. A meaningful difference means an\n// external source moved the page, so we re-sync to it.\nconst onScroll=()=>{if(Math.abs(window.scrollY-lastAppliedY)<=2)return;// our own scroll\ntarget=window.scrollY;current=window.scrollY;lastAppliedY=window.scrollY;};const onResize=()=>{target=clamp(target);};window.addEventListener(\"wheel\",onWheel,{passive:false});window.addEventListener(\"keydown\",onKey);window.addEventListener(\"scroll\",onScroll,{passive:true});window.addEventListener(\"resize\",onResize);return()=>{cancelAnimationFrame(rafId);window.removeEventListener(\"wheel\",onWheel);window.removeEventListener(\"keydown\",onKey);window.removeEventListener(\"scroll\",onScroll);window.removeEventListener(\"resize\",onResize);};}const badgeStyle={display:\"inline-flex\",alignItems:\"center\",gap:8,padding:\"8px 12px\",borderRadius:8,background:\"#0c0a09\",color:\"#fafaf9\",fontFamily:\"Inter, sans-serif\",fontSize:12,fontWeight:600,whiteSpace:\"nowrap\",border:\"1px solid #e11d0022\"};/**\n * Smooth Scroll (Custom)\n *\n * @framerIntrinsicWidth 220\n * @framerIntrinsicHeight 40\n *\n * @framerSupportedLayoutWidth any-prefer-fixed\n * @framerSupportedLayoutHeight any-prefer-fixed\n */export default function SmoothScrollControl(props){const{enabled=true,smoothness=.8,wheelStrength=1,keyboard=true,smoothTouch=false}=props;const onCanvas=RenderTarget.current()===RenderTarget.canvas;useEffect(()=>{if(onCanvas)return;if(!enabled)return;const cleanup=startEngine({smoothness,wheelStrength,keyboard,smoothTouch});return cleanup;},[onCanvas,enabled,smoothness,wheelStrength,keyboard,smoothTouch]);// Invisible on the live site; a small badge in the editor so it's selectable.\nif(onCanvas){return /*#__PURE__*/_jsx(\"div\",{style:badgeStyle,children:/*#__PURE__*/_jsxs(\"span\",{children:[\"⟳ Smooth Scroll (custom)\",enabled?\"\":\" \\xb7 off\"]})});}return null;}addPropertyControls(SmoothScrollControl,{enabled:{type:ControlType.Boolean,title:\"Enabled\",defaultValue:true,enabledTitle:\"On\",disabledTitle:\"Off\"},smoothness:{type:ControlType.Number,title:\"Smoothness\",defaultValue:.8,min:.2,max:2,step:.05,description:\"Higher = smoother, longer glide\"},wheelStrength:{type:ControlType.Number,title:\"Wheel\",defaultValue:1,min:.3,max:2.5,step:.05,description:\"Scroll speed multiplier\"},keyboard:{type:ControlType.Boolean,title:\"Keyboard\",defaultValue:true,enabledTitle:\"On\",disabledTitle:\"Off\"},smoothTouch:{type:ControlType.Boolean,title:\"Touch\",defaultValue:false,enabledTitle:\"Smooth\",disabledTitle:\"Native\",description:\"Smooth scrolling on touch devices\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"SmoothScrollControl\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutWidth\":\"any-prefer-fixed\",\"framerIntrinsicWidth\":\"220\",\"framerSupportedLayoutHeight\":\"any-prefer-fixed\",\"framerContractVersion\":\"1\",\"framerIntrinsicHeight\":\"40\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./SmoothScrollControl.map"],"mappings":"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"}