/* ============================================================
   Quiniela Mundial 2026 — root app
   ============================================================ */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "matchCard": "detail"
}/*EDITMODE-END*/;

/* join code from the invite URL: /join/<CODE> (Hosting rewrite) or ?join=<CODE> (local dev) */
function parseJoinCode() {
  try {
    const m = (location.pathname || "").match(/\/join\/([A-Za-z0-9]+)/);
    if (m) return m[1];
    return new URLSearchParams(location.search).get("join") || null;
  } catch (e) { return null; }
}
function cleanJoinUrl() { try { history.replaceState({}, "", "/"); } catch (e) {} }
function navIcon(ic, size) { return ic === "leagues" ? <LIcon name="leagues" size={size} /> : <Icon name={ic} size={size} />; }

/* ---------- navigation config (per-role item set) ----------
   Colaborador (staff)  → Partidos · Ranking · Tabla · Mis Ligas · (Admin)
   Invitado (guest)     → Partidos · Tabla · Mis Ligas
   "Reglas y FAQ" y "Ayuda" son acciones (modales), no pantallas: su ubicación
   depende del rol/dispositivo (ver TopBar, UserMenu y TabBar). */
const SCREEN_META = {
  matches:     ["Partidos", "ball"],
  // leaderboard = ranking entre usuarios (trophy) · standings = tabla de posiciones del mundial (table)
  leaderboard: ["Ranking", "trophy"],
  standings:   ["Tabla", "table"],
  leagues:     ["Mis Ligas", "leagues"],
  admin:       ["Admin", "shield"],
};
function navScreens(role, isAdmin) {
  if (role === "guest") return ["matches", "standings", "leagues"];
  const base = ["matches", "leaderboard", "standings", "leagues"];
  if (isAdmin) base.push("admin");
  return base;
}

