/* ─────────────────────────────────────────────────────────────────────────
   MENÚ FACTORY — Cinematic Landing v7.0
   Single hero + immersive in-page live demo (no scroll journey).
   Exports window.MFLanding / window.MFLandingView.
   Props: { onStart, onSignIn }
   ───────────────────────────────────────────────────────────────────── */
const { useState, useEffect, useRef, useCallback } = React;

const C = {
  bg: '#080604', copper: '#C4813A', copperL: '#E8A855',
  text: '#F5F0E8', muted: 'rgba(245,240,232,0.52)',
  dim: 'rgba(245,240,232,0.24)', faint: 'rgba(245,240,232,0.08)',
  green: '#6DB86D',
};
/* Typography — aligned with the rest of Menú Factory:
   Fraunces (serif) for display / personality / prices, Inter Tight (sans) for
   labels, navigation, buttons and body. Both already loaded by index.html. */
const SF   = '"Fraunces","Georgia",serif';
const UI   = '"Inter Tight",system-ui,-apple-system,sans-serif';
const IMGS = {
  hero: '/img-hero.png',
};

/* MXN currency formatting — never raw integers for money. */
const mx = n => Number(n).toLocaleString('es-MX', { minimumFractionDigits: 0, maximumFractionDigits: 0 });

/* ── CSS ──────────────────────────────────────────────────────────── */
const CSS = `
@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300..600;1,9..144,300..600&family=Inter+Tight:ital,wght@0,400;0,500;0,600;1,400&display=swap');
.mfc *{box-sizing:border-box;margin:0;padding:0}
.mfc button,.mfc a{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;text-decoration:none}
.mfc button:disabled{opacity:.45;cursor:not-allowed}

@keyframes mfc-grain{0%,100%{transform:translate(0,0)}20%{transform:translate(-3%,-2%)}40%{transform:translate(2%,3%)}60%{transform:translate(-2%,1%)}80%{transform:translate(3%,-2%)}}
@keyframes mfc-blink{0%,100%{opacity:1}50%{opacity:0}}
@keyframes mfc-ring{0%,100%{opacity:.20;transform:scale(1)}50%{opacity:.55;transform:scale(1.05)}}
@keyframes mfc-pulse{0%,100%{opacity:.30;transform:scale(1)}50%{opacity:.95;transform:scale(1.18)}}
@keyframes mfc-up{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}
@keyframes mfc-up-sm{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@keyframes mfc-in{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:scale(1)}}
@keyframes mfc-scan{0%{transform:translateY(-120%)}100%{transform:translateY(2200%)}}
@keyframes mfc-stripe{0%{transform:translateX(-100%)}100%{transform:translateX(320%)}}
@keyframes mfc-pop{0%{transform:scale(.6);opacity:0}60%{transform:scale(1.12)}100%{transform:scale(1);opacity:1}}
@keyframes mfc-fadeout{from{opacity:1}to{opacity:0}}
@keyframes mfc-draw{to{stroke-dashoffset:0}}

.mfc-nav{position:fixed;top:0;left:0;right:0;z-index:120;display:flex;align-items:center;justify-content:space-between;padding:18px 40px;transition:background .4s,border-color .4s}
.mfc-nav.sc{background:rgba(8,6,4,.93);border-bottom:1px solid rgba(196,129,58,.1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.mfc-nav-btn{font-family:${UI};font-size:9px;letter-spacing:.22em;text-transform:uppercase;color:#C4813A;border:1px solid rgba(196,129,58,.4);padding:9px 18px;min-height:34px;background:transparent;transition:background .26s,border-color .26s,color .26s,transform .12s}
.mfc-nav-btn:hover{background:rgba(196,129,58,.1);border-color:#C4813A}
.mfc-nav-btn:active{transform:scale(.97)}
.mfc-nav-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(196,129,58,.22)}
.mfc-nav-btn.ghost{color:rgba(245,240,232,.52);border-color:rgba(245,240,232,.18)}
.mfc-nav-btn.ghost:hover{color:#F5F0E8;border-color:rgba(245,240,232,.4);background:rgba(245,240,232,.04)}

/* hero CTAs */
.mfc-cta{font-family:${UI};font-size:10px;letter-spacing:.22em;text-transform:uppercase;padding:0 34px;height:52px;display:inline-flex;align-items:center;justify-content:center;min-width:44px;transition:background .28s,border-color .28s,color .28s,box-shadow .28s,transform .12s}
.mfc-cta:active{transform:scale(.97)}
.mfc-cta:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(196,129,58,.3)}
.mfc-cta.primary{background:#C4813A;color:#0c0905;border:1px solid #C4813A}
.mfc-cta.primary:hover{background:#E8A855;border-color:#E8A855}
.mfc-cta.primary:focus-visible{box-shadow:0 0 0 3px rgba(232,168,85,.35)}
.mfc-cta.ghost{background:transparent;color:#F5F0E8;border:1px solid rgba(245,240,232,.28)}
.mfc-cta.ghost:hover{border-color:#C4813A;color:#C4813A}

/* generic demo button */
.mfc-btn{font-family:${SF};display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;min-width:44px;font-size:11px;letter-spacing:.16em;text-transform:uppercase;padding:0 22px;border-radius:2px;transition:background .2s,border-color .2s,color .2s,box-shadow .2s,transform .12s;border:1px solid transparent}
.mfc-btn:active{transform:scale(.97)}
.mfc-btn:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(196,129,58,.28)}
.mfc-btn.primary{background:#C4813A;color:#0c0905}
.mfc-btn.primary:hover{background:#E8A855}
.mfc-btn.ghost{background:transparent;color:rgba(245,240,232,.7);border-color:rgba(196,129,58,.28)}
.mfc-btn.ghost:hover{color:#F5F0E8;border-color:#C4813A;background:rgba(196,129,58,.07)}
.mfc-btn.lg{height:54px;font-size:12px;letter-spacing:.2em}

.mfc-glass{background:rgba(8,6,4,.86);border:1px solid rgba(196,129,58,.16);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-radius:4px}
.mfc-glass-lt{background:rgba(14,10,6,.7);border:1px solid rgba(196,129,58,.11);border-radius:4px}

/* dish row interactivity */
.mfc-dish{display:flex;align-items:flex-start;gap:14px;padding:16px 0;border-bottom:1px solid rgba(196,129,58,.08);transition:opacity .2s}
.mfc-dish:last-child{border-bottom:none}
.mfc-add{flex-shrink:0;width:34px;height:34px;border-radius:50%;border:1px solid rgba(196,129,58,.4);color:#C4813A;display:flex;align-items:center;justify-content:center;font-size:18px;line-height:1;transition:background .18s,border-color .18s,color .18s,transform .12s;background:transparent}
.mfc-add:hover{background:rgba(196,129,58,.12);border-color:#C4813A}
.mfc-add:active{transform:scale(.9)}
.mfc-add:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(196,129,58,.28)}
.mfc-add.in{background:#C4813A;color:#0c0905;border-color:#C4813A}

.mfc-step{display:flex;align-items:center;gap:8px}
.mfc-step-dot{width:7px;height:7px;border-radius:50%;background:rgba(245,240,232,.18);transition:background .3s,transform .3s}
.mfc-step-dot.on{background:#C4813A;transform:scale(1.25)}
.mfc-step-dot.done{background:rgba(196,129,58,.45)}

.mfc-scanline{position:absolute;left:8%;right:8%;height:2px;background:linear-gradient(90deg,transparent,#E8A855,transparent);animation:mfc-scan 2.1s ease-in-out infinite}

.mfc-x{width:36px;height:36px;border-radius:50%;background:rgba(245,240,232,.06);border:1px solid rgba(245,240,232,.14);color:rgba(245,240,232,.7);display:flex;align-items:center;justify-content:center;transition:background .2s,color .2s,transform .12s;flex-shrink:0}
.mfc-x:hover{background:rgba(245,240,232,.12);color:#F5F0E8}
.mfc-x:active{transform:scale(.92)}
.mfc-x:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(196,129,58,.28)}

.mfc-prog{height:3px;background:rgba(196,129,58,.12);border-radius:2px;overflow:hidden;position:relative}
.mfc-prog-stripe{position:absolute;top:0;bottom:0;width:40%;background:linear-gradient(90deg,transparent,#C4813A,transparent);animation:mfc-stripe 1.1s linear infinite}

.mfc-scroll::-webkit-scrollbar{width:0;display:none}
.mfc-scroll{scrollbar-width:none}

/* the product, told in three icon+word beats */
.mfc-what{display:flex;align-items:center;justify-content:center;flex-wrap:wrap}
.mfc-what-item{display:flex;align-items:center;gap:9px}
.mfc-what-sep{width:22px;height:1px;background:rgba(196,129,58,.28);margin:0 18px;flex-shrink:0}

/* contextual POV label in the demo header */
.mfc-ctx{display:inline-flex;align-items:center;gap:8px}

@media(max-width:767px){
  .mfc-nav{padding:13px 18px}
  .mfc-nav-btn{padding:7px 13px;font-size:8px;letter-spacing:.16em}
  .mfc-hero-ctas{flex-direction:column;width:100%;max-width:320px}
  .mfc-cta{width:100%}
  .mfc-demo-grid{grid-template-columns:1fr!important;gap:16px!important}
  .mfc-demo-pad{padding:18px!important}
  .mfc-ctx{display:none}
}
@media(max-width:540px){
  .mfc-what{flex-direction:column;gap:14px}
  .mfc-what-sep{display:none}
}
`;

