// ============================================================================
// ⚡ AUTOMATIZACIÓN — lo que JARVIS hace SOLO, todos los días, sin que nadie lo pida.
// ----------------------------------------------------------------------------
// POR QUÉ ESTÁ AQUÍ Y NO DENTRO DE CONTENIDO (Danny, 14-ago-2026):
//   «No es un botón, es una función muy completa. Y no solo será esto: los demás
//    departamentos del futuro no irán dentro de contenido y tendrán automatización
//    también, así que hay que hacerle un lugar AISLADO.»
//   → NINGÚN departamento lleva mandos de automatización dentro. Solo esta pestaña.
//
// Y la otra, suya: «lo que uno hace es hablar con el ORQUESTADOR, no con Karen ni
// Atlas» → ningún nombre de agente en los mandos.
//
// 🎨 EL ASPECTO — lo que la hace premium no es el color, es que hay MATERIAL:
//    superficies con gradiente · una línea de luz de 1px en el borde SUPERIOR (eso
//    es lo que hace que un panel parezca material y no un rectángulo dibujado) ·
//    sombras largas que separan capas · esquinas generosas · el acento MUY contenido.
//
// 🏗️ LA FORMA — la corrigió Danny TRES VECES, y cada vez fue el mismo error mío
//    visto desde más lejos: yo diseñaba para el encargo que hay hoy.
//      1ª · la cuenta atrás de UN encargo ocupaba media pantalla → no cabe con cuatro.
//      2ª · pintaba «12:04», que es el formato de un reloj, y se peleaba con la hora
//           que él mismo había programado más abajo.
//      3ª · «ese reloj solo sirve para UNA automatización, y nadie estará pendiente
//           mirándolo» — y ahí estaba el fondo: UNA CUENTA ATRÁS ES UNA PANTALLA PARA
//           ESPERAR, y esto promete justo lo contrario. El reloj contradecía al producto.
//    → Arriba, EL ESTADO DE LA CASA en una frase («Todo marcha, señor» / «Algo se me
//      atascó»): lo único que uno viene a saber al abrir, y vale igual con uno que con
//      diez. Abajo, la rejilla de encargos; la hora de cada uno vive DENTRO de su
//      tarjeta, que es el único sitio donde significa algo.
//      La lección, la misma que la del sitio: **no diseñar para uno, diseñar para muchos.**
//
// 🪦 LO QUE SE QUITÓ Y NO VUELVE — la tira con las láminas de la última pieza.
//    Duró un día. Danny la miró: «se ve raro, siento que no tiene sentido». Y al
//    mirarla de cerca tenía tres fallos, en orden de gravedad al revés:
//      · la leyó como un historial de carruseles, y eran las 5 LÁMINAS DE UNO. Si el
//        dueño del producto la lee mal, un cliente también.
//      · no eran las fotos: eran lienzos de color con el título encima. Ocupaba como
//        una foto sin valer como una foto.
//      · y podía MENTIR: el motor estampa `source: 'ai'` tanto al piloto como al botón
//        «Crear» de Contenido, así que la tira enseñaba la última pieza FUESE DE QUIEN
//        FUESE, bajo un rótulo («entregado a su Telegram») que salía del estado del
//        piloto. Rótulo y contenido podían no ser de lo mismo.
//    Lo que la tira intentaba decir ya lo dice el titular de arriba, en una frase y sin
//    poder mentir. Si algún día vuelve a hacer falta una prueba visual, primero hay que
//    poder distinguir lo que hizo el piloto de lo que hizo el señor a mano.
//
// 🔒 LO QUE ESTA PANTALLA NO HACE, NUNCA: inventarse un dato. Al lado de estos mandos
//    hay un interruptor que publica de verdad en el Instagram del señor. El día que
//    mienta una vez, deja de creerse también el interruptor.
// ============================================================================
(function () {
  const { useState, useEffect } = React;

  const CSS_ID = "enc-css";
  function injectCss() {
    if (document.getElementById(CSS_ID)) return;
    const s = document.createElement("style");
    s.id = CSS_ID;
    s.textContent = `
      /* 🎨 LOS COLORES SON LOS DE LA CASA, y esto lo cazó Danny comparando pantallas:
         «lo veo diferente... usar verdes es más para otro proyecto». Fui a mirar el CSS
         de Mission Control en vez de fiarme de la memoria, y tenía razón por partida
         doble: el acento Y el fondo estaban fuera de sitio.
           · la identidad es CIAN — «--cyan: #00eeff», y #7EE8FF es el color más usado
             de toda la consola (36 apariciones). El ámbar #FFD170 es el segundo.
           · el fondo de la casa es AZUL-negro (#030c17), no el negro neutro que puse.
           · el verde existe, sí, pero como «--state-working»: es ESTADO, no identidad.
         Así que el verde no se va: BAJA a lo que es en el resto de MC — el punto de
         «funcionando». Lo demás pasa a cian.
         📌 Se descartó darle a esta pestaña un color propio (rojo/naranja para
            destacar): rojo y naranja significan PELIGRO en cualquier interfaz, y esta
            pantalla dice «todo marcha» — sería el mismo error que el reloj, la forma
            contradiciendo al mensaje. Y una sección que se inventa su color es como se acaba
            teniendo un producto que parece cuatro productos. Lo que destaca a esta pestaña es
            su estructura, no un color distinto. */
      .enc-wrap { flex:1; display:flex; flex-direction:column; min-width:0; min-height:0;
                  overflow:auto; position:relative; box-sizing:border-box;
                  background:#030c17; color:#EAF6FF;
                  font-family:-apple-system,"SF Pro Display","Segoe UI Variable",system-ui,sans-serif; }
      .enc-aura { position:absolute; top:-500px; left:50%; transform:translateX(-50%);
                  width:1560px; height:960px; pointer-events:none;
                  background:radial-gradient(ellipse at center, rgba(0,238,255,.11), rgba(0,238,255,.028) 40%, transparent 66%);
                  animation:enc-respira 7s ease-in-out infinite; }
      .enc-amb  { position:absolute; inset:0; pointer-events:none;
                  background-image:radial-gradient(circle at 14% 8%, rgba(126,232,255,.055), transparent 40%),
                                   radial-gradient(circle at 88% 82%, rgba(255,209,112,.028), transparent 44%); }
      @keyframes enc-respira { 0%,100%{opacity:.55;transform:translateX(-50%) scale(1);} 50%{opacity:1;transform:translateX(-50%) scale(1.05);} }
      @keyframes enc-latido  { 0%,100%{opacity:.85;} 50%{opacity:.35;} }
      .enc-pulso { animation:enc-latido 2.6s ease-in-out infinite; }
      @media (prefers-reduced-motion: reduce) { .enc-aura, .enc-pulso { animation:none; } }

      .enc-hoja { position:relative; padding:36px clamp(28px,4vw,56px) 40px;
                  display:flex; flex-direction:column; gap:30px; flex:1; min-height:0; }
      .enc-lbl  { font-size:11.5px; font-weight:590; letter-spacing:.055em; color:rgba(235,245,255,.42); }

      .enc-cab { display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; }

      /* EL HÉROE — un TITULAR, no un reloj. El porqué, en el JSX. */
      .enc-heroe { display:flex; flex-direction:column; align-items:center; gap:11px; padding:clamp(16px,3vh,34px) 0 clamp(10px,1.6vh,20px); text-align:center; }
      .enc-titular { font-size:clamp(30px,3.7vw,48px); font-weight:230; letter-spacing:-.035em; line-height:1.1; max-width:22ch;
                     background:linear-gradient(180deg,#ffffff 16%,rgba(126,232,255,.52) 112%);
                     -webkit-background-clip:text; background-clip:text; color:transparent; }
      .enc-titular.apagado { background:linear-gradient(180deg,rgba(234,246,255,.45) 16%,rgba(234,246,255,.15) 112%);
                             -webkit-background-clip:text; background-clip:text; }
      .enc-titular.malo { background:linear-gradient(180deg,#ffd7ac 16%,rgba(255,164,112,.55) 112%);
                          -webkit-background-clip:text; background-clip:text; }
      .enc-quien { font-size:14.5px; line-height:1.55; color:rgba(235,245,255,.5); max-width:44ch; }

      /* LA REJILLA — hoy un encargo, mañana los que hagan falta. */
      .enc-rejilla { display:grid; gap:20px; grid-template-columns:repeat(auto-fit,minmax(430px,1fr)); align-items:start; }
      @media (max-width: 720px) { .enc-rejilla { grid-template-columns:1fr; } }

      .enc-card { border-radius:22px; overflow:hidden; display:flex; flex-direction:column;
                  background:linear-gradient(180deg,rgba(255,255,255,.062),rgba(255,255,255,.022));
                  border:1px solid rgba(255,255,255,.085);
                  box-shadow:inset 0 1px 0 rgba(255,255,255,.10), 0 30px 70px -28px rgba(0,0,0,.95); }
      .enc-card-cab { display:flex; align-items:center; gap:13px; padding:22px 26px 0; }
      .enc-card-cuerpo { padding:20px 26px 24px; display:flex; flex-direction:column; gap:20px; }
      .enc-proximo { border-color:rgba(79,216,255,.26); }
      /* El distintivo de cada tarjeta. Pequeño a propósito: informa, no compite con
         el título. Verde = --state-working, igual que en el resto de Mission Control. */
      .enc-estado { flex:none; align-self:flex-start; display:flex; align-items:center; gap:7px;
                    padding:5px 11px 5px 9px; border-radius:999px; font-size:11.5px; font-weight:590;
                    color:#7dffcd; background:rgba(0,255,157,.09); border:1px solid rgba(0,255,157,.20); }
      .enc-estado.off { color:rgba(234,246,255,.45); background:rgba(255,255,255,.04); border-color:rgba(255,255,255,.08); }

      .enc-futuro { border-radius:22px; border:1px dashed rgba(255,255,255,.10); background:rgba(255,255,255,.012);
                    min-height:190px; display:flex; flex-direction:column; align-items:center; justify-content:center;
                    gap:10px; padding:26px; text-align:center; }

      .enc-icono { width:36px; height:36px; border-radius:11px; display:flex; align-items:center; justify-content:center; flex:none;
                   background:linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,.035));
                   border:1px solid rgba(255,255,255,.09); box-shadow:inset 0 1px 0 rgba(255,255,255,.13); }

      .enc-seg { display:flex; gap:5px; padding:3px; border-radius:11px; background:rgba(0,0,0,.28);
                 border:1px solid rgba(255,255,255,.055); box-shadow:inset 0 1px 3px rgba(0,0,0,.5); }
      .enc-seg button { font:inherit; font-size:13px; padding:6px 14px; border-radius:8px; border:none; cursor:pointer;
                        background:none; color:rgba(235,245,255,.42); transition:color .15s; }
      .enc-seg button:hover:not(.on) { color:rgba(235,245,255,.7); }
      .enc-seg button.on { font-weight:600; color:#032430;
                           background:linear-gradient(180deg,#7EE8FF,#4FD8FF);
                           box-shadow:0 2px 9px rgba(79,216,255,.32), inset 0 1px 0 rgba(255,255,255,.32); }
      .enc-seg button:disabled { cursor:default; }

      .enc-hora { font:inherit; font-size:25px; font-weight:300; letter-spacing:-.03em; font-variant-numeric:tabular-nums;
                  background:none; border:none; color:#f2f6fb; padding:0; cursor:pointer; }
      .enc-hora::-webkit-calendar-picker-indicator { filter:invert(1); opacity:.35; cursor:pointer; }

      .enc-btn { font:inherit; font-size:13.5px; font-weight:550; padding:11px 18px; border-radius:11px; cursor:pointer;
                 background:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,.05));
                 border:1px solid rgba(255,255,255,.10); color:#eaf3ff;
                 box-shadow:inset 0 1px 0 rgba(255,255,255,.13); transition:filter .15s; }
      .enc-btn:hover { filter:brightness(1.18); }
      .enc-btn.go { background:linear-gradient(180deg,#7EE8FF,#4FD8FF); border:none; color:#032430; font-weight:650;
                    box-shadow:0 4px 16px rgba(79,216,255,.30), inset 0 1px 0 rgba(255,255,255,.34); }
      .enc-btn.quieto { background:none; border:1px solid rgba(255,255,255,.07); color:rgba(255,150,150,.82); font-weight:500; box-shadow:none; }
      .enc-btn:disabled { opacity:.5; cursor:default; filter:none; }

      /* ⚠️ EL AMARILLO SE SUBIÓ. Estaba a .055 de fondo y .15 de borde: se veía apagado,
         y un aviso apagado es un aviso que nadie lee. Danny: «ese amarillo muy opaco».
         El texto también: iba en gris azulado (.6) sobre ámbar — ahora va en un blanco
         cálido, que es lo que se lee sin esfuerzo dentro de una caja de color. */
      .enc-aviso { display:flex; gap:11px; align-items:flex-start; padding:13px 15px; border-radius:13px;
                   background:rgba(255,196,74,.10); border:1px solid rgba(255,196,74,.30);
                   font-size:13px; line-height:1.6; color:rgba(255,243,224,.8); }
      .enc-aviso.malo { background:rgba(255,110,110,.06); border-color:rgba(255,110,110,.18); }
      .enc-empty { font-size:13.5px; color:rgba(235,245,255,.45); padding:40px 56px; }
      .enc-pie { display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap;
                 font-size:12.5px; color:rgba(235,245,255,.32); }
    `;
    document.head.appendChild(s);
  }

  // ⏳ Cuántos minutos faltan para esa hora HOY, en la zona del señor. Devuelve un
  //    número negativo si ya pasó (eso significa «mañana a esa hora», que vale).
  //    Se lee con Intl y no con getHours(): el navegador puede estar en otra zona que
  //    la que él eligió, y entonces frenaríamos una hora que sí le daba tiempo.
  function minutosHasta(hora, tz) {
    try {
      const m = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(String(hora || ""));
      if (!m) return null;
      const f = new Intl.DateTimeFormat("en-CA", { timeZone: tz || undefined, hour12: false, hour: "2-digit", minute: "2-digit" });
      const p = {};
      for (const x of f.formatToParts(new Date())) p[x.type] = x.value;
      return ((+m[1]) * 60 + (+m[2])) - ((+p.hour) * 60 + (+p.minute));
    } catch (e) { return null; }
  }

  // 1=lunes … 7=domingo — el mismo número que cuenta el reloj del servidor. La X del
  // miércoles es la convención que la gente ya sabe leer; el nombre entero va aparte.
  const DIAS = [
    ["1", "L", "lunes"], ["2", "M", "martes"], ["3", "X", "miércoles"], ["4", "J", "jueves"],
    ["5", "V", "viernes"], ["6", "S", "sábado"], ["7", "D", "domingo"],
  ];

  // Un texto para el día en que corrió, en su idioma y no en el del ordenador.
  function diaEnPalabras(iso) {
    if (!iso) return "";
    try {
      const hoy = new Date();
      const p = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
      if (p(hoy) === iso) return "hoy";
      const ayer = new Date(hoy.getTime() - 86400000);
      if (p(ayer) === iso) return "ayer";
      const [a, m, d] = iso.split("-");
      const MES = ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"];
      return d + "-" + (MES[parseInt(m, 10) - 1] || m);
    } catch (e) { return iso; }
  }

  function Marca({ d, s }) {
    return (
      <svg width={s || 18} height={s || 18} viewBox="0 0 24 24" fill="none" stroke="currentColor"
           strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">{d}</svg>
    );
  }
  const AVISO_D = (
    <React.Fragment>
      <path d="M12 9.5v4"></path><path d="M12 17.2h.01"></path>
      <path d="M10.3 4.2 2.6 17.9a1.9 1.9 0 0 0 1.7 2.8h15.4a1.9 1.9 0 0 0 1.7-2.8L13.7 4.2a1.9 1.9 0 0 0-3.4 0Z"></path>
    </React.Fragment>
  );
  const CAL_D = (
    <React.Fragment>
      <rect x="3.5" y="5" width="17" height="15" rx="3"></rect><path d="M3.5 10h17"></path>
      <path d="M8.5 2.5v4"></path><path d="M15.5 2.5v4"></path>
    </React.Fragment>
  );

  function EncargosApp() {
    const [pil, setPil] = useState(null);
    const [ocupado, setOcupado] = useState(false);
    const [msg, setMsg] = useState("");
    const [llaves, setLlaves] = useState(false);
    const [tgOk, setTgOk] = useState(false);
    const [cargando, setCargando] = useState(true);

    useEffect(function () {
      let vivo = true;
      Promise.all([
        window.MCNet.piloto().catch(function () { return null; }),
        window.MCNet.autoLlave().catch(function () { return null; }),
        window.MCNet.tgEstado().catch(function () { return null; }),
      ]).then(function (r) {
        if (!vivo) return;
        if (r[0] && r[0].ok) setPil(r[0].piloto);
        if (r[1] && r[1].ok) setLlaves(!!(r[1].tiene && r[1].tieneCf));
        if (r[2] && r[2].ok) setTgOk(!!r[2].enlazado);
        setCargando(false);
      });
      return function () { vivo = false; };
    }, []);

    // 🔑 AL ENCENDER, LAS LLAVES SE COPIAN SOLAS. No hay botón, no hay pregunta.
    //    Danny, 14-ago: «nadie va a estar poniendo de nuevo sus llaves... eso hace todo
    //    más largo e incluso más fastidioso». Y es exacto: NO son otras llaves, son LAS
    //    MISMAS que ya puso al entrar. Lo único que pasa es que a las 22:00 su navegador
    //    está cerrado y no hay quien las mande, así que el servidor necesita una copia
    //    cifrada. Eso es fontanería nuestra, no una decisión suya.
    const copiarLlavesSiFaltan = function () {
      if (llaves) return Promise.resolve(true);
      const L = (window.MCNet.llavesLocales && window.MCNet.llavesLocales()) || {};
      const van = [];
      if (L.llave) van.push(window.MCNet.setAutoLlave(L.proveedor, L.llave));
      if (L.cfToken && L.cfAccount) van.push(window.MCNet.setAutoLlave(null, null, L.cfToken, L.cfAccount));
      if (!van.length) return Promise.resolve(false);
      return Promise.all(van).catch(function () {})
        .then(function () { return window.MCNet.autoLlave(); })
        .then(function (e) { const ok = !!(e && e.ok && e.tiene && e.tieneCf); setLlaves(ok); return ok; })
        .catch(function () { return false; });
    };

    const guardar = function (cambio) {
      setMsg(""); setOcupado(true);
      // Encender es UN gesto: si le faltan las llaves, se copian aquí mismo. Un
      // encargo encendido que no puede trabajar no es un encargo, es una trampa.
      if (cambio.activa === true && !llaves) {
        return copiarLlavesSiFaltan().then(function (ok) {
          setOcupado(false);
          if (!ok) { setMsg('no encuentro sus llaves en este navegador. Póngalas en JARVIS y vuelva.'); return; }
          guardar(cambio);
        });
      }
      // La zona horaria va SIEMPRE la del navegador: «las 22:00» tienen que ser las
      // suyas. El servidor vive en UTC, y sin esto alguien fuera de Perú vería llegar
      // su carrusel a una hora que no eligió, sin entender por qué.
      let tz = pil && pil.tz; try { tz = Intl.DateTimeFormat().resolvedOptions().timeZone || tz; } catch (e) {}
      window.MCNet.setPiloto(Object.assign({ tz: tz }, cambio))
        .then(function (r) {
          if (r && r.ok && r.piloto) {
            setPil(r.piloto);
            // 📓 Queda escrito en el registro de la casa — y es VERDAD, que es la única
            //    razón por la que puede estar ahí. Se verá en Vista de equipo.
            if (cambio.activa !== undefined) {
              try {
                window.MissionState && window.MissionState.addLog({
                  source: "JARVIS", type: "ENCARGO", severity: "low",
                  message: cambio.activa
                    ? "Encargo aceptado: un carrusel al día a las " + r.piloto.hora + "."
                    : "Encargo retirado: el carrusel diario queda detenido.",
                });
              } catch (e) {}
            }
            return;
          }
          const m = { 'canary_only': 'todavía no está abierto en su cuenta',
                      'no-account': 'su sesión no se reconoce',
                      'db': 'no se pudo guardar ahora mismo' };
          setMsg((m[r && r.reason] || 'no se pudo guardar') + '.');
        })
        .catch(function () { setMsg('no se pudo guardar.'); })
        .then(function () { setOcupado(false); });
    };

    if (cargando) return <div className="enc-wrap"><div className="enc-empty">Un momento, señor…</div></div>;
    if (!pil) return <div className="enc-wrap"><div className="enc-empty">No he podido leer sus automatizaciones, señor. Recargue la página.</div></div>;

    const on = !!pil.activa;
    const firma = pil.modo !== "auto";

    // 📅 Los días en que trabaja. 1=lunes … 7=domingo, la misma cuenta que usa el reloj
    //    del servidor (`_mcPilotoAhoraLocal`). Sin fila guardada, todos.
    const dias = String(pil.dias || "1,2,3,4,5,6,7").split(",").filter(Boolean);
    const todosLosDias = dias.length === 7;
    const alternarDia = function (n) {
      const puesto = dias.indexOf(n) >= 0;
      // 🔒 NUNCA CERO DÍAS. Sin ningún día no es «pausado»: es una automatización
      //    encendida, con su punto verde latiendo, que no va a trabajar nunca. Eso es
      //    peor que estar apagada, porque miente. Si quiere pararlo, existe «Detener».
      if (puesto && dias.length === 1) { setMsg("__undia__"); return; }
      const nuevos = puesto ? dias.filter(function (d) { return d !== n; }) : dias.concat([n]);
      nuevos.sort();
      setMsg("");
      guardar({ dias: nuevos.join(",") });
    };
    // 🗂️ LOS ENCARGOS, EN LISTA — y esto es a propósito aunque hoy solo haya UNO.
    //    Danny: «¿y si tenemos 3 o 4 automatizaciones? ¿saldrían ahí también, o solo
    //    está pensado para 1?». Estaba pensado para uno, sí — ese ha sido mi error en
    //    esta pantalla tres veces seguidas. Ahora la pantalla YA NO SABE CUÁNTOS HAY:
    //    los pinta recorriendo esta lista y los cuenta. El día que llegue el encargo
    //    del segundo departamento es AÑADIR UN DATO AQUÍ, no rediseñar una pantalla.
    //
    //    ⚠️ Lo que todavía NO escala, y hay que saberlo: la base. `mc_piloto` guarda
    //    UNA fila por usuario (`onConflict: 'user_id'`), así que el servidor aún no
    //    puede sostener dos encargos. Eso se abre el día que exista el segundo y
    //    sepamos qué forma tiene — inventarme hoy su forma sería adivinar, y adivinar
    //    la forma de algo que no existe es como se llega a una tabla que no sirve.
    //    Lo que sí nació preparado: el reloj de la casa ya recorre TODAS las filas
    //    activas (`.eq('activa', true)`), no solo la de uno.
    function cuerpoCarrusel() {
      return (
        <React.Fragment>
      {!tgOk ? (
        <div className="enc-aviso">
          <span style={{ color: "#ffd166", flex: "none", marginTop: 1 }}><Marca d={AVISO_D} s={16} /></span>
          <div>Para automatizar esto, señor, primero tiene que conectarme a su móvil. Se hace en <b>Contenido</b>, con el botón «📮 Conectar mi JARVIS al móvil».</div>
        </div>
      ) : (
        <React.Fragment>
          <div style={{ display: "flex", gap: 26, alignItems: "flex-end", flexWrap: "wrap" }}>
            <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
              <div className="enc-lbl">A las</div>
              {/* 🚧 NO SE ACEPTA UNA HORA A MENOS DE 5 MINUTOS, y lo pidió Danny con el
                  caso de uso exacto: «muchos pueden poner 1 o 2 minutos después; mejor
                  decirle que la hora mínima tiene que ser 5 minutos después, así evitamos
                  problemas de usuarios que quieren rápido y no les funcione».
                  Tiene razón y no es un capricho: escribir y dibujar cuesta ~3 minutos
                  medidos. Con 2 de margen la pieza sale TARDE — y esta pantalla acaba de
                  prometer «a las 22:00 en punto». Aceptar una hora imposible es prometer
                  algo que no se puede cumplir, y el usuario no culpa a su prisa: culpa al
                  sistema, lo apaga y no vuelve.
                  📌 Cuando una entrada lleva a un resultado que no podemos cumplir, se
                     rechaza EN EL MOMENTO y se dice por qué. Aceptarla en silencio no es
                     ser flexible: es aplazar el fallo hasta que ya no se pueda explicar. */}
              <input className="enc-hora" type="time" value={pil.hora} disabled={ocupado}
                onChange={function (e) {
                  const v = e.target.value;
                  if (!/^([01]\d|2[0-3]):[0-5]\d$/.test(v)) return;
                  const falta = minutosHasta(v, pil.tz);
                  // Solo se frena la ventana de AHORA: una hora ya pasada significa
                  // «mañana a esa hora», y eso es perfectamente válido.
                  if (falta !== null && falta >= 0 && falta < 5) {
                    setMsg("__pronto__");
                    return;
                  }
                  setMsg("");
                  guardar({ hora: v });
                }} />
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
              <div className="enc-lbl">Al día</div>
              <div className="enc-seg">
                <button type="button" className={pil.piezas_dia < 2 ? "on" : ""} disabled={ocupado} onClick={function () { setMsg(""); guardar({ piezas_dia: 1 }); }}>1</button>
                <button type="button" className={pil.piezas_dia > 1 ? "on" : ""} disabled={ocupado} onClick={function () { guardar({ piezas_dia: 2 }); }}>2</button>
              </div>
              {/* 🔵 CON DOS PIEZAS, LAS DOS LLEGAN A LA MISMA HORA — y se DICE.
                  Danny propuso una hora distinta para cada una (y hora por día). Se
                  aplazó a propósito: la automatización todavía no ha corrido ni un día
                  completo sin nadie delante, así que una segunda hora sería construir
                  para un uso que aún no ha ocurrido. Cuando una semana real diga que
                  hace falta, se hace con un dato en la mano y no con una suposición.
                  📌 Pero lo que NO se puede hacer es dejar un botón que sorprenda. Si
                     hoy no vamos a cambiarlo, que al menos no engañe: es la misma regla
                     del aviso de las cifras. Una limitación dicha es una decisión; una
                     limitación callada es un fallo esperando a que alguien lo encuentre. */}
              {pil.piezas_dia > 1 ? (
                <div style={{ fontSize: 11.5, lineHeight: 1.45, color: "rgba(235,245,255,.38)", maxWidth: "26ch" }}>
                  Las dos le llegarán juntas, a esta misma hora.
                </div>
              ) : null}
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
              <div className="enc-lbl">Entrega</div>
              <div className="enc-seg">
                <button type="button" className={firma ? "on" : ""} disabled={ocupado} onClick={function () { setMsg(""); guardar({ modo: "firma" }); }}>Con mi firma</button>
                <button type="button" className={!firma ? "on" : ""} disabled={ocupado} onClick={function () { if (firma) setMsg("__auto__"); }}>Sin revisión</button>
              </div>
            </div>

            {/* 📅 LOS DÍAS. Lo cazó Danny el 18-ago: «la automatización es más un tema de
                hora Y FECHA; las personas deben seleccionar qué días quieren que salga...
                eso nos faltó hacer».
                Y lo raro del caso: el MOTOR ya los tenía desde el principio —
                `_mcPilotoToca` respeta `cfg.dias` y hay pruebas de «solo entre semana, y
                es sábado» — y el servidor ya los validaba al guardar. Lo único que no
                existía era el mando. O sea: la función estaba construida, probada y
                DESPLEGADA, y ningún usuario podía llegar a ella.
                📌 Una capacidad sin mando en la pantalla no existe para el usuario. Ese
                   tipo de hueco no lo encuentra una prueba —todas pasaban— ni se ve
                   leyendo el servidor: se ve cuando alguien intenta USAR el producto.
                Se usa L·M·X·J·V·S·D con la X del miércoles, que es lo que la gente ya
                sabe leer; el nombre entero va en el `title` para quien dude. */}
            <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
              <div style={{ display: "flex", alignItems: "baseline", gap: 9 }}>
                <div className="enc-lbl">Días</div>
                {!todosLosDias ? (
                  <button type="button" disabled={ocupado}
                    style={{ font: "inherit", fontSize: 11, background: "none", border: "none", padding: 0,
                             color: "rgba(126,232,255,.7)", cursor: "pointer" }}
                    onClick={function () { setMsg(""); guardar({ dias: "1,2,3,4,5,6,7" }); }}>todos</button>
                ) : null}
              </div>
              <div className="enc-seg">
                {DIAS.map(function (d) {
                  return (
                    <button type="button" key={d[0]} title={d[2]} disabled={ocupado}
                      className={dias.indexOf(d[0]) >= 0 ? "on" : ""}
                      onClick={function () { alternarDia(d[0]); }}>{d[1]}</button>
                  );
                })}
              </div>
            </div>
          </div>

          {/* ⏱️ LA HORA ES CUÁNDO EMPIEZO, NO CUÁNDO LLEGA — y no lo decía en ningún
              sitio. Lo cazó Danny mientras esperábamos la primera prueba:
              «puede pensar que a esa hora saldrá... y de la nada a las 11:49 le llega.
               Puede decir "está fallando" y lo apaga».
              Tenía razón, y es un fallo conceptual mío, no un aviso que faltaba: yo
              llamé «A las» a un campo que es una hora de ARRANQUE y dejé que se leyera
              como una hora de ENTREGA. Dos cosas suman ahí, y ninguna se ve:
                · el reloj de la casa mira cada 5 min y su vuelta no está alineada con
                  la hora del señor → hasta 5 min antes siquiera de empezar.
                · escribir la pieza y dibujar sus 5 láminas lleva otro par de minutos.
              📌 Cuando algo tarda, decir cuánto NO es una excusa: es lo que evita que
                 el usuario apague una cosa que estaba funcionando bien. El silencio
                 durante la espera es lo que se lee como avería.

              ⏱️ Y LA HORA SE CUMPLE AL MINUTO, DESDE EL 18-AGO. Antes esto decía «unos 3
                 minutos después» — medido, sí, pero era una disculpa. Danny propuso lo
                 correcto: «que empiece a las 5:50 y cuando lo tenga listo se espere a que
                 lleguen las 6 en punto, así cumple con lo que él puso». Y hay una razón de
                 negocio: la hora a la que se publica en Instagram AFECTA AL ALCANCE — si
                 eligió las 6:00 porque ahí está su gente, las 6:05 no es lo mismo.
                 La jornada quedó partida en dos fases, y las dos viven en la BASE:
                   A · a las (hora − 10 min): escribe y dibuja. No entrega.
                   B · cuando llegan las (hora): entrega o publica, en punto.
                 Medido: 2 min 55 s de faena (~20 s por lámina), así que 10 de adelanto
                 sobran. Tarde puede salir si la faena se alarga; ANTES de su hora, nunca.
                 Detalle y el SQL: docs/sql/mc_piloto_puntual.sql */}
          {on ? (
            <div style={{ fontSize: 12.5, lineHeight: 1.5, color: "rgba(235,245,255,.42)", marginTop: -8 }}>
              Le llegará a su Telegram <b style={{ color: "rgba(235,245,255,.7)", fontWeight: 600 }}>a las {pil.hora} en punto</b>.
              {" "}Empiezo diez minutos antes para tenerlo listo a su hora, no unos minutos después.
            </div>
          ) : null}

          {/* ⚠️ EL AVISO EN EL MOMENTO DE MOVER EL INTERRUPTOR — condición de Danny:
              «cuando ponga la opción sin revisión, que se le avise ahí mismo». Se dice
              lo único que de verdad cambia: quién responde de lo que sale con su cara. */}
          {msg === "__auto__" && firma ? (
            <div className="enc-aviso" style={{ flexDirection: "column", gap: 12 }}>
              {/* ✍️ EL TEXTO SE REESCRIBIÓ. Danny: «inicia muy bien, pero lo que dice
                  adelante es muy complejo, hasta me confunde». Y era verdad: arrancaba
                  concreto («sin que usted lo vea antes») y seguía con «la calidad de lo
                  que salga con su nombre pasa a ser cosa suya» — una frase de contrato,
                  abstracta, en el sitio exacto donde hace falta que se entienda.
                  📌 Un aviso no se hace más serio con lenguaje más formal: se hace más
                     serio contando lo que va a PASAR. Una línea, una consecuencia. */}
              <div>
                <b style={{ color: "#ffd166" }}>Se publicará en su Instagram sin que usted lo vea antes.</b>
                <br />Si un carrusel sale mal, saldrá igual — y lo verá ya publicado.
                <br />Lo único que no haré solo: si trae un número que no puedo comprobar, <b>me paro y le pregunto</b>.
              </div>
              <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                <button type="button" className="enc-btn" disabled={ocupado}
                  onClick={function () { setMsg(""); guardar({ modo: "auto" }); }}>Entendido, que publique solo</button>
                <button type="button" className="enc-btn quieto" style={{ color: "rgba(235,245,255,.6)" }}
                  onClick={function () { setMsg(""); }}>Mejor con mi firma</button>
              </div>
            </div>
          ) : null}

          {/* ⚠️→ LA LETRA PEQUEÑA, SOLO DONDE ES LETRA PEQUEÑA.
              Aquí había un aviso amarillo FIJO sobre el freno de las cifras. Danny:
              «¿qué importancia tiene si la gente solo viene y pone la hora? ¿esa nota
              hará que yo modifique algo?». No: no cambiaba ninguna decisión suya.
              Y por modos se ve por qué. En «Con mi firma» JARVIS ya le pregunta por
              TODO, así que prometerle que preguntará ante un número raro no informa de
              nada — es ruido. Solo significa algo en «Sin revisión», donde es la
              excepción a lo que usted acaba de autorizar. Encima ya se lo decimos en el
              momento que manda: en el aviso de mover el interruptor, ahí arriba.
              📌 Un aviso permanente que no cambia ninguna decisión no protege a nadie:
                 enseña a no leer los avisos. Y en esta pantalla hay avisos que SÍ. */}
          {!firma ? (
            <div style={{ fontSize: 12.5, lineHeight: 1.5, color: "rgba(235,245,255,.42)" }}>
              Publico solo, sí — <b style={{ color: "rgba(235,245,255,.72)", fontWeight: 600 }}>salvo si una pieza
              trae un número que no pueda comprobar</b>. Ese se lo mando y le pregunto antes.
            </div>
          ) : null}

          {/* ♻️🤝 CUANDO NO HAYA TEMA NUEVO — el mando del reciclaje (25-ago-2026).
              Vive DENTRO de «Sin revisión» a propósito: al que entrega con firma ya le pasa
              todo por delante, así que enseñárselo sería un mando sin capacidad detrás.
              🩹 14-sep: aquí ponía «el defecto es FIRMA», y es FALSO desde el 28-ago: quien eligió
              automático ya dio permiso, así que sin respuesta las retomadas SALEN SOLAS con aviso
              (`_mcRecicladoAuto` en server.js). Solo un «firma» explícito las manda a firmar.
              Y el botón marcado mentía igual: sin elegir, pintaba «Que pasen por mi firma». */}
          {!firma ? (
            <div style={{ display: "flex", flexDirection: "column", gap: 7, marginTop: 2 }}>
              <div className="enc-lbl">Cuando no haya tema nuevo</div>
              <div style={{ fontSize: 12.5, lineHeight: 1.5, color: "rgba(235,245,255,.42)", marginBottom: 2 }}>
                A veces ya se ha contado todo lo que hay en su nicho. Cuando pase, retomo un tema
                anterior y lo cuento desde otro enfoque. <b style={{ color: "rgba(235,245,255,.72)", fontWeight: 600 }}>Siempre
                irán señaladas como retomadas.</b>
              </div>
              <div className="enc-seg">
                <button type="button" className={pil.reciclado_modo !== "firma" ? "on" : ""} disabled={ocupado}
                        onClick={function () { setMsg(""); guardar({ reciclado_modo: "auto" }); }}>Que salgan solas</button>
                <button type="button" className={pil.reciclado_modo === "firma" ? "on" : ""} disabled={ocupado}
                        onClick={function () { setMsg(""); guardar({ reciclado_modo: "firma" }); }}>Que pasen por mi firma</button>
              </div>
            </div>
          ) : null}

          {/* La hora demasiado pronto no es un ERROR del sistema, así que no se pinta
              como uno: se explica el porqué y se dice qué hacer. Y se dice el número —
              «al menos 5 minutos» — porque «más tarde» no le dice a nadie cuánto. */}
          {msg === "__pronto__" ? (
            <div className="enc-aviso">
              <span style={{ color: "#ffd166", flex: "none", marginTop: 1 }}><Marca d={AVISO_D} s={16} /></span>
              {/* ✍️ SIN NÚMEROS SOBRE MÍ MISMO. La primera versión decía «dibujar sus CINCO
                  láminas me lleva unos TRES minutos». Danny cortó las dos cosas:
                    · «¿tú cómo sabes que son 5? Quizás sean 4 o más» — estaba a fuego, y
                      los carruseles no siempre traen cinco.
                    · «si dices 3 minutos, entonces si demora va a decir el usuario...» —
                      exacto: eso es una PREDICCIÓN sobre mí, y las predicciones sobre uno
                      mismo se incumplen.
                  📌 Los 5 minutos sí se dicen, y la diferencia es toda: es una REGLA QUE
                     YO HAGO CUMPLIR, no una promesa sobre mi velocidad. Decir lo que se
                     controla, callar lo que se estima. */}
              <div>
                Esa hora es demasiado pronto, señor. Necesito un rato para prepararle el carrusel,
                así que <b style={{ color: "#ffd166" }}>póngala al menos 5 minutos más tarde</b> y se lo
                entregaré a la hora exacta. La de ahora sigue guardada.
              </div>
            </div>
          ) : null}

          {msg === "__undia__" ? (
            <div className="enc-aviso">
              <span style={{ color: "#ffd166", flex: "none", marginTop: 1 }}><Marca d={AVISO_D} s={16} /></span>
              <div>
                Tiene que quedarme <b style={{ color: "#ffd166" }}>al menos un día</b>, señor. Sin ninguno esto
                seguiría encendido sin trabajar nunca — si quiere pararlo, use «Detener».
              </div>
            </div>
          ) : null}

          {msg && msg !== "__auto__" && msg !== "__pronto__" && msg !== "__undia__" ? (
            <div className="enc-aviso malo"><div>No se guardó: {msg}</div></div>
          ) : null}

          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
            {/* 🔢 SIN NÚMERO, Y A PROPÓSITO. Aquí ponía «N piezas revisadas», pero esa N
                salía de las 30 últimas que pide el navegador — mientras el servidor
                compara de verdad contra hasta 1.000. El número era MENOR que la verdad
                y aun así sonaba a dato duro. Una cifra que no se puede sostener no se
                redondea: se quita. */}
            <div style={{ fontSize: 12.5, color: "rgba(235,245,255,.4)", maxWidth: "34ch" }}>
              Reviso lo que ya le he escrito antes de elegir el tema, para no repetirle una idea
            </div>
            {/* 🗣️ EL VERBO DE ESTA PANTALLA ES «AUTOMATIZAR», NO «ENCARGAR».
                Danny: «se supone que todo esto es automatización, no debería decir
                automatizar o algo parecido... y lo que dice arriba, encargo, se ve raro».
                Tenía razón: la pestaña promete AUTOMATIZACIÓN y por dentro yo hablaba de
                «encargos» — vocabulario de mayordomo de otra época, bonito y ajeno.
                📌 La palabra del botón tiene que ser la misma que la del sitio donde está.
                   Si el usuario tiene que traducir, la pantalla ya le está costando.
                (Por dentro, el archivo y las rutas siguen llamándose `encargos`: eso es
                 nuestro, y renombrarlo solo movería riesgo sin mover nada que se vea.) */}
            <button type="button" className={"enc-btn" + (on ? " quieto" : " go")} disabled={ocupado}
              onClick={function () { guardar({ activa: !on }); }}>
              {ocupado ? "…" : on ? "Detener" : "Automatizar"}
            </button>
          </div>
        </React.Fragment>
      )}
        </React.Fragment>
      );
    }

    const encargos = [
      {
        id: "carrusel",
        titulo: "Su carrusel diario",
        sub: "Contenido · JARVIS elige el tema, lo escribe y lo dibuja",
        icono: CAL_D,
        activa: on,
        listo: tgOk,            // ¿tiene ya lo que necesita para poder trabajar?
        firma: firma,
        hora: pil.hora,
        dia: pil.ultimo_dia,
        error: pil.ultimo_error,
        cuerpo: cuerpoCarrusel,
      },
    ];

    // 📣 EL ESTADO DE LA CASA EN UNA FRASE — CONTADA, no escrita a mano. Ni un dato
    //    inventado: todo sale de lo que el servidor dice que pasó, y si no ha pasado
    //    nada todavía, lo dice.
    const enServicio = encargos.filter(function (e) { return e.activa; });
    const atascado = enServicio.filter(function (e) { return e.error; })[0];
    const entregados = enServicio.filter(function (e) { return e.dia; })
      .sort(function (a, b) { return String(b.dia).localeCompare(String(a.dia)); });
    const sinPoder = encargos.filter(function (e) { return !e.listo; });
    const cuenta = enServicio.length + (enServicio.length === 1 ? " automatización en servicio" : " automatizaciones en servicio");
    let titular, bajada;
    if (sinPoder.length === encargos.length) {
      titular = "Aún no puedo trabajarle";
      bajada = "Conécteme a su móvil desde Contenido y podré encargarme de esto solo.";
    } else if (!enServicio.length) {
      titular = "Nada automatizado todavía";
      bajada = "Automatice su carrusel y lo haré cada día, a su hora, sin que tenga que pedírmelo.";
    } else if (atascado) {
      titular = "Algo se me atascó";
      bajada = "No pude terminar " + (atascado.dia ? "lo de " + diaEnPalabras(atascado.dia) : "lo último que tenía que hacer") +
               " en «" + atascado.titulo.toLowerCase() + "»: " + atascado.error + ". Volveré a intentarlo a su hora.";
    } else if (entregados.length) {
      titular = "Todo marcha, señor";
      bajada = cuenta + ". Lo último se lo entregué " + diaEnPalabras(entregados[0].dia) +
               " a su Telegram" + (entregados[0].firma ? ", esperando su firma." : ".");
    } else {
      titular = "Listo, ya queda automatizado";
      bajada = cuenta + ". La primera entrega será a las " + enServicio[0].hora + ", en su Telegram.";
    }

    return (
      <div className="enc-wrap">
        <div className="enc-aura"></div>
        <div className="enc-amb"></div>

        <div className="enc-hoja">

          <div className="enc-cab">
            <div className="enc-lbl">Automatización</div>
            {/* 🚫 AQUÍ HABÍA UNA PÍLDORA GLOBAL que decía «Funcionando». Se quitó, y el
                argumento es de Danny, textual: «imagina que tenemos 5 y de las 5 solo
                esta funciona, las otras 4 están sin funcionar: eso dirá que todo está
                funcionando». Exacto — un estado que resume varias cosas distintas en una
                palabra acaba mintiendo sobre casi todas.
                📌 EL ESTADO NO SE RESUME: se dice en cada cosa que lo tiene. Cada tarjeta
                   lleva el suyo («Funcionando» con el punto latiendo / «Detenida»), y lo
                   único que sí se puede resumir sin mentir es una CUENTA — y esa ya la
                   dice el titular: «3 automatizaciones en servicio».
                Es el tercer error de la misma familia en esta pantalla (el reloj, la
                cuenta atrás, esto): poner en el centro algo que solo vale para una. */}
          </div>

          {/* ⭐ EL HÉROE NO ES UN RELOJ — lo corrigió Danny mirando la versión que ya
              tenía delante: «ese reloj solo sirve para UNA automatización, y nadie
              estará pendiente mirándolo».
              Y tenía razón por debajo del formato: UNA CUENTA ATRÁS ES UNA PANTALLA
              PARA ESPERAR, y lo que esta función promete es justo que NO hay que
              esperar. Un reloj gigante contradecía el producto — además de no caber
              el día que haya cuatro encargos, cada uno con su hora.
              → Lo que sí quiere saber al abrir: ¿marcha todo, o hay algo atascado?
                Eso cabe en una frase, vale igual con uno que con diez, y es lo único
                que justifica ocupar la parte alta de la pantalla. La hora de cada
                encargo vive DENTRO de su tarjeta, que es donde significa algo. */}
          <div className="enc-heroe">
            <div className={"enc-titular" + (enServicio.length ? (atascado ? " malo" : "") : " apagado")}>{titular}</div>
            <div className="enc-quien">{bajada}</div>
          </div>

          {/* LA REJILLA — se RECORRE. Hoy trae uno; el hueco de al lado dice que vendrán más. */}
          <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            <div className="enc-lbl">Sus automatizaciones</div>
            <div className="enc-rejilla">
              {encargos.map(function (e) {
                return (
                  <div className={"enc-card" + (e.activa ? " enc-proximo" : "")} key={e.id}>
                    <div className="enc-card-cab">
                      <div className="enc-icono" style={{ color: "#eaf3ff" }}><Marca d={e.icono} /></div>
                      <div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0, flex: 1 }}>
                        <div style={{ fontSize: 17.5, fontWeight: 600, letterSpacing: "-.012em" }}>{e.titulo}</div>
                        <div style={{ fontSize: 12.5, color: "rgba(235,245,255,.42)" }}>{e.sub}</div>
                      </div>
                      {/* 🟢 EL ESTADO, EN LA CABECERA DE SU PROPIA TARJETA.
                          Danny, tras pulsar «Automatizar»: «debería salir arriba también
                          algo como activo para identificarlo, aparte de ver que dice
                          Detener». Tenía dos razones, y la segunda es la de siempre:
                            · el único acuse de recibo era que el botón cambiaba de
                              «Automatizar» a «Detener» — y ese botón se vuelve MÁS
                              discreto al activarse, así que pulsar parecía no hacer nada.
                            · y la píldora que había arriba resumía en UNA palabra el estado de todas:
                              con cuatro, no decía CUÁL corría. Esa píldora ya no existe — ver el motivo
                              donde estaba, en la cabecera de la pantalla. */}
                      <div className={"enc-estado" + (e.activa ? "" : " off")}>
                        <span className={e.activa ? "enc-pulso" : ""} style={{ width: 5, height: 5, borderRadius: "50%",
                               background: e.activa ? "#00ff9d" : "rgba(234,246,255,.3)",
                               boxShadow: e.activa ? "0 0 8px rgba(0,255,157,.75)" : "none" }}></span>
                        {e.activa ? "Funcionando" : "Detenida"}
                      </div>
                    </div>
                    <div className="enc-card-cuerpo">{e.cuerpo()}</div>
                  </div>
                );
              })}

              {/* El hueco del siguiente. No promete fechas ni nombres: solo dice que
                  esta casa está pensada para más de un encargo. */}
              <div className="enc-futuro">
                <span style={{ color: "rgba(235,245,255,.22)" }}><Marca d={<React.Fragment><path d="M12 5v14"></path><path d="M5 12h14"></path></React.Fragment>} s={22} /></span>
                <div style={{ fontSize: 13, color: "rgba(235,245,255,.34)", lineHeight: 1.55, maxWidth: "30ch" }}>
                  Los demás departamentos traerán aquí sus automatizaciones
                </div>
              </div>
            </div>
          </div>

          <div className="enc-pie" style={{ marginTop: "auto" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <span style={{ color: "rgba(235,245,255,.28)" }}>
                <Marca s={13} d={<React.Fragment><rect x="4.5" y="10.5" width="15" height="9.5" rx="2.5"></rect><path d="M8 10.5V7.2a4 4 0 0 1 8 0v3.3"></path></React.Fragment>} />
              </span>
              {/* 🔑 EL PIE EXPLICA, Y YA NO HAY BOTÓN DE BORRAR. Aquí había uno,
                  «Retirar mis llaves». Danny no le encontró lógica: «¿quién haría eso?
                  Si no hay nada benéfico con ese botón, entonces quitarlo; si hay algo
                  peligroso, ¿para qué tenerlo expuesto? En vez de generar ayuda genera
                  desorden: deja de funcionar algo y piensa que es el sistema que falló».
                  Al ir al servidor a defenderlo, era PEOR de lo que él sospechaba: esa
                  copia no es «la llave de la automatización», es la que JARVIS usa
                  SIEMPRE que el señor no está delante del navegador — la usan _mcTgHabla,
                  _mcTgCrearYEnviar, _mcTgHacerCambio, _mcTgAtender y el piloto. Un botón
                  en la esquina de Automatización apagaba TODO Telegram. Y encima era un
                  duplicado del que vivía en el panel de Telegram de Contenido.
                  → El derecho a borrarla no se pierde: se mudó al gesto que la gente SÍ
                    hace — DESENLAZAR EL MÓVIL, que es literalmente decir «deja de
                    trabajar sin mí». Lo hace `/api/mc/telegram/desenlazar`, y también
                    el `/desenlazar` del bot, que además lo dice al contestar.
                  📌 UN CONTROL DESTRUCTIVO QUE NADIE TIENE MOTIVO PARA PULSAR NO PROTEGE
                     A NADIE: solo espera a que alguien lo pulse por curiosidad. Y si un
                     derecho solo se ejerce con un botón que nadie pulsa, ese derecho no
                     se ejerce nunca — hay que colgarlo de una acción que sí ocurre. */}
              {llaves ? "Para trabajar de madrugada guardo una copia cifrada de sus llaves — se borra sola si desenlaza su móvil"
                      : "Al automatizar algo copiaré sus llaves, cifradas"}
            </div>
          </div>
        </div>
      </div>
    );
  }

  function mount() {
    if (document.getElementById("enc-root")) return;
    if (!(window.MCNet && window.MCNet.flags && window.ReactDOM)) return;
    window.MCNet.flags().then(function (r) {
      // Mismo permiso que el panel de Telegram: sin móvil enlazado no hay a dónde
      // entregar el trabajo, así que abrir uno sin el otro no tendría sentido.
      if (!(r && r.ok && r.tgPanel)) return;
      const host = document.getElementById("encargos-react-root");
      const tab = document.getElementById("tab-encargos");
      if (!host || document.getElementById("enc-root")) return;
      injectCss();
      if (tab) tab.hidden = false;
      const el = document.createElement("div"); el.id = "enc-root";
      el.style.cssText = "flex:1 1 auto;min-height:0;min-width:0;width:100%;display:flex;";
      host.appendChild(el);
      try { ReactDOM.createRoot(el).render(<EncargosApp />); }
      catch (e) { try { ReactDOM.render(<EncargosApp />, el); } catch (_) {} }
    }).catch(function () {});
  }

  if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", mount);
  else mount();
})();
