/* Reset y base */

/* --- Escala tipográfica ---------------------------------------------------
   Una sola familia sans del sistema para toda la UI. Escala fija en rem, sin
   clamp(): el layout es denso y de contenedores, y un tamaño fluido rompe la
   predicibilidad espacial. Ratio ~1.125-1.2 entre pasos cercanos.
   Los tokens son semánticos (--text-sm), nunca numéricos (--font-14). */
:root {
    --font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

    --text-xs:   0.75rem;    /* 12px */
    --text-sm:   0.875rem;   /* 14px */
    --text-base: 1rem;       /* 16px */
    --text-md:   1.125rem;   /* 18px */
    --text-lg:   1.25rem;    /* 20px */
    --text-xl:   1.5rem;     /* 24px */

    --weight-normal: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;

    --leading-tight: 1.2;
    --leading-body: 1.55;
    --tracking-tight: -0.01em;

    /* --- Paleta ------------------------------------------------------------
       Único lugar donde vive un color crudo. Los nombres son semánticos:
       --c-ink/--c-ink-soft/--c-muted son tinta, --c-line* son líneas y
       superficies, --c-accent* es el acento de marca, --c-up/--c-down/
       --c-warn/--c-info son estados. */
    --c-ink:             #111827;
    --c-ink-soft:        #4b5563;
    --c-muted:           #676f7b;
    --c-line:            #e5e7eb;
    --c-line-soft:       #f3f4f6;
    --c-bg:              #ffffff;
    --c-bg-page:         #f9fafb;
    --c-row-hover:       #fafbfc;

    --c-accent:          #2563eb;
    --c-accent-strong:   #1d4ed8;
    --c-on-accent:       #ffffff;

    /* Estados: positivo, negativo, atención, informativo. */
    --c-up:              #15803d;
    --c-down:            #b91c1c;
    --c-warn:            #b45309;
    --c-info:            #1e40af;

    /* Superficies de estado: fondos y bordes suaves que acompañan al color
       de estado sin competir con el dato. */
    --c-warn-surface:    #fef9c3;
    --c-warn-border:     #fde68a;
    --c-info-surface:    #eff6ff;
    --c-info-border:     #dbeafe;
    --c-success-surface: #d1fae5;
    --c-success-text:    #065f46;
    --c-error-surface:   #fee2e2;
    --c-error-text:      #991b1b;

    /* Paleta categórica: solo donde el color codifica una categoría (los
       doughnuts de medio de pago y tipo de tarjeta). En series temporales el
       color no aporta: el largo de la barra ya codifica el valor. El orden
       es significativo: el índice de la categoría es el que se pinta. */
    --c-cat-1:           #2563eb;
    --c-cat-2:           #0891b2;
    --c-cat-3:           #16a34a;
    --c-cat-4:           #ea580c;
    --c-cat-5:           #9333ea;
    --c-cat-6:           #db2777;
    --c-cat-7:           #ca8a04;
    --c-cat-8:           #475569;

    /* Controles y navegación.
       --c-control-line es el borde de un control interactivo (campo de
       formulario, selector). Va separado de --c-line, que es separador
       decorativo: un borde que se puede tocar tiene que llegar a 3:1
       (WCAG 1.4.11). */
    --c-control-line:    #7d8592;   /* 3.72:1 sobre --c-bg */
    --c-topnav-bg:       #1f2937;
    --c-topnav-fg:       #ffffff;
    --c-topnav-line:     #8a929e;   /* 4.67:1 sobre --c-topnav-bg */
    --c-topnav-hover:    #374151;

    /* --- Escala de z-index --------------------------------------------------
       Escala semántica con un único lugar donde vive. Nunca números sueltos
       en las reglas: un 999 suelto termina compitiendo con otro 999. */
    --z-base:            0;   /* contenido normal */
    --z-sticky:          2;   /* columna identificadora fija de las tablas */
    --z-sticky-head:     3;   /* encabezado de esa columna */
    --z-topnav:          4;   /* barra de navegacion superior */
    --z-overlay:         10;  /* capas por encima: dialogo, menu desplegable */
}

* { box-sizing: border-box; }

body {
    font-family: var(--font-stack);
    font-size: var(--text-base);
    margin: 0;
    background: var(--c-bg-page);
    color: var(--c-ink);
    line-height: var(--leading-body);
}

/* Título de página. Cada página del dashboard lleva exactamente un h1. */
h1 {
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    line-height: var(--leading-tight);
    letter-spacing: -0.015em;
    text-wrap: balance;
    margin: 0 0 1rem;
}