/* ---------- rules & FAQ (modal) ---------- */
function RulesModal({ onClose }) {
  return (
    <div className="qm-modal-backdrop" onClick={onClose}>
      <div className="qm-modal" onClick={(e) => e.stopPropagation()}>
        <div className="qm-modal-head">
          <b>Reglas y preguntas frecuentes</b>
          <button className="close" onClick={onClose} aria-label="Cerrar"><Icon name="x" size={16} /></button>
        </div>

        <div className="qm-rules">
          <h4>📋 Reglas del juego</h4>

          <h5>¿Cómo se juega?</h5>
          <p>Antes de cada partido pronosticas el <b>marcador exacto</b>: goles del equipo local y goles del visitante. Acumulas puntos según qué tan cerca estuviste del resultado real.</p>

          <h5>¿Cómo se ganan puntos?</h5>
          <table className="qm-rules-pts">
            <tbody>
              <tr className="exact">
                <td>⭐ <b>Marcador exacto</b> (ej. predijiste 2–1 y quedó 2–1)</td>
                <td className="pts">3 pts</td>
              </tr>
              <tr className="result">
                <td>✓ <b>Resultado correcto</b> (acertaste quién gana o el empate, pero no el marcador)</td>
                <td className="pts">1 pt</td>
              </tr>
              <tr className="miss">
                <td>✗ <b>Fallaste</b> o no pronosticaste</td>
                <td className="pts">0 pts</td>
              </tr>
            </tbody>
          </table>
          <p className="note">El "resultado correcto" incluye los empates: si predices empate y el partido termina empatado, ganas 1 punto aunque no aciertes el marcador.</p>

          <h5>⭐ Partidos destacados (puntos ×2)</h5>
          <p>Cada ronda elegimos algunos <b>partidos destacados</b>, marcados con una franja dorada y el sello <b>"Partido destacado · Puntos ×2"</b>. En esos partidos los puntos valen el <b>doble</b>: <b>6</b> por marcador exacto y <b>2</b> por resultado correcto (un fallo sigue siendo 0). Son una herramienta de alta varianza pensada para que quien va detrás pueda <b>remontar</b>, así que conviene afinar el pronóstico en esos partidos.</p>
          <p className="note">El doble solo afecta los <b>puntos</b>. Para los desempates de la tabla, un destacado cuenta como un único acierto exacto o de resultado, igual que cualquier otro partido.</p>

          <h5>¿Hasta cuándo puedo pronosticar o editar?</h5>
          <p>Hasta el <b>momento del pitazo inicial</b> de cada partido. Una vez que el partido inicia, el pronóstico queda <b>cerrado</b> y ya no se puede modificar. El cierre se controla con la <b>hora del servidor</b>, no con la hora de tu dispositivo, así que asegúrate de guardar con tiempo.</p>

          <h5>Eliminatorias (fase final)</h5>
          <p>En los partidos de eliminación directa, además del marcador debes indicar <b>qué equipo avanza</b> en caso de que predigas un empate. Si pronosticas empate y no eliges quién pasa, el pronóstico no se podrá guardar.</p>

          <div className="qm-rules-divider" />

          <h4>🏆 Ranking</h4>
          <h5>¿Cómo se ordena la tabla?</h5>
          <p>La posición se define por, en este orden:</p>
          <ol>
            <li><b>Total de puntos</b> acumulados</li>
            <li><b>Cantidad de marcadores exactos</b> (⭐)</li>
            <li><b>Cantidad de resultados correctos</b> (✓)</li>
            <li>Orden alfabético del nombre (último criterio de desempate)</li>
          </ol>
          <p>También verás tu <b>racha de los últimos 4 partidos</b> y si <b>subiste o bajaste</b> posiciones respecto a la jornada anterior (▲/▼).</p>

          <div className="qm-rules-divider" />

          <h4>❓ Preguntas frecuentes</h4>

          <p className="qm-rules-faq-q">¿Cómo ingreso a la quiniela?</p>
          <p>Te registras con tu correo. Recibirás un <b>enlace de verificación</b> en tu bandeja para confirmar que el correo es tuyo y activar tu cuenta.</p>

          <p className="qm-rules-faq-q">Olvidé mi contraseña.</p>
          <p>Usa la opción de recuperación: te llegará un <b>enlace mágico</b> al correo para volver a ingresar y restablecerla.</p>

          <p className="qm-rules-faq-q">¿Puedo guardar todos mis pronósticos de una vez?</p>
          <p>Sí. Con el botón <b>"Guardar todo"</b> envías de golpe todos los pronósticos que tengas pendientes; los que estén válidos se guardan y se te avisa si alguno quedó sin guardar.</p>

          <p className="qm-rules-faq-q">Me equivoqué en un pronóstico, ¿puedo corregirlo?</p>
          <p>Sí, las veces que quieras, <b>siempre que el partido no haya iniciado</b>. Después del pitazo inicial ya no.</p>

          <p className="qm-rules-faq-q">¿Qué pasa si no pronostico un partido?</p>
          <p>Recibes <b>0 puntos</b> en ese partido, pero sigues en la competencia para los demás.</p>

          <p className="qm-rules-faq-q">¿Qué son las ligas privadas?</p>
          <p>Además del ranking general, puedes competir en una <b>liga privada</b> con un grupo cerrado de personas mediante un código/enlace de invitación. Usas los mismos pronósticos, pero con una tabla aparte solo para ese grupo.</p>

          <p className="qm-rules-faq-q">¿Tiene algún costo? ¿Hay premios?</p>
          <p>¡No tiene ningún costo! El premio para la liga de colaboradores Quantia será comunicado por el equipo de Gestión Humana.</p>
        </div>
      </div>
    </div>
  );
}

function TopBar({ screen, setScreen, role, isAdmin, openLeague, onBack, onRules, onSupport }) {
  const Q = window.QStore;
  const me = Q.current;
  const screens = navScreens(role, isAdmin);
  return (
    <header className="qm-topbar">
      <div className="inner">
        {openLeague ? (
          <>
            <button className="lg-back" onClick={onBack} aria-label="Volver"><LIcon name="back" size={18} stroke={2.4} /></button>
            <div className="qm-brand"><div className="tag" style={{ whiteSpace: "normal", maxWidth: 220 }}>{openLeague.name}</div></div>
          </>
        ) : (
          <div className="qm-brand">
            <img className="iso" src="assets/iso-white.png" alt="Quantia" />
            <div className="tag">quantia<small>Quiniela 2026</small></div>
          </div>
        )}
        {/* Desktop (≥880px): links + Reglas en el topbar. En móvil el nav vive
            en la barra inferior; Reglas/Ayuda/Salir, en el menú del avatar. */}
        <nav className="qm-topnav">
          {screens.map((k) => {
            const [l, ic] = SCREEN_META[k];
            return (
              <button key={k} className={screen === k && !openLeague ? "on" : ""} onClick={() => setScreen(k)}>
                {navIcon(ic, 17)}{l}
              </button>
            );
          })}
          <button onClick={onRules} title="Reglas y preguntas frecuentes">
            <Icon name="book" size={17} />Reglas
          </button>
        </nav>
        <UserMenu me={me} role={role} onRules={onRules} onSupport={onSupport} />
      </div>
    </header>
  );
}

