// BOOKING STYLES — 6 different picker UIs, shared hooks from booking.jsx
// All take the same props: days, day, setDay, selected, setSelected (wraps {d,si}),
// seats (seatsCount[day][slotIndex]), and SLOT_HOURS.

// -----------------------------------------------------------------
// Shared — sessions recently filled proof, live booking indicator, what-next
// -----------------------------------------------------------------
function SessionsProof() {
  const { tweaks } = useApp();
  const style = tweaks.proofStyle || 'chip';

  if (style === 'off') return null;

  // MINIMAL — tiny one-liner, no box, just a purple dot and text
  if (style === 'minimal') {
    return (
      <div style={{
        display:'flex',alignItems:'center',gap:8,
        padding:'4px 2px',marginBottom:14,
      }}>
        <span style={{
          width:6,height:6,borderRadius:'50%',background:BRAND.purple,flexShrink:0,
          animation:'apex-pulse 1.6s ease-in-out infinite',boxShadow:`0 0 8px ${BRAND.purple}`,
        }}/>
        <div style={{fontSize:12,color:'var(--mute)',lineHeight:1.4,letterSpacing:0.1}}>
          <strong style={{color:'var(--ink)',fontWeight:700}}>3 of last 5 sessions</strong> sold out
        </div>
      </div>
    );
  }

  // CHIP — on-brand purple pill, matches the "Founding Ambassador" etc stamps
  if (style === 'chip') {
    return (
      <div style={{
        display:'flex',alignItems:'center',gap:10,
        padding:'9px 14px',marginBottom:14,
        background:'rgba(124,58,237,0.06)',
        border:'1px solid rgba(124,58,237,0.2)',borderRadius:999,
      }}>
        <span style={{
          display:'inline-flex',alignItems:'center',gap:4,
          fontSize:9.5,fontWeight:800,letterSpacing:1.8,textTransform:'uppercase',
          color:'#fff',background:BRAND.gradient,
          padding:'3px 8px',borderRadius:999,flexShrink:0,
        }}>
          <span style={{
            width:5,height:5,borderRadius:'50%',background:'#fff',
            animation:'apex-pulse 1.4s ease-in-out infinite',
          }}/>
          Live
        </span>
        <div style={{fontSize:12.5,color:'var(--ink)',fontWeight:600,lineHeight:1.4,letterSpacing:0.1}}>
          <strong style={{fontWeight:800}}>3 of the last 5</strong>
          <span style={{color:'var(--mute)'}}> sessions sold out</span>
        </div>
      </div>
    );
  }

  // BARS — inline 5-segment bar showing which sessions sold out (data-vis vibe)
  if (style === 'bars') {
    const pattern = [true, true, false, true, false]; // 3 of 5 sold out
    return (
      <div style={{
        display:'flex',alignItems:'center',gap:12,
        padding:'10px 14px',marginBottom:14,
        background:'var(--card)',border:'1px solid var(--border)',borderRadius:12,
      }}>
        <div style={{display:'flex',gap:3,flexShrink:0}}>
          {pattern.map((full, i) => (
            <span key={i} style={{
              width:10,height:22,borderRadius:2,
              background: full ? BRAND.gradient : 'var(--break-bg)',
              border: full ? 'none' : '1px dashed var(--border-strong)',
              boxShadow: full ? '0 2px 6px rgba(124,58,237,0.25)' : 'none',
            }}/>
          ))}
        </div>
        <div style={{flex:1,minWidth:0,lineHeight:1.3}}>
          <div style={{fontSize:9.5,fontWeight:800,letterSpacing:1.8,textTransform:'uppercase',color:'var(--mute)',marginBottom:1}}>
            Last 5 sessions
          </div>
          <div style={{fontSize:12.5,color:'var(--ink)',fontWeight:700,letterSpacing:-0.1}}>
            3 sold out · 2 filling now
          </div>
        </div>
      </div>
    );
  }

  // TICKER — monospace counter, editorial feel
  if (style === 'ticker') {
    return (
      <div style={{
        display:'flex',alignItems:'center',gap:14,
        padding:'10px 14px',marginBottom:14,
        background:'var(--card)',border:'1px solid var(--border)',borderRadius:10,
        fontFamily:'ui-monospace,SFMono-Regular,Menlo,monospace',
      }}>
        <div style={{
          fontSize:22,fontWeight:800,letterSpacing:-1.5,
          background:BRAND.gradient,
          WebkitBackgroundClip:'text',WebkitTextFillColor:'transparent',backgroundClip:'text',
          fontFamily:'DM Sans,sans-serif',lineHeight:1,
        }}>3<span style={{color:'var(--mute)',fontSize:14,fontWeight:600,WebkitTextFillColor:'initial',marginLeft:2}}>/5</span></div>
        <div style={{height:24,width:1,background:'var(--border)'}}/>
        <div style={{flex:1,fontSize:11.5,color:'var(--ink)',fontFamily:'DM Sans,sans-serif',lineHeight:1.35,letterSpacing:0.1}}>
          recent sessions sold out<br/>
          <span style={{color:'var(--mute)',fontSize:10.5,letterSpacing:0.3}}>avg seat held in 4.2 min</span>
        </div>
      </div>
    );
  }

  return null;
}

function LiveBookingPing() {
  const [show, setShow] = useState(false);
  const [name, setName] = useState('');
  useEffect(() => {
    let live = true;
    const tick = () => {
      if (!live) return;
      const p = TOAST_PEOPLE[Math.floor(Math.random()*TOAST_PEOPLE.length)];
      setName(`${p.n.split(' ')[0]} in ${p.c.split(',')[0]}`);
      setShow(true);
      setTimeout(() => live && setShow(false), 3200);
    };
    const iv = setInterval(tick, 9000);
    setTimeout(tick, 2500);
    return () => { live = false; clearInterval(iv); };
  }, []);
  return (
    <div style={{
      fontSize:11.5,color:'var(--mute)',textAlign:'center',
      height:18,marginTop:4,marginBottom:4,letterSpacing:0.2,
      opacity: show ? 1 : 0, transition:'opacity 0.35s',
    }}>
      <span style={{
        display:'inline-flex',alignItems:'center',gap:6,
      }}>
        <span style={{
          display:'inline-flex',gap:2,
        }}>
          {[0,1,2].map(i => (
            <span key={i} style={{
              width:4,height:4,borderRadius:'50%',background:'var(--purple)',
              animation:`apex-typing 1.2s ease-in-out ${i*0.15}s infinite`,
            }}/>
          ))}
        </span>
        {name} is booking now…
      </span>
    </div>
  );
}

