/* ============================================================
   GAME MAKER — the no-code "step-card" maker (GAME-MAKER-MASTER-PLAN
   §3–4), styled to the claude.ai/design "Torchlit Maker" Build kit.

   The metaphor: a game is a STACK OF STEP-CARDS. Each card answers
   "what does everyone see? (👁️ public) / what's your secret? (🤫)"
   and "how do we move on? (⏲️ timer · 🗳️ vote · 👍 ready · 🎲 roll)".

   It is FUNCTIONAL: compileToGameDef() turns the wizard's data into a
   real GameDef that GameRuntime (runtime.jsx) runs through the same
   data-driven engine views — so "Try with bots" plays the in-progress
   game for real. Made games persist to localStorage + window.USER_GAMES
   and appear in the launcher next to the built-ins. No new transport,
   no build step — window.* globals, per the house architecture.
   ============================================================ */
const { useState: useS_mk, useEffect: useE_mk } = React;

/* ---------- built-in secret tables (emoji-led, per the maker brand) ---------- */
const MK_TABLES = {
  places: { id:'places', label:'Places', emoji:'🏖️', kind:'place', items:[
    { id:'casino',   name:'Casino',        emoji:'🎰', roles:['Dealer','High Roller','Bouncer','Bartender','Pit Boss'] },
    { id:'sub',      name:'Submarine',     emoji:'🚢', roles:['Captain','Sonar Tech','Cook','Navigator','Medic'] },
    { id:'castle',   name:'Castle',        emoji:'🏰', roles:['King','Knight','Jester','Cook','Guard'] },
    { id:'beach',    name:'Beach',         emoji:'🏖️', roles:['Lifeguard','Tourist','Vendor','Surfer','Photographer'] },
    { id:'station',  name:'Space Station', emoji:'🚀', roles:['Commander','Scientist','Engineer','Doctor','Tourist'] },
    { id:'circus',   name:'Circus',        emoji:'🎪', roles:['Ringmaster','Clown','Acrobat','Lion Tamer','Juggler'] },
    { id:'hospital', name:'Hospital',      emoji:'🏥', roles:['Surgeon','Nurse','Patient','Intern','Paramedic'] },
    { id:'studio',   name:'Movie Studio',  emoji:'🎬', roles:['Director','Star','Stunt Double','Camera','Extra'] }
  ]},
  words: { id:'words', label:'Words', emoji:'💬', kind:'word', items:[
    { id:'cat',name:'Cat',emoji:'🐱' },{ id:'dog',name:'Dog',emoji:'🐶' },{ id:'pizza',name:'Pizza',emoji:'🍕' },
    { id:'beach',name:'Beach',emoji:'🏖️' },{ id:'rocket',name:'Rocket',emoji:'🚀' },{ id:'ghost',name:'Ghost',emoji:'👻' },
    { id:'robot',name:'Robot',emoji:'🤖' },{ id:'dragon',name:'Dragon',emoji:'🐉' }
  ]},
  jobs: { id:'jobs', label:'Jobs', emoji:'🧰', kind:'job', items:[
    { id:'chef',name:'Chef',emoji:'👨‍🍳' },{ id:'pilot',name:'Pilot',emoji:'✈️' },{ id:'doctor',name:'Doctor',emoji:'🩺' },
    { id:'farmer',name:'Farmer',emoji:'🚜' },{ id:'spy',name:'Spy',emoji:'🕵️' },{ id:'artist',name:'Artist',emoji:'🎨' },
    { id:'sailor',name:'Sailor',emoji:'⚓' },{ id:'wizard',name:'Wizard',emoji:'🧙' }
  ]},
  animals: { id:'animals', label:'Animals', emoji:'🦊', kind:'animal', items:[
    { id:'fox',name:'Fox',emoji:'🦊' },{ id:'panda',name:'Panda',emoji:'🐼' },{ id:'frog',name:'Frog',emoji:'🐸' },
    { id:'owl',name:'Owl',emoji:'🦉' },{ id:'lion',name:'Lion',emoji:'🦁' },{ id:'whale',name:'Whale',emoji:'🐋' },
    { id:'bee',name:'Bee',emoji:'🐝' },{ id:'snake',name:'Snake',emoji:'🐍' }
  ]}
};

