<!doctype html>
<html lang="en">
  <head>
    <!-- Runs before Vite entry (in head). Avoids race if /assets/*.js fails before body boot script runs. -->
    <script>
      (function () {
        window.__bokonsNotifyBootFailure = function (subtitle) {
          window.__bokonsBootFailurePending = true;
          if (arguments.length && subtitle != null) {
            window.__bokonsBootFailureSubtitle = String(subtitle);
          }
        };
      })();
    </script>
    <meta charset="UTF-8" />
    <!-- Belt-and-suspenders with _headers: stale document + new deploy → wrong /assets/*.js hash → MIME error -->
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="Pragma" content="no-cache" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BOKONS — Admin Hub</title>
    <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=Inter:wght@400;500;600;700;800;900&family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,700;0,9..40,800;0,9..40,900;1,9..40,400&family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet">
    <script type="module" crossorigin src="/assets/index-BH9q4BSk.js" onerror="try{window.__bokonsNotifyBootFailure&&window.__bokonsNotifyBootFailure()}catch(e){}"></script>
    <link rel="stylesheet" crossorigin href="/assets/index-DN-94M9m.css">
  </head>
  <body style="margin:0;background:#faf9f6">
    <!-- Static shell until React mounts (avoids blank #root before Vite bundle runs). -->
    <div id="root">
      <div
        id="bokons-static-boot"
        style="min-height:100vh;display:flex;align-items:center;justify-content:center;font-family:system-ui,sans-serif;font-size:14px;color:#64748b;padding:2rem;text-align:center;background:#faf9f6"
      >
        Loading BOKONS…
      </div>
    </div>
    <script>
      (function () {
        var BOOT_RETRY_KEY = 'bokons_boot_retry_once';
        /** Non-auth routes: one automatic reload if the shell is stuck (stale deploy / slow chunk). */
        var BOOT_TIMEOUT_MS = 20000;
        /**
         * Clerk sign-in + /auth/me can exceed 10s; auto-replace here interrupted sessions and looked like a reload loop.
         * On these paths: longer wait, no forced navigation — user keeps the tab for debugging.
         */
        var AUTH_FLOW_TIMEOUT_MS = 60000;
        var bootRecoveryShown = false;
        function hasSpaMounted() {
          return document.documentElement.getAttribute('data-bokons-spa-ready') === 'true';
        }
        function isAuthFlowPath() {
          try {
            var p = window.location.pathname || '';
            return (
              p === '/login' ||
              p.indexOf('/login/') === 0 ||
              p === '/post-signin' ||
              p.indexOf('/post-signin/') === 0 ||
              p === '/register' ||
              p.indexOf('/register/') === 0
            );
          } catch (e) {
            return false;
          }
        }
        /** forceAfterSpa: cuando falla un asset crítico (p. ej. CSS) tras montar React, #bokons-static-boot ya no existe — usar overlay en body. */
        function showBootRecoveryMessage(subtitle, forceAfterSpa) {
          if (!forceAfterSpa && (bootRecoveryShown || hasSpaMounted())) return;
          bootRecoveryShown = true;
          var el = document.getElementById('bokons-static-boot');
          if (!el) {
            el = document.getElementById('bokons-boot-recovery-host');
            if (!el) {
              el = document.createElement('div');
              el.id = 'bokons-boot-recovery-host';
              el.setAttribute('role', 'alert');
              el.style.cssText =
                'position:fixed;inset:0;z-index:2147483646;display:flex;align-items:center;justify-content:center;padding:2rem;background:#faf9f6;font-family:system-ui,sans-serif;';
              document.body.appendChild(el);
            }
          }
          while (el.firstChild) el.removeChild(el.firstChild);
          var wrap = document.createElement('div');
          wrap.style.maxWidth = '480px';
          wrap.style.lineHeight = '1.45';
          var title = document.createElement('div');
          title.style.fontWeight = '700';
          title.style.color = '#334155';
          title.style.marginBottom = '6px';
          title.textContent = 'No se pudo iniciar BOKONS';
          var body = document.createElement('div');
          body.style.marginBottom = '12px';
          body.textContent =
            subtitle ||
            'La app no terminó de cargar. Si acabas de desplegar, prueba recargar sin caché (mayúsculas + recargar) o purga la caché del sitio en Cloudflare.';
          var btn = document.createElement('button');
          btn.type = 'button';
          btn.style.padding = '8px 12px';
          btn.style.border = '1px solid #cbd5e1';
          btn.style.borderRadius = '8px';
          btn.style.background = '#fff';
          btn.style.color = '#0f172a';
          btn.style.cursor = 'pointer';
          btn.textContent = 'Recargar';
          btn.addEventListener('click', function () {
            try {
              sessionStorage.removeItem(BOOT_RETRY_KEY);
            } catch (e) {}
            window.location.reload();
          });
          wrap.appendChild(title);
          wrap.appendChild(body);
          wrap.appendChild(btn);
          el.appendChild(wrap);
        }
        if (window.__bokonsBootFailurePending) {
          showBootRecoveryMessage(window.__bokonsBootFailureSubtitle);
          try {
            delete window.__bokonsBootFailurePending;
            delete window.__bokonsBootFailureSubtitle;
          } catch (e) {}
        }
        window.__bokonsNotifyBootFailure = showBootRecoveryMessage;
        // Immediate feedback when the Vite main chunk fails to load (404, HTML fallback / MIME error) or throws while loading.
        window.addEventListener(
          'error',
          function (ev) {
            var t = ev && ev.target;
            // Producción: Vite emite `/assets/*.css`; si 404 o fallback HTML, React puede montar sin Tailwind (enlaces azules, "skip" visible). Tratar aunque el SPA ya marcó ready (carrera de red).
            if (
              t &&
              t.tagName === 'LINK' &&
              String(t.rel || '').toLowerCase() === 'stylesheet' &&
              t.href &&
              String(t.href).indexOf('/assets/') !== -1
            ) {
              showBootRecoveryMessage(
                'No se pudieron cargar los estilos (CSS). Suele pasar tras un despliegue con caché desalineada. Prueba recargar sin caché (Ctrl+Shift+R) o purgar la caché del sitio en el navegador.',
                true,
              );
              return;
            }
            if (hasSpaMounted()) return;
            if (t && t.tagName === 'SCRIPT' && t.src && String(t.src).indexOf('/assets/') !== -1) {
              showBootRecoveryMessage(
                'No se pudo cargar el archivo de la aplicación (suele pasar tras un despliegue si el navegador guardó una versión vieja). Prueba recargar sin caché.',
              );
              return;
            }
            if (
              ev &&
              ev.filename &&
              String(ev.filename).indexOf('/assets/') !== -1 &&
              !(t && t.tagName === 'SCRIPT')
            ) {
              showBootRecoveryMessage(
                'Error al ejecutar el código cargado. Revisa la consola del navegador o vuelve a desplegar el Web Hub.',
              );
            }
          },
          true,
        );
        window.addEventListener('unhandledrejection', function (ev) {
          if (hasSpaMounted() || !ev || !ev.reason) return;
          var msg = String(ev.reason && ev.reason.message ? ev.reason.message : ev.reason);
          if (msg.indexOf('Failed to fetch dynamically imported module') !== -1 || msg.indexOf('Importing a module script failed') !== -1) {
            showBootRecoveryMessage(
              'Falló la carga de un módulo (chunks desalineados tras un deploy). Recarga forzada o purga de caché.',
            );
          }
        });
        // Chrome a menudo NO dispara `error` en <link> cuando la URL devuelve 200 con text/html (fallback SPA): MIME inválido en consola pero la UI queda sin Tailwind.
        var __bokonsCssMimeProbeDone = false;
        function probeViteCssMime() {
          if (__bokonsCssMimeProbeDone || typeof fetch === 'undefined') return;
          var links = document.querySelectorAll('link[rel="stylesheet"]');
          for (var i = 0; i < links.length; i++) {
            var href = links[i].href || '';
            if (href.indexOf('/assets/') === -1) continue;
            __bokonsCssMimeProbeDone = true;
            fetch(href, { credentials: 'same-origin', cache: 'no-store' })
              .then(function (res) {
                var ct = (res.headers.get('content-type') || '').toLowerCase();
                if (ct.indexOf('text/html') !== -1) {
                  showBootRecoveryMessage(
                    'El servidor respondió HTML en la URL del CSS (caché o deploy desalineado). Prueba Ctrl+Shift+R. Si sigue: Cloudflare → Caching → Purge Everything o purga el hostname — y confirma que el último deploy de Pages terminó bien.',
                    true,
                  );
                }
              })
              .catch(function () {});
            return;
          }
        }
        probeViteCssMime();
        document.addEventListener('DOMContentLoaded', probeViteCssMime);
        window.setTimeout(probeViteCssMime, 50);
        window.setTimeout(
          function () {
            if (hasSpaMounted()) return;
            if (isAuthFlowPath()) {
              showBootRecoveryMessage(
                'El inicio de sesión está tardando más de lo normal (Clerk o la API). Revisa la red, la consola (F12) y prueba Recargar. No forzamos otra recarga automática aquí para que puedas leer errores.',
              );
              return;
            }
            try {
              var alreadyRetried = sessionStorage.getItem(BOOT_RETRY_KEY) === '1';
              if (!alreadyRetried) {
                sessionStorage.setItem(BOOT_RETRY_KEY, '1');
                var url = new URL(window.location.href);
                url.searchParams.set('_boot_retry', String(Date.now()));
                window.location.replace(url.toString());
                return;
              }
            } catch (e) {
              // ignore storage/url errors and show fallback message
            }
            showBootRecoveryMessage();
          },
          isAuthFlowPath() ? AUTH_FLOW_TIMEOUT_MS : BOOT_TIMEOUT_MS,
        );
      })();
    </script>
    <!-- E2E: after navigation use wait_until≥load and wait for html[data-bokons-spa-ready]; do not rely on wait_until=commit alone. -->
  </body>
</html>
