{"version":3,"file":"HeaderAutoContrast.BRcB8FbL.mjs","names":["useRef","useCallback"],"sources":["https:/framerusercontent.com/modules/pYUIMf49QUUfXIN0SGsB/VWU66ByYXjdOazOWSwjg/HeaderAutoContrast.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{forwardRef,useCallback,useEffect,useRef}from\"react\";// HeaderAutoContrast\n// ------------------\n// Makes the Header's nav text adapt to whatever page section is\n// scrolled behind it — without touching the logo or the \"Get a Demo\"\n// button.\n//\n// How it works:\n//   1. On mount, walks the Header's DOM subtree and collects the\n//      text-carrying elements (<a>, <p>, <h*>, <span>) that are\n//      NOT inside any element with an image or a solid/gradient\n//      background. That excludes the logo (image) and the button\n//      (purple gradient) automatically.\n//   2. On scroll, samples the background at MULTIPLE points across\n//      the viewport ~96px below the top and majority-votes whether\n//      the section behind the header is light or dark.\n//        - If a <video> element covers the sample point (common\n//          for dark hero animations), the sample is treated as dark\n//          regardless of any CSS background on the transparent\n//          wrapper above it.\n//        - Otherwise the sampler walks up ancestors looking for a\n//          non-transparent `background-color` and reads luminance\n//          from that.\n//   3. If the section behind the header is light, it sets the\n//      collected nav elements' color to near-black; otherwise it\n//      restores the original (white) color.\n//\n// Attach via Framer UI:\n//   1. Select the Header instance.\n//   2. Right panel → Code → + New Override.\n//   3. File: HeaderAutoContrast · Override: withAutoContrast\nconst DARK_TEXT=\"rgb(11, 15, 26)\";const LUMINANCE_THRESHOLD=.55;const SAMPLE_Y=96// just below the 80px fixed header\n;// --- Helpers --------------------------------------------------------\nfunction hasSolidBgAncestor(el,stopAt){let cur=el;while(cur&&cur!==stopAt){const cs=getComputedStyle(cur);const bi=cs.backgroundImage;if(bi&&bi!==\"none\"&&bi.includes(\"gradient\"))return true;const bg=cs.backgroundColor;if(bg&&bg!==\"rgba(0, 0, 0, 0)\"&&bg!==\"transparent\"){const parts=bg.match(/[\\d.]+/g);if(parts){const alpha=parts.length>=4?parseFloat(parts[3]):1;if(alpha>.15)return true;}}cur=cur.parentElement;}return false;}function hasImageDescendant(el){if(el.tagName===\"IMG\")return true;if(el.querySelector(\"img\"))return true;const bi=getComputedStyle(el).backgroundImage;if(bi&&bi!==\"none\"&&!bi.includes(\"gradient\"))return true;const descendants=el.querySelectorAll(\"*\");for(let i=0;i<descendants.length;i++){const d=descendants[i];const dbi=getComputedStyle(d).backgroundImage;if(dbi&&dbi!==\"none\"&&!dbi.includes(\"gradient\"))return true;}return false;}function collectNavTexts(header){const out=new Set;// Prefer anchors: the nav links (Why USDN, Products, Company, Resources).\nconst anchors=header.querySelectorAll(\"a\");anchors.forEach(a=>{const text=(a.textContent||\"\").trim();if(!text)return;if(hasImageDescendant(a))return;// logo anchor\nif(hasSolidBgAncestor(a,header))return;// button\nout.add(a);});// Also collect text-bearing leaves that aren't covered by anchors.\nconst textEls=header.querySelectorAll(\"p, h1, h2, h3, h4, h5, h6, span\");textEls.forEach(el=>{const text=(el.textContent||\"\").trim();if(!text)return;if(el.querySelector(\"img, svg\"))return;if(hasSolidBgAncestor(el,header))return;// Skip if already covered by a collected anchor.\nlet covered=false;out.forEach(existing=>{if(existing.contains(el))covered=true;});if(covered)return;out.add(el);});return Array.from(out);}// Check whether any <video> on the page covers the given viewport point.\n// Framer hero animations (e.g. /our-team, /results) use <video> on top of\n// a transparent wrapper — walking DOM ancestors would otherwise land on\n// the white page root and mis-detect the section as \"light\".\nfunction pointIsOverVideo(x,y){const videos=document.querySelectorAll(\"video\");for(let i=0;i<videos.length;i++){const v=videos[i];const r=v.getBoundingClientRect();if(r.width>0&&r.height>0&&x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom){return true;}}return false;}function luminanceAt(x,y){// Dark-hero case: if a video is rendering at this point, treat as dark.\nif(pointIsOverVideo(x,y))return 0;const el=document.elementFromPoint(x,y);if(!el)return null;let cur=el;while(cur){const cs=getComputedStyle(cur);const bg=cs.backgroundColor;if(bg&&bg!==\"rgba(0, 0, 0, 0)\"&&bg!==\"transparent\"){const m=bg.match(/\\d+/g);if(m&&m.length>=3){const[r,g,b]=m.map(Number);return(.299*r+.587*g+.114*b)/255;}}cur=cur.parentElement;}return null;}// Sample luminance at several horizontal positions just below the header\n// and majority-vote. Single samples can be misleading if they land on a\n// card, icon, or absolutely-positioned decoration at that exact point.\nfunction detectIsLight(){const w=window.innerWidth;const positions=[.12,.3,.5,.7,.88];let lights=0;let darks=0;for(const frac of positions){const x=Math.max(1,Math.min(w-1,w*frac));const lum=luminanceAt(x,SAMPLE_Y);if(lum===null)continue;if(lum>LUMINANCE_THRESHOLD)lights++;else darks++;}if(lights+darks===0)return null;// Tie → light (prioritise readability on light sections; white text on\n// genuinely dark sections is already handled by the default style).\nreturn lights>=darks;}// --- Override -------------------------------------------------------\nexport function withAutoContrast(Component){return /*#__PURE__*/forwardRef((props,ref)=>{const innerRef=useRef(null);const setRef=useCallback(node=>{innerRef.current=node;if(typeof ref===\"function\")ref(node);else if(ref)ref.current=node;},[ref]);useEffect(()=>{let raf=0;let navTexts=[];let originals=[];let appliedLight=null;let attempts=0;const setup=()=>{attempts++;const root=innerRef.current;if(!root)return false;navTexts=collectNavTexts(root);if(navTexts.length===0)return false;originals=navTexts.map(el=>el.style.color);navTexts.forEach(el=>{el.style.transition=\"color 180ms ease\";});return true;};const apply=light=>{if(appliedLight===light)return;appliedLight=light;navTexts.forEach((el,i)=>{el.style.color=light?DARK_TEXT:originals[i]||\"\";});};const update=()=>{raf=0;if(navTexts.length===0){const ok=setup();if(!ok){if(attempts<20)setTimeout(update,200);return;}}const isLight=detectIsLight();if(isLight===null)return;apply(isLight);};const onScroll=()=>{if(!raf)raf=requestAnimationFrame(update);};const initial=setTimeout(update,50);window.addEventListener(\"scroll\",onScroll,{passive:true});window.addEventListener(\"resize\",onScroll);return()=>{clearTimeout(initial);if(raf)cancelAnimationFrame(raf);window.removeEventListener(\"scroll\",onScroll);window.removeEventListener(\"resize\",onScroll);// Restore originals\nnavTexts.forEach((el,i)=>{el.style.color=originals[i]||\"\";});};},[]);return /*#__PURE__*/_jsx(Component,{ref:setRef,...props});});}\nexport const __FramerMetadata__ = {\"exports\":{\"withAutoContrast\":{\"type\":\"reactHoc\",\"name\":\"withAutoContrast\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./HeaderAutoContrast.map"],"mappings":"qJAgCA,SAAS,EAAmB,EAAG,EAAO,CAAC,IAAI,EAAI,EAAG,KAAM,GAAK,IAAM,GAAO,CAAC,IAAM,EAAG,iBAAiB,EAAI,CAAO,EAAG,EAAG,gBAAgB,GAAG,GAAI,IAAK,QAAQ,EAAG,SAAS,WAAW,CAAC,MAAO,GAAK,IAAM,EAAG,EAAG,gBAAgB,GAAG,GAAI,IAAK,oBAAoB,IAAK,cAAc,CAAC,IAAM,EAAM,EAAG,MAAM,UAAU,CAAC,GAAG,IAAmB,EAAM,QAAQ,EAAE,WAAW,EAAM,GAAG,CAAC,GAAW,IAAI,MAAO,GAAO,EAAI,EAAI,cAAe,MAAO,GAAO,SAAS,EAAmB,EAAG,CAAmC,GAA/B,EAAG,UAAU,OAAqB,EAAG,cAAc,MAAM,CAAC,MAAO,GAAK,IAAM,EAAG,iBAAiB,EAAG,CAAC,gBAAgB,GAAG,GAAI,IAAK,QAAQ,CAAC,EAAG,SAAS,WAAW,CAAC,MAAO,GAAK,IAAM,EAAY,EAAG,iBAAiB,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAY,OAAO,IAAI,CAAC,IAAM,EAAE,EAAY,GAAS,EAAI,iBAAiB,EAAE,CAAC,gBAAgB,GAAG,GAAK,IAAM,QAAQ,CAAC,EAAI,SAAS,WAAW,CAAC,MAAO,GAAM,MAAO,GAAO,SAAS,EAAgB,EAAO,CAAC,IAAM,EAAI,IAAI,IAKxxB,OAJrG,EAAO,iBAAiB,IAAI,CAAS,QAAQ,GAAG,EAAa,EAAE,aAAa,IAAI,MAAM,GAAoB,EAAmB,EAAE,EAC1I,EAAmB,EAAE,EAAO,EAC/B,EAAI,IAAI,EAAE,GAAG,CACC,EAAO,iBAAiB,kCAAkC,CAAS,QAAQ,GAAI,CAA+F,GAApD,EAA9B,EAAG,aAAa,IAAI,MAAM,EAAoB,EAAG,cAAc,WAAW,EAAW,EAAmB,EAAG,EAAO,CAAC,OAC7N,IAAI,EAAQ,GAAM,EAAI,QAAQ,GAAU,CAAI,EAAS,SAAS,EAAG,GAAC,EAAQ,KAAO,CAAI,IAAe,EAAI,IAAI,EAAG,EAAG,CAAQ,MAAM,KAAK,EAAI,CAIzI,SAAS,EAAiB,EAAE,EAAE,CAAC,IAAM,EAAO,SAAS,iBAAiB,QAAQ,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,EAAO,OAAO,IAAI,CAAmB,IAAM,EAAhB,EAAO,GAAa,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,MAAM,GAAG,EAAE,OAAO,GAAG,EAAE,KAAK,GAAG,EAAE,OAAQ,MAAO,GAAO,MAAO,GAAO,SAAS,EAAY,EAAE,EAAE,CACjS,GAAG,EAAiB,EAAE,EAAE,CAAC,MAAO,GAAE,IAAM,EAAG,SAAS,iBAAiB,EAAE,EAAE,CAAC,GAAG,CAAC,EAAG,OAAO,KAAK,IAAI,EAAI,EAAG,KAAM,GAAI,CAAgC,IAAM,EAA5B,iBAAiB,EAAI,CAAa,gBAAgB,GAAG,GAAI,IAAK,oBAAoB,IAAK,cAAc,CAAC,IAAM,EAAE,EAAG,MAAM,OAAO,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAK,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,OAAO,CAAC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,KAAM,EAAI,EAAI,cAAe,OAAO,KAG1W,SAAS,GAAe,CAAC,IAAM,EAAE,EAAO,WAAiB,EAAU,CAAC,IAAI,GAAG,GAAG,GAAG,IAAI,CAAK,EAAO,EAAM,EAAM,EAAE,IAAI,IAAM,KAAQ,EAAU,CAA0C,IAAM,EAAI,EAA3C,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,EAAK,CAAC,CAAyB,EAAS,CAAI,IAAM,OAAiB,EAAI,EAAoB,IAAc,KAEvR,OAFmS,EAAO,IAAQ,EAAS,KAEpT,GAAQ,EACf,SAAgB,EAAiB,EAAU,CAAC,OAAoB,GAAY,EAAM,IAAM,CAAC,IAAM,EAASA,EAAO,KAAK,CAAO,EAAOC,EAAY,GAAM,CAAC,EAAS,QAAQ,EAAQ,OAAO,GAAM,WAAW,EAAI,EAAK,CAAS,IAAI,EAAI,QAAQ,IAAO,CAAC,EAAI,CAAC,CAChL,OADiL,MAAc,CAAC,IAAI,EAAI,EAAM,EAAS,EAAE,CAAK,EAAU,EAAE,CAAK,EAAa,KAAS,EAAS,EAAQ,MAAU,CAAC,IAAW,IAAM,EAAK,EAAS,QAA4M,MAAjM,CAAC,IAAkB,EAAS,EAAgB,EAAK,CAAI,EAAS,SAAS,GAAS,IAAM,EAAU,EAAS,IAAI,GAAI,EAAG,MAAM,MAAM,CAAC,EAAS,QAAQ,GAAI,CAAC,EAAG,MAAM,WAAW,oBAAqB,CAAQ,KAAa,EAAM,GAAO,CAAI,IAAe,IAAa,EAAa,EAAM,EAAS,SAAS,EAAG,IAAI,CAAC,EAAG,MAAM,MAAM,EAAM,EAAU,EAAU,IAAI,IAAK,GAAS,MAAW,CAAO,GAAN,EAAI,EAAK,EAAS,SAAS,GAAuB,CAAX,GAAO,CAAQ,CAAI,EAAS,IAAG,WAAW,EAAO,IAAI,CAAC,OAAS,IAAM,EAAQ,GAAe,CAAI,IAAU,MAAY,EAAM,EAAQ,EAAS,MAAa,CAAC,AAAQ,IAAI,sBAAsB,EAAO,EAAS,EAAQ,WAAW,EAAO,GAAG,CAAsG,OAArG,EAAO,iBAAiB,SAAS,EAAS,CAAC,QAAQ,GAAK,CAAC,CAAC,EAAO,iBAAiB,SAAS,EAAS,KAAW,CAAC,aAAa,EAAQ,CAAI,GAAI,qBAAqB,EAAI,CAAC,EAAO,oBAAoB,SAAS,EAAS,CAAC,EAAO,oBAAoB,SAAS,EAAS,CAC1xC,EAAS,SAAS,EAAG,IAAI,CAAC,EAAG,MAAM,MAAM,EAAU,IAAI,IAAK,GAAK,EAAE,CAAC,CAAqB,EAAK,EAAU,CAAC,IAAI,EAAO,GAAG,EAAM,CAAC,EAAG,4BAjDtF,IAA2D,CA8BhG,EAAU,kBAAwB,EAAoB,IAAU,EAAS"}