// ============================================================
// guide.jsx · Portadas "vendedor" + navegación por rol
// Cross-role journey + intro covers + deep-link sections
// ============================================================

// Journey global (orden de roles en el ciclo de vida del producto)
const ROLE_META = {
  sysadmin:     { label: "Sysadmin", short: "Alta de escuela" },
  director:     { label: "Director · alta", short: "Onboarding" },
  "director-op":{ label: "Director · consola", short: "Operación diaria" },
  finanzas:     { label: "Finanzas", short: "Cobranza · CFDI" },
  maestro:      { label: "Maestro", short: "Aula" },
  portero:      { label: "Portero", short: "Pickup" },
  padre:        { label: "Padre", short: "Familia" },
};

// deep-link: true → la app expone navegación por postMessage (consolas)
// console: true → rol nativo (no iframe); las secciones saltan a pantallas internas
const ROLE_GUIDE = {
  // ---------------- SYSADMIN ----------------
  sysadmin: {
    icon: "shield", accent: "#3C3489", accentTint: "var(--xokai-purple-light)",
    eyebrow: "Plataforma · Operación interna Xokai",
    title: "Sysadmin",
    tagline: "El back office de Xokai · da de alta cada escuela, define su plan e invita a la dirección con un magic link · en ~5 minutos.",
    outcome: "Al final: la escuela queda creada como tenant, con su plan y datos fiscales, y la dirección recibe la invitación para arrancar su onboarding.",
    valueBadges: ["Alta en 3 pasos", "Plan y billing", "Magic link al director", "Multi-tenant"],
    demoChecklist: [
      "El dashboard muestra MRR, escuelas activas y onboarding pendiente",
      "El alta corre en 3 pasos: datos fiscales, plan e invitación",
      "Al crear, Xokai dispara el magic link a la dirección",
      "Desde aquí Xokai entra como soporte a cualquier escuela",
    ],
    journeyPrev: null,
    journeyNext: { role: "director", note: "La dirección recibe el link y configura su escuela" },
    internalSteps: "Dashboard → Datos fiscales → Plan y billing → Invitar director → Tenant creado",
    console: true, deepLink: false, dashId: "A1", heroComp: "A1",
    sections: [
      { id: "A1", label: "Dashboard sysadmin", icon: "layout-dashboard", desc: "MRR, escuelas y pendientes" },
      { id: "A2", label: "Datos fiscales", icon: "building-2", desc: "Paso 1 · alta de la escuela" },
      { id: "A3", label: "Plan y billing", icon: "credit-card", desc: "Paso 2 · modalidad de cobro" },
      { id: "A4", label: "Invitar director", icon: "send", desc: "Paso 3 · magic link" },
      { id: "A5", label: "Tenant creado", icon: "party-popper", desc: "Confirmación · celebration" },
    ],
  },

  // ---------------- DIRECTOR · ALTA ----------------
  director: {
    icon: "monitor", accent: "#6D4AE8", accentTint: "var(--xk-accent-light)",
    eyebrow: "Onboarding · Configuración inicial",
    title: "Director · alta",
    tagline: "El primer día de la dirección en Xokai · configura perfil, branding, estructura y pickup, y carga toda su comunidad · todo guiado.",
    outcome: "Al final: la escuela queda configurada de punta a punta y con su comunidad cargada (personal, familias, alumnos), lista para invitar a los padres.",
    valueBadges: ["Onboarding guiado", "Branding white-label", "Pickup escalonado", "Carga masiva"],
    demoChecklist: [
      "El onboarding va paso a paso sin abrumar a la dirección",
      "El branding detecta los colores del logo de la escuela",
      "El centro de carga sube personal, familias y alumnos por CSV",
      "Al terminar, un magic link masivo activa a todos los padres",
    ],
    journeyPrev: { role: "sysadmin", note: "Xokai ya creó el tenant y mandó la invitación" },
    journeyNext: { role: "director-op", note: "La dirección pasa a operar la escuela día a día" },
    internalSteps: "Welcome → Perfil → Branding → Estructura → Ciclo → Pickup → Centro de carga → Activación",
    console: true, deepLink: false, dashId: "B0", heroComp: "I0",
    sections: [
      { id: "B0", label: "Welcome", icon: "hand", desc: "Bienvenida post magic link" },
      { id: "B2", label: "Branding", icon: "palette", desc: "Logo y color de la escuela" },
      { id: "B3", label: "Estructura", icon: "layout-grid", desc: "Niveles y grupos" },
      { id: "B5", label: "Pickup semáforo", icon: "radio", desc: "Ventanas de salida" },
      { id: "B7", label: "Onboarding listo", icon: "party-popper", desc: "Celebration" },
      { id: "I0", label: "Centro de carga", icon: "upload", desc: "Hub de carga masiva" },
      { id: "I5", label: "Activación masiva", icon: "rocket", desc: "Magic link a 614 padres" },
    ],
  },

  // ---------------- FINANZAS (plantilla a fondo) ----------------
  finanzas: {
    icon: "wallet", accent: "#0F6E56", accentTint: "var(--xk-success-tint)",
    eyebrow: "Módulo · Operación financiera",
    title: "Finanzas",
    tagline: "Cobra colegiaturas, concilia pagos y timbra CFDI sin salir de Xokai · adiós al Excel de cobranza.",
    outcome: "Al final de este módulo: la escuela cierra el mes con la cobranza al día, cada pago conciliado contra banco y su factura CFDI timbrada automáticamente.",
    valueBadges: ["Cobranza automatizada", "CFDI 4.0 timbrado", "Conciliación bancaria", "Cero Excel"],
    demoChecklist: [
      "El dashboard abre con el estado de cobranza del mes en un vistazo",
      "Cobranza activa lista las 12 familias morosas con su acción sugerida",
      "Reconciliación empata pagos de banco contra recibos automáticamente",
      "CFDI timbra la factura sin capturar datos fiscales de nuevo",
    ],
    journeyPrev: { role: "director-op", note: "La dirección ya tiene a las familias inscritas en la consola" },
    journeyNext: { role: "padre", note: "El tutor recibe su estado de cuenta y paga desde la app" },
    internalSteps: "Dashboard → Cierre de mes → Cobranza activa → Reconciliación → Pagos → Conceptos → CFDI",
    deepLink: true, dashId: "Dashboard", heroScreen: "Dashboard", heroSrc: "roles/finanzas/index.html",
    sections: [
      { id: "Dashboard", label: "Dashboard", icon: "layout-dashboard", desc: "Estado de cobranza del mes en un vistazo" },
      { id: "Cierre de mes", label: "Cierre de mes", icon: "calendar-check", desc: "Corte mensual y generación de recibos" },
      { id: "Cobranza activa", label: "Cobranza activa", icon: "alert-circle", desc: "Familias morosas con acción sugerida" },
      { id: "Reconciliación", label: "Reconciliación", icon: "shield-check", desc: "Empata pagos de banco con recibos" },
      { id: "Pagos", label: "Pagos", icon: "credit-card", desc: "Historial y registro de pagos" },
      { id: "Conceptos", label: "Conceptos", icon: "receipt", desc: "Colegiaturas, inscripción, descuentos" },
      { id: "CFDI", label: "CFDI", icon: "file-check-2", desc: "Timbrado de facturas 4.0" },
      { id: "Solicitudes", label: "Solicitudes", icon: "inbox", desc: "Peticiones de facturas y aclaraciones" },
      { id: "DMs", label: "Mensajes", icon: "message-square", desc: "Conversación 1-a-1 con tutores" },
      { id: "Excepciones", label: "Excepciones", icon: "alert-triangle", desc: "Becas, convenios y casos especiales" },
      { id: "Settings", label: "Configuración", icon: "settings", desc: "Datos fiscales y preferencias" },
    ],
  },

  // ---------------- DIRECTOR · CONSOLA ----------------
  "director-op": {
    icon: "layout-dashboard", accent: "#6D4AE8", accentTint: "var(--xk-accent-light)",
    eyebrow: "Consola · Operación diaria",
    title: "Director · consola",
    tagline: "El centro de mando de la dirección una vez que la escuela está viva · avisos, pendientes, eventos, staff y pickup en un lugar.",
    outcome: "Al final: la dirección ve el pulso de la escuela cada día, manda avisos a las familias, resuelve pendientes y monitorea la salida en vivo.",
    valueBadges: ["Pulso diario", "Broadcast a familias", "Pendientes accionables", "Pickup en vivo"],
    demoChecklist: [
      "El dashboard resume cobranza, asistencia y pickup del día",
      "Broadcast manda un aviso a un segmento con read receipts",
      "Pendientes junta cobranza, docs e incidencias en una bandeja",
      "El monitor de pickup muestra las ventanas en tiempo real",
    ],
    journeyPrev: { role: "director", note: "La dirección ya completó el onboarding y la carga" },
    journeyNext: { role: "maestro", note: "Los maestros operan el aula día a día" },
    internalSteps: "Dashboard → Broadcast → Pendientes → Eventos → Staff → Pickup → Reportes",
    deepLink: true, dashId: "dashboard", heroScreen: "broadcast", heroSrc: "roles/director-op/index.html",
    sections: [
      { id: "dashboard", label: "Dashboard", icon: "layout-dashboard", desc: "Pulso de la escuela hoy" },
      { id: "broadcast", label: "Broadcast", icon: "megaphone", desc: "Avisos a familias con read receipts" },
      { id: "pendientes", label: "Pendientes", icon: "list-checks", desc: "Cobranza, reinscripción, docs, incidencias" },
      { id: "eventos", label: "Eventos", icon: "calendar-days", desc: "Crear, dashboard, historial" },
      { id: "staff", label: "Staff", icon: "users-round", desc: "Maestros y administrativos" },
      { id: "pickup", label: "Pickup", icon: "radio", desc: "Monitor de salida en vivo" },
      { id: "permisos", label: "Permisos", icon: "shield", desc: "Solicitudes de salida y delegación" },
      { id: "reports", label: "Reportes", icon: "bar-chart-3", desc: "Snapshot mensual · export PDF" },
      { id: "settings", label: "Configuración", icon: "settings", desc: "Perfil, permisos, idioma" },
    ],
  },

  // ---------------- MAESTRO (intro-only) ----------------
  maestro: {
    icon: "smartphone", accent: "#6D4AE8", accentTint: "var(--xk-accent-light)",
    eyebrow: "App móvil · Aula",
    title: "Maestro",
    tagline: "La app del maestro en la mano · asistencia, avisos al grupo, mensajes con familias e incidencias, desde el celular.",
    outcome: "Al final: el maestro pasa lista en segundos, avisa al grupo, responde a las familias y registra incidencias sin papel.",
    valueBadges: ["Asistencia en 1 toque", "Broadcast al grupo", "Mensajes con familias", "Incidencias"],
    demoChecklist: [
      "La asistencia se toma con un toque por alumno",
      "El broadcast llega solo al grupo del maestro",
      "Los DMs mantienen el contacto familia–maestro ordenado",
      "Las incidencias quedan registradas con foto y hora",
    ],
    journeyPrev: { role: "director-op", note: "La dirección asigna grupos y maestros" },
    journeyNext: { role: "padre", note: "La familia recibe asistencia, avisos y mensajes" },
    internalSteps: "Inicio → Asistencia → Broadcast → DMs → Incidencias → Permisos → Calendario",
    deepLink: true, dashId: "entry", heroScreen: "m2", heroSrc: "roles/maestro/index.html", mobile: true,
    sections: [
      { id: "entry", label: "Inicio", icon: "home", desc: "Home del maestro" },
      { id: "m1", label: "M1 · Asistencia", icon: "list-checks", desc: "Pasar lista en 1 toque" },
      { id: "m2", label: "M2 · Broadcast", icon: "megaphone", desc: "Aviso al grupo" },
      { id: "m3", label: "M3 · DMs", icon: "message-square", desc: "Mensajes con familias" },
      { id: "m4", label: "M4 · Incidencias", icon: "alert-triangle", desc: "Reporte estructurado" },
      { id: "m5", label: "M5 · Permisos", icon: "clipboard-check", desc: "Aprobar / escalar" },
      { id: "m6", label: "M6 · Calendario", icon: "calendar-days", desc: "Grupo y atelier" },
      { id: "m7", label: "M7 · Ajustes", icon: "settings", desc: "Perfil e idioma" },
    ],
  },

  // ---------------- PORTERO (intro-only) ----------------
  portero: {
    icon: "scan-line", accent: "#BA7517", accentTint: "var(--xk-warning-tint)",
    eyebrow: "Kiosko · Salida segura",
    title: "Portero",
    tagline: "El semáforo de pickup en el kiosko de la entrada · quién sale, en qué ventana y quién está autorizado a recogerlo.",
    outcome: "Al final: la salida deja de ser un caos · cada alumno sale en su ventana, con su tutor verificado, y los casos de riesgo se escalan solos.",
    valueBadges: ["Semáforo por ventana", "Tutor verificado", "Escalación automática", "Cierre de día"],
    demoChecklist: [
      "El kiosko muestra la ventana activa con su color de semáforo",
      "La fila lista a cada alumno con su tutor autorizado",
      "Un tutor sin permiso queda bloqueado y se escala",
      "El cierre de día reporta olvidos y pendientes",
    ],
    journeyPrev: { role: "director", note: "La dirección configuró las ventanas de pickup" },
    journeyNext: { role: "padre", note: "El tutor llega en su ventana y recoge a su hijo" },
    internalSteps: "Fila → Entrega → Recogida temporal → Multi-hijo → Buscar → Alertas",
    deepLink: true, dashId: "queue", heroScreen: "queue", heroSrc: "roles/portero/index.html", kiosk: true,
    sections: [
      { id: "queue", label: "Fila de pickup", icon: "users", desc: "Ventana activa en vivo" },
      { id: "preview", label: "Entrega", icon: "scan-line", desc: "Verificar y entregar" },
      { id: "temporal", label: "Recogida temporal", icon: "user-plus", desc: "Tercero autorizado" },
      { id: "multihijo", label: "Multi-hijo", icon: "users-round", desc: "Hermanos en una entrega" },
      { id: "search", label: "Buscar alumno", icon: "search", desc: "Búsqueda manual" },
      { id: "alertLate", label: "Alerta · tarde", icon: "clock", desc: "Fuera de ventana" },
      { id: "alertBlock", label: "Verificación bloqueada", icon: "shield-alert", desc: "Caso de riesgo" },
    ],
  },

  // ---------------- PADRE (intro-only) ----------------
  padre: {
    icon: "smartphone", accent: "#88B83C", accentTint: "var(--tenant-brand-tint)",
    eyebrow: "App móvil · Familia",
    title: "Padre",
    tagline: "Toda la vida escolar de su hijo en una app branded de la escuela · pickup, pagos, avisos y reinscripción.",
    outcome: "Al final: el tutor vive la escuela desde su celular · sabe cuándo recoger, paga sin filas, recibe avisos y reinscribe con un toque.",
    valueBadges: ["Pickup en vivo", "Pago + CFDI", "Avisos y mensajes", "Reinscripción"],
    demoChecklist: [
      "El inicio muestra el próximo pickup y los pendientes",
      "El pago se hace desde el celular y genera CFDI",
      "Los avisos de la escuela llegan branded, no por WhatsApp",
      "La reinscripción se confirma en un par de toques",
    ],
    journeyPrev: { role: "finanzas", note: "Finanzas emitió el estado de cuenta" },
    journeyNext: null,
    internalSteps: "Mañana → Durante el día → Pickup → Domingo → Pagos → Reinscripción → Permisos → DMs",
    deepLink: true, dashId: "m1-home", heroScreen: "m7-reinscripcion", heroSrc: "roles/padre/index.html", mobile: true,
    sections: [
      { id: "m1-home", label: "M1 · Mañana", icon: "sunrise", desc: "Bandeja pre-escuela" },
      { id: "m2-day", label: "M2 · Durante el día", icon: "bell", desc: "Push y avisos" },
      { id: "m3-pickup", label: "M3 · Pickup", icon: "car-front", desc: "3 rutas de recogida" },
      { id: "m5-week", label: "M5 · Domingo", icon: "calendar-days", desc: "Planning semanal" },
      { id: "m6-pagos", label: "M6 · Pagos", icon: "credit-card", desc: "Colegiatura + CFDI" },
      { id: "m7-reinscripcion", label: "M7 · Reinscripción", icon: "repeat", desc: "Checklist + co-firma" },
      { id: "m9-permisos", label: "M9 · Permisos", icon: "clipboard-check", desc: "Solicitar / justificar" },
      { id: "m10-dms", label: "M10 · DMs", icon: "message-square", desc: "Mensajes con maestros" },
      { id: "settings", label: "Ajustes", icon: "settings", desc: "Co-tutores e idioma" },
    ],
  },
};