/* ---------- user / points pill with logout menu ---------- */
function UserMenu({ me, role, onRules, onSupport }) {
  const Q = window.QStore;
  const [open, setOpen] = useState(false);
  const btnRef = useRef(null);
  const openedAt = useRef(0);
  if (!me) return null;
  // fixed-positioned popover (escapes the topbar's overflow:hidden clip)
  let pos = { top: 64, right: 16 };
  if (open && btnRef.current) {
    const r = btnRef.current.getBoundingClientRect();
    pos = { top: r.bottom + 8, right: Math.max(8, window.innerWidth - r.right) };
  }
  const close = () => setOpen(false);
  // iOS Safari sintetiza un "ghost click" justo después del tap que abre el menú.
  // Como el backdrop a pantalla completa aparece bajo el dedo, ese click cae sobre
  // él (o de nuevo sobre el avatar) y cerraría el menú al instante. Ignoramos
  // cualquier interacción de apertura/cierre dentro de los ~350 ms posteriores a abrir.
  const GHOST_MS = 350;
  const toggle = () =>
    setOpen((o) => {
      if (o) return Date.now() - openedAt.current < GHOST_MS ? true : false;
      openedAt.current = Date.now();
      return true;
    });
  const onBackdrop = () => { if (Date.now() - openedAt.current >= GHOST_MS) setOpen(false); };
  return (
    <div className="qm-usermenu">
      <button ref={btnRef} className="qm-pts-pill" onClick={toggle} aria-haspopup="menu" aria-expanded={open} title="Tu cuenta">
        <span className="av">{initials(me.name)}</span>
        <Icon name="chevD" size={15} stroke={2.4} />
      </button>
      {open && ReactDOM.createPortal(
        <>
          <div className="qm-menu-backdrop" onClick={onBackdrop} />
          <div className="qm-usermenu-pop" role="menu" style={{ top: pos.top, right: pos.right }}>
            <div className="who">
              <Avatar name={me.name} size={38} />
              <div style={{ minWidth: 0 }}>
                <b>{me.name}</b>
                <small>{me.email}{me.area ? ` · ${me.area}` : ""}</small>
              </div>
            </div>
            {/* Reglas y FAQ en el avatar solo para colaborador en móvil; en desktop
                vive en el topbar (oculto aquí por CSS) y el invitado lo tiene abajo. */}
            {role === "colaborador" && onRules && (
              <button className="qm-menu-item qm-menu-item-mobile" role="menuitem" onClick={() => { close(); onRules(); }}>
                <Icon name="book" size={16} />Reglas y FAQ
              </button>
            )}
            {onSupport && (
              <button className="qm-menu-item" role="menuitem" onClick={() => { close(); onSupport(); }}>
                <Icon name="help" size={16} />Ayuda
              </button>
            )}
            <button className="qm-menu-item" role="menuitem" onClick={() => { close(); Q.actions.logout(); }}>
              <Icon name="logout" size={16} />Salir
            </button>
          </div>
        </>,
        document.body
      )}
    </div>
  );
}

function TabBar({ screen, setScreen, role, isAdmin, onRules }) {
  const screens = navScreens(role, isAdmin);
  return (
    <nav className="qm-tabbar">
      {screens.map((k) => {
        const [l, ic] = SCREEN_META[k];
        return (
          <button key={k} className={screen === k ? "on" : ""} onClick={() => setScreen(k)}>
            {navIcon(ic, 22)}{l}
          </button>
        );
      })}
      {/* Invitado: "Reglas y FAQ" vive en la barra inferior (su nav es más corta) */}
      {role === "guest" && onRules && (
        <button onClick={onRules}>
          <Icon name="book" size={22} />Reglas
        </button>
      )}
    </nav>
  );
}