function WhatHappensNext({ compact=false }) {
  const steps = [
    ['Text confirm', 'Arrives in ~30 seconds'],
    ['Calendar invite', 'Goes to your email'],
    ['Reminder 1h before', 'We text again'],
    ['Join from the text', 'One-tap into Zoom'],
  ];
  return (
    <div style={{
      marginTop:18,padding: compact ? '14px 14px' : '16px 16px',
      background:'var(--break-bg)',borderRadius:14,
      border:'1px solid var(--border)',
    }}>
      <div style={{fontSize:10.5,fontWeight:800,letterSpacing:2,textTransform:'uppercase',color:'var(--mute)',marginBottom:10}}>
        What happens after you book
      </div>
      <div style={{display:'grid',gridTemplateColumns:'repeat(4,1fr)',gap:6}}>
        {steps.map((s,i) => (
          <div key={i} style={{position:'relative',textAlign:'center',padding:'2px 4px'}}>
            <div style={{
              width:22,height:22,borderRadius:'50%',margin:'0 auto 6px',
              background:BRAND.gradient,color:'#fff',
              fontSize:10.5,fontWeight:800,fontFamily:'DM Sans,sans-serif',
              display:'flex',alignItems:'center',justifyContent:'center',
            }}>{i+1}</div>
            <div style={{fontSize:10.5,fontWeight:700,color:'var(--ink)',lineHeight:1.2,letterSpacing:0.1}}>{s[0]}</div>
            <div style={{fontSize:9.5,color:'var(--mute)',lineHeight:1.3,marginTop:2}}>{s[1]}</div>
            {i<3 && (
              <span style={{
                position:'absolute',right:-3,top:9,fontSize:10,color:'var(--dim)',
              }}>→</span>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// -----------------------------------------------------------------
// STYLE 1 — CLASSIC list (baseline)
// -----------------------------------------------------------------
function BookingClassic({ days, day, setDay, selected, setSelected, seats }) {
  const pick = (d, si) => {
    if (seats[d][si] === 0) return;
    setSelected({d, si}); setDay(d);
  };
  return (
    <>
      <SessionsProof/>
      <div style={{display:'flex',gap:8,marginBottom:14}}>
        {days.map((d, i) => (
          <button key={i} onClick={() => setDay(i)} style={{
            flex:1,padding:'12px 10px',
            background: day===i ? 'var(--card)' : 'var(--break-bg)',
            border: day===i ? '1.5px solid var(--purple)' : '1.5px solid transparent',
            borderRadius:12,color:'var(--ink)',fontSize:13,fontWeight:600,
            cursor:'pointer',transition:'all 0.2s',textAlign:'center',
          }}>
            <span style={{display:'block',fontSize:10,letterSpacing:1.5,textTransform:'uppercase',
              color: day===i ? 'var(--purple)' : 'var(--mute)',marginBottom:3,fontWeight:700}}>
              {d.short}
            </span>
            {d.date}
          </button>
        ))}
      </div>
      {SLOT_HOURS[day].map((slot, si) => {
        const n = seats[day][si];
        const isFull = n === 0;
        const urgent = n > 0 && n <= 5;
        const isSel = selected && selected.d === day && selected.si === si;
        return (
          <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
            width:'100%',background: isSel ? 'var(--card)' : 'var(--break-bg)',
            border: isSel ? '1.5px solid var(--purple)' : '1.5px solid transparent',
            borderRadius:12,padding:'14px 16px',marginBottom:8,
            cursor: isFull ? 'not-allowed' : 'pointer',
            opacity: isFull ? 0.45 : 1,transition:'all 0.2s',
            display:'flex',alignItems:'center',justifyContent:'space-between',gap:10,
            textAlign:'left',filter: isFull ? 'saturate(0)' : 'none',
          }}>
            <div style={{minWidth:0,flex:1}}>
              <div style={{fontSize:15,fontWeight:700,color:'var(--ink)',whiteSpace:'nowrap',textDecoration: isFull ? 'line-through' : 'none'}}>{slot.time}</div>
              <div style={{fontSize:10.5,color:'var(--mute)',marginTop:2,letterSpacing:1,fontWeight:500}}>{slot.tz}</div>
            </div>
            <div style={{display:'flex',alignItems:'center',gap:6,fontSize:12,fontWeight:500,flexShrink:0,
              color: isFull ? '#ef4444' : (urgent ? '#ef4444' : 'var(--mute)')}}>
              {isFull ? <>
                <span style={{width:6,height:6,borderRadius:'50%',background:'#ef4444'}}/>
                <span style={{fontWeight:800,letterSpacing:1.5}}>FULL</span>
              </> : <>
                <LiveDot color={urgent?'#ef4444':'#10b981'} size={6}/>
                <span style={{fontWeight:urgent?800:700,color: urgent ? '#ef4444' : 'var(--ink)'}}>{n}</span>
                <span>left</span>
              </>}
            </div>
          </button>
        );
      })}
    </>
  );
}

// -----------------------------------------------------------------
// STYLE 2 — WHEEL: horizontal day chips + 2-col grid of fat session tiles
// -----------------------------------------------------------------
function BookingWheel({ days, day, setDay, selected, setSelected, seats }) {
  const pick = (d, si) => {
    if (seats[d][si] === 0) return;
    setSelected({d, si}); setDay(d);
  };
  return (
    <>
      <SessionsProof/>
      <div style={{
        display:'flex',gap:8,overflowX:'auto',paddingBottom:4,marginBottom:14,
        scrollbarWidth:'none',
      }}>
        {days.map((d, i) => (
          <button key={i} onClick={() => setDay(i)} style={{
            minWidth:100,padding:'10px 14px',
            background: day===i ? BRAND.gradient : 'var(--break-bg)',
            color: day===i ? '#fff' : 'var(--ink)',
            border:'none',borderRadius:999,
            fontSize:13,fontWeight:700,cursor:'pointer',flexShrink:0,
            boxShadow: day===i ? '0 8px 22px rgba(124,58,237,0.32)' : 'none',
            transition:'all 0.2s',
          }}>
            <span style={{display:'block',fontSize:9.5,letterSpacing:1.4,textTransform:'uppercase',
              color: day===i ? 'rgba(255,255,255,0.85)' : 'var(--mute)',marginBottom:1,fontWeight:700}}>
              {d.short}
            </span>
            {d.date}
          </button>
        ))}
      </div>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10}}>
        {SLOT_HOURS[day].map((slot, si) => {
          const n = seats[day][si];
          const isFull = n === 0;
          const urgent = n > 0 && n <= 5;
          const isSel = selected && selected.d === day && selected.si === si;
          return (
            <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
              background: isSel ? 'var(--card)' : 'var(--break-bg)',
              border: isSel ? '2px solid var(--purple)' : '2px solid transparent',
              borderRadius:16,padding:'18px 14px',
              cursor: isFull ? 'not-allowed' : 'pointer',
              opacity: isFull ? 0.4 : 1,
              textAlign:'left',transition:'all 0.2s',
              boxShadow: isSel ? '0 10px 30px rgba(124,58,237,0.2)' : 'none',
              filter: isFull ? 'saturate(0)' : 'none',
            }}>
              <div style={{fontSize:11,fontWeight:800,letterSpacing:1.5,textTransform:'uppercase',color: isSel ? 'var(--purple)' : 'var(--mute)',marginBottom:4}}>
                {slot.tz} time
              </div>
              <div style={{fontSize:20,fontWeight:800,color:'var(--ink)',letterSpacing:'-0.5px',fontFamily:'DM Sans,sans-serif',lineHeight:1.1,marginBottom:6}}>
                {slot.time.replace(':00','')}
              </div>
              {isFull ? (
                <span style={{fontSize:11,fontWeight:800,letterSpacing:1.5,color:'#ef4444'}}>
                  • FULL
                </span>
              ) : (
                <div style={{display:'flex',alignItems:'center',gap:5,fontSize:11,fontWeight:600,color: urgent ? '#ef4444' : 'var(--mute)'}}>
                  <LiveDot color={urgent?'#ef4444':'#10b981'} size={5}/>
                  <span style={{fontWeight:800,color: urgent ? '#ef4444' : 'var(--ink)'}}>{n}</span>
                  <span>seats left</span>
                </div>
              )}
            </button>
          );
        })}
      </div>
    </>
  );
}

// -----------------------------------------------------------------
// STYLE 3 — STADIUM: visual seat grid
// -----------------------------------------------------------------
function StadiumSeats({ total, taken, onPick, mySeatIdx }) {
  // Creates a grid of dots; taken are filled, remaining are clickable.
  // Realistic pattern: taken seats are scattered (deterministic hash) not front-to-back
  const cols = 10;
  const rows = Math.ceil(total / cols);
  // Deterministic "scattered" taken pattern based on seat idx
  const isTaken = (i) => {
    if (i === mySeatIdx) return false;
    // Pseudo-random but stable: hash of index
    const h = ((i * 2654435761) >>> 0) % total;
    return h < taken;
  };
  const cells = Array.from({length: total}, (_, i) => isTaken(i));
  return (
    <div style={{
      padding:'16px 10px 12px',background:'linear-gradient(180deg,rgba(124,58,237,0.06),transparent)',
      borderRadius:12,marginTop:10,
    }}>
      {/* "Stage" label */}
      <div style={{
        width:'70%',margin:'0 auto 8px',height:4,borderRadius:2,
        background:BRAND.gradient,boxShadow:'0 0 20px rgba(124,58,237,0.5)',
      }}/>
      <div style={{fontSize:9,letterSpacing:2,textTransform:'uppercase',color:'var(--mute)',textAlign:'center',marginBottom:10,fontWeight:800}}>
        ← STAGE (Apex) →
      </div>
      <SoloSeatsLabel/>
      <div style={{
        display:'grid',
        gridTemplateColumns:`repeat(${cols}, 1fr)`,
        gap:4,maxWidth:360,margin:'0 auto',
      }}>
        {cells.map((filled, i) => {
          const isMine = i === mySeatIdx;
          return (
            <button key={i}
              onClick={() => !filled && onPick && onPick(i)}
              disabled={filled}
              style={{
                position:'relative',
                aspectRatio:'1/1',border:'none',
                borderRadius:3,
                background: isMine ? '#10b981' : (filled ? 'rgba(124,58,237,0.55)' : '#fff'),
                boxShadow: isMine
                  ? '0 0 0 2px #10b981, 0 0 12px rgba(16,185,129,0.7)'
                  : (filled ? 'inset 0 0 0 1px rgba(124,58,237,0.65)' : 'inset 0 0 0 1px var(--border-strong)'),
                cursor: filled ? 'not-allowed' : 'pointer',
                transition:'all 0.15s',padding:0,
                transform: isMine ? 'scale(1.15)' : 'scale(1)',
                display:'flex',alignItems:'center',justifyContent:'center',
              }}
              onMouseEnter={e => { if (!filled && !isMine) { e.currentTarget.style.background = BRAND.purple; e.currentTarget.style.transform = 'scale(1.15)'; }}}
              onMouseLeave={e => { if (!filled && !isMine) { e.currentTarget.style.background = '#fff'; e.currentTarget.style.transform = 'scale(1)'; }}}
              title={isMine ? 'Your seat ✓' : (filled ? 'Taken' : `Claim seat ${i+1}`)}
            >
              {!filled && !isMine && (
                <span style={{
                  width:4,height:4,borderRadius:'50%',background:'#10b981',
                  boxShadow:'0 0 4px rgba(16,185,129,0.9)',
                  animation:'apex-avail-blink 1.4s ease-in-out infinite',
                }}/>
              )}
            </button>
          );
        })}
      </div>
      <SeatLegend total={cells.length} taken={cells.filter(Boolean).length}/>
    </div>
  );
}

function BookingStadium({ days, day, setDay, selected, setSelected, seats }) {
  // Model: each session has 60 seats; taken = 60 - seats[d][si]
  const CAP = 60;
  const pick = (d, si) => { if (seats[d][si] === 0) return; setSelected({d, si}); setDay(d); };
  const chosen = selected && selected.d === day ? selected.si : null;

  // --- VIP Box state --------------------------------------------------
  const { tweaks } = useApp();
  const boxesOn      = tweaks.stadiumBoxes !== 'off';
  const boxCount     = parseInt(tweaks.vipBoxCount || '10', 10);      // 6 | 8 | 10 | 12
  const boxesFull    = tweaks.vipBoxesFull || 'mostly';               // 'few' | 'half' | 'mostly'
  const showLabels   = tweaks.boxLabels !== 'off';                    // show brokerage names on FULL boxes
  const escapeOn     = tweaks.vipEscape !== 'off';

  // Seed boxes: mix of sizes 4-20, most full. Reseed when tweaks change.
  const seedBoxes = () => {
    const sizes = [10, 8, 12, 6, 10, 8, 20, 6, 10, 8, 12, 6];
    const numFull = boxesFull === 'few' ? Math.ceil(boxCount * 0.3)
                  : boxesFull === 'half' ? Math.ceil(boxCount * 0.5)
                  : Math.ceil(boxCount * 0.75);
    return Array.from({length: boxCount}, (_, i) => {
      const size = sizes[i % sizes.length];
      const full = i < numFull;
      return {
        id: i+1,
        letter: BOX_LETTERS[i],
        size,
        taken: full ? size : 0,
        brokerage: showLabels && full ? FAKE_BROKERAGES[i % FAKE_BROKERAGES.length] : null,
      };
    });
  };
  const [boxes, setBoxes] = useState(seedBoxes);
  useEffect(() => {
    // Reseed when the tweak knobs that define the box layout change.
    setBoxes(seedBoxes());
    setMyBoxId(null);
    // eslint-disable-next-line
  }, [boxCount, boxesFull, showLabels]);
  const [modalBox, setModalBox]   = useState(null);
  const [myBoxId,  setMyBoxId]    = useState(null);

  // --- Standard seat state -------------------------------------------
  const [mySeat, setMySeat]         = useState(null); // { d, si, seatIdx }
  const [stdModalSeat, setStdModal] = useState(null); // seat idx triggering std modal

  const { updateBooking } = useApp();
  const onBoxConfirm = ({ boxId, hostName, seatCount, size, emails, mode, link }) => {
    const box = boxes.find(b => b.id === boxId);
    setBoxes(prev => prev.map(b => b.id === boxId
      ? { ...b, host: b.host || hostName, size, taken: Math.min(size, seatCount), brokerage: b.brokerage }
      : b));
    setMyBoxId(boxId);
    setMySeat(null);
    // Route to confirm screen with VIP payload
    const slot = SLOT_HOURS[day]?.[chosen];
    const dayDate = days[day]?.raw || new Date();
    updateBooking({
      step: 'confirm',
      day, dayDate,
      time: slot ? slot.time + ' PT' : '',
      iso: slot?.iso || '',
      vipBox: {
        boxLetter: box?.letter || 'B',
        boxId, size, seatCount,
        hostName, emails: emails || [], mode: mode || 'emails', link: link || null,
      },
    });
  };
  const onBoxEscape = () => { setModalBox(null); setMyBoxId(null); /* release box so std seats become clickable */ };

  const claimStdSeat = (seatIdx) => {
    if (chosen === null) return;
    // Can't claim a std seat if already hold a VIP box
    if (myBoxId) return;
    setStdModal({ seatIdx });
  };
  const onStdConfirm = ({ seatIdx, plusN, emails }) => {
    setMySeat({ d: day, si: chosen, seatIdx, plusN });
    setSelected({d: day, si: chosen});
    setStdModal(null);
    const slot = SLOT_HOURS[day]?.[chosen];
    updateBooking({
      step: 'confirm',
      day, dayDate: days[day]?.raw || new Date(),
      time: slot ? slot.time + ' PT' : '',
      iso: slot?.iso || '',
      stdSeat: {
        seatIdx, seatLabel: `#${seatIdx + 1}`,
        plusN, emails: emails || [],
      },
    });
  };

  const [live, setLive] = useState(0);
  useEffect(() => {
    const iv = setInterval(() => setLive(n => n + 1), 8000);
    return () => clearInterval(iv);
  }, []);

  return (
    <>
      <SessionsProof/>
      {/* Day picker */}
      <div style={{display:'flex',gap:8,marginBottom:12}}>
        {days.map((d, i) => (
          <button key={i} onClick={() => setDay(i)} style={{
            flex:1,padding:'10px 8px',
            background: day===i ? 'var(--card)' : 'var(--break-bg)',
            border: day===i ? '1.5px solid var(--purple)' : '1.5px solid transparent',
            borderRadius:10,color:'var(--ink)',fontSize:12.5,fontWeight:600,
            cursor:'pointer',textAlign:'center',
          }}>
            <span style={{display:'block',fontSize:9.5,letterSpacing:1.5,textTransform:'uppercase',
              color: day===i ? 'var(--purple)' : 'var(--mute)',marginBottom:2,fontWeight:700}}>
              {d.short}
            </span>
            {d.date}
          </button>
        ))}
      </div>
      {/* Session list (compact row) */}
      <div style={{display:'grid',gridTemplateColumns:`repeat(${SLOT_HOURS[day].length},1fr)`,gap:6,marginBottom:6}}>
        {SLOT_HOURS[day].map((slot, si) => {
          const n = seats[day][si];
          const isFull = n === 0;
          const isSel = chosen === si;
          return (
            <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
              background: isSel ? BRAND.gradient : 'var(--break-bg)',
              color: isSel ? '#fff' : 'var(--ink)',
              border:'none',borderRadius:10,padding:'10px 6px',
              cursor: isFull ? 'not-allowed' : 'pointer',
              opacity: isFull ? 0.4 : 1,
              textAlign:'center',transition:'all 0.2s',
              boxShadow: isSel ? '0 8px 22px rgba(124,58,237,0.35)' : 'none',
              fontSize:13,fontWeight:700,
            }}>
              {slot.time.replace(':00','')}
              <span style={{
                display:'block',fontSize:9.5,letterSpacing:0.5,marginTop:2,fontWeight:600,
                color: isSel ? 'rgba(255,255,255,0.85)' : 'var(--mute)',
              }}>
                {isFull ? 'FULL' : `${n} open`}
              </span>
            </button>
          );
        })}
      </div>
      {/* Seat map for selected */}
      {chosen !== null ? (
        <>
          {boxesOn && (tweaks.boxPosition || 'above') === 'above' && (
            <VipBoxRow boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId}/>
          )}
          {boxesOn && tweaks.boxPosition === 'flank' ? (
            <div style={{
              display:'grid',gridTemplateColumns:'56px 1fr 56px',gap:8,alignItems:'stretch',
            }}>
              <VipBoxFlankColumn
                boxes={boxes.slice(0, Math.ceil(boxes.length/2))}
                onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} side="left"/>
              <StadiumSwitcher
                total={CAP}
                taken={Math.min(CAP - seats[day][chosen], CAP)}
                mySeatIdx={mySeat && mySeat.d===day && mySeat.si===chosen ? mySeat.seatIdx : null}
                onPick={(seatIdx) => claimStdSeat(typeof seatIdx === 'number' ? seatIdx : (CAP - seats[day][chosen]))}
              />
              <VipBoxFlankColumn
                boxes={boxes.slice(Math.ceil(boxes.length/2))}
                onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} side="right"/>
            </div>
          ) : boxesOn && tweaks.boxPosition === 'opera' ? (
            <div style={{position:'relative'}}>
              <div style={{
                position:'absolute',top:18,left:-2,zIndex:2,width:46,
              }}>
                <VipBoxOperaCorners boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} position="top-left"/>
              </div>
              <div style={{
                position:'absolute',top:18,right:-2,zIndex:2,width:46,
              }}>
                <VipBoxOperaCorners boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} position="top-right"/>
              </div>
              <div style={{
                position:'absolute',bottom:40,left:-2,zIndex:2,width:46,
              }}>
                <VipBoxOperaCorners boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} position="bottom-left"/>
              </div>
              <div style={{
                position:'absolute',bottom:40,right:-2,zIndex:2,width:46,
              }}>
                <VipBoxOperaCorners boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId} position="bottom-right"/>
              </div>
              <div style={{padding:'0 52px'}}>
                <StadiumSwitcher
                  total={CAP}
                  taken={Math.min(CAP - seats[day][chosen], CAP)}
                  mySeatIdx={mySeat && mySeat.d===day && mySeat.si===chosen ? mySeat.seatIdx : null}
                  onPick={(seatIdx) => claimStdSeat(typeof seatIdx === 'number' ? seatIdx : (CAP - seats[day][chosen]))}
                />
              </div>
            </div>
          ) : (
            <StadiumSwitcher
              total={CAP}
              taken={Math.min(CAP - seats[day][chosen], CAP)}
              mySeatIdx={mySeat && mySeat.d===day && mySeat.si===chosen ? mySeat.seatIdx : null}
              onPick={(seatIdx) => claimStdSeat(typeof seatIdx === 'number' ? seatIdx : (CAP - seats[day][chosen]))}
            />
          )}
          {boxesOn && tweaks.boxPosition === 'below' && (
            <div style={{marginTop:12}}>
              <VipBoxRow boxes={boxes} onOpenBox={(b) => setModalBox(b)} myBoxId={myBoxId}/>
            </div>
          )}
          <BoxSeatModal
            open={!!modalBox} onClose={() => { setModalBox(null); if (!myBoxId) return; /* if they already confirmed a box earlier, releasing happens via Escape; here just close */ }}
            box={modalBox} onConfirm={onBoxConfirm}
            onEscape={escapeOn ? onBoxEscape : null}
          />
          <StandardSeatModal
            open={!!stdModalSeat} onClose={() => setStdModal(null)}
            seatIdx={stdModalSeat?.seatIdx}
            seatLabel={stdModalSeat ? `#${stdModalSeat.seatIdx + 1}` : ''}
            onConfirm={onStdConfirm}
            onUpgradeToBox={() => {
              // Close standard modal, open the first open VIP box
              setStdModal(null);
              const openBox = boxes.find(b => b.taken < b.size && b.id !== myBoxId);
              if (openBox) setModalBox(openBox);
            }}
          />
        </>
      ) : (
        <div style={{
          padding:'22px 14px',textAlign:'center',
          background:'var(--break-bg)',borderRadius:12,
          border:'1px dashed var(--border-strong)',
          fontSize:12.5,color:'var(--mute)',lineHeight:1.5,
        }}>
          Pick a session above to see the live seat map.
        </div>
      )}
      {chosen !== null && mySeat && mySeat.d===day && mySeat.si===chosen && (
        <div style={{
          marginTop:10,padding:'10px 14px',
          background:'rgba(16,185,129,0.08)',border:'1px solid rgba(16,185,129,0.25)',
          borderRadius:10,fontSize:12.5,color:'var(--ink)',textAlign:'center',fontWeight:600,
        }}>
          <span style={{color:'#10b981',fontWeight:800}}>✓</span> Seat #{mySeat.seatIdx + 1} is yours
          {mySeat.plusN ? ` + ${mySeat.plusN} teammate${mySeat.plusN===1?'':'s'}` : ''} — lock it below.
        </div>
      )}
      {chosen !== null && myBoxId && !mySeat && (
        <div style={{
          marginTop:10,padding:'10px 14px',
          background:'rgba(251,191,36,0.1)',border:'1px solid rgba(251,191,36,0.35)',
          borderRadius:10,fontSize:12.5,color:'var(--ink)',textAlign:'center',fontWeight:600,
        }}>
          <span style={{color:'#b45309',fontWeight:800}}>★</span> Box {boxes.find(b=>b.id===myBoxId)?.letter} locked ·
          {' '}<strong>{boxes.find(b=>b.id===myBoxId)?.size} VIP seats</strong> — confirm below.
        </div>
      )}
      {chosen !== null && !mySeat && !myBoxId && (
        <div style={{
          marginTop:10,padding:'10px 14px',
          background:'var(--break-bg)',border:'1px dashed var(--border-strong)',
          borderRadius:10,fontSize:12.5,color:'var(--mute)',textAlign:'center',
        }}>
          👆 Tap a standard seat to claim, or host a VIP box above
        </div>
      )}
    </>
  );
}