window.ROLE_GUIDE = ROLE_GUIDE;
window.ROLE_META = ROLE_META;

// ============================================================
// LiveMock · live, scaled iframe of the role's star screen
// ============================================================
function LiveMock({ src, comp, screen, mobile, kiosk, accent }) {
  const ref = useRef(null);
  const post = () => { try { if (screen && ref.current && ref.current.contentWindow) ref.current.contentWindow.postMessage({ type: "xk-nav", section: screen }, "*"); } catch (e) {} };
  useEffect(() => {
    const onMsg = (e) => { if (e.data && e.data.type === "xk-ready") post(); };
    window.addEventListener("message", onMsg);
    return () => window.removeEventListener("message", onMsg);
  }, [screen]);
  const logicalW = mobile ? 390 : 1280;
  const renderW = mobile ? 460 : 980;
  const scale = renderW / logicalW;
  const logicalH = Math.round((mobile ? 760 : 760) / scale);
  const Comp = comp ? window[comp] : null;

  // ---- MOBILE: crop the focus-overlay so only the phone SCREEN shows ----
  if (mobile && !Comp) {
    // iframe logical viewport sized so the design-canvas focus overlay renders
    // the phone (392×820 / 390×780) at ~1:1, centered. We then crop to it.
    const vpW = 592, vpH = 1120;          // overlay viewport we force on the iframe
    const phoneW = 392, phoneH = 820;     // artboard size
    // phone rect inside the overlay (left:100 chrome, vertically centered in top64/bottom56 box)
    const phoneX = 100;
    const phoneY = 64 + ((vpH - 120) - phoneH) / 2;
    const Hf = 560, Wf = Math.round(Hf * (phoneW / phoneH)); // display size of the screen
    const s = Hf / phoneH;
    return (
      <div aria-hidden style={{ position: "absolute", inset: 0, overflow: "hidden", borderRadius: 18, pointerEvents: "none" }}>
        <div style={{ position: "absolute", right: -80, top: "10%", width: Wf, height: Hf,
          borderRadius: 30, overflow: "hidden", background: "#0F0E0C",
          boxShadow: "0 30px 70px -20px rgba(0,0,0,0.55)", border: "1px solid rgba(15,14,12,0.6)" }}>
          <div style={{ position: "absolute", inset: 0, borderRadius: 26, overflow: "hidden", background: "#fff" }}>
            <div style={{ position: "absolute", left: -phoneX * s, top: -phoneY * s, width: vpW, height: vpH, transform: "scale(" + s + ")", transformOrigin: "top left" }}>
              <iframe ref={ref} src={src} title="preview" scrolling="no"
                onLoad={() => { post(); setTimeout(post, 700); setTimeout(post, 1600); }}
                style={{ width: vpW, height: vpH, border: "none", pointerEvents: "none", display: "block" }}></iframe>
            </div>
          </div>
        </div>
        <div style={{ position: "absolute", inset: 0, background: "linear-gradient(100deg, " + accent + " 44%, color-mix(in oklab, " + accent + " 55%, transparent) 66%, transparent 88%)" }}></div>
      </div>
    );
  }

  // ---- KIOSK (Portero): landscape screen filling bottom-right, 10% empty top ----
  if (kiosk && !Comp) {
    const vpW = 1366, vpH = 820;            // kiosk iframe viewport
    const cropTop = 8;                      // small top trim
    const cropLeft = 252;                   // crop the app's dark demo-nav rail on the left
    const visW = vpW - cropLeft;
    const Wf = 680, s = Wf / visW;
    const Hf = Math.round((vpH - cropTop) * s);
    return (
      <div aria-hidden style={{ position: "absolute", inset: 0, overflow: "hidden", borderRadius: 18, pointerEvents: "none" }}>
        <div style={{ position: "absolute", right: -90, top: "10%", width: Wf, height: Hf,
          borderRadius: 12, overflow: "hidden", background: "#fff",
          boxShadow: "0 30px 70px -20px rgba(0,0,0,0.55)", border: "1px solid rgba(15,14,12,0.08)" }}>
          <iframe ref={ref} src={src} title="preview" scrolling="no"
            onLoad={() => { post(); setTimeout(post, 700); setTimeout(post, 1600); }}
            style={{ width: vpW, height: vpH, border: "none", transform: "translate(" + (-cropLeft * s) + "px," + (-cropTop * s) + "px) scale(" + s + ")", transformOrigin: "top left", pointerEvents: "none", display: "block" }}></iframe>
        </div>
        <div style={{ position: "absolute", inset: 0, background: "linear-gradient(100deg, " + accent + " 42%, color-mix(in oklab, " + accent + " 55%, transparent) 64%, transparent 86%)" }}></div>
      </div>
    );
  }

  // ---- DESKTOP / console: upright browser window, contained right, 10% empty top, bleeds right edge ----
  const vpW = 1280, vpH = 800;
  const Wf = 560, Hf = Math.round(Wf * (vpH / vpW));
  const s = Wf / vpW;
  const dvpH = Math.round(Hf / s);
  return (
    <div aria-hidden style={{ position: "absolute", inset: 0, overflow: "hidden", borderRadius: 18, pointerEvents: "none" }}>
      <div style={{ position: "absolute", right: -90, top: "10%", width: Wf,
        borderRadius: 12, overflow: "hidden", boxShadow: "0 28px 60px -18px rgba(0,0,0,0.5)", border: "1px solid rgba(255,255,255,0.12)" }}>
        <div style={{ height: 16, background: "rgba(28,26,23,0.9)", display: "flex", alignItems: "center", gap: 4, padding: "0 9px" }}>
          {["#ff5f57", "#febc2e", "#28c840"].map((c, i) => <span key={i} style={{ width: 6, height: 6, borderRadius: 999, background: c }}></span>)}
        </div>
        <div style={{ width: Wf, height: Hf, overflow: "hidden", background: "#fff" }}>
          {Comp ? (
            <div style={{ width: vpW, height: dvpH, transform: "scale(" + s + ")", transformOrigin: "top left", pointerEvents: "none" }}>
              <Comp state="happy" openModal={() => {}} />
            </div>
          ) : (
            <iframe ref={ref} src={src} title="preview" scrolling="no"
              onLoad={() => { post(); setTimeout(post, 700); setTimeout(post, 1600); }}
              style={{ width: vpW, height: dvpH, border: "none", transform: "scale(" + s + ")", transformOrigin: "top left", pointerEvents: "none", display: "block" }}></iframe>
          )}
        </div>
      </div>
      {/* left scrim — keeps the text fully legible over the hero gradient */}
      <div style={{ position: "absolute", inset: 0, background: "linear-gradient(100deg, " + accent + " 40%, color-mix(in oklab, " + accent + " 52%, transparent) 60%, transparent 82%)" }}></div>
    </div>
  );
}
window.LiveMock = LiveMock;


