// storefront-modals.jsx — TryOn + Reserva + StylizedMap

// ─── Modal shell ────────────────────────────────────────────────────
function ModalShell({ open, onClose, mobile, children, title, kicker }) {
  return (
    <div style={{
      position:'absolute', inset: 0, zIndex: 100,
      background: open ? 'rgba(10,10,10,0.55)' : 'transparent',
      opacity: open ? 1 : 0, pointerEvents: open ? 'auto' : 'none',
      transition: 'opacity .25s',
      display:'flex', alignItems: mobile ? 'stretch' : 'center', justifyContent:'center',
      padding: mobile ? 0 : 24,
    }}>
      <div style={{
        background:'#fff', width:'100%',
        maxWidth: mobile ? '100%' : 920, height: mobile ? '100%' : 'auto',
        maxHeight: mobile ? '100%' : '90%',
        display:'flex', flexDirection:'column',
        transform: open ? 'translateY(0)' : 'translateY(20px)',
        transition:'transform .35s cubic-bezier(.2,.8,.2,1)',
        overflow:'hidden',
      }}>
        <div style={{
          padding: mobile ? '14px 16px' : '20px 28px', borderBottom:`1px solid ${C.border}`,
          display:'flex', justifyContent:'space-between', alignItems:'center',
        }}>
          <div>
            <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.2em', textTransform:'uppercase', color: C.fgMuted }}>{kicker}</div>
            <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 22 : 28, textTransform:'uppercase', letterSpacing:'0.01em' }}>{title}</div>
          </div>
          <button onClick={onClose} style={iconBtn}>{Icon.close(20)}</button>
        </div>
        <div style={{ flex: 1, overflow: 'auto' }}>
          {children}
        </div>
      </div>
    </div>
  );
}
const iconBtn = { background:'transparent', border:0, padding:8, cursor:'pointer', color:'#0A0A0A' };

// ─── Step indicator ─────────────────────────────────────────────────
function Steps({ step, total, labels }) {
  return (
    <div style={{ display:'flex', gap: 8, marginBottom: 24 }}>
      {Array.from({ length: total }).map((_, i) => (
        <div key={i} style={{ flex: 1, opacity: i <= step ? 1 : 0.3 }}>
          <div style={{ height: 2, background: i <= step ? C.accent : C.border, marginBottom: 6 }}/>
          <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', textTransform:'uppercase' }}>
            0{i+1} · {labels[i]}
          </div>
        </div>
      ))}
    </div>
  );
}