.container {
    max-width: 960px;
    margin: 0 auto;
    padding: 0 1rem;
}

/* Topnav */
.topnav {
    background: var(--c-topnav-bg);
    color: var(--c-topnav-fg);
    padding: 0.75rem 0;
    margin-bottom: 2rem;
}
.topnav .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.brand {
    color: var(--c-topnav-fg);
    text-decoration: none;
    font-weight: var(--weight-semibold);
    font-size: var(--text-md);
}
.user-info {
    display: flex;
    align-items: center;
    gap: 1rem;
    font-size: var(--text-sm);
}
.logout-form { margin: 0; }
.btn-link {
    background: none;
    border: 1px solid var(--c-topnav-line);
    color: var(--c-topnav-fg);
    padding: 0.3rem 0.7rem;
    border-radius: 4px;
    cursor: pointer;
    font-size: var(--text-sm);
}
.btn-link:hover { background: var(--c-topnav-hover); }

/* Flashes */
.flashes { margin-bottom: 1rem; }
.flash {
    padding: 0.75rem 1rem;
    border-radius: 4px;
    margin-bottom: 0.5rem;
}
.flash-success { background: var(--c-success-surface); color: var(--c-success-text); }
.flash-error   { background: var(--c-error-surface);   color: var(--c-error-text); }
.flash-info    { background: var(--c-info-surface);    color: var(--c-info); }

/* Card. Sin sombra difusa: la jerarquía la hacen el borde y el espacio. */
.card, .login-card {
    background: var(--c-bg);
    border: 1px solid var(--c-line);
    border-radius: 6px;
    padding: 1.5rem 2rem;
}

.login-card { max-width: 400px; margin: 2rem auto; }

/* Forms */
form label {
    display: block;
    margin-top: 0.75rem;
    margin-bottom: 0.25rem;
    font-size: var(--text-sm);
    color: var(--c-ink-soft);
}
form input[type="email"], form input[type="password"], form input[type="text"] {
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--c-control-line);
    border-radius: 4px;
    font-size: var(--text-base);
}
.btn-primary {
    margin-top: 1.25rem;
    background: var(--c-accent);
    color: var(--c-on-accent);
    border: 0;
    padding: 0.6rem 1.2rem;
    border-radius: 4px;
    font-size: var(--text-base);
    cursor: pointer;
}
.btn-primary:hover { background: var(--c-accent-strong); }

/* --- Estado de error de campo ---------------------------------------------
   El borde rojo marca qué campo está mal: es la única señal roja de la app
   y aparece solo cuando hay error. El mensaje va en un bloque con fondo de
   estado, para que se lea sin depender del color (WCAG 1.4.1). */
form input[aria-invalid="true"] {
    border: 2px solid var(--c-down);
    background: var(--c-bg);
}
.field-error {
    margin: 0.65rem 0 0;
    padding: 0.55rem 0.7rem;
    border-radius: 4px;
    background: var(--c-error-surface);
    color: var(--c-error-text);
    font-size: var(--text-sm);
}

.muted { color: var(--c-muted); font-size: var(--text-sm); }

/* --- Foco visible ---------------------------------------------------------
   Un único anillo para toda la app. :focus-visible (y no :focus) para que
   el anillo aparezca solo cuando el elemento recibe foco por teclado.
   Offset 2px para los elementos con borde, -1px para los controles con
   relleno (el anillo se dibuja sobre el borde, no lo separa). */
:where(a, button, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--c-accent);
    outline-offset: 2px;
}
:where(input, select, textarea):focus-visible {
    outline: 2px solid var(--c-accent);
    outline-offset: -1px;
}
/* Sobre la barra oscura el anillo de acento no se ve: va en el color del
   texto de la barra. */
.topnav :where(a, button, summary):focus-visible {
    outline-color: var(--c-topnav-fg);
}

/* --- Movimiento ------------------------------------------------------------
   Solo transiciones cortas de color. El dashboard es una herramienta de
   consulta: el movimiento informa el cambio de estado, no decora. */
a,
button,
select,
summary {
    transition: background-color 160ms cubic-bezier(0.4, 0, 0.2, 1),
                color 160ms cubic-bezier(0.4, 0, 0.2, 1),
                border-color 160ms cubic-bezier(0.4, 0, 0.2, 1),
                outline-color 160ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Movimiento reducido: sin transiciones ni animaciones (también aplica a
   la animación de los gráficos, que se desactiva en charts.js). */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}