// -----------------------------------------------------------------
// STYLE 4 — EXPRESS: one giant "next session" button + secondary list
// -----------------------------------------------------------------
function BookingExpress({ days, day, setDay, selected, setSelected, seats, countdown }) {
  const [expanded, setExpanded] = useState(false);
  const pick = (d, si) => { if (seats[d][si] === 0) return; setSelected({d, si}); setDay(d); };

  // Find the first non-full session (across all days)
  let nextD = 0, nextS = 0;
  outer: for (let d = 0; d < seats.length; d++) {
    for (let s = 0; s < seats[d].length; s++) { if (seats[d][s] > 0) { nextD = d; nextS = s; break outer; } }
  }
  const nextSlot = SLOT_HOURS[nextD][nextS];
  const nextSeats = seats[nextD][nextS];
  const nextDay = days[nextD];

  const grab = () => pick(nextD, nextS);
  const isSel = selected && selected.d === nextD && selected.si === nextS;

  return (
    <>
      <SessionsProof/>
      {/* Hero CTA */}
      <button onClick={grab} style={{
        width:'100%',padding:'22px 20px',
        background: isSel ? 'var(--card)' : BRAND.gradient,
        color: isSel ? 'var(--ink)' : '#fff',
        border: isSel ? '2px solid var(--purple)' : 'none',
        borderRadius:18,textAlign:'left',cursor:'pointer',
        boxShadow: isSel ? '0 10px 30px rgba(124,58,237,0.15)' : '0 20px 60px rgba(124,58,237,0.45)',
        transition:'all 0.25s',position:'relative',overflow:'hidden',
      }}>
        {!isSel && (
          <div style={{
            position:'absolute',inset:0,
            background:'linear-gradient(120deg, transparent 30%, rgba(255,255,255,0.18) 50%, transparent 70%)',
            backgroundSize:'200% 100%',
            animation:'apex-shimmer 3s linear infinite',pointerEvents:'none',
          }}/>
        )}
        <div style={{position:'relative',display:'flex',justifyContent:'space-between',alignItems:'center',gap:14}}>
          <div style={{flex:1,minWidth:0}}>
            <div style={{fontSize:10.5,fontWeight:800,letterSpacing:2,textTransform:'uppercase',
              color: isSel ? 'var(--purple)' : 'rgba(255,255,255,0.88)',marginBottom:4}}>
              {isSel ? '✓ Selected' : 'Next session'} · Starts in {countdown}
            </div>
            <div style={{fontSize:22,fontWeight:800,letterSpacing:'-0.5px',fontFamily:'DM Sans,sans-serif',lineHeight:1.1,marginBottom:3}}>
              {nextDay.short}, {nextSlot.time} PT
            </div>
            <div style={{fontSize:12,fontWeight:600,opacity:0.9}}>
              {nextSeats} of 60 seats open
            </div>
          </div>
          <span style={{
            flexShrink:0,width:40,height:40,borderRadius:'50%',
            background: isSel ? BRAND.gradient : 'rgba(255,255,255,0.22)',
            color:'#fff',display:'flex',alignItems:'center',justifyContent:'center',fontSize:18,fontWeight:700,
          }}>→</span>
        </div>
      </button>

      {/* Show all alternates toggle */}
      <button onClick={() => setExpanded(e => !e)} style={{
        width:'100%',marginTop:12,padding:'12px 14px',
        background:'transparent',border:'1px solid var(--border-strong)',
        borderRadius:12,color:'var(--mute)',fontFamily:'inherit',
        fontSize:12.5,fontWeight:700,letterSpacing:0.3,cursor:'pointer',
        display:'flex',alignItems:'center',justifyContent:'center',gap:8,
      }}>
        {expanded ? '− Hide other times' : '+ Or pick a different time'}
      </button>

      {expanded && (
        <div style={{marginTop:12,animation:'apex-fade-in 0.3s ease'}}>
          <div style={{display:'flex',gap:6,marginBottom:10,overflowX:'auto',scrollbarWidth:'none'}}>
            {days.map((d, i) => (
              <button key={i} onClick={() => setDay(i)} style={{
                flex:1,minWidth:90,padding:'9px 10px',
                background: day===i ? 'var(--card)' : 'var(--break-bg)',
                border: day===i ? '1.5px solid var(--purple)' : '1.5px solid transparent',
                borderRadius:10,color:'var(--ink)',fontSize:12,fontWeight:600,
                cursor:'pointer',textAlign:'center',flexShrink:0,
              }}>
                <span style={{display:'block',fontSize:9,letterSpacing:1.5,textTransform:'uppercase',
                  color: day===i ? 'var(--purple)' : 'var(--mute)',marginBottom:2,fontWeight:700}}>
                  {d.short}
                </span>
                {d.date}
              </button>
            ))}
          </div>
          {SLOT_HOURS[day].map((slot, si) => {
            const n = seats[day][si];
            const isFull = n === 0;
            const urgent = n > 0 && n <= 5;
            const isSelHere = selected && selected.d === day && selected.si === si;
            return (
              <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
                width:'100%',background: isSelHere ? 'var(--card)' : 'var(--break-bg)',
                border: isSelHere ? '1.5px solid var(--purple)' : '1.5px solid transparent',
                borderRadius:10,padding:'10px 14px',marginBottom:6,
                cursor: isFull ? 'not-allowed' : 'pointer',
                opacity: isFull ? 0.4 : 1,transition:'all 0.2s',
                display:'flex',alignItems:'center',justifyContent:'space-between',textAlign:'left',
                filter: isFull ? 'saturate(0)' : 'none',
              }}>
                <div style={{fontSize:13.5,fontWeight:700,color:'var(--ink)'}}>
                  {slot.time} <span style={{fontWeight:500,color:'var(--mute)',fontSize:11}}>PT</span>
                </div>
                <div style={{fontSize:11.5,fontWeight:600,color: isFull?'#ef4444':(urgent?'#ef4444':'var(--mute)')}}>
                  {isFull ? 'FULL' : <><strong>{n}</strong> left</>}
                </div>
              </button>
            );
          })}
        </div>
      )}
    </>
  );
}

