// form.jsx — Multi-step registration wizard
//
// HARDENING v2 (pre-Ethical Hacking):
// 1. Token compartido con Apps Script (TOKEN_API).
// 2. Honeypot anti-bot (campo "website" oculto fuera de pantalla).
// 3. Validación cliente: RUT (módulo 11), email robusto, longitudes,
//    sanitización contra inyección HTML/scripts.
// 4. Rate limit cliente: máx 3 envíos por sesión, mín 60s entre envíos.
// 5. Checkbox de consentimiento Ley 19.628 obligatorio.
// 6. SessionId aleatorio por pestaña para rate limit servidor.

const { useState, useEffect, useRef, useMemo } = React;

// ─────────────────────────────────────────────────────────────────────────────
// Google Sheets webhook (Apps Script Web App URL)
// Paste here the deployment URL from your Google Apps Script.
// While empty the form falls back to local "success" mode — no data leaves the
// browser. See README-google-sheets.md for setup instructions.
const SHEETS_WEBHOOK_URL = "https://script.google.com/macros/s/AKfycbzjO5D6IK9Mjl81jnTC8BBb9dMRUn9lriZyDZ_DwNeXxMWfIyi8rBIme9SOxfCkoNVuLw/exec"; // Apps Script publicado desde copaculinariacarozzi@gmail.com

// Token compartido con el Apps Script. Debe coincidir con TOKEN_API
// definido en el servidor. Si no coincide, el servidor rechaza la petición.
const TOKEN_API = "cck2026_jh0MX_alRMQ4Nbjh";
// ─────────────────────────────────────────────────────────────────────────────

// ── SessionId único por pestaña (para rate limit en servidor) ──
const SESSION_ID = (function(){
  try {
    let s = sessionStorage.getItem('cck_sid');
    if (!s) {
      s = 'sid_' + Math.random().toString(36).slice(2, 10) +
                   Date.now().toString(36);
      sessionStorage.setItem('cck_sid', s);
    }
    return s;
  } catch(e) {
    // sessionStorage puede fallar en modo privado de algunos navegadores
    return 'sid_' + Math.random().toString(36).slice(2, 10);
  }
})();

// ── Validadores cliente ──

// Validación de RUT chileno con dígito verificador real (módulo 11).
// Tolera formato con/sin puntos, con/sin guión.
function validarRut(rut){
  if(!rut) return false;
  const limpio = String(rut).replace(/\./g,'').replace(/\s/g,'').toUpperCase();
  const m = limpio.match(/^(\d{1,8})-?([\dK])$/);
  if(!m) return false;
  const cuerpo = m[1];
  const dv = m[2];
  let suma = 0, mult = 2;
  for(let i = cuerpo.length - 1; i >= 0; i--){
    suma += parseInt(cuerpo.charAt(i), 10) * mult;
    mult = mult === 7 ? 2 : mult + 1;
  }
  const resto = suma % 11;
  const calc = 11 - resto;
  const esperado = calc === 11 ? '0' : (calc === 10 ? 'K' : String(calc));
  return dv === esperado;
}

// Email: regex razonable, longitud máxima, sin caracteres de control
function validarEmail(email){
  if(!email) return false;
  const e = String(email).trim();
  if(e.length === 0 || e.length > 254) return false;
  if(/[\x00-\x1F\x7F]/.test(e)) return false;
  return /^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/.test(e);
}

// Teléfono chileno: 8-12 dígitos (acepta +56, espacios, guiones; valida solo dígitos)
function validarTelefono(tel){
  if(!tel) return false;
  const solo = String(tel).replace(/[\s\-\+\(\)]/g, '');
  return /^\d{8,12}$/.test(solo);
}