// ════════════════════════════════════════════════════════════════════
// TryOnModal
// ════════════════════════════════════════════════════════════════════
function TryOnModal({ mobile }) {
  const s = useStore();
  const product = s.tryOnProduct;
  const [step, setStep] = useState(0);
  const [progress, setProgress] = useState(0);
  const [statusIdx, setStatusIdx] = useState(0);
  const size = 'M'; // size selection removed from try-on flow — handled in PDP/cart

  const STATUSES = ['Detectando silueta…', 'Aplicando prenda…', 'Ajustando luz…'];

  useEffect(() => {
    if (!s.tryOnOpen) {
      setStep(0); setProgress(0); setStatusIdx(0);
    }
  }, [s.tryOnOpen]);

  useEffect(() => {
    if (step !== 1) return;
    setProgress(0); setStatusIdx(0);
    const t0 = Date.now();
    const id = setInterval(() => {
      const elapsed = Date.now() - t0;
      const p = Math.min(elapsed / 2500, 1);
      setProgress(p);
      setStatusIdx(Math.min(2, Math.floor(p * 3)));
      if (p >= 1) {
        clearInterval(id);
        setTimeout(() => setStep(2), 280);
      }
    }, 60);
    return () => clearInterval(id);
  }, [step]);

  if (!product) return null;
  const colorIdx = 0;
  const color = product.colors[colorIdx];

  return (
    <ModalShell open={s.tryOnOpen} onClose={() => s.setTryOnOpen(false)} mobile={mobile}
      kicker="AI Try-On · Beta" title={product.name}>
      <div style={{ padding: mobile ? '20px 16px' : '24px 28px' }}>
        <Steps step={step} total={3} labels={['Foto','Procesando','Resultado']}/>

        {step === 0 && (
          <div>
            <div style={{ marginBottom: mobile ? 16 : 22 }}>
              <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 6 }}>
                Necesitamos 2 fotos
              </div>
              <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 26 : 32, textTransform:'uppercase', letterSpacing:'-0.01em', lineHeight: 1 }}>
                Cara + cuerpo completo.
              </div>
              <div style={{ fontFamily:'Roboto, sans-serif', fontSize: 13, color:'#444', lineHeight: 1.5, marginTop: 8, maxWidth: 520 }}>
                Sube una foto de tu cara y otra de cuerpo entero. Fondo claro, brazos a los lados. Tus fotos solo se usan para generar el preview.
              </div>
            </div>
            <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr 1fr' : '1fr 1fr', gap: mobile ? 12 : 18 }}>
              {[
                { k:'face', label:'Foto de la cara', hint:'Encuadre del cuello hacia arriba', icon: Icon.user ? Icon.user(28) : Icon.camera(28) },
                { k:'body', label:'Cuerpo completo', hint:'Cuerpo entero, brazos a los lados', icon: Icon.upload(28) },
              ].map(slot => (
                <div key={slot.k} style={{
                  border:`1.5px dashed ${C.border}`, padding: mobile ? '24px 14px' : '36px 24px', textAlign:'center',
                  display:'flex', flexDirection:'column', alignItems:'center', gap: 10,
                  cursor:'pointer', background: C.bgWarm, aspectRatio: '3/4',
                  justifyContent:'center',
                }}>
                  {slot.icon}
                  <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 16 : 18, textTransform:'uppercase', letterSpacing:'0.01em', lineHeight: 1 }}>{slot.label}</div>
                  <div style={{ fontFamily:'Roboto, sans-serif', fontSize: 12, color:'#444', maxWidth: 180, lineHeight: 1.4 }}>
                    {slot.hint}
                  </div>
                  <div style={{ marginTop: 4, fontFamily:'JetBrains Mono, monospace', fontSize: 9, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted }}>
                    Subir o usar cámara
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {step === 1 && (
          <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1.4fr', gap: 24, alignItems:'center' }}>
            <div style={{ position:'relative', aspectRatio:'4/5', background: '#0F0F0F', overflow:'hidden' }}>
              <BodySkeleton color={color.hex} pulse />
              <div style={{ position:'absolute', top:14, left:14, fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', textTransform:'uppercase', color:'rgba(255,255,255,0.55)' }}>
                Inferring · {Math.round(progress * 100)}%
              </div>
            </div>
            <div>
              <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 8 }}>Estado</div>
              <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 32 : 44, textTransform:'uppercase', letterSpacing:'-0.01em', lineHeight: 1, minHeight: 52 }}>
                {STATUSES[statusIdx]}
              </div>
              <div style={{ marginTop: 28, height: 3, background: C.border, position:'relative' }}>
                <div style={{ position:'absolute', inset:0, width: `${progress*100}%`, background: C.accent, transition:'width .15s linear' }}/>
              </div>
              <div style={{ marginTop: 10, fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted, display:'flex', justifyContent:'space-between' }}>
                <span>0%</span>
                <span>{Math.round(progress*100)}%</span>
                <span>100%</span>
              </div>
            </div>
          </div>
        )}

        {step === 2 && (() => {
          const set = product.imagesByColor && product.imagesByColor[color.name];
          const maleImg = set && set.male;
          return (
          <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: mobile ? 20 : 32 }}>
            <div style={{ position:'relative', aspectRatio:'4/5', background:'#FAF8F3', overflow:'hidden', border:`1px solid ${C.border}` }}>
              {maleImg ? (
                // Real on-model photo (male) — the headline "this is how it'll look" result
                <img src={maleImg} alt={`${product.name} en modelo`} style={{
                  position:'absolute', inset:0, width:'100%', height:'100%', objectFit:'cover', display:'block',
                }}/>
              ) : (
                <BodySilhouetteResult product={product} color={color} />
              )}
              <div style={{
                position:'absolute', top: 14, left: 14,
                fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.2em', textTransform:'uppercase',
                color: maleImg ? '#0A0A0A' : C.fgMuted,
                opacity: maleImg ? 0.55 : 1,
                mixBlendMode: maleImg ? 'multiply' : 'normal',
                background: maleImg ? 'rgba(255,255,255,0.55)' : 'transparent',
                padding: maleImg ? '3px 7px' : 0,
              }}>Generado por AI · Vista preliminar</div>
              <div style={{
                position:'absolute', bottom: 14, right: 14,
                background: C.fg, color:'#fff', padding:'4px 7px',
                fontFamily:'JetBrains Mono, monospace', fontSize: 9, letterSpacing:'0.18em', textTransform:'uppercase',
              }}>{color.name}</div>
            </div>
            <div>
              <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 6 }}>Resultado</div>
              <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 32 : 44, textTransform:'uppercase', letterSpacing:'-0.01em', lineHeight: 0.95 }}>
                Así te queda<br/>el {product.name.toLowerCase()}.
              </div>
              <p style={{ fontFamily:'Roboto, sans-serif', fontSize: 13, color:'#444', lineHeight: 1.5, marginTop: 14 }}>
                Modelo predictivo basado en silueta. La caída real puede variar ±3%. Para precisión absoluta, apártala en estudio.
              </p>

              <div style={{ marginTop: 24, display:'flex', flexDirection:'column', gap: 10 }}>
                <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.16em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 4 }}>
                  Elige tu talla en el siguiente paso
                </div>
                <button className="cmd-btn-primary" onClick={() => {
                  s.addToCart({ id: product.id, name: product.name, price: product.price, color: color.name, colorHex: color.hex, size, qty: 1 });
                  s.setTryOnOpen(false); s.setCartOpen(true);
                }}>
                  Agregar a la bolsa {Icon.arrowR(16)}
                </button>
                <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 10 }}>
                  <button className="cmd-btn-secondary" onClick={() => setStep(0)}>Probar otra foto</button>
                  <button className="cmd-btn-secondary">Compartir {Icon.share(13)}</button>
                </div>
              </div>
            </div>
          </div>
          );
        })()}

        {/* Footer disclaimer + nav */}
        <div style={{ marginTop: 24, paddingTop: 16, borderTop: `1px solid ${C.border}`, display:'flex', justifyContent:'space-between', alignItems:'center', gap: 12 }}>
          <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.16em', textTransform:'uppercase', color: C.fgMuted }}>
            Beta · Tecnología de prueba virtual en desarrollo
          </div>
          {step === 0 && (
            <button className="cmd-btn-primary cmd-btn-inline" onClick={() => setStep(1)}>
              Continuar {Icon.arrowR(14)}
            </button>
          )}
        </div>
      </div>
    </ModalShell>
  );
}