/* ── Utilities ───────────────────────────────────────────────────── */
function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    const fn = () => setY(window.scrollY);
    window.addEventListener('scroll', fn, { passive: true });
    return () => window.removeEventListener('scroll', fn);
  }, []);
  return y;
}

function useIsMobile() {
  const [m, setM] = useState(typeof window !== 'undefined' ? window.innerWidth < 768 : false);
  useEffect(() => {
    const fn = () => setM(window.innerWidth < 768);
    window.addEventListener('resize', fn);
    return () => window.removeEventListener('resize', fn);
  }, []);
  return m;
}

/* ── Atoms ───────────────────────────────────────────────────────── */
function Grain() {
  return (
    <div style={{ position:'fixed', inset:0, zIndex:9999, pointerEvents:'none', overflow:'hidden', opacity:.038 }}>
      <svg width="100%" height="100%" style={{ animation:'mfc-grain 0.18s steps(1) infinite' }}>
        <filter id="mfg"><feTurbulence type="fractalNoise" baseFrequency="0.68" numOctaves="4" stitchTiles="stitch"/></filter>
        <rect width="100%" height="100%" filter="url(#mfg)" opacity="1"/>
      </svg>
    </div>
  );
}

function Logo({ sz = 26, style }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap:10, ...style }}>
      <svg width={sz} height={sz} viewBox="0 0 32 32" fill="none">
        <rect x="1" y="1" width="30" height="30" stroke={C.copper} strokeWidth="1"/>
        <text x="16" y="22" textAnchor="middle" fill={C.copper}
          style={{ fontFamily:SF, fontSize:13, fontWeight:400 }}>MF</text>
      </svg>
      <div style={{ display:'flex', flexDirection:'column', lineHeight:1 }}>
        <span style={{ fontFamily:UI, fontSize:11, fontWeight:600, letterSpacing:'.22em', textTransform:'uppercase', color:C.muted }}>
          Menú Factory
        </span>
        <span style={{ fontFamily:UI, fontSize:8, letterSpacing:'.1em', color:C.dim, opacity:0.55, marginTop:3 }}>
          by sinapsys
        </span>
      </div>
    </div>
  );
}

/* small reusable caption label */
function Cap({ children, color = C.copper, style }) {
  return (
    <div style={{ fontFamily:UI, fontSize:8.5, letterSpacing:'.2em', textTransform:'uppercase',
      color, fontWeight:600, ...style }}>{children}</div>
  );
}