/* ---------- demo / review switcher ---------- */
function DemoSwitcher({ screen, setScreen }) {
  const Q = useStore();
  const [open, setOpen] = useState(false);
  const reg = Q.db.registered;
  const admin = Q.db.isAdmin;

  // Oculto en producción. Solo aparece para revisión interna con ?demo=1 en la URL.
  let showDemo = false;
  try { showDemo = new URLSearchParams(location.search).get("demo") === "1"; } catch (e) {}
  if (!showDemo) return null;

  return (
    <>
      {open && (
        <div className="qm-demo-panel">
          <div className="dh">
            <b>Modo demo</b><span className="tagx">Review</span>
            <button className="close" onClick={() => setOpen(false)}><Icon name="x" size={16} /></button>
          </div>

          <div className="qm-demo-sec">Estado de sesión</div>
          <div className="qm-seg">
            <button className={reg ? "on" : ""} onClick={() => { Q.actions.setRegistered(true); }}>Registrado</button>
            <button className={!reg ? "on" : ""} onClick={() => { Q.actions.setRegistered(false); }}>Ver registro</button>
          </div>

          <div className="qm-demo-sec">Acceso admin</div>
          <div className="qm-seg">
            <button className={!admin ? "on" : ""} onClick={() => { Q.actions.setAdmin(false); if (screen === "admin") setScreen("matches"); }}>Participante</button>
            <button className={admin ? "on" : ""} onClick={() => { Q.actions.setAdmin(true); }}>Admin</button>
          </div>

          <div className="qm-demo-sec">Ver como participante</div>
          <select className="qm-sel" value={Q.db.currentUserId} onChange={(e) => Q.actions.setCurrentUser(e.target.value)}>
            {Q.db.users.slice().sort((a, b) => a.name.localeCompare(b.name)).map((u) => (
              <option key={u.userId} value={u.userId}>{u.name} — {u.area}</option>
            ))}
          </select>

          <button className="qm-demo-reset" onClick={() => { if (confirm("¿Reiniciar todos los datos de la demo?")) { Q.actions.resetAll(); setScreen("matches"); } }}>
            Reiniciar datos de la demo
          </button>
        </div>
      )}
      <button className="qm-demo-fab" onClick={() => setOpen((o) => !o)} title="Modo demo / review" aria-label="Modo demo">
        <Icon name={open ? "x" : "users"} size={22} />
      </button>
    </>
  );
}

/* ---------- support / help form (floating, global) ---------- */
const SUPPORT_CATS = [
  ["pronosticos", "Pronósticos"],
  ["acceso", "Acceso / inicio de sesión"],
  ["ranking", "Ranking y puntajes"],
  ["ligas", "Ligas"],
  ["otro", "Otro"],
];