function BodySkeleton({ color, pulse }) {
  return (
    <svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid meet" style={{ position:'absolute', inset:0, width:'100%', height:'100%' }}>
      <defs>
        <linearGradient id="pulseG" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#fff" stopOpacity="0.08"/>
          <stop offset="50%" stopColor="#fff" stopOpacity="0.32"/>
          <stop offset="100%" stopColor="#fff" stopOpacity="0.08"/>
        </linearGradient>
      </defs>
      <g fill="none" stroke="rgba(255,255,255,0.32)" strokeWidth="1.2" strokeDasharray="2 4">
        <circle cx="100" cy="50" r="24"/>
        <path d="M100 75 L100 150 M70 90 L130 90 L150 130 M50 130 L70 90 M100 150 L70 230 M100 150 L130 230"/>
        <path d="M70 90 L70 130 M130 90 L130 130"/>
      </g>
      <g fill={color} fillOpacity="0.5">
        <path d="M70 90 L130 90 L150 130 L130 130 L130 200 L70 200 L70 130 L50 130 Z" style={{ animation: pulse ? 'cmd-pulse 1.4s ease-in-out infinite' : 'none' }}/>
      </g>
      <rect x="0" y="0" width="200" height="250" fill="url(#pulseG)" style={{ animation:'cmd-shine 1.6s ease-in-out infinite' }}/>
    </svg>
  );
}

function BodySilhouetteResult({ product, color }) {
  return (
    <svg viewBox="0 0 200 250" preserveAspectRatio="xMidYMid meet" style={{ position:'absolute', inset:0, width:'100%', height:'100%' }}>
      {/* body silhouette */}
      <g fill="#0A0A0A" fillOpacity="0.92">
        <circle cx="100" cy="40" r="20"/>
        <path d="M82 60 L118 60 L130 80 L130 130 L118 130 L116 230 L84 230 L82 130 L70 130 L70 80 Z"/>
        <path d="M84 130 L78 230 L94 230 L96 130 Z"/>
        <path d="M116 130 L122 230 L106 230 L104 130 Z"/>
      </g>
      {/* garment overlay block */}
      <g>
        {product.category === 'hoodies' || product.category === 'crewnecks' ? (
          <path d="M68 76 Q100 66 132 76 L150 92 L144 130 L132 130 L132 175 L68 175 L68 130 L56 130 L50 92 Z" fill={color.hex} fillOpacity="0.95"/>
        ) : product.category === 'outerwear' ? (
          <path d="M62 74 L100 80 L138 74 L154 92 L148 145 L138 145 L138 195 L62 195 L62 145 L52 145 L46 92 Z" fill={color.hex} fillOpacity="0.95"/>
        ) : product.category === 'sets' ? (
          <>
            <path d="M76 70 L124 70 L142 88 L138 110 L130 110 L130 130 L70 130 L70 110 L62 110 L58 88 Z" fill={color.hex} fillOpacity="0.95"/>
            <path d="M72 140 L128 140 L130 230 L106 230 L102 170 L98 170 L94 230 L70 230 Z" fill={color.hex} fillOpacity="0.95"/>
          </>
        ) : (
          <path d="M72 78 L128 78 L142 90 L138 110 L130 110 L130 168 L70 168 L70 110 L62 110 L58 90 Z" fill={color.hex} fillOpacity="0.95"/>
        )}
      </g>
      {/* monospace tag */}
      <g fontFamily="JetBrains Mono, monospace" fontSize="6" fill="#fff" opacity="0.7" textAnchor="middle">
        <text x="100" y="135">[ COMMANDO · {product.id.toUpperCase()} ]</text>
      </g>
    </svg>
  );
}