/* ---------- the content menu (maps each item → a ContentBlock kind) ---------- */
const MK_CONTENT = [
  { kind:'text',    emoji:'💬', label:'Message' },
  { kind:'timer',   emoji:'⏲️', label:'Timer' },
  { kind:'secret',  emoji:'🤫', label:'Secret card' },
  { kind:'list',    emoji:'📋', label:'List' },
  { kind:'vote',    emoji:'🗳️', label:'Vote' },
  { kind:'callvote',emoji:'⚖️', label:'Call a vote' },
  { kind:'guess',   emoji:'🔮', label:'Spy guess' },
  { kind:'dice',    emoji:'🎲', label:'Dice' },
  { kind:'ready',   emoji:'👍', label:'Ready button' }
];
const MK_ADVANCE = [['timer','⏲️','Timer'],['vote','🗳️','Vote'],['ready','👍','Ready'],['dice','🎲','Roll']];

/* a fresh working template (compiles to a playable Spyfall-like game) */
function mkDefaultData(){
  return {
    name: 'My spy game',
    table: 'shared', modPlays: false,
    secret: 'places', spies: 1,
    selStep: 0,
    steps: [
      { title:'Briefing', emoji:'📣', advance:'timer', secs:6,
        publicItems:[{kind:'text',emoji:'💬',label:'Check your phone!'},{kind:'timer',emoji:'⏲️',label:'Timer'}],
        secretItems:[{kind:'secret',emoji:'🤫',label:'Secret card'}] },
      { title:'Questions', emoji:'🗣️', advance:'timer', secs:120,
        publicItems:[{kind:'text',emoji:'💬',label:'Ask each other questions'},{kind:'timer',emoji:'⏲️',label:'Timer'},{kind:'list',emoji:'📋',label:'The list'}],
        secretItems:[{kind:'secret',emoji:'🤫',label:'Secret card'},{kind:'guess',emoji:'🔮',label:'Spy guess'},{kind:'callvote',emoji:'⚖️',label:'Call a vote'}] },
      { title:'Accuse', emoji:'🗳️', advance:'vote',
        publicItems:[{kind:'vote',emoji:'🗳️',label:'Vote'}],
        secretItems:[{kind:'vote',emoji:'🗳️',label:'Vote'}] }
    ],
    win: { who:'table', does:'votes the spy', then:'the table wins' }
  };
}

/* ============================================================
   COMPILER — wizard data → a runnable GameDef (gamedef.js shape)
   ============================================================ */
function mkBlock(item, tbl){
  switch(item.kind){
    case 'text':   return { t:'text', value:item.label||'', style:'cue' };
    case 'timer':  return { t:'timer' };
    case 'secret': return { t:'secret' };
    case 'list':   return { t:'list', from:tbl.id, label:'📋 '+(tbl.label||'The list') };
    case 'vote':   return { t:'vote' };
    case 'dice':   return { t:'dice', sides:6 };
    case 'ready':  return { t:'ready' };
    case 'callvote': return { t:'button', label:'⚖ Call a vote', choice:'callVote' };
    case 'guess':  return { t:'guess', role:'spy', from:tbl.id, setVar:'spyGuess', valueKey:'id', confirm:true, label:'Guess the '+tbl.kind };
    default: return null;
  }
}
function mkItems(items, tbl){ return (items||[]).map(it=>mkBlock(it,tbl)).filter(Boolean); }