// Sanitizar texto: escapar HTML básico, eliminar caracteres de control,
// limitar longitud. NO se permite < > " ' & sin escapar.
function sanitizarTexto(valor, maxLen){
  if(valor === null || valor === undefined) return '';
  let s = String(valor);
  // Quitar caracteres de control (excepto \n y \t)
  s = s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
  // Escape básico de HTML
  s = s.replace(/&/g, '&amp;')
       .replace(/</g, '&lt;')
       .replace(/>/g, '&gt;')
       .replace(/"/g, '&quot;')
       .replace(/'/g, '&#39;');
  // Limitar longitud
  if(typeof maxLen === 'number' && s.length > maxLen){
    s = s.slice(0, maxLen);
  }
  return s.trim();
}

// Sanitización ligera para campos cortos (nombre, etc.): solo escapa HTML
// sin reemplazar entidades, manteniendo el texto legible. Más permisiva.
function limpiarCampo(valor, maxLen){
  if(valor === null || valor === undefined) return '';
  let s = String(valor);
  s = s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
  // Bloquear cualquier intento de inyectar etiquetas
  s = s.replace(/<[^>]*>/g, '');
  if(typeof maxLen === 'number' && s.length > maxLen){
    s = s.slice(0, maxLen);
  }
  return s.trim();
}

// ── Rate limit cliente: máx 3 envíos por sesión, mín 60s entre envíos ──
const RATE_MAX_POR_SESION = 3;
const RATE_MIN_SEGUNDOS = 60;

function chequearRateLimit(){
  try {
    const raw = sessionStorage.getItem('cck_envios') || '[]';
    const envios = JSON.parse(raw);
    const ahora = Date.now();

    if (envios.length >= RATE_MAX_POR_SESION) {
      return { ok: false, motivo: 'maximo' };
    }
    if (envios.length > 0) {
      const ultimo = envios[envios.length - 1];
      const segs = (ahora - ultimo) / 1000;
      if (segs < RATE_MIN_SEGUNDOS) {
        const esperar = Math.ceil(RATE_MIN_SEGUNDOS - segs);
        return { ok: false, motivo: 'espera', segundos: esperar };
      }
    }
    return { ok: true };
  } catch(e){
    return { ok: true }; // si sessionStorage falla, dejar pasar
  }
}

function registrarEnvioCliente(){
  try {
    const raw = sessionStorage.getItem('cck_envios') || '[]';
    const envios = JSON.parse(raw);
    envios.push(Date.now());
    sessionStorage.setItem('cck_envios', JSON.stringify(envios));
  } catch(e){}
}

// ─────────────────────────────────────────────────────────────────────────────

const REGIONES = [
  'Arica y Parinacota','Tarapacá','Antofagasta','Atacama','Coquimbo','Valparaíso',
  'Metropolitana de Santiago','Lib. Bernardo O\'Higgins','Maule','Ñuble','Biobío',
  'La Araucanía','Los Ríos','Los Lagos','Aysén','Magallanes y Antártica'
];
const CIUDADES_CLASIF = ['Antofagasta','La Serena','Viña del Mar','Santiago','Puerto Montt','Concepción'];
const TIPO_INST = ['Hotel','Restaurant','Catering','Casino','Otro'];
const TALLAS = ['S','M','L','XL','XXL'];

// ── Field helpers ──────────────────────────────────────────

const Field = ({label, required, error, children, span=1, hint}) => (
  <label style={{display:'block', gridColumn:`span ${span}`}}>
    <div style={{
      display:'flex', justifyContent:'space-between', alignItems:'baseline',
      fontSize:9.5, letterSpacing:'.12em', textTransform:'uppercase', fontWeight:700,
      color:error ? 'var(--c-red)' : 'rgba(255,255,255,.55)', marginBottom:4
    }}>
      <span>{label}{required && <span style={{color:'var(--c-red)', marginLeft:3}}>*</span>}</span>
      {hint && !error && <span style={{textTransform:'none', letterSpacing:'.02em', fontSize:9, color:'rgba(255,255,255,.35)', fontWeight:500}}>{hint}</span>}
      {error && <span style={{textTransform:'none', letterSpacing:'.02em', fontSize:9.5, fontWeight:500}}>{error}</span>}
    </div>
    {children}
  </label>
);

const inputBase = {
  width:'100%', padding:'9px 12px',
  background:'rgba(46,42,107,.18)',
  border:'1px solid rgba(255,255,255,.12)',
  borderRadius:6, color:'#fff', fontSize:13.5, fontFamily:'inherit',
  outline:'none', transition:'border-color .2s, background .2s',
  height:38
};

const Input = ({value, onChange, type='text', placeholder, error, ...rest}) => (
  <input type={type} value={value||''} onChange={e=>onChange(e.target.value)} placeholder={placeholder}
    style={{...inputBase, borderColor: error ? 'var(--c-red)' : inputBase.border}}
    onFocus={e=>{if(!error)e.target.style.borderColor='rgba(255,255,255,.4)'}}
    onBlur={e=>{if(!error)e.target.style.borderColor='rgba(255,255,255,.12)'}}
    {...rest}/>
);

const Select = ({value, onChange, options, placeholder, error}) => (
  <div style={{position:'relative'}}>
    <select value={value||''} onChange={e=>onChange(e.target.value)} style={{
      ...inputBase, appearance:'none', paddingRight:40,
      borderColor: error ? 'var(--c-red)' : inputBase.border,
      color: value ? '#fff' : 'rgba(255,255,255,.4)'
    }}>
      <option value="" style={{background:'#1a1a1a'}}>{placeholder || 'Selecciona…'}</option>
      {options.map(o => <option key={o} value={o} style={{background:'#1a1a1a', color:'#fff'}}>{o}</option>)}
    </select>
    <svg style={{position:'absolute', right:14, top:'50%', transform:'translateY(-50%)', pointerEvents:'none'}} width="14" height="14" viewBox="0 0 24 24" fill="none">
      <path d="M6 9l6 6 6-6" stroke="rgba(255,255,255,.5)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  </div>
);

const Radio = ({value, onChange, options}) => (
  <div style={{display:'flex', gap:8, flexWrap:'wrap'}}>
    {options.map(o => (
      <button type="button" key={o} onClick={()=>onChange(o)} style={{
        padding:'9px 14px', borderRadius:6, border:'1px solid', cursor:'pointer',
        borderColor: value===o ? 'var(--c-red)' : 'rgba(255,255,255,.15)',
        background: value===o ? 'rgba(226,35,26,.12)' : 'transparent',
        color: value===o ? '#fff' : 'rgba(255,255,255,.75)',
        fontSize:13, fontWeight:value===o ? 700 : 500, fontFamily:'inherit',
        transition:'all .2s'
      }}>{o}</button>
    ))}
  </div>
);

const Textarea = ({value, onChange, placeholder, rows=5, error}) => (
  <textarea value={value||''} onChange={e=>onChange(e.target.value)} placeholder={placeholder} rows={rows}
    style={{...inputBase, resize:'vertical', borderColor: error ? 'var(--c-red)' : inputBase.border, fontFamily:'inherit'}}/>
);

const FileField = ({value, onChange, accept, hint}) => {
  const ref = useRef(null);
  return (
    <div>
      <input ref={ref} type="file" accept={accept} style={{display:'none'}} onChange={e=>onChange(e.target.files[0]?.name || '')}/>
      <button type="button" onClick={()=>ref.current?.click()} style={{
        width:'100%', padding:'10px 14px',
        background:'rgba(46,42,107,.12)', border:'1px dashed rgba(255,255,255,.22)',
        borderRadius:6, color: value ? '#fff' : 'rgba(255,255,255,.55)', fontSize:14, cursor:'pointer',
        textAlign:'left', display:'flex', alignItems:'center', justifyContent:'space-between',
        fontFamily:'inherit'
      }}>
        <span>{value || hint || 'Subir archivo (PDF, JPG, PNG)'}</span>
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </button>
    </div>
  );
};

// ── Validation ──────────────────────────────────────────

// Los validators de paso delegan en las MISMAS funciones fuertes que usa
// handleSubmit (validarRut con módulo 11, validarEmail, validarTelefono).
// Así el avance entre pasos aplica el mismo criterio que el envío final:
// nada inválido puede pasar al siguiente paso.
const validators = {
  required: v => !v ? 'Requerido' : null,
  rut: v => {
    if (!v) return 'Requerido';
    if (!validarRut(v)) return 'RUT inválido';
    return null;
  },
  email: v => {
    if (!v) return 'Requerido';
    if (!validarEmail(v)) return 'Correo inválido';
    return null;
  },
  phone: v => {
    if (!v) return 'Requerido';
    if (!validarTelefono(v)) return 'Teléfono inválido';
    return null;
  },
};

// ── Person block ──────────────────────────────────────────

function PersonBlock({title, badge, data, set, fieldPrefix='', errors={}, extraTopRight, instagramRequired=false}){
  const f = (key) => data[key];
  const setF = (key) => (v) => set({...data, [key]: v});

  return (
    <div style={{
      background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)',
      borderRadius:8, padding:'20px 22px 18px', marginBottom:12
    }}>
      <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:18, gap:16, flexWrap:'wrap'}}>
        <div style={{display:'flex', alignItems:'center', gap:12}}>
          {badge && <div style={{
            width:32, height:32, borderRadius:6, background:'var(--c-red)',
            display:'flex', alignItems:'center', justifyContent:'center',
            fontFamily:'var(--f-display)', fontWeight:700, fontSize:14, color:'#fff'
          }}>{badge}</div>}
          <h4 className="display" style={{fontSize:18, margin:0, color:'#fff'}}>{title}</h4>
        </div>
        {extraTopRight}
      </div>

      <div style={{display:'grid', gridTemplateColumns:'repeat(12, 1fr)', gap:10}} className="form-row">
        <Field label="Género" required span={3}>
          <Radio value={f('genero')} onChange={setF('genero')} options={['Hombre','Mujer']}/>
        </Field>
        <Field label="Nacionalidad" required span={3}>
          <Radio value={f('nacionalidad')} onChange={setF('nacionalidad')} options={['Chilena','Extranjera']}/>
        </Field>
        <Field label="Talla" required span={2}>
          <Select value={f('talla')} onChange={setF('talla')} options={TALLAS} placeholder="—"/>
        </Field>
        <Field label="RUT" required span={4} hint="12345678-9" error={errors[fieldPrefix+'rut']}>
          <Input value={f('rut')} onChange={setF('rut')} placeholder="12345678-9"/>
        </Field>

        <Field label="Nombres" required span={4} error={errors[fieldPrefix+'nombres']}>
          <Input value={f('nombres')} onChange={setF('nombres')} placeholder="Ej: María Fernanda"/>
        </Field>
        <Field label="Apellido paterno" required span={4} error={errors[fieldPrefix+'apPaterno']}>
          <Input value={f('apPaterno')} onChange={setF('apPaterno')} placeholder="Ej: Soto"/>
        </Field>
        <Field label="Apellido materno" required span={4}>
          <Input value={f('apMaterno')} onChange={setF('apMaterno')} placeholder="Ej: Rojas"/>
        </Field>

        <Field label="Dirección" required span={5}>
          <Input value={f('direccion')} onChange={setF('direccion')} placeholder="Calle, número, depto"/>
        </Field>
        <Field label="Comuna" required span={3}>
          <Input value={f('comuna')} onChange={setF('comuna')} placeholder="Comuna"/>
        </Field>
        <Field label="Región" required span={4}>
          <Select value={f('region')} onChange={setF('region')} options={REGIONES} placeholder="Selecciona"/>
        </Field>

        <Field label="Celular" required span={4} hint="+569XXXXXXXX" error={errors[fieldPrefix+'celular']}>
          <Input value={f('celular')} onChange={setF('celular')} placeholder="+56912345678"/>
        </Field>
        <Field label="Correo" required span={4} error={errors[fieldPrefix+'correo']}>
          <Input value={f('correo')} onChange={setF('correo')} placeholder="tu@correo.cl" type="email"/>
        </Field>
        <Field label={instagramRequired ? 'Instagram' : 'Instagram (opcional)'} span={4} hint="@usuario">
          <Input value={f('instagram')} onChange={setF('instagram')} placeholder="@usuario"/>
        </Field>
      </div>

      <style>{`
        @media (max-width: 960px){
          .form-row { grid-template-columns:repeat(6, 1fr) !important; }
          .form-row > label { grid-column: span 3 !important; }
        }
        @media (max-width: 540px){
          .form-row { grid-template-columns:1fr !important; }
          .form-row > label { grid-column: span 1 !important; }
        }
      `}</style>
    </div>
  );
}