// ════════════════════════════════════════════════════════════════════
// ReservaModal
// ════════════════════════════════════════════════════════════════════
function ReservaModal({ mobile }) {
  const s = useStore();
  const product = s.reservaProduct;
  const [step, setStep] = useState(0);
  const [studioId, setStudioId] = useState(null);
  const [date, setDate] = useState(null);
  const [size, setSize] = useState(product?.sizes[2] || 'M');
  const [colorIdx, setColorIdx] = useState(0);

  useEffect(() => { if (!s.reservaOpen) { setStep(0); setStudioId(null); setDate(null); }}, [s.reservaOpen]);

  if (!product) return null;
  const studio = STUDIOS.find(st => st.id === studioId);
  const color = product.colors[colorIdx];

  const dates = useMemo(() => {
    const today = new Date();
    return Array.from({ length: 14 }, (_, i) => {
      const d = new Date(today); d.setDate(today.getDate() + i + 1); return d;
    });
  }, []);

  const canNext = (step === 0 && studioId) || (step === 1 && date) || step === 2;

  return (
    <ModalShell open={s.reservaOpen} onClose={() => s.setReservaOpen(false)} mobile={mobile}
      kicker="Reserva en estudio · 48h de gracia" title={product.name}>
      <div style={{ padding: mobile ? '20px 16px' : '24px 28px' }}>
        <Steps step={step} total={3} labels={['Estudio','Fecha','Confirma']}/>

        {step === 0 && (
          <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr' : '1.3fr 1fr', gap: mobile ? 16 : 24 }}>
            <div style={{ position:'relative', aspectRatio:'4/3', background:'#fff', border:`1px solid ${C.border}` }}>
              <StylizedMap pins={STUDIOS} highlight={studioId} onPin={setStudioId} />
            </div>
            <div style={{ maxHeight: mobile ? 280 : 380, overflowY:'auto', border:`1px solid ${C.border}` }}>
              {['CDMX','EDOMX','GDL','Cancún'].map(city => {
                const list = STUDIOS.filter(st => st.city === city);
                return (
                  <div key={city}>
                    <div style={{ padding:'10px 14px', background: C.bgWarm, fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.2em', textTransform:'uppercase', borderBottom:`1px solid ${C.border}` }}>{city} · {list.length}</div>
                    {list.map(st => (
                      <button key={st.id} disabled={st.soon} onClick={() => setStudioId(st.id)} style={{
                        width:'100%', textAlign:'left', padding:'12px 14px', cursor: st.soon ? 'not-allowed' : 'pointer',
                        background: studioId === st.id ? C.fg : 'transparent',
                        color: studioId === st.id ? '#fff' : (st.soon ? C.fgMuted : C.fg),
                        border: 0, borderBottom:`1px solid ${C.borderSoft}`,
                        fontFamily:'Roboto, sans-serif', fontSize: 14,
                        display:'flex', justifyContent:'space-between', alignItems:'center', gap: 10,
                      }}>
                        <span>{st.name}</span>
                        {st.soon && <span style={{ fontFamily:'JetBrains Mono, monospace', fontSize:9, letterSpacing:'0.16em', textTransform:'uppercase' }}>Próximamente</span>}
                      </button>
                    ))}
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {step === 1 && (
          <div>
            <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 14 }}>
              Recoge en {studio?.name} · {studio?.city} · 14 días disponibles
            </div>
            <div style={{ display:'grid', gridTemplateColumns: mobile ? 'repeat(4, 1fr)' : 'repeat(7, 1fr)', gap: 8 }}>
              {dates.map(d => {
                const k = d.toISOString().slice(0,10);
                const sel = date === k;
                return (
                  <button key={k} onClick={() => setDate(k)} style={{
                    padding:'12px 8px', textAlign:'center', cursor:'pointer',
                    border: sel ? `1.5px solid ${C.fg}` : `1px solid ${C.border}`,
                    background: sel ? C.fg : '#fff', color: sel ? '#fff' : C.fg,
                  }}>
                    <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 9, letterSpacing:'0.18em', textTransform:'uppercase', opacity: 0.75 }}>{d.toLocaleDateString('es-MX', { weekday:'short' }).toUpperCase().replace('.','')}</div>
                    <div style={{ fontFamily:'Anton, sans-serif', fontSize: 22, lineHeight: 1, marginTop: 4 }}>{d.getDate()}</div>
                    <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 9, opacity: 0.65 }}>{d.toLocaleDateString('es-MX', { month:'short' })}</div>
                  </button>
                );
              })}
            </div>
          </div>
        )}

        {step === 2 && (
          <div>
            <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: mobile ? 16 : 32 }}>
              <div>
                <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.18em', textTransform:'uppercase', marginBottom: 10 }}>Color</div>
                <div style={{ display:'flex', gap: 10 }}>
                  {product.colors.map((c, i) => (
                    <button key={i} onClick={() => setColorIdx(i)} style={{
                      width: 36, height: 36, padding: 3, borderRadius:'50%',
                      border: colorIdx === i ? `1.5px solid ${C.fg}` : '1.5px solid transparent',
                      background:'transparent', cursor:'pointer',
                    }}>
                      <span style={{ display:'block', width:'100%', height:'100%', borderRadius:'50%', background: c.hex, boxShadow:'inset 0 0 0 1px rgba(0,0,0,0.18)' }}/>
                    </button>
                  ))}
                </div>
                <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.18em', textTransform:'uppercase', margin: '20px 0 10px' }}>Talla</div>
                <div style={{ display:'grid', gridTemplateColumns:`repeat(${product.sizes.length}, 1fr)`, gap: 6 }}>
                  {product.sizes.map(sz => (
                    <button key={sz} onClick={() => setSize(sz)} style={{
                      padding:'10px 0', border: size === sz ? `1.5px solid ${C.fg}` : `1px solid ${C.border}`,
                      background: size === sz ? C.fg : '#fff', color: size === sz ? '#fff' : C.fg,
                      fontFamily:'JetBrains Mono, monospace', fontSize: 11, letterSpacing:'0.14em', cursor:'pointer',
                    }}>{sz}</button>
                  ))}
                </div>
              </div>
              <div style={{ background: C.bgWarm, padding: 20, borderLeft: `2px solid ${C.accent}` }}>
                <div style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.2em', textTransform:'uppercase', color: C.fgMuted, marginBottom: 10 }}>Resumen</div>
                <SummaryRow l="Prenda" v={product.name}/>
                <SummaryRow l="Color" v={color.name}/>
                <SummaryRow l="Talla" v={size}/>
                <SummaryRow l="Estudio" v={studio?.name}/>
                <SummaryRow l="Recoge" v={date ? new Date(date).toLocaleDateString('es-MX', { weekday:'short', day:'numeric', month:'short' }) : '—'}/>
                <SummaryRow l="Apartado por" v="48 horas" accent/>
                <div style={{ marginTop: 14, fontFamily:'Roboto, sans-serif', fontSize: 12, color:'#444', lineHeight: 1.5 }}>
                  Te llega confirmación por SMS y correo. Si no la recoges en 48 horas, la pieza vuelve al inventario sin penalización.
                </div>
              </div>
            </div>
          </div>
        )}

        <div style={{ marginTop: 24, paddingTop: 16, borderTop:`1px solid ${C.border}`, display:'flex', justifyContent:'space-between', gap: 12 }}>
          <button className="cmd-btn-line cmd-btn-line-sm" onClick={() => step > 0 ? setStep(step-1) : s.setReservaOpen(false)}>
            ← {step > 0 ? 'Atrás' : 'Cancelar'}
          </button>
          {step < 2 && (
            <button className="cmd-btn-primary cmd-btn-inline" disabled={!canNext} onClick={() => setStep(step + 1)}>
              Siguiente {Icon.arrowR(14)}
            </button>
          )}
          {step === 2 && (
            <button className="cmd-btn-primary cmd-btn-inline" onClick={() => {
              alert(`Apartado confirmado en ${studio.name} · ${size} · ${color.name}`);
              s.setReservaOpen(false);
            }}>
              Confirmar apartado {Icon.check(14)}
            </button>
          )}
        </div>
      </div>
    </ModalShell>
  );
}

