function OperatorView({state,dispatch,onTimerAction,onFx,autoTimer,autoAdvance,setAutoTimer,setAutoAdvance,autoAdvanceRef,autoTimerDuration,pairingCode,remotePaired,generatePairingCode}){
  // Mobile detection
  const[isMobile,setIsMobile]=useState(function(){return window.matchMedia('(max-width:768px),(max-height:500px)').matches});
  useEffect(function(){
    var mq=window.matchMedia('(max-width:768px),(max-height:500px)');
    var handler=function(e){setIsMobile(e.matches)};
    mq.addEventListener('change',handler);
    return function(){mq.removeEventListener('change',handler)};
  },[]);

  // Retry unsent show reports on operator load
  useEffect(function(){
    var unsent=localStorage.getItem('lc_unsent_report');
    if(!unsent||!LINECONIC_API_KEY)return;
    fetch(CIRCUIT_API_URL+'/api/lineconic/show-report',{
      method:'POST',
      headers:{'Content-Type':'application/json','X-Lineconic-Key':LINECONIC_API_KEY},
      body:unsent
    }).then(function(r){
      if(r.ok){localStorage.removeItem('lc_unsent_report');console.log('[LINECONIC] Retried unsent report successfully')}
    }).catch(function(){});
  },[]);

  // Close show: collect data from Firebase and push to Circuit
  async function closeShow(){
    if(!confirm('Close show and report to Circuit?'))return;
    if(!state.show||!state.show.id){alert('No active show');return}
    if(!fbdb){alert('Firebase not connected');return}
    var showId=state.show.id;
    var showRef=fbdb.ref('live/'+showId);
    var fluencyProfiles={};

    // Collect guest IDs from companions
    var companionsSnap=await showRef.child('companions').once('value');
    var companions=companionsSnap.val()||{};
    var guestIds=Object.keys(companions);

    // Collect per-guest responses
    var guestResponsesSnap=await showRef.child('guest_responses').once('value');
    var guestResponses=guestResponsesSnap.val()||{};

    // Build per-guest scores
    var guests=guestIds.map(function(gid){
      var responses=guestResponses[gid]||{};
      var slides=Object.values(responses);
      return{
        guestId:gid,
        knewIt:slides.filter(function(v){return v==='knew_it'}).length,
        noClue:slides.filter(function(v){return v==='no_clue'}).length,
        totalSlides:slides.length
      };
    });

    // Compute room average
    var maxSlides = 0;
    guests.forEach(function(g){ if(g.totalSlides > maxSlides) maxSlides = g.totalSlides; });
    var totalAccuracy = 0;
    var scoredGuests = 0;
    guests.forEach(function(g){
      if(g.totalSlides > 0){
        totalAccuracy += g.knewIt / g.totalSlides;
        scoredGuests++;
      }
    });
    if(scoredGuests > 0 && maxSlides > 0){
      var roomAvg = Math.round((totalAccuracy / scoredGuests) * maxSlides * 10) / 10;
      await fbdb.ref('live/'+showId+'/roomAverage').set(roomAvg);
    }

    // ═══ CARD STATS — aggregate per-card performance for algorithm ═══
    try{
      var responsesSnap=await showRef.child('responses').once('value');
      var responses=responsesSnap.val()||{};
      // Build slideId → cardId map from show sections
      var slideToCard={};
      if(state.show&&Array.isArray(state.show.sections)){
        state.show.sections.forEach(function(sec){
          if(!sec.slides)return;
          sec.slides.forEach(function(sl){
            if(sl.cardId)slideToCard[sl.id]=sl;
          });
        });
      }
      // Aggregate per-card stats
      var cardAgg={};
      Object.keys(responses).forEach(function(slideId){
        var sl=slideToCard[slideId];
        if(!sl)return;
        var r=responses[slideId];
        var knewIt=r.knewIt||0;var noClue=r.noClue||0;var total=knewIt+noClue;
        if(total===0)return;
        if(!cardAgg[sl.cardId])cardAgg[sl.cardId]={knewIt:0,noClue:0,total:0,slideType:sl.type};
        cardAgg[sl.cardId].knewIt+=knewIt;
        cardAgg[sl.cardId].noClue+=noClue;
        cardAgg[sl.cardId].total+=total;
      });
      // Write to card_stats
      var statsUpdates={};
      var dateStr=new Date().toISOString().split('T')[0];
      Object.keys(cardAgg).forEach(function(cardId){
        var a=cardAgg[cardId];
        statsUpdates['card_stats/'+cardId+'/shows/'+showId]={
          knewIt:a.knewIt,noClue:a.noClue,total:a.total,
          knewPct:Math.round(a.knewIt/a.total*100),
          slideType:a.slideType,showId:showId,date:dateStr
        };
      });
      if(Object.keys(statsUpdates).length>0){
        await fbdb.ref().update(statsUpdates);
        console.log('[LINECONIC] Card stats written for '+Object.keys(statsUpdates).length+' cards');
      }

      // ═══ AUTO CROWD_SCORE WRITEBACK + FLAGS + DIFFICULTY RECALIBRATION ═══
      // Re-read card_stats after writing new show data, then update each card
      var allStatsSnap=await fbdb.ref('card_stats').once('value');
      var allStats=allStatsSnap.val()||{};
      var cardUpdates={};
      var cardsSnap=await fbdb.ref('cards/cards').once('value');
      var allCards=cardsSnap.val()||{};

      Object.keys(cardAgg).forEach(function(cardId){
        var stats=allStats[cardId];
        if(!stats||!stats.shows)return;
        var entries=Object.values(stats.shows);
        if(entries.length===0)return;

        // Compute rolling crowd_score (recency-weighted)
        entries.sort(function(a,b){return(b.date||'').localeCompare(a.date||'')});
        var now=Date.now();
        var lastPlayed=entries[0].date||null;
        var weightSum=0,valSum=0;
        entries.forEach(function(e){
          var daysSince=lastPlayed?Math.max(0,(now-new Date(e.date).getTime())/86400000):0;
          var recencyWeight=Math.pow(0.85,daysSince/7)*e.total;
          valSum+=(e.knewPct||0)*recencyWeight;
          weightSum+=recencyWeight;
        });
        var avgPct=weightSum>0?valSum/weightSum:50;
        var crowdScore=Math.round(avgPct/10*10)/10;

        cardUpdates['cards/cards/'+cardId+'/scores/crowd_score']=crowdScore;

        // Auto-flag underperformers: crowd_score < 3 after 3+ shows → status: 'review'
        var card=allCards[cardId];
        if(entries.length>=3&&crowdScore<3&&card&&card.status!=='review'){
          cardUpdates['cards/cards/'+cardId+'/status']='review';
        }

        // Difficulty recalibration based on avg_knew_pct
        // >80% knew = too easy → decrease difficulty (min 1)
        // <30% knew = too hard → increase difficulty (max 5)
        if(card&&entries.length>=3){
          var totalKnew=0,totalAll=0;
          entries.forEach(function(e){totalKnew+=(e.knewPct||0);totalAll++});
          var overallAvgPct=totalAll>0?totalKnew/totalAll:50;
          var currentDiff=card.difficulty||3;
          if(overallAvgPct>80&&currentDiff>1){
            cardUpdates['cards/cards/'+cardId+'/difficulty']=currentDiff-1;
          }else if(overallAvgPct<30&&currentDiff<5){
            cardUpdates['cards/cards/'+cardId+'/difficulty']=currentDiff+1;
          }
        }
      });

      if(Object.keys(cardUpdates).length>0){
        await fbdb.ref().update(cardUpdates);
        console.log('[LINECONIC] Auto-updated '+Object.keys(cardUpdates).length+' card fields (crowd_score, flags, difficulty)');
      }
    }catch(e){console.warn('[LINECONIC] Card stats failed:',e)}

    // ═══ FLUENCY PROFILES — persist per-guest cultural fluency across shows ═══
    try{
      // Build slideId → card metadata map (need media_type for category breakdown)
      var slideToCardMeta={};
      if(state.show&&Array.isArray(state.show.sections)){
        state.show.sections.forEach(function(sec){
          if(!sec.slides)return;
          sec.slides.forEach(function(sl){
            if(sl.cardId){
              slideToCardMeta[sl.id]={cardId:sl.cardId,mediaType:sl.mediaType||sl.media_type||'unknown',difficulty:sl.difficulty||3};
            }
          });
        });
      }

      var profileUpdates={};

      for(var gi=0;gi<guestIds.length;gi++){
        var gid=guestIds[gi];
        var gResponses=guestResponses[gid]||{};
        var slideKeys=Object.keys(gResponses);
        if(slideKeys.length===0)continue;

        // Compute per-media-type stats for this show
        var mediaStats={};
        var totalKnew=0,totalAnswered=0;
        slideKeys.forEach(function(slideId){
          var answer=gResponses[slideId]; // 'knew_it' or 'no_clue'
          var meta=slideToCardMeta[slideId];
          if(!meta)return;
          var mt=meta.mediaType;
          if(!mediaStats[mt])mediaStats[mt]={knew:0,total:0};
          mediaStats[mt].total++;
          totalAnswered++;
          if(answer==='knew_it'){mediaStats[mt].knew++;totalKnew++}
        });

        if(totalAnswered===0)continue;

        var overallPct=Math.round(totalKnew/totalAnswered*100);

        // Tier calculation
        var tier='CULTURALLY SOUND';
        if(overallPct>=90)tier='ICON';
        else if(overallPct>=70)tier='MAIN CHARACTER';
        else if(overallPct>=40)tier='CULTURALLY SOUND';
        else if(overallPct>=10)tier='ON THIN ICE';
        else tier='UNCULTURED';

        // Per-media-type accuracy for this show
        var mediaBreakdown={};
        Object.keys(mediaStats).forEach(function(mt){
          var s=mediaStats[mt];
          mediaBreakdown[mt]={knew:s.knew,total:s.total,pct:Math.round(s.knew/s.total*100)};
        });

        // Read existing profile to merge
        var existingSnap=await fbdb.ref('profiles/'+gid+'/fluency').once('value');
        var existing=existingSnap.val();

        var newProfile;
        if(existing&&existing.show_count>0){
          // Merge: weighted average across shows (existing weight = show_count, new weight = 1)
          var prevWeight=existing.show_count;
          var newWeight=1;
          var totalWeight=prevWeight+newWeight;
          var mergedScore=Math.round((existing.overall_score*prevWeight+overallPct*newWeight)/totalWeight);

          // Merge per-media-type
          var mergedMedia=JSON.parse(JSON.stringify(existing.media_types||{}));
          Object.keys(mediaBreakdown).forEach(function(mt){
            var prev=mergedMedia[mt];
            var curr=mediaBreakdown[mt];
            if(prev){
              mergedMedia[mt]={
                knew:prev.knew+curr.knew,
                total:prev.total+curr.total,
                pct:Math.round((prev.knew+curr.knew)/(prev.total+curr.total)*100)
              };
            }else{
              mergedMedia[mt]=curr;
            }
          });

          // Find strongest/weakest
          var mediaEntries=Object.entries(mergedMedia).filter(function(e){return e[1].total>=2});
          mediaEntries.sort(function(a,b){return b[1].pct-a[1].pct});
          var strongest=mediaEntries.length>0?mediaEntries[0][0]:null;
          var weakest=mediaEntries.length>1?mediaEntries[mediaEntries.length-1][0]:null;

          newProfile={
            overall_score:mergedScore,
            tier:tier,
            show_count:existing.show_count+1,
            last_show_date:dateStr,
            last_show_id:showId,
            media_types:mergedMedia,
            strongest_category:strongest,
            weakest_category:weakest,
            shows:Object.assign({},existing.shows||{})
          };
          newProfile.shows[showId]={date:dateStr,score:overallPct,answered:totalAnswered};
        }else{
          // First show for this guest
          var mediaEntries2=Object.entries(mediaBreakdown).filter(function(e){return e[1].total>=2});
          mediaEntries2.sort(function(a,b){return b[1].pct-a[1].pct});
          var strongest2=mediaEntries2.length>0?mediaEntries2[0][0]:null;
          var weakest2=mediaEntries2.length>1?mediaEntries2[mediaEntries2.length-1][0]:null;

          newProfile={
            overall_score:overallPct,
            tier:tier,
            show_count:1,
            last_show_date:dateStr,
            last_show_id:showId,
            media_types:mediaBreakdown,
            strongest_category:strongest2,
            weakest_category:weakest2,
            shows:{}
          };
          newProfile.shows[showId]={date:dateStr,score:overallPct,answered:totalAnswered};
        }

        profileUpdates['profiles/'+gid+'/fluency']=newProfile;
        fluencyProfiles[gid]=newProfile;
      }

      if(Object.keys(profileUpdates).length>0){
        await fbdb.ref().update(profileUpdates);
        console.log('[LINECONIC] Fluency profiles written for '+Object.keys(profileUpdates).length+' guests');
      }
    }catch(e){console.warn('[LINECONIC] Fluency profile aggregation failed:',e)}

    // Collect vote results
    var votesSnap=await fbdb.ref('votes').once('value');
    var votes=votesSnap.val()||{};
    var voteResults=Object.entries(votes).map(function(entry){
      return{
        topic:entry[0].replace(/_/g,' '),
        dead:entry[1].dead||0,
        alive:entry[1].alive||0
      };
    });

    // Enrich guests with fluency data for Circuit
    var enrichedGuests=guests.map(function(g){
      var fp=fluencyProfiles[g.guestId];
      if(fp){
        return Object.assign({},g,{
          fluency:{
            overall_score:fp.overall_score,
            tier:fp.tier,
            show_count:fp.show_count,
            strongest_category:fp.strongest_category,
            weakest_category:fp.weakest_category
          }
        });
      }
      return g;
    });

    var payload={
      showId:showId,
      showName:state.show.name||showId,
      date:new Date().toISOString().split('T')[0],
      eventId:new URLSearchParams(window.location.search).get('event')||'',
      scores:{cyan:state.scores[0],pink:state.scores[1]},
      crowdMetrics:{
        peakCompanions:guestIds.length
      },
      guests:enrichedGuests,
      voteResults:voteResults
    };

    try{
      var res=await fetch(CIRCUIT_API_URL+'/api/lineconic/show-report',{
        method:'POST',
        headers:{'Content-Type':'application/json','X-Lineconic-Key':LINECONIC_API_KEY},
        body:JSON.stringify(payload)
      });
      var data=await res.json();
      if(res.ok){
        alert('Show reported: '+data.attendanceCount+' guests, '+(data.newUnlocks?data.newUnlocks.length:0)+' unlocks triggered');
      }else{
        localStorage.setItem('lc_unsent_report',JSON.stringify(payload));
        alert('Report failed (saved for retry). Error: '+(data.error||res.status));
      }
    }catch(err){
      localStorage.setItem('lc_unsent_report',JSON.stringify(payload));
      alert('Could not reach Circuit. Report saved for retry.');
    }

    // Clean up remote pairing nodes
    try{
      await showRef.child('pairing_code').remove();
      await showRef.child('remote_paired').remove();
      await showRef.child('remote_cmd').remove();
    }catch(e){}
  }

  // Mobile remote-pairing mode
  const[mobileRemoteMode,setMobileRemoteMode]=useState('local'); // 'local' | 'pairing' | 'remote'
  const[mobileRemoteCode,setMobileRemoteCode]=useState('');
  const[mobileRemoteError,setMobileRemoteError]=useState('');
  const[mobileRemoteShowId,setMobileRemoteShowId]=useState(null);
  const[mobileRemoteState,setMobileRemoteState]=useState(null);
  const[mobileDeviceId]=useState(function(){var id=localStorage.getItem('lc_op_remote_device');if(id)return id;var nid='oprem_'+Math.random().toString(36).slice(2,10);localStorage.setItem('lc_op_remote_device',nid);return nid});

  // Listen for active show when in pairing/remote mode
  useEffect(function(){
    if(mobileRemoteMode==='local'||!fbdb)return;
    var ref=fbdb.ref('active_show');
    ref.on('value',function(snap){
      var id=snap.val();
      setMobileRemoteShowId(id||null);
      if(!id&&mobileRemoteMode==='remote'){setMobileRemoteMode('local')}
    });
    return function(){ref.off()};
  },[mobileRemoteMode]);

  // Sync remote state when paired
  useEffect(function(){
    if(mobileRemoteMode!=='remote'||!fbdb||!mobileRemoteShowId)return;
    var ref=fbdb.ref('live/'+mobileRemoteShowId+'/state');
    ref.on('value',function(snap){setMobileRemoteState(snap.val())});
    return function(){ref.off()};
  },[mobileRemoteMode,mobileRemoteShowId]);

  function mobileRemotePair(){
    if(!fbdb||!mobileRemoteShowId){setMobileRemoteError('NO ACTIVE SHOW');return}
    if(mobileRemoteCode.length!==4){setMobileRemoteError('ENTER 4-DIGIT CODE');return}
    fbdb.ref('live/'+mobileRemoteShowId+'/pairing_code').once('value',function(snap){
      var serverCode=String(snap.val()||'');
      if(serverCode!==mobileRemoteCode){setMobileRemoteError('WRONG CODE');return}
      var pairedRef=fbdb.ref('live/'+mobileRemoteShowId+'/remote_paired');
      pairedRef.set({deviceId:mobileDeviceId,ts:Date.now()});
      pairedRef.onDisconnect().remove();
      setMobileRemoteMode('remote');
      setMobileRemoteError('');
    });
  }

  function mobileRemoteSendCmd(type){
    if(!fbdb||!mobileRemoteShowId)return;
    if(navigator.vibrate)navigator.vibrate(30);
    fbdb.ref('live/'+mobileRemoteShowId+'/remote_cmd').set({type:type,ts:Date.now(),deviceId:mobileDeviceId});
  }

  function mobileRemoteDispatch(action){
    switch(action.type){
      case'NEXT_SLIDE':mobileRemoteSendCmd('NEXT');break;
      case'PREV_SLIDE':mobileRemoteSendCmd('PREV');break;
      case'TOGGLE_REVEAL':mobileRemoteSendCmd('REVEAL');break;
      case'SCORE_CYAN':mobileRemoteSendCmd(action.payload>0?'SCORE_CYAN_UP':'SCORE_CYAN_DOWN');break;
      case'SCORE_PINK':mobileRemoteSendCmd(action.payload>0?'SCORE_PINK_UP':'SCORE_PINK_DOWN');break;
      case'TOGGLE_SCOREBOARD':mobileRemoteSendCmd('TOGGLE_SCOREBOARD');break;
      case'TOGGLE_SCOREBOARD_POS':mobileRemoteSendCmd('TOGGLE_SCOREBOARD_POS');break;
      case'JUMP_SECTION':mobileRemoteSendCmd('JUMP_SECTION:'+action.payload);break;
      case'TOGGLE_MUTE':mobileRemoteSendCmd('TOGGLE_MUTE');break;
    }
  }

  function mobileRemoteTimerAction(action,duration){
    mobileRemoteSendCmd('TIMER:'+action+(duration?':'+duration:''));
  }

  function mobileRemoteFx(fxType){
    mobileRemoteSendCmd('FX:'+fxType);
  }

  function getMobileRemoteMergedState(){
    if(!mobileRemoteState)return state;
    return {
      ...state,
      currentSlide:mobileRemoteState.slide!=null?mobileRemoteState.slide:state.currentSlide,
      scores:mobileRemoteState.scores||state.scores,
      revealState:mobileRemoteState.revealState||state.revealState,
      showScoreboard:mobileRemoteState.scoreboard!=null?mobileRemoteState.scoreboard:state.showScoreboard,
      scoreboardPosition:mobileRemoteState.scoreboardPosition||state.scoreboardPosition,
      muted:mobileRemoteState.muted!=null?mobileRemoteState.muted:state.muted,
      extrasBypassed:mobileRemoteState.extrasBypassed!=null?mobileRemoteState.extrasBypassed:state.extrasBypassed,
      bonusSections:Array.isArray(mobileRemoteState.bonusSections)?mobileRemoteState.bonusSections:state.bonusSections
    };
  }

  const flat=useMemo(()=>flattenSlides(state.show,state.redFlags,state.extrasBypassed,state.bonusSections),[state.show,state.redFlags,state.extrasBypassed,state.bonusSections]);
  const slide=flat[state.currentSlide];
  const nextSlide=flat[state.currentSlide+1]||null;

  if(!slide)return <div className="operator-grid"><div style={{color:'var(--text-secondary)',padding:'var(--space-04)'}}>LOADING...</div></div>;

  if(isMobile){
    // Pairing code entry
    if(mobileRemoteMode==='pairing'){
      var mono={fontFamily:"'Space Mono',monospace"};
      var pairBase={background:'#000',color:'#fff',width:'100vw',height:'100vh',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',padding:24,boxSizing:'border-box',userSelect:'none',WebkitUserSelect:'none'};
      return React.createElement('div',{style:pairBase},
        React.createElement('div',{style:{...mono,fontSize:12,letterSpacing:'.12em',color:'rgba(255,255,255,.5)',marginBottom:24}},'PAIR TO REMOTE SHOW'),
        React.createElement('input',{
          type:'tel',inputMode:'numeric',maxLength:4,value:mobileRemoteCode,
          onChange:function(e){var v=e.target.value.replace(/\D/g,'').slice(0,4);setMobileRemoteCode(v);setMobileRemoteError('')},
          onKeyDown:function(e){if(e.key==='Enter')mobileRemotePair()},
          style:{...mono,fontSize:48,letterSpacing:'.3em',textAlign:'center',width:240,padding:'12px 0',background:'transparent',border:'none',borderBottom:'2px solid #FF007F',color:'#fff',outline:'none'},
          autoFocus:true
        }),
        mobileRemoteError?React.createElement('div',{style:{...mono,color:'#FF007F',fontSize:12,marginTop:12}},mobileRemoteError):null,
        React.createElement('button',{onClick:mobileRemotePair,style:{...mono,marginTop:24,padding:'14px 48px',fontSize:14,letterSpacing:'.08em',background:'#FF007F',color:'#fff',border:'none',cursor:'pointer',textTransform:'uppercase'}},'PAIR'),
        React.createElement('button',{onClick:function(){setMobileRemoteMode('local');setMobileRemoteCode('');setMobileRemoteError('')},style:{...mono,marginTop:32,padding:'8px 24px',fontSize:10,letterSpacing:'.06em',background:'transparent',color:'rgba(255,255,255,.4)',border:'1px solid rgba(255,255,255,.15)',cursor:'pointer',textTransform:'uppercase'}},'BACK TO LOCAL')
      );
    }

    // Remote mode — same MobileOperatorLayout but with remote dispatch
    if(mobileRemoteMode==='remote'){
      var rms=getMobileRemoteMergedState();
      var rFlat=flattenSlides(rms.show,rms.redFlags,rms.extrasBypassed,rms.bonusSections);
      var rSlide=rFlat[rms.currentSlide];
      var rNext=rFlat[rms.currentSlide+1]||null;
      if(!rSlide)return React.createElement('div',{style:{background:'#000',color:'rgba(255,255,255,.3)',padding:40,fontFamily:"'Space Mono',monospace"}},'LOADING REMOTE...');
      return <MobileOperatorLayout
        state={rms} dispatch={mobileRemoteDispatch}
        flat={rFlat} slide={rSlide} nextSlide={rNext}
        onTimerAction={mobileRemoteTimerAction} onFx={mobileRemoteFx}
        autoTimer={autoTimer} autoAdvance={autoAdvance}
        setAutoTimer={setAutoTimer} setAutoAdvance={setAutoAdvance}
        autoAdvanceRef={autoAdvanceRef} autoTimerDuration={autoTimerDuration}
        onBackToLocal={function(){setMobileRemoteMode('local');setMobileRemoteState(null)}}
      />;
    }

    // Local mode (default)
    return <MobileOperatorLayout
      state={state} dispatch={dispatch} flat={flat} slide={slide} nextSlide={nextSlide}
      onTimerAction={onTimerAction} onFx={onFx}
      autoTimer={autoTimer} autoAdvance={autoAdvance}
      setAutoTimer={setAutoTimer} setAutoAdvance={setAutoAdvance}
      autoAdvanceRef={autoAdvanceRef} autoTimerDuration={autoTimerDuration}
      onPairToOther={function(){setMobileRemoteMode('pairing')}}
    />;
  }

  return (
    <div className="operator-grid">
      <div className="operator-left">
        <SectionNav show={state.show} currentSlide={state.currentSlide} dispatch={dispatch} redFlags={state.redFlags} extrasBypassed={state.extrasBypassed} bonusSections={state.bonusSections}/>
        <div className="operator-left-controls">
          <AutoToggles autoTimer={autoTimer} autoAdvance={autoAdvance} setAutoTimer={setAutoTimer} setAutoAdvance={setAutoAdvance} muted={state.muted} onToggleMute={()=>dispatch({type:'TOGGLE_MUTE'})} extrasBypassed={state.extrasBypassed} dispatch={dispatch}/>
          <RedFlagForm redFlags={state.redFlags} dispatch={dispatch}/>
          <RedFlagSubmissions showId={state.show&&state.show.id} dispatch={dispatch} redFlags={state.redFlags}/>
          <div style={{marginTop:'auto',display:'flex',flexDirection:'column',gap:'var(--space-02)',alignItems:'center',width:'100%'}}>
            <div style={{fontFamily:"'Space Mono',monospace",fontSize:'var(--type-meta)',color:'var(--text-disabled)',textAlign:'center'}}>PRESS ? FOR SHORTCUTS</div>
            <button onClick={function(){if(fbauth)fbauth.signOut()}} style={{
              background:'transparent',
              border:'1px solid var(--border-subtle)',
              color:'var(--text-disabled)',
              fontFamily:"'Space Mono',monospace",
              fontSize:10,
              letterSpacing:'.06em',
              textTransform:'uppercase',
              padding:'4px 12px',
              cursor:'pointer',
              width:'100%'
            }}>SIGN OUT</button>
          </div>
        </div>
      </div>
      <div className="operator-main">
        <CurrentSlideCard slide={slide} slideIndex={state.currentSlide} totalSlides={flat.length} revealState={state.revealState} dispatch={dispatch}/>
        <NextSlideCard slide={nextSlide}/>
      </div>
      <div className="operator-right">
        <ConnectionSignal/>
        <div style={{padding:'6px 0',fontFamily:"'Space Mono',monospace"}}>
          <div style={{display:'flex',alignItems:'center',gap:8}}>
            <span style={{fontSize:20,letterSpacing:'.2em',color:'var(--text-primary)'}}>{pairingCode||'----'}</span>
            <button onClick={generatePairingCode} style={{fontSize:9,padding:'3px 8px',background:'transparent',border:'1px solid var(--border-subtle)',color:'var(--text-secondary)',fontFamily:"'Space Mono',monospace",cursor:'pointer',letterSpacing:'.06em'}}>NEW</button>
            {remotePaired?<span style={{color:'#00FF88',fontSize:10}}>● PAIRED</span>:<span style={{color:'var(--text-disabled)',fontSize:10}}>WAITING...</span>}
          </div>
          <span style={{fontSize:9,color:'var(--text-disabled)',letterSpacing:'.06em'}}>OPEN /OPERATOR OR /REMOTE ON PHONE</span>
        </div>
        <CrowdTemperature showId={state.show&&state.show.id} curSlide={flat[state.currentSlide]}/>
        <QuickAccessButtons/>
        <button className="setlist-btn" onClick={function(){dispatch({type:'TOGGLE_SETLIST_EDITOR'})}} style={{width:'100%',padding:'8px 12px',fontSize:11}}>{state.liveMode?'LIVE \uD83D\uDD34':'SETLIST [L]'}</button>
        <BonusButtons show={state.show} redFlags={state.redFlags} extrasBypassed={state.extrasBypassed} bonusSections={state.bonusSections} currentSlide={state.currentSlide} dispatch={dispatch}/>
        <GameControls scores={state.scores} dispatch={dispatch} scoreboardPosition={state.scoreboardPosition} showScoreboard={state.showScoreboard} show={state.show} flatSlides={flat} slideIndex={state.currentSlide}/>
        <TimerDisplay onTimerAction={onTimerAction} autoAdvanceRef={autoAdvanceRef} autoTimerDuration={autoTimerDuration} dispatch={dispatch}/>
      </div>
      <div className="operator-bottom">
        <div className="soundboard">
          <button className="snd-btn" onClick={()=>onFx('airhorn')}>AIRHORN</button>
          <button className="snd-btn" onClick={()=>onFx('rimshot')}>RIMSHOT</button>
          <button className="snd-btn" onClick={()=>onFx('crickets')}>CRICKETS</button>
          <button className="snd-btn" onClick={()=>onFx('scream')}>SCREAM</button>
          <button className="snd-btn" onClick={()=>onFx('rain')}>RAIN</button>
        </div>
        <button className="snd-btn" style={{background:'var(--signal)',color:'var(--void)',fontWeight:'bold',border:'none'}} onClick={closeShow}>CLOSE SHOW</button>
        <div data-testid="slide-counter" style={{fontFamily:"'Space Mono',monospace",fontSize:'var(--type-meta)',color:'var(--text-secondary)'}}>{state.currentSlide+1}/{flat.length}</div>
      </div>
      {state.showShortcuts&&<ShortcutOverlay onClose={()=>dispatch({type:'CLOSE_OVERLAYS'})}/>}
      {state.showSetlistEditor&&<SetlistEditor show={state.show} dispatch={dispatch} liveMode={state.liveMode} redFlags={state.redFlags} currentSlide={state.currentSlide} extrasBypassed={state.extrasBypassed} bonusSections={state.bonusSections}/>}
    </div>
  );
}
