// amps-enrollment.jsx — Enrollment section + Confirmation
const { useState: useStateE, useEffect: useEffectE, useMemo: useMemoE } = React;

// Permanently reserved — the Society itself
const PERMANENTLY_RESERVED = new Set(['AMPS']);

// Specifically assigned to founders and crew (Captain expands this list)
const ASSIGNED_RESERVED = new Set([
  'JM01', 'SM01',
  'AMP1', 'AMP2', 'AMP3', 'SHP1', 'SHP2',
]);

// Codes in circulation (replace with live DB check in production)
const TAKEN_CODES = new Set(['NOVA', 'MARS', 'SOL7', 'STAR', 'ORCA', 'MOON']);

// Reserve entire format classes from public pool:
//   XXNN (e.g. JM01, SM01) — family / founder format
//   XXXN (e.g. AMP1, SHP2) — fleet ship format
function isReservedPattern(code) {
  if (!code || code.length !== 4) return false;
  return /^[A-Z]{2}\d{2}$/.test(code) || /^[A-Z]{3}\d{1}$/.test(code);
}

function getCodeStatus(code) {
  if (!code || code.length < 4) return null;
  const upper = code.toUpperCase();
  if (PERMANENTLY_RESERVED.has(upper)) return { available: false, message: '✗ Reserved by the Society' };
  if (ASSIGNED_RESERVED.has(upper)) return { available: false, message: '✗ Designated — not available' };
  if (isReservedPattern(upper)) return { available: false, message: '✗ Format reserved for founders' };
  if (TAKEN_CODES.has(upper)) return { available: false, message: '✗ Already commissioned' };
  return { available: true, message: `✦ Available — NAV-${upper} is yours` };
}

function isCodeAvailable(code) {
  return getCodeStatus(code.toUpperCase())?.available === true;
}

function generateCode() {
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  let code = '';
  let attempts = 0;
  do {
    code = '';
    for (let i = 0; i < 4; i++) code += chars[Math.floor(Math.random() * chars.length)];
    attempts++;
    if (attempts > 1000) break;
  } while (!isCodeAvailable(code));
  return code;
}

function OAuthBtn({ p, connected, onClick }) {
  return (
    <button onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 14,
      width: '100%', padding: '14px 18px',
      background: connected ? `${T.amber}18` : 'transparent',
      border: connected ? `1px solid ${T.amber}` : `1px solid ${T.void}55`,
      borderRadius: 0, cursor: 'pointer',
      color: T.void, fontFamily: T.fontBody, fontSize: 15,
      fontWeight: 500, letterSpacing: '0.01em',
      transition: 'all 0.18s',
    }}
    onMouseEnter={e => !connected && (e.currentTarget.style.borderColor = T.void)}
    onMouseLeave={e => !connected && (e.currentTarget.style.borderColor = `${T.void}55`)}>
      {p.glyph(T.void)}
      <span style={{ flex: 1, textAlign: 'left' }}>
        {connected ? `Connected — ${p.name}` : `Continue with ${p.name.split(' ')[0]}`}
      </span>
      {connected && <Star size={14} color={T.amber} />}
    </button>
  );
}

function StepHeader({ n, label, status }) {
  return (
    <div style={{ marginBottom: 20 }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
        <span style={{
          fontFamily: T.fontMono, fontSize: 11, color: T.amber,
          letterSpacing: '0.28em', fontWeight: 600,
        }}>STEP {String(n).padStart(2, '0')}</span>
        <div style={{ flex: 1, height: 1, background: `${T.void}33` }} />
        {status && <span style={{
          fontFamily: T.fontMono, fontSize: 10, color: T.amber,
          letterSpacing: '0.18em',
        }}>{status}</span>}
      </div>
      <div style={{
        fontFamily: T.fontDisplay, fontSize: 26, fontWeight: 600,
        color: T.void, marginTop: 12, letterSpacing: '0.005em',
      }}>{label}</div>
    </div>
  );
}

function FieldLabel({ children, hint }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
      <span style={{
        fontFamily: T.fontMono, fontSize: 11, color: T.void,
        letterSpacing: '0.18em', fontWeight: 600,
      }}>{children}</span>
      {hint && <span style={{
        fontFamily: T.fontMono, fontSize: 10, color: `${T.void}99`,
        letterSpacing: '0.1em',
      }}>{hint}</span>}
    </div>
  );
}

function inputStyle({ focused, mono = false }) {
  return {
    width: '100%', boxSizing: 'border-box',
    padding: '14px 16px',
    background: T.inputBg,
    color: T.void,
    border: focused ? `1px solid ${T.amber}` : `1px solid ${T.void}55`,
    borderRadius: 0,
    fontFamily: mono ? T.fontMono : T.fontBody,
    fontSize: mono ? 16 : 17,
    letterSpacing: mono ? '0.18em' : '0.005em',
    fontWeight: mono ? 500 : 400,
    outline: 'none',
    boxShadow: 'none',
    transition: 'border-color 0.15s',
  };
}

