/* BMX Performance — Sistema de diseño centralizado (sección 78).
   La identidad visual puede cambiarse sin tocar el resto del frontend: basta con editar
   estas variables. */

:root {
    --primary: #ff5a1f;         /* naranja BMX: velocidad, tierra, adrenalina */
    --primary-dark: #d6440f;
    --secondary: #1f2a44;       /* azul noche: profesionalismo */
    --background: #f5f6f9;
    --surface: #ffffff;
    --text: #16181d;
    --text-muted: #6b7280;
    --success: #16a34a;
    --warning: #d97706;
    --danger: #dc2626;
    --border: #e5e7eb;
    --radius: 14px;
    --radius-sm: 8px;
    --shadow: 0 2px 10px rgba(16, 20, 30, 0.06);
    --shadow-lg: 0 12px 30px rgba(16, 20, 30, 0.12);
    --nav-height: 64px;
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --background: #0f1115;
        --surface: #1a1d24;
        --text: #eef0f3;
        --text-muted: #9aa1ad;
        --border: #2a2e38;
        --shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
        --shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.5);
    }
}

:root[data-theme="dark"] {
    --background: #0f1115;
    --surface: #1a1d24;
    --text: #eef0f3;
    --text-muted: #9aa1ad;
    --border: #2a2e38;
    --shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.5);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--background);
    color: var(--text);
    font-family: var(--font);
    -webkit-font-smoothing: antialiased;
    /* Red de seguridad: en mobile-first ningún elemento debería desbordar el ancho de la
       pantalla, pero si alguno lo hace (texto largo, tabla sin envolver, etc.) esto evita el
       scroll horizontal accidental de toda la página en vez de solo ese elemento. */
    overflow-x: hidden;
}

a { color: inherit; }

.app-shell {
    display: flex;
    min-height: 100vh;
}

.app-main {
    flex: 1;
    /* El espacio para que el bottom-nav fijo (móvil) no tape el contenido ya no se reserva aquí:
       el <footer class="app-footer"> que sigue a este <main> (mismo layout) es ahora el último
       elemento del flujo y es quien reserva esa altura, así que aquí basta un padding normal. */
    padding: 20px 16px;
    max-width: 1200px;
    margin: 0 auto;
    width: 100%;
}

@media (min-width: 960px) {
    .app-main { padding: 28px 32px; }
}

/* Footer visible en toda página autenticada (sección 1/125: crédito estándar, sin emojis). En
   móvil el bottom-nav queda fijo sobre el viewport (nav-height), así que el footer reserva ese
   mismo espacio abajo para no quedar tapado; en escritorio el bottom-nav no existe y no hace falta. */
.app-footer {
    text-align: center;
    color: var(--text-muted);
    font-size: 0.78rem;
    padding: 16px 16px calc(var(--nav-height) + 16px);
    max-width: 1200px;
    margin: 0 auto;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    flex-wrap: wrap;
}
.app-footer svg { flex-shrink: 0; color: var(--primary); }

@media (min-width: 960px) {
    .app-footer { padding: 16px 32px; }
}

/* Topbar */
.app-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 12px;
    padding: 12px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}
.app-topbar__actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
@media (min-width: 480px) {
    .app-topbar__actions { gap: 10px; }
}
/* En pantallas muy angostas, el nombre completo de la marca compite por espacio con las
   acciones (búsqueda/notificaciones/tema/usuario); el ícono solo ya es reconocible. */
@media (max-width: 360px) {
    .app-topbar__brand-text { display: none; }
}

.app-topbar__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 700;
    font-size: 1.05rem;
}

.app-topbar__brand svg { flex-shrink: 0; }

/* El nombre del usuario no debe forzar el desborde del topbar en pantallas angostas: se trunca
   con puntos suspensivos y, si aun así no hay espacio, se oculta del todo (el sidebar de
   escritorio ya no compite por ese espacio, pero en mobile el topbar es la única fila). */
.app-topbar__username {
    font-size: 0.85rem;
    color: var(--text-muted);
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex-shrink: 1;
}
@media (max-width: 420px) {
    .app-topbar__username { display: none; }
}

/* Botones que solo contienen un ícono (búsqueda, tema, etc.) */
.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Alternancia sol/luna del botón de tema (sección 79): solo uno visible a la vez. */
.icon-moon { display: none; }
:root[data-theme="dark"] .icon-sun { display: none; }
:root[data-theme="dark"] .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .icon-sun { display: none; }
    :root:not([data-theme="light"]) .icon-moon { display: block; }
}

