// Mobile screens — separate views for phone device. Mirrors the V2 wireframes.
// Hooks into the same App router/ctx so flows work identically on either device.

const STEPS_M = ['DETAILS', 'WAIVER', 'CONFIRM'];

// Tight field for mobile forms
const MField = ({ label, value, onChange, ph, type = 'text', error }) => (
  <label style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
    <span style={{ fontFamily: "'JetBrains Mono',monospace", fontSize: 9, color: error ? T.red : T.mute, letterSpacing: 0.5 }}>
      {label}{error ? ' · ' + error : ''}
    </span>
    <input
      type={type}
      value={value || ''}
      placeholder={ph || ''}
      onChange={(e) => onChange?.(e.target.value)}
      style={{
        height: 38, padding: '0 10px',
        background: 'transparent',
        border: `1px solid ${error ? T.red : T.rule}`,
        color: T.bone,
        fontFamily: "'JetBrains Mono',monospace",
        fontSize: 13,
        outline: 'none',
      }}
    />
  </label>
);

// ─── LANDING ─────────────────────────────────────────────────────────
const LandingMobile = ({ go }) => {
  const [about] = useAboutContent();
  const events = useActiveEvents();
  const [hero] = useHeroVideo();
  const eventsRef = React.useRef(null);
  const nextEvent = events[0];
  const scrollToEvents = () => {
    const target = eventsRef.current;
    if (!target) return;
    let parent = target.parentElement;
    while (parent && parent !== document.body) {
      const oy = getComputedStyle(parent).overflowY;
      if ((oy === 'auto' || oy === 'scroll') && parent.scrollHeight > parent.clientHeight) break;
      parent = parent.parentElement;
    }
    if (!parent) { target.scrollIntoView({ block: 'start' }); return; }
    parent.scrollTop = target.getBoundingClientRect().top - parent.getBoundingClientRect().top + parent.scrollTop - 4;
  };
  return (
  <div style={{ background: T.bg, color: T.bone, height: '100%', overflowY: 'auto', scrollBehavior: 'smooth' }}>
    {/* Top bar */}
    <div style={{ padding: '12px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `1px solid ${T.rule}` }}>
      <SWLockup size={0.8} />
    </div>

    {/* Hero — full-bleed media with centered type overlaid */}
    <div style={{ position: 'relative' }}>
      <TerrainSlot h={460} src={hero.src} mediaType={hero.meta?.type || 'video/mp4'} objectPosition="center" style={{ background: T.bg }}>
        <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(14,14,16,0.6) 0%, rgba(14,14,16,0.18) 40%, rgba(14,14,16,0.98) 100%)' }} />
        <div style={{ position: 'absolute', inset: 0, padding: '20px 18px 22px', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', textAlign: 'center' }}>
          <Mono size={10} color={T.gold}>// 2026 COUNTRY EVENT SERIES</Mono>
          <Bebas size={52} color={T.bone} style={{ marginTop: 8, lineHeight: 0.92, display: 'block', letterSpacing: '-0.005em' }}>SPECIAL WARFARE<br/>TRAINING DAY.</Bebas>
          <Body size={14} color={T.bone} style={{ marginTop: 10 }}>
            Six cities. One standard. Show up, see what the pipeline asks of you.
          </Body>
          {events.length > 0 && (
            <div style={{ marginTop: 16 }}>
              <PrimaryCTA onClick={scrollToEvents} style={{ fontSize: 13, padding: '11px 16px', textAlign: 'center', width: '100%' }}>
                ↓ Click a location to sign up
              </PrimaryCTA>
            </div>
          )}
        </div>
      </TerrainSlot>
    </div>

    {/* Tour stops */}
    <div ref={eventsRef} style={{ padding: '24px 18px 28px' }}>
      <Mono size={10} color={T.gold}>// 01 UPCOMING EVENTS</Mono>
      <Bebas size={36} as="h2" style={{ marginTop: 6, marginBottom: 14, lineHeight: 0.94, display: 'block' }}>UPCOMING EVENTS.</Bebas>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        {events.map(e => {
          return (
            <button key={e.code} onClick={() => go('signup', { eventCode: e.code })} style={{
              display: 'block', textAlign: 'left', width: '100%',
              border: `1px solid ${T.rule}`, padding: '14px',
              background: 'transparent', color: T.bone, cursor: 'pointer',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                <div>
                  <Bebas size={22}>{e.city}</Bebas>
                  <Mono size={9} color={T.mute} style={{ display: 'block', marginTop: 2 }}>{e.state} · {e.date} · {e.venue.split('·')[0].trim()}</Mono>
                </div>
              </div>
              <div style={{ marginTop: 10, paddingTop: 10, borderTop: `1px solid ${T.rule}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <Mono size={9} color={T.mute}>FREE · CANDIDATE PORTAL</Mono>
                <Bebas size={13} color={T.bone}>Sign up →</Bebas>
              </div>
            </button>
          );
        })}
      </div>
    </div>

    {/* About — what is Training Day */}
    <div style={{ background: T.bg2, borderTop: `1px solid ${T.rule}`, padding: '32px 18px 32px' }}>
      <Mono size={10} color={T.gold}>// 02 ABOUT THE EVENT</Mono>
      <Bebas size={40} as="h2" style={{ marginTop: 8, lineHeight: 0.94, display: 'block' }}>{about.headline}</Bebas>
      {about.intro.map((p, i) => (
        <Body key={i} size={14} color={T.bone} style={{ marginTop: i === 0 ? 14 : 12, display: 'block' }}>{p}</Body>
      ))}

      <div style={{ marginTop: 26 }}>
        <Mono size={10} color={T.mute}>// WHAT TO EXPECT</Mono>
        <div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 10 }}>
          {about.expect.map(b => (
            <div key={b.num} style={{ border: `1px solid ${T.rule}`, padding: '14px', background: T.bg }}>
              <Mono size={9} color={T.mute}>EVENT · {b.num}</Mono>
              <Bebas size={22} style={{ marginTop: 4, display: 'block', lineHeight: 1 }}>{b.title}</Bebas>
              <Body size={12} color={T.bone} style={{ marginTop: 8, display: 'block' }}>{b.body}</Body>
            </div>
          ))}
        </div>
      </div>

      <div style={{ marginTop: 26 }}>
        <Mono size={10} color={T.mute}>// WHO SHOULD COME</Mono>
        <div style={{ marginTop: 8, borderTop: `1px solid ${T.rule}` }}>
          {about.who.map((w, i) => (
            <div key={i} style={{ padding: '12px 0', borderBottom: `1px solid ${T.rule}` }}>
              <Mono size={10} color={T.gold}>{w.label}</Mono>
              <Body size={12} color={T.bone} style={{ marginTop: 6, display: 'block' }}>{w.text}</Body>
            </div>
          ))}
        </div>
      </div>

      <div style={{ marginTop: 24, borderLeft: `3px solid ${T.gold}`, padding: '12px 14px', background: T.bg }}>
        <Mono size={9} color={T.gold}>// THE BOTTOM LINE</Mono>
        <Body size={14} color={T.bone} style={{ marginTop: 6, display: 'block' }}>{about.bottomLine}</Body>
      </div>
    </div>

    {/* Final CTA — for visitors who scrolled all the way through. */}
    {events.length > 0 && (
      <div style={{ padding: '40px 18px 36px', borderTop: `1px solid ${T.rule}`, textAlign: 'center' }}>
        <Mono size={9} color={T.gold} style={{ display: 'block' }}>// READY TO SHOW UP?</Mono>
        <Bebas size={32} as="h2" style={{ marginTop: 8, lineHeight: 0.95, display: 'block' }}>PICK A LOCATION.</Bebas>
        <Body size={13} color={T.mute} style={{ marginTop: 10, display: 'block' }}>
          Free. Sign up takes about three minutes.
        </Body>
        <PrimaryCTA onClick={scrollToEvents} style={{ fontSize: 13, padding: '12px 18px', marginTop: 16, width: '100%' }}>
          ↑ See events
        </PrimaryCTA>
      </div>
    )}

    {/* Footer — lockup + AFSW logo + tagline. Admin entry is hidden;
        recruiters navigate to /#admin directly. */}
    <div style={{ padding: '20px 18px', borderTop: `1px solid ${T.rule}`, display: 'flex', flexDirection: 'column', gap: 14, alignItems: 'stretch' }}>
      <div style={{ display: 'flex', justifyContent: 'center' }}>
        <SWLockup size={0.7} />
      </div>
      <div style={{ display: 'flex', justifyContent: 'center' }}>
        <div style={{ background: T.bone, padding: '5px 10px', display: 'flex', alignItems: 'center' }}>
          <img
            src="media/slideshow/01-special-warfare.png"
            alt="U.S. Air Force Special Warfare"
            onError={e => { e.currentTarget.parentElement.style.display = 'none'; }}
            style={{ height: 24, width: 'auto', display: 'block' }}
          />
        </div>
      </div>
      <Mono size={9} color={T.mute} style={{ textAlign: 'center' }}>SW TRAINING DAY · 2026 SERIES</Mono>
    </div>
  </div>
  );
};

// ─── SIGNUP STEPPER (mobile compact) ─────────────────────────────────
const StepperMobile = ({ step }) => (
  <div style={{ padding: '12px 14px 4px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
    {STEPS_M.map((s, i) => (
      <React.Fragment key={s}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
          <div style={{
            width: 22, height: 22,
            background: i < step ? T.gold : (i === step ? T.blue2 : 'transparent'),
            border: `1px solid ${i <= step ? (i < step ? T.gold : T.blue2) : T.rule}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}><Mono size={10} color={i < step ? T.bg : T.bone}>{i < step ? '✓' : i + 1}</Mono></div>
          <Mono size={7} color={i === step ? T.bone : T.mute}>{s}</Mono>
        </div>
        {i < STEPS_M.length - 1 && <div style={{ flex: 1, height: 1, background: i < step ? T.gold : T.rule, margin: '0 4px', marginBottom: 12 }} />}
      </React.Fragment>
    ))}
  </div>
);

// ─── DETAILS step (mobile) ───────────────────────────────────────────
const DetailsMobile = ({ ctx, setCtx, go }) => {
  const age = window.calcAge(ctx.birthday);
  const isMinor = age !== null && age < 18;
  const careers = Array.isArray(ctx.careers) ? ctx.careers : [];
  const toggleCareer = (code) => {
    setCtx(prev => {
      const list = Array.isArray(prev.careers) ? prev.careers : [];
      return { careers: list.includes(code) ? list.filter(c => c !== code) : [...list, code] };
    });
  };
  const emailOk = window.isValidEmail(ctx.email);
  const phoneOk = window.isValidPhone(ctx.phone);
  const birthdayOk = window.isValidBirthday(ctx.birthday);
  const guardianEmailOk = window.isValidEmail(ctx.guardianEmail);
  const guardianPhoneOk = !ctx.guardianPhone || window.isValidPhone(ctx.guardianPhone);
  const canContinue = !!(
    ctx.first?.trim() && ctx.last?.trim() &&
    emailOk && phoneOk && birthdayOk &&
    careers.length > 0 &&
    (!isMinor || (ctx.guardianName?.trim() && guardianEmailOk && guardianPhoneOk))
  );

  return (
    <div style={{ padding: '4px 14px 28px', display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div>
        <Mono size={9} color={T.mute}>// STEP 01 OF 03</Mono>
        <Bebas size={24} style={{ marginTop: 2, display: 'block', lineHeight: 1.05 }}>Your details.</Bebas>
      </div>
      <MField label="FIRST NAME *" value={ctx.first} onChange={v => setCtx({ first: v })} />
      <MField label="LAST NAME *" value={ctx.last} onChange={v => setCtx({ last: v })} />
      <MField label="EMAIL *" type="email" value={ctx.email} onChange={v => setCtx({ email: v })}
        error={ctx.email && !emailOk ? 'INVALID' : undefined} />
      <MField label="BIRTHDAY *" value={ctx.birthday} onChange={v => setCtx({ birthday: formatDate(v) })} ph="MM/DD/YYYY"
        error={ctx.birthday && !birthdayOk ? 'CHECK DATE / 14–80' : undefined} />
      <MField label="PHONE *" value={ctx.phone} onChange={v => setCtx({ phone: formatPhone(v) })} ph="(555) 555-5555"
        error={ctx.phone && !phoneOk ? 'INCOMPLETE' : undefined} />

      {isMinor && (
        <div style={{ padding: 12, border: `1px solid ${T.gold}`, background: 'rgba(200,168,78,0.06)', display: 'flex', flexDirection: 'column', gap: 8 }}>
          <Mono size={9} color={T.gold}>// GUARDIAN INFO REQUIRED</Mono>
          <MField label="GUARDIAN NAME *" value={ctx.guardianName} onChange={v => setCtx({ guardianName: v })} />
          <MField label="GUARDIAN EMAIL *" value={ctx.guardianEmail} onChange={v => setCtx({ guardianEmail: v })}
            error={ctx.guardianEmail && !guardianEmailOk ? 'INVALID' : undefined} />
          <MField label="GUARDIAN PHONE" value={ctx.guardianPhone} onChange={v => setCtx({ guardianPhone: formatPhone(v) })} ph="(555) 555-5555"
            error={ctx.guardianPhone && !guardianPhoneOk ? 'INCOMPLETE' : undefined} />
        </div>
      )}

      <div style={{ marginTop: 4 }}>
        <Mono size={9} color={T.mute}>CAREER INTEREST · pick all that apply{careers.length > 0 ? ` · ${careers.length} selected` : ''}</Mono>
        <div style={{ marginTop: 6, display: 'flex', flexWrap: 'wrap', gap: 4 }}>
          {CAREER_FIELDS.map(c => {
            const active = careers.includes(c.code);
            return (
              <button key={c.code} onClick={() => toggleCareer(c.code)} style={{
                padding: '4px 8px',
                border: `1px solid ${active ? T.gold : T.rule}`,
                background: active ? 'rgba(200,168,78,0.12)' : 'transparent',
                color: active ? T.gold : T.bone,
                fontFamily: "'JetBrains Mono',monospace",
                fontSize: 10, letterSpacing: 0.5, cursor: 'pointer',
              }}>{active ? '✓ ' : ''}{c.code}</button>
            );
          })}
        </div>
      </div>

      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 10 }}>
        <button onClick={() => go('landing')} style={{ background: 'transparent', border: 'none', color: T.mute, fontFamily: "'JetBrains Mono',monospace", fontSize: 10, cursor: 'pointer' }}>← Back</button>
        <PrimaryCTA blue disabled={!canContinue} onClick={() => go('signup', { step: 1 })}>Continue →</PrimaryCTA>
      </div>
    </div>
  );
};

// ─── WAIVER step (mobile) ────────────────────────────────────────────
const WaiverMobile = ({ ctx, setCtx, go, event }) => {
  const [unlocked, setUnlocked] = React.useState(false);
  const [progress, setProgress] = React.useState(0);
  const [mode, setMode] = React.useState('type');
  const [busy, setBusy] = React.useState(false);
  const [submitError, setSubmitError] = React.useState('');
  const fullName = `${ctx.first || ''} ${ctx.last || ''}`.trim();
  const isMinor = ctx.guardianName ? true : false;

  const onScroll = (e) => {
    const el = e.currentTarget;
    const max = el.scrollHeight - el.clientHeight;
    const p = max > 0 ? Math.min(1, el.scrollTop / max) : 1;
    setProgress(p);
    if (p >= 0.95) setUnlocked(true);
  };

  const sigOk = mode === 'type' ? (ctx.typedSig && ctx.typedSig.trim().length > 1) : ctx.drawnSig === 'drawn';
  const guardianSigOk = !isMinor || (ctx.guardianTypedSig && ctx.guardianTypedSig.trim().length > 1);
  const canConfirm = unlocked && sigOk && guardianSigOk;

  return (
    <div style={{ padding: '4px 14px 28px' }}>
      <Mono size={9} color={T.mute}>// STEP 02 OF 03 · LIABILITY RELEASE</Mono>
      <Bebas size={22} style={{ marginTop: 2, display: 'block' }}>Waiver · review & sign.</Bebas>

      <div style={{ marginTop: 12, border: `1px solid ${T.rule}`, position: 'relative' }}>
        <div onScroll={onScroll} style={{ height: 240, overflowY: 'auto', padding: 14 }}>
          <Mono size={8} color={T.gold} style={{ display: 'block', marginBottom: 4 }}>// LIABILITY RELEASE AND EXPRESS ASSUMPTION OF RISK</Mono>
          <Mono size={8} color={T.mute} style={{ display: 'block', marginBottom: 10 }}>AIR FORCE SPECIAL WARFARE TRAINING ACTIVITIES · {event.city}, {event.state} · {event.date}</Mono>
          <Body size={12} color={T.bone}>
            {WAIVER_OPENER_BEFORE}<span style={{ color: T.gold }}>{fullName || '(your name)'}</span>{WAIVER_OPENER_AFTER}
          </Body>
          {WAIVER_TEXT.map((p, i) => (
            <Body key={i} size={12} color={T.bone} style={{ display: 'block', marginTop: 10 }}>{p}</Body>
          ))}
          <Body size={11} color={T.mute} style={{ display: 'block', marginTop: 14 }}>
            Last revised: 06 MAY 2026 · USAF / AFSPECWAR · Previous edition is obsolete.
          </Body>
        </div>
        <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 3, background: T.rule }}>
          <div style={{ height: '100%', width: (progress * 100) + '%', background: unlocked ? T.gold : T.blue2, transition: 'width .1s' }} />
        </div>
      </div>

      <Mono size={9} color={unlocked ? T.gold : T.mute} style={{ display: 'block', marginTop: 6 }}>
        {unlocked ? '✓ WAIVER REVIEWED' : `SCROLL TO UNLOCK · ${Math.round(progress * 100)}%`}
      </Mono>

      <div style={{ marginTop: 16, opacity: unlocked ? 1 : 0.4, pointerEvents: unlocked ? 'auto' : 'none' }}>
        <Mono size={9} color={T.mute}>// CANDIDATE SIGNATURE</Mono>
        <div style={{ display: 'flex', gap: 4, marginTop: 6 }}>
          {['type', 'draw'].map(m => (
            <button key={m} onClick={() => setMode(m)} style={{
              padding: '4px 10px',
              background: mode === m ? T.bone : 'transparent',
              color: mode === m ? T.bg : T.bone,
              border: `1px solid ${T.bone}`,
              fontFamily: "'JetBrains Mono',monospace", fontSize: 10, cursor: 'pointer',
            }}>{m.toUpperCase()}</button>
          ))}
        </div>
        <div style={{ marginTop: 8 }}>
          {mode === 'type' ? (
            <input
              value={ctx.typedSig || fullName}
              onChange={e => setCtx({ typedSig: e.target.value })}
              style={{ width: '100%', padding: 10, background: T.bg2, border: `1px solid ${T.rule}`, color: T.bone, fontFamily: "'Caveat',cursive", fontSize: 26, outline: 'none' }}
            />
          ) : (
            <div style={{ height: 70, border: `1px solid ${T.rule}`, background: T.bg2, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
                 onTouchStart={() => setCtx({ drawnSig: 'drawn' })}
                 onMouseDown={() => setCtx({ drawnSig: 'drawn' })}>
              <Mono size={10} color={ctx.drawnSig === 'drawn' ? T.gold : T.mute}>
                {ctx.drawnSig === 'drawn' ? '✓ SIGNATURE CAPTURED' : 'TAP TO SIGN'}
              </Mono>
            </div>
          )}
        </div>
        {isMinor && (
          <div style={{ marginTop: 14, padding: 12, border: `1px solid ${T.gold}`, background: 'rgba(200,168,78,0.06)' }}>
            <Mono size={9} color={T.gold}>// GUARDIAN CO-SIGN</Mono>
            <input
              value={ctx.guardianTypedSig || ctx.guardianName || ''}
              onChange={e => setCtx({ guardianTypedSig: e.target.value })}
              style={{ width: '100%', marginTop: 6, padding: 8, background: T.bg2, border: `1px solid ${T.rule}`, color: T.bone, fontFamily: "'Caveat',cursive", fontSize: 22, outline: 'none' }}
            />
          </div>
        )}
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'stretch', gap: 6, marginTop: 18 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <button onClick={() => go('signup', { step: 0 })} style={{ background: 'transparent', border: 'none', color: T.mute, fontFamily: "'JetBrains Mono',monospace", fontSize: 10, cursor: 'pointer' }}>← Back</button>
          <PrimaryCTA blue disabled={!canConfirm || busy} style={{ opacity: busy ? 0.6 : 1 }} onClick={async () => {
            if (busy) return;
            setBusy(true); setSubmitError('');
            const signedAt = new Date().toISOString();
            const body = {
              eventCode: event.code,
              first: ctx.first, last: ctx.last,
              email: ctx.email, phone: ctx.phone, birthday: ctx.birthday,
              careers: ctx.careers || [],
              waiver: {
                signatureType: mode,
                ...(mode === 'type' ? { typedSig: ctx.typedSig || fullName } : { drawnSig: ctx.drawnSig || 'drawn' }),
                signedAt,
              },
            };
            if (isMinor) {
              body.guardianName = ctx.guardianName;
              body.guardianEmail = ctx.guardianEmail;
              body.guardianPhone = ctx.guardianPhone;
              body.waiver.guardianTypedSig = ctx.guardianTypedSig || ctx.guardianName;
              body.waiver.guardianSignatureType = 'type';
              body.waiver.guardianSignedAt = signedAt;
            }
            try {
              const r = await window.api.apiPost('/api/signup', body);
              setCtx({ confirmNum: r.confirmationNumber, signedAt });
              go('signup', { step: 2 });
            } catch (e) {
              const fields = e.fields ? ` (${e.fields.join(', ')})` : '';
              setSubmitError(`${e.message}${fields}`);
            } finally {
              setBusy(false);
            }
          }}>{busy ? 'Submitting…' : 'Confirm →'}</PrimaryCTA>
        </div>
        {submitError && <Mono size={9} color={T.red} style={{ textAlign: 'right' }}>{submitError}</Mono>}
      </div>
    </div>
  );
};

// ─── CONFIRM step (mobile) ───────────────────────────────────────────
const ConfirmMobile = ({ ctx, go, event }) => {
  const fullName = `${ctx.first || 'Candidate'} ${ctx.last || ''}`.trim();
  const careerCodes = Array.isArray(ctx.careers) ? ctx.careers : (ctx.career ? [ctx.career] : []);
  const careerLabel = careerCodes.length === 0 ? '—' : careerCodes.join(' · ');
  const [resources] = useResources();
  const cal = window.buildCalendarPayload(event, ctx, fullName);

  return (
    <div>
      <div style={{ position: 'relative' }}>
        <TerrainSlot h={220}>
          <CornerStamp time="0600" place={`${event.city}, ${event.state}`} />
          <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(14,14,16,0.3) 0%, rgba(14,14,16,0.95) 100%)' }} />
          <div style={{ position: 'absolute', inset: 0, padding: '36px 18px 18px', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }}>
            <Mono size={9} color={T.gold} style={{ display: 'block' }}>// REGISTRATION CONFIRMED</Mono>
            <Bebas size={56} color={T.bone} style={{ marginTop: 6, lineHeight: 0.88, display: 'block' }}>YOU'RE IN.</Bebas>
            <Mono size={10} color={T.bone} style={{ marginTop: 6, display: 'block' }}>{ctx.confirmNum || 'AFSW-XXX-XXXX'}</Mono>
          </div>
        </TerrainSlot>
      </div>

      <div style={{ padding: '20px 18px', borderBottom: `1px solid ${T.rule}` }}>
        <Mono size={9} color={T.mute} style={{ display: 'block' }}>// EVENT</Mono>
        <Bebas size={24} style={{ marginTop: 4, display: 'block' }}>{event.city}, {event.state}</Bebas>
        <Mono size={11} color={T.bone} style={{ display: 'block', marginTop: 6 }}>{event.date} · {event.startTime || '0600'} LOCAL</Mono>
        <Mono size={10} color={T.mute} style={{ display: 'block', marginTop: 2 }}>{event.venue}</Mono>
        <Body size={12} color={T.mute} style={{ marginTop: 8 }}>Final time and address sent via email when finalized.</Body>
        <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
          <a href={cal.googleUrl} target="_blank" rel="noopener noreferrer"
             style={{ flex: 1, padding: '10px', background: T.blue2, color: T.bone, border: 'none', fontFamily: "'Bebas Neue',sans-serif", fontSize: 12, textAlign: 'center', textDecoration: 'none' }}>
            + Google Calendar
          </a>
          <button onClick={() => window.downloadIcs(cal)}
                  style={{ flex: 1, padding: '10px', background: 'transparent', color: T.bone, border: `1px solid ${T.bone}`, fontFamily: "'Bebas Neue',sans-serif", fontSize: 12, cursor: 'pointer' }}>
            + Apple (.ics)
          </button>
        </div>
      </div>

      <div style={{ padding: '18px', borderBottom: `1px solid ${T.rule}` }}>
        <Mono size={9} color={T.mute} style={{ display: 'block' }}>// CANDIDATE</Mono>
        <Bebas size={20} style={{ marginTop: 4, display: 'block' }}>{fullName}</Bebas>
        <div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 6 }}>
          {[
            ['CAREER', careerLabel, T.gold],
            ['EMAIL', ctx.email, T.bone],
            ['PHONE', ctx.phone, T.bone],
            ['WAIVER', '✓ SIGNED', T.gold],
          ].map(([l, v, col]) => (
            <div key={l} style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
              <Mono size={10} color={T.mute}>{l}</Mono>
              <Mono size={10} color={col} style={{ textAlign: 'right' }}>{v}</Mono>
            </div>
          ))}
        </div>
      </div>

      <div style={{ padding: '18px' }}>
        <Mono size={9} color={T.gold} style={{ display: 'block' }}>// RESOURCES</Mono>
        <div style={{ marginTop: 10, display: 'flex', flexDirection: 'column' }}>
          {resources.length === 0 && (
            <Body size={12} color={T.mute} style={{ display: 'block', padding: '10px 0' }}>No resources attached.</Body>
          )}
          {resources.map((f, i) => (
            <a key={f.id} href={f.downloadUrl} target="_blank" rel="noopener noreferrer"
               style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 0', borderTop: i ? `1px solid ${T.rule}` : 'none', textDecoration: 'none', color: 'inherit' }}>
              <div>
                <Body size={12} color={T.bone}>{f.name}</Body>
                <Mono size={9} color={T.mute} style={{ display: 'block', marginTop: 2 }}>{formatFileSize(f.size)}</Mono>
              </div>
              <Mono size={11} color={T.gold}>↓</Mono>
            </a>
          ))}
        </div>
        <Body size={11} color={T.mute} style={{ marginTop: 14, textAlign: 'center', display: 'block' }}>
          Confirmation sent to {ctx.email || 'your email'}.
        </Body>
        <button onClick={() => go('landing')} style={{ width: '100%', marginTop: 14, background: 'transparent', border: `1px solid ${T.rule}`, color: T.bone, padding: '10px', fontFamily: "'Bebas Neue',sans-serif", fontSize: 13, letterSpacing: 1, cursor: 'pointer' }}>
          ← Back to events
        </button>
      </div>
    </div>
  );
};

// ─── SIGNUP shell (mobile) ───────────────────────────────────────────
const SignupMobile = ({ ctx, setCtx, go, step = 0 }) => {
  const [allEvents] = useEventsStore();
  const active = allEvents.filter(e => !e.archived);
  const event = allEvents.find(e => e.code === ctx.eventCode) || active[active.length - 1] || allEvents[0];
  return (
    <div style={{ height: '100%', overflowY: 'auto', background: T.bg, color: T.bone }}>
      {/* Header */}
      <div style={{ padding: '10px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `1px solid ${T.rule}` }}>
        <SWLockup size={0.7} />
        <Mono size={9} color={T.mute}>SECURE · SSL</Mono>
      </div>
      {/* Event banner */}
      <div style={{ background: T.bg2, padding: '10px 14px', borderBottom: `1px solid ${T.rule}` }}>
        <Mono size={9} color={T.gold}>// SIGNING UP FOR</Mono>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginTop: 4 }}>
          <div>
            <Bebas size={18} style={{ display: 'block' }}>{event.city}, {event.state}</Bebas>
            <Mono size={9} color={T.mute} style={{ display: 'block', marginTop: 2 }}>{event.date} · {event.venue.split('·')[0].trim()}</Mono>
          </div>
        </div>
      </div>

      <StepperMobile step={step} />

      {step === 0 && <DetailsMobile ctx={ctx} setCtx={setCtx} go={go} />}
      {step === 1 && <WaiverMobile ctx={ctx} setCtx={setCtx} go={go} event={event} />}
      {step === 2 && <ConfirmMobile ctx={ctx} go={go} event={event} />}
    </div>
  );
};

// ─── ADMIN (mobile) — full-edit form is desktop-only; mobile shows roster +
// archive/unarchive button for the selected event.
const AdminMobile = ({ go }) => {
  const [events, ev_mut] = useEventsStore();
  const [tab, setTab] = React.useState(0);
  const ev = events[tab] || events[0];
  const ROSTER = [
    ['Doe, J.', 'CCT', '21'],
    ['Nguyen, T.', 'PJ', '19'],
    ['Alvarez, M.', 'TACP', '17·M'],
    ['Lee, K.', 'EOD', '23'],
    ['Park, S.', 'SR', '22'],
    ['Reed, J.', 'STO', '24'],
  ];
  if (!ev) {
    return (
      <div style={{ background: T.bg, color: T.bone, height: '100%', padding: 18 }}>
        <Mono size={10} color={T.mute}>NO EVENTS · use desktop admin to create.</Mono>
      </div>
    );
  }
  return (
    <div style={{ background: T.bg, color: T.bone, height: '100%', overflowY: 'auto' }}>
      <div style={{ padding: '10px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: `1px solid ${T.rule}` }}>
        <SWLockup size={0.7} />
        <Mono size={9} color={T.gold}>ADMIN</Mono>
      </div>
      <div style={{ display: 'flex', overflowX: 'auto', borderBottom: `1px solid ${T.rule}`, background: T.bg2 }}>
        {events.map((e, i) => (
          <button key={e.code} onClick={() => setTab(i)} style={{
            flex: '0 0 auto', padding: '10px 12px',
            background: tab === i ? T.bg : 'transparent',
            border: 'none',
            borderBottom: tab === i ? `2px solid ${T.blue2}` : '2px solid transparent',
            cursor: 'pointer', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 2,
            opacity: e.archived ? 0.5 : 1,
          }}>
            <Bebas size={13} color={tab === i ? T.bone : T.mute} style={{ textDecoration: e.archived ? 'line-through' : 'none' }}>{e.code}</Bebas>
            <Mono size={8} color={e.archived ? T.red : T.mute}>{e.archived ? 'ARCHIVED' : e.dateShort}</Mono>
          </button>
        ))}
      </div>
      <div style={{ padding: 14 }}>
        {ev.archived && (
          <div style={{ marginBottom: 12, padding: 8, border: `1px solid ${T.red}`, background: 'rgba(200,68,58,0.06)' }}>
            <Mono size={9} color={T.red}>// ARCHIVED · hidden from public site</Mono>
          </div>
        )}
        <Mono size={9} color={T.gold}>// {ev.date} · {ev.venue.split('·')[0].trim()}</Mono>
        <Bebas size={22} style={{ marginTop: 4, display: 'block' }}>{ev.city}, {ev.state}</Bebas>
        <div style={{ marginTop: 12, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
          <div style={{ padding: 10, border: `1px solid ${T.rule}` }}>
            <Mono size={9} color={T.mute}>SIGNUPS</Mono>
            <Bebas size={22} style={{ display: 'block', marginTop: 2 }}>{String(ev.spots).padStart(2,'0')}/{ev.cap}</Bebas>
          </div>
          <div style={{ padding: 10, border: `1px solid ${T.rule}` }}>
            <Mono size={9} color={T.mute}>WAIVERS</Mono>
            <Bebas size={22} color={T.gold} style={{ display: 'block', marginTop: 2 }}>{String(Math.floor(ev.spots * 0.8)).padStart(2,'0')}</Bebas>
          </div>
        </div>
        <button onClick={() => ev.archived ? ev_mut.unarchive(ev.code) : ev_mut.archive(ev.code)} style={{
          width: '100%', marginTop: 12,
          background: 'transparent', border: `1px solid ${ev.archived ? T.gold : T.red}`,
          color: ev.archived ? T.gold : T.red,
          padding: '8px', fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: 1, cursor: 'pointer',
        }}>
          {ev.archived ? '↻ UNARCHIVE' : '⌕ ARCHIVE'}
        </button>
        <div style={{ marginTop: 14 }}>
          <Mono size={9} color={T.mute}>// ROSTER</Mono>
          <div style={{ marginTop: 6 }}>
            {ROSTER.map(([n, c, a], i) => (
              <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr 60px 50px', gap: 8, padding: '10px 0', borderTop: `1px solid ${T.rule}`, alignItems: 'center' }}>
                <Body size={12} color={T.bone}>{n}</Body>
                <Mono size={10} color={T.gold}>{c}</Mono>
                <Mono size={10} color={T.mute}>{a}</Mono>
              </div>
            ))}
          </div>
        </div>
        <button onClick={() => go('landing')} style={{ width: '100%', marginTop: 16, background: 'transparent', border: `1px solid ${T.rule}`, color: T.mute, padding: '8px', fontFamily: "'JetBrains Mono',monospace", fontSize: 10, letterSpacing: 1, cursor: 'pointer' }}>
          ← Back to landing
        </button>
      </div>
    </div>
  );
};

Object.assign(window, { LandingMobile, SignupMobile, AdminMobile });