function LiveDot({ color = C.green }) {
  return (
    <span style={{ position:'relative', display:'inline-flex', width:7, height:7 }}>
      <span style={{ position:'absolute', inset:0, borderRadius:'50%', background:color,
        animation:'mfc-pulse 1.8s ease-in-out infinite' }} />
      <span style={{ position:'relative', width:7, height:7, borderRadius:'50%', background:color }} />
    </span>
  );
}

/* avatar chip */
function Avatar({ name, active, size = 30 }) {
  const initial = (name || '?').trim().charAt(0).toUpperCase();
  return (
    <div title={name} style={{
      width:size, height:size, borderRadius:'50%', flexShrink:0,
      display:'flex', alignItems:'center', justifyContent:'center',
      fontFamily:SF, fontSize:size * 0.42,
      color: active ? '#0c0905' : C.copper,
      background: active ? C.copper : 'transparent',
      border:`1px solid ${active ? C.copper : 'rgba(196,129,58,.4)'}`,
    }}>{initial}</div>
  );
}

/* ── What Menú Factory is, told in icons ─────────────────────────────
   Three glyphs that carry the whole product without a paragraph. Reused by
   the hero explainer and the demo intro so the promise reads identically. */
function IconScan({ s = 20 }) {
  return (
    <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M4 8V5a1 1 0 0 1 1-1h3M16 4h3a1 1 0 0 1 1 1v3M20 16v3a1 1 0 0 1-1 1h-3M8 20H5a1 1 0 0 1-1-1v-3" />
      <line x1="4" y1="12" x2="20" y2="12" />
    </svg>
  );
}
function IconGroup({ s = 20 }) {
  return (
    <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="9" cy="8" r="3" />
      <path d="M3 20c0-3 2.7-5 6-5s6 2 6 5" />
      <path d="M16 5.2A3 3 0 0 1 16 11M21 20c0-2.4-1.4-4.2-3.5-4.8" />
    </svg>
  );
}
function IconPay({ s = 20 }) {
  return (
    <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke="currentColor"
      strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2.5" y="5.5" width="19" height="13" rx="2" />
      <line x1="2.5" y1="10" x2="21.5" y2="10" />
      <line x1="6" y1="15" x2="10" y2="15" />
    </svg>
  );
}

/* The product in three beats — concrete, low-text, used in two places. */
const WHAT = [
  { label: 'Escanean la mesa', Icon: IconScan },
  { label: 'Piden en grupo',   Icon: IconGroup },
  { label: 'Pagan dividido',   Icon: IconPay },
];

/* horizontal icon+word explainer; sep dividers collapse on narrow screens */
function WhatRow({ size = 20, fontSize = 12, color = C.text }) {
  return (
    <div className="mfc-what">
      {WHAT.map((w, i) => (
        <React.Fragment key={w.label}>
          {i > 0 && <span className="mfc-what-sep" />}
          <div className="mfc-what-item">
            <span style={{ color: C.copper, display: 'inline-flex' }}><w.Icon s={size} /></span>
            <span style={{ fontFamily: UI, fontSize, letterSpacing: '.03em', color }}>{w.label}</span>
          </div>
        </React.Fragment>
      ))}
    </div>
  );
}

/* ── Navigation ──────────────────────────────────────────────────── */
function CNav({ onStart, onSignIn, onShowPricing, hidden }) {
  const y = useScrollY();
  if (hidden) return null;
  return (
    <nav className={`mfc-nav${y > 60 ? ' sc' : ''}`}>
      <div style={{ opacity: y > 60 ? 1 : 0, transition:'opacity .4s', pointerEvents: y > 60 ? 'auto' : 'none' }}>
        <Logo />
      </div>
      <div style={{ display:'flex', gap:12, alignItems:'center' }}>
        {onShowPricing && <button className="mfc-nav-btn ghost" onClick={onShowPricing} style={{ color: C.muted }}>Precios</button>}
        <button className="mfc-nav-btn ghost" onClick={onSignIn}>Iniciar sesión</button>
        <button className="mfc-nav-btn" onClick={onStart}>Solicitar acceso</button>
      </div>
    </nav>
  );
}

/* ─────────────────────────────────────────────────────────────────────────
   HERO — typewriter, kept faithful, now with a primary "Vivir la demo" CTA
   ───────────────────────────────────────────────────────────────────── */