function compileToGameDef(data){
  const tbl = MK_TABLES[data.secret] || MK_TABLES.places;
  const isPlace = tbl.kind==='place';
  const steps = (data.steps && data.steps.length) ? data.steps : mkDefaultData().steps;
  // the accuse/vote step is where a "Call a vote" jumps to
  const voteIdx = steps.findIndex(s=> s.advance==='vote');

  const phases = steps.map((s,i)=>{
    const isLast = i===steps.length-1;
    const nextId = isLast ? 'reveal' : ('s'+(i+1));
    const ph = { id:'s'+i, name:s.title||('Step '+(i+1)),
      audience:{ main:{show:mkItems(s.publicItems,tbl)}, players:{show:mkItems(s.secretItems,tbl)} }, next:[] };
    if(s.advance==='timer'){
      ph.duration = Math.max(2, s.secs||60);
      // only a timer that ENDS the game means "time ran out"; intermediate
      // timer advances just move to the next card.
      ph.next.push(nextId==='reveal'
        ? { when:{kind:'timer'}, toPhaseId:nextId, set:{ _timedOut:true } }
        : { when:{kind:'timer'}, toPhaseId:nextId });
    } else if(s.advance==='vote'){
      ph.block = { type:'vote', options:'players', prompt:'Who is the spy?', secret:true };
      ph.next.push({ when:{kind:'vote'}, toPhaseId:nextId });
      if(!ph.audience.main.show.some(b=>b.t==='vote')) ph.audience.main.show.push({t:'vote'});
      if(!ph.audience.players.show.some(b=>b.t==='vote')) ph.audience.players.show.push({t:'vote'});
    } else if(s.advance==='ready'){
      ph.next.push({ when:{kind:'ready'}, toPhaseId:nextId });
      if(!ph.audience.players.show.some(b=>b.t==='ready')) ph.audience.players.show.push({t:'ready'});
      if(!ph.audience.main.show.some(b=>b.t==='ready')) ph.audience.main.show.push({t:'ready'});
    } else if(s.advance==='dice'){
      ph.next.push({ when:{kind:'dice', min:1, max:99}, toPhaseId:nextId });
      if(!ph.audience.players.show.some(b=>b.t==='dice')) ph.audience.players.show.push({t:'dice',sides:6});
    }
    // a "Call a vote" button anywhere → a choice exit to the vote step
    if((s.secretItems||[]).some(it=>it.kind==='callvote') && voteIdx>=0 && voteIdx!==i){
      ph.next.push({ when:{kind:'choice', value:'callVote'}, toPhaseId:'s'+voteIdx });
    }
    return ph;
  });
  phases.push({ id:'reveal', name:'Reveal',
    audience:{ main:{show:[{t:'reveal'}]}, players:{show:[{t:'reveal'}]} }, next:[] });

  return {
    id: 'usergame-'+Date.now().toString(36)+Math.floor(Math.random()*900).toString(36),
    title: (data.name||'My game').trim().slice(0,40) || 'My game',
    kind: 'social', emoji: tbl.emoji || '🔨', maker: true,
    players: { min: Math.max(3, (Number(data.spies)||1)+2), max: 12 },
    needsModerator: data.table==='hosted',
    mainScreen: data.table==='phones' ? 'none' : 'optional',
    blurb: 'A game you made with the step-card maker.',
    setup: {
      tables: { [tbl.id]: tbl.items },
      pick: [{ id:'x', from:tbl.id }],
      assignRoles: { pool:[{ id:'spy', n:Math.max(1, Number(data.spies)||1) }], default:'civilian' },
      deal: {
        civilian: { title:'{x.name}', emoji:'{x.emoji}', tone:'civ',
          subtitle: isPlace ? 'You are here — blend in.' : ('Your secret '+tbl.kind+' — describe it, don’t say it.') },
        spy: { title:'Spy', emoji:'🕵️', tone:'spy', spy:true, subtitle:"You don't know the secret. Blend in!" }
      }
    },
    startPhaseId: 's0', endPhaseId: 'reveal',
    reveal: { facts: [ (isPlace?'The place was {x.name}':'The secret was {x.name}') ] },
    phases,
    // plain-language win step is illustrative; emit the standard hidden-role rule set
    winConditions: [
      { when:{kind:'voteResultRole', role:'spy', is:true},  outcome:{winner:'group', text:'The spy was caught — the table wins!'} },
      { when:{kind:'and', all:[{kind:'varSet',key:'spyGuess'},{kind:'varEquals',key:'spyGuess',value:'{x.id}'}]}, outcome:{winner:'spy', text:'The spy guessed it — spy wins!'} },
      { when:{kind:'and', all:[{kind:'varSet',key:'spyGuess'},{kind:'not',cond:{kind:'varEquals',key:'spyGuess',value:'{x.id}'}}]}, outcome:{winner:'group', text:'The spy guessed wrong — the table wins!'} },
      { when:{kind:'voteResultRole', role:'spy', is:false}, outcome:{winner:'spy', text:'Wrong vote — the spy escapes!'} },
      { when:{kind:'noKill'},                               outcome:{winner:'spy', text:'The vote was split — the spy escapes!'} },
      { when:{kind:'flag', key:'_timedOut'},                outcome:{winner:'spy', text:'Time ran out — the spy wins!'} }
    ]
  };
}

