const E = ({children,block,style}) => React.createElement(block?'div':'span',{contentEditable:true,suppressContentEditableWarning:true,className:'cs-edit',style},children);
function distractors(qs, q) {
  const others = qs.filter(x=>x.id!==q.id).map(x=>x.answer);
  const picks = []; let i = q.id;
  while (picks.length<3 && others.length) { const c = others[(i*7)%others.length]; if(!picks.includes(c)&&c!==q.answer) picks.push(c); i++; if(i>200)break; }
  while (picks.length<3) picks.push('None of the above');
  const opts = [...picks]; opts.splice(q.id%4,0,q.answer);
  return opts;
}
function pickQuestions(made) {
  const D = window.CS_DATA;
  const isPuzzle = made.type==='crossword'||made.type==='wordsearch';
  const f = made.f;
  let pool = D.questions.filter(q =>
    (!isPuzzle || q.puzzle) &&
    (f.specialty==='All specialties' || q.specialty===f.specialty) &&
    (f.topic==='All topics' || q.topic===f.topic) &&
    (f.diff==='Any difficulty' || q.diff===f.diff) &&
    (f.qtype==='Any format' || q.qtype===f.qtype));
  if (pool.length<4) pool = D.questions.filter(q=>!isPuzzle||q.puzzle);
  const first = pool.filter(q=>made.picked.includes(q.id));
  const rest = pool.filter(q=>!made.picked.includes(q.id));
  return [...first,...rest].slice(0, Math.min(parseInt(f.count)||10, 10));
}
function PageFrame({ children, landscape }) {
  return <div className="cs-page" style={{width:landscape?760:620,minHeight:landscape?590:800,background:'#fff',boxShadow:'0 3px 16px rgba(12,12,29,.14)',margin:'0 auto',padding:'44px 48px',borderRadius:6,boxSizing:'border-box',fontFamily:'var(--sitm-font-body)',color:'var(--sitm-text-price)'}}>{children}</div>;
}
function SheetHeader({ title, subtitle, clean, accent }) {
  return <div style={{borderBottom:clean?'2px solid var(--sitm-text-price)':'3px solid '+(accent||'var(--sitm-teal)'),paddingBottom:12,marginBottom:20,display:'flex',alignItems:'center',gap:14}}>
    {!clean && <img src="./assets/sitm-logo.png" alt="" style={{width:44,height:44}}/>}
    <div style={{flex:1}}>
      <E block style={{fontFamily:clean?'var(--sitm-font-body)':'var(--sitm-font-heading)',fontWeight:clean?700:'normal',fontSize:21,color:clean?'var(--sitm-text-price)':'var(--sitm-navy)',lineHeight:1.15}}>{title}</E>
      <E block style={{fontSize:11,marginTop:3,color:'var(--sitm-text)'}}>{subtitle}</E>
    </div>
    <div style={{display:'flex',alignItems:'baseline',gap:7,fontSize:11,color:'var(--sitm-text)',whiteSpace:'nowrap'}}>Name<span style={{display:'inline-block',width:110,borderBottom:'1px solid rgba(62,71,97,.4)',height:13}}></span></div>
  </div>;
}
function WorksheetPage({ qs, tpl, answers, accent }) {
  const clean = tpl==='ws-clean'; const two = tpl==='ws-two';
  return <PageFrame>
    <SheetHeader clean={clean} accent={accent} title={answers?'Physics Practice Worksheet: Answer Key':'Physics Practice Worksheet'} subtitle="Sonographer in the Making"/>
    {answers
      ? <ol style={{margin:0,padding:'0 0 0 20px',display:'flex',flexDirection:'column',gap:10}}>
          {qs.map(q=><li key={q.id} style={{fontSize:12.5,lineHeight:1.5}}><E>{q.answer}</E></li>)}
        </ol>
      : <ol style={{margin:0,padding:'0 0 0 20px',display:two?'grid':'flex',gridTemplateColumns:'1fr 1fr',flexDirection:'column',gap:two?'14px 28px':16}}>
          {qs.map(q=><li key={q.id} style={{fontSize:12.5,lineHeight:1.5}}>
            <E block style={{fontWeight:500}}>{q.stem}</E>
            <div style={{display:'flex',flexDirection:'column',gap:3,marginTop:6}}>
              {distractors(qs,q).map((o,i)=><div key={i} style={{display:'flex',gap:8,alignItems:'baseline',fontSize:12}}>
                <span style={{fontWeight:600,color:clean?'var(--sitm-text-price)':'var(--sitm-teal-deep)'}}>{'ABCD'[i]}.</span><E>{o}</E></div>)}
            </div>
          </li>)}
        </ol>}
    <div style={{marginTop:26,paddingTop:10,borderTop:'1px solid var(--sitm-border)',fontSize:10,color:'var(--sitm-text)',display:'flex',justifyContent:'space-between'}}>
      <E>sonographerinthemaking.com</E><span>Page {answers?2:1}</span>
    </div>
  </PageFrame>;
}
function FlashcardsPage({ qs, backs, large }) {
  const per = large?4:8; const cards = qs.slice(0,per);
  return <PageFrame>
    <div style={{fontSize:10,color:'var(--sitm-text)',marginBottom:10,display:'flex',justifyContent:'space-between'}}><span>{backs?'Card backs. Print on the reverse side.':'Card fronts. Cut along the dashed lines.'}</span><span>Sonographer in the Making</span></div>
    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gridAutoRows:large?300:160,gap:0}}>
      {cards.map((q,i)=><div key={q.id} style={{border:'1.5px dashed rgba(62,71,97,.4)',padding:'16px 18px',display:'flex',flexDirection:'column',boxSizing:'border-box'}}>
        {backs ? <React.Fragment>
          <E block style={{fontFamily:'var(--sitm-font-heading)',fontSize:large?20:14.5,color:'var(--sitm-navy)',flex:1,display:'flex',alignItems:'center',justifyContent:'center',textAlign:'center'}}>{q.answer}</E>
          <E block style={{fontSize:8.5,color:'var(--sitm-text)',textAlign:'center'}}>{window.CS_DATA.citation}</E>
        </React.Fragment> : <React.Fragment>
          <div style={{height:5,background:'var(--sitm-teal)',margin:'-16px -18px 12px'}}></div>
          <E block style={{fontSize:large?14.5:11.5,lineHeight:1.5,flex:1,display:'flex',alignItems:'center',textAlign:'center',fontWeight:500}}>{q.stem}</E>
          <div style={{fontSize:8.5,color:'var(--sitm-text)',textAlign:'center'}}>{i+1}</div>
        </React.Fragment>}
      </div>)}
    </div>
  </PageFrame>;
}
function BadgePage({ qs, horiz }) {
  const rows = qs.slice(0,6);
  const card = (back) => <div style={{width:horiz?300:200,height:horiz?200:300,border:'1px solid rgba(62,71,97,.4)',background:'#fff',padding:'14px 16px',boxSizing:'border-box',position:'relative'}}>
    <div style={{width:9,height:9,borderRadius:'50%',border:'2px solid rgba(62,71,97,.45)',position:'absolute',top:7,left:horiz?7:'50%',transform:horiz?'none':'translateX(-50%)'}}></div>
    <E block style={{fontFamily:'var(--sitm-font-heading)',fontSize:13,color:'var(--sitm-navy)',margin:'12px 0 8px',textAlign:'center'}}>{back?'Physics quick reference, back':'Physics quick reference'}</E>
    <div style={{display:'flex',flexDirection:'column',gap:5}}>
      {(back?rows.slice(3):rows.slice(0,3)).map(q=><div key={q.id} style={{fontSize:9.5,lineHeight:1.4,borderBottom:'1px solid var(--sitm-border)',paddingBottom:4}}>
        <E style={{fontWeight:600,color:'var(--sitm-teal-deep)'}}>{q.answer}</E><br/><E>{q.stem}</E>
      </div>)}
    </div>
  </div>;
  return <PageFrame>
    <div style={{fontSize:10,color:'var(--sitm-text)',marginBottom:14}}>Badge cards. Cut out and laminate. Front and back below.</div>
    <div style={{display:'flex',gap:22,justifyContent:'center',flexWrap:'wrap',paddingTop:10}}>{card(false)}{card(true)}</div>
  </PageFrame>;
}
function QuizPage({ qs }) {
  const [answers,setAnswers] = React.useState({});
  const [checked,setChecked] = React.useState(false);
  const score = qs.filter(q=>answers[q.id]===q.answer).length;
  return <div style={{width:640,margin:'0 auto',background:'#fff',boxShadow:'0 3px 16px rgba(12,12,29,.14)',fontFamily:'var(--sitm-font-body)',borderRadius:10,overflow:'hidden'}}>
    <div style={{background:'var(--sitm-navy)',color:'#fff',padding:'22px 30px',display:'flex',alignItems:'center',gap:14}}>
      <img src="./assets/sitm-logo.png" alt="" style={{width:44,height:44}}/>
      <div>
        <E block style={{fontFamily:'var(--sitm-font-heading)',fontSize:20}}>Physics Practice Quiz</E>
        <E block style={{fontSize:11.5,opacity:.85,marginTop:2}}>Tap an answer for each question, then check how you did.</E>
      </div>
    </div>
    <div style={{padding:'22px 30px',display:'flex',flexDirection:'column',gap:20}}>
      {qs.map((q,qi)=><div key={q.id}>
        <E block style={{fontSize:13.5,fontWeight:600,color:'var(--sitm-text-price)',marginBottom:8}}>{(qi+1)+'. '+q.stem}</E>
        <div style={{display:'flex',flexDirection:'column',gap:6}}>
          {distractors(qs,q).map((o,i)=>{ const sel = answers[q.id]===o; const right = checked && o===q.answer; const wrong = checked && sel && o!==q.answer;
            return <button key={i} onClick={()=>!checked&&setAnswers({...answers,[q.id]:o})}
              style={{fontFamily:'var(--sitm-font-body)',fontSize:12.5,textAlign:'left',padding:'9px 13px',cursor:checked?'default':'pointer',display:'flex',gap:9,alignItems:'center',borderRadius:8,
                border:'1px solid '+(right?'var(--sitm-teal-deep)':wrong?'var(--sitm-sale-text)':sel?'var(--sitm-teal)':'var(--sitm-border)'),
                background:right?'rgba(97,189,183,.15)':wrong?'rgba(194,0,0,.06)':sel?'rgba(97,189,183,.1)':'#fff',color:'var(--sitm-text)'}}>
              <span style={{width:15,height:15,flex:'none',borderRadius:'50%',border:'2px solid '+(sel||right?'var(--sitm-teal)':'rgba(62,71,97,.35)'),background:sel?'var(--sitm-teal)':'transparent'}}></span>
              {o}{right && <span style={{marginLeft:'auto',color:'var(--sitm-teal-deep)'}}><Icon name="check" size={14} stroke={3}/></span>}
            </button>;})}
        </div>
      </div>)}
      <div style={{display:'flex',alignItems:'center',gap:14,paddingTop:6}}>
        <Btn onClick={()=>setChecked(true)} disabled={checked}>Check my answers</Btn>
        {checked && <span style={{fontSize:14,fontWeight:600,color:'var(--sitm-navy)'}}>{score} of {qs.length} right{score===qs.length?'. Perfect.':''}</span>}
        {checked && <Btn kind="ghost" size="sm" onClick={()=>{setChecked(false);setAnswers({});}}>Try again</Btn>}
      </div>
    </div>
  </div>;
}
function letterGrid(words, size) {
  const g = Array.from({length:size},(_,r)=>Array.from({length:size},(_,c)=>String.fromCharCode(65+((r*7+c*13)%26))));
  const placed = [];
  words.forEach((w,i)=>{ const row = 1+i*2; if(row<size && w.length<=size-1){ for(let j=0;j<w.length;j++) g[row][1+j]=w[j]; placed.push({row,col:1,len:w.length}); } });
  return {g,placed};
}
function WordSearchPage({ qs, solution }) {
  const words = qs.map(q=>q.answer.toUpperCase().replace(/[^A-Z]/g,'')).filter(w=>w.length>=3&&w.length<=14).slice(0,6);
  const {g,placed} = letterGrid(words,14);
  return <PageFrame>
    <SheetHeader title="Physics Word Search" subtitle="Find every answer word in the grid"/>
    <div style={{display:'flex',gap:24}}>
      <div style={{display:'grid',gridTemplateColumns:'repeat(14,26px)',border:'1.5px solid var(--sitm-navy)'}}>
        {g.map((row,r)=>row.map((ch,c)=>{ const hot = solution && placed.some(p=>p.row===r&&c>=p.col&&c<p.col+p.len);
          return <div key={r+'-'+c} style={{width:26,height:26,display:'flex',alignItems:'center',justifyContent:'center',fontSize:12,fontWeight:600,color:'var(--sitm-text-price)',background:hot?'rgba(97,189,183,.4)':'transparent'}}>{ch}</div>;}))}
      </div>
      <div style={{flex:1}}>
        <div style={{fontSize:12,fontWeight:600,textTransform:'uppercase',letterSpacing:'0.06em',color:'var(--sitm-teal-deep)',marginBottom:8}}>{solution?'Solution':'Find these'}</div>
        <div style={{display:'flex',flexDirection:'column',gap:6}}>
          {words.map(w=><E key={w} block style={{fontSize:12.5,fontWeight:500}}>{w}</E>)}
        </div>
      </div>
    </div>
  </PageFrame>;
}
function CrosswordPage({ qs, solution }) {
  const words = qs.filter(q=>q.puzzle).slice(0,5);
  const size = 13;
  return <PageFrame>
    <SheetHeader title="Physics Crossword" subtitle="Every answer comes from your question bank"/>
    <div style={{display:'flex',gap:24}}>
      <div style={{display:'grid',gridTemplateColumns:'repeat('+size+',26px)',border:'1.5px solid var(--sitm-navy)'}}>
        {Array.from({length:size*size}).map((_,i)=>{ const r=Math.floor(i/size), c=i%size;
          const onWord = words.some((w,wi)=> r===1+wi*2 && c>=1 && c<1+Math.min(w.answer.replace(/[^A-Za-z]/g,'').length,11));
          const wi = words.findIndex((w,x)=> r===1+x*2 && c===1);
          const ch = (()=>{ const w = words.find((w,x)=> r===1+x*2 && c>=1 && c<1+Math.min(w.answer.replace(/[^A-Za-z]/g,'').length,11)); if(!w) return ''; return w.answer.toUpperCase().replace(/[^A-Z]/g,'')[c-1]||''; })();
          return <div key={i} style={{width:26,height:26,boxSizing:'border-box',border:'0.5px solid rgba(62,71,97,.35)',position:'relative',display:'flex',alignItems:'center',justifyContent:'center',
            background:onWord?'#fff':'var(--sitm-navy)',fontSize:11.5,fontWeight:600,color:'var(--sitm-text-price)'}}>
            {wi>=0 && <span style={{position:'absolute',top:1,left:2,fontSize:7,fontWeight:600,color:'var(--sitm-teal-deep)'}}>{wi+1}</span>}
            {solution && onWord ? ch : ''}
          </div>;})}
      </div>
      <div style={{flex:1}}>
        <div style={{fontSize:12,fontWeight:600,textTransform:'uppercase',letterSpacing:'0.06em',color:'var(--sitm-teal-deep)',marginBottom:8}}>Across</div>
        <ol style={{margin:0,padding:'0 0 0 18px',display:'flex',flexDirection:'column',gap:8}}>
          {words.map(w=><li key={w.id} style={{fontSize:12,lineHeight:1.5}}><E>{w.stem}</E></li>)}
        </ol>
      </div>
    </div>
  </PageFrame>;
}
function PdfDocPage({ name, accent }) {
  return <PageFrame>
    <SheetHeader title={name || 'The Ultimate Physics Study Guide'} subtitle="Sonographer in the Making" accent={accent}/>
    <E block style={{fontFamily:'var(--sitm-font-heading)',fontSize:15,color:accent||'var(--sitm-teal-deep)',marginBottom:10}}>Chapter 2: Sound</E>
    <E block style={{fontSize:12.5,lineHeight:1.7,marginBottom:12}}>Sound is a mechanical, longitudinal wave. It carries energy through a medium by compressing and expanding the particles in its path, which means it cannot travel through a vacuum.</E>
    <E block style={{fontSize:12.5,lineHeight:1.7,marginBottom:12}}>Frequency is the number of cycles per second, measured in hertz. Sonographers control some acoustic parameters, while others are determined only by the medium.</E>
    <div style={{background:'rgba(97,189,183,.1)',borderLeft:'3px solid '+(accent||'var(--sitm-teal)'),padding:'10px 14px',marginBottom:12,borderRadius:'0 8px 8px 0'}}>
      <E block style={{fontSize:12,lineHeight:1.6,fontWeight:500}}>Remember: propagation speed in soft tissue is 1540 m/s. It depends on the medium, never on the sonographer.</E>
    </div>
    <E block style={{fontSize:12.5,lineHeight:1.7}}>Period and frequency are reciprocals. As frequency goes up, period goes down. If you know one, you can always find the other.</E>
    <div style={{marginTop:26,paddingTop:10,borderTop:'1px solid var(--sitm-border)',fontSize:10,color:'var(--sitm-text)',display:'flex',justifyContent:'space-between'}}>
      <E>sonographerinthemaking.com</E><span>Page 1</span>
    </div>
  </PageFrame>;
}
function EditorPage({ payload, go, toast, elements, onSaveElement, cats, rules, shortcut, collections, onSaveFile }) {
  const D = window.CS_DATA;
  const made = payload && payload.made;
  const pdfDoc = payload && payload.pdfDoc;
  const isPdf = payload && (payload.pdfName || payload.pdfUpload || (pdfDoc && pdfDoc.format==='Page PDF'));
  const fromFile = payload && payload.fromFile;
  const type = made ? made.type
    : pdfDoc ? ({'Page PDF':'pdf','Flashcards':'flashcards','Badge cards':'badges'})[pdfDoc.format]||'pdf'
    : fromFile ? ({'Worksheet':'worksheet','Flashcards':'flashcards','Interactive quiz':'quiz','Word search':'wordsearch'})[fromFile.type]||'worksheet' : 'pdf';
  const docSubject = pdfDoc ? pdfDoc.subject : made ? made.f.specialty : 'Physics';
  const collMatch = (collections||[]).find(c=>c.name===docSubject || (docSubject==='All specialties'&&false));
  const accent = collMatch ? collMatch.color : null;
  const t = D.contentTypes.find(c=>c.id===type);
  const qs = made ? pickQuestions(made) : D.questions.slice(0,8);
  const isHtml = type==='quiz';
  const pages = isPdf ? ['Page 1'] : ({ worksheet:['Questions','Answer key'], flashcards:['Card fronts','Card backs'], badges:['Badge cards'], quiz:['Quiz'], crossword:['Puzzle','Solution'], wordsearch:['Puzzle','Solution'] })[type] || ['Page 1'];
  const [page,setPage] = React.useState(0);
  const [saved,setSaved] = React.useState(false);
  const [tab,setTab] = React.useState('pages');
  const [objects,setObjects] = React.useState([]);
  const [selId,setSelId] = React.useState(null);
  const [editingId,setEditingId] = React.useState(null);
  const [saveElOpen,setSaveElOpen] = React.useState(false);
  const [hasTextSel,setHasTextSel] = React.useState(false);
  const sel = objects.find(o=>o.id===selId) || null;
  const history = React.useRef([]);
  const prevObjs = React.useRef(objects);
  const skipHist = React.useRef(false);
  const lastPush = React.useRef(0);
  React.useEffect(()=>{
    if (objects !== prevObjs.current) {
      if (skipHist.current) skipHist.current = false;
      else { const now = Date.now();
        if (now - lastPush.current > 350) { history.current.push(prevObjs.current); if (history.current.length > 60) history.current.shift(); }
        lastPush.current = now; }
      prevObjs.current = objects;
    }
  },[objects]);
  const undo = ()=>{ const prev = history.current.pop();
    if (prev) { skipHist.current = true; setObjects(prev); setSelId(null); setEditingId(null); }
    else toast('Nothing to undo yet.'); };
  const spawn = (p,extra)=>{ const id = Date.now()+Math.random();
    setObjects(o=>[...o,{ id, page, x:60+(o.length%5)*28, y:70+(o.length%5)*28, z:o.length, opacity:100, ...extra }]); setSelId(id); };
  const placeEl = (el)=> el.obj
    ? spawn(0,{ ...el.obj, type:el.obj.type })
    : spawn(0,{ type:'element', kind:el.kind, w:170, h:90 });
  const placeShape = (shape)=> spawn(0,{ type:'shape', shape, fill:'#61bdb7', w: shape==='line'?200:120, h: shape==='line'?8:shape==='rect'||shape==='rounded'?80:110 });
  const placeText = (preset)=> spawn(0, preset==='heading' ? { type:'text', text:'Add a heading', font:'Tilt Warp', size:28, color:'#242253', w:280, h:44 }
    : preset==='sub' ? { type:'text', text:'Add a subheading', font:'Poppins', size:18, bold:true, color:'#3e4761', w:240, h:34 }
    : { type:'text', text:'Add a little body text', font:'Poppins', size:13, color:'#3e4761', w:220, h:30 });
  const changeObj = (id,patch)=> setObjects(o=>o.map(x=>x.id===id?{...x,...patch}:x));
  const layerObj = (id,dir)=> setObjects(o=>{ const i=o.findIndex(x=>x.id===id); const j=i+dir; if(j<0||j>=o.length) return o;
    const c=[...o]; const [it]=c.splice(i,1); c.splice(j,0,it); return c.map((x,k)=>({...x,z:k})); });
  const dupObj = (id)=>{ const src=objects.find(x=>x.id===id); if(!src) return; const nid=Date.now()+Math.random();
    setObjects(o=>[...o,{...src,id:nid,x:src.x+18,y:src.y+18,z:o.length}]); setSelId(nid); };
  const nudge = (dx,dy)=>{ if(!selId) return false; setObjects(o=>o.map(x=>x.id===selId?{...x,x:x.x+dx,y:x.y+dy}:x)); return true; };
  const delObj = (id)=>{ setObjects(o=>o.filter(x=>x.id!==id)); setSelId(null); setEditingId(null); };
  const selectObj = (id)=>{ setSelId(id); if (id!==editingId) setEditingId(null); };
  const execText = (cmd,val)=>{ try { document.execCommand('styleWithCSS',false,true); document.execCommand(cmd,false,val); } catch(e){} };
  React.useEffect(()=>{
    const onSel = ()=>{ const s = window.getSelection();
      setHasTextSel(!!(s && !s.isCollapsed && s.anchorNode && s.anchorNode.parentElement && s.anchorNode.parentElement.closest('.cs-edit'))); };
    const inText = ()=>{ const a=document.activeElement; return a && (a.isContentEditable || a.tagName==='INPUT' || a.tagName==='TEXTAREA'); };
    const onKey = (e)=>{
      if(e.key==='Escape'){ setEditingId(null); setSelId(null); }
      if((e.ctrlKey||e.metaKey) && !e.shiftKey && (e.key==='z'||e.key==='Z')){ if(!inText()){ e.preventDefault(); undo(); } return; }
      if(selId && !inText()){
        const step = e.shiftKey ? 10 : 1;
        if(e.key==='ArrowLeft'){ e.preventDefault(); nudge(-step,0); }
        if(e.key==='ArrowRight'){ e.preventDefault(); nudge(step,0); }
        if(e.key==='ArrowUp'){ e.preventDefault(); nudge(0,-step); }
        if(e.key==='ArrowDown'){ e.preventDefault(); nudge(0,step); }
      }
      if((e.key==='Delete'||e.key==='Backspace') && selId && !inText()){ e.preventDefault(); delObj(selId); } };
    const onKeyUp = (e)=>{ if (e.key===' ' || [',','.','!','?',';',':','Enter'].includes(e.key)) {
      const t = e.target; const root = t && t.closest ? t.closest('.cs-edit') : null;
      if (root && window.csWordStyle) csWordStyle.applyRules(root, rules||[], { collection: docSubject }); } };
    const onKeyDownCapture = (e)=>{ const a=document.activeElement;
      if (a && a.isContentEditable && window.csWordStyle) csWordStyle.handleUndoKey(e, shortcut||'Backspace'); };
    document.addEventListener('selectionchange',onSel); window.addEventListener('keydown',onKey);
    document.addEventListener('keyup',onKeyUp,true); document.addEventListener('keydown',onKeyDownCapture,true);
    return ()=>{ document.removeEventListener('selectionchange',onSel); window.removeEventListener('keydown',onKey);
      document.removeEventListener('keyup',onKeyUp,true); document.removeEventListener('keydown',onKeyDownCapture,true); };
  },[selId, page, rules, shortcut]);
  const defaultName = pdfDoc ? pdfDoc.name : isPdf ? (payload.pdfName || 'New document') : fromFile ? fromFile.name : ({ worksheet:'Physics practice worksheet', flashcards:'Physics flashcards', badges:'Physics badge cards', quiz:'Physics quiz', crossword:'Physics crossword', wordsearch:'Physics word search' })[type];
  const tplId = made ? made.template : 'ws-classic';
  const canvas = () => {
    if (isPdf) return <PdfDocPage name={pdfDoc ? pdfDoc.name : payload.pdfName} accent={accent}/>;
    if (type==='worksheet') return <WorksheetPage qs={qs} tpl={tplId} answers={page===1} accent={accent}/>;
    if (type==='flashcards') return <FlashcardsPage qs={qs} backs={page===1} large={tplId==='fc-large'}/>;
    if (type==='badges') return <BadgePage qs={qs} horiz={tplId==='badge-horiz'}/>;
    if (type==='quiz') return <QuizPage qs={qs.slice(0,4)}/>;
    if (type==='crossword') return <CrosswordPage qs={qs} solution={page===1}/>;
    if (type==='wordsearch') return <WordSearchPage qs={qs} solution={page===1}/>;
    return <PdfDocPage/>;
  };
  return <div style={{position:'fixed',inset:0,top:64,display:'flex',flexDirection:'column',background:'var(--sitm-bg-dim)',zIndex:20}}>
    <div style={{background:'#fff',borderBottom:'1px solid var(--sitm-border)',padding:'0 24px',height:56,display:'flex',alignItems:'center',gap:14}}>
      <Btn kind="ghost" size="sm" icon="chevL" onClick={()=>go(made?'create':isPdf?'pdfpick':'files')}>Back</Btn>
      <E style={{fontFamily:'var(--sitm-font-heading)',fontSize:16,color:'var(--sitm-navy)',padding:'4px 8px'}}>{defaultName}</E>
      {!isPdf && !fromFile && <Chip>New, not saved yet</Chip>}
      <div style={{flex:1}}></div>
      <Btn kind="ghost" size="sm" icon="undo" onClick={undo}>Undo</Btn>
      <Btn kind="ghost" size="sm" onClick={()=>{setSaved(true);
        onSaveFile && onSaveFile({ name:defaultName, type: pdfDoc?pdfDoc.kind:({worksheet:'Worksheet',flashcards:'Flashcards',badges:'Badge cards',quiz:'Interactive quiz',crossword:'Crossword',wordsearch:'Word search',pdf:'Document'})[type]||'Document', out:isHtml?'HTML':'PDF', pages:pages.length+(pages.length===1?' page':' pages') });
        toast('Saved to My files.');}}>{saved?'Saved':'Save to My files'}</Btn>
      <Btn size="sm" icon="download" onClick={()=>toast(isHtml?'Your quiz is downloading as a web page.':'Your PDF is downloading.')}>{isHtml?'Save as web page':'Save as PDF'}</Btn>
    </div>
    <SelectionToolbar sel={sel} onChange={changeObj} onLayer={layerObj} onDuplicate={dupObj} onDelete={delObj} hasTextSel={hasTextSel} execText={execText}/>
    <div style={{flex:1,display:'flex',minHeight:0}}>
      <div style={{width:206,flex:'none',background:'#fff',borderRight:'1px solid var(--sitm-border)',padding:'14px 14px 16px',display:'flex',flexDirection:'column',gap:12,overflow:'hidden'}}>
        <div style={{display:'flex',gap:4,background:'var(--sitm-bg-dim)',padding:3,borderRadius:9,flex:'none'}}>
          {[['pages','Pages'],['elements','Elements'],['text','Text']].map(([id,label])=>
            <button key={id} onClick={()=>setTab(id)} style={{flex:1,fontFamily:'var(--sitm-font-body)',fontSize:11.5,fontWeight:600,padding:'6px 0',cursor:'pointer',border:'none',borderRadius:7,
              background:tab===id?'#fff':'transparent',color:tab===id?'var(--sitm-navy)':'var(--sitm-text)',boxShadow:tab===id?'0 1px 4px rgba(62,71,97,.15)':'none'}}>{label}</button>)}
        </div>
        {tab==='elements' && <ElementsPanel elements={elements} cats={cats} onPlace={(el)=>{placeEl(el);}}
          onPlaceShape={(s)=>{placeShape(s);}} onSaveNew={()=>setSaveElOpen(true)}/>}
        {tab==='text' && <div style={{display:'flex',flexDirection:'column',gap:8}}>
          <button onClick={()=>placeText('heading')} style={{fontFamily:'Tilt Warp',fontSize:19,color:'var(--sitm-navy)',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:10,padding:'13px 12px',cursor:'pointer',textAlign:'left'}}>Add a heading</button>
          <button onClick={()=>placeText('sub')} style={{fontFamily:'var(--sitm-font-body)',fontWeight:600,fontSize:14.5,color:'var(--sitm-text)',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:10,padding:'12px 12px',cursor:'pointer',textAlign:'left'}}>Add a subheading</button>
          <button onClick={()=>placeText('body')} style={{fontFamily:'var(--sitm-font-body)',fontSize:12.5,color:'var(--sitm-text)',background:'#fff',border:'1px solid var(--sitm-border)',borderRadius:10,padding:'11px 12px',cursor:'pointer',textAlign:'left'}}>Add a little body text</button>
          <div style={{fontSize:10.5,lineHeight:1.5,color:'var(--sitm-text)',marginTop:4}}>A text box lands on the page. Drag it anywhere, then use the toolbar above to change the font, size, and color.</div>
        </div>}
        {tab==='pages' && <div style={{display:'flex',flexDirection:'column',gap:12,overflow:'auto'}}>
        {pages.map((p,i)=><div key={p} onClick={()=>{setPage(i);setSelId(null);setEditingId(null);}} style={{cursor:'pointer'}}>
          <div style={{height:88,background:'var(--sitm-bg-light-dim)',border:page===i?'2px solid var(--sitm-teal)':'1px solid var(--sitm-border)',display:'flex',alignItems:'center',justifyContent:'center',borderRadius:8}}>
            <div style={{width:'55%',display:'flex',flexDirection:'column',gap:4}}>
              <div style={{width:'60%',height:4,background:'var(--sitm-teal)'}}></div>
              <div style={{width:'100%',height:2.5,background:'rgba(62,71,97,.25)'}}></div>
              <div style={{width:'85%',height:2.5,background:'rgba(62,71,97,.25)'}}></div>
              <div style={{width:'92%',height:2.5,background:'rgba(62,71,97,.25)'}}></div>
            </div>
          </div>
          <div style={{fontSize:11.5,fontWeight:page===i?600:500,color:page===i?'var(--sitm-navy)':'var(--sitm-text)',marginTop:5,textAlign:'center'}}>{p}</div>
        </div>)}
        {!isPdf && type!=='quiz' && <div style={{fontSize:11,lineHeight:1.5,color:'var(--sitm-text)',borderTop:'1px solid var(--sitm-border)',paddingTop:10}}>Both pages go into one PDF when you save.</div>}
        </div>}
      </div>
      <div style={{flex:1,overflow:'auto',padding:'26px 20px 60px'}} onMouseDown={()=>{setSelId(null);setEditingId(null);}}>
        <div style={{position:'relative',width:'fit-content',margin:'0 auto'}}>
          {canvas()}
          {objects.filter(o=>(o.page||0)===page).map(o=><CanvasObject key={o.id} o={o} selected={selId===o.id} editing={editingId===o.id} onSelect={selectObj} onChange={changeObj} onEdit={setEditingId}/>)}
        </div>
      </div>
    </div>
    <SaveElementModal open={saveElOpen} onClose={()=>setSaveElOpen(false)} cats={cats} hasSelection={!!sel}
      onSave={(name,cat)=>{ const obj={...sel}; delete obj.id;
        onSaveElement({ id:'e'+Date.now(), name, cat, kind:'custom', obj });
        setSaveElOpen(false); toast('Saved. '+name+' is in your Elements library.'); }}/>
  </div>;
}
Object.assign(window, { EditorPage });