function Hero({ onStart }) {
  const PROBLEM  = 'Convertimos la experiencia de siempre en una conexión de otro nivel.';
  const SOLUTION = 'Menú Factory.';
  const TAGLINE  = 'El comensal se une a tu restaurante como en su propia casa: lo que piensa es lo que pide.';

  const [txt, setTxt]               = useState('');
  const [phase, setPhase]           = useState('idle');
  const [showSub, setShowSub]       = useState(false);
  const [showCTA, setShowCTA]       = useState(false);
  const [isSolution, setIsSolution] = useState(false);
  const [heroLoaded, setHeroLoaded] = useState(false);

  useEffect(() => {
    const img = new Image();
    img.onload = () => setHeroLoaded(true);
    img.src = IMGS.hero;
    if (img.complete) setHeroLoaded(true);
  }, []);

  useEffect(() => {
    const t = setTimeout(() => setPhase('typing-p'), 900);
    return () => clearTimeout(t);
  }, []);

  useEffect(() => {
    let t;
    if (phase === 'typing-p') {
      if (txt.length < PROBLEM.length) {
        t = setTimeout(() => setTxt(PROBLEM.slice(0, txt.length + 1)), 46);
      } else {
        t = setTimeout(() => setPhase('pause'), 2400);
      }
    } else if (phase === 'pause') {
      t = setTimeout(() => setPhase('deleting'), 200);
    } else if (phase === 'deleting') {
      if (txt.length > 0) {
        t = setTimeout(() => setTxt(s => s.slice(0, -1)), 24);
      } else {
        setIsSolution(true);
        t = setTimeout(() => setPhase('typing-s'), 380);
      }
    } else if (phase === 'typing-s') {
      if (txt.length < SOLUTION.length) {
        t = setTimeout(() => setTxt(SOLUTION.slice(0, txt.length + 1)), 72);
      } else {
        setPhase('done');
        setTimeout(() => setShowSub(true),  700);
        setTimeout(() => setShowCTA(true), 1400);
      }
    }
    return () => clearTimeout(t);
  }, [phase, txt]);

  const showCursor = phase !== 'done';

  return (
    <section style={{ position:'relative', minHeight:'100vh', overflow:'hidden',
      display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center' }}>

      <div style={{ position:'absolute', inset:0, background:'#0e0a06' }} />
      <div style={{ position:'absolute', inset:0,
        backgroundImage:`url(${IMGS.hero})`,
        backgroundSize:'cover', backgroundPosition:'center 38%',
        filter:'brightness(.28) saturate(.9)',
        opacity: heroLoaded ? 1 : 0, transition:'opacity .6s ease' }} />
      <div style={{ position:'absolute', inset:0,
        background:'radial-gradient(ellipse 80% 70% at 50% 50%, transparent 30%, rgba(8,6,4,.72) 100%)' }} />

      <div style={{ position:'relative', zIndex:2, textAlign:'center', padding:'120px 32px 80px', maxWidth:820, width:'100%' }}>
        <Cap style={{ marginBottom:32, opacity:.85, fontSize:8.5 }}>Menú Factory</Cap>

        <h1 style={{ fontFamily:SF, fontWeight:300, lineHeight:1.18, letterSpacing:'-.005em',
          minHeight:'2.6em', fontSize:'clamp(26px, 3.4vw, 50px)',
          color: isSolution ? C.copper : C.text, transition:'color .6s ease' }}>
          {txt}
          {showCursor && (
            <span style={{ color:C.copper, animation:'mfc-blink .75s step-end infinite', marginLeft:2 }}>|</span>
          )}
        </h1>

        {isSolution && (
          <div style={{ fontFamily:UI, fontSize:'clamp(9px, 0.85vw, 11px)', letterSpacing:'.22em',
            textTransform:'uppercase', color:C.copper, opacity: showSub ? 0.55 : 0, marginTop:10,
            transition:'opacity .9s ease' }}>
            by sinapsys
          </div>
        )}

        <p style={{ fontFamily:SF, fontSize:'clamp(14px, 1.6vw, 20px)',
          color:C.muted, marginTop:24, letterSpacing:'.02em',
          opacity: showSub ? 1 : 0, transform: showSub ? 'translateY(0)' : 'translateY(14px)',
          transition:'opacity .9s ease, transform .9s ease' }}>
          {TAGLINE}
        </p>

        {/* What it actually is — the carta digital, in three concrete beats */}
        <div style={{ marginTop:32,
          opacity: showSub ? 1 : 0, transform: showSub ? 'translateY(0)' : 'translateY(12px)',
          transition:'opacity .9s ease .15s, transform .9s ease .15s' }}>
          <WhatRow size={20} fontSize={12.5} />
        </div>

        <div className="mfc-hero-ctas" style={{ marginTop:40, display:'flex', gap:16,
          alignItems:'center', justifyContent:'center', flexWrap:'wrap',
          opacity: showCTA ? 1 : 0, transform: showCTA ? 'translateY(0)' : 'translateY(14px)',
          transition:'opacity .9s ease, transform .9s ease' }}>
          <button className="mfc-cta primary" onClick={onStart}>Solicitar acceso</button>
        </div>

        {showCTA && (
          <p style={{ fontFamily:SF, fontSize:12, color:C.dim, marginTop:20,
            animation:'mfc-up-sm .7s ease both' }}>
            Sin instalar nada. Vívela como la vive tu comensal.
          </p>
        )}
      </div>
    </section>
  );
}

/* ─────────────────────────────────────────────────────────────────────────
   THE LIVE DEMO — immersive, in-page, five felt steps
   ───────────────────────────────────────────────────────────────────── */

const MENU = [
  { id:'d1', name:'Aguachile de camarón', desc:'Limón, serrano, pepino, cebolla morada.', price:185, tag:'Picante' },
  { id:'d2', name:'Tostada de atún',      desc:'Atún sellado, aguacate, chile macha.',    price:165, tag:'Del mar' },
  { id:'d3', name:'Tlayuda Oaxaqueña',    desc:'Asiento, quesillo, tasajo, frijol.',      price:220, tag:'Para compartir' },
  { id:'d4', name:'Mezcal Tobalá',        desc:'Espadín silvestre, naranja, sal de gusano.', price:140, tag:'Casa' },
  { id:'d5', name:'Flan de cajeta',       desc:'Cajeta de Celaya, nuez garapiñada.',      price:95,  tag:'Dulce' },
];

const STEPS = [
  { key:'scan',   label:'Escanear' },
  { key:'menu',   label:'La carta' },
  { key:'group',  label:'En grupo' },
  { key:'pay',    label:'La cuenta' },
  { key:'done',   label:'El cierre' },
];

function StepRail({ index }) {
  return (
    <div style={{ display:'flex', alignItems:'center', gap:18, flexWrap:'wrap' }}>
      {STEPS.map((s, i) => (
        <div key={s.key} className="mfc-step">
          <span className={`mfc-step-dot${i === index ? ' on' : i < index ? ' done' : ''}`} />
          <span style={{ fontFamily:UI, fontSize:10, fontWeight:600, letterSpacing:'.14em', textTransform:'uppercase',
            color: i === index ? C.copper : C.dim, transition:'color .3s' }}>{s.label}</span>
        </div>
      ))}
    </div>
  );
}

/* STEP 1 — Scan / arrival */
function StepScan({ onNext }) {
  const [connecting, setConnecting] = useState(false);
  const [connected, setConnected]   = useState(false);

  useEffect(() => {
    if (!connecting) return;
    const t = setTimeout(() => { setConnected(true); }, 1700);
    return () => clearTimeout(t);
  }, [connecting]);

  useEffect(() => {
    if (!connected) return;
    const t = setTimeout(onNext, 1300);
    return () => clearTimeout(t);
  }, [connected, onNext]);

  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', textAlign:'center',
      padding:'8px 0', animation:'mfc-up .5s ease both' }}>
      <Cap style={{ marginBottom:18 }}>Mesa 4 · Casa Amaranta</Cap>

      <div style={{ position:'relative', width:200, height:200, marginBottom:32 }}>
        {/* concentric rings */}
        {[0,1,2].map(i => (
          <div key={i} style={{ position:'absolute', inset: i * 26, borderRadius:'50%',
            border:`1px solid ${C.copper}`, opacity:.2,
            animation:`mfc-ring ${2.4 + i * 0.4}s ease-in-out ${i * 0.2}s infinite` }} />
        ))}
        {/* QR plate */}
        <div className="mfc-glass" style={{ position:'absolute', inset:46, borderRadius:8,
          display:'flex', alignItems:'center', justifyContent:'center', overflow:'hidden' }}>
          {!connected ? (
            <>
              <svg width="78" height="78" viewBox="0 0 78 78" style={{ opacity: connecting ? .9 : .55, transition:'opacity .4s' }}>
                {[[6,6],[6,52],[52,6]].map(([x,y],k)=>(
                  <g key={k}>
                    <rect x={x} y={y} width="20" height="20" fill="none" stroke={C.copper} strokeWidth="2.4"/>
                    <rect x={x+6} y={y+6} width="8" height="8" fill={C.copper}/>
                  </g>
                ))}
                {[[34,8],[44,8],[34,18],[54,18],[34,30],[46,30],[8,38],[20,38],[34,40],[50,42],[64,40],
                  [38,52],[50,52],[62,54],[38,64],[52,62],[64,66],[34,52],[34,62]].map(([x,y],k)=>(
                  <rect key={k} x={x} y={y} width="6" height="6" fill={C.copper} opacity=".8"/>
                ))}
              </svg>
              {connecting && <div className="mfc-scanline" />}
            </>
          ) : (
            <div style={{ animation:'mfc-pop .5s cubic-bezier(.34,1.56,.64,1) both' }}>
              <svg width="56" height="56" viewBox="0 0 24 24" fill="none" stroke={C.green} strokeWidth="2"
                strokeLinecap="round" strokeLinejoin="round">
                <circle cx="12" cy="12" r="10" />
                <polyline points="7.5,12.5 10.5,15.5 16.5,8.5" />
              </svg>
            </div>
          )}
        </div>
      </div>

      {!connected ? (
        <>
          <h2 style={{ fontFamily:SF, fontSize:'clamp(26px,4vw,36px)', fontWeight:300, color:C.text, marginBottom:10 }}>
            {connecting ? 'Conectando tu mesa…' : 'Escanea para sentarte'}
          </h2>
          <p style={{ fontFamily:SF, fontSize:15, color:C.muted, maxWidth:340, lineHeight:1.6, marginBottom:28 }}>
            {connecting
              ? 'Estás entrando a la mesa, como quien cruza la puerta de casa.'
              : 'Apunta tu cámara al código de la mesa. No hay app que descargar.'}
          </p>
          {!connecting && (
            <button className="mfc-btn primary lg" onClick={() => setConnecting(true)}>
              Escanear la mesa
            </button>
          )}
          {connecting && (
            <div style={{ width:220 }}>
              <div className="mfc-prog"><div className="mfc-prog-stripe" /></div>
            </div>
          )}
        </>
      ) : (
        <div style={{ animation:'mfc-up-sm .4s ease both' }}>
          <h2 style={{ fontFamily:SF, fontSize:'clamp(26px,4vw,36px)', fontWeight:300, color:C.copper, marginBottom:8 }}>
            Mesa conectada.
          </h2>
          <div style={{ display:'inline-flex', alignItems:'center', gap:8 }}>
            <LiveDot />
            <span style={{ fontFamily:UI, fontSize:13, letterSpacing:'.06em', color:C.muted }}>
              Experiencia activa en Mesa 4
            </span>
          </div>
        </div>
      )}
    </div>
  );
}