.avatar-placeholder {
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; background: var(--background); border: 1px solid var(--border);
    color: var(--text-muted); flex-shrink: 0;
}

/* Navegación móvil inferior (sección 76): pocas opciones, táctiles */
.bottom-nav {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    height: var(--nav-height);
    display: flex;
    background: var(--surface);
    border-top: 1px solid var(--border);
    z-index: 30;
}

.bottom-nav a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    font-size: 0.72rem;
    text-decoration: none;
    color: var(--text-muted);
    min-height: 48px;
}

.bottom-nav a.active { color: var(--primary); font-weight: 600; }
.bottom-nav svg { width: 22px; height: 22px; }

@media (min-width: 960px) {
    .bottom-nav { display: none; }
    .app-sidebar {
        width: 240px;
        flex-shrink: 0;
        background: var(--surface);
        border-right: 1px solid var(--border);
        padding: 20px 14px;
    }
    .app-sidebar a {
        display: flex; align-items: center; gap: 10px;
        padding: 10px 12px; border-radius: var(--radius-sm);
        text-decoration: none; color: var(--text-muted); font-weight: 500;
        margin-bottom: 4px;
    }
    .app-sidebar a.active, .app-sidebar a:hover { background: var(--background); color: var(--primary); }
}

@media (max-width: 959px) {
    .app-sidebar { display: none; }
}

/* Cards */
.card {
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 18px;
    border: 1px solid var(--border);
    text-decoration: none;
}

a.card:hover {
    border-color: var(--primary);
}

.card-grid {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.stat-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.stat-card .label { color: var(--text-muted); font-size: 0.78rem; text-transform: uppercase; letter-spacing: .04em; }
.stat-card .value { font-size: 1.6rem; font-weight: 700; }

/* Un stat-card a veces muestra texto libre en vez de un número (nombre de archivo importado,
   nombre de competencia): sin esto, un valor largo sin espacios empuja el ancho de la tarjeta
   -y de la cuadrícula que la contiene- más allá de la pantalla en vez de partirse en líneas
   (mismo patrón de bug ya corregido en las celdas de tabla móvil). */
.stat-card .label, .stat-card .value { overflow-wrap: anywhere; word-break: break-word; }
.card-grid > * { min-width: 0; }

/* Utilidad para pares de campos de formulario en fila (fecha inicio/fin, min/max, etc.):
   fluida en escritorio, colapsa a una sola columna en el mismo breakpoint móvil que el resto
   del sistema (evita columnas demasiado angostas para inputs/selects en pantallas de 320-360px). */
.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 720px) {
    .form-grid-2 { grid-template-columns: 1fr; }
}

/* Variante de .card-grid forzada a 2 columnas (comparaciones lado a lado, p. ej. fusión de
   deportistas duplicados): igual que arriba, colapsa a 1 columna en móvil en vez de aplastar
   cada tarjeta a un ancho inutilizable. */
.card-grid--2col { grid-template-columns: 1fr 1fr; }
@media (max-width: 720px) {
    .card-grid--2col { grid-template-columns: 1fr; }
}

/* Badges */
.badge {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 10px; border-radius: 999px;
    font-size: 0.72rem; font-weight: 600;
    background: var(--background); color: var(--text-muted);
    border: 1px solid var(--border);
}
.badge--success { background: rgba(22,163,74,.12); color: var(--success); border-color: transparent; }
.badge--warning { background: rgba(217,119,6,.12); color: var(--warning); border-color: transparent; }
.badge--danger { background: rgba(220,38,38,.12); color: var(--danger); border-color: transparent; }
.badge--primary { background: rgba(255,90,31,.12); color: var(--primary); border-color: transparent; }

/* Botones */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 18px; border-radius: var(--radius-sm);
    font-weight: 600; font-size: 0.92rem;
    border: 1px solid transparent; cursor: pointer;
    text-decoration: none;
    min-height: 44px; /* táctil, sección 75 */
}
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-block { width: 100%; }
.btn:disabled { opacity: .55; cursor: not-allowed; }

/* Un <label> asociado a un checkbox/radio activa ese campo al hacer clic en su texto, pero el
   navegador no muestra el cursor de mano por defecto — parece texto seleccionable en vez de un
   control interactivo. Aplica a cualquier label (de un campo normal también: clickearlo enfoca
   su input, así que el cursor de mano es correcto ahí también). */