// -----------------------------------------------------------------
// STYLE 5 — CALENDAR: mini month grid
// -----------------------------------------------------------------
function BookingCalendar({ days, day, setDay, selected, setSelected, seats }) {
  const pick = (d, si) => { if (seats[d][si] === 0) return; setSelected({d, si}); setDay(d); };

  // Build a mini-month grid centered on today
  const today = new Date();
  const year = today.getFullYear(), month = today.getMonth();
  const firstOfMonth = new Date(year, month, 1);
  const startDay = firstOfMonth.getDay(); // 0=Sun
  const daysInMonth = new Date(year, month+1, 0).getDate();
  const monthName = today.toLocaleDateString('en-US',{month:'long'});

  // Map date-of-month → days[] index (0/1/2)
  const dayOfMonthToIdx = {};
  days.forEach((d, i) => { dayOfMonthToIdx[d.raw.getDate()] = i; });

  const cells = [];
  for (let i = 0; i < startDay; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);

  return (
    <>
      <SessionsProof/>
      <div style={{
        background:'var(--card)',border:'1px solid var(--border)',borderRadius:16,
        padding:'14px 14px 10px',boxShadow:'var(--shadow)',marginBottom:14,
      }}>
        <div style={{
          textAlign:'center',fontSize:14,fontWeight:800,letterSpacing:0.3,
          color:'var(--ink)',marginBottom:10,fontFamily:'DM Sans,sans-serif',
        }}>
          {monthName} {year}
        </div>
        <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:3,marginBottom:6}}>
          {['S','M','T','W','T','F','S'].map((d,i) => (
            <div key={i} style={{
              fontSize:10,fontWeight:800,letterSpacing:1,color:'var(--mute)',textAlign:'center',padding:'3px 0',
            }}>{d}</div>
          ))}
        </div>
        <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:3}}>
          {cells.map((d, i) => {
            if (d === null) return <div key={i}/>;
            const idx = dayOfMonthToIdx[d];
            const available = idx !== undefined;
            const isToday = d === today.getDate();
            const isSelected = available && day === idx;
            return (
              <button key={i}
                onClick={() => available && setDay(idx)}
                disabled={!available}
                style={{
                  aspectRatio:'1/1',border:'none',
                  background: isSelected ? BRAND.gradient : (available ? 'rgba(124,58,237,0.08)' : 'transparent'),
                  color: isSelected ? '#fff' : (available ? 'var(--ink)' : 'var(--dim)'),
                  fontSize:12.5,fontWeight: isSelected ? 800 : (available ? 700 : 500),
                  borderRadius:8,cursor: available ? 'pointer' : 'default',
                  transition:'all 0.15s',position:'relative',padding:0,
                  fontFamily:'DM Sans,sans-serif',
                  boxShadow: isToday && !isSelected ? 'inset 0 0 0 1.5px var(--purple)' : 'none',
                }}>
                {d}
                {available && !isSelected && (
                  <span style={{
                    position:'absolute',bottom:3,left:'50%',transform:'translateX(-50%)',
                    width:4,height:4,borderRadius:'50%',background:'#10b981',
                  }}/>
                )}
              </button>
            );
          })}
        </div>
        <div style={{
          fontSize:10.5,color:'var(--mute)',textAlign:'center',marginTop:8,
          letterSpacing:0.3,display:'flex',justifyContent:'center',gap:12,
        }}>
          <span style={{display:'inline-flex',alignItems:'center',gap:4}}>
            <span style={{width:4,height:4,borderRadius:'50%',background:'#10b981'}}/>
            Available
          </span>
          <span style={{display:'inline-flex',alignItems:'center',gap:4}}>
            <span style={{width:8,height:8,borderRadius:'50%',background:BRAND.gradient}}/>
            Selected
          </span>
        </div>
      </div>
      {/* Slot list for the selected day */}
      <div style={{fontSize:11,fontWeight:800,letterSpacing:1.5,textTransform:'uppercase',color:'var(--mute)',marginBottom:8}}>
        Sessions on {days[day].short} {days[day].date}
      </div>
      {SLOT_HOURS[day].map((slot, si) => {
        const n = seats[day][si];
        const isFull = n === 0;
        const urgent = n > 0 && n <= 5;
        const isSel = selected && selected.d === day && selected.si === si;
        return (
          <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
            width:'100%',background: isSel ? 'var(--card)' : 'var(--break-bg)',
            border: isSel ? '1.5px solid var(--purple)' : '1.5px solid transparent',
            borderRadius:12,padding:'14px 16px',marginBottom:8,
            cursor: isFull ? 'not-allowed' : 'pointer',
            opacity: isFull ? 0.45 : 1,transition:'all 0.2s',
            display:'flex',alignItems:'center',justifyContent:'space-between',gap:10,textAlign:'left',
            filter: isFull ? 'saturate(0)' : 'none',
          }}>
            <div style={{minWidth:0,flex:1}}>
              <div style={{fontSize:15,fontWeight:700,color:'var(--ink)',whiteSpace:'nowrap',textDecoration: isFull?'line-through':'none'}}>{slot.time}</div>
              <div style={{fontSize:10.5,color:'var(--mute)',marginTop:2,letterSpacing:1,fontWeight:500}}>{slot.tz}</div>
            </div>
            <div style={{fontSize:12,fontWeight:600,color: isFull?'#ef4444':(urgent?'#ef4444':'var(--mute)'),flexShrink:0,whiteSpace:'nowrap'}}>
              {isFull ? 'FULL' : <><strong style={{color:'var(--ink)'}}>{n}</strong> left</>}
            </div>
          </button>
        );
      })}
    </>
  );
}