/* STEP 2 — Browse the menu, add dishes */
function StepMenu({ cart, addDish, onNext }) {
  const total = cart.reduce((s, c) => s + c.price * c.qty, 0);
  const count = cart.reduce((s, c) => s + c.qty, 0);

  return (
    <div style={{ animation:'mfc-up .5s ease both' }}>
      <div style={{ marginBottom:22 }}>
        <Cap>La carta · Casa Amaranta</Cap>
        <h2 style={{ fontFamily:SF, fontSize:'clamp(24px,3.4vw,34px)', fontWeight:300, color:C.text, marginTop:8 }}>
          Pide <span style={{ color:C.copper }}>como en casa</span>.
        </h2>
        <p style={{ fontFamily:UI, fontSize:14, color:C.muted, marginTop:4, lineHeight:1.5 }}>
          Toca un platillo para sumarlo a la cuenta de la mesa.
        </p>
      </div>

      <div className="mfc-scroll" style={{ maxHeight:'42vh', overflowY:'auto', paddingRight:4, marginBottom:4 }}>
        {MENU.map(d => {
          const inCart = cart.find(c => c.id === d.id);
          return (
            <div key={d.id} className="mfc-dish">
              <button className={`mfc-add${inCart ? ' in' : ''}`} title={inCart ? `Quitar ${d.name}` : `Agregar ${d.name}`}
                onClick={() => addDish(d)} aria-label={`Agregar ${d.name}`}>
                {inCart ? inCart.qty : '+'}
              </button>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ display:'flex', justifyContent:'space-between', gap:12, alignItems:'baseline' }}>
                  <span style={{ fontFamily:SF, fontSize:18, color:C.text }}>{d.name}</span>
                  <span style={{ fontFamily:SF, fontSize:18, color:C.copper, whiteSpace:'nowrap',
                    fontVariantNumeric:'tabular-nums' }}>${mx(d.price)}</span>
                </div>
                <div style={{ display:'flex', justifyContent:'space-between', gap:12, marginTop:3 }}>
                  <span style={{ fontFamily:UI, fontSize:13, color:C.muted, lineHeight:1.5 }}>{d.desc}</span>
                </div>
                <span style={{ display:'inline-block', marginTop:8, fontFamily:UI, fontSize:8.5,
                  letterSpacing:'.16em', textTransform:'uppercase', color:C.dim, fontWeight:600,
                  border:'1px solid rgba(196,129,58,.2)', borderRadius:999, padding:'3px 10px' }}>{d.tag}</span>
              </div>
            </div>
          );
        })}
      </div>

      <div style={{ marginTop:20, paddingTop:20, borderTop:'1px solid rgba(196,129,58,.12)',
        display:'flex', alignItems:'center', justifyContent:'space-between', gap:16, flexWrap:'wrap' }}>
        {count === 0 ? (
          <span style={{ fontFamily:SF, fontSize:14, color:C.dim }}>
            Tu mesa aún no pide nada.
          </span>
        ) : (
          <div>
            <Cap color={C.muted} style={{ marginBottom:4 }}>Cuenta de la mesa</Cap>
            <span style={{ fontFamily:SF, fontSize:26, color:C.copper, fontVariantNumeric:'tabular-nums' }}>
              ${mx(total)}
            </span>
            <span style={{ fontFamily:UI, fontSize:13, color:C.muted, marginLeft:10 }}>
              {count} {count === 1 ? 'platillo' : 'platillos'}
            </span>
          </div>
        )}
        <button className="mfc-btn primary lg" disabled={count === 0} onClick={onNext}>
          Continuar
        </button>
      </div>
    </div>
  );
}