// ============================================================
// Cover · portada "vendedor" de cada rol
// ============================================================
function RoleCover({ guide, roleId, onEnter, onSection }) {
  if (!guide) return null;
  const accent = guide.accent;
  const prev = guide.journeyPrev, next = guide.journeyNext;
  const metaPrev = prev && ROLE_META[prev.role];
  const metaNext = next && ROLE_META[next.role];
  return (
    <div className="no-scrollbar" style={{ height: "100%", overflowY: "auto", background: "var(--xk-bg)" }}>
      <div style={{ maxWidth: 900, margin: "0 auto", padding: "32px 36px 48px" }}>
        {/* Hero · opción 3: live mock difuminado de fondo, acotado al hero */}
        <div className="animate-fade-up" style={{ position: "relative", overflow: "hidden", borderRadius: 18, padding: "32px 32px 30px",
          background: "linear-gradient(135deg, " + accent + ", color-mix(in oklab, " + accent + " 72%, black))", color: "#fff", minHeight: 260 }}>
          {(guide.heroSrc || guide.heroComp)
            ? <LiveMock src={guide.heroSrc} comp={guide.heroComp} screen={guide.heroScreen} mobile={guide.mobile} kiosk={guide.kiosk} accent={accent} />
            : <div style={{ position: "absolute", top: -40, right: -30, opacity: 0.14 }}><Icon name={guide.icon} size={200} color="#fff" /></div>}
          <div style={{ position: "relative", zIndex: 2, maxWidth: 560 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 18 }}>
              <span style={{ width: 60, height: 60, borderRadius: 15, background: "rgba(255,255,255,0.18)", display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                <Icon name={guide.icon} size={30} color="#fff" />
              </span>
              <div>
                <div style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.08em", textTransform: "uppercase", opacity: 0.85 }}>{guide.eyebrow}</div>
                <h1 style={{ margin: "3px 0 0", fontSize: 30, fontWeight: 600, letterSpacing: "-0.02em" }}>{guide.title}</h1>
              </div>
            </div>
            <p style={{ margin: 0, fontSize: 16, lineHeight: 1.55, maxWidth: 540, opacity: 0.95 }}>{guide.tagline}</p>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 18 }}>
              {guide.valueBadges.map((b, i) => (
                <span key={i} style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "5px 11px", background: "rgba(255,255,255,0.16)", borderRadius: 999, fontSize: 12, fontWeight: 500 }}>
                  <Icon name="check" size={12} color="#fff" />{b}
                </span>
              ))}
            </div>
            <div style={{ marginTop: 22 }}>
              <button onClick={onEnter} className="xk-btn-press" style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "11px 20px", background: "#fff", color: accent, border: "none", borderRadius: 10, fontSize: 14.5, fontWeight: 600, cursor: "pointer" }}>
                Entrar al prototipo <Icon name="arrow-right" size={16} />
              </button>
            </div>
          </div>
        </div>

        {/* Outcome */}
        <div className="animate-fade-up" style={{ animationDelay: "0.1s", marginTop: 20, display: "flex", gap: 13, padding: "16px 18px", background: guide.accentTint, borderRadius: 12, border: "1px solid color-mix(in oklab, " + accent + " 22%, transparent)" }}>
          <Icon name="target" size={18} color={accent} style={{ marginTop: 1, flexShrink: 0 }} />
          <div style={{ fontSize: 13.5, lineHeight: 1.55, color: "var(--xk-text)" }}><strong>Qué se logra · </strong>{guide.outcome}</div>
        </div>

        {/* Journey position */}
        <div className="animate-fade-up" style={{ animationDelay: "0.16s", marginTop: 20 }}>
          <Eyebrow>En el flujo de la escuela</Eyebrow>
          <div style={{ display: "flex", alignItems: "stretch", gap: 10 }}>
            <JourneyChip meta={metaPrev} note={prev && prev.note} dir="prev" />
            <div style={{ flexShrink: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: "0 4px" }}>
              <span style={{ width: 44, height: 44, borderRadius: 12, background: accent, color: "#fff", display: "inline-flex", alignItems: "center", justifyContent: "center" }}><Icon name={guide.icon} size={22} color="#fff" /></span>
              <span style={{ fontSize: 10.5, fontWeight: 600, color: accent, marginTop: 5 }}>Estás aquí</span>
            </div>
            <JourneyChip meta={metaNext} note={next && next.note} dir="next" />
          </div>
        </div>

        {/* Internal steps */}
        <div className="animate-fade-up" style={{ animationDelay: "0.22s", marginTop: 20 }}>
          <Eyebrow>Pasos dentro del módulo</Eyebrow>
          {guide.sections && guide.sections.length > 0 ? (
            <div className="no-scrollbar" style={{ display: "flex", alignItems: "stretch", gap: 0, overflowX: "auto", padding: "4px 2px" }}>
              {guide.sections.map((s, i) => (
                <React.Fragment key={i}>
                  <div onClick={() => guide.deepLink && onSection(s.id)} className={guide.deepLink ? "xk-btn-press" : ""} style={{ flex: "0 0 auto", width: 104, textAlign: "center", cursor: guide.deepLink ? "pointer" : "default" }}>
                    <div style={{ width: 52, height: 52, margin: "0 auto", borderRadius: 14, background: guide.accentTint, color: accent, display: "flex", alignItems: "center", justifyContent: "center", border: "1px solid color-mix(in oklab, " + accent + " 22%, transparent)" }}>
                      <Icon name={s.icon} size={23} />
                    </div>
                    <div style={{ fontSize: 11.5, fontWeight: 600, marginTop: 8, lineHeight: 1.25 }}>{s.label}</div>
                  </div>
                  {i < guide.sections.length - 1 && (
                    <div style={{ flex: "0 0 auto", display: "flex", alignItems: "center", paddingTop: 26 }}>
                      <Icon name="chevron-right" size={16} color="var(--xk-text-muted)" />
                    </div>
                  )}
                </React.Fragment>
              ))}
            </div>
          ) : (
            <div style={{ padding: "13px 16px", background: "var(--xk-surface)", border: "1px solid var(--xk-border)", borderRadius: 12, fontSize: 13, color: "var(--xk-text-secondary)", lineHeight: 1.6 }}>
              {guide.internalSteps}
            </div>
          )}
        </div>

        {/* Demo checklist */}
        <div className="animate-fade-up" style={{ animationDelay: "0.28s", marginTop: 20 }}>
          <Eyebrow>Qué notar en la demo</Eyebrow>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {guide.demoChecklist.map((c, i) => (
              <div key={i} style={{ display: "flex", gap: 11, alignItems: "flex-start", padding: "11px 14px", background: "var(--xk-surface)", border: "1px solid var(--xk-border)", borderRadius: 10 }}>
                <span style={{ width: 20, height: 20, borderRadius: 999, background: guide.accentTint, color: accent, display: "inline-flex", alignItems: "center", justifyContent: "center", flexShrink: 0, fontSize: 11, fontWeight: 700, fontFamily: "var(--xk-font-mono)" }}>{i + 1}</span>
                <span style={{ fontSize: 13, lineHeight: 1.5, color: "var(--xk-text)" }}>{c}</span>
              </div>
            ))}
          </div>
        </div>

        {/* Sections (deep-link) */}
        {guide.deepLink && guide.sections.length > 0 && (
          <div className="animate-fade-up" style={{ animationDelay: "0.34s", marginTop: 20 }}>
            <Eyebrow>Saltar a una pantalla</Eyebrow>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              {guide.sections.map((s, i) => (
                <div key={i} onClick={() => onSection(s.id)} className="xk-card-interactive" style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 14px", background: "var(--xk-surface)", border: "1px solid var(--xk-border)", borderRadius: 10, cursor: "pointer" }}>
                  <IconBox icon={s.icon} size={32} bg={guide.accentTint} color={accent} iconSize={16} />
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600 }}>{s.label}</div>
                    <div style={{ fontSize: 11.5, color: "var(--xk-text-muted)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.desc}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        <div style={{ marginTop: 26, textAlign: "center" }}>
          <button onClick={onEnter} className="xk-btn-press" style={{ display: "inline-flex", alignItems: "center", gap: 8, padding: "12px 24px", background: accent, color: "#fff", border: "none", borderRadius: 11, fontSize: 14.5, fontWeight: 600, cursor: "pointer" }}>
            Entrar al prototipo de {guide.title} <Icon name="arrow-right" size={16} color="#fff" />
          </button>
        </div>
      </div>
    </div>
  );
}
function JourneyChip({ meta, note, dir }) {
  if (!meta) return (
    <div style={{ flex: 1, display: "flex", alignItems: "center", justifyContent: "center", padding: "14px", background: "var(--xk-surface-2)", border: "1px dashed var(--xk-border-strong)", borderRadius: 12, fontSize: 12, color: "var(--xk-text-muted)" }}>
      {dir === "prev" ? "Inicio del flujo" : "Fin del flujo"}
    </div>
  );
  return (
    <div style={{ flex: 1, padding: "12px 14px", background: "var(--xk-surface)", border: "1px solid var(--xk-border)", borderRadius: 12 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 10.5, color: "var(--xk-text-muted)", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 5 }}>
        <Icon name={dir === "prev" ? "arrow-left" : "arrow-right"} size={12} />{dir === "prev" ? "Antes" : "Después"}
      </div>
      <div style={{ fontSize: 13, fontWeight: 600 }}>{meta.label}</div>
      {note && <div style={{ fontSize: 11.5, color: "var(--xk-text-secondary)", marginTop: 3, lineHeight: 1.4 }}>{note}</div>}
    </div>
  );
}
window.RoleCover = RoleCover;