/* ---------- persistence: made games live on this device + in the launcher ---------- */
const MK_KEY = 'torchlit-usergames';
function loadUserGames(){ try{ return JSON.parse(localStorage.getItem(MK_KEY)||'[]'); }catch(_){ return []; } }
function saveUserGame(def){
  const list = loadUserGames().filter(g=> g.id!==def.id);
  list.unshift(def);
  try{ localStorage.setItem(MK_KEY, JSON.stringify(list.slice(0,30))); }catch(_){}
  window.USER_GAMES = list.slice(0,30);
  return def;
}
window.USER_GAMES = loadUserGames();
window.loadUserGames = loadUserGames;
window.compileToGameDef = compileToGameDef;

/* ============================================================
   MAKER UI — kit-styled controls (replicated; no design bundle)
   ============================================================ */
function MkPicture({ emoji, label, sublabel, tone='gold', selected, onClick }){
  return (
    <button type="button" className={`mk-pic tone-${tone} ${selected?'sel':''}`} onClick={onClick} aria-pressed={selected}>
      {selected && <span className="mk-pic-check" aria-hidden="true">✓</span>}
      <span className="mk-pic-emoji" aria-hidden="true">{emoji}</span>
      <span className="mk-pic-label">{label}</span>
      {sublabel && <span className="mk-pic-sub">{sublabel}</span>}
    </button>
  );
}
function MkStepper({ value, min=1, max=4, emoji, onChange }){
  const set=(v)=> onChange(Math.max(min,Math.min(max,v)));
  return (
    <div className="mk-stepper">
      <button className="mk-round" disabled={value<=min} onClick={()=>set(value-1)} aria-label="less">−</button>
      <span className="mk-stepper-n">{emoji && <span aria-hidden="true" style={{marginRight:6}}>{emoji}</span>}{value}</span>
      <button className="mk-round" disabled={value>=max} onClick={()=>set(value+1)} aria-label="more">+</button>
    </div>
  );
}
function MkToggle({ checked, onChange, label, emoji }){
  return (
    <label className="mk-toggle-wrap">
      <span className={`mk-toggle ${checked?'on':''}`} role="switch" aria-checked={checked} onClick={()=>onChange(!checked)}>
        <span className="mk-toggle-knob"/>
      </span>
      <span className="mk-toggle-label">{emoji && <span aria-hidden="true">{emoji}</span>} {label}</span>
    </label>
  );
}
/* the signature step-card (public/secret zones + "next when…") */
function MkStepCard({ index, step, selected, onClick }){
  const adv = { timer:['⏲️','Timer runs out'], vote:['🗳️','Everyone votes'], ready:['👍','Everyone taps Ready'], dice:['🎲','Someone rolls'] }[step.advance] || ['⏲️','Timer'];
  const Zone = ({ pub, items })=>(
    <div className="mk-zone">
      <div className={`mk-zone-h ${pub?'pub':'sec'}`}>{pub?'👁️ Everyone sees':'🤫 Your secret'}</div>
      <div className="mk-zone-items">
        {(!items||!items.length) && <span className="mk-zone-empty">—</span>}
        {(items||[]).map((it,i)=> <span key={i} className={`mk-item ${pub?'pub':'sec'}`}><span aria-hidden="true">{it.emoji}</span>{it.label}</span>)}
      </div>
    </div>
  );
  return (
    <div className={`mk-step ${selected?'sel':''}`} onClick={onClick}>
      <div className="mk-step-head">
        <span className="mk-step-n">{index+1}</span>
        <span className="mk-step-emoji" aria-hidden="true">{step.emoji}</span>
        <span className="mk-step-title">{step.title}</span>
        <span className="mk-step-grip" aria-hidden="true">⠿</span>
      </div>
      <div className="mk-step-zones"><Zone pub items={step.publicItems}/><span className="mk-step-div"/><Zone items={step.secretItems}/></div>
      <div className="mk-step-foot"><span className="mk-step-foot-lbl">Next when</span>
        <span className="mk-step-adv"><span aria-hidden="true">{adv[0]}</span>{adv[1]}</span></div>
    </div>
  );
}