/* STEP 3 — A second guest joins live, multiplayer felt */
function StepGroup({ cart, addDish, onNext }) {
  const [sofiaJoined, setSofiaJoined] = useState(false);
  const [sofiaOrdered, setSofiaOrdered] = useState(false);

  useEffect(() => {
    const t1 = setTimeout(() => setSofiaJoined(true), 900);
    const t2 = setTimeout(() => {
      setSofiaOrdered(true);
      addDish(MENU[2], 'Sofía'); // Tlayuda, attributed to Sofía
    }, 2300);
    return () => { clearTimeout(t1); clearTimeout(t2); };
    // eslint-disable-next-line
  }, []);

  const total = cart.reduce((s, c) => s + c.price * c.qty, 0);
  const guests = [
    { name:'Tú', active:true, status:'En la carta' },
    { name:'Sofía', active:false, status: sofiaOrdered ? 'Pidió Tlayuda' : sofiaJoined ? 'Mirando la carta' : 'Conectando…' },
  ];

  return (
    <div style={{ animation:'mfc-up .5s ease both' }}>
      <div style={{ marginBottom:20 }}>
        <Cap>Mesa 4 · En grupo</Cap>
        <h2 style={{ fontFamily:SF, fontSize:'clamp(24px,3.4vw,34px)', fontWeight:300, color:C.text, marginTop:8 }}>
          La mesa pide <span style={{ color:C.copper }}>en conjunto</span>.
        </h2>
        <p style={{ fontFamily:UI, fontSize:14, color:C.muted, marginTop:4, lineHeight:1.5 }}>
          Cada comensal escanea el mismo código. La cuenta es una sola, viva, compartida.
        </p>
      </div>

      {/* guest cards */}
      <div style={{ display:'flex', gap:12, flexWrap:'wrap', marginBottom:18 }}>
        {guests.map((g, i) => (
          <div key={g.name} className="mfc-glass-lt" style={{ flex:'1 1 180px', padding:16,
            display:'flex', alignItems:'center', gap:12,
            animation: g.name === 'Sofía' && sofiaJoined ? 'mfc-in .5s cubic-bezier(.34,1.56,.64,1) both' : 'none',
            opacity: g.name === 'Sofía' && !sofiaJoined ? 0.35 : 1, transition:'opacity .4s' }}>
            <Avatar name={g.name} active={g.active} />
            <div style={{ minWidth:0 }}>
              <div style={{ fontFamily:SF, fontSize:16, color:C.text }}>{g.name}</div>
              <div style={{ display:'flex', alignItems:'center', gap:6, marginTop:2 }}>
                {(g.active || sofiaJoined) && <LiveDot color={g.active ? C.copper : C.green} />}
                <span style={{ fontFamily:UI, fontSize:12, color:C.muted }}>{g.status}</span>
              </div>
            </div>
          </div>
        ))}
      </div>

      {/* shared cart */}
      <div className="mfc-glass" style={{ padding:18, borderRadius:6 }}>
        <Cap color={C.muted} style={{ marginBottom:12 }}>Cuenta compartida · Mesa 4</Cap>
        {cart.length === 0 ? (
          <p style={{ fontFamily:SF, fontSize:14, color:C.dim }}>Aún sin platillos.</p>
        ) : cart.map((c, i) => (
          <div key={c.id} style={{ display:'flex', alignItems:'center', justifyContent:'space-between',
            gap:12, padding:'9px 0', borderBottom: i < cart.length-1 ? '1px solid rgba(196,129,58,.07)' : 'none',
            animation:'mfc-up-sm .4s ease both', animationDelay:`${Math.min(i,3)*0.04}s` }}>
            <div style={{ display:'flex', alignItems:'center', gap:10, minWidth:0 }}>
              <Avatar name={c.by} active={c.by === 'Tú'} size={22} />
              <span style={{ fontFamily:SF, fontSize:16, color:C.text, overflow:'hidden',
                textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{c.name}</span>
              {c.qty > 1 && <span style={{ fontFamily:UI, fontSize:12, color:C.muted }}>×{c.qty}</span>}
            </div>
            <span style={{ fontFamily:SF, fontSize:16, color:C.copper, whiteSpace:'nowrap',
              fontVariantNumeric:'tabular-nums' }}>${mx(c.price * c.qty)}</span>
          </div>
        ))}
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline',
          marginTop:14, paddingTop:14, borderTop:'1px solid rgba(196,129,58,.14)' }}>
          <span style={{ fontFamily:UI, fontSize:13, fontWeight:600, letterSpacing:'.1em', textTransform:'uppercase', color:C.muted }}>Total mesa</span>
          <span style={{ fontFamily:SF, fontSize:24, color:C.copper, fontVariantNumeric:'tabular-nums' }}>${mx(total)}</span>
        </div>
      </div>

      <div style={{ marginTop:18, display:'flex', alignItems:'center', justifyContent:'space-between', gap:16, flexWrap:'wrap' }}>
        <div style={{ display:'inline-flex', alignItems:'center', gap:8 }}>
          <LiveDot />
          <span style={{ fontFamily:SF, fontSize:13, color:C.muted }}>
            {sofiaOrdered ? 'Todos están sincronizados' : 'Sincronizando la mesa…'}
          </span>
        </div>
        <button className="mfc-btn primary lg" onClick={onNext}>Pedir la cuenta</button>
      </div>
    </div>
  );
}

