{"version":3,"file":"TableOfContents.eF6C77sd.mjs","names":["useState","useState"],"sources":["https:/framerusercontent.com/modules/0YDXppAbNnmfuQj16MPp/33GO6KfnrYBUjRSmbfLy/ReadingProgress.js","https:/framerusercontent.com/modules/ea9cAL08g6NZB8CKaX5d/msTeqigZPdUdcYJDgrvy/TableOfContents.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useState}from\"react\";import{createPortal}from\"react-dom\";import{addPropertyControls,ControlType,RenderTarget}from\"framer\";import{motion,useMotionValue,useReducedMotion,useSpring}from\"framer-motion\";// The first element with this id that's actually on screen. Framer can render\n// one copy per breakpoint and hide the others.\nfunction visibleById(id){for(const el of document.querySelectorAll(`[id=\"${CSS.escape(id)}\"]`)){if(el.getClientRects().length)return el;}return null;}// The nav: the outermost fixed or sticky element covering the top of the screen.\n// Only the page itself counts (#main on Framer sites), so Framer's editor bar, an\n// iframe pinned to the top for logged-in teammates, is never mistaken for the nav.\nfunction findNav(){const root=document.getElementById(\"main\")??document.body;for(const hit of document.elementsFromPoint(window.innerWidth/2,1)){if(hit.tagName===\"IFRAME\"||!root.contains(hit))continue;let nav=null;for(let el=hit;el&&el!==root&&el!==document.body;el=el.parentElement){const{position}=getComputedStyle(el);if(position===\"fixed\"||position===\"sticky\")nav=el;}if(nav)return nav;}return null;}// How far through the article the reader is: 0 when its top reaches the bottom\n// of the nav, 1 when its bottom reaches the bottom of the screen.\nfunction measure(target,nav){const vh=window.innerHeight;const navRect=nav?.getBoundingClientRect();const top=navRect?Math.min(Math.max(0,navRect.bottom),vh):0;const r=(target??document.documentElement).getBoundingClientRect();const distance=r.height-(vh-top);const progress=distance<=0?r.top<vh?1:0:Math.min(1,Math.max(0,(top-r.top)/distance));// A nav taller than half the screen is an open mobile menu: get out of its way.\nreturn{progress,hidden:Boolean(navRect&&navRect.height>vh*.5)};}/**\n * A reading-progress bar pinned to the bottom edge of the site's navigation.\n *\n * Place it anywhere on the article template with Position set to Absolute; it\n * attaches itself under the nav and never affects the layout. Bind Color to\n * the site's accent color style and set Article ID to the article body's ID.\n *\n * @framerSupportedLayoutWidth any\n * @framerSupportedLayoutHeight fixed\n * @framerIntrinsicWidth 400\n * @framerIntrinsicHeight 3\n */export default function ReadingProgress(props){const{targetId=\"article-body\",navId=\"\",thickness=3,color=\"rgb(207, 157, 78)\",trackColor=\"rgba(0, 0, 0, 0)\",zIndex=0,smooth=true}=props;const isCanvas=RenderTarget.current()===RenderTarget.canvas;const reduceMotion=useReducedMotion();const progress=useMotionValue(0);const eased=useSpring(progress,{stiffness:300,damping:40,restDelta:5e-4});const opacity=useMotionValue(1);// Where the bar is drawn: inside the nav, or <body> when the page has none.\nconst[host,setHost]=useState(null);useEffect(()=>{if(isCanvas)return;let target=null;let nav=null;let hostEl=null;let frame=0;let until=0;let lastFind=0;const ro=new ResizeObserver(()=>kick());const find=()=>{lastFind=performance.now();target=targetId?visibleById(targetId):null;nav=navId?visibleById(navId):findNav();const el=nav??document.body;if(el!==hostEl){hostEl=el;setHost({el,inNav:Boolean(nav)});}ro.disconnect();if(target)ro.observe(target);};const update=()=>{frame=0;// Framer can swap nodes on hydration or a breakpoint change: look again, at most once a second.\nconst stale=!nav?.isConnected||targetId&&!target?.isConnected;if(stale&&performance.now()-lastFind>1e3)find();const m=measure(target,nav);progress.set(m.progress);opacity.set(m.hidden?0:1);if(performance.now()<until)frame=requestAnimationFrame(update);};function kick(){until=performance.now()+600;if(!frame)frame=requestAnimationFrame(update);}const onResize=()=>{find();kick();};find();kick();// Capture catches scrolling inside any container, not just the window.\nwindow.addEventListener(\"scroll\",kick,{passive:true,capture:true});window.addEventListener(\"resize\",onResize,{passive:true});return()=>{cancelAnimationFrame(frame);ro.disconnect();window.removeEventListener(\"scroll\",kick,{capture:true});window.removeEventListener(\"resize\",onResize);};},[isCanvas,targetId,navId]);if(isCanvas){return /*#__PURE__*/_jsx(\"div\",{style:{width:\"100%\",height:thickness,background:trackColor,overflow:\"hidden\"},children:/*#__PURE__*/_jsx(\"div\",{style:{width:\"40%\",height:\"100%\",background:color}})});}if(!host)return null;// Inside the nav, the bar hangs off its bottom edge and moves with it. z-index -1\n// keeps it under the nav's own dropdowns while the nav's layer keeps it above the page.\nconst position=host.inNav?{position:\"absolute\",top:\"100%\",zIndex:zIndex||-1}:{position:\"fixed\",top:0,zIndex:zIndex||2147483e3};return /*#__PURE__*/createPortal(/*#__PURE__*/_jsx(motion.div,{\"aria-hidden\":true,\"data-reading-progress\":\"\",style:{...position,left:0,right:0,height:thickness,opacity,background:trackColor,pointerEvents:\"none\"},children:/*#__PURE__*/_jsx(motion.div,{style:{height:\"100%\",background:color,scaleX:smooth&&!reduceMotion?eased:progress,transformOrigin:\"0% 50%\"}})}),host.el);}ReadingProgress.displayName=\"Reading Progress\";addPropertyControls(ReadingProgress,{color:{type:ControlType.Color,title:\"Color\",defaultValue:\"rgb(207, 157, 78)\",description:\"Bind to the site's accent color style.\"},trackColor:{type:ControlType.Color,title:\"Track\",defaultValue:\"rgba(0, 0, 0, 0)\"},thickness:{type:ControlType.Number,title:\"Thickness\",defaultValue:3,min:1,max:12,step:1,unit:\"px\"},smooth:{type:ControlType.Boolean,title:\"Smooth\",defaultValue:true,description:\"Eases the fill. Always off for people who turn on reduced motion.\"},targetId:{type:ControlType.String,title:\"Article ID\",defaultValue:\"article-body\",description:\"The ID of the frame whose length the bar measures. Empty = the whole page.\"},navId:{type:ControlType.String,title:\"Nav ID\",defaultValue:\"\",placeholder:\"Found automatically\",description:\"Only if the bar attaches to the wrong element.\"},zIndex:{type:ControlType.Number,title:\"Z Index\",defaultValue:0,step:1,description:\"0 = automatic: under the nav's menus, above the page.\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"ReadingProgress\",\"slots\":[],\"annotations\":{\"framerSupportedLayoutWidth\":\"any\",\"framerIntrinsicHeight\":\"3\",\"framerContractVersion\":\"1\",\"framerIntrinsicWidth\":\"400\",\"framerSupportedLayoutHeight\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./ReadingProgress.map","import{jsx as _jsx}from\"react/jsx-runtime\";import{startTransition,useState,useEffect}from\"react\";import{addPropertyControls,ControlType}from\"framer\";export default function TableOfContents(props){const[headings,setHeadings]=useState([]);useEffect(()=>{// This function looks for your CMS content\nconst findContent=()=>{// Priority 1: The ID 'cms-content'\n// Priority 2: Any div that looks like a CMS collection\nif(typeof document===\"undefined\")return;const contentArea=document.getElementById(\"cms-content\")||document.querySelector(\"[data-framer-component-type='CMSContent']\")||document.querySelector(\".framer-cms-content\");if(contentArea){//Use below to include h2 and h3 in the table of contents, remove double slash to uncomment\nconst found=Array.from(contentArea.querySelectorAll(\"h2,h3\"));const filtered=found.filter(heading=>{if(heading.tagName===\"H2\")return props.showH2;if(heading.tagName===\"H3\")return props.showH3;return false;});//Use below to only include h2 and NOT h3 in the table of contents\n//const found = Array.from(contentArea.querySelectorAll(\"h2\"))\nconst data=filtered.map((h,i)=>{if(!h.id)h.id=`section-${i}`;return{id:h.id,text:h.textContent??\"\",level:h.tagName};});startTransition(()=>setHeadings(data));}};// Run once, then wait a split second for Framer to load the CMS data\nfindContent();const timer=setTimeout(findContent,500);return()=>clearTimeout(timer);},[props.showH2,props.showH3]);const style={display:\"flex\",flexDirection:\"column\",gap:\"12px\",padding:\"10px\",color:props.textColor,fontFamily:\"sans-serif\"};if(headings.length===0){return /*#__PURE__*/_jsx(\"div\",{style:style});}return /*#__PURE__*/_jsx(\"nav\",{style:style,children:headings.map(h=>/*#__PURE__*/_jsx(\"a\",{onClick:e=>{if(typeof document===\"undefined\"||typeof window===\"undefined\"){return;}e.preventDefault();const element=document.getElementById(h.id);if(element){const offset=110// Your header height + some breathing room\n    ;const bodyRect=document.body.getBoundingClientRect().top;const elementRect=element.getBoundingClientRect().top;const elementPosition=elementRect-bodyRect;const offsetPosition=elementPosition-offset;window.scrollTo({top:offsetPosition,behavior:\"smooth\"});}},href:`#${h.id}`,style:{marginLeft:h.level===\"H3\"?\"15px\":\"0px\",textDecoration:\"none\",color:\"inherit\",fontSize:h.level===\"H3\"?\"12px\":\"14px\",fontWeight:h.level===\"H2\"?600:\"normal\",opacity:.8},children:h.text},h.id))});}addPropertyControls(TableOfContents,{textColor:{type:ControlType.Color,defaultValue:\"#333\"},showH2:{type:ControlType.Boolean,title:\"Show H2 headings\",defaultValue:true},showH3:{type:ControlType.Boolean,title:\"Show H3 headings\",defaultValue:true}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"TableOfContents\",\"slots\":[],\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./TableOfContents.map"],"mappings":"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"}