function SupportForm({ onClose }) {
  const Q = window.QStore;
  const me = Q.current;                 // prellenado si hay sesión
  const [name, setName] = useState(me ? me.name : "");
  const [email, setEmail] = useState(me ? (me.email || "") : "");
  const [area, setArea] = useState(me ? (me.area || "") : "");
  const [category, setCategory] = useState("pronosticos");
  const [message, setMessage] = useState("");
  const [sending, setSending] = useState(false);

  const submit = async () => {
    if (sending) return;
    setSending(true);
    const r = await Q.actions.sendSupport({ name, email, area, category, message });
    setSending(false);
    if (r.ok) { toast("Mensaje enviado · te responderemos a tu correo", "ok"); onClose(); }
    else toast(r.error, "");
  };

  return (
    <div className="qm-modal-backdrop" onClick={onClose}>
      <div className="qm-modal" onClick={(e) => e.stopPropagation()}>
        <div className="qm-modal-head">
          <b>Soporte · Quiniela Quantia</b>
          <button className="close" onClick={onClose}><Icon name="x" size={16} /></button>
        </div>
        <p className="ph">Cuéntanos tu consulta o problema. Te responderemos al correo que indiques.</p>

        <div className="qm-field">
          <label>Nombre</label>
          <input className="qm-input" value={name} onChange={(e) => setName(e.target.value)} placeholder="Tu nombre" />
        </div>
        <div className="qm-field">
          <label>Correo</label>
          <input className="qm-input" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="tucorreo@ep.net.pe" />
        </div>
        <div className="qm-field">
          <label>Área <span style={{ fontWeight: 600, textTransform: "none", color: "var(--fg-3)" }}>(opcional)</span></label>
          <input className="qm-input" value={area} onChange={(e) => setArea(e.target.value)} placeholder="Tu área" />
        </div>
        <div className="qm-field">
          <label>Tipo de consulta</label>
          <select className="qm-sel" style={{ width: "100%" }} value={category} onChange={(e) => setCategory(e.target.value)}>
            {SUPPORT_CATS.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
          </select>
        </div>
        <div className="qm-field">
          <label>Mensaje</label>
          <textarea className="qm-input" rows={5} value={message} onChange={(e) => setMessage(e.target.value)}
            placeholder="Describe tu consulta con el mayor detalle posible…" style={{ resize: "vertical", lineHeight: 1.5 }} />
        </div>

        <button className="qm-btn qm-btn-grad qm-btn-block" disabled={sending} onClick={submit}>
          {sending ? "Enviando…" : "Enviar a soporte"}
        </button>
      </div>
    </div>
  );
}

// Botón flotante "?" = Ayuda. Visible en todas las vistas y roles (vive en Root).
function SupportFab({ onOpen }) {
  return (
    <button className="qm-support-fab" onClick={onOpen} title="Ayuda" aria-label="Ayuda">
      <Icon name="help" size={24} />
    </button>
  );
}

function App({ onOpenSupport, onOpenRules }) {
  const Q = useStore();
  const Ql = window.QLeagues;
  Ql.useLeagues();                          // re-render when league membership changes
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // URL params
  const params = new URLSearchParams(location.search);
  const urlEmail = params.get("email");
  const urlAdmin = params.get("admin");
  const [prefillEmail] = useState(urlEmail || "");
  const joinCode = parseJoinCode();

  useEffect(() => {
    if (urlAdmin) Q.actions.setAdmin(true);
    if (urlEmail && !joinCode) Q.actions.setRegistered(false);
    // eslint-disable-next-line
  }, []);

  const [screen, setScreen] = useState("matches");
  const [leagueOpenId, setLeagueOpenId] = useState(null);
  const [sheet, setSheet] = useState(null);
  const [manageId, setManageId] = useState(null);
  const [joinedCode, setJoinedCode] = useState(false);
  const [showAnnounce, setShowAnnounce] = useState(false);

  const registered = Q.db.registered;
  const isAdmin = Q.db.isAdmin;
  const me = Q.current;
  const isGuest = registered && me && me.guest;
  // puede crear/gestionar ligas quien está en el whitelist: staff corporativo (por
  // dominio) o invitado externo autorizado por correo (branding). Distinto de isGuest:
  // ese invitado es guest (fuera del ranking de empresa) pero SÍ administra sus ligas;
  // los que entran por /join no están en whitelist y solo pueden unirse.
  const canManageLeagues = !!(registered && me && Q.emailAuthorized(me.email));

  // ---- anuncio "Mis Ligas": disparo al volverse activo (carga + refoco de pestaña) ----
  // El ref espeja el estado vivo para que los listeners lo lean sin cierres rancios.
  const annRef = useRef({});
  annRef.current = { registered, me, isGuest, joinCode, sheet, manageId, leagueOpenId, showAnnounce };
  const tryShowAnnounce = () => {
    const A = window.QLeaguesAnnounce; if (!A) return;
    const g = annRef.current;
    if (!g.registered || !g.me || g.isGuest || g.joinCode) return; // solo colaborador, fuera de /join
    if (g.sheet || g.manageId || g.leagueOpenId) return;           // no solapar con otro modal
    if (g.showAnnounce) return;
    if (!A.eligible(Q.NOW)) return;                                // audiencia + 12h + tope 4 + fecha
    A.markShown(g.me.userId, Q.NOW);                               // marca AL mostrar (no al cerrar)
    A.track("league_modal_shown");
    setShowAnnounce(true);
  };
  useEffect(() => {
    // respiro para que el listener de ligas resuelva antes de evaluar "0 ligas"
    const t = setTimeout(tryShowAnnounce, 1800);
    const onVis = () => { if (document.visibilityState === "visible") tryShowAnnounce(); };
    document.addEventListener("visibilitychange", onVis);
    return () => { clearTimeout(t); document.removeEventListener("visibilitychange", onVis); };
    // eslint-disable-next-line
  }, []);

  // ---- public invite join flow (/join/<code>) — works logged-out or logged-in ----
  const alreadyMember = registered && (Ql.mine || []).some((l) => l.code === joinCode);
  if (joinCode && !joinedCode && !alreadyMember) {
    return (
      <div className="qm-app">
        <ErrorBoundary>
          <GuestFlow code={joinCode}
            onJoined={(lid) => { setJoinedCode(true); setLeagueOpenId(lid); setScreen("leagues"); cleanJoinUrl(); }} />
        </ErrorBoundary>
        <ToastHost />
      </div>
    );
  }

  // ---- not registered → register/login ----
  if (!registered) {
    return (
      <div className="qm-app">
        <RegisterScreen prefillEmail={prefillEmail} onDone={() => setScreen("matches")} />
        <ToastHost />
        <DemoSwitcher screen={screen} setScreen={setScreen} />
        <Tweaks t={t} setTweak={setTweak} />
      </div>
    );
  }

  // ---- authenticated shell (colaborador / invitado) ----
  // Misma estructura para ambos; el set de pantallas y permisos cambia por rol.
  //   colaborador → Partidos · Ranking · Tabla · Mis Ligas · (Admin)
  //   invitado    → Partidos · Tabla · Mis Ligas  (su ranking vive en Mis Ligas)
  const role = isGuest ? "guest" : "colaborador";
  const openLeague = leagueOpenId ? Ql.findLeague(leagueOpenId) : null;
  const manageLeague = manageId ? Ql.findLeague(manageId) : null;
  const goTab = (s) => { setLeagueOpenId(null); setScreen(s); };
  return (
    <div className="qm-app">
      <TopBar screen={screen} setScreen={goTab} role={role} isAdmin={isAdmin}
        openLeague={openLeague} onBack={() => setLeagueOpenId(null)}
        onRules={onOpenRules} onSupport={onOpenSupport} />
      <main className="qm-main">
        <ErrorBoundary key={screen + (leagueOpenId || "")}>
          {openLeague ? (
            <LeagueView league={openLeague} persona={canManageLeagues ? "employee" : "guest"}
              onManage={canManageLeagues ? () => setManageId(openLeague.id) : undefined} />
          ) : screen === "matches" ? <MatchesScreen tweaks={t} />
            : screen === "standings" ? <StandingsScreen />
            : screen === "leaderboard" && !isGuest ? <LeaderboardScreen />
            : screen === "admin" && isAdmin ? <AdminScreen />
            : screen === "leagues" ? (
                <MisLigasScreen leagues={Ql.mine} loading={false} hideCreate={!canManageLeagues}
                  onOpen={(id) => setLeagueOpenId(id)} onCreate={() => setSheet("name")} />
              )
            : <MatchesScreen tweaks={t} />}
        </ErrorBoundary>
      </main>
      {!openLeague && <TabBar screen={screen} setScreen={goTab} role={role} isAdmin={isAdmin} onRules={onOpenRules} />}
      {sheet && canManageLeagues && <CreateLeagueSheet initialStep={sheet} onClose={() => setSheet(null)}
        onGoToLeague={(lid) => { setSheet(null); setScreen("leagues"); if (lid) setLeagueOpenId(lid); }} />}
      {manageLeague && canManageLeagues && <ManagePanel league={manageLeague} onClose={() => setManageId(null)} onDeleted={() => { setManageId(null); setLeagueOpenId(null); }} />}
      {showAnnounce && !openLeague && !sheet && !manageId && (
        <LeaguesAnnounceModal
          onCreate={() => { setShowAnnounce(false); window.QLeaguesAnnounce.track("league_modal_cta_create"); goTab("leagues"); setSheet("name"); }}
          onDismiss={() => { setShowAnnounce(false); window.QLeaguesAnnounce.track("league_modal_dismiss"); }}
        />
      )}
      <ToastHost />
      <DemoSwitcher screen={screen} setScreen={goTab} />
      <Tweaks t={t} setTweak={setTweak} />
    </div>
  );
}

function Tweaks({ t, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection label="Tarjeta de partido" />
      <TweakRadio label="Estilo" value={t.matchCard} options={["detail", "compact"]}
        onChange={(v) => setTweak("matchCard", v)} />
    </TweaksPanel>
  );
}

// Ayuda (soporte) y Reglas y FAQ viven en la raíz para estar disponibles en
// todas las pantallas y roles (position:fixed / modales globales). El botón "?"
// flotante abre Ayuda; el avatar / topbar / barra inferior abren cualquiera.
function Root() {
  const [support, setSupport] = useState(false);
  const [rules, setRules] = useState(false);
  return (
    <>
      <App onOpenSupport={() => setSupport(true)} onOpenRules={() => setRules(true)} />
      <SupportFab onOpen={() => setSupport(true)} />
      {support && <SupportForm onClose={() => setSupport(false)} />}
      {rules && <RulesModal onClose={() => setRules(false)} />}
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<Root />);