/* STEP 4 — Split + pay at table */
function StepPay({ cart, onNext }) {
  const total = cart.reduce((s, c) => s + c.price * c.qty, 0);
  const people = ['Tú', 'Sofía'];
  const per = total / people.length;
  const [paid, setPaid] = useState([]);

  const payAll = () => {
    people.forEach((p, i) => setTimeout(() => setPaid(prev => [...prev, p]), 500 + i * 700));
  };
  const allPaid = paid.length === people.length;

  useEffect(() => {
    if (!allPaid) return;
    const t = setTimeout(onNext, 1200);
    return () => clearTimeout(t);
  }, [allPaid, onNext]);

  return (
    <div style={{ animation:'mfc-up .5s ease both' }}>
      <div style={{ marginBottom:20 }}>
        <Cap>Mesa 4 · La cuenta</Cap>
        <h2 style={{ fontFamily:SF, fontSize:'clamp(24px,3.4vw,34px)', fontWeight:300, color:C.text, marginTop:8 }}>
          Se divide <span style={{ color:C.copper }}>sin pedir la cuenta</span>.
        </h2>
        <p style={{ fontFamily:UI, fontSize:14, color:C.muted, marginTop:4, lineHeight:1.5 }}>
          Cada quien paga desde su teléfono. Nadie espera al mesero con la terminal.
        </p>
      </div>

      {/* total + split math */}
      <div className="mfc-glass" style={{ padding:22, borderRadius:6, textAlign:'center', marginBottom:18 }}>
        <Cap color={C.muted} style={{ marginBottom:8 }}>Total de la mesa</Cap>
        <div style={{ fontFamily:SF, fontSize:'clamp(36px,7vw,54px)', color:C.copper, lineHeight:1,
          fontVariantNumeric:'tabular-nums' }}>${mx(total)}</div>
        <div style={{ fontFamily:UI, fontSize:15, color:C.muted, marginTop:10 }}>
          ÷ {people.length} comensales = <span style={{ fontFamily:SF, color:C.text }}>${mx(per)} c/u</span>
        </div>
      </div>

      {/* per-person cards */}
      <div className="mfc-demo-grid" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14, marginBottom:20 }}>
        {people.map(p => {
          const done = paid.includes(p);
          return (
            <div key={p} className="mfc-glass-lt" style={{ padding:16, borderRadius:6,
              borderColor: done ? 'rgba(109,184,109,.4)' : undefined,
              transition:'border-color .3s' }}>
              <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:12 }}>
                <Avatar name={p} active={p === 'Tú'} />
                <div>
                  <div style={{ fontFamily:SF, fontSize:16, color:C.text }}>{p}</div>
                  <div style={{ fontFamily:UI, fontSize:11, color:C.muted }}>{p === 'Tú' ? 'Apple Pay' : 'Tarjeta ·· 4291'}</div>
                </div>
              </div>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                <span style={{ fontFamily:SF, fontSize:20, color:C.copper, fontVariantNumeric:'tabular-nums' }}>${mx(per)}</span>
                {done ? (
                  <span style={{ display:'inline-flex', alignItems:'center', gap:6, fontFamily:UI, fontSize:13,
                    color:C.green, animation:'mfc-pop .4s cubic-bezier(.34,1.56,.64,1) both' }}>
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={C.green} strokeWidth="2.4"
                      strokeLinecap="round" strokeLinejoin="round"><polyline points="4,12 10,18 20,6"/></svg>
                    Pagado
                  </span>
                ) : (
                  <span style={{ fontFamily:UI, fontSize:12, color:C.dim }}>Pendiente</span>
                )}
              </div>
            </div>
          );
        })}
      </div>

      <button className="mfc-btn primary lg" style={{ width:'100%' }} disabled={paid.length > 0} onClick={payAll}>
        {paid.length === 0 ? 'Revisar y pagar' : allPaid ? 'Cuenta saldada' : 'Procesando pagos…'}
      </button>
    </div>
  );
}

