function useMarkdown(path){
const [state,setState]=React.useState({loading:true,md:'',error:null});
React.useEffect(()=>{let live=true;
fetch(path).then(r=>{if(!r.ok)throw new Error(r.status+'');return r.text();})
.then(md=>{if(live)setState({loading:false,md,error:null});})
.catch(e=>{if(live)setState({loading:false,md:'',error:String(e.message||e)});});
return()=>{live=false;};},[path]);
return state;
}

function Toc({md}){
const heads=window.mdHeadings(md);
const [active,setActive]=React.useState('');
React.useEffect(()=>{
if(!heads.length)return;
let raf=0;
const check=()=>{raf=0;let cur='';
heads.forEach(h=>{const el=document.getElementById(h.id);if(el&&el.getBoundingClientRect().top<160)cur=h.id;});
setActive(cur||heads[0].id);};
const onScroll=()=>{if(!raf)raf=requestAnimationFrame(check);};
check();window.addEventListener('scroll',onScroll,{passive:true});
return()=>{window.removeEventListener('scroll',onScroll);cancelAnimationFrame(raf);};},[md]);
if(heads.length<2)return null;
return <nav className="toc pin" aria-label="On this page">
<div className="eyebrow" style={{marginBottom:10}}>On this page</div>
{heads.map(h=><a key={h.id} href={'#'+h.id} className={active===h.id?'active':''}>{h.text}</a>)}
</nav>;
}

function MarkdownPage({path,active,eyebrow,title,lead,meta}){
const {loading,md,error}=useMarkdown(path);
return <Page active={active}>
<PageHead eyebrow={eyebrow} title={title} lead={lead}/>
{meta}
<section className="wrap sec split" style={{paddingTop:'clamp(16px,2vw,32px)'}}>
<Toc md={md}/>
<div>
{loading&&<p className="body">Loading…</p>}
{error&&<p className="body">This page's text couldn't be loaded ({error}). Try again, or write to <a className="linked" href={'mailto:'+window.EMAIL}>{window.EMAIL}</a>.</p>}
{!loading&&!error&&<div className="prose" dangerouslySetInnerHTML={{__html:window.mdToHtml(md.replace(/^\s*#\s+.*\n/,''))}}/>}
</div>
</section>
</Page>;
}
Object.assign(window,{MarkdownPage,useMarkdown,Toc});