function SummaryRow({ l, v, accent }) {
  return (
    <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', padding:'8px 0', borderBottom:`1px solid ${C.borderSoft}` }}>
      <span style={{ fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', textTransform:'uppercase', color: C.fgMuted }}>{l}</span>
      <span style={{ fontFamily: accent ? 'Anton, sans-serif' : 'Roboto, sans-serif', fontSize: accent ? 18 : 14, color: accent ? C.accent : C.fg, textTransform: accent ? 'uppercase' : 'none', letterSpacing: accent ? '0.01em' : '0' }}>{v}</span>
    </div>
  );
}

// ════════════════════════════════════════════════════════════════════
// StylizedMap — abstract, not literal geography
// ════════════════════════════════════════════════════════════════════
function StylizedMap({ pins, highlight, onPin }) {
  return (
    <div style={{ position:'absolute', inset: 0, background: '#FAFAF7' }}>
      {/* abstract terrain via radial gradients */}
      <svg viewBox="0 0 100 75" preserveAspectRatio="none" style={{ position:'absolute', inset: 0, width:'100%', height:'100%' }}>
        <defs>
          <pattern id="grid" width="6" height="6" patternUnits="userSpaceOnUse">
            <path d="M 6 0 L 0 0 0 6" fill="none" stroke="#E5E2D8" strokeWidth="0.18"/>
          </pattern>
        </defs>
        <rect width="100" height="75" fill="url(#grid)"/>
        {/* stylized landmasses */}
        <path d="M5 35 Q15 28 22 32 Q26 38 32 38 Q35 50 30 60 Q24 65 18 60 Q10 55 5 50 Z" fill="#F1EEE2" stroke="#E0DBC8" strokeWidth="0.25"/>
        <path d="M28 25 Q40 18 50 22 Q60 24 65 28 Q70 36 64 50 Q58 60 50 62 Q42 60 36 55 Q30 48 28 38 Z" fill="#EDE9DA" stroke="#D9D4C0" strokeWidth="0.3"/>
        <path d="M70 28 Q78 24 84 28 Q88 34 86 42 Q82 48 78 46 Q72 42 70 36 Z" fill="#F1EEE2" stroke="#E0DBC8" strokeWidth="0.25"/>
        {/* dashed road network */}
        <g stroke="#C8C2AB" strokeWidth="0.18" fill="none" strokeDasharray="0.6 0.6">
          <path d="M14 50 Q30 40 46 46 Q60 50 80 38"/>
          <path d="M30 30 Q40 36 50 50 Q56 64 50 70"/>
          <path d="M14 38 Q26 36 36 30"/>
        </g>
        {/* city labels */}
        <g fontFamily="JetBrains Mono, monospace" fontSize="2.2" fill="#9A9A9A" letterSpacing="0.3">
          <text x="14" y="62" textAnchor="middle">GDL</text>
          <text x="48" y="68" textAnchor="middle">CDMX · EDOMX</text>
          <text x="80" y="50" textAnchor="middle">CANCÚN</text>
        </g>
      </svg>

      {/* pins */}
      {pins.map(p => {
        const sel = highlight === p.id;
        return (
          <button key={p.id} onClick={() => onPin?.(p.id)} disabled={p.soon || !onPin} style={{
            position:'absolute', left:`${p.x*100}%`, top:`${p.y*100}%`,
            transform:'translate(-50%, -100%)',
            width: sel ? 22 : 14, height: sel ? 28 : 18, padding: 0,
            background:'transparent', border: 0, cursor: onPin && !p.soon ? 'pointer' : 'default',
            transition:'all .2s',
          }}>
            <svg viewBox="0 0 24 30" width="100%" height="100%">
              <path d="M12 0 C5.4 0 0 5.4 0 12 c0 9 12 18 12 18 s12 -9 12 -18 C24 5.4 18.6 0 12 0 z" fill={sel ? C.accent : (p.soon ? '#C8C8C8' : C.fg)}/>
              <circle cx="12" cy="12" r="4" fill={sel ? '#fff' : '#fff'}/>
            </svg>
          </button>
        );
      })}

      {/* legend */}
      <div style={{
        position:'absolute', top: 12, left: 12,
        fontFamily:'JetBrains Mono, monospace', fontSize: 9, letterSpacing:'0.2em', textTransform:'uppercase',
        color: C.fgMuted, background:'rgba(255,255,255,0.85)', padding:'5px 8px',
      }}>
        + 24 estudios · MX
      </div>
      {highlight && (() => {
        const p = pins.find(p => p.id === highlight); if (!p) return null;
        return (
          <div style={{
            position:'absolute', left:`${p.x*100}%`, top:`${p.y*100}%`,
            transform:'translate(-50%, -130%)', whiteSpace:'nowrap',
            background: C.fg, color:'#fff', padding:'4px 8px',
            fontFamily:'JetBrains Mono, monospace', fontSize: 9, letterSpacing:'0.16em', textTransform:'uppercase',
          }}>{p.name}</div>
        );
      })()}
    </div>
  );
}

// ─── Notify International Modal ─────────────────────────────────────
function NotifyCountryModal({ mobile }) {
  const s = useStore();
  const c = s.notifyCountry;
  const open = !!c;
  const [email, setEmail] = useState('');
  const [sent, setSent] = useState(false);
  useEffect(() => { if (!open) { setEmail(''); setSent(false); } }, [open]);
  const COUNTRY_LABELS = { EU:'Europa', US:'Estados Unidos' };
  const name = c ? (COUNTRY_LABELS[c.k] || c.label) : '';
  return (
    <ModalShell open={open} onClose={() => s.setNotifyCountry(null)} mobile={mobile} title="Próximamente" kicker={c ? `· ${c.label}` : ''}>
      <div style={{ padding: mobile ? '20px 18px 28px' : '40px 48px 48px', display:'flex', flexDirection:'column', gap: mobile ? 14 : 18 }}>
        <div style={{
          fontFamily:'JetBrains Mono, monospace', fontSize: 10,
          letterSpacing:'0.22em', textTransform:'uppercase', color: C.accent, marginBottom: mobile ? -4 : 0,
        }}>Pronto · {name}</div>
        <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 32 : 64, lineHeight: 0.95, textTransform:'uppercase', letterSpacing:'-0.01em' }}>
          Llegamos a <span style={{ color: C.accent }}>{name}</span> pronto.
        </div>
        <p style={{ margin: 0, fontFamily:'Roboto, sans-serif', fontSize: mobile ? 13 : 15, lineHeight: 1.5, color:'#444', maxWidth: 460 }}>
          COMMANDO Apparel llega a {name} próximamente. Déjanos tu correo y serás el primero en saberlo.
        </p>
        {sent ? (
          <div style={{
            border:`1.5px solid ${C.accent}`, padding: mobile ? '16px 18px' : '18px 20px',
            display:'grid', gridTemplateColumns:'auto 1fr', gap: 12, alignItems:'flex-start',
            fontFamily:'JetBrains Mono, monospace', fontSize: mobile ? 12 : 13,
            letterSpacing:'0.12em', textTransform:'uppercase', color: C.fg, lineHeight: 1.5,
          }}>
            <span style={{ color: C.accent, fontSize: 18, lineHeight: 1.2, marginTop: 1 }}>✓</span>
            <span style={{ minWidth: 0 }}>Listo. Te avisamos cuando estemos en {name}.</span>
          </div>
        ) : (
          <form onSubmit={(e) => { e.preventDefault(); setSent(true); }} style={{ display:'flex', flexDirection:'column', gap: 10, marginTop: 2 }}>
            <input
              type="email" required value={email} onChange={e => setEmail(e.target.value)}
              placeholder="tu@correo.com"
              style={{
                padding: mobile ? '14px 16px' : '16px 18px',
                border:`1.5px solid ${C.border}`, background:'#fff', color: C.fg,
                fontFamily:'JetBrains Mono, monospace', fontSize: 13, letterSpacing:'0.06em',
                outline: 'none', borderRadius: 0,
              }}
            />
            <button type="submit" className="cmd-btn-primary" style={{ padding: mobile ? '16px 20px' : '18px 24px', fontSize: mobile ? 12 : 13 }}>
              Notifícame {Icon.arrowR(15)}
            </button>
          </form>
        )}
        <div style={{ marginTop: 0, fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', color: C.fgMuted, textTransform:'uppercase', textAlign:'center' }}>
          Sin spam · solo el aviso de lanzamiento
        </div>
      </div>
    </ModalShell>
  );
}

// ─── Newsletter Modal ───────────────────────────────────────────────
function NewsletterModal({ mobile }) {
  const s = useStore();
  const open = !!s.newsletterOpen;
  const [email, setEmail] = useState('');
  const [name, setName] = useState('');
  const [sent, setSent] = useState(false);
  useEffect(() => { if (!open) { setEmail(''); setName(''); setSent(false); } }, [open]);
  return (
    <ModalShell open={open} onClose={() => s.setNewsletterOpen(false)} mobile={mobile} title="Newsletter" kicker="· comunidad commando">
      <div style={{ padding: mobile ? '20px 18px 28px' : '40px 48px 48px', display:'flex', flexDirection:'column', gap: mobile ? 14 : 18 }}>
        <div style={{
          fontFamily:'JetBrains Mono, monospace', fontSize: 10,
          letterSpacing:'0.22em', textTransform:'uppercase', color: C.accent, marginBottom: mobile ? -4 : 0,
        }}>FITFAMM · est. 2017</div>
        <div style={{ fontFamily:'Anton, sans-serif', fontSize: mobile ? 36 : 64, lineHeight: 0.95, textTransform:'uppercase', letterSpacing:'-0.01em' }}>
          Únete al <span style={{ color: C.accent }}>escuadrón.</span>
        </div>
        <p style={{ margin: 0, fontFamily:'Roboto, sans-serif', fontSize: mobile ? 13 : 15, lineHeight: 1.5, color:'#444', maxWidth: 480 }}>
          Drops, comunidad y descuentos exclusivos. Sin spam, solo lo importante.
        </p>
        {sent ? (
          <div style={{
            border:`1.5px solid ${C.accent}`, padding: mobile ? '16px 18px' : '18px 20px',
            display:'grid', gridTemplateColumns:'auto 1fr', gap: 12, alignItems:'flex-start',
            fontFamily:'JetBrains Mono, monospace', fontSize: mobile ? 12 : 13,
            letterSpacing:'0.12em', textTransform:'uppercase', color: C.fg, lineHeight: 1.5,
          }}>
            <span style={{ color: C.accent, fontSize: 18, lineHeight: 1.2, marginTop: 1 }}>✓</span>
            <span style={{ minWidth: 0 }}>Bienvenido al escuadrón. Revisa tu correo.</span>
          </div>
        ) : (
          <form onSubmit={(e) => { e.preventDefault(); setSent(true); }} style={{ display:'flex', flexDirection:'column', gap: 10, marginTop: 2 }}>
            <div style={{ display:'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1.4fr', gap: 10 }}>
              <input
                type="text" required value={name} onChange={e => setName(e.target.value)}
                placeholder="Nombre"
                style={{
                  padding: mobile ? '14px 16px' : '16px 18px',
                  border:`1.5px solid ${C.border}`, background:'#fff', color: C.fg,
                  fontFamily:'JetBrains Mono, monospace', fontSize: 13, letterSpacing:'0.06em',
                  outline: 'none', borderRadius: 0,
                }}
              />
              <input
                type="email" required value={email} onChange={e => setEmail(e.target.value)}
                placeholder="tu@correo.com"
                style={{
                  padding: mobile ? '14px 16px' : '16px 18px',
                  border:`1.5px solid ${C.border}`, background:'#fff', color: C.fg,
                  fontFamily:'JetBrains Mono, monospace', fontSize: 13, letterSpacing:'0.06em',
                  outline: 'none', borderRadius: 0,
                }}
              />
            </div>
            <label style={{ display:'flex', alignItems:'center', gap: 10, padding:'2px 0', cursor:'pointer' }}>
              <input type="checkbox" defaultChecked style={{ accentColor: C.accent, width: 16, height: 16, flexShrink: 0 }}/>
              <span style={{ fontFamily:'Roboto, sans-serif', fontSize: mobile ? 11 : 12, color:'#444', lineHeight: 1.45 }}>
                Acepto recibir comunicaciones. Puedo darme de baja cuando quiera.
              </span>
            </label>
            <button type="submit" className="cmd-btn-primary" style={{ marginTop: 4, padding: mobile ? '16px 20px' : '18px 24px', fontSize: mobile ? 12 : 13 }}>
              Únete al escuadrón {Icon.arrowR(15)}
            </button>
          </form>
        )}
        <div style={{ marginTop: 0, fontFamily:'JetBrains Mono, monospace', fontSize: 10, letterSpacing:'0.18em', color: C.fgMuted, textTransform:'uppercase', textAlign:'center' }}>
          Comunidad · disciplina · sin spam
        </div>
      </div>
    </ModalShell>
  );
}

Object.assign(window, { TryOnModal, ReservaModal, StylizedMap, ModalShell, NotifyCountryModal, NewsletterModal });