/* STEP 5 — The close + invitation */
function StepDone({ onStart, onReplay }) {
  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', textAlign:'center',
      padding:'10px 0', animation:'mfc-up .5s ease both' }}>
      <div style={{ position:'relative', width:120, height:120, marginBottom:28 }}>
        {[0,1].map(i => (
          <div key={i} style={{ position:'absolute', inset: i * 18, borderRadius:'50%',
            border:`1px solid ${C.green}`, opacity:.22,
            animation:`mfc-ring ${2.6 + i*0.4}s ease-in-out infinite` }} />
        ))}
        <div style={{ position:'absolute', inset:32, borderRadius:'50%', border:`1px solid rgba(109,184,109,.5)`,
          display:'flex', alignItems:'center', justifyContent:'center',
          animation:'mfc-pop .6s cubic-bezier(.34,1.56,.64,1) both' }}>
          <svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke={C.green} strokeWidth="2"
            strokeLinecap="round" strokeLinejoin="round"><polyline points="5,13 10,18 19,7"/></svg>
        </div>
      </div>

      <h2 style={{ fontFamily:SF, fontSize:'clamp(30px,5vw,46px)', fontWeight:300, color:C.copper, marginBottom:14 }}>
        Completamente pagada.
      </h2>
      <p style={{ fontFamily:SF, fontSize:'clamp(15px,2vw,19px)', color:C.muted, maxWidth:420, lineHeight:1.65, marginBottom:8 }}>
        La mesa se sentó, pidió en grupo y pagó dividido — sin esperar a nadie.
      </p>
      <p style={{ fontFamily:SF, fontSize:14, color:C.dim, maxWidth:380, lineHeight:1.6, marginBottom:32 }}>
        "La experiencia termina. La inteligencia de tu restaurante continúa."
      </p>

      <div className="mfc-hero-ctas" style={{ display:'flex', gap:14, flexWrap:'wrap', justifyContent:'center' }}>
        <button className="mfc-cta primary" onClick={onStart}>Solicitar acceso</button>
        <button className="mfc-cta ghost" onClick={onReplay}>Vivirla otra vez</button>
      </div>
    </div>
  );
}

/* STEP 0 — Intro: frame the demo so the restaurant owner knows what they're
   about to do — step into the comensal's shoes, not watch a marketing reel. */
function StepIntro({ onBegin }) {
  return (
    <div style={{ display:'flex', flexDirection:'column', alignItems:'center', textAlign:'center',
      padding:'8px 0', animation:'mfc-up .5s ease both' }}>
      <Cap style={{ marginBottom:18 }}>La demo · 60 segundos</Cap>

      <h2 style={{ fontFamily:SF, fontSize:'clamp(28px,4.4vw,40px)', fontWeight:300, color:C.text,
        lineHeight:1.15, marginBottom:14 }}>
        Ponte en el lugar de <span style={{ color:C.copper }}>tu comensal</span>.
      </h2>
      <p style={{ fontFamily:UI, fontSize:15, color:C.muted, maxWidth:400, lineHeight:1.65, marginBottom:30 }}>
        Esto no es un video. Es la experiencia real que vive quien se sienta en tu mesa —
        tú la recorres paso a paso, desde el teléfono, como si fueras él.
      </p>

      {/* the three beats they're about to live */}
      <div style={{ marginBottom:34 }}>
        <WhatRow size={22} fontSize={13} />
      </div>

      <button className="mfc-btn primary lg" onClick={onBegin}>Comenzar la experiencia</button>
      <p style={{ fontFamily:UI, fontSize:12, color:C.dim, marginTop:18 }}>
        Tú tocas, nosotros simulamos al resto de la mesa.
      </p>
    </div>
  );
}

/* ── Footer ──────────────────────────────────────────────────────── */
function Footer({ onStart }) {
  return (
    <footer style={{ background:'#050302', borderTop:'1px solid rgba(196,129,58,.1)', padding:'56px 0 28px', position:'relative', zIndex:2 }}>
      <div style={{ maxWidth:1100, margin:'0 auto', padding:'0 44px',
        display:'flex', justifyContent:'space-between', alignItems:'flex-start', flexWrap:'wrap', gap:32 }}>
        <div style={{ maxWidth:300 }}>
          <Logo />
          <p style={{ fontFamily:SF, fontSize:14, color:C.muted, lineHeight:1.7, marginTop:16 }}>
            El comensal se une a tu restaurante como en su propia casa.
          </p>
          <div style={{ display:'flex', gap:12, marginTop:22, flexWrap:'wrap' }}>
            <button className="mfc-btn primary" onClick={onStart}>Solicitar acceso</button>
          </div>
        </div>
        {[
          { t:'Producto', l:['Menú digital','Panel admin','Cuenta compartida','API'] },
          { t:'Casas',    l:['Casa Amaranta','Oryu omakase','La Huerta','Ver todas'] },
          { t:'Empresa',  l:['Manifiesto','Equipo','Contacto','Términos'] },
        ].map(col => (
          <div key={col.t}>
            <Cap color={C.dim} style={{ marginBottom:16, fontSize:8 }}>{col.t}</Cap>
            {col.l.map(item => (
              <div key={item} style={{ fontFamily:UI, fontSize:14, color:C.muted, marginBottom:9 }}>{item}</div>
            ))}
          </div>
        ))}
      </div>
      <div style={{ maxWidth:1100, margin:'32px auto 0', padding:'20px 44px 0',
        borderTop:'1px solid rgba(196,129,58,.06)',
        display:'flex', justifyContent:'space-between', flexWrap:'wrap', gap:8, fontFamily:UI, fontSize:11, color:C.dim }}>
        <span>MMXXVI Menú Factory <span style={{ fontSize:9, opacity:0.55, letterSpacing:'.08em' }}>by sinapsys</span></span>
        <span>Version 7.0 · Immersive</span>
      </div>
    </footer>
  );
}

/* ── Root export ─────────────────────────────────────────────────── */
window.MFLanding = function MFLanding({ onStart, onSignIn, onShowPricing }) {
  useEffect(() => {
    const style = document.createElement('style');
    style.textContent = CSS;
    document.head.appendChild(style);
    return () => { try { document.head.removeChild(style); } catch (e) {} };
  }, []);

  return (
    <div className="mfc" style={{ background:C.bg, color:C.text, fontFamily:UI, minHeight:'100vh' }}>
      <Grain />
      <CNav onStart={onStart} onSignIn={onSignIn} onShowPricing={onShowPricing} />
      <Hero onStart={onStart} />
      <Footer onStart={onStart} />
    </div>
  );
};
window.MFLandingView = window.MFLanding;