// ── Wizard ──────────────────────────────────────────

function FormWizard(){
  const [step, setStep] = useState(0);
  const [category, setCategory] = useState('');
  const [errors, setErrors] = useState({});
  const [submitted, setSubmitted] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState('');

  // Junior data
  const [c1, setC1] = useState({});
  const [c2, setC2] = useState({});
  const [coach, setCoach] = useState({nombres:'', apPaterno:'', apMaterno:'', rut:''});
  const [institucion, setInstitucion] = useState({nombre:'', sede:'', carta:''});

  // Profesional data
  const [part, setPart] = useState({});
  const [ayudante, setAyudante] = useState({nombres:'', apPaterno:'', apMaterno:'', rut:''});
  const [profMeta, setProfMeta] = useState({tipoInst:'', ciudadClasif:''});

  // Propuesta
  const [propuesta, setPropuesta] = useState({menu:'', archivo:''});
  const [acepta, setAcepta] = useState(false);

  // Preselect on event
  useEffect(()=>{
    const handler = (e) => {
      setCategory(e.detail);
      // Auto-advance from step 0
      setTimeout(()=>setStep(1), 200);
    };
    window.addEventListener('preselect-category', handler);
    return ()=> window.removeEventListener('preselect-category', handler);
  },[]);

  const steps = category === 'junior'
    ? ['Categoría','Concursantes','Institución & Coach','Postulación','Revisión']
    : category === 'profesional'
    ? ['Categoría','Participante','Ayudante & Clasificatoria','Postulación','Revisión']
    : ['Categoría','Datos','Equipo','Postulación','Revisión'];

  // Validation per step
  const validateStep = () => {
    const e = {};
    if (step === 1){
      const checkPerson = (p, prefix) => {
        if (!p.nombres) e[prefix+'nombres'] = 'Requerido';
        if (!p.apPaterno) e[prefix+'apPaterno'] = 'Requerido';
        const rutErr = validators.rut(p.rut); if (rutErr) e[prefix+'rut'] = rutErr;
        const phoneErr = validators.phone(p.celular); if (phoneErr) e[prefix+'celular'] = phoneErr;
        const emailErr = validators.email(p.correo); if (emailErr) e[prefix+'correo'] = emailErr;
      };
      if (category === 'junior'){
        checkPerson(c1, 'c1.');
        checkPerson(c2, 'c2.');
      } else {
        checkPerson(part, 'p.');
      }
    }
    if (step === 2){
      // Paso 2: validar el RUT del coach (Junior) o ayudante (Senior).
      // Mismo criterio módulo 11 que el envío final.
      const persona = category === 'junior' ? coach : ayudante;
      const rutErr = validators.rut(persona.rut);
      if (rutErr) e['coach.rut'] = rutErr;
    }
    setErrors(e);
    return Object.keys(e).length === 0;
  };

  const next = () => {
    if (!validateStep()) {
      // Smooth scroll to top of form
      document.getElementById('inscripcion')?.scrollIntoView({behavior:'smooth', block:'start'});
      return;
    }
    setStep(s => Math.min(s+1, steps.length-1));
    setTimeout(()=>document.getElementById('inscripcion')?.scrollIntoView({behavior:'smooth', block:'start'}), 100);
  };
  const back = () => {
    setStep(s => Math.max(s-1, 0));
    setTimeout(()=>document.getElementById('inscripcion')?.scrollIntoView({behavior:'smooth', block:'start'}), 100);
  };

  const handleSubmit = async () => {
    if (!acepta || submitting) return;
    setSubmitError('');

    // ── Rate limit cliente: máx 3 envíos por sesión, mín 60s entre envíos ──
    const rl = chequearRateLimit();
    if (!rl.ok) {
      if (rl.motivo === 'maximo') {
        setSubmitError('Has alcanzado el máximo de inscripciones por sesión. Si necesitas inscribir más equipos, escríbenos a contacto@copaculinariacarozzi.cl.');
      } else if (rl.motivo === 'espera') {
        setSubmitError('Por favor espera ' + rl.segundos + ' segundos antes de enviar otra inscripción.');
      }
      return;
    }

    // ── Honeypot cliente: leer el campo trampa ──
    // Si un bot llenó el campo "website" (oculto), abortamos silenciosamente.
    let hpValor = '';
    try {
      const hp = document.getElementById('cck_hp_website');
      hpValor = hp ? hp.value : '';
    } catch(e){}
    if (hpValor) {
      // Bot detectado: simulamos éxito SIN enviar al servidor.
      setSubmitting(true);
      await new Promise(r => setTimeout(r, 700));
      setSubmitting(false);
      setSubmitted(true);
      return;
    }

    // ── Validación cliente de datos críticos antes de enviar ──
    const principal = category === 'junior' ? c1 : part;

    if (!validarRut(principal.rut)) {
      setSubmitError('El RUT del ' + (category === 'junior' ? 'Concursante 1' : 'Participante') + ' no es válido. Revísalo e inténtalo nuevamente.');
      return;
    }
    if (!validarEmail(principal.correo)) {
      setSubmitError('El correo del ' + (category === 'junior' ? 'Concursante 1' : 'Participante') + ' no tiene un formato válido.');
      return;
    }
    if (principal.celular && !validarTelefono(principal.celular)) {
      setSubmitError('El teléfono del ' + (category === 'junior' ? 'Concursante 1' : 'Participante') + ' no tiene un formato válido.');
      return;
    }
    // Para Junior, validar también C2
    if (category === 'junior') {
      if (c2.rut && !validarRut(c2.rut)) {
        setSubmitError('El RUT del Concursante 2 no es válido. Revísalo e inténtalo nuevamente.');
        return;
      }
      if (c2.correo && !validarEmail(c2.correo)) {
        setSubmitError('El correo del Concursante 2 no tiene un formato válido.');
        return;
      }
    }
    // Coach (Junior) o Ayudante (Senior): validar RUT si vino
    const coachLike = category === 'junior' ? coach : ayudante;
    if (coachLike.rut && !validarRut(coachLike.rut)) {
      setSubmitError('El RUT del ' + (category === 'junior' ? 'Coach' : 'Ayudante') + ' no es válido.');
      return;
    }

    // Build flat payload — categoria + concursantes/participante + coach/ayudante + institución/clasificatoria + propuesta
    const _now = new Date();
    const _pad = (n) => String(n).padStart(2, '0');
    const stamp = _pad(_now.getDate()) + '-' + _pad(_now.getMonth() + 1) + '-' +
                  _now.getFullYear() + ' ' + _pad(_now.getHours()) + ':' + _pad(_now.getMinutes());
    const payload = {
      // ── Campos de seguridad (validados por el servidor) ──
      _token: TOKEN_API,
      _sid: SESSION_ID,
      website: '',  // honeypot: vacío en envíos legítimos

      timestamp: stamp,
      categoria: category,

      // Concursante 1 / Participante (con limpieza ligera anti-HTML)
      c1_genero: principal.genero || '',
      c1_nombres: limpiarCampo(principal.nombres, 100),
      c1_apPaterno: limpiarCampo(principal.apPaterno, 100),
      c1_apMaterno: limpiarCampo(principal.apMaterno, 100),
      c1_rut: limpiarCampo(principal.rut, 20),
      c1_nacionalidad: limpiarCampo(principal.nacionalidad, 50),
      c1_direccion: limpiarCampo(principal.direccion, 200),
      c1_comuna: limpiarCampo(principal.comuna, 100),
      c1_region: limpiarCampo(principal.region, 100),
      c1_celular: limpiarCampo(principal.celular, 20),
      c1_correo: limpiarCampo(principal.correo, 254),
      c1_talla: principal.talla || '',
      c1_instagram: limpiarCampo(principal.instagram, 50),

      // Concursante 2 (solo Junior)
      c2_genero: category === 'junior' ? (c2.genero || '') : '',
      c2_nombres: category === 'junior' ? limpiarCampo(c2.nombres, 100) : '',
      c2_apPaterno: category === 'junior' ? limpiarCampo(c2.apPaterno, 100) : '',
      c2_apMaterno: category === 'junior' ? limpiarCampo(c2.apMaterno, 100) : '',
      c2_rut: category === 'junior' ? limpiarCampo(c2.rut, 20) : '',
      c2_nacionalidad: category === 'junior' ? limpiarCampo(c2.nacionalidad, 50) : '',
      c2_direccion: category === 'junior' ? limpiarCampo(c2.direccion, 200) : '',
      c2_comuna: category === 'junior' ? limpiarCampo(c2.comuna, 100) : '',
      c2_region: category === 'junior' ? limpiarCampo(c2.region, 100) : '',
      c2_celular: category === 'junior' ? limpiarCampo(c2.celular, 20) : '',
      c2_correo: category === 'junior' ? limpiarCampo(c2.correo, 254) : '',
      c2_talla: category === 'junior' ? (c2.talla || '') : '',
      c2_instagram: category === 'junior' ? limpiarCampo(c2.instagram, 50) : '',

      // Coach (Junior) o Ayudante (Profesional)
      coach_nombres: limpiarCampo(category === 'junior' ? coach.nombres : ayudante.nombres, 100),
      coach_apPaterno: limpiarCampo(category === 'junior' ? coach.apPaterno : ayudante.apPaterno, 100),
      coach_apMaterno: limpiarCampo(category === 'junior' ? coach.apMaterno : ayudante.apMaterno, 100),
      coach_rut: limpiarCampo(category === 'junior' ? coach.rut : ayudante.rut, 20),
      coach_rol: category === 'junior' ? 'Coach' : 'Ayudante',

      // Institución (Junior) o lugar de trabajo (Profesional)
      institucion: limpiarCampo(category === 'junior' ? institucion.nombre : profMeta.tipoInst, 200),
      sede: limpiarCampo(category === 'junior' ? institucion.sede : profMeta.ciudadClasif, 100),
      carta_apoyo: category === 'junior' ? limpiarCampo(institucion.carta, 200) : '',

      // Propuesta (texto largo, hasta 2000 caracteres)
      menu: limpiarCampo(propuesta.menu, 2000),
      archivo_propuesta: limpiarCampo(propuesta.archivo, 200),
    };

    // If no webhook configured, simulate success (prototype mode)
    if (!SHEETS_WEBHOOK_URL){
      setSubmitting(true);
      await new Promise(r => setTimeout(r, 700));
      setSubmitting(false);
      setSubmitted(true);
      return;
    }

    setSubmitting(true);
    try {
      // Enviamos como text/plain: Apps Script lo acepta sin preflight CORS
      // y, a diferencia de 'no-cors', el navegador SÍ puede leer la
      // respuesta, así confirmamos que la inscripción se guardó de verdad.
      const res = await fetch(SHEETS_WEBHOOK_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'text/plain;charset=utf-8' },
        body: JSON.stringify(payload),
      });

      if (!res.ok) {
        throw new Error('HTTP ' + res.status);
      }

      const data = await res.json();

      if (data && data.ok) {
        // Éxito real (incluye el caso duplicado, que también es ok)
        registrarEnvioCliente();
        setSubmitted(true);
      } else {
        // El Apps Script respondió pero rechazó la inscripción
        setSubmitError(
          'No pudimos registrar tu inscripción. ' +
          'Revisa que los datos estén completos e inténtalo nuevamente. ' +
          'Si el problema persiste, escríbenos a contacto@copaculinariacarozzi.cl.'
        );
      }
    } catch (err){
      // Error de red, servidor caído, o respuesta ilegible
      setSubmitError('No pudimos enviar tu inscripción. Revisa tu conexión e inténtalo nuevamente.');
    } finally {
      setSubmitting(false);
    }
  };

  // ── Step renderers ──

  const renderStep0 = () => (
    <div className="fade-up">
      <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>Elige tu categoría</h3>
      <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:520, fontSize:14}}>
        Define en qué categoría compites. Esto adaptará los siguientes pasos del formulario.
      </p>

      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:18}} className="cat-pick">
        {[
          {id:'junior', label:'Junior', desc:'Estudiantes de educación superior de gastronomía. Equipo de 2 personas.', meta:'Dupla · 1 coach', prize:'$10.000 USD'},
          {id:'profesional', label:'Senior', desc:'Cocineros profesionales con experiencia comprobable. Participación individual.', meta:'Individual · 1 ayudante', prize:'$5.000.000 CLP'},
        ].map(c => {
          const active = category === c.id;
          return (
            <button key={c.id} type="button" onClick={()=>setCategory(c.id)} style={{
              textAlign:'left', padding:'24px 22px',
              background: active ? 'rgba(226,35,26,.08)' : 'rgba(255,255,255,.025)',
              border:'1px solid',
              borderColor: active ? 'var(--c-red)' : 'rgba(255,255,255,.1)',
              borderRadius:8, cursor:'pointer', transition:'all .2s',
              color:'#fff', fontFamily:'inherit', position:'relative'
            }}>
              {active && (
                <div style={{position:'absolute', top:18, right:18, width:24, height:24, borderRadius:'50%', background:'var(--c-red)', display:'flex', alignItems:'center', justifyContent:'center'}}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                </div>
              )}
              <div className="display" style={{fontSize:30, color:'#fff', marginBottom:4}}>{c.label}</div>
              <div style={{fontSize:10.5, letterSpacing:'.16em', textTransform:'uppercase', color:'var(--c-red)', fontWeight:700, marginBottom:14}}>{c.meta}</div>
              <p style={{fontSize:13.5, color:'rgba(255,255,255,.7)', margin:'0 0 16px', lineHeight:1.55}}>{c.desc}</p>
              <div style={{paddingTop:14, borderTop:'1px solid rgba(255,255,255,.08)', display:'flex', justifyContent:'space-between', alignItems:'baseline'}}>
                <span style={{fontSize:10, letterSpacing:'.2em', color:'rgba(255,255,255,.5)', textTransform:'uppercase', fontWeight:700}}>1er Lugar</span>
                <span className="display" style={{fontSize:22, color:'#fff'}}>{c.prize}</span>
              </div>
            </button>
          );
        })}
      </div>

      <style>{`
        @media (max-width: 720px){ .cat-pick { grid-template-columns:1fr !important; } }
      `}</style>
    </div>
  );

  const renderStep1 = () => (
    <div className="fade-up">
      <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>
        {category === 'junior' ? 'Datos de los concursantes' : 'Datos del participante'}
      </h3>
      <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:560, fontSize:14}}>
        {category === 'junior'
          ? 'Completa la información de ambos concursantes. Todos los campos marcados son obligatorios.'
          : 'Completa tu información personal. Todos los campos marcados son obligatorios.'}
      </p>

      {category === 'junior' ? (
        <>
          <PersonBlock title="Concursante 1" badge="01" data={c1} set={setC1} fieldPrefix="c1." errors={errors}/>
          <PersonBlock title="Concursante 2" badge="02" data={c2} set={setC2} fieldPrefix="c2." errors={errors}/>
        </>
      ) : (
        <PersonBlock title="Participante" badge="01" data={part} set={setPart} fieldPrefix="p." errors={errors} instagramRequired/>
      )}
    </div>
  );

  const renderStep2Junior = () => (
    <div className="fade-up">
      <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>Institución y coach</h3>
      <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:560, fontSize:14}}>
        Datos de la casa de estudios y del coach que los acompañará durante la competencia.
      </p>

      <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:'20px 22px', marginBottom:12}}>
        <h4 className="display" style={{fontSize:18, margin:'0 0 12px', color:'#fff'}}>Institución</h4>
        <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:12}} className="form-row">
          <Field label="Institución" required>
            <Input value={institucion.nombre} onChange={v=>setInstitucion({...institucion, nombre:v})} placeholder="Centro educacional, ej: DUOC UC"/>
          </Field>
          <Field label="Sede" required>
            <Input value={institucion.sede} onChange={v=>setInstitucion({...institucion, sede:v})} placeholder="Ej: San Carlos de Apoquindo"/>
          </Field>
          <Field label="Carta de apoyo del instituto" required span={2} hint="PDF firmado por la institución">
            <FileField value={institucion.carta} onChange={v=>setInstitucion({...institucion, carta:v})} accept=".pdf,.jpg,.png"/>
          </Field>
        </div>
      </div>

      <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:'20px 22px'}}>
        <h4 className="display" style={{fontSize:18, margin:'0 0 12px', color:'#fff'}}>Coach</h4>
        <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:12}} className="form-row">
          <Field label="Nombres" required>
            <Input value={coach.nombres} onChange={v=>setCoach({...coach, nombres:v})} placeholder="Nombres del coach"/>
          </Field>
          <Field label="RUT" required hint="12345678-9" error={errors['coach.rut']}>
            <Input value={coach.rut} onChange={v=>setCoach({...coach, rut:v})} placeholder="12345678-9"/>
          </Field>
          <Field label="Apellido paterno" required>
            <Input value={coach.apPaterno} onChange={v=>setCoach({...coach, apPaterno:v})}/>
          </Field>
          <Field label="Apellido materno" required>
            <Input value={coach.apMaterno} onChange={v=>setCoach({...coach, apMaterno:v})}/>
          </Field>
        </div>
      </div>
    </div>
  );

  const renderStep2Prof = () => (
    <div className="fade-up">
      <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>Ayudante y clasificatoria</h3>
      <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:560, fontSize:14}}>
        Datos del ayudante que te acompañará y la ciudad donde compites.
      </p>

      <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:'20px 22px', marginBottom:12}}>
        <h4 className="display" style={{fontSize:18, margin:'0 0 12px', color:'#fff'}}>Lugar de trabajo y clasificatoria</h4>
        <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:12}} className="form-row">
          <Field label="Tipo de establecimiento" required>
            <Select value={profMeta.tipoInst} onChange={v=>setProfMeta({...profMeta, tipoInst:v})} options={TIPO_INST} placeholder="Hotel, Restaurant, etc."/>
          </Field>
          <Field label="Ciudad clasificatoria" required>
            <Select value={profMeta.ciudadClasif} onChange={v=>setProfMeta({...profMeta, ciudadClasif:v})} options={CIUDADES_CLASIF} placeholder="Selecciona ciudad"/>
          </Field>
        </div>
      </div>

      <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:'20px 22px'}}>
        <h4 className="display" style={{fontSize:18, margin:'0 0 12px', color:'#fff'}}>Ayudante</h4>
        <div style={{display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:12}} className="form-row">
          <Field label="Nombres" required>
            <Input value={ayudante.nombres} onChange={v=>setAyudante({...ayudante, nombres:v})} placeholder="Nombres del ayudante"/>
          </Field>
          <Field label="RUT" required hint="12345678-9" error={errors['coach.rut']}>
            <Input value={ayudante.rut} onChange={v=>setAyudante({...ayudante, rut:v})} placeholder="12345678-9"/>
          </Field>
          <Field label="Apellido paterno" required>
            <Input value={ayudante.apPaterno} onChange={v=>setAyudante({...ayudante, apPaterno:v})}/>
          </Field>
          <Field label="Apellido materno" required>
            <Input value={ayudante.apMaterno} onChange={v=>setAyudante({...ayudante, apMaterno:v})}/>
          </Field>
        </div>
      </div>
    </div>
  );

  const renderStep3 = () => (
    <div className="fade-up">
      <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>Tu postulación</h3>
      <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:560, fontSize:14}}>
        Cuéntanos por qué deberías ser parte de la competencia. Puedes escribir tu postulación y, si quieres, adjuntar un archivo de respaldo.
      </p>

      <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:'20px 22px'}}>
        <div style={{display:'grid', gap:24}}>
          <Field label="Tu postulación" required hint="Mín. 200 caracteres">
            <Textarea value={propuesta.menu} onChange={v=>setPropuesta({...propuesta, menu:v})} rows={7}
              placeholder="Cuéntanos sobre tu motivación, tu experiencia, tus logros y qué te hace un buen candidato para representar el talento culinario en esta competencia…"/>
          </Field>
          <Field label="Archivo de respaldo (opcional)" hint="PDF o imagen, hasta 10 MB">
            <FileField value={propuesta.archivo} onChange={v=>setPropuesta({...propuesta, archivo:v})} accept=".pdf,.jpg,.png"
              hint="Adjunta fotografías, recetas o presentación visual"/>
          </Field>
        </div>
      </div>
    </div>
  );

  const renderStep4 = () => {
    const principal = category === 'junior' ? c1 : part;
    return (
      <div className="fade-up">
        <h3 className="display" style={{fontSize:30, margin:'0 0 8px', color:'#fff'}}>Revisión final</h3>
        <p style={{color:'rgba(255,255,255,.65)', marginBottom:22, maxWidth:560, fontSize:14}}>
          Confirma los datos y acepta las bases legales para enviar tu inscripción.
        </p>

        <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:18}} className="review-grid">
          <div style={{background:'rgba(46,42,107,.12)', border:'1px solid rgba(120,110,210,.18)', borderRadius:8, padding:28}}>
            <div style={{fontSize:11, letterSpacing:'.18em', textTransform:'uppercase', fontWeight:700, color:'var(--c-red)', marginBottom:16}}>Resumen</div>
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14, fontSize:13, color:'rgba(255,255,255,.85)'}}>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>Categoría</div>{category === 'junior' ? 'Junior' : 'Senior'}</div>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>{category === 'junior' ? 'Concursante 1' : 'Participante'}</div>{[principal.nombres, principal.apPaterno].filter(Boolean).join(' ') || '—'}</div>
              {category === 'junior' && (
                <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>Concursante 2</div>{[c2.nombres, c2.apPaterno].filter(Boolean).join(' ') || '—'}</div>
              )}
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>Correo</div>{principal.correo || '—'}</div>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>{category === 'junior' ? 'Institución' : 'Establecimiento'}</div>{category === 'junior' ? (institucion.nombre || '—') : (profMeta.tipoInst || '—')}</div>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>{category === 'junior' ? 'Sede' : 'Clasificatoria'}</div>{category === 'junior' ? (institucion.sede || '—') : (profMeta.ciudadClasif || '—')}</div>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>{category === 'junior' ? 'Coach' : 'Ayudante'}</div>{
                category === 'junior'
                  ? [coach.nombres, coach.apPaterno].filter(Boolean).join(' ') || '—'
                  : [ayudante.nombres, ayudante.apPaterno].filter(Boolean).join(' ') || '—'
              }</div>
              <div><div style={{color:'rgba(255,255,255,.45)', fontSize:11, marginBottom:2}}>Postulación</div>{propuesta.menu ? `${propuesta.menu.length} caracteres` : '—'}</div>
            </div>

            <label style={{display:'flex', gap:12, alignItems:'flex-start', marginTop:28, padding:'18px 18px', background:'rgba(226,35,26,.04)', border:'1px solid rgba(226,35,26,.2)', borderRadius:6, cursor:'pointer'}}>
              <input type="checkbox" checked={acepta} onChange={e=>setAcepta(e.target.checked)} style={{marginTop:3, accentColor:'var(--c-red)', width:18, height:18}}/>
              <span style={{fontSize:13, color:'rgba(255,255,255,.85)', lineHeight:1.5}}>
                Declaro haber leído y aceptar las <a href="#" style={{color:'var(--c-red)', fontWeight:700}}>bases legales</a> del concurso, autorizo el tratamiento de mis datos personales con fines de inscripción y comunicación según la <a href="privacidad.html" target="_blank" rel="noopener noreferrer" style={{color:'var(--c-red)', fontWeight:700}}>Política de Privacidad</a> (Ley 19.628 de Chile), y certifico que la información proporcionada es verdadera.
              </span>
            </label>

            {/* Honeypot anti-bot: invisible para humanos, llenado por bots automáticos.
                Si llega lleno al servidor, la inscripción se descarta silenciosamente.
                Usamos position:absolute en lugar de display:none para que los bots lo vean. */}
            <div aria-hidden="true" style={{position:'absolute', left:'-9999px', top:'-9999px', width:1, height:1, overflow:'hidden', opacity:0, pointerEvents:'none'}}>
              <label>
                Si eres humano, deja este campo vacío:
                <input
                  type="text"
                  id="cck_hp_website"
                  name="website"
                  tabIndex={-1}
                  autoComplete="off"
                />
              </label>
            </div>
          </div>

          <div style={{background:'var(--c-navy)', borderRadius:8, padding:28, color:'#fff', position:'relative', overflow:'hidden'}}>
            <div style={{position:'absolute', top:0, right:0, width:160, height:160, background:'radial-gradient(circle at top right, rgba(226,35,26,.45), transparent 70%)', pointerEvents:'none'}}/>
            <div style={{fontSize:11, letterSpacing:'.18em', textTransform:'uppercase', fontWeight:700, color:'rgba(255,255,255,.7)', marginBottom:8}}>Tu llamado</div>
            <h4 className="display" style={{fontSize:34, margin:'0 0 14px', lineHeight:.95}}>Ya estás a un clic.</h4>
            <p style={{fontSize:13, color:'rgba(255,255,255,.8)', margin:'0 0 20px', lineHeight:1.55}}>Recibirás un correo de confirmación con tus datos y los próximos pasos. Nos pondremos en contacto contigo muy pronto.</p>
            <ul style={{listStyle:'none', padding:0, margin:0, display:'flex', flexDirection:'column', gap:10, fontSize:12, color:'rgba(255,255,255,.85)'}}>
              {['Confirmación inmediata por correo','Revisión por el comité Carozzi','Comunicación de tu clasificatoria'].map((t,i)=> (
                <li key={i} style={{display:'flex', gap:10, alignItems:'center'}}>
                  <span style={{width:22, height:22, borderRadius:'50%', background:'var(--c-red)', display:'inline-flex', alignItems:'center', justifyContent:'center', flexShrink:0, fontSize:11, fontWeight:700}}>{i+1}</span>
                  {t}
                </li>
              ))}
            </ul>
          </div>
        </div>

        <style>{`
          @media (max-width: 860px){ .review-grid { grid-template-columns:1fr !important; } }
        `}</style>
      </div>
    );
  };

  // ── Submitted state — pantalla completa ──
  if (submitted){
    return (
      <div style={{
        position:'fixed', inset:0, zIndex:9999,
        display:'flex', alignItems:'center', justifyContent:'center',
        padding:'72px 24px', overflowY:'auto', boxSizing:'border-box',
        background:'linear-gradient(180deg, var(--c-black) 0%, #11132e 55%, var(--c-black) 100%)',
      }}>
        {/* Glows decorativos */}
        <div aria-hidden="true" style={{
          position:'absolute', top:'8%', left:'-12%', width:'55%', height:'55%',
          background:'radial-gradient(ellipse at center, rgba(46,42,107,.4), transparent 62%)',
          pointerEvents:'none', filter:'blur(20px)'
        }}/>
        <div aria-hidden="true" style={{
          position:'absolute', bottom:'4%', right:'-12%', width:'55%', height:'55%',
          background:'radial-gradient(ellipse at center, rgba(226,35,26,.22), transparent 65%)',
          pointerEvents:'none', filter:'blur(20px)'
        }}/>

        <div style={{maxWidth:760, width:'100%', textAlign:'center', position:'relative', zIndex:1, margin:'auto', paddingBlock:24}}>
          <div style={{
            display:'inline-flex', alignItems:'center', justifyContent:'center',
            width:96, height:96, borderRadius:'50%', background:'var(--c-red)',
            marginBottom:32, boxShadow:'0 24px 48px -16px rgba(226,35,26,.6)'
          }}>
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </div>
          <div className="eyebrow" style={{color:'var(--c-red)', marginBottom:18}}>Inscripción enviada</div>
          <h2 className="display h-xl" style={{margin:'0 0 20px', color:'#fff'}}>
            Bienvenido al <span className="script" style={{color:'var(--c-red)', fontSize:'1em', display:'inline-block', transform:'rotate(-3deg)'}}>llamado</span><br/>2026.
          </h2>
          <p style={{fontSize:17, color:'rgba(255,255,255,.7)', lineHeight:1.6, maxWidth:520, marginInline:'auto'}}>
            Tu inscripción fue recibida correctamente. En unos minutos recibirás un correo de confirmación con los detalles de tu registro. Nos pondremos en contacto contigo muy pronto.
          </p>
          <p style={{fontSize:14, color:'rgba(255,255,255,.45)', lineHeight:1.6, maxWidth:480, marginInline:'auto', marginTop:14}}>
            Revisa también tu carpeta de spam o correo no deseado por si acaso.
          </p>
          <div style={{marginTop:36, display:'flex', justifyContent:'center'}}>
            <button className="btn btn-primary btn-lg" onClick={()=>{ window.location.reload(); }}>Volver al inicio</button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <section id="inscripcion" data-screen-label="09 Inscripción" style={{
      paddingTop:64, paddingBottom:80, position:'relative', overflow:'hidden',
      background:'linear-gradient(180deg, var(--c-black) 0%, #11132e 50%, var(--c-black) 100%)',
      color:'#fff'
    }}>
      {/* Top accent: red + navy gradient line */}
      <div aria-hidden="true" style={{position:'absolute', top:0, left:0, right:0, height:1, background:'linear-gradient(90deg, transparent, rgba(46,42,107,.6) 30%, rgba(226,35,26,.6) 50%, rgba(46,42,107,.6) 70%, transparent)'}}/>

      {/* Decorative navy glows */}
      <div aria-hidden="true" style={{
        position:'absolute', top:'10%', left:'-10%', width:'55%', height:'55%',
        background:'radial-gradient(ellipse at center, rgba(46,42,107,.35), transparent 60%)',
        pointerEvents:'none', filter:'blur(20px)'
      }}/>
      <div aria-hidden="true" style={{
        position:'absolute', bottom:'5%', right:'-12%', width:'55%', height:'55%',
        background:'radial-gradient(ellipse at center, rgba(46,42,107,.28), transparent 65%)',
        pointerEvents:'none', filter:'blur(20px)'
      }}/>
      <div aria-hidden="true" style={{
        position:'absolute', top:'40%', left:'50%', transform:'translate(-50%, -50%)', width:'40%', height:'40%',
        background:'radial-gradient(ellipse at center, rgba(226,35,26,.10), transparent 65%)',
        pointerEvents:'none', filter:'blur(40px)'
      }}/>

      <div className="wrap" style={{position:'relative', zIndex:1}}>
        <div data-reveal="up" style={{textAlign:'center', marginBottom:36}}>
          <div className="section-label" style={{justifyContent:'center'}}>Postula al concurso · XI Edición 2026</div>
          <h2 className="display h-lg" style={{margin:'14px 0 18px', color:'#fff', lineHeight:1.02}}>
            Inscríbete en la
            <span className="script" style={{
              color:'var(--c-red)', fontSize:'1.05em',
              display:'block', lineHeight:1.1, marginTop:4, marginBottom:4,
              transform:'rotate(-2deg)', transformOrigin:'center'
            }}>Copa Culinaria</span>
            2026
          </h2>
          <p style={{maxWidth:520, marginInline:'auto', color:'rgba(255,255,255,.65)', fontSize:15, margin:'0 auto'}}>
            Cinco pasos. Menos de diez minutos. Una postulación que puede cambiar tu carrera.
          </p>
        </div>

        {/* Stepper */}
        <div style={{maxWidth:920, margin:'0 auto 32px'}}>
          <div style={{display:'flex', justifyContent:'space-between', position:'relative'}} className="stepper">
            <div style={{position:'absolute', top:18, left:18, right:18, height:2, background:'rgba(46,42,107,.35)', zIndex:0}}/>
            <div style={{position:'absolute', top:18, left:18, height:2, width:`calc(${(step/(steps.length-1))*100}% - 36px*${step/(steps.length-1)})`, background:'var(--c-red)', zIndex:0, transition:'width .4s ease'}}/>
            {steps.map((s, i) => (
              <div key={s} style={{position:'relative', zIndex:1, display:'flex', flexDirection:'column', alignItems:'center', gap:10, flex:'0 0 auto'}}>
                <div style={{
                  width:36, height:36, borderRadius:'50%', background:i<=step ? 'var(--c-red)' : 'rgba(46,42,107,.35)',
                  border:i===step ? '4px solid rgba(226,35,26,.25)' : 'none',
                  display:'flex', alignItems:'center', justifyContent:'center',
                  color:'#fff', fontWeight:700, fontSize:13, transition:'all .3s'
                }}>{i < step ? (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M5 13l4 4L19 7" stroke="#fff" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg>
                ) : i+1}</div>
                <div style={{fontSize:11, letterSpacing:'.08em', textTransform:'uppercase', fontWeight:700, color:i<=step ? '#fff' : 'rgba(255,255,255,.4)', textAlign:'center', maxWidth:120}}>{s}</div>
              </div>
            ))}
          </div>
        </div>

        {/* Step content */}
        <div style={{maxWidth:920, margin:'0 auto'}}>
          {step === 0 && renderStep0()}
          {step === 1 && renderStep1()}
          {step === 2 && (category === 'junior' ? renderStep2Junior() : renderStep2Prof())}
          {step === 3 && renderStep3()}
          {step === 4 && renderStep4()}

          {/* Nav */}
          {submitError && (
            <div role="alert" style={{
              marginTop:20, padding:'14px 18px',
              background:'rgba(226,35,26,.1)', border:'1px solid rgba(226,35,26,.35)',
              borderRadius:6, color:'#fff', fontSize:13, lineHeight:1.5
            }}>
              <strong style={{color:'var(--c-red)'}}>Error · </strong>{submitError}
            </div>
          )}
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginTop:28, gap:12, flexWrap:'wrap'}}>
            <button className="btn btn-ghost" onClick={back} disabled={step===0} style={{opacity:step===0 ? .3 : 1, cursor:step===0?'not-allowed':'pointer'}}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M19 12H5M11 19l-7-7 7-7" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/></svg>
              Atrás
            </button>
            <div style={{fontSize:12, color:'rgba(255,255,255,.5)', letterSpacing:'.08em', fontWeight:600}}>
              Paso {step+1} de {steps.length}
            </div>
            {step < steps.length - 1 ? (
              <button className="btn btn-primary" onClick={next} disabled={step===0 && !category}
                style={{opacity:(step===0 && !category) ? .4 : 1, cursor:(step===0 && !category) ? 'not-allowed' : 'pointer'}}>
                Continuar <Arrow size={12}/>
              </button>
            ) : (
              <button className="btn btn-primary btn-lg" onClick={handleSubmit} disabled={!acepta || submitting}
                style={{opacity:(acepta && !submitting) ? 1 : .55, cursor:(acepta && !submitting) ? 'pointer' : 'not-allowed', minWidth:200, justifyContent:'center'}}>
                {submitting ? (
                  <>
                    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" style={{animation:'spin 1s linear infinite'}}>
                      <circle cx="12" cy="12" r="9" stroke="currentColor" strokeOpacity=".3" strokeWidth="2.4"/>
                      <path d="M21 12a9 9 0 0 0-9-9" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"/>
                    </svg>
                    Enviando…
                  </>
                ) : (
                  <>Enviar inscripción <Arrow/></>
                )}
              </button>
            )}
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {FormWizard});