// ─────────────────────────────────────────────────────────────
// Processor catalog — ~60 creator-grade chips.
// Starship-class: dedicated AI NPU (local inference capable).
//   All Apple Silicon M-series carry Neural Engine — Starship.
//   AMD Ryzen AI, Intel Core Ultra, Qualcomm X — Starship.
// Airship-class: capable host machines, AI via cloud services.
//   All entry-point for reclassification after enrollment.
// ─────────────────────────────────────────────────────────────
const PROCESSOR_CATALOG = [
  {
    group: '✦ STARSHIP-CLASS · ONBOARD INTELLIGENCE',
    hint: 'Dedicated NPU · local AI inference',
    items: [
      // ── AMD Ryzen AI (Strix Halo / Strix Point · XDNA 2 · 50+ TOPS) ──
      'AMD Ryzen AI MAX+ 395',
      'AMD Ryzen AI MAX 390',
      'AMD Ryzen AI 9 HX 370',
      'AMD Ryzen AI 9 365',
      'AMD Ryzen AI 7 365',
      'AMD Ryzen AI 7 350',
      'AMD Ryzen AI 5 340',
      'AMD Ryzen AI 5 330',
      // ── AMD Ryzen 8000 (Hawk Point · XDNA NPU · 16 TOPS) ──
      'AMD Ryzen 9 8945HS',
      'AMD Ryzen 7 8845HS',
      // ── Apple Silicon (M4) ──
      'Apple M4 Max',
      'Apple M4 Pro',
      'Apple M4',
      // ── Apple Silicon (M3) ──
      'Apple M3 Ultra',
      'Apple M3 Max',
      'Apple M3 Pro',
      'Apple M3',
      // ── Apple Silicon (M2) ──
      'Apple M2 Ultra',
      'Apple M2 Max',
      'Apple M2 Pro',
      'Apple M2',
      // ── Apple Silicon (M1) ──
      'Apple M1 Ultra',
      'Apple M1 Max',
      'Apple M1 Pro',
      'Apple M1',
      // ── Intel Core Ultra (Series 2 — Lunar Lake / Arrow Lake) ──
      'Intel Core Ultra 9 (Series 2)',
      'Intel Core Ultra 7 (Series 2)',
      'Intel Core Ultra 5 (Series 2)',
      // ── Intel Core Ultra (Series 1 — Meteor Lake) ──
      'Intel Core Ultra 9 (Series 1)',
      'Intel Core Ultra 7 (Series 1)',
      'Intel Core Ultra 5 (Series 1)',
      // ── Qualcomm Snapdragon X ──
      'Qualcomm Snapdragon X Elite',
      'Qualcomm Snapdragon X Plus',
      'Qualcomm Snapdragon X',
    ],
  },
  {
    group: '⬡ AIRSHIP-CLASS · CLOUD-CONNECTED',
    hint: 'Capable host machines · AI via cloud services · reclassification available',
    items: [
      // ── AMD Desktop (AM5) ──
      'AMD Ryzen 9 9950X',
      'AMD Ryzen 9 9900X',
      'AMD Ryzen 9 7950X',
      'AMD Ryzen 9 7900X',
      'AMD Ryzen 9 5950X',
      'AMD Ryzen 7 9800X3D',
      'AMD Ryzen 7 7800X3D',
      'AMD Ryzen 7 7700X',
      'AMD Ryzen 7 5800X3D',
      // ── AMD Mobile (no NPU) ──
      'AMD Ryzen 9 7945HX',
      'AMD Ryzen 7 7745HX',
      // ── AMD Threadripper ──
      'AMD Threadripper PRO 7985WX',
      'AMD Threadripper 7970X',
      // ── Intel Desktop ──
      'Intel Core i9 (14th gen)',
      'Intel Core i9 (13th gen)',
      'Intel Core i9 (12th gen)',
      'Intel Core i7 (14th gen)',
      'Intel Core i7 (13th gen)',
      'Intel Core i7 (12th gen)',
      'Intel Core i5 (14th gen)',
      // ── Intel Mobile HX ──
      'Intel Core i9 HX (14th gen)',
      'Intel Core i9 HX (13th gen)',
      'Intel Core i7 HX (14th gen)',
      // ── Intel Xeon ──
      'Intel Xeon W-3500 series',
      'Intel Xeon W-2500 series',
      '__other__',
    ],
  },
];

// Classify a processor string into vessel class.
// Returns 'starship' | 'airship'.
function classifyProcessor(p) {
  if (!p) return null;
  const starshipList = PROCESSOR_CATALOG[0].items;
  return starshipList.includes(p) ? 'starship' : 'airship';
}
window.classifyProcessor = classifyProcessor;