label { cursor: pointer; }

/* Formularios */
.form-group { margin-bottom: 16px; }
.form-label { display: block; margin-bottom: 6px; font-weight: 600; font-size: 0.85rem; }
.form-control {
    width: 100%; padding: 11px 12px; border-radius: var(--radius-sm);
    border: 1px solid var(--border); background: var(--surface); color: var(--text);
    font-size: 0.95rem; min-height: 44px;
}
.form-control:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
.form-error { color: var(--danger); font-size: 0.78rem; margin-top: 4px; }
.form-hint { color: var(--text-muted); font-size: 0.78rem; margin-top: 4px; }

/* Tablas: en móvil se comportan como cards apiladas (sección 82) */
.table-wrap { overflow-x: auto; }
table.data-table { width: 100%; border-collapse: collapse; }
.data-table th, .data-table td {
    text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); font-size: 0.9rem;
}
.data-table th { color: var(--text-muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; }

@media (max-width: 720px) {
    .data-table thead { display: none; }
    .data-table, .data-table tbody, .data-table tr, .data-table td { display: block; width: 100%; }
    .data-table tr { margin-bottom: 12px; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }
    .data-table td {
        border-bottom: 1px solid var(--border);
        display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
        gap: 4px 12px; min-width: 0;
        /* Sin esto, un valor largo sin espacios (nombre de archivo, etc.) empuja el ancho de
           toda la tabla más allá de la pantalla en vez de partirse en varias líneas. */
        word-break: break-word; overflow-wrap: anywhere; text-align: right;
    }
    .data-table td::before { content: attr(data-label); font-weight: 600; color: var(--text-muted); text-align: left; flex-shrink: 0; }
}

.page-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.page-header h1 { font-size: 1.35rem; margin: 0; }

.empty-state { text-align: center; padding: 40px 20px; color: var(--text-muted); }

.auth-shell {
    min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 18px;
    background: linear-gradient(160deg, var(--secondary), #0f1115);
    padding: 20px;
}
/* En el fondo oscuro degradado del login, var(--text-muted) del tema claro no siempre contrasta
   lo suficiente; el footer aquí fuerza un tono claro fijo legible sobre ese degradado concreto. */
.auth-shell .app-footer { color: rgba(255,255,255,0.65); }
.auth-shell .app-footer svg { color: var(--primary); }
.auth-card { width: 100%; max-width: 380px; background: var(--surface); border-radius: var(--radius); padding: 28px 24px; box-shadow: var(--shadow-lg); }
.auth-card .brand { text-align: center; margin-bottom: 20px; }

/* Modal de confirmación propio (sustituye window.confirm(), sección 79/105). */
.confirm-modal {
    position: fixed; inset: 0; z-index: 100;
    background: rgba(15, 17, 21, 0.55);
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
}
.confirm-modal[hidden] { display: none; }
.confirm-modal__box {
    width: 100%; max-width: 400px;
    background: var(--surface); color: var(--text);
    border-radius: var(--radius); box-shadow: var(--shadow-lg);
    padding: 22px 20px;
}
.confirm-modal__message { margin: 0 0 18px; font-size: 0.98rem; line-height: 1.4; }
.confirm-modal__actions { display: flex; gap: 10px; justify-content: flex-end; }

/* Cualquier foto de deportista con clase .js-photo-zoom (ficha, listas, formulario de edición)
   se puede ampliar con un clic (mismo patrón que el modal de confirmación de arriba: overlay
   fijo oculto con [hidden], listener delegado en app.js). Solo aplica a fotos reales, nunca al
   ícono de casco (avatar-placeholder) que se muestra cuando no hay foto. */
.js-photo-zoom { cursor: pointer; }
.photo-zoom-modal {
    position: fixed; inset: 0; z-index: 100;
    background: rgba(15, 17, 21, 0.75);
    display: flex; align-items: center; justify-content: center;
    padding: 20px;
}
.photo-zoom-modal[hidden] { display: none; }
.photo-zoom-modal__img {
    max-width: 90vw; max-height: 80vh;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
    object-fit: contain;
}
.photo-zoom-modal__close {
    position: absolute; top: 18px; right: 18px;
    width: 40px; height: 40px; border-radius: 50%;
    background: var(--surface); color: var(--text);
    border: 1px solid var(--border);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}