// -----------------------------------------------------------------
// STYLE 6 — CHAT: Apex texts you; you pick best/next-best/other
// -----------------------------------------------------------------
function BookingChat({ days, day, setDay, selected, setSelected, seats, countdown }) {
  const pick = (d, si) => { if (seats[d][si] === 0) return; setSelected({d, si}); setDay(d); };

  // Find 2 recommended — next non-full + one "alternate" from tomorrow
  let best = null;
  outer: for (let d = 0; d < seats.length; d++) {
    for (let s = 0; s < seats[d].length; s++) { if (seats[d][s] > 0) { best = {d, si: s}; break outer; } }
  }
  let alt = null;
  if (best) {
    const startD = Math.min(best.d + 1, seats.length - 1);
    altOuter: for (let d = startD; d < seats.length; d++) {
      for (let s = 0; s < seats[d].length; s++) {
        if (seats[d][s] > 0 && !(d === best.d && s === best.si)) { alt = {d, si: s}; break altOuter; }
      }
    }
  }
  const [showMore, setShowMore] = useState(false);

  const Bubble = ({ children, from='apex' }) => (
    <div style={{
      background: from==='apex' ? 'var(--break-bg)' : BRAND.gradient,
      color: from==='apex' ? 'var(--ink)' : '#fff',
      borderRadius: from==='apex' ? '18px 18px 18px 4px' : '18px 18px 4px 18px',
      padding:'11px 14px',fontSize:13.5,lineHeight:1.45,
      maxWidth:'88%',
      marginLeft: from==='apex' ? 0 : 'auto',marginRight: from==='apex' ? 'auto' : 0,
      marginBottom:6,boxShadow:'var(--shadow)',
    }}>{children}</div>
  );

  const RecCard = ({ slot, info, label, tone='primary' }) => {
    const isSel = selected && selected.d === info.d && selected.si === info.si;
    return (
      <button onClick={() => pick(info.d, info.si)} style={{
        width:'100%',background: isSel ? 'var(--card)' : (tone==='primary' ? BRAND.gradient : 'var(--break-bg)'),
        color: isSel ? 'var(--ink)' : (tone==='primary' ? '#fff' : 'var(--ink)'),
        border: isSel ? '2px solid var(--purple)' : 'none',
        borderRadius:16,padding:'16px 18px',marginBottom:8,
        cursor:'pointer',textAlign:'left',
        boxShadow: isSel ? '0 10px 30px rgba(124,58,237,0.2)' : (tone==='primary' ? '0 14px 40px rgba(124,58,237,0.32)' : 'var(--shadow)'),
        transition:'all 0.2s',display:'flex',justifyContent:'space-between',alignItems:'center',gap:10,
      }}>
        <div style={{minWidth:0,flex:1}}>
          <div style={{fontSize:10,fontWeight:800,letterSpacing:2,textTransform:'uppercase',
            color: isSel ? 'var(--purple)' : (tone==='primary' ? 'rgba(255,255,255,0.85)' : 'var(--mute)'),marginBottom:3,whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
            {isSel ? '✓ Selected' : label}
          </div>
          <div style={{fontSize:17,fontWeight:800,fontFamily:'DM Sans,sans-serif',letterSpacing:'-0.3px',lineHeight:1.1,whiteSpace:'nowrap'}}>
            {days[info.d].short} · {slot.time} PT
          </div>
          <div style={{fontSize:11.5,fontWeight:600,opacity:0.9,marginTop:3}}>
            {seats[info.d][info.si]} of 60 seats open
          </div>
        </div>
        <span style={{
          flexShrink:0,width:32,height:32,borderRadius:'50%',
          background: tone==='primary' && !isSel ? 'rgba(255,255,255,0.22)' : 'rgba(124,58,237,0.12)',
          color: tone==='primary' && !isSel ? '#fff' : BRAND.purple,
          display:'flex',alignItems:'center',justifyContent:'center',fontSize:15,fontWeight:700,
        }}>→</span>
      </button>
    );
  };

  return (
    <>
      <div style={{
        display:'flex',alignItems:'center',gap:10,marginBottom:12,padding:'10px 12px',
        background:'var(--break-bg)',borderRadius:12,
      }}>
        <div style={{
          width:30,height:30,borderRadius:'50%',flexShrink:0,
          background:BRAND.gradient,display:'flex',alignItems:'center',justifyContent:'center',
          color:'#fff',fontSize:13,fontWeight:800,
        }}>A</div>
        <div style={{flex:1,minWidth:0}}>
          <div style={{fontSize:13,fontWeight:800,color:'var(--ink)'}}>Apex</div>
          <div style={{fontSize:10.5,color:'#10b981',fontWeight:600,display:'flex',alignItems:'center',gap:5}}>
            <LiveDot color="#10b981" size={5}/> Active now
          </div>
        </div>
      </div>

      <Bubble>Hey — ready to lock in your session?</Bubble>
      <Bubble>Based on when you're on this page, these are your best picks 👇</Bubble>

      {best && <RecCard slot={SLOT_HOURS[best.d][best.si]} info={best} label={`Best · starts in ${countdown}`} tone="primary"/>}
      {alt && <RecCard slot={SLOT_HOURS[alt.d][alt.si]} info={alt} label="Next best"/>}

      <Bubble>Both FREE. Both live. Either one works.</Bubble>

      <button onClick={() => setShowMore(m=>!m)} style={{
        width:'100%',marginTop:6,padding:'10px 14px',
        background:'transparent',border:'1px solid var(--border-strong)',
        borderRadius:10,color:'var(--mute)',fontFamily:'inherit',
        fontSize:12,fontWeight:700,letterSpacing:0.3,cursor:'pointer',
      }}>
        {showMore ? '− Close the full picker' : '+ Show me all the times'}
      </button>

      {showMore && (
        <div style={{marginTop:14,animation:'apex-fade-in 0.3s ease'}}>
          <div style={{display:'flex',gap:6,marginBottom:10,overflowX:'auto',scrollbarWidth:'none'}}>
            {days.map((d, i) => (
              <button key={i} onClick={() => setDay(i)} style={{
                flex:1,minWidth:90,padding:'9px 10px',
                background: day===i ? 'var(--card)' : 'var(--break-bg)',
                border: day===i ? '1.5px solid var(--purple)' : '1.5px solid transparent',
                borderRadius:10,color:'var(--ink)',fontSize:12,fontWeight:600,
                cursor:'pointer',textAlign:'center',flexShrink:0,
              }}>
                <span style={{display:'block',fontSize:9,letterSpacing:1.5,textTransform:'uppercase',
                  color: day===i ? 'var(--purple)' : 'var(--mute)',marginBottom:2,fontWeight:700}}>
                  {d.short}
                </span>
                {d.date}
              </button>
            ))}
          </div>
          {SLOT_HOURS[day].map((slot, si) => {
            const n = seats[day][si];
            const isFull = n === 0;
            const isSel = selected && selected.d === day && selected.si === si;
            return (
              <button key={si} onClick={() => pick(day, si)} disabled={isFull} style={{
                width:'100%',background: isSel ? 'var(--card)' : 'var(--break-bg)',
                border: isSel ? '1.5px solid var(--purple)' : '1.5px solid transparent',
                borderRadius:10,padding:'10px 14px',marginBottom:6,
                cursor: isFull ? 'not-allowed' : 'pointer',
                opacity: isFull ? 0.4 : 1,transition:'all 0.2s',
                display:'flex',alignItems:'center',justifyContent:'space-between',textAlign:'left',
                filter: isFull ? 'saturate(0)' : 'none',
              }}>
                <div style={{fontSize:13.5,fontWeight:700,color:'var(--ink)'}}>
                  {slot.time}
                </div>
                <div style={{fontSize:11.5,fontWeight:600,color: isFull?'#ef4444':'var(--mute)'}}>
                  {isFull ? 'FULL' : <><strong>{n}</strong> left</>}
                </div>
              </button>
            );
          })}
        </div>
      )}
    </>
  );
}

// -----------------------------------------------------------------
// Router
// -----------------------------------------------------------------
function BookingBody(props) {
  const { tweaks } = useApp();
  const style = tweaks.bookingStyle || 'classic';
  if (style === 'wheel') return <BookingWheel {...props}/>;
  if (style === 'stadium') return <BookingStadium {...props}/>;
  if (style === 'express') return <BookingExpress {...props}/>;
  if (style === 'calendar') return <BookingCalendar {...props}/>;
  if (style === 'chat') return <BookingChat {...props}/>;
  return <BookingClassic {...props}/>;
}

Object.assign(window, {
  BookingBody, SessionsProof, LiveBookingPing, WhatHappensNext,
  BookingClassic, BookingWheel, BookingStadium, BookingExpress, BookingCalendar, BookingChat,
});