/* ============================================================
   THE WIZARD
   ============================================================ */
const MK_STEPS = [
  { id:'table',  emoji:'🎲', label:'Table',      title:'How does everyone play?' },
  { id:'secret', emoji:'🤫', label:'Secret',     title:"What's the secret?" },
  { id:'steps',  emoji:'🃏', label:'Step-cards', title:'Build the step-card stack' },
  { id:'win',    emoji:'🏆', label:'Who wins',   title:'Who wins?' },
  { id:'bots',   emoji:'🤖', label:'Try it',     title:'Try it with bots' },
];

function MakerApp({ onClose }){
  const [i, setI] = useS_mk(0);
  const [data, setData] = useS_mk(mkDefaultData);
  const set = (patch)=> setData(d=>({ ...d, ...patch }));
  const pct = Math.round(((i+1)/MK_STEPS.length)*100);
  const last = i===MK_STEPS.length-1;

  const tryWithBots = ()=>{
    const def = compileToGameDef(data);
    const chk = window.GameDef.validate(window.GameDef.normalize(def));
    if(!chk.ok){ alert('This game isn’t playable yet:\n• '+chk.errors.join('\n• ')); return; }
    window.Game.clearBots(); window.Game.addBots(4);
    window.GameRuntime.start(def);
    onClose();
  };
  const publish = ()=>{
    const def = compileToGameDef(data);
    const chk = window.GameDef.validate(window.GameDef.normalize(def));
    if(!chk.ok){ alert('This game isn’t playable yet:\n• '+chk.errors.join('\n• ')); return; }
    saveUserGame(def);
    alert('🎉 Game made! "'+def.title+'" is now in your Party Games list — start it any time, or “Try 4 bots”.');
    onClose();
  };

  return (
    <div className="mk-overlay">
      <div className="mk-topbar">
        <span className="mk-brand-flame" aria-hidden="true">🔥</span>
        <span className="mk-brand">TORCHLIT</span><span className="mk-brand-tag">Maker · Build</span>
        <span style={{flex:1}}/>
        <span className="mk-title-readout">“{data.name}”</span>
        <button className="mk-x" onClick={onClose} aria-label="Close maker">✕</button>
      </div>

      <div className="mk-railwrap">
        <div className="mk-rail">
          {MK_STEPS.map((s,n)=>(
            <button key={s.id} className={`mk-rail-btn ${n===i?'on':''} ${n<i?'done':''}`} onClick={()=>setI(n)}>
              <span aria-hidden="true">{n<i?'✓':s.emoji}</span>{s.label}
            </button>
          ))}
        </div>
        <div className="mk-progress"><div className="mk-progress-fill" style={{width:pct+'%'}}/></div>
        <div className="mk-progress-lbl">{last?'Done — try it!':`${MK_STEPS.length-i-1} steps to try it`}</div>
      </div>

      <div className="mk-screen" key={i}>
        <h2 className="mk-screen-h"><span aria-hidden="true">{MK_STEPS[i].emoji}</span> {MK_STEPS[i].title}</h2>
        {i===0 && <MkTable data={data} set={set}/>}
        {i===1 && <MkSecret data={data} set={set}/>}
        {i===2 && <MkSteps data={data} set={set}/>}
        {i===3 && <MkWin data={data} set={set}/>}
        {i===4 && <MkTry data={data}/>}
      </div>

      <div className="mk-foot">
        <button className="mk-btn ghost" disabled={i===0} onClick={()=>setI(n=>Math.max(0,n-1))}>← Back</button>
        {!last
          ? <button className="mk-btn gold" onClick={()=>setI(n=>n+1)}>Continue →</button>
          : <div style={{display:'flex',gap:10}}>
              <button className="mk-btn" onClick={tryWithBots}>🤖 Try 4 bots</button>
              <button className="mk-btn gold" onClick={publish}>🎉 Make it!</button>
            </div>}
      </div>
    </div>
  );
}