function ProcessorSelect({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const [focused, setFocused] = React.useState(false);
  // "other" mode: user picked "Other · not listed" and is free-typing their own chip
  const isOther = typeof value === 'string' && value.startsWith('Other: ');
  const [otherMode, setOtherMode] = React.useState(isOther);
  const [otherText, setOtherText] = React.useState(isOther ? value.replace(/^Other: /, '') : '');
  const [otherFocus, setOtherFocus] = React.useState(false);
  const ref = React.useRef(null);
  const otherInputRef = React.useRef(null);

  React.useEffect(() => {
    if (!open) return;
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', close);
    return () => document.removeEventListener('mousedown', close);
  }, [open]);

  React.useEffect(() => {
    if (otherMode && otherInputRef.current) {
      otherInputRef.current.focus();
    }
  }, [otherMode]);

  const commitOther = (text) => {
    const clean = text.trim();
    if (clean) onChange(`Other: ${clean}`);
    else onChange('');
  };

  const display = value || '';
  const isPlaceholder = !display;
  const classified = classifyProcessor(value);

  // If we're in "other" mode, render the inline free-text field instead of the button
  if (otherMode) {
    return (
      <div style={{ position: 'relative' }}>
        <div style={{
          ...inputStyle({ focused: otherFocus }),
          padding: 0,
          display: 'flex', alignItems: 'stretch',
        }}>
          <input
            ref={otherInputRef}
            value={otherText}
            onChange={e => { setOtherText(e.target.value); commitOther(e.target.value); }}
            onFocus={() => setOtherFocus(true)}
            onBlur={() => setOtherFocus(false)}
            placeholder="Name your processor…"
            style={{
              flex: 1, minWidth: 0,
              background: 'transparent', color: T.void,
              border: 'none', outline: 'none',
              padding: '14px 16px',
              fontFamily: T.fontBody, fontSize: 17,
              letterSpacing: '0.005em',
            }}
          />
          <button
            type="button"
            onClick={() => { setOtherMode(false); setOtherText(''); onChange(''); }}
            style={{
              background: 'transparent', color: `${T.void}99`,
              border: 'none', borderLeft: `1px solid ${T.void}33`,
              padding: '0 16px', cursor: 'pointer',
              fontFamily: T.fontMono, fontSize: 10,
              letterSpacing: '0.2em',
            }}
            title="Back to catalog"
          >↶ CATALOG</button>
        </div>
        <div style={{
          marginTop: 8,
          display: 'flex', alignItems: 'center', gap: 10,
          fontFamily: T.fontMono, fontSize: 10,
          color: T.void, opacity: 0.75, letterSpacing: '0.14em',
        }}>
          <span style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            border: `1px solid ${T.amber}`, color: T.amber,
            padding: '3px 8px', letterSpacing: '0.22em', fontWeight: 600,
          }}>⬡ AIRSHIP</span>
          <span style={{ fontStyle: 'italic' }}>
            Classified as Airship for now. Navigators may request reclassification once enrolled.
          </span>
        </div>
      </div>
    );
  }

  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button
        type="button"
        onClick={() => setOpen(v => !v)}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        style={{
          ...inputStyle({ focused: focused || open }),
          textAlign: 'left',
          cursor: 'pointer',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          gap: 12,
          color: isPlaceholder ? `${T.void}88` : T.void,
        }}
      >
        <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>
          {display || 'Select your processor…'}
        </span>
        {classified && (
          <span style={{
            fontFamily: T.fontMono, fontSize: 9,
            color: T.amber, letterSpacing: '0.2em',
            border: `1px solid ${T.amber}`,
            padding: '2px 6px', flexShrink: 0,
          }}>
            {classified === 'starship' ? '✦ STARSHIP' : '⬡ AIRSHIP'}
          </span>
        )}
        <span style={{
          fontFamily: T.fontMono, fontSize: 11, color: T.amber,
          letterSpacing: '0.18em', flexShrink: 0,
          transform: open ? 'rotate(180deg)' : 'rotate(0)',
          transition: 'transform 0.18s',
        }}>▾</span>
      </button>

      {open && (
        <div style={{
          position: 'absolute', top: 'calc(100% + 4px)', left: 0, right: 0,
          background: T.inputBg,
          border: `1px solid ${T.amber}`,
          boxShadow: `0 8px 32px rgba(12,21,33,0.25)`,
          maxHeight: 360, overflowY: 'auto',
          zIndex: 20,
        }}>
          {PROCESSOR_CATALOG.map((g, gi) => (
            <div key={gi}>
              <div style={{
                position: 'sticky', top: 0,
                background: `${T.void}`,
                color: T.amber,
                padding: '10px 16px 8px',
                fontFamily: T.fontMono, fontSize: 10,
                letterSpacing: '0.22em', fontWeight: 600,
                borderBottom: `1px solid ${T.amber}33`,
              }}>
                <div>{g.group}</div>
                <div style={{
                  fontFamily: T.fontBody, fontSize: 10, fontStyle: 'italic',
                  color: `${T.parchment}99`, letterSpacing: '0.02em',
                  fontWeight: 400, marginTop: 2, textTransform: 'none',
                }}>{g.hint}</div>
              </div>
              {g.items.map((item, ii) => {
                const isOtherRow = item === '__other__';
                const label = isOtherRow ? 'Other · enter your processor' : item;
                const isTop = gi === 0 && ii === 0;
                const selected = value === item;
                return (
                  <button
                    key={ii}
                    type="button"
                    onMouseDown={(e) => {
                      e.preventDefault();
                      if (isOtherRow) {
                        setOtherMode(true);
                        setOtherText('');
                        onChange('');
                      } else {
                        onChange(item);
                      }
                      setOpen(false);
                    }}
                    style={{
                      display: 'flex', alignItems: 'center', gap: 10,
                      width: '100%', textAlign: 'left',
                      padding: '11px 16px',
                      background: selected ? `${T.amber}22` : 'transparent',
                      color: isOtherRow ? `${T.void}99` : T.void,
                      fontStyle: isOtherRow ? 'italic' : 'normal',
                      border: 'none', borderRadius: 0, cursor: 'pointer',
                      fontFamily: T.fontBody, fontSize: 15,
                      borderBottom: `1px solid ${T.void}11`,
                      transition: 'background 0.12s',
                    }}
                    onMouseEnter={(e) => { if (!selected) e.currentTarget.style.background = `${T.void}0C`; }}
                    onMouseLeave={(e) => { if (!selected) e.currentTarget.style.background = 'transparent'; }}
                  >
                    <span style={{ flex: 1 }}>{label}</span>
                    {isTop && (
                      <span style={{
                        fontFamily: T.fontMono, fontSize: 9,
                        color: T.amber, letterSpacing: '0.2em',
                        border: `1px solid ${T.amber}`,
                        padding: '2px 6px',
                        whiteSpace: 'nowrap',
                      }}>FLAGSHIP</span>
                    )}
                    {selected && (
                      <span style={{ color: T.amber, fontFamily: T.fontMono, fontSize: 12 }}>✓</span>
                    )}
                  </button>
                );
              })}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function Toggle({ options, value, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 0, border: `1px solid ${T.void}55` }}>
      {options.map(opt => {
        const active = value === opt.value;
        return (
          <button key={opt.value} onClick={() => onChange(opt.value)} style={{
            flex: 1, padding: '12px 14px',
            background: active ? T.void : 'transparent',
            color: active ? T.amber : T.void,
            border: 'none', borderRadius: 0, cursor: 'pointer',
            fontFamily: T.fontMono, fontSize: 11,
            letterSpacing: '0.18em', fontWeight: 500,
            textTransform: 'uppercase',
            transition: 'all 0.15s',
          }}>{opt.label}</button>
        );
      })}
    </div>
  );
}

function ShipCard({ active, onClick, label, glyph, children }) {
  return (
    <div onClick={onClick} style={{
      flex: 1, padding: '20px 22px', cursor: 'pointer',
      background: active ? `${T.amber}1A` : 'transparent',
      border: active ? `1px solid ${T.amber}` : `1px solid ${T.void}44`,
      borderRadius: 0,
      transition: 'all 0.18s',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
        <span style={{ fontFamily: T.fontMono, fontSize: 16, color: T.amber }}>{glyph}</span>
        <span style={{
          fontFamily: T.fontMono, fontSize: 12, color: T.void,
          letterSpacing: '0.22em', fontWeight: 600,
        }}>{label}</span>
      </div>
      <div style={{ fontFamily: T.fontBody, fontSize: 14, color: T.void, opacity: 0.8, lineHeight: 1.6 }}>
        {children}
      </div>
    </div>
  );
}

function Enrollment({ auths, setAuths, onConfirm, mobile, surnameMaxChars = 24 }) {
  const [surname, setSurname] = useStateE('');
  const [surnameFocus, setSurnameFocus] = useStateE(false);
  const [codeMode, setCodeMode] = useStateE('choose'); // 'choose' | 'random'
  const [code, setCode] = useStateE('');
  const [randomCode, setRandomCode] = useStateE(generateCode());
  const [codeFocus, setCodeFocus] = useStateE(false);
  const [shipStatus, setShipStatus] = useStateE('pending'); // 'pending' | 'registered'
  const [shipName, setShipName] = useStateE('');
  const [processor, setProcessor] = useStateE('');

  // Validation
  const codeUpper = code.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 4);
  const codeStatusResult = useMemoE(() => {
    if (codeMode !== 'choose') return null;
    if (codeUpper.length === 0) return null;
    if (codeUpper.length < 4) return { available: false, message: `· ${4 - codeUpper.length} characters remain`, incomplete: true };
    return getCodeStatus(codeUpper);
  }, [codeUpper, codeMode]);
  const codeStatus = codeStatusResult?.incomplete ? 'incomplete'
    : codeStatusResult?.available === true ? 'available'
    : codeStatusResult?.available === false ? 'unavailable'
    : null;

  const canSubmit = surname.trim().length >= 2 && (
    (codeMode === 'choose' && codeStatus === 'available') ||
    (codeMode === 'random' && randomCode.length === 4)
  ) && (auths.spotify || auths.youtube || auths.email) && (
    shipStatus === 'pending' || (shipName.trim() && processor.trim())
  );

  const finalCode = codeMode === 'choose' ? codeUpper : randomCode;

  const submit = () => {
    if (!canSubmit) return;
    onConfirm({
      surname: surname.trim(),
      code: finalCode,
      ship: shipStatus === 'registered' ? { name: shipName.trim(), processor: processor.trim() } : null,
    });
  };

  return (
    <section data-amps-enrollment style={{
      background: T.parchment,
      color: T.void,
      padding: mobile ? '80px 24px' : '120px 80px',
      position: 'relative',
      overflow: 'hidden',
    }}>
      {/* parchment fiber texture */}
      <svg style={{ position: 'absolute', inset: 0, opacity: 0.4, mixBlendMode: 'multiply', pointerEvents: 'none' }}
           width="100%" height="100%" preserveAspectRatio="none">
        <defs>
          <filter id="parchment-grain">
            <feTurbulence baseFrequency="0.85" numOctaves="3" />
            <feColorMatrix values="0 0 0 0 0.6  0 0 0 0 0.5  0 0 0 0 0.3  0 0 0 0.06 0" />
          </filter>
          <radialGradient id="parchment-vignette" cx="0.5" cy="0.5" r="0.7">
            <stop offset="0.7" stopColor="rgba(0,0,0,0)" />
            <stop offset="1" stopColor="rgba(80,55,20,0.18)" />
          </radialGradient>
        </defs>
        <rect width="100%" height="100%" filter="url(#parchment-grain)" />
        <rect width="100%" height="100%" fill="url(#parchment-vignette)" />
      </svg>

      <div style={{ maxWidth: 720, margin: '0 auto', position: 'relative' }}>
        {/* Header */}
        <div style={{ marginBottom: 56 }}>
          <Catalog>· Folio I.vi ·</Catalog>
          <h2 style={{
            fontFamily: T.fontDisplay,
            fontSize: mobile ? 48 : 72, fontWeight: 500,
            color: T.void, margin: '0 0 24px',
            letterSpacing: '0.005em', lineHeight: 1.0,
          }}>Take a name.<br/><em style={{ fontStyle: 'italic' }}>Take the helm.</em></h2>
          <p style={{
            fontFamily: T.fontBody, fontSize: mobile ? 17 : 20,
            fontStyle: 'italic', color: T.void, opacity: 0.85,
            lineHeight: 1.6, margin: 0, maxWidth: 460,
          }}>
            No payment.<br/>Only your mark in the log.
          </p>
        </div>

        {/* STEP 1 — OAuth */}
        <div style={{ marginBottom: 56 }}>
          <StepHeader n={1} label="Connect your platforms"
            status={Object.values(auths).filter(Boolean).length ? `${Object.values(auths).filter(Boolean).length} CONNECTED` : null} />
          <p style={{ fontFamily: T.fontBody, fontSize: 16, fontStyle: 'italic',
                       color: T.void, opacity: 0.75, marginBottom: 24 }}>
            One channel, or several.
          </p>
          <div style={{ display: 'grid',
                         gridTemplateColumns: mobile ? '1fr' : '1fr 1fr',
                         gap: 12 }}>
            {PLATFORMS.filter(p => p.method === 'oauth').map(p => (
              <OAuthBtn key={p.id} p={p} connected={!!auths[p.id]}
                onClick={() => setAuths(prev => ({ ...prev, [p.id]: !prev[p.id] }))} />
            ))}
          </div>
          <button onClick={() => setAuths(prev => ({ ...prev, email: !prev.email }))} style={{
            background: 'none', border: 'none', padding: '14px 0 0',
            color: T.void, opacity: 0.7,
            fontFamily: T.fontBody, fontSize: 14, fontStyle: 'italic',
            cursor: 'pointer', textDecoration: 'underline',
            textUnderlineOffset: 4, textDecorationColor: `${T.void}55`,
          }}>
            {auths.email ? '✦ Email registered' : 'Or continue with email →'}
          </button>
        </div>

        {/* STEP 2 — Identity */}
        <div style={{ marginBottom: 56 }}>
          <StepHeader n={2} label="Your identity" />

          {/* Surname */}
          <div style={{ marginBottom: 32 }}>
            <FieldLabel hint={`${surname.length} / ${surnameMaxChars}`}>SOCIETY SURNAME ·</FieldLabel>
            <input
              value={surname}
              onChange={e => setSurname(e.target.value.slice(0, surnameMaxChars))}
              onFocus={() => setSurnameFocus(true)}
              onBlur={() => setSurnameFocus(false)}
              placeholder="The name by which you will be known"
              style={inputStyle({ focused: surnameFocus })}
            />
            <div style={{
              fontFamily: T.fontMono, fontSize: 10, color: T.void,
              opacity: 0.6, letterSpacing: '0.12em', marginTop: 8,
            }}>· Choose with care.</div>
          </div>

          {/* Code */}
          <div>
            <FieldLabel>NAVIGATOR CODE · 4 CHARACTERS</FieldLabel>
            <div style={{ marginBottom: 14 }}>
              <Toggle
                options={[{ value: 'choose', label: 'Choose Your Own' }, { value: 'random', label: 'Assign Randomly' }]}
                value={codeMode}
                onChange={setCodeMode}
              />
            </div>

            {codeMode === 'choose' ? (
              <>
                <div style={{ position: 'relative' }}>
                  <input
                    value={codeUpper}
                    onChange={e => setCode(e.target.value)}
                    onFocus={() => setCodeFocus(true)}
                    onBlur={() => setCodeFocus(false)}
                    placeholder="NOVA"
                    maxLength={4}
                    style={{
                      ...inputStyle({ focused: codeFocus, mono: true }),
                      paddingRight: 64, fontSize: 22, letterSpacing: '0.4em', textTransform: 'uppercase',
                    }}
                  />
                  <span style={{
                    position: 'absolute', right: 16, top: '50%',
                    transform: 'translateY(-50%)',
                    fontFamily: T.fontMono, fontSize: 11,
                    color: T.void, opacity: 0.6, letterSpacing: '0.1em',
                  }}>{codeUpper.length}/4</span>
                </div>
                <div style={{ marginTop: 10, minHeight: 22,
                               fontFamily: T.fontMono, fontSize: 11,
                               letterSpacing: '0.14em' }}>
                  {codeStatus === 'available' && (
                    <span style={{ color: T.amber }}>{codeStatusResult.message}</span>
                  )}
                  {codeStatus === 'unavailable' && (
                    <span style={{ color: T.errorRed }}>{codeStatusResult.message}</span>
                  )}
                  {codeStatus === 'incomplete' && (
                    <span style={{ color: T.void, opacity: 0.5 }}>{codeStatusResult.message}</span>
                  )}
                </div>
              </>
            ) : (
              <div style={{
                background: T.inputBg, border: `1px solid ${T.void}55`,
                padding: '20px 24px', display: 'flex', alignItems: 'center',
                justifyContent: 'space-between', flexWrap: 'wrap', gap: 12,
              }}>
                <span style={{
                  fontFamily: T.fontMono, fontSize: 30,
                  color: T.amber, letterSpacing: '0.4em', fontWeight: 600,
                }}>{randomCode}</span>
                <button onClick={() => setRandomCode(generateCode())} style={{
                  background: 'none', border: 'none', padding: 0,
                  color: T.void, opacity: 0.7,
                  fontFamily: T.fontMono, fontSize: 11,
                  letterSpacing: '0.18em', cursor: 'pointer',
                  textTransform: 'uppercase',
                }}>Regenerate ↺</button>
              </div>
            )}
            <div style={{
              fontFamily: T.fontMono, fontSize: 10, color: T.void,
              opacity: 0.6, letterSpacing: '0.1em', marginTop: 12,
              lineHeight: 1.6,
            }}>
              Letters and numbers · A–Z · 0–9<br/>
              Yours alone.
            </div>
          </div>
        </div>

        {/* STEP 3 — Ship */}
        <div style={{ marginBottom: 56 }}>
          <StepHeader n={3} label="Your ship" status="OPTIONAL" />
          <p style={{ fontFamily: T.fontBody, fontSize: 15, fontStyle: 'italic',
                       color: T.void, opacity: 0.75, marginBottom: 20 }}>
            If you have one.
          </p>

          <div style={{ display: 'flex', gap: 14, flexDirection: mobile ? 'column' : 'row' }}>
            <ShipCard active={shipStatus === 'pending'}
              onClick={() => setShipStatus('pending')}
              label="COMMISSION PENDING" glyph="◇">
              The vessel will find you.
            </ShipCard>
            <ShipCard active={shipStatus === 'registered'}
              onClick={() => setShipStatus('registered')}
              label="SHIP REGISTERED" glyph="✦">
              You command a vessel and wish to register her with the Society.
            </ShipCard>
          </div>

          {shipStatus === 'registered' && (
            <div style={{ marginTop: 24, padding: '24px',
                           border: `1px solid ${T.void}33`,
                           background: `${T.void}06` }}>
              <div style={{ marginBottom: 24 }}>
                <FieldLabel>SHIP DESIGNATION ·</FieldLabel>
                <input value={shipName} onChange={e => setShipName(e.target.value)}
                  placeholder="What do you call her?"
                  style={inputStyle({ focused: false })} />
              </div>
              <div>
                <FieldLabel>PRIMARY PROCESSOR ·</FieldLabel>
                <ProcessorSelect value={processor} onChange={setProcessor} />
                <div style={{
                  fontFamily: T.fontMono, fontSize: 10, color: T.void,
                  opacity: 0.6, letterSpacing: '0.1em', marginTop: 10,
                  fontStyle: 'italic',
                }}>Determines her class.</div>
              </div>

              <div style={{
                display: 'grid',
                gridTemplateColumns: mobile ? '1fr' : '1fr 1fr',
                gap: 12, marginTop: 20,
              }}>
                <div style={{ padding: '14px 16px', border: `1px dashed ${T.void}33` }}>
                  <div style={{ fontFamily: T.fontMono, fontSize: 11, color: T.amber,
                                 letterSpacing: '0.22em', marginBottom: 6, fontWeight: 600 }}>
                    ⬡ AIRSHIP
                  </div>
                  <div style={{ fontFamily: T.fontBody, fontSize: 13, color: T.void, opacity: 0.75 }}>
                    Cloud-connected processing · AI via cloud services
                  </div>
                </div>
                <div style={{ padding: '14px 16px', border: `1px dashed ${T.void}33` }}>
                  <div style={{ fontFamily: T.fontMono, fontSize: 11, color: T.amber,
                                 letterSpacing: '0.22em', marginBottom: 6, fontWeight: 600 }}>
                    ✦ STARSHIP
                  </div>
                  <div style={{ fontFamily: T.fontBody, fontSize: 13, color: T.void, opacity: 0.75 }}>
                    Local AI inference · Onboard intelligence
                  </div>
                </div>
              </div>
              <div style={{
                fontFamily: T.fontMono, fontSize: 10, color: T.void,
                opacity: 0.6, letterSpacing: '0.1em', marginTop: 14,
              }}>· Class confirmed after enrollment.</div>
            </div>
          )}
        </div>

        {/* Submit */}
        <div style={{ marginTop: 64 }}>
          <button
            onClick={submit}
            disabled={!canSubmit}
            style={{
              width: '100%', maxWidth: 500,
              padding: '20px 28px',
              background: canSubmit ? T.void : 'transparent',
              color: canSubmit ? T.amber : `${T.void}66`,
              border: canSubmit ? `1px solid ${T.amber}` : `1px solid ${T.void}33`,
              borderRadius: 0,
              fontFamily: T.fontMono, fontSize: 13,
              letterSpacing: '0.32em', fontWeight: 600,
              textTransform: 'uppercase', cursor: canSubmit ? 'pointer' : 'not-allowed',
              transition: 'all 0.2s',
              display: 'block', margin: '0 auto',
            }}
            onMouseEnter={e => canSubmit && (e.currentTarget.style.background = T.amber, e.currentTarget.style.color = T.void)}
            onMouseLeave={e => canSubmit && (e.currentTarget.style.background = T.void, e.currentTarget.style.color = T.amber)}
          >
            ✦  Enlist  ✦
          </button>

          <div style={{
            textAlign: 'center', marginTop: 18,
            fontFamily: T.fontMono, fontSize: 10, color: T.void,
            opacity: 0.55, letterSpacing: '0.16em', lineHeight: 1.7,
          }}>
            No payment. No data beyond what you give.
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// Confirmation
// ─────────────────────────────────────────────────────────────
function Confirmation({ data, onReset, mobile }) {
  const [creedAffirmed, setCreedAffirmed] = useStateE([false, false, false, false, false]);
  const allAffirmed = creedAffirmed.every(Boolean);

  const togglePledge = (i) => setCreedAffirmed(prev => prev.map((v, j) => j === i ? !v : v));

  const date = useMemoE(() => {
    const months = ['JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC'];
    const d = new Date();
    return `${String(d.getDate()).padStart(2,'0')} ${months[d.getMonth()]} ${d.getFullYear()}`;
  }, []);

  const vesselClass = data.ship?.processor
    ? classifyProcessor(data.ship.processor)
    : null;
  const vesselClassLabel = vesselClass === 'starship' ? '✦ STARSHIP'
    : vesselClass === 'airship' ? '⬡ AIRSHIP'
    : 'CLASS PENDING';

  return (
    <section style={{
      background: T.void,
      minHeight: '100vh',
      padding: mobile ? '80px 24px' : '120px 80px',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      position: 'relative', overflow: 'hidden',
    }}>
      {/* Backdrop stars */}
      <svg style={{ position: 'absolute', inset: 0 }} preserveAspectRatio="none" viewBox="0 0 100 100">
        {[...Array(40)].map((_, i) => {
          const x = (Math.sin(i * 12.9898) * 43758.5453) % 1 * 100;
          const y = (Math.sin(i * 78.233) * 43758.5453) % 1 * 100;
          return <circle key={i} cx={Math.abs(x)} cy={Math.abs(y)} r="0.15" fill={T.discoveryWhite} opacity="0.5" />;
        })}
      </svg>

      <div style={{
        position: 'relative',
        background: T.observatory,
        border: `1px solid ${T.amber}`,
        padding: mobile ? '48px 28px' : '72px 80px',
        maxWidth: 640, width: '100%',
        textAlign: 'center',
      }}>
        {/* corner ornaments */}
        {[[8,8],[8,'auto'],['auto',8],['auto','auto']].map(([t,l],i) => (
          <div key={i} style={{
            position: 'absolute',
            top: t === 'auto' ? 'auto' : t, left: l === 'auto' ? 'auto' : l,
            bottom: t === 'auto' ? 8 : 'auto', right: l === 'auto' ? 8 : 'auto',
            width: 14, height: 14,
            borderTop: t !== 'auto' ? `1px solid ${T.amber}` : 'none',
            borderBottom: t === 'auto' ? `1px solid ${T.amber}` : 'none',
            borderLeft: l !== 'auto' ? `1px solid ${T.amber}` : 'none',
            borderRight: l === 'auto' ? `1px solid ${T.amber}` : 'none',
          }} />
        ))}

        <div style={{ marginBottom: 24 }}><Star size={20} color={T.amber} /></div>

        <div style={{
          fontFamily: T.fontMono, fontSize: 11, color: T.amber,
          letterSpacing: '0.32em', marginBottom: 24, fontWeight: 600,
        }}>· COMMISSION CONFIRMED ·</div>

        <h1 style={{
          fontFamily: T.fontDisplay,
          fontSize: mobile ? 44 : 64, fontWeight: 600,
          color: T.amber, margin: '0 0 32px',
          letterSpacing: '0.005em', lineHeight: 1.1,
        }}>Welcome.</h1>

        <Rule mb={28} />

        <div style={{
          fontFamily: T.fontMono, fontSize: mobile ? 13 : 16,
          color: T.discoveryWhite, letterSpacing: '0.18em',
          lineHeight: 2.2, fontWeight: 500,
        }}>
          NAVIGATOR · {data.surname.toUpperCase()} · NAV-{data.code}<br/>
          <span style={{ color: T.silver, opacity: 0.85 }}>
            CLASS · FIRST EXPEDITION
          </span><br/>
          <span style={{ color: T.silver, opacity: 0.85 }}>
            DATE · {date}
          </span>
          {data.ship && (
            <>
              <br/>
              <span style={{ color: vesselClass ? T.amber : T.silver, opacity: 0.9 }}>
                VESSEL · {data.ship.name.toUpperCase()} · {vesselClassLabel}
              </span>
            </>
          )}
        </div>

        <Rule mt={28} mb={28} />

        <p style={{
          fontFamily: T.fontBody, fontSize: 17, fontStyle: 'italic',
          color: T.silver, lineHeight: 1.7, margin: '0 0 32px',
        }}>
          The log records you.<br/>
          <em style={{ color: T.amber }}>The rest, in time.</em>
        </p>

        {/* Creed affirmation */}
        <div style={{
          textAlign: 'left',
          borderTop: `1px solid ${T.silver}22`,
          paddingTop: 24, marginBottom: 32,
        }}>
          <div style={{
            fontFamily: T.fontMono, fontSize: 10, color: T.silver,
            letterSpacing: '0.28em', marginBottom: 18, opacity: 0.7,
            textAlign: 'center',
          }}>· AFFIRM THE NAVIGATOR'S CREED ·</div>
          {['Augmentation', 'Curiosity', 'Sovereignty', 'Respect', 'Creation'].map((title, i) => (
            <div
              key={i}
              onClick={() => togglePledge(i)}
              style={{
                display: 'flex', alignItems: 'flex-start', gap: 14,
                marginBottom: 12, cursor: 'pointer',
                padding: '8px 0',
                borderBottom: i < 4 ? `1px solid ${T.silver}11` : 'none',
              }}
            >
              <div style={{
                width: 18, height: 18, flexShrink: 0,
                border: `1px solid ${creedAffirmed[i] ? T.amber : T.silver + '44'}`,
                background: creedAffirmed[i] ? `${T.amber}22` : 'transparent',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                marginTop: 1, transition: 'all 0.15s',
              }}>
                {creedAffirmed[i] && (
                  <Star size={10} color={T.amber} />
                )}
              </div>
              <span style={{
                fontFamily: T.fontMono, fontSize: mobile ? 10 : 11,
                color: creedAffirmed[i] ? T.amber : T.silver,
                letterSpacing: '0.14em', lineHeight: 1.5,
                transition: 'color 0.15s',
              }}>
                {['I', 'II', 'III', 'IV', 'V'][i]} · The Pledge of {title}
              </span>
            </div>
          ))}
        </div>

        <button
          disabled={!allAffirmed}
          onClick={() => { if (allAffirmed) window.location.href = 'transmission.html'; }}
          style={{
            padding: '16px 36px',
            background: allAffirmed ? T.amber : 'transparent',
            color: allAffirmed ? T.void : `${T.silver}55`,
            border: allAffirmed ? 'none' : `1px solid ${T.silver}33`,
            borderRadius: 0,
            fontFamily: T.fontMono, fontSize: 12,
            letterSpacing: '0.28em', fontWeight: 600,
            textTransform: 'uppercase',
            cursor: allAffirmed ? 'pointer' : 'default',
            transition: 'all 0.2s',
          }}
        >{allAffirmed ? 'CONTINUE TRANSMISSION INSIDE →' : 'AFFIRM THE CREED TO CONTINUE'}</button>

        <div style={{ marginTop: 32 }}>
          <button onClick={onReset} style={{
            background: 'none', border: 'none',
            color: T.silver, opacity: 0.6,
            fontFamily: T.fontMono, fontSize: 10,
            letterSpacing: '0.2em', cursor: 'pointer',
          }}>← Return to enrollment (demo)</button>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Enrollment, Confirmation });