/* ---- step 1: table ---- */
function MkTable({ data, set }){
  const presets=[
    {id:'shared',emoji:'📺',label:'Party',sub:'Shared screen + phones',tone:'gold'},
    {id:'phones',emoji:'📱',label:'Party',sub:'Phones only · no TV',tone:'teal'},
    {id:'hosted',emoji:'🎲',label:'Hosted',sub:'Campaign · a moderator',tone:'evil'}
  ];
  return (
    <div className="mk-field-wrap">
      <label className="mk-field"><span className="mk-label">Name your game</span>
        <input className="mk-input" value={data.name} maxLength={40} onChange={e=>set({name:e.target.value})}/></label>
      <div className="mk-field"><span className="mk-label">How does everyone play?</span>
        <div className="mk-pics">{presets.map(p=> <MkPicture key={p.id} {...p} selected={data.table===p.id} onClick={()=>set({table:p.id})}/>)}</div>
      </div>
      {data.table==='hosted' && <div className="mk-field"><MkToggle emoji="🎭" label="Moderator also plays?" checked={data.modPlays} onChange={v=>set({modPlays:v})}/></div>}
    </div>
  );
}
/* ---- step 2: secret ---- */
function MkSecret({ data, set }){
  const tbl = MK_TABLES[data.secret]||MK_TABLES.places;
  return (
    <div className="mk-field-wrap">
      <div className="mk-field"><span className="mk-label">What's the secret?</span>
        <div className="mk-pics">{Object.values(MK_TABLES).map(t=> <MkPicture key={t.id} emoji={t.emoji} label={t.label} tone="teal" selected={data.secret===t.id} onClick={()=>set({secret:t.id})}/>)}</div>
      </div>
      <div className="mk-row-wrap">
        <div className="mk-field"><span className="mk-label">How many spies?</span><MkStepper emoji="🕵️" value={data.spies} min={1} max={4} onChange={v=>set({spies:v})}/></div>
        <div className="mk-field"><span className="mk-label">{tbl.label} in the deck</span>
          <div className="mk-list">{tbl.items.slice(0,8).map(it=> <span key={it.id} className="mk-list-chip"><span aria-hidden="true">{it.emoji}</span>{it.name}</span>)}</div>
        </div>
      </div>
    </div>
  );
}
/* ---- step 3: the step-card stack ---- */
function MkSteps({ data, set }){
  const steps=data.steps, sel=data.selStep, cur=steps[sel]||steps[0];
  const addItem=(zone,item)=> set({ steps: steps.map((s,i)=> i===sel ? {...s,[zone]:[...s[zone],{kind:item.kind,emoji:item.emoji,label:item.label}]} : s) });
  const setAdvance=(adv)=> set({ steps: steps.map((s,i)=> i===sel ? {...s,advance:adv} : s) });
  const setTitle=(t)=> set({ steps: steps.map((s,i)=> i===sel ? {...s,title:t} : s) });
  const clearItems=()=> set({ steps: steps.map((s,i)=> i===sel ? {...s,publicItems:[],secretItems:[]} : s) });
  const addStep=()=> set({ steps:[...steps,{title:'New step',emoji:'🃏',advance:'ready',publicItems:[],secretItems:[]}], selStep:steps.length });
  const delStep=()=> { if(steps.length<=1) return; const ns=steps.filter((_,i)=>i!==sel); set({ steps:ns, selStep:Math.max(0,sel-1) }); };
  const move=(dir)=>{ const j=sel+dir; if(j<0||j>=steps.length) return; const ns=steps.slice(); const t=ns[sel]; ns[sel]=ns[j]; ns[j]=t; set({steps:ns,selStep:j}); };
  return (
    <div className="mk-steps-grid">
      <div>
        <div className="mk-label">The stack · tap a card to edit</div>
        <div className="mk-stack">
          {steps.map((s,i)=> <MkStepCard key={i} index={i} step={s} selected={i===sel} onClick={()=>set({selStep:i})}/>)}
          <button className="mk-addstep" onClick={addStep}>＋ Add a step</button>
        </div>
      </div>
      <div className="mk-panel">
        <input className="mk-input" value={cur.title} maxLength={28} onChange={e=>setTitle(e.target.value)}/>
        <div className="mk-panel-row">
          <button className="mk-mini" onClick={()=>move(-1)} disabled={sel===0}>↑</button>
          <button className="mk-mini" onClick={()=>move(1)} disabled={sel===steps.length-1}>↓</button>
          <button className="mk-mini" onClick={clearItems}>clear</button>
          <button className="mk-mini danger" onClick={delStep} disabled={steps.length<=1}>✕ step</button>
        </div>
        <div className="mk-label">Add to step {sel+1} — tap 👁️ public or 🤫 secret</div>
        <div className="mk-menu">
          {MK_CONTENT.map(m=>(
            <div key={m.kind} className="mk-menu-item">
              <span className="mk-menu-name"><span aria-hidden="true">{m.emoji}</span>{m.label}</span>
              <span className="mk-menu-adds">
                <button className="mk-add pub" title="Add to public" onClick={()=>addItem('publicItems',m)}>👁️</button>
                <button className="mk-add sec" title="Add to secret" onClick={()=>addItem('secretItems',m)}>🤫</button>
              </span>
            </div>
          ))}
        </div>
        <div className="mk-label">Move on when…</div>
        <div className="mk-advance">
          {MK_ADVANCE.map(([id,e,l])=> <button key={id} className={`mk-adv ${cur.advance===id?'on':''}`} onClick={()=>setAdvance(id)}><span aria-hidden="true">{e}</span>{l}</button>)}
        </div>
      </div>
    </div>
  );
}
/* ---- step 4: win (plain language; emits the standard hidden-role rule set) ---- */
function MkWin({ data, set }){
  const r=data.win, upd=(k,v)=>set({win:{...r,[k]:v}});
  const Sel=({k,opts})=> <select className="mk-sentence" value={r[k]} onChange={e=>upd(k,e.target.value)}>{opts.map(o=><option key={o} value={o}>{o}</option>)}</select>;
  return (
    <div className="mk-field-wrap">
      <div className="mk-field"><span className="mk-label">Who wins? · build the rule from plain words</span>
        <div className="mk-sentence-box">
          <span>If the</span><Sel k="who" opts={['table','spy','good team','evil team']}/>
          <Sel k="does" opts={['votes the spy','runs out of time','finds the place','survives']}/>
          <span>then</span><Sel k="then" opts={['the table wins','the spy wins','good wins','evil wins']}/>
          <span aria-hidden="true">🏆</span>
        </div>
      </div>
      <div className="mk-field"><span className="mk-label">Built-in rules (auto)</span>
        <div className="mk-list">
          <span className="mk-list-chip"><span aria-hidden="true">🗳️</span>Catch the spy → table wins</span>
          <span className="mk-list-chip"><span aria-hidden="true">🔮</span>Spy guesses right → spy wins</span>
          <span className="mk-list-chip"><span aria-hidden="true">⏲️</span>Time runs out → spy wins</span>
        </div>
        <div className="mk-hint">The maker emits these proven win rules for a hidden-role game. Custom rule editing comes with the Advanced tier.</div>
      </div>
    </div>
  );
}
/* ---- step 5: try it ---- */
function MkTry({ data }){
  const def = compileToGameDef(data);
  return (
    <div className="mk-try">
      <div className="mk-try-emoji" aria-hidden="true">🤖</div>
      <h3 className="mk-try-h">Ready to play “{def.title}”</h3>
      <p className="mk-try-sub">Tap <b>Try 4 bots</b> below — four friendly bots fill the table and play your game right now, no friends needed. Or <b>Make it!</b> to add it to your Party Games.</p>
      <div className="mk-try-facts">
        <span>👥 {def.players.min}–{def.players.max}</span>
        <span>🕵️ {data.spies} spy{data.spies>1?'s':''}</span>
        <span>🃏 {def.phases.length-1} step-cards</span>
        <span>{def.mainScreen==='none'?'📱 phones only':'📺 shared screen'}</span>
      </div>
    </div>
  );
}

/* ============================================================
   OVERLAY — mounted once; opened from the launcher's "Make your own!"
   ============================================================ */
function MakerOverlay(){
  const [open, setOpen] = useS_mk(false);
  useE_mk(()=>{ window.__openMaker = ()=> setOpen(true); return ()=>{ if(window.__openMaker) delete window.__openMaker; }; }, []);
  if(!open) return null;
  return <MakerApp onClose={()=>setOpen(false)}/>;
}
window.MakerOverlay = MakerOverlay;
