/* ============================================================================================================
   Base visual (UX fase 1, 2026-10-07). Tokens de diseño + componentes comunes, compatibles con Bootstrap 5.3.3.
   - Todo color, radio, sombra y tamaño nuevo sale de estos tokens; las variables antiguas (--bg, --text, --primary…)
     quedan como alias para que las reglas de cada módulo sigan funcionando.
   - Tema oscuro (fase 2): bastará con redefinir los tokens --c-* bajo [data-tema="oscuro"]. Hoy solo hay tema claro.
   - Los estados nunca dependen solo del color: avisos con icono, insignias con texto, sección actual con peso y marca.
   ============================================================================================================ */
/* Valores claros (por omisión y en cualquier zona marcada data-bs-theme="light", p. ej. la vista previa de Excel). */
:root, [data-bs-theme="light"] {
    color-scheme: light;

    /* Superficies y texto */
    --c-fondo: #f4f5f7;
    --c-superficie: #ffffff;
    --c-superficie-2: #f8f9fb;          /* zonas suaves dentro de una tarjeta */
    --c-relleno: #eef0f3;               /* encabezados de tabla, chips neutros */
    --c-relleno-2: #e5e7eb;             /* rellenos más marcados (insignia neutra, «en 0») */
    --c-borde-suave: #eceef1;
    --c-borde: #dde1e6;
    --c-borde-fuerte: #c9ced6;
    --c-gris-medio: #9ca3af;            /* barras y marcas neutras */
    --c-texto: #1c2230;
    --c-texto-2: #424b5a;               /* etiquetas y texto secundario: 8.6:1 sobre blanco */
    --c-texto-suave: #5f6775;           /* ayudas y metadatos: 5.8:1 sobre blanco */
    --c-texto-tenue: #80878f;           /* marcadores de posición y deshabilitado */
    --c-invertido: #1f2937;             /* fondo oscuro con texto blanco (tooltip, segmento activo) */
    --c-sobre-color: #ffffff;           /* icono o texto sobre un relleno semántico */

    /* Marca: relleno (botones) y texto (enlaces) por separado, porque en oscuro no pueden ser el mismo color. */
    --c-primario: #1d4ed8;
    --c-primario-hover: #1e40af;
    --c-primario-activo: #1e3a8a;
    --c-primario-suave: #eef3fe;
    --c-primario-suave-2: #e2eafd;
    --c-primario-borde: #bfd0f7;
    --c-enlace: #1d4ed8;
    --c-enlace-hover: #1e40af;

    /* Semánticos: texto (fuerte), fondo (suave), borde y marca de cada estado */
    --c-exito: #15803d;   --c-exito-suave: #f0fdf4;  --c-exito-borde: #bbf7d0;  --c-exito-marca: #15803d;  --c-exito-texto-2: #166534;
    --c-aviso: #92400e;   --c-aviso-suave: #fffbeb;  --c-aviso-borde: #fcd34d;  --c-aviso-marca: #d97706;  --c-aviso-texto-2: #78350f;
    --c-error: #b91c1c;   --c-error-suave: #fef2f2;  --c-error-borde: #fecaca;  --c-error-marca: #b91c1c;
    --c-info: #1e40af;    --c-info-suave: #eff6ff;   --c-info-borde: #bfdbfe;   --c-info-marca: #1e40af;

    /* Familias de color de los módulos: fondo, fondo-2, borde, sólido (relleno con texto blanco), sólido-2, texto. */
    --azul-fondo: #eff6ff;    --azul-fondo-2: #dbeafe;    --azul-borde: #93c5fd;    --azul-solido: #2563eb;    --azul-solido-2: #1e40af;    --azul-texto: #1e40af;
    --indigo-fondo: #eef2ff;  --indigo-fondo-2: #e0e7ff;  --indigo-borde: #c7d2fe;  --indigo-solido: #4f46e5;  --indigo-solido-2: #3730a3;  --indigo-texto: #3730a3;
    --verde-fondo: #f0fdf4;   --verde-fondo-2: #dcfce7;   --verde-borde: #bbf7d0;   --verde-solido: #16a34a;   --verde-solido-2: #15803d;   --verde-texto: #15803d;
    --teal-fondo: #f0fdfa;    --teal-fondo-2: #ccfbf1;    --teal-borde: #99f6e4;    --teal-solido: #14b8a6;    --teal-solido-2: #0f766e;    --teal-texto: #0f766e;
    --ambar-fondo: #fffbeb;   --ambar-fondo-2: #fef3c7;   --ambar-borde: #fcd34d;   --ambar-solido: #f59e0b;   --ambar-solido-2: #b45309;   --ambar-texto: #92400e;
    --naranja-fondo: #fff7ed; --naranja-fondo-2: #ffedd5; --naranja-borde: #fdba74; --naranja-solido: #ea580c; --naranja-solido-2: #c2410c; --naranja-texto: #9a3412;
    --rojo-fondo: #fef2f2;    --rojo-fondo-2: #fee2e2;    --rojo-borde: #fecaca;    --rojo-solido: #b91c1c;    --rojo-solido-2: #991b1b;    --rojo-texto: #991b1b;
    --violeta-fondo: #f5f3ff; --violeta-fondo-2: #ede9fe; --violeta-borde: #ddd6fe; --violeta-solido: #6d28d9; --violeta-solido-2: #5b21b6; --violeta-texto: #5b21b6;
    /* Canales RGB para transparencias: rgb(var(--azul-rgb) / .12) */
    --azul-rgb: 37 99 235; --rojo-rgb: 185 28 28; --verde-rgb: 21 128 61; --violeta-rgb: 124 58 237; --teal-rgb: 15 118 110; --sombra-rgb: 15 23 42;

    --foco-color: #1d4ed8;
    --foco-rgb: 29 78 216;

    /* Bootstrap: valores que dependen del tema */
    --bs-primary: #1d4ed8;
    --bs-primary-rgb: 29, 78, 216;
    --bs-link-color: #1d4ed8;
    --bs-link-color-rgb: 29, 78, 216;
    --bs-link-hover-color: #1e40af;
    --bs-link-hover-color-rgb: 30, 64, 175;
}

/* Valores oscuros: misma función para cada token, ajustada a un fondo oscuro (no es una inversión de colores):
   superficies escalonadas, texto con contraste ≥ 4.5:1, rellenos de estado oscuros y textos de estado claros. */
[data-bs-theme="dark"] {
    color-scheme: dark;

    --c-fondo: #121519;
    --c-superficie: #1b1f26;
    --c-superficie-2: #20252d;
    --c-relleno: #262b34;
    --c-relleno-2: #30363f;
    --c-borde-suave: #2a2f38;
    --c-borde: #343a45;
    --c-borde-fuerte: #4a5260;
    --c-gris-medio: #6d7686;
    --c-texto: #e7eaef;                 /* 13.9:1 sobre la superficie */
    --c-texto-2: #c5cbd4;
    --c-texto-suave: #a1a9b6;           /* 7.1:1 */
    --c-texto-tenue: #7f8899;           /* 4.6:1 */
    --c-invertido: #3a4250;
    --c-sobre-color: #10141a;

    --c-primario: #3466e8;              /* relleno con texto blanco: 4.8:1 */
    --c-primario-hover: #2a58d6;
    --c-primario-activo: #2249b8;
    --c-primario-suave: #1a2742;
    --c-primario-suave-2: #22335a;
    --c-primario-borde: #34508f;
    --c-enlace: #93b4ff;                /* 8.1:1 sobre la superficie */
    --c-enlace-hover: #b5ccff;

    --c-exito: #6bdc92;   --c-exito-suave: #11261a;  --c-exito-borde: #22583a;  --c-exito-marca: #3fbf6c;  --c-exito-texto-2: #8ae6a9;
    --c-aviso: #f5c066;   --c-aviso-suave: #2a2110;  --c-aviso-borde: #6b4f12;  --c-aviso-marca: #e3940f;  --c-aviso-texto-2: #f8cf85;
    --c-error: #ff9d9d;   --c-error-suave: #2d1517;  --c-error-borde: #7a2a2f;  --c-error-marca: #f06a6a;
    --c-info: #9dbaff;    --c-info-suave: #16223b;   --c-info-borde: #33508d;   --c-info-marca: #7aa0ff;

    --azul-fondo: #16223b;    --azul-fondo-2: #1c2c4e;    --azul-borde: #33508d;    --azul-solido: #3b6cf0;    --azul-solido-2: #2a58d6;    --azul-texto: #9dbaff;
    --indigo-fondo: #1c1f3d;  --indigo-fondo-2: #262a52;  --indigo-borde: #3d4290;  --indigo-solido: #6366f1;  --indigo-solido-2: #4f46e5;  --indigo-texto: #b4bcfd;
    --verde-fondo: #11261a;   --verde-fondo-2: #153322;   --verde-borde: #22583a;   --verde-solido: #229a4f;   --verde-solido-2: #1b8443;   --verde-texto: #6bdc92;
    --teal-fondo: #0f2928;    --teal-fondo-2: #133635;    --teal-borde: #1f5c59;    --teal-solido: #14a394;    --teal-solido-2: #0f8a7e;    --teal-texto: #5eead4;
    --ambar-fondo: #2a2110;   --ambar-fondo-2: #382a0f;   --ambar-borde: #6b4f12;   --ambar-solido: #d98a0b;   --ambar-solido-2: #b87308;   --ambar-texto: #f5c066;
    --naranja-fondo: #2b1c12; --naranja-fondo-2: #3a2514; --naranja-borde: #7a4a24; --naranja-solido: #e0702a; --naranja-solido-2: #c25a1b; --naranja-texto: #fdba74;
    --rojo-fondo: #2d1517;    --rojo-fondo-2: #3d1b1e;    --rojo-borde: #7a2a2f;    --rojo-solido: #d33a41;    --rojo-solido-2: #b82e35;    --rojo-texto: #ff9d9d;
    --violeta-fondo: #211a3a; --violeta-fondo-2: #2c224f; --violeta-borde: #4c3a8a;  --violeta-solido: #8b5cf6; --violeta-solido-2: #7c4ef0; --violeta-texto: #c9b8ff;
    --azul-rgb: 110 150 255; --rojo-rgb: 240 90 90; --verde-rgb: 70 200 120; --violeta-rgb: 167 139 250; --teal-rgb: 45 212 191; --sombra-rgb: 0 0 0;

    --foco-color: #93b4ff;
    --foco-rgb: 147 180 255;

    --bs-primary: #3466e8;
    --bs-primary-rgb: 52, 102, 232;
    --bs-link-color: #93b4ff;
    --bs-link-color-rgb: 147, 180, 255;
    --bs-link-hover-color: #b5ccff;
    --bs-link-hover-color-rgb: 181, 204, 255;
}

/* Tokens que no cambian con el tema, y los que se derivan de otros: se declaran en cada zona con tema para que
   se resuelvan con los valores de esa zona. */
:root, [data-bs-theme] {
    /* Tipografía */
    --fuente: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --fuente-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --t-xs: 12px; --t-sm: 13px; --t-base: 14px; --t-md: 16px; --t-lg: 18px; --t-xl: 22px; --t-2xl: 26px;

    /* Espaciado, radios y sombras */
    --e-1: 4px; --e-2: 8px; --e-3: 12px; --e-4: 16px; --e-5: 24px; --e-6: 32px;
    --r-sm: 4px; --r: 6px; --r-lg: 10px; --r-pill: 999px;
    --sombra-1: 0 1px 2px rgb(var(--sombra-rgb) / .05);
    --sombra-2: 0 8px 24px rgb(var(--sombra-rgb) / .14);
    --sombra-3: 0 12px 40px rgb(var(--sombra-rgb) / .2);
    --foco: 0 0 0 3px rgb(var(--foco-rgb) / .35);

    /* Alias de las variables anteriores (no usar en código nuevo). */
    --bg: var(--c-fondo);
    --card-bg: var(--c-superficie);
    --border: var(--c-borde);
    --text: var(--c-texto);
    --muted: var(--c-texto-suave);
    --primary: var(--c-primario);
    --primary-hover: var(--c-primario-hover);
    --danger: var(--c-error);
    --ok: var(--c-exito);
    --warn: var(--ambar-solido-2);

    /* Bootstrap toma los mismos valores. */
    --bs-body-font-family: var(--fuente);
    --bs-body-font-size: var(--t-base);
    --bs-body-line-height: 1.5;
    --bs-body-color: var(--c-texto);
    --bs-body-bg: var(--c-fondo);
    --bs-emphasis-color: var(--c-texto);
    --bs-secondary-color: var(--c-texto-suave);
    --bs-secondary-bg: var(--c-relleno);
    --bs-tertiary-bg: var(--c-superficie-2);
    --bs-border-color: var(--c-borde);
    --bs-border-radius: var(--r);
    --bs-focus-ring-color: rgb(var(--foco-rgb) / .35);
    --bs-form-invalid-color: var(--c-error);
    --bs-form-invalid-border-color: var(--c-error);
}
/* Zonas con tema propio dentro de la página (p. ej. la vista previa de Excel): su texto y fondo vuelven a calcularse. */
[data-bs-theme]:not(html) { color: var(--c-texto); }

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--fuente);
    font-size: var(--t-base);
    line-height: 1.5;
    background: var(--c-fondo);
    color: var(--c-texto);
    -webkit-text-size-adjust: 100%;
}

/* Jerarquía de títulos (Bootstrap los escala con el ancho; aquí son fijos y sobrios). */
h1, h2, h3, h4, h5 { color: var(--c-texto); font-weight: 600; line-height: 1.3; letter-spacing: -.005em; margin: 0 0 var(--e-3); }
h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-md); }
h5 { font-size: 15px; }
p { margin: 0 0 var(--e-3); }
a { color: var(--c-enlace); }
a:hover { color: var(--c-enlace-hover); }

/* Cifras: dígitos de ancho fijo para que las columnas se alineen. */
td, .celda-numero, .kpi-value, .kpi-alerta, .chart-bar-value { font-variant-numeric: tabular-nums; }

/* Foco visible y uniforme en todo control operable con teclado. */
:focus-visible { outline: 2px solid var(--foco-color); outline-offset: 2px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }

/* Enlace para saltar la navegación (solo aparece con teclado). */
.saltar-contenido { position: absolute; left: var(--e-3); top: var(--e-3); z-index: 1100; padding: var(--e-2) var(--e-4);
    background: var(--c-superficie); color: var(--c-enlace); border: 1px solid var(--c-primario); border-radius: var(--r);
    box-shadow: var(--sombra-2); text-decoration: none; font-weight: 600; }
.saltar-contenido:not(:focus) { clip-path: inset(50%); width: 1px; height: 1px; padding: 0; border: 0; overflow: hidden; white-space: nowrap; }

/* ------------------------------------------------------------------ Cabecera y navegación principal */
.app-header {
    background: var(--c-superficie);
    border-bottom: 1px solid var(--c-borde);
    box-shadow: var(--sombra-1);
    position: sticky;
    top: 0;
    z-index: 1030;
}
.app-barra { display: flex; align-items: center; justify-content: space-between; gap: var(--e-3); padding: 10px 24px 0; }
.app-marca { min-width: 0; overflow: hidden; text-overflow: ellipsis; display: inline-flex; align-items: baseline; gap: 6px; color: var(--c-texto); text-decoration: none; font-size: 15px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; }
.app-marca:hover { color: var(--c-texto); }
@media (max-width: 419.98px) { .app-barra .app-marca-sub { display: none; } }
.app-marca-sub { font-weight: 400; color: var(--c-texto-suave); }
.app-marca::before { content: ""; align-self: center; width: 10px; height: 10px; border-radius: 3px; background: var(--c-primario); }

.cuenta { display: flex; align-items: center; gap: var(--e-3); font-size: var(--t-sm); color: var(--c-texto-suave); }
.cuenta-nombre { white-space: nowrap; }
.cuenta-nombre strong { color: var(--c-texto-2); font-weight: 600; }
.cuenta form { display: inline; margin: 0; }
.cuenta-accion {
    display: inline-flex; align-items: center; min-height: 32px; padding: 4px 10px; margin: 0;
    background: none; border: 1px solid transparent; border-radius: var(--r);
    color: var(--c-enlace); font: inherit; font-weight: 500; text-decoration: none; cursor: pointer; white-space: nowrap;
}
.cuenta-accion:hover { background: var(--c-primario-suave); color: var(--c-enlace-hover); }
.cuenta-salir { color: var(--c-texto-2); border-color: var(--c-borde); }
.cuenta-salir:hover { background: var(--c-fondo); color: var(--c-texto); }

/* Botón del menú en pantallas angostas. */
.nav-toggle {
    display: none; align-items: center; gap: 8px; min-height: 40px; padding: 6px 12px; margin: 0;
    background: var(--c-superficie); color: var(--c-texto); border: 1px solid var(--c-borde); border-radius: var(--r);
    font: inherit; font-weight: 600; cursor: pointer;
}
.nav-toggle:hover { background: var(--c-fondo); }
/* Muy angosto (p. ej. 360 px al 150 %): solo el icono; el texto sigue disponible para lectores de pantalla. */
@media (max-width: 299.98px) { .nav-toggle-texto { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .nav-toggle { padding: 6px 10px; } }
.nav-toggle-icono, .nav-toggle-icono::before, .nav-toggle-icono::after { display: block; width: 16px; height: 2px; border-radius: 1px; background: currentColor; transition: transform .15s; }
.nav-toggle-icono { position: relative; }
.nav-toggle-icono::before, .nav-toggle-icono::after { content: ""; position: absolute; left: 0; }
.nav-toggle-icono::before { top: -5px; }
.nav-toggle-icono::after { top: 5px; }
.nav-toggle[aria-expanded="true"] .nav-toggle-icono { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle-icono::before { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-icono::after { transform: translateY(-5px) rotate(-45deg); }

.mainnav { display: flex; align-items: center; gap: 2px; padding: 8px 24px 10px; flex-wrap: wrap; row-gap: 6px; }
.mainnav-cuenta { display: none; }
.mainnav-group { display: flex; align-items: center; gap: 2px; }
.mainnav-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--c-texto-suave); margin: 0 6px 0 4px; }
.mainnav-divider { width: 1px; height: 22px; background: var(--c-borde); margin: 0 10px; }

.mainnav-link {
    display: inline-flex; align-items: center; gap: 4px; min-height: 34px; padding: 6px 12px; margin: 0;
    border-radius: var(--r); border: none; background: none;
    font-family: inherit; font-size: var(--t-sm); font-weight: 500; line-height: 1.3; color: var(--c-texto-2);
    text-decoration: none; cursor: pointer; white-space: nowrap;
}
.mainnav-link:hover { background: var(--c-fondo); color: var(--c-enlace); }
/* Sección actual: fondo suave, texto de marca, más peso y una marca inferior (no solo color). */
.mainnav-link.active, button.mainnav-menu-boton.active {
    background: var(--c-primario-suave); color: var(--c-enlace); font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--c-primario);
}
.mainnav-link.active:hover, button.mainnav-menu-boton.active:hover { background: var(--azul-fondo-2); color: var(--c-enlace-hover); }
.mainnav-cobertura { /* reservado: Apartado conserva su entrada propia */ }

/* Submenús (Inventario, Configuraciones, Administración): se abren con clic, Enter o Espacio; Escape o clic fuera los cierra. */
.mainnav-menu { position: relative; }
.mainnav-flecha { font-size: 10px; margin-left: 2px; display: inline-block; transition: transform .15s; }
.mainnav-submenu {
    position: absolute; top: 100%; left: 0; z-index: 1050; min-width: 230px; padding: 6px;
    margin-top: 4px; background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-lg);
    box-shadow: var(--sombra-2);
    /* visible al instante al abrir; al cerrar se oculta cuando termina el desvanecido */
    opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .15s, transform .15s, visibility 0s linear .15s;
}
.mainnav-menu-derecha .mainnav-submenu { left: auto; right: 0; }
.mainnav-menu.abierto .mainnav-submenu { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) { .mainnav-submenu, .mainnav-flecha, .nav-toggle-icono, .nav-toggle-icono::before, .nav-toggle-icono::after { transition: none; } }
.mainnav-menu.abierto .mainnav-flecha { transform: rotate(180deg); }
.mainnav-submenu a {
    display: block; padding: 8px 12px; border-radius: var(--r); font-size: var(--t-sm); color: var(--c-texto);
    text-decoration: none; white-space: nowrap;
}
.mainnav-submenu a:hover, .mainnav-submenu a:focus-visible { background: var(--c-fondo); color: var(--c-enlace); }
.mainnav-submenu a.active { background: var(--c-primario-suave); color: var(--c-enlace); font-weight: 600; box-shadow: inset 3px 0 0 var(--c-primario); }

/* Escritorio medio: sin las etiquetas de grupo para que todo quepa en un renglón. */
@media (max-width: 1199.98px) {
    .mainnav-label { display: none; }
    .mainnav-divider { margin: 0 6px; }
}

/* Tableta y móvil: menú colapsable con submenús en acordeón y la cuenta (incluido Salir) al inicio del panel. */
@media (max-width: 1023.98px) {
    .app-barra { padding: 8px 16px; }
    .app-barra .cuenta { display: none; }
    .nav-toggle { display: inline-flex; }
    .mainnav {
        display: none; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0; padding: 4px 16px 16px;
        border-top: 1px solid var(--c-borde);
        max-height: calc(100vh - 57px); max-height: calc(100dvh - 57px); overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
    }
    .app-header.nav-abierta .mainnav { display: flex; }
    .mainnav-cuenta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px;
        padding: 10px 0 12px; margin-bottom: 4px; border-bottom: 1px solid var(--c-borde); }
    .mainnav-cuenta .cuenta-nombre { white-space: normal; flex: 1 1 100%; }
    .mainnav-cuenta .cuenta-acciones { display: flex; gap: 8px; }
    .mainnav-cuenta .cuenta-accion { min-height: 40px; }
    .mainnav-group { flex-direction: column; align-items: stretch; gap: 0; }
    .mainnav-label { display: block; margin: 12px 0 4px; }
    .mainnav-divider { display: none; }
    .mainnav-link { display: flex; min-height: 44px; padding: 10px 12px; font-size: var(--t-base); }
    .mainnav-link.active, button.mainnav-menu-boton.active { box-shadow: inset 3px 0 0 var(--c-primario); }
    .mainnav-menu-boton { width: 100%; justify-content: space-between; }
    .mainnav-submenu, .mainnav-menu-derecha .mainnav-submenu {
        position: static; display: none; min-width: 0; margin: 0 0 4px 12px; padding: 2px 0 2px 8px;
        border: none; border-left: 2px solid var(--c-borde); border-radius: 0; box-shadow: none;
        opacity: 1; visibility: visible; transform: none; transition: none;
    }
    .mainnav-menu.abierto .mainnav-submenu { display: block; }
    .mainnav-submenu a { min-height: 44px; display: flex; align-items: center; font-size: var(--t-base); white-space: normal; }
}

/* ------------------------------------------------------------------ Página */
.container { max-width: 1320px; margin: 28px auto; padding: 0 24px; }
/* Movimientos y Planeación usan más ancho de pantalla que el resto del sitio. */
body.page-movimientos .container,
body.page-planeacion .container { max-width: 1680px; }
/* Listas de Productos, Insumos y Recetas. */
body.page-ancha .container { max-width: 1260px; }
body.page-ancha .clamp-2 { max-width: 480px; }
/* Listas de catálogo: encabezados en una línea; clave y números solo lo que necesitan. */
.tabla-catalogo th,
.tabla-catalogo td.celda-corta { white-space: nowrap; }

.page-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--e-3); margin-bottom: var(--e-4); }
.page-header h2 { margin: 0; }
.page-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--e-3); margin-bottom: 20px; }
.page-toolbar .almacen-tabs { margin-bottom: 0; }

.form-row { display: flex; gap: var(--e-4); }
.form-row > div { flex: 1; min-width: 0; }

@media (max-width: 900px) {
    .container { margin: 20px auto; padding: 0 16px; }
    .form-row { flex-direction: column; gap: 0; }
}

/* ------------------------------------------------------------------ Tarjetas y secciones */
.card {
    background: var(--c-superficie);
    border: 1px solid var(--c-borde);
    border-radius: var(--r-lg);
    box-shadow: var(--sombra-1);
    padding: var(--e-5);
    min-width: 0;
}
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
@media (max-width: 575.98px) { .card { padding: var(--e-4); } }

.encabezado-seccion { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: var(--e-2) var(--e-4); margin-bottom: var(--e-3); }
.encabezado-seccion h2, .encabezado-seccion h3 { margin: 0; }

fieldset { border: 1px solid var(--c-borde); border-radius: var(--r-lg); margin: 0 0 var(--e-4); padding: var(--e-4); min-width: 0; }
legend { float: none; width: auto; padding: 0 6px; margin: 0; font-size: var(--t-sm); font-weight: 600; color: var(--c-texto-2); }

/* ------------------------------------------------------------------ Formularios */
label { display: block; font-size: var(--t-sm); font-weight: 500; margin-bottom: 6px; color: var(--c-texto-2); }

input[type=email], input[type=password], input[type=text], input[type=number], input[type=date], input[type=search],
input[type=tel], input[type=url], input[type=datetime-local], input[type=month], input[type=time], select, textarea {
    width: 100%;
    padding: 8px 12px;
    min-height: 38px;
    border: 1px solid var(--c-borde-fuerte);
    border-radius: var(--r);
    background-color: var(--c-superficie);
    color: var(--c-texto);
    font-size: var(--t-base);
    line-height: 1.45;
    margin-bottom: var(--e-4);
    font-family: inherit;
    resize: vertical;
    transition: border-color .15s, box-shadow .15s;
}
input::placeholder, textarea::placeholder { color: var(--c-texto-tenue); opacity: 1; }
input:focus, select:focus, textarea:focus { border-color: var(--c-primario); box-shadow: var(--foco); outline: none; }
input:disabled, select:disabled, textarea:disabled, input[readonly] { background-color: var(--c-superficie-2); color: var(--c-texto-suave); cursor: not-allowed; }
input[readonly] { cursor: default; }
input.is-invalid, select.is-invalid, textarea.is-invalid, [aria-invalid="true"] { border-color: var(--c-error-marca); }
input.is-invalid:focus, select.is-invalid:focus, textarea.is-invalid:focus { box-shadow: 0 0 0 3px rgb(var(--rojo-rgb) / .2); }

.help-text { font-size: var(--t-xs); line-height: 1.45; color: var(--c-texto-suave); margin: -12px 0 var(--e-4); }
/* Error de un campo: icono + texto, debajo del control. */
.campo-error, .invalid-feedback { display: block; margin: -10px 0 var(--e-4); font-size: var(--t-xs); font-weight: 500; color: var(--c-error); }
.campo-error::before, .invalid-feedback::before { content: "✕ "; font-weight: 700; }

/* ------------------------------------------------------------------ Botones
   <button> sin clase .btn: botón primario por defecto (especificidad mínima para que las clases propias de cada
   módulo —pestañas, filtros, menús— lo sustituyan sin pelear). Los .btn usan el motor de Bootstrap con nuestros
   valores; así hover, foco, activo y deshabilitado son coherentes. */
button:where(:not(.btn)) {
    display: inline-block;
    background: var(--c-primario);
    color: #fff;
    border: none;
    padding: 8px 16px;
    border-radius: var(--r);
    font-family: inherit;
    font-size: var(--t-base);
    font-weight: 500;
    line-height: 1.45;
    cursor: pointer;
    text-decoration: none;
    transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s;
}
button:where(:not(.btn)):hover { background: var(--c-primario-hover); }
button:where(:not(.btn)):disabled { opacity: .5; cursor: not-allowed; }

.btn {
    --bs-btn-padding-x: 15px; --bs-btn-padding-y: 7px;
    --bs-btn-font-size: var(--t-base); --bs-btn-font-weight: 500; --bs-btn-line-height: 1.45;
    --bs-btn-border-width: 1px; --bs-btn-border-radius: var(--r);
    --bs-btn-box-shadow: none; --bs-btn-focus-box-shadow: var(--foco); --bs-btn-disabled-opacity: .5;
    /* .btn sin variante = primario (así se usaba). */
    --bs-btn-color: #fff; --bs-btn-bg: var(--c-primario); --bs-btn-border-color: var(--c-primario);
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: var(--c-primario-hover); --bs-btn-hover-border-color: var(--c-primario-hover);
    --bs-btn-active-color: #fff; --bs-btn-active-bg: var(--c-primario-activo); --bs-btn-active-border-color: var(--c-primario-activo);
    --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: var(--c-primario); --bs-btn-disabled-border-color: var(--c-primario);
    text-decoration: none;
}
.btn:focus-visible { outline: none; }
.btn-primary {
    --bs-btn-color: #fff; --bs-btn-bg: var(--c-primario); --bs-btn-border-color: var(--c-primario);
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: var(--c-primario-hover); --bs-btn-hover-border-color: var(--c-primario-hover);
    --bs-btn-active-color: #fff; --bs-btn-active-bg: var(--c-primario-activo); --bs-btn-active-border-color: var(--c-primario-activo);
    --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: var(--c-primario); --bs-btn-disabled-border-color: var(--c-primario);
}
/* Secundario: neutro con borde. */
.btn-secondary, .btn-outline-secondary {
    --bs-btn-color: var(--c-texto); --bs-btn-bg: var(--c-superficie); --bs-btn-border-color: var(--c-borde-fuerte);
    --bs-btn-hover-color: var(--c-texto); --bs-btn-hover-bg: var(--c-relleno); --bs-btn-hover-border-color: var(--c-borde-fuerte);
    --bs-btn-active-color: var(--c-texto); --bs-btn-active-bg: var(--c-relleno-2); --bs-btn-active-border-color: var(--c-borde-fuerte);
    --bs-btn-disabled-color: var(--c-texto-suave); --bs-btn-disabled-bg: var(--c-superficie); --bs-btn-disabled-border-color: var(--c-borde);
}
.btn-outline-secondary { --bs-btn-bg: transparent; }
.btn-outline-primary {
    --bs-btn-color: var(--c-enlace); --bs-btn-bg: transparent; --bs-btn-border-color: var(--c-primario);
    --bs-btn-hover-color: var(--c-enlace-hover); --bs-btn-hover-bg: var(--c-primario-suave); --bs-btn-hover-border-color: var(--c-primario-hover);
    --bs-btn-active-color: var(--c-enlace-hover); --bs-btn-active-bg: var(--c-primario-suave-2); --bs-btn-active-border-color: var(--c-primario-hover);
    --bs-btn-disabled-color: var(--c-enlace); --bs-btn-disabled-bg: transparent; --bs-btn-disabled-border-color: var(--c-primario);
}
/* Destructivo: sólido para la acción que confirma; contorno para la que solo la inicia. */
.btn-danger {
    --bs-btn-color: #fff; --bs-btn-bg: var(--rojo-solido); --bs-btn-border-color: var(--rojo-solido);
    --bs-btn-hover-color: #fff; --bs-btn-hover-bg: var(--rojo-solido-2); --bs-btn-hover-border-color: var(--rojo-solido-2);
    --bs-btn-active-color: #fff; --bs-btn-active-bg: var(--rojo-solido-2); --bs-btn-active-border-color: var(--rojo-solido-2);
    --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: var(--rojo-solido); --bs-btn-disabled-border-color: var(--rojo-solido);
}
.btn-outline-danger {
    --bs-btn-color: var(--c-error); --bs-btn-bg: transparent; --bs-btn-border-color: var(--rojo-borde);
    --bs-btn-hover-color: var(--rojo-texto); --bs-btn-hover-bg: var(--c-error-suave); --bs-btn-hover-border-color: var(--c-error-marca);
    --bs-btn-active-color: var(--rojo-texto); --bs-btn-active-bg: var(--rojo-fondo-2); --bs-btn-active-border-color: var(--c-error-marca);
    --bs-btn-disabled-color: var(--c-error); --bs-btn-disabled-bg: transparent; --bs-btn-disabled-border-color: var(--rojo-borde);
}
.btn-sm { --bs-btn-padding-x: 10px; --bs-btn-padding-y: 3px; --bs-btn-font-size: var(--t-xs); --bs-btn-border-radius: 5px; }

/* Acciones en línea de las tablas (enlaces con aspecto de texto). */
.actions-cell { display: flex; gap: 10px; }
.actions-cell a, .actions-cell button.link {
    background: none; border: none; padding: 0; font-size: var(--t-sm); color: var(--c-enlace);
    cursor: pointer; text-decoration: none;
}
.actions-cell a:hover, .actions-cell button.link:hover { text-decoration: underline; background: none; }
.actions-cell .danger { color: var(--c-error); }

/* ------------------------------------------------------------------ Avisos: icono + texto, nunca solo color. */
.alert {
    position: relative;
    padding: 10px 14px 10px 40px;
    border: 1px solid var(--c-info-borde);
    border-radius: var(--r);
    background: var(--c-info-suave);
    color: var(--c-info);
    font-size: var(--t-sm);
    line-height: 1.5;
    margin-bottom: var(--e-4);
}
.alert::before {
    content: "i"; position: absolute; left: 13px; top: 11px; width: 18px; height: 18px; border-radius: 50%;
    background: var(--c-info-marca); color: var(--c-sobre-color); font: 700 12px/18px Georgia, "Times New Roman", serif; text-align: center;
}
.alert-error, .alert-danger { background: var(--c-error-suave); color: var(--c-error); border-color: var(--c-error-borde); }
.alert-error::before, .alert-danger::before { content: "✕"; background: var(--c-error-marca); font: 700 11px/18px var(--fuente); }
.alert-success, .alert-ok { background: var(--c-exito-suave); color: var(--verde-texto); border-color: var(--c-exito-borde); }
.alert-success::before, .alert-ok::before { content: "✓"; background: var(--c-exito-marca); font: 700 11px/18px var(--fuente); }
.alert-warning, .alert-aviso { background: var(--c-aviso-suave); color: var(--ambar-texto); border-color: var(--c-aviso-borde); }
.alert-warning::before, .alert-aviso::before { content: "!"; background: var(--c-aviso-marca); font: 700 12px/18px var(--fuente); }

/* ------------------------------------------------------------------ Insignias (siempre con texto) */
.badge { display: inline-block; padding: 2px 8px; border-radius: var(--r-pill); font-size: var(--t-xs); font-weight: 600; line-height: 1.5; }
.badge-ok { background: var(--verde-fondo-2); color: var(--c-exito); }
.badge-warn, .badge-warning { background: var(--ambar-fondo-2); color: var(--c-aviso); }
.badge-danger { background: var(--rojo-fondo-2); color: var(--c-error); }
.badge-muted { background: var(--c-relleno-2); color: var(--c-texto-2); }

/* ------------------------------------------------------------------ Tablas */
.table-scroll { max-width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll table { min-width: 640px; }
table { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--c-borde); }
th { color: var(--c-texto-2); font-weight: 600; }
td:first-child, th:first-child { white-space: nowrap; }
.celda-numero { text-align: right; white-space: nowrap; }

.table-scroll.table-scroll-tall { max-height: 560px; overflow-y: auto; }
.table-scroll-tall table thead th {
    position: sticky;
    top: 0;
    background-color: var(--c-superficie);   /* siempre opaco: nada se transparenta al desplazar */
    background-clip: padding-box;
    z-index: 2;
    box-shadow: 0 1px 0 var(--c-borde), 0 2px 4px rgb(var(--sombra-rgb) / .06);
}

/* ------------------------------------------------------------------ Ventanas (modales de Bootstrap) */
.modal-content { border-radius: var(--r-lg); border: 1px solid var(--c-borde); box-shadow: var(--sombra-3); }
.modal-header { border-bottom: 1px solid var(--c-borde); padding: 16px 20px; }
.modal-header .modal-title, .modal-title { font-size: var(--t-md); font-weight: 600; margin: 0; }
.modal-body { padding: 20px; font-size: var(--t-base); color: var(--c-texto); }
.modal-footer { border-top: 1px solid var(--c-borde); padding: 14px 20px; gap: 8px; }
.modal-footer > * { margin: 0; }
.modal.fade .modal-dialog { transform: scale(.96); transition: transform .18s ease-out, opacity .18s ease-out; opacity: 0; }
.modal.show .modal-dialog { transform: scale(1); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .modal.fade .modal-dialog { transition: none; } }

/* ------------------------------------------------------------------ Acceso y cambio de contraseña */
.login-pie { display: flex; justify-content: center; gap: var(--e-4); margin-top: var(--e-4); font-size: var(--t-sm); }
.login-pie form { margin: 0; }
.login-secundario { background: none; border: none; padding: 4px 8px; color: var(--c-texto-suave); font-size: var(--t-sm); cursor: pointer; width: auto; }
.login-secundario:hover { background: none; color: var(--c-texto); text-decoration: underline; }

/* ------------------------------------------------------------------ Varios comunes */
.estado-filter-form { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: var(--t-sm); color: var(--c-texto-suave); }
.estado-filter-form select { margin: 0; width: auto; min-width: 160px; max-width: 100%; }

/*
 * .clamp-2: el texto YA viene precortado desde PHP (truncar_caracteres(), a
 * un tamano que cabe holgado en 2 lineas) con su propio "..." agregado como
 * texto real. A proposito NO se usa -webkit-line-clamp aqui: combinarlo con
 * un max-height fijo producia un pleito entre los dos mecanismos de corte
 * (el line-clamp del navegador cortaba a mitad de glifo la 2a linea, o se
 * comia el "..." que ya venia en el texto). Con el texto ya corto de por si,
 * overflow:hidden + un max-height con margen amplio (bastante mas de 2
 * lineas) es solo una red de seguridad que en el uso normal nunca llega a
 * activarse -- nunca corta a la mitad de un renglon.
 */
.clamp-2 {
    max-width: 320px;
    overflow: hidden;
    line-height: 1.4;
    max-height: 4.2em;
    cursor: help;
}

.actions-fixed { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }
.actions-fixed form { display: inline-block; margin: 0; }

.producto-heading { display: flex; flex-direction: column; gap: 4px; }
.producto-clave { font-size: 13px; font-weight: 600; color: var(--c-enlace); text-transform: uppercase; letter-spacing: 0.03em; }
.producto-descripcion { font-size: 20px; font-weight: 700; line-height: 1.3; }

.action-bar { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); display: flex; gap: 10px; }
.action-bar form { margin: 0; }


.almacen-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.almacen-tabs a {
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 6px;
    text-decoration: none;
    color: var(--text);
    font-size: 13px;
}
.almacen-tabs a.active { background: var(--primary); color: #fff; border-color: var(--primary); }

.empty-state { color: var(--muted); font-size: 13px; padding: 24px 0; text-align: center; }

.vista-tabs { margin-bottom: 0; }
.vista-tabs .nav-link { color: var(--muted); font-size: 14px; }
.vista-tabs .nav-link.active { color: var(--c-enlace); font-weight: 600; }

.table-excel { border: 1px solid var(--border); }
.table-excel th, .table-excel td { border: 1px solid var(--border); }
.table-excel thead th { background: var(--c-fondo); }
.table-excel tbody tr:nth-child(even) { background: var(--c-superficie-2); }

.resultados-layout { display: grid; grid-template-columns: 1fr 280px; gap: 20px; align-items: start; }
.insumos-panel { position: sticky; top: 100px; }
.insumos-panel-table { width: 100%; font-size: 12px; }
.insumos-panel-table td { padding: 4px 6px; border-bottom: 1px solid var(--border); }
.insumos-panel-table td:last-child { text-align: right; font-weight: 600; }

@media (max-width: 1100px) {
    .resultados-layout { grid-template-columns: 1fr; }
    .insumos-panel { position: static; }
}

/* --- Movimientos: calendario --- */
.calendar-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }

.calendar-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 4px;
}

.calendar-dow { text-align: center; font-size: 12px; color: var(--muted); font-weight: 600; padding: 4px 0; }

.calendar-day {
    aspect-ratio: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--text);
    font-size: 13px;
    border: 1px solid transparent;
}

.calendar-day:hover { background: var(--bg); }
.calendar-day-empty { visibility: hidden; }
.calendar-day-today { border-color: var(--primary); font-weight: 700; }
.calendar-day-selected { background: var(--primary); color: #fff; }
.calendar-day-selected:hover { background: var(--primary-hover); color: #fff; }
.calendar-day-dot { width: 6px; height: 6px; border-radius: 999px; background: var(--warn); }
.calendar-day-selected .calendar-day-dot { background: var(--c-superficie); }

/* Version compacta: celdas mas chicas, con los codigos de los items del dia
   (no solo un punto), ordenados por hora — usada en el layout de Movimientos
   junto al formulario. */
.calendar-grid-compact { gap: 3px; }
.calendar-day-compact {
    aspect-ratio: auto;
    min-height: 52px;
    justify-content: flex-start;
    align-items: flex-start;
    padding: 3px 4px;
    gap: 0;
    overflow: hidden;
}
.calendar-day-compact .calendar-day-number { font-size: 11px; font-weight: 600; margin-bottom: 1px; }
.calendar-day-item {
    font-size: 9px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    width: 100%;
    color: var(--muted);
}
.calendar-day-compact.calendar-day-selected .calendar-day-item { color: #e5e7eb; }
.calendar-day-item-entrada::before { content: "↑ "; color: var(--ok); }
.calendar-day-item-salida::before { content: "↓ "; color: var(--warn); }
.calendar-day-compact.calendar-day-selected .calendar-day-item-entrada::before,
.calendar-day-compact.calendar-day-selected .calendar-day-item-salida::before { color: #fff; }
.calendar-day-extra { font-size: 9px; color: var(--muted); }

/* --- Movimientos: layout (formulario izquierda, calendario derecha) ---
   align-items: stretch (el default, explicito aqui para que quede claro) hace
   que ambas columnas del grid midan lo mismo de alto SIEMPRE, sin importar
   cuanto contenido tenga cada una -- ya no es una aproximacion visual. */
.movimientos-layout { display: grid; grid-template-columns: 1.2fr 1fr; gap: 20px; align-items: stretch; }
@media (max-width: 950px) {
    .movimientos-layout { grid-template-columns: minmax(0, 1fr); }
}

/* La columna izquierda es un flex-column que ocupa el 100% del alto que le
   dio el grid; su ultima card (Buscar producto o insumo) crece con flex:1
   para absorber cualquier sobrante y que el conjunto cuadre exacto con la
   altura de la card del calendario, sin huecos ni fragmentos sueltos. */
.movimientos-col-izq { display: flex; flex-direction: column; gap: 20px; }
.movimientos-col-izq .card:last-child { flex: 1; display: flex; flex-direction: column; }

/* --- Movimientos: chooser de tipo/entrada-salida --- */
.mov-item-tabs { display: flex; gap: 8px; list-style: none; padding: 0; margin: 0 0 16px; }
.mov-item-tabs .nav-link {
    background: var(--bg);
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 6px 16px;
    font-size: 13px;
}
.mov-item-tabs .nav-link.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.mov-item-tabs .nav-link:disabled, .mov-choice-btn:disabled {
    opacity: .4;
    cursor: not-allowed;
    pointer-events: none;
}
#movStartBtn:disabled {
    background: var(--border) !important;
    border-color: var(--border) !important;
    color: var(--muted) !important;
    cursor: not-allowed;
}

.mov-choice-buttons { display: flex; gap: 12px; }
.mov-choice-btn { flex: 1; padding: 20px 12px; font-size: 15px; font-weight: 600; }

/* Formulario de captura dentro del modal ancho: 2 columnas para que quede
   horizontal (mas ancho que alto) en vez de una sola columna larga. */
.mov-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; align-items: start; }
.mov-form-grid-full { grid-column: 1 / -1; }
@media (max-width: 700px) {
    .mov-form-grid { grid-template-columns: 1fr; }
}

.dropzone {
    max-width: 640px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 2px dashed var(--border);
    border-radius: 10px;
    padding: 32px 20px;
    text-align: center;
    cursor: pointer;
    color: var(--muted);
    background: var(--bg);
}

.dropzone:hover, .dropzone.drag-over { border-color: var(--primary); background: var(--azul-fondo); color: var(--c-enlace); }
.dropzone.has-file { border-color: var(--c-exito-marca); border-style: solid; background: var(--verde-fondo); }
.dropzone input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; margin: 0; }
.dropzone-text { font-size: 14px; }
.dropzone-filename { font-size: 13px; font-weight: 600; color: var(--text); }

.stock-zero { color: var(--c-texto); font-weight: 700; background: var(--c-relleno-2); border-radius: 4px; padding: 2px 8px; }
.stock-red { color: var(--danger); font-weight: 700; }
.stock-yellow { color: var(--ambar-texto); font-weight: 700; }

/* --- Dashboard: KPIs y graficas --- */
.almacen-panel-title { font-size: 15px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 12px; }

.kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 20px; }
@media (max-width: 900px) { .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 299.98px) { .kpi-grid { grid-template-columns: minmax(0, 1fr); } }

.kpi-card { background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-lg); box-shadow: var(--sombra-1); padding: 16px; min-width: 0; overflow-wrap: anywhere; }
.kpi-label { font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.kpi-value { font-size: 28px; font-weight: 700; line-height: 1; }
.kpi-value-small { font-size: 15px; font-weight: 600; }

.kpi-alertas-row { display: flex; gap: 10px; }
.kpi-alerta { display: flex; flex-direction: column; align-items: center; font-size: 20px; font-weight: 700; line-height: 1.1; }
.kpi-alerta small { font-size: 10px; font-weight: 500; color: var(--muted); text-transform: uppercase; }
.kpi-alerta-negra { color: var(--c-texto); }
.kpi-alerta-roja { color: var(--danger); }
.kpi-alerta-amarilla { color: var(--ambar-texto); }

.dash-panels { display: grid; gap: 20px; margin-bottom: 20px; }
.dash-panels.dash-panels-2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 1000px) { .dash-panels.dash-panels-2 { grid-template-columns: 1fr; } }

.chart-bars { display: flex; flex-direction: column; gap: 10px; }
.chart-bar-row { display: grid; grid-template-columns: 90px 1fr 60px; align-items: center; gap: 10px; font-size: 12px; }
.chart-bar-label { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-bar-track { display: block; background: var(--bg); border-radius: 4px; height: 16px; overflow: hidden; }
.chart-bar-fill { display: block; height: 100%; border-radius: 4px; }
.chart-bar-value { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }

.chart-bar-fill-stock-red, .chart-bar-fill-danger { background: var(--c-error-marca); }
.chart-bar-fill-stock-yellow, .chart-bar-fill-warn { background: var(--ambar-solido); }
.chart-bar-fill-stock-zero { background: var(--c-texto); }
.chart-bar-fill-ok { background: var(--c-exito-marca); }
.chart-bar-fill-muted { background: var(--c-gris-medio); }
.chart-bar-fill-normal { background: var(--primary); }

.chart-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11px; color: var(--muted); margin-top: 12px; }
.chart-legend-item { display: flex; align-items: center; gap: 5px; }
.chart-legend-swatch { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }

/* Combobox con busqueda (autocompletar), usado tanto en "Registrar movimiento"
   como en "Buscar producto o insumo". */
.combo-wrap { position: relative; }
.combo-dropdown {
    position: absolute;
    z-index: 20;
    left: 0;
    right: 0;
    top: calc(100% - 12px);
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    max-height: 260px;
    overflow-y: auto;
    box-shadow: 0 8px 24px rgb(var(--sombra-rgb) / .1);
}
.combo-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 12px;
    cursor: pointer;
    font-size: 13px;
}
.combo-option:hover, .combo-option.active { background: var(--bg); }
.combo-option-main { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo-option-stock { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; flex-shrink: 0; }
.combo-empty { padding: 10px 12px; font-size: 13px; color: var(--muted); }
/* Unidad destino: nombre arriba; estado e institución abajo, en gris. */
.combo-option.combo-option-unidad { flex-direction: column; align-items: flex-start; gap: 2px; }
.combo-option-unidad .combo-option-main { white-space: normal; }
.combo-option-sub { font-size: 11px; color: var(--muted); }

/* Detalle de producto/insumo dentro del modal de "Buscar producto o insumo". */
.detalle-dl { display: grid; grid-template-columns: 150px 1fr; gap: 10px 16px; margin: 0; }
.detalle-dl dt { color: var(--muted); font-size: 12px; }
.detalle-dl dd { margin: 0; font-size: 14px; word-break: break-word; }

/* Botones de guardar sin cambios pendientes (data-detectar-cambios en app.js). */
form[data-detectar-cambios] button[type=submit]:disabled,
form[data-detectar-cambios] button:not([type]):disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Aviso de confirmación: lista de cambios por guardar. */
.confirm-cambios-titulo { margin-top: 14px; font-weight: 600; font-size: 13px; }
.confirm-cambios { margin: 6px 0 0; padding-left: 18px; font-size: 13px; }
.confirm-cambios li { margin: 3px 0; word-break: break-word; }
.confirm-antes { color: var(--muted); text-decoration: line-through; }
.confirm-despues { color: var(--text); font-weight: 600; }

/* Detalle de producto/insumo (Movimientos): ventana ancha, datos en 2 columnas;
   los textos largos (descripción, nombre corto, notas) ocupan todo el ancho. */
.detalle-dl.detalle-dl-2col { grid-template-columns: 1fr 1fr; gap: 14px 28px; }
.detalle-dl-2col > div { display: grid; grid-template-columns: 140px 1fr; gap: 4px 12px; align-items: baseline; }
.detalle-dl-2col > div.detalle-ancho { grid-column: 1 / -1; }
@media (max-width: 700px) { .detalle-dl.detalle-dl-2col { grid-template-columns: 1fr; } }


/* Tablas cuyos renglones abren un detalle (ej. resumen de Existencias). */
.tabla-clicable tbody tr[data-href] { cursor: pointer; }
.tabla-clicable tbody tr[data-href]:hover { background: var(--bg); }

/* Resultados Generales: lista de insumos dentro de la fila. */
.tabla-generales select.insumo-resultado { min-width: 210px; font-size: 13px; padding: 4px 8px; margin: 0; }
/* La tabla se desplaza dentro de su columna en vez de empujar el panel de insumos fuera de la pantalla. */
.resultados-layout > div { min-width: 0; }

/* Resultados Generales: almacén en consulta (distinto del configurado), naranja suave. */
.tabla-generales select.almacen-consulta { min-width: 120px; font-size: 13px; padding: 4px 8px; margin: 0; }
.tabla-generales td.celda-almacen.en-consulta { background: var(--naranja-fondo-2); }
.tabla-generales td.celda-almacen.en-consulta select { background-color: var(--naranja-fondo); border-color: var(--naranja-borde); }
.tabla-generales .nota-consulta { font-size: 11px; color: var(--naranja-texto); margin-top: 4px; }
.tabla-generales .nota-consulta a { color: var(--c-enlace); }


/* Detalle por pedido: columnas del Excel + cálculo; una línea más marcada separa las dos partes. */
.tabla-pedidos th, .tabla-pedidos td { white-space: nowrap; }
.tabla-pedidos td.clamp-2 { white-space: normal; min-width: 260px; }
.tabla-pedidos .inicio-calculo, .tabla-pedidos td.celda-almacen { border-left: 2px solid var(--c-gris-medio); }

/* Detalle por pedido como libro de Excel: hojas abajo, filtro ▾ en cada encabezado. */
.tabla-filtrable thead th { padding-right: 30px; position: sticky; }
.tabla-filtrable .filtro-col {
    position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
    width: 22px; height: 22px; padding: 0; margin: 0; line-height: 20px; font-size: 11px;
    background: var(--c-superficie); color: var(--muted); border: 1px solid var(--border); border-radius: 4px; cursor: pointer;
}
.tabla-filtrable .filtro-col:hover { border-color: var(--primary); color: var(--c-enlace); }
.tabla-filtrable .filtro-col.activo { background: var(--primary); border-color: var(--primary); color: #fff; }
.menu-filtro {
    position: absolute; z-index: 1060; width: 280px; padding: 8px;
    background: var(--c-superficie); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgb(var(--sombra-rgb) / .15);
    font-size: 13px;
}
.menu-filtro > button:not(.btn) {
    display: block; width: 100%; text-align: left; margin: 0; padding: 6px 8px;
    background: none; border: 0; border-radius: 4px; color: var(--text); font-size: 13px; cursor: pointer;
}
.menu-filtro > button:not(.btn):hover:not(:disabled) { background: var(--bg); }
.menu-filtro > button:disabled { color: var(--c-texto-tenue); cursor: default; }
.menu-filtro .mf-borrar { border-bottom: 1px solid var(--border) !important; border-radius: 0 !important; margin-bottom: 8px !important; }
.menu-filtro .mf-buscar { width: 100%; margin: 0 0 6px; padding: 6px 8px; font-size: 13px; }
.menu-filtro .mf-lista { max-height: 240px; overflow-y: auto; border: 1px solid var(--border); border-radius: 4px; padding: 4px 6px; }
.menu-filtro .mf-lista label { display: block; margin: 0; padding: 3px 0; font-weight: normal; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
.menu-filtro .mf-lista label[hidden] { display: none; }
.menu-filtro .mf-lista input { width: auto; margin: 0 4px 0 0; vertical-align: middle; }
.menu-filtro .mf-acciones { display: flex; justify-content: flex-end; gap: 6px; margin-top: 8px; }
.menu-filtro .mf-acciones .btn { margin: 0; }
.hojas-barra {
    display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; flex-wrap: wrap;
    border-top: 1px solid var(--border); background: var(--c-fondo); padding: 0 8px 6px; margin-top: -1px;
}
.hojas-tabs { display: flex; gap: 2px; }
.hoja-tab {
    margin: 0; padding: 7px 16px; font-size: 13px; color: var(--muted);
    background: var(--c-relleno-2); border: 1px solid var(--border); border-top: 0; border-radius: 0 0 6px 6px; cursor: pointer;
}
.hoja-tab:hover { color: var(--text); }
.hoja-tab.activa { background: var(--c-superficie); color: var(--ok); font-weight: 600; border-bottom: 3px solid var(--c-exito-marca); }
.hoja-tab.filtrada::after { content: " ⧩"; color: var(--c-enlace); }
.hoja-tab .hoja-cuenta { font-size: 11px; color: var(--muted); font-weight: normal; margin-left: 4px; }
.hojas-estado { display: flex; align-items: center; gap: 10px; padding-top: 6px; font-size: 13px; color: var(--muted); }
.hojas-estado .btn { margin: 0; }

/* Detalle por pedido: el contenedor siempre mide lo mismo; lo que falta se llena con renglones vacíos. */
.libro-excel .table-scroll.table-scroll-tall { height: 560px; }
.libro-excel tbody.filas-relleno td { height: 40px; padding: 0 10px; background: var(--c-superficie); }
.libro-excel .hoja { position: relative; }
.libro-excel .hoja-vacia {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2;
    padding: 10px 18px; background: var(--c-superficie); border: 1px solid var(--border); border-radius: 8px; color: var(--muted); font-size: 14px;
}

/* "Filtros aplicados", a la derecha de las pestañas de la planeación. */
.vista-tabs { align-items: flex-end; }
.barra-derecha {
    margin-left: auto; align-self: center; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    justify-content: flex-end; padding: 4px 0 6px; font-size: 13px; max-width: 72%;
}
.filtros-aplicados { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.restablecer-vista {
    margin: 0; padding: 3px 10px; font-size: 12px; cursor: pointer; white-space: nowrap;
    background: var(--c-superficie); color: var(--muted); border: 1px solid var(--border); border-radius: 6px;
}
.restablecer-vista:hover { color: var(--text); border-color: var(--muted); }
.filtros-aplicados .fa-titulo { color: var(--muted); font-weight: 600; white-space: nowrap; }
.filtros-aplicados .fa-lista { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.filtros-aplicados .fa-ninguno { color: var(--muted); font-style: italic; }
.filtros-aplicados .fa-grupo { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.filtros-aplicados button { margin: 0; font-size: 12px; cursor: pointer; }
.filtros-aplicados .fa-hoja { background: none; border: 0; padding: 0 2px; color: var(--text); font-weight: 600; }
.filtros-aplicados .fa-hoja:hover { color: var(--c-enlace); text-decoration: underline; }
.filtros-aplicados .fa-chip {
    display: inline-flex; align-items: center; gap: 6px; padding: 3px 6px 3px 10px;
    background: var(--azul-fondo); color: var(--c-enlace); border: 1px solid var(--azul-borde); border-radius: 999px;
}
.filtros-aplicados .fa-chip:hover { background: var(--azul-fondo-2); border-color: var(--primary); }
.filtros-aplicados .fa-x {
    display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
    border-radius: 50%; background: var(--azul-borde); font-size: 13px; line-height: 1;
}
.filtros-aplicados .fa-chip:hover .fa-x { background: var(--primary); color: #fff; }
.filtros-aplicados .fa-todos { background: var(--c-superficie); color: var(--danger); border: 1px solid var(--rojo-fondo-2); border-radius: 6px; padding: 3px 10px; }
.filtros-aplicados .fa-todos:hover { background: var(--rojo-fondo-2); }

/* Tooltip propio (app.js, [data-tooltip]). */
[data-tooltip] { cursor: help; }
.badge[data-tooltip] { text-decoration: underline dotted; text-underline-offset: 3px; }
.tooltip-flotante {
    position: fixed; z-index: 2000; max-width: 320px; padding: 8px 10px;
    background: var(--c-invertido); color: #fff; font-size: 12px; line-height: 1.4; border-radius: 6px;
    box-shadow: 0 6px 18px rgb(var(--sombra-rgb) / .25); pointer-events: none;
}

/* Editor de configuración: cantidad corta y unidad base a lo ancho de su texto
   ("ENVASE (unidad del producto)", "Corrugados de esta configuración"). Más
   específico que la regla general de input[type=text], que la estiraba. */

/* Empaque provisional (carga BQ LOTES 2026): leyenda en resultados y configuraciones. */
.aviso-provisional { margin-top: 4px; font-size: 11px; line-height: 1.3; color: var(--ambar-texto); white-space: normal; max-width: 190px; }
.aviso-provisional::before { content: "⚠ "; }
.aviso-provisional-general {
    margin: 0 0 14px; padding: 10px 14px; font-size: 13px; color: var(--ambar-texto);
    background: var(--ambar-fondo); border: 1px solid var(--ambar-solido); border-radius: 8px;
}
.badge-provisional { background: var(--ambar-fondo-2); color: var(--ambar-texto); }
.supuesto-provisional { margin-top: 6px; font-size: 12px; color: var(--ambar-texto); background: var(--ambar-fondo); border: 1px solid var(--ambar-borde); border-radius: 6px; padding: 6px 8px; white-space: pre-line; }
.aviso-incompleta { margin-top: 4px; font-size: 11px; line-height: 1.3; color: var(--c-texto-2); white-space: normal; max-width: 190px; }
.aviso-incompleta::before { content: "◌ "; }
.aviso-incompleta-general { background: var(--c-fondo); border-color: var(--c-borde-fuerte); color: var(--c-texto-2); }

/* Editor de configuración: contexto, capacidad con etiqueta y estado de cada fila. */
.config-contexto { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-top: 14px; }
.config-contexto div { display: grid; gap: 2px; }
.config-contexto span { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.config-contexto strong { font-size: 15px; }
.chip-estado { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.chip-confirmado { background: var(--verde-fondo-2); color: var(--verde-texto); }
.chip-provisional { background: var(--ambar-fondo-2); color: var(--ambar-texto); }
.chip-pendiente { background: var(--c-relleno-2); color: var(--c-texto-2); }

/* Lotes (2026-09-30): alta de lote nuevo en la entrada y tabla de lotes del detalle. */
.mov-lote-nuevo { margin-bottom: 16px; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; padding: 12px; background: var(--bg); border: 1px dashed var(--border); border-radius: 8px; }
.mov-lote-nuevo > div:first-child { grid-column: 1 / -1; }
.tabla-lotes { font-size: 13px; }
.tabla-lotes td, .tabla-lotes th { padding: 6px 8px; }

/* Productos «Ambos» (2026-09-30): búsqueda y filtros al instante. */
.filtros-vivos { display: grid; grid-template-columns: minmax(220px, 2fr) repeat(3, minmax(150px, 1fr)) auto; gap: 12px; align-items: end; margin-bottom: 12px; }
.filtros-vivos label { font-size: 12px; color: var(--muted); margin-bottom: 4px; display: block; }
.filtros-vivos input, .filtros-vivos select { margin-bottom: 0; }
.filtros-vivos input[type=search] { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 14px; font-family: inherit; }
.filtro-resumen { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; font-size: 13px; color: var(--muted); white-space: nowrap; }
@media (max-width: 900px) { .filtros-vivos { grid-template-columns: 1fr 1fr; } .filtro-busqueda { grid-column: 1 / -1; } .filtro-resumen { align-items: flex-start; } }
#tablaTotal mark { background: var(--ambar-borde); color: inherit; padding: 0 1px; border-radius: 2px; }
#tablaTotal tfoot .fila-total td { font-weight: 700; background: var(--bg); border-top: 2px solid var(--border); }

/* Rol consultor (2026-09-30): solo consulta. El servidor rechaza cualquier escritura; aquí solo se ocultan los controles. */
.solo-consulta-aviso { display: none; }
.solo-consulta .solo-consulta-aviso { display: block; padding: 10px 12px; border-radius: 6px; background: var(--bg); color: var(--muted); font-size: 13px; }
.solo-consulta .solo-edicion,
.solo-consulta a[href$="/crear"], .solo-consulta a[href*="/crear?"], .solo-consulta a[href$="/editar"],
.solo-consulta [data-editar],
.solo-consulta form.solo-lectura button[type=submit] { display: none !important; }
.solo-consulta form.solo-lectura input, .solo-consulta form.solo-lectura select, .solo-consulta form.solo-lectura textarea { background: var(--bg); cursor: default; }

/* Configuración en solo consulta (2026-09-30): los datos como texto, sin controles. */

/* Consulta de Lotes (2026-09-30). */
.kpi-lotes { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 16px; }
.kpi-lotes > div { background: var(--card-bg, var(--c-superficie)); border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.kpi-lotes strong { display: block; font-size: 22px; line-height: 1.1; }
.kpi-lotes span { font-size: 12px; color: var(--muted); }
.kpi-lotes .kpi-alerta { border-color: var(--ambar-solido); background: var(--ambar-fondo); }
@media (max-width: 900px) { .kpi-lotes { grid-template-columns: repeat(2, 1fr); } }
.filtros-vivos-lotes { grid-template-columns: minmax(220px, 2fr) repeat(4, minmax(130px, 1fr)) auto; }
@media (max-width: 1100px) { .filtros-vivos-lotes { grid-template-columns: 1fr 1fr; } .filtros-vivos-lotes .filtro-busqueda { grid-column: 1 / -1; } }
.stock-negativo { color: var(--danger); }
tr.fila-historica td { color: var(--muted); }
.tabla-filtros-vivos mark { background: var(--ambar-borde); color: inherit; padding: 0 1px; border-radius: 2px; }
.tabla-filtros-vivos tfoot .fila-total td { font-weight: 700; background: var(--bg); border-top: 2px solid var(--border); }
body.page-lotes .container { max-width: 1680px; }
body.page-lotes .celda-producto { max-width: 240px; font-size: 12px; }
body.page-lotes #tablaLotes td, body.page-lotes #tablaLotes th { padding-left: 8px; padding-right: 8px; }
/* Lote = lote del fabricante; si no hay, «Sin lote registrado» en gris. */
.celda-lote { font-weight: 600; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.celda-lote.sin-lote { font-weight: 400; font-family: inherit; color: var(--muted); font-style: italic; }
.celda-marca { font-size: 12px; max-width: 220px; }
/* Estado del lote (activar / eliminar) en su formulario. */
.zona-lote-acciones { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
@media (max-width: 700px) { .zona-lote-acciones { grid-template-columns: 1fr; } }

/* Inventario → Actualizar stock (2026-10-01). */
.stock-archivos { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.stock-archivo { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; background: var(--card-bg); }
.stock-archivo-nombre { flex: 1; font-weight: 500; word-break: break-all; }
.stock-archivo-peso { color: var(--muted); font-size: 12px; white-space: nowrap; }
.stock-acciones { display: flex; align-items: center; gap: 14px; margin-top: 16px; }
.stock-progreso { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
.stock-barra { height: 8px; background: var(--bg); border-radius: 4px; overflow: hidden; }
.stock-barra span { display: block; height: 100%; width: 0; background: var(--primary); transition: width 0.2s; }
.stock-progreso.trabajando .stock-barra span { width: 100% !important; background: linear-gradient(90deg, var(--primary) 0%, var(--azul-borde) 50%, var(--primary) 100%); background-size: 200% 100%; animation: stock-trabajando 1.2s linear infinite; }
@keyframes stock-trabajando { from { background-position: 200% 0; } to { background-position: 0 0; } }
.reporte-stock-encabezado { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 12px; }
.reporte-stock-meta { color: var(--muted); font-size: 12px; margin-left: auto; }
.reporte-stock-almacen { margin-top: 16px; }
.reporte-stock-almacen h4 { margin: 0 0 8px; font-size: 16px; }
.reporte-stock-archivo { font-weight: 400; color: var(--muted); font-size: 12px; margin-left: 6px; }
.reporte-stock-igual { color: var(--muted); margin: 0; }
.reporte-stock-dif { font-size: 11px; margin-left: 4px; }
.reporte-stock-dif.sube { color: var(--ok); }
.reporte-stock-dif.baja { color: var(--danger); }
.reporte-stock-detalle td { background: var(--bg); padding-top: 4px !important; padding-bottom: 6px !important; }
.reporte-stock-detalle summary { cursor: pointer; font-size: 12px; color: var(--c-enlace); }
.reporte-stock-detalle ul { margin: 4px 0 8px; padding-left: 18px; font-size: 12px; }
.reporte-stock-sub { font-size: 11px; font-weight: 600; text-transform: uppercase; color: var(--muted); margin-top: 6px; }

/* Productos «Ambos» por lote (2026-10-01): las columnas de cada almacén con un fondo suave y una línea donde empieza cada clave. */
.tabla-ambos-lotes tbody .col-cedis, .tabla-ambos-lotes tfoot .col-cedis { background: rgb(var(--azul-rgb) / 0.04); }
.tabla-ambos-lotes tbody .col-xochi, .tabla-ambos-lotes tfoot .col-xochi { background: rgb(var(--verde-rgb) / 0.05); }
/* Encabezado fijo SÓLIDO: al desplazar, los datos no se ven a través (mismo tono, pero opaco). */
.tabla-ambos-lotes thead th { background: var(--card-bg); }
.tabla-ambos-lotes thead th.col-cedis { background: var(--azul-fondo); }
.tabla-ambos-lotes thead th.col-xochi { background: var(--verde-fondo); color: var(--verde-texto); }
.tabla-ambos-lotes tbody tr.inicio-clave td { border-top: 2px solid var(--border); }
.tabla-ambos-lotes tbody tr.lote-siguiente td:nth-child(-n+3), .tabla-ambos-lotes tbody tr.lote-siguiente .total-clave { color: var(--muted); }
.tabla-ambos-lotes .celda-lote-ambos { min-width: 170px; }
.tabla-ambos-lotes .lote-nombre { display: block; font-size: 11px; color: var(--muted); }
.tabla-ambos-lotes .celda-vacia { color: var(--muted); font-size: 12px; }

/* Productos «Ambos» como Excel (2026-10-01): búsqueda, filtros aplicados y conteo en una línea; los filtros van en ▾ de cada encabezado. */
.filtros-vivos.filtros-vivos-excel { grid-template-columns: minmax(240px, 1.2fr) minmax(0, 2fr) auto; }
.filtros-vivos-excel .filtros-aplicados { align-self: end; padding-bottom: 6px; font-size: 13px; }
@media (max-width: 900px) { .filtros-vivos.filtros-vivos-excel { grid-template-columns: 1fr; } .filtros-vivos-excel .filtros-aplicados { justify-content: flex-start; } }
body.page-ambos .container { max-width: 1680px; }
body.page-ambos .tabla-ambos-lotes .clamp-2 { max-width: 300px; }
.alert-warning-suave { background: var(--ambar-fondo); border: 1px solid var(--ambar-solido); color: var(--ambar-texto); border-radius: 8px; padding: 10px 14px; margin-top: 10px; font-size: 13px; }
.alert-warning-suave ul { margin: 6px 0 0; padding-left: 18px; }

/* Ventana de opciones de exportación (Productos · Ambos, 2026-10-05). */
.exportar-opciones { border: none; margin: 0 0 10px; padding: 0; }
.exportar-opciones legend { font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 6px; }
.exportar-opcion { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; margin: 0 0 8px; border: 1px solid var(--border); border-radius: 10px; cursor: pointer; }
.exportar-opcion:has(input:checked) { border-color: var(--primary); background: var(--azul-fondo); }
.exportar-opcion input { width: auto !important; margin: 3px 0 0 !important; flex: none; }
.exportar-opcion span { display: flex; flex-direction: column; gap: 2px; }
.exportar-opcion small { color: var(--muted); font-size: 12.5px; }

/* Insumos · Ambos (2026-10-05): semáforo como color del número (sin tapar el tinte de la columna). */
.semaforo.stock-zero { padding: 1px 7px; }

/* Stock total de ambas plantas (2026-10-05): violeta, para que destaque frente a CEDIS (azul) y Xochimilco (verde). */
.tabla-ambos-lotes tbody .col-total, .tabla-ambos-lotes tfoot .col-total { background: rgb(var(--violeta-rgb) / 0.09); color: var(--violeta-texto); font-weight: 700; }
.tabla-ambos-lotes thead th.col-total { background: var(--violeta-fondo); color: var(--violeta-texto); }
.tabla-ambos-lotes thead th.col-total .filtro-btn { color: var(--violeta-texto); }
/* Disponible total: ámbar, distinto de CEDIS (azul), Xochimilco (verde) y stock general (violeta). */
.tabla-ambos-lotes tbody .col-disponible-total, .tabla-ambos-lotes tfoot .col-disponible-total { background: var(--ambar-fondo); color: var(--ambar-texto); font-weight: 700; }
.tabla-ambos-lotes thead th.col-disponible-total { background: var(--ambar-fondo); color: var(--ambar-texto); }
.tabla-ambos-lotes thead th.col-disponible-total .filtro-btn { color: var(--ambar-texto); }

/* Configuraciones (rediseño 2026-10-05): cadena de empaque, grupos por nivel y renglones legibles. */
.chip-estimado { background: var(--azul-fondo-2); color: var(--indigo-texto); }
.chip-mini { font-size: 11px; padding: 1px 8px; margin-top: 4px; }
.config-volver { margin: 0 0 12px; }
.config-cabecera .producto-descripcion { font-size: 17px; }
.cadena-empaque { list-style: none; display: flex; flex-wrap: wrap; gap: 0; margin: 18px 0 0; padding: 0; }
.cadena-empaque li { display: grid; gap: 2px; padding: 10px 28px 10px 16px; background: var(--c-superficie-2); border: 1px solid var(--border); border-left: 0; position: relative; min-width: 150px; }
.cadena-empaque li:first-child { border-left: 1px solid var(--border); border-radius: 8px 0 0 8px; }
.cadena-empaque li:last-child { border-radius: 0 8px 8px 0; }
.cadena-empaque li:not(:last-child)::after { content: '›'; position: absolute; right: 8px; top: 50%; transform: translateY(-50%); color: var(--muted); font-size: 20px; }
.cadena-empaque .cadena-nivel { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.cadena-empaque small { color: var(--muted); font-size: 12px; }
.cadena-empaque .cadena-pendiente strong { color: var(--ambar-texto); }
.config-insumos-titulo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.config-insumos-titulo h3 { margin: 0; }
.config-leyenda { display: flex; flex-wrap: wrap; gap: 6px; }
.cadena-mini { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.cadena-mini span { font-size: 12px; padding: 1px 7px; border-radius: 4px; background: var(--c-fondo); }
.cadena-mini span + span::before { content: '› '; color: var(--muted); }
.cadena-mini-pendiente { background: var(--ambar-fondo-2) !important; }

/* Planeación: PLAYO se totaliza por almacén después de sumar vueltas; nunca mezclar plantas. */
.resumen-playo { margin-bottom:20px; border-top:4px solid var(--violeta-solido); }
.resumen-playo-encabezado { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; margin-bottom:14px; }
.resumen-playo-encabezado h3 { margin:0 0 4px; }
.resumen-playo-encabezado p { margin:0; }
.resumen-playo-almacenes { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:14px; }
.resumen-playo-almacen { border:1px solid var(--border); border-radius:10px; padding:14px; background:var(--c-superficie-2); }
.resumen-playo-almacen h4 { margin:0 0 10px; font-size:15px; }
.resumen-playo-insumo + .resumen-playo-insumo { margin-top:12px; padding-top:12px; border-top:1px solid var(--border); }
.resumen-playo-insumo-titulo { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.resumen-playo-metricas { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; margin:12px 0 0; }
.resumen-playo-metricas div { padding:8px; border-radius:7px; background:var(--c-superficie); border:1px solid var(--c-borde); }
.resumen-playo-metricas dt { color:var(--muted); font-size:11px; text-transform:uppercase; letter-spacing:.03em; }
.resumen-playo-metricas dd { margin:3px 0 0; font-weight:700; font-size:14px; }
.aviso-playo { margin-top:10px; padding:9px 10px; border-radius:7px; font-size:12px; }
.aviso-playo span { display:block; margin-top:4px; }
.aviso-playo-incompleto { background:var(--ambar-fondo-2); color:var(--ambar-texto); }
.aviso-playo-faltante { background:var(--rojo-fondo-2); color:var(--rojo-texto); }
.aviso-playo-provisional { background:var(--naranja-fondo); color:var(--naranja-texto); }
@media (max-width: 900px) {
    .resumen-playo-almacenes { grid-template-columns:1fr; }
    .resumen-playo-encabezado { flex-direction:column; }
}
@media (max-width: 560px) {
    .resumen-playo-metricas { grid-template-columns:repeat(2, minmax(0, 1fr)); }
}

/* ============================================================================================================
   Configuraciones (2026-10-06): misma cuadrícula en consulta y edición. Todo acotado a .cfg; los controles son
   los de Bootstrap 5.3 (form-label, form-control, form-select, form-check, btn, row g-3). Las reglas globales de
   label / input / select / button de arriba se ajustan aquí solo dentro del módulo, por especificidad (sin !important).
   ============================================================================================================ */
/* Abrir o cerrar un editor no debe mover la página (el anclaje de desplazamiento del navegador la reacomodaba). */
.cfg { overflow-anchor: none; }
.cfg { --cfg-texto: var(--c-texto); --cfg-secundario: var(--c-texto-suave); --cfg-borde: var(--c-borde); --cfg-suave: var(--c-superficie-2); --cfg-foco: rgb(var(--azul-rgb) / .25); }
.cfg .config-volver { margin: 0 0 12px; font-size: .875rem; }
.cfg .card + .card { margin-top: 20px; }
.cfg h3 { font-size: 1.125rem; font-weight: 600; margin: 0; color: var(--cfg-texto); }

/* Controles dentro del módulo: alturas, márgenes y tipografía uniformes. */
.cfg label, .cfg .form-label { display: block; margin: 0 0 .375rem; font-size: .8125rem; font-weight: 500; color: var(--c-texto-2); }
.cfg .form-control, .cfg .form-select { margin: 0; padding: .4375rem .75rem; font-size: .875rem; line-height: 1.5; color: var(--cfg-texto);
    border: 1px solid var(--c-borde-fuerte); border-radius: 6px; background-color: var(--c-superficie); min-height: 2.375rem; }
.cfg .form-select { padding-right: 2.25rem; }
.cfg textarea.form-control { min-height: 3.75rem; resize: vertical; }
.cfg .form-control:focus, .cfg .form-select:focus { border-color: var(--primary); box-shadow: 0 0 0 .2rem var(--cfg-foco); outline: 0; }
.cfg .form-text { margin-top: .3125rem; font-size: .78rem; line-height: 1.4; color: var(--cfg-secundario); }
.cfg .form-check { display: flex; align-items: center; gap: .5rem; min-height: 1.5rem; padding-left: 0; margin: 0; }
.cfg .form-check-input { float: none; margin: 0; width: 1rem; height: 1rem; }
.cfg .form-check-label { display: inline; margin: 0; font-size: .875rem; color: var(--cfg-texto); font-weight: 400; }
.cfg .form-check-input:focus { box-shadow: 0 0 0 .2rem var(--cfg-foco); }

/* Cabecera y cadena de empaque. */
.cfg .config-contexto { margin-top: 16px; gap: 12px 32px; }
.cfg .cadena-empaque li { padding: 10px 30px 10px 16px; }

/* Título de la sección y leyenda de estados (discreta, no compite con el título). */
.cfg-titulo { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 16px; margin-bottom: 4px; }
.cfg-leyenda { display: flex; flex-wrap: wrap; gap: 4px; margin: 0; }
.cfg-leyenda .chip-estado { font-size: .6875rem; font-weight: 500; padding: 1px 8px; }

/* Grupos: encabezado discreto y una sola lista con separadores suaves (sin tarjetas por insumo). */
.cfg-grupo { margin-top: 22px; }
.cfg-grupo-titulo { margin: 0 0 8px; font-size: .75rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--cfg-secundario); }
.cfg-lista { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--cfg-borde); border-bottom: 1px solid var(--cfg-borde); }
.cfg-item + .cfg-item { border-top: 1px solid var(--cfg-borde); }

/* Renglón: identificación · relación · estado · acciones. Columnas fijas para que todo quede alineado entre insumos;
   las notas largas solo agregan altura (todo se alinea arriba). */
.cfg-resumen { display: grid; grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) 9.5rem 10.5rem; gap: 6px 20px; align-items: start; padding: 14px 4px; }
.cfg-lista-lectura .cfg-resumen { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) 9.5rem; }
.cfg-id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cfg-codigo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.cfg-codigo strong { font-size: .9375rem; color: var(--cfg-texto); }
.cfg-tipo { display: inline-block; width: auto; padding: 1px 8px; border-radius: 999px; font-size: .6875rem; font-weight: 500; background: var(--c-relleno); color: var(--c-texto-2); }
.cfg-nombre { font-size: .8125rem; color: var(--cfg-secundario); overflow-wrap: anywhere; }
.cfg-relacion { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cfg-relacion-texto { font-size: .9375rem; font-weight: 600; color: var(--cfg-texto); }
.cfg-nota { font-size: .8125rem; line-height: 1.45; color: var(--cfg-secundario); overflow-wrap: anywhere; }
.cfg-antecedente { font-style: italic; }
.cfg-aviso-provisional { align-self: flex-start; padding: 1px 8px; border-radius: 4px; font-size: .78rem; font-weight: 500; background: var(--ambar-fondo-2); color: var(--ambar-texto); }
.cfg-estado { display: flex; justify-content: flex-start; }
.cfg-estado .chip-estado { white-space: nowrap; }
.cfg-acciones { display: flex; justify-content: flex-end; align-items: center; gap: 6px; }
.cfg-acciones form { margin: 0; }
.cfg-pendiente .cfg-relacion-texto { font-weight: 500; color: var(--c-texto-2); }
.cfg-item.is-editando .cfg-equivalencia { display: none; }   /* la equivalencia se ve una sola vez: en el editor */

/* Panel de edición: debajo del resumen, a todo el ancho del renglón, sobre gris muy suave. */
.cfg-editor { margin: 0 4px 14px; padding: 18px 20px 16px; background: var(--cfg-suave); border: 1px solid var(--cfg-borde); border-radius: 8px; }
.cfg-editor .row { --bs-gutter-x: 1.25rem; --bs-gutter-y: 1rem; }
.cfg-alcance { display: inline-block; margin-left: 4px; padding: 0 6px; border-radius: 4px; font-size: .6875rem; font-weight: 500; vertical-align: 1px;
    background: var(--c-relleno); color: var(--c-texto-2); }
.cfg-alcance-insumo { background: var(--ambar-fondo-2); color: var(--ambar-texto); }
.cfg .equivalencia-playo { margin: -4px 0 0; font-size: .8125rem; color: var(--cfg-secundario); }
.cfg-editor-pie { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding-top: 14px;
    border-top: 1px solid var(--cfg-borde); }
.cfg-editor-marcas { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.cfg-editor-botones { display: flex; gap: 8px; margin-left: auto; }
.cfg .receta-revisar .form-check-label { color: var(--ambar-texto); font-weight: 500; }
.cfg .revisar-capacidad { border-color: var(--ambar-solido); box-shadow: 0 0 0 .2rem var(--ambar-borde); }
.cfg-error { margin: 0 0 14px; }
.cfg .form-control.is-invalid, .cfg .form-select.is-invalid { border-color: var(--c-error-marca); }
.cfg .form-control.is-invalid:focus, .cfg .form-select.is-invalid:focus { box-shadow: 0 0 0 .2rem rgb(var(--rojo-rgb) / .2); }
.cfg-ayuda { margin: 18px 0 0; }
.cfg-agregar .cfg-editor-pie { border-top: 0; padding-top: 0; }
.cfg-agregar h3 { margin-bottom: 14px; }

/* Tablet: estado y acciones bajo la relación. */
@media (max-width: 991.98px) {
    .cfg-resumen { grid-template-columns: minmax(0, 13rem) minmax(0, 1fr); }
    .cfg-lista-lectura .cfg-resumen { grid-template-columns: minmax(0, 13rem) minmax(0, 1fr); }
    .cfg-estado { grid-column: 1; }
    .cfg-acciones { grid-column: 2; justify-content: flex-end; }
}
/* Móvil: todo apilado; botones a lo ancho en el pie del editor. */
@media (max-width: 575.98px) {
    .cfg-resumen, .cfg-lista-lectura .cfg-resumen { grid-template-columns: minmax(0, 1fr) auto; padding: 12px 0; }
    .cfg-id, .cfg-relacion { grid-column: 1 / -1; }
    .cfg-estado { grid-column: 1; align-self: center; }
    .cfg-acciones { grid-column: 2; }
    .cfg-editor { margin: 0 0 12px; padding: 14px; }
    .cfg-editor-botones { width: 100%; }
    .cfg-editor-botones .btn { flex: 1 1 0; }
    .cfg .cadena-empaque li { flex: 1 1 100%; border-left: 1px solid var(--border); border-radius: 0; }
}

/* Ventana «Exportar a Excel» (2026-10-06): versión, columnas y vista previa con el aspecto del .xlsx. */
.exportar-excel .modal-xl { max-width: min(1500px, 96vw); }
.exportar-excel .xl-opciones { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 16px; margin-bottom: 14px; }
.exportar-excel .xl-versiones[hidden] + .xl-columnas { grid-column: 1 / -1; }
.exportar-excel fieldset { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin: 0; min-width: 0; }
.exportar-excel legend { float: none; width: auto; font-size: 13px; font-weight: 600; color: var(--muted); padding: 0 4px; margin: 0; display: flex; gap: 8px; align-items: center; }
.exportar-excel legend button { background: none; border: 0; padding: 0; color: var(--c-enlace); font-size: 12px; font-weight: 600; cursor: pointer; }
.exportar-excel .xl-version { display: flex; gap: 8px; align-items: flex-start; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; margin: 6px 0 0; cursor: pointer; }
.exportar-excel .xl-version:has(input:checked) { border-color: var(--primary); background: var(--azul-fondo); }
.exportar-excel .xl-version input { width: auto !important; margin: 3px 0 0 !important; flex: none; }
.exportar-excel .xl-version span { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; }
.exportar-excel .xl-version small { color: var(--muted); font-size: 12px; }
.exportar-excel .xl-izq { display: grid; gap: 12px; align-content: start; }
.exportar-excel .xl-resumen { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; font-size: 13px; display: grid; gap: 3px; }
.exportar-excel .xl-resumen strong { font-size: 18px; }
.exportar-excel .xl-generado { color: var(--muted); }
.exportar-excel .xl-columnas-lista { list-style: none; margin: 6px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 4px 8px; max-height: 230px; overflow: auto; }
.exportar-excel .xl-col { display: flex; gap: 4px; align-items: center; padding: 3px 4px 3px 8px; border: 1px solid var(--border); border-radius: 8px; font-size: 13px; }
.exportar-excel .xl-col.xl-col-si { border-color: var(--azul-borde); background: var(--azul-fondo); }
.exportar-excel .xl-col label { display: flex; gap: 6px; align-items: center; flex: 1; margin: 0; cursor: pointer; min-width: 0; }
.exportar-excel .xl-col label span { overflow-wrap: anywhere; }
.exportar-excel .xl-col input { width: auto !important; margin: 0 !important; }
.exportar-excel .xl-col button { border: 1px solid var(--border); background: var(--c-superficie); border-radius: 6px; width: 26px; height: 24px; line-height: 1; padding: 0; color: var(--text); }
.exportar-excel .xl-col button:disabled { opacity: .35; }
.exportar-excel .xl-previa-titulo { font-size: 13px; margin-bottom: 6px; }
.exportar-excel .xl-archivo, .exportar-excel .xl-nota { color: var(--muted); }
.exportar-excel .xl-previa { border: 1px solid var(--c-borde-fuerte); border-radius: 6px; overflow: auto; max-height: 52vh; background: var(--c-superficie); }
.exportar-excel .xl-cargando { padding: 30px; text-align: center; color: var(--muted); }
.exportar-excel .xl-aviso { margin-right: auto; color: var(--danger); font-size: 13px; }
@media (max-width: 800px) { .exportar-excel .xl-opciones { grid-template-columns: 1fr; } }

/* La hoja: Arial 11, encabezado en la fila 1, todo centrado salvo descripción y nombre (izquierda). */
.xl-hoja { width: auto; table-layout: fixed; border-collapse: collapse; font-family: Arial, Helvetica, sans-serif; font-size: 13px; color: var(--c-texto); }
.xl-hoja th, .xl-hoja td { border: 1px solid var(--c-borde); padding: 3px 6px; text-align: center; vertical-align: middle; white-space: normal; overflow-wrap: anywhere; }
.xl-hoja thead th { position: sticky; top: 0; z-index: 2; background: var(--c-relleno); color: var(--c-texto-suave); font-weight: 400; font-size: 11.5px; padding: 2px; }
.xl-hoja .xl-fila { width: 38px; background: var(--c-relleno); color: var(--c-texto-suave); font-weight: 400; font-size: 11.5px; position: sticky; left: 0; z-index: 1; }
.xl-hoja thead .xl-esquina { left: 0; z-index: 3; }
.xl-hoja .xl-encabezado td { background: var(--c-fondo); color: var(--c-texto-2); font-weight: 700; border-bottom: 2px solid var(--c-borde-fuerte); height: 40px; }
.xl-hoja .xl-encabezado td.xl-t-cedis { background: var(--azul-fondo-2); }
.xl-hoja .xl-encabezado td.xl-t-xochi { background: var(--c-relleno-2); }
.xl-hoja .xl-encabezado td.xl-t-total { background: var(--violeta-fondo); color: var(--violeta-texto); }
.xl-hoja tr.xl-banda td { background: var(--c-superficie-2); }
.xl-hoja tr.xl-inicio td:not(.xl-vacia):not(.xl-info) { border-top: 2px solid var(--c-borde-fuerte); }
.xl-hoja td.xl-fondo { background: var(--xl-fondo) !important; }
.xl-hoja td.xl-texto { text-align: left; padding-left: 10px; }
.xl-hoja td.xl-t-cedis { background: var(--azul-fondo); } .xl-hoja tr.xl-banda td.xl-t-cedis { background: var(--azul-fondo); }
.xl-hoja td.xl-t-xochi { background: var(--c-fondo); } .xl-hoja tr.xl-banda td.xl-t-xochi { background: var(--c-relleno); }
.xl-hoja td.xl-t-total { background: var(--violeta-fondo); color: var(--violeta-texto); } .xl-hoja tr.xl-banda td.xl-t-total { background: var(--violeta-fondo-2); }
.xl-hoja td.xl-num.xl-t-cedis, .xl-hoja td.xl-num.xl-t-xochi, .xl-hoja td.xl-num.xl-t-total { font-weight: 700; }
.xl-hoja td.xl-negativo { color: var(--rojo-texto); }
.xl-hoja td.xl-stock-red { color: var(--rojo-texto); font-weight: 700; }
.xl-hoja td.xl-stock-yellow { color: var(--ambar-texto); font-weight: 700; }
.xl-hoja td.xl-stock-zero { background: var(--c-relleno-2) !important; color: var(--c-texto); font-weight: 700; }
.xl-hoja td.xl-activo { background: var(--verde-fondo-2) !important; color: var(--verde-texto); font-weight: 700; }
.xl-hoja td.xl-inactivo { background: var(--c-relleno-2) !important; color: var(--c-texto-suave); font-weight: 700; }
.xl-hoja tr.xl-total td:not(.xl-vacia):not(.xl-info) { background: var(--c-fondo); font-weight: 700; border-top: 2px solid var(--c-borde-fuerte); }
.xl-hoja tr.xl-total td.xl-t-total { background: var(--violeta-fondo-2); color: var(--violeta-texto); }
.xl-hoja tr.xl-mas td:not(.xl-vacia):not(.xl-info) { color: var(--muted); font-style: italic; background: var(--c-superficie); }
.xl-hoja td.xl-vacia { border-color: var(--c-borde-suave); background: var(--c-superficie); }
.xl-hoja td.xl-info { text-align: left; color: var(--c-texto-2); border-color: var(--c-borde-suave); background: var(--c-superficie); }
.xl-hoja td.xl-info-titulo { color: var(--azul-texto); font-weight: 700; font-size: 15px; }
.xl-hoja tr.xl-sobra td:not(.xl-info):not(.xl-vacia) { border-color: var(--c-borde-suave); }
.xl-hoja td.xl-clave { white-space: nowrap; overflow-wrap: normal; }

/* Productos con apartados de Cobertura (2026-10-06): descripción completa, referencias y disponible. */
.celda-texto-completo { white-space: normal; min-width: 220px; max-width: 420px; overflow-wrap: anywhere; line-height: 1.35; }
.tabla-productos-inv .celda-texto-completo { min-width: 260px; }
body.page-ambos .tabla-productos-inv .clamp-2 { -webkit-line-clamp: unset; display: block; max-width: none; }
.tabla-productos-inv th { white-space: normal; min-width: 72px; vertical-align: bottom; }
.tabla-productos-inv th.th-texto { min-width: 260px; }
.tabla-productos-inv th.th-cobertura, .tabla-productos-inv .celda-cobertura { min-width: 220px; }
.tabla-productos-inv .celda-cobertura { white-space: normal; font-size: 12px; line-height: 1.35; }
.cob-ref { display: block; }
.cob-ref + .cob-ref, .cob-ref + .cob-ref-det, .cob-ref-det + .cob-ref { margin-top: 3px; }
.cob-ref-activo { color: var(--azul-texto); font-weight: 600; }
.cob-ref-pendiente { color: var(--ambar-texto); font-weight: 600; }
.cob-ref-prueba { color: var(--muted); font-style: italic; font-weight: 400; }
.cob-ref-det summary { cursor: pointer; list-style: revert; }
.cob-ref-det ul { margin: 4px 0 0; padding-left: 16px; font-weight: 400; color: var(--text); }
.cob-ref-det.cob-ref-prueba ul { color: var(--muted); }
.disp-nota { display: inline-block; width: 15px; height: 15px; margin-left: 4px; vertical-align: -2px; border-radius: 50%; background: var(--azul-fondo-2); cursor: help; position: relative; }
.disp-nota::after { content: 'i'; position: absolute; inset: 0; font: 700 10px/15px Georgia, serif; color: var(--indigo-texto); text-align: center; }
.disp-nota-ej { cursor: default; }
body.page-ambos main, body.page-ambos .container, body.page-ambos .card { min-width: 0; max-width: 100%; }
@media (max-width: 700px) {
    .tabla-productos-inv .celda-texto-completo { min-width: 200px; }
    .tabla-productos-inv th.th-cobertura, .tabla-productos-inv .celda-cobertura { min-width: 180px; }
}

.xl-hoja td.xl-num, .xl-hoja td.xl-clave, .xl-hoja td.xl-fecha { white-space: nowrap; overflow-wrap: normal; }

/* Detalles de tablas (2026-10-06): todo centrado; solo la descripción (o el nombre del insumo) a la izquierda. */
.tabla-centrada th, .tabla-centrada td, .tabla-centrada .celda-numero { text-align: center; }
.tabla-centrada td.celda-descripcion { text-align: left; white-space: normal; min-width: 260px; max-width: 420px; overflow-wrap: anywhere; line-height: 1.35; }
.tabla-centrada td.celda-nota { white-space: normal; min-width: 180px; max-width: 320px; overflow-wrap: anywhere; font-size: 12px; }
.tabla-centrada .celda-lote-ambos, .tabla-centrada .celda-cobertura { text-align: center; }
/* «Recortar descripciones»: 2 líneas con puntos suspensivos (el title tiene el texto completo). */
body.recortar-descripciones .tabla-centrada td.celda-descripcion .desc-texto { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.opcion-recortar { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); margin: 0 10px 0 0; cursor: pointer; white-space: nowrap; }
.opcion-recortar input { width: auto !important; margin: 0 !important; }
/* Cobertura en dos líneas: «6 | 1,450 · BIENESTAR» y «Cant: 100 · Lote: …». */
.cob-l1, .cob-l2 { display: block; }
.cob-l2 { font-weight: 400; color: var(--text); opacity: .85; }
.cob-ref-prueba .cob-l2 { color: var(--muted); }
.cob-ref-det li { margin-top: 4px; list-style: none; }
.cob-ref-det ul { padding-left: 0; }
.cob-origen { display: block; font-size: 11px; color: var(--muted); font-weight: 400; }
.celda-cobertura .cob-l1, .celda-cobertura .cob-l2 { overflow-wrap: normal; word-break: keep-all; }
.celda-cobertura .cob-l2 { white-space: nowrap; }

/* Navegación por celdas (2026-10-06, navegacion-celdas.js): la celda elegida, su fila y su encabezado. */
table.tabla-navegable { outline: none; }
table.tabla-navegable tbody td { cursor: cell; }
table.tabla-navegable tbody td a, table.tabla-navegable tbody td button, table.tabla-navegable tbody td summary { cursor: pointer; }
table.tabla-navegable tbody tr.fila-sel > td { background-image: linear-gradient(rgb(var(--azul-rgb) / .06), rgb(var(--azul-rgb) / .06)); }
table.tabla-navegable tbody td.celda-sel { box-shadow: inset 0 0 0 2px var(--azul-solido); background-image: linear-gradient(rgb(var(--azul-rgb) / .12), rgb(var(--azul-rgb) / .12)); }
table.tabla-navegable:not(:focus) tbody td.celda-sel { box-shadow: inset 0 0 0 2px var(--azul-borde); }
table.tabla-navegable thead th.col-sel { box-shadow: inset 0 -3px 0 var(--azul-solido); }
table.tabla-navegable tbody td.celda-copiada { box-shadow: inset 0 0 0 2px var(--verde-solido); }
table.tabla-navegable:focus-visible { box-shadow: 0 0 0 2px var(--azul-borde); }

/* Encabezados más destacados (2026-10-06): mismos tonos, un poco más oscuros y sólidos, bordes visibles y el
   texto centrado vertical y horizontalmente. */
.tabla-ambos-lotes thead th, .table-scroll-tall table.tabla-encabezado-solido thead th, table.tabla-encabezado-solido thead th { background: var(--c-relleno-2); color: var(--c-texto-2); font-weight: 700; vertical-align: middle; text-align: center;
    border: 1px solid var(--c-borde-fuerte); border-bottom: 2px solid var(--c-borde-fuerte); white-space: normal; line-height: 1.25; }
.tabla-ambos-lotes thead th.col-cedis { background: var(--azul-fondo-2); }
.tabla-ambos-lotes thead th.col-xochi { background: var(--verde-fondo-2); color: var(--verde-texto); }
.tabla-ambos-lotes thead th.col-total { background: var(--violeta-fondo-2); color: var(--violeta-texto); }
.tabla-ambos-lotes thead th.col-disponible-total { background: var(--ambar-fondo-2); color: var(--ambar-texto); }
.tabla-productos-inv th { vertical-align: middle; }

.ayuda-navegacion { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.ayuda-navegacion kbd { font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; padding: 2px 5px; border: 1px solid var(--border); border-bottom-width: 2px; border-radius: 4px; background: var(--c-superficie); color: var(--text); }

/* Encabezados con filtro ▾ (2026-10-06): el mismo margen a los dos lados, así el título queda centrado de verdad
   y nunca toca la flecha (que va a la derecha). Insumos: títulos cortos en una línea. */
.tabla-ambos-lotes.tabla-filtrable thead th { padding-left: 32px; padding-right: 32px; }
.tabla-ambos-lotes.tabla-filtrable thead th[data-sin-filtro] { padding-left: 10px; padding-right: 10px; }
#tablaInsumos thead th { white-space: nowrap; }

/* Detalle de apartado (2026-10-06): «escenario | FILA · COORDINACIÓN» es un enlace al apartado en su escenario. */
.celda-cobertura a.cob-enlace { color: inherit; text-decoration: underline; text-decoration-color: rgb(var(--azul-rgb) / .35); text-underline-offset: 3px; cursor: pointer; }
.celda-cobertura a.cob-enlace:hover, .celda-cobertura a.cob-enlace:focus-visible { color: var(--azul-texto); text-decoration-color: currentColor; }
.cob-ref-prueba a.cob-enlace { color: var(--muted); }
/* Vista previa con varias líneas (Detalle apartado) y aviso «Copiado» de Ctrl+Shift+clic. */
.tooltip-flotante { white-space: pre-line; max-width: 420px; text-align: left; }
.aviso-copiado { position: fixed; z-index: 2000; padding: 3px 9px; border-radius: 6px; background: var(--verde-solido-2); color: #fff; font-size: 12px; font-weight: 600; pointer-events: none; box-shadow: 0 4px 12px rgb(var(--sombra-rgb) / .15); }
.aviso-copiado.sale { animation: aviso-copiado 1.1s ease-out forwards; }
@keyframes aviso-copiado { 0% { opacity: 0; transform: translateY(4px); } 15% { opacity: 1; transform: none; } 80% { opacity: 1; } 100% { opacity: 0; } }

/* Ocultar / mostrar columnas (2026-10-06, columnas-ocultas.js): menú de clic derecho y la marca delgada donde hay
   columnas ocultas (doble clic la muestra). Casi no se nota, pero se nota. */
.menu-columnas { position: fixed; z-index: 2000; min-width: 220px; padding: 4px; background: var(--c-superficie); border: 1px solid var(--c-borde-fuerte); border-radius: 8px; box-shadow: 0 8px 24px rgb(var(--sombra-rgb) / .16); }
.menu-columnas button { display: block; width: 100%; text-align: left; padding: 7px 10px; border: 0; background: none; border-radius: 6px; font-size: 13px; color: var(--text); cursor: pointer; }
.menu-columnas button:hover:not(:disabled), .menu-columnas button:focus-visible { background: var(--azul-fondo); color: var(--azul-texto); outline: none; }
.menu-columnas button:disabled { color: var(--muted); cursor: default; }
.tabla-columnas thead th .marca-oculta { position: absolute; top: 0; bottom: 0; width: 5px; z-index: 2; cursor: col-resize;
    background: repeating-linear-gradient(to bottom, var(--azul-borde) 0 4px, transparent 4px 7px); opacity: .75; }
.tabla-columnas thead th .marca-oculta.lado-der { right: -1px; }
.tabla-columnas thead th .marca-oculta.lado-izq { left: -1px; }
.tabla-columnas thead th .marca-oculta:hover, .tabla-columnas thead th .marca-oculta:focus-visible { opacity: 1; width: 7px; background: var(--azul-solido); outline: none; }

/* Subtítulo del encabezado (2026-10-06): «Stock total general (CEDIS + Xochimilco)» y «Disponible … (- Apartado)»
   con la resta en rojo. */
.tabla-ambos-lotes thead th .th-sub, .xl-hoja .xl-sub { display: block; font-size: 11.5px; font-weight: 600; color: var(--c-texto-suave); margin-top: 1px; }
.tabla-ambos-lotes thead th .th-sub.th-resta, .xl-hoja .xl-sub.xl-resta { color: var(--rojo-texto); font-weight: 700; }
.tabla-ambos-lotes thead th .th-sub { white-space: nowrap; }

/* ============================================================================================================
   Mi perfil y tema (UX fase 2, 2026-10-08)
   ============================================================================================================ */
.avatar {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--c-primario-suave-2); color: var(--c-enlace); border: 1px solid var(--c-primario-borde);
    font-size: 12px; font-weight: 700; letter-spacing: .02em; line-height: 1; text-transform: uppercase;
}
.avatar-grande { width: 56px; height: 56px; font-size: 20px; }
.cuenta-perfil { display: inline-flex; align-items: center; gap: 8px; padding: 3px 10px 3px 3px; border-radius: var(--r-pill); color: var(--c-texto-suave); text-decoration: none; }
.cuenta-perfil:hover, .cuenta-perfil.active { background: var(--c-relleno); color: var(--c-texto-2); }
.mainnav-cuenta .cuenta-nombre { display: flex; align-items: center; gap: 8px; }
.cuenta-accion.active { background: var(--c-primario-suave); }

.perfil { max-width: 760px; margin: 0 auto; display: grid; gap: 20px; }
.perfil .card { display: block; }
.perfil h3 { margin-bottom: var(--e-4); }
.perfil-cabecera { display: flex; align-items: center; gap: 16px; }
.perfil-cabecera h2 { margin: 0; overflow-wrap: anywhere; }
.perfil-sub { margin: 2px 0 0; color: var(--c-texto-suave); overflow-wrap: anywhere; }
.perfil-form input[type=text] { max-width: 420px; }
.perfil-datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px 24px; margin: 0 0 6px; }
.perfil-datos dt { font-size: var(--t-xs); font-weight: 500; color: var(--c-texto-suave); }
.perfil-datos dd { margin: 2px 0 0; font-weight: 600; overflow-wrap: anywhere; }
.perfil-nota { margin: 0 0 var(--e-4); }

.selector-tema { border: 0; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
.selector-tema legend { padding: 0; margin-bottom: 8px; font-size: var(--t-sm); }
.opcion-tema {
    display: grid; grid-template-columns: auto 1fr; gap: 8px 10px; align-items: start; margin: 0; padding: 12px;
    border: 1px solid var(--c-borde); border-radius: var(--r-lg); background: var(--c-superficie); color: var(--c-texto); cursor: pointer;
}
.opcion-tema:hover { border-color: var(--c-borde-fuerte); }
.opcion-tema:has(input:checked) { border-color: var(--c-primario); box-shadow: inset 0 0 0 1px var(--c-primario); background: var(--c-primario-suave); }
.opcion-tema:has(input:focus-visible) { outline: 2px solid var(--foco-color); outline-offset: 2px; }
.opcion-tema input { width: auto; min-height: 0; margin: 3px 0 0; accent-color: var(--c-primario); }
.opcion-tema-texto { display: grid; gap: 2px; }
.opcion-tema-texto small { color: var(--c-texto-suave); font-size: var(--t-xs); }
/* Miniatura del tema: dibujada con colores fijos a propósito (muestra cómo se ve cada uno, sin depender del actual). */
.muestra-tema { grid-column: 1 / -1; order: -1; height: 54px; border-radius: var(--r); border: 1px solid var(--c-borde); }
.muestra-claro { background: linear-gradient(#ffffff 0 30%, #f4f5f7 30%); box-shadow: inset 12px -8px 0 -4px #dde1e6; }
.muestra-oscuro { background: linear-gradient(#1b1f26 0 30%, #121519 30%); box-shadow: inset 12px -8px 0 -4px #343a45; }
.muestra-automatico { background: linear-gradient(135deg, #f4f5f7 0 50%, #121519 50%); }
.estado-tema { min-height: 1.5em; margin: 12px 0 0; font-size: var(--t-sm); }
.estado-tema.estado-guardando { color: var(--c-texto-suave); }
.estado-tema.estado-ok { color: var(--c-exito); }
.estado-tema.estado-ok::before { content: "✓ "; font-weight: 700; }
.estado-tema.estado-error { color: var(--c-error); font-weight: 500; }
.estado-tema.estado-error::before { content: "✕ "; font-weight: 700; }

/* ============================================================================================================
   Tablas y estados de interacción (UX fase 3, 2026-10-08)
   ============================================================================================================ */
/* Utilidades de texto y espaciado usadas al quitar estilos en línea de las vistas. */
.texto-intro { margin: -6px 0 12px; }
.nota-tabla { margin: 8px 0 0; }
.ayuda-pegada { margin: 4px 0 0; }
.texto-secundario { display: block; margin-top: 2px; font-size: var(--t-xs); color: var(--c-texto-suave); }
.texto-chico { font-size: var(--t-xs); }
.texto-suave { color: var(--c-texto-suave); }
.texto-tenue { color: var(--c-texto-tenue); }
.titulo-pagina { margin: 0 0 16px; }
.titulo-calendario { margin: 0; font-size: 15px; }
.titulo-lotes { margin: 16px 0 8px; }
.page-header h3, .page-toolbar h3 { margin: 0; }
.card.seccion { margin-bottom: 20px; }
.card.seccion-arriba { margin-top: 20px; }
.tarjeta-angosta { max-width: 640px; }
.grupo-acciones { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.grupo-acciones form { margin: 0; }
.acciones-pie { margin-top: 16px; }
.casilla-linea { align-items: center; gap: 8px; font-size: var(--t-sm); color: var(--c-texto); margin-bottom: 0; }
.casilla-linea input { width: auto; min-height: 0; margin: 0; }
.clave-temporal { font-family: var(--fuente-mono); font-size: 22px; letter-spacing: 1px; background: var(--c-fondo); padding: 12px 16px; border-radius: var(--r-lg); user-select: all; overflow-wrap: anywhere; }
.detalle-json { font-size: 11px; white-space: pre-wrap; overflow-wrap: anywhere; background: var(--c-superficie-2); color: var(--c-texto-2); padding: 8px; border-radius: var(--r); }
tr.fila-inactiva td { color: var(--c-texto-suave); }

/* Barra de filtros de servidor (Bitácora y similares): controles alineados abajo, acciones al final. */
.barra-filtros { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 12px; margin-bottom: 12px; }
.barra-filtros > div { min-width: 0; }
.barra-filtros select, .barra-filtros input { margin-bottom: 0; width: auto; min-width: 180px; max-width: 100%; }
.barra-filtros-acciones { display: flex; gap: 8px; }
.paginacion { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 10px; align-items: center; }

/* Estado vacío: dice si no hay registros o si los filtros no dejan ninguno, y ofrece cómo salir. */
.estado-vacio { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 12px; padding: 24px 12px; text-align: center; color: var(--c-texto-suave); font-size: var(--t-sm); }
.estado-vacio strong { color: var(--c-texto-2); font-weight: 600; }
tr.fila-vacia > td { padding: 0; }
.empty-state .btn { margin-left: 8px; }

/* Cantidades: a la derecha y con dígitos tabulares (también en las tablas «todo centrado»). */
.th-numero, .celda-numero { text-align: right; }
.tabla-centrada .celda-numero, .tabla-centrada th.th-numero { text-align: right; }
td.celda-numero { font-variant-numeric: tabular-nums; }

/* Movimientos recientes: anchos proporcionales en escritorio. */
.tabla-movimientos { table-layout: auto; }
.tabla-movimientos col.c-fecha { width: 11%; } .tabla-movimientos col.c-item { width: 24%; } .tabla-movimientos col.c-lote { width: 12%; }
.tabla-movimientos col.c-tipo { width: 8%; } .tabla-movimientos col.c-cantidad { width: 7%; } .tabla-movimientos col.c-motivo { width: 11%; }
.tabla-movimientos col.c-origen { width: 15%; } .tabla-movimientos col.c-ref { width: 8%; } .tabla-movimientos col.c-usuario { width: 10%; }
.tabla-bitacora .celda-detalle { font-size: var(--t-xs); overflow-wrap: anywhere; min-width: 220px; }
.tabla-bitacora .celda-sobre { white-space: normal; min-width: 180px; }

/* Móvil: las tablas .tabla-apilable se leen como tarjetas (cada celda con su etiqueta); no se pierde ningún dato. */
@media (max-width: 640px) {
    .tabla-apilable, .tabla-apilable tbody, .tabla-apilable tr, .tabla-apilable td { display: block; width: 100%; }
    .table-scroll .tabla-apilable { min-width: 0; }
    .tabla-apilable thead, .tabla-apilable colgroup { display: none; }
    .tabla-apilable tr { padding: 10px 0; border-bottom: 1px solid var(--c-borde); }
    .tabla-apilable tr.fila-vacia { border: 0; }
    .tabla-apilable td { border: 0; padding: 3px 0; white-space: normal; text-align: left; min-width: 0; }
    .tabla-apilable td[data-etiqueta] { display: grid; grid-template-columns: 7.5rem minmax(0, 1fr); gap: 8px; align-items: baseline; }
    .tabla-apilable td[data-etiqueta]::before { content: attr(data-etiqueta); font-size: var(--t-xs); font-weight: 600; color: var(--c-texto-suave); }
    .tabla-apilable td.celda-numero { text-align: left; }
    .table-scroll.table-scroll-tall:has(.tabla-apilable) { max-height: none; }
    .barra-filtros > div, .barra-filtros select { width: 100%; }
}

/* Selector de columnas (columnas-ocultas.js): botón y panel compacto, con búsqueda si hay muchas columnas. */
.herramientas-tabla { display: flex; justify-content: flex-end; gap: 8px; margin: 0 0 8px; }
.selector-columnas { position: relative; }
.selector-columnas-panel {
    position: absolute; right: 0; top: calc(100% + 4px); z-index: 1060; width: 280px; max-width: calc(100vw - 32px); padding: 8px;
    background: var(--c-superficie); border: 1px solid var(--c-borde); border-radius: var(--r-lg); box-shadow: var(--sombra-2);
}
.selector-columnas-panel[hidden] { display: none; }
.selector-columnas-panel input[type=search] { margin: 0 0 6px; min-height: 32px; padding: 5px 8px; font-size: var(--t-sm); }
.selector-columnas-lista { max-height: 280px; overflow-y: auto; margin: 0; padding: 0; list-style: none; }
.selector-columnas-lista label { display: flex; align-items: center; gap: 8px; margin: 0; padding: 6px 6px; border-radius: var(--r); font-size: var(--t-sm); font-weight: 400; color: var(--c-texto); cursor: pointer; }
.selector-columnas-lista label:hover { background: var(--c-relleno); }
.selector-columnas-lista input { width: auto; min-height: 0; margin: 0; accent-color: var(--c-primario); }
.selector-columnas-pie { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--c-borde); font-size: var(--t-xs); color: var(--c-texto-suave); align-items: center; }

/* Envío en curso: el botón dice «Guardando…» y no admite un segundo clic; el resto de la página sigue usable. */
button.ocupado, .btn.ocupado { cursor: progress; opacity: .75; }
button.ocupado::before, .btn.ocupado::before {
    content: ""; display: inline-block; width: .9em; height: .9em; margin-right: 6px; vertical-align: -.1em;
    border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: girar .7s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { button.ocupado::before, .btn.ocupado::before { animation: none; border-right-color: currentColor; } }
.texto-pegado { margin: 0; font-size: var(--t-sm); }
.pestana-abierta { border-top-left-radius: 0; }
.titulo-panel { font-size: var(--t-base); }
/* Descripción completa en tablas de cálculo (antes se cortaba a 65 caracteres): se parte en renglones legibles. */
td.celda-descripcion-completa { white-space: normal; min-width: 240px; max-width: 420px; overflow-wrap: anywhere; line-height: 1.35; }
.titulo-historial { margin-top: 20px; }
/* Mensaje vacío dentro de una tabla ancha: se queda al borde izquierdo visible del contenedor con desplazamiento. */
td.celda-vacia-tabla { padding: 0; text-align: left; }
.estado-vacio-fijo { position: sticky; left: 0; justify-content: flex-start; width: min(100%, calc(100vw - 96px)); max-width: 900px; text-align: left; }

/* ============================================================================================================
   Marca y movimiento (UX fase 4, 2026-10-08)
   ============================================================================================================ */
/* Logotipo (public/assets/branding): alto fijo, ancho por su proporción (atributos width/height: sin saltos). */
.app-marca:has(.marca-logo) { align-items: center; gap: 10px; }
.app-marca:has(.marca-logo)::before { display: none; }
.marca-logo { display: block; flex: none; max-width: 180px; height: auto; object-fit: contain; }
.marca-texto { display: inline; }
.marca-logo-oscuro { display: none; }
[data-bs-theme="dark"] .marca-logo-claro { display: none; }
[data-bs-theme="dark"] .marca-logo-oscuro { display: block; }
/* Sin versión oscura: el logo claro va sobre una placa clara para que se lea en el tema oscuro. */
[data-bs-theme="dark"] .marca-logo-placa { background: #ffffff; padding: 3px 6px; border-radius: var(--r); box-sizing: content-box; }
@media (max-width: 419.98px) { .app-barra .app-marca:has(.marca-logo) .marca-texto { display: none; } }

/* Movimiento: breve (150–240 ms), solo opacidad y un desplazamiento mínimo (no mueve la distribución), una sola
   vez al cargar. El contenido es visible e interactivo desde el inicio del efecto; sin CSS de animación se ve igual. */
:root { --mov-rapido: 150ms; --mov-medio: 200ms; --mov-lento: 240ms; --mov-curva: cubic-bezier(.2, .7, .3, 1); }
@keyframes entrar-suave { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes aparecer { from { opacity: 0; } to { opacity: 1; } }
@keyframes desplegar { from { opacity: 0; transform: translateY(-4px) scale(.98); } to { opacity: 1; transform: none; } }

/* Encabezados, tarjetas y contenedores de tabla del contenido de la página (no las filas). */
main.container > .card, main.container > .page-header, main.container > h2, main.container > .almacen-tabs,
main.container > .cfg > .card, main.container > .perfil > .card, .cob-arriba, .cob-principal { animation: entrar-suave var(--mov-medio) var(--mov-curva) both; }
main.container > .card:nth-of-type(2) { animation-delay: 40ms; }
main.container > .card:nth-of-type(3) { animation-delay: 80ms; }
main.container > .card:nth-of-type(n+4) { animation-delay: 110ms; }
/* Dashboard: las tarjetas de indicadores entran escalonadas (máximo 8, en total < 250 ms). */
.kpi-grid .kpi-card, .dash-panels > .card { animation: entrar-suave var(--mov-medio) var(--mov-curva) both; }
.kpi-grid .kpi-card:nth-child(2) { animation-delay: 30ms; } .kpi-grid .kpi-card:nth-child(3) { animation-delay: 60ms; } .kpi-grid .kpi-card:nth-child(4) { animation-delay: 90ms; }
.dash-panels > .card:nth-child(2) { animation-delay: 60ms; }
/* Paneles propios: se despliegan cada vez que se abren (no hay transición de display; basta la animación). */
.selector-columnas-panel:not([hidden]), .menu-filtro, .menu-columnas:not([hidden]), .cob-columnas:not([hidden]), .combo-dropdown { animation: desplegar var(--mov-rapido) var(--mov-curva) both; transform-origin: top; }
details[open] > :not(summary) { animation: aparecer var(--mov-medio) ease-out both; }
.alert, .estado-tema:not(:empty) { animation: aparecer var(--mov-medio) ease-out both; }
/* Interacción: los botones y enlaces de navegación ya tenían transición de color; las tarjetas de opción también. */
.opcion-tema, .kpi-card, .cob-archivos a { transition: border-color var(--mov-rapido), box-shadow var(--mov-rapido), background-color var(--mov-rapido); }

/* Movimiento reducido: nada se desplaza ni se desvanece; todo aparece en su lugar. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: 1ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
    button.ocupado::before, .btn.ocupado::before { animation: none !important; }
}

/* Utilidades de formularios y listas (UX fase 4, al quitar estilos en línea de Configuraciones, Lotes, Insumos y Productos). */
.tarjeta-formulario { max-width: 820px; }
.tarjeta-formulario-chica { max-width: 560px; }
.aviso-separado { margin: 14px 0 0; }
.ayuda-compacta { margin: 4px 0 8px; }
.ayuda-media { margin-top: -8px; }
.grupo-amplio { gap: 12px; }
.buscar-angosto { max-width: 420px; }
.casilla-formulario { display: flex; margin-bottom: 20px; }
th.col-acciones { width: 170px; }
th.col-detalle { width: 90px; }

/* ============================================================================================================
   Acceso CTRL - STOCK (2026-10-08): diseño de ctrl-stock-login (laravel/login-ctrl-stock.css), integrado aquí en lugar
   de las reglas anteriores de .login-wrap/.login-card. Usa los tokens --c-*; el alcance .login-wrap lo aplica también
   a /cambiar-password. Sus colores propios (--c-login-*) solo existen dentro de .login-wrap.
   ============================================================================================================ */
.login-wrap {
    --c-login-azul: #173f89;
    --c-login-turquesa: #07b0c8;
    --c-login-azul-suave: #dce7f8;
    --c-login-turquesa-suave: #d8f1f4;
    --c-login-trama: #e8ecf2;
    --c-login-linea: #cad9ed;
    --c-login-campo-borde: #8793a5;
    --c-login-sobre-boton: #ffffff;
    --c-login-foco: var(--foco-color);
    --c-login-foco-rgb: var(--foco-rgb);
    --c-login-sombra-rgb: 20 41 77;
    --c-login-transparente: transparent;
    position: relative;
    isolation: isolate;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 24px 16px;
    background: var(--c-fondo);
    color: var(--c-texto);
}
[data-bs-theme="dark"] .login-wrap {
    --c-login-azul: #244c99;
    --c-login-turquesa: #168c9f;
    --c-login-azul-suave: #1b2b44;
    --c-login-turquesa-suave: #18383e;
    --c-login-trama: #1a2029;
    --c-login-linea: #2e4056;
    --c-login-campo-borde: #637187;
    --c-login-sombra-rgb: 0 0 0;
}

/* Decoración CSS: no recibe foco, clics ni lecturas de asistencia. */
.login-wrap .login-fondo {
    position: absolute;
    inset: 0;
    overflow: hidden;
    z-index: -1;
    pointer-events: none;
    user-select: none;
    background:
        radial-gradient(ellipse at 50% 47%, var(--c-superficie) 0%, var(--c-login-transparente) 65%),
        var(--c-fondo);
}
.login-wrap .login-trama {
    position: absolute;
    inset: -25%;
    transform: rotate(-12deg) skewX(-12deg);
    background-image:
        linear-gradient(var(--c-login-trama) 1px, var(--c-login-transparente) 1px),
        linear-gradient(90deg, var(--c-login-trama) 1px, var(--c-login-transparente) 1px);
    background-size: 104px 72px;
    -webkit-mask-image: linear-gradient(90deg, var(--c-texto), var(--c-login-transparente) 34%, var(--c-login-transparente) 66%, var(--c-texto));
    mask-image: linear-gradient(90deg, var(--c-texto), var(--c-login-transparente) 34%, var(--c-login-transparente) 66%, var(--c-texto));
}
.login-wrap .login-franjas {
    position: absolute;
    width: clamp(300px, 35vw, 620px);
    height: 220px;
    transform: rotate(-12deg) skewX(-12deg);
}
.login-wrap .login-franjas-arriba { top: 14%; right: -110px; }
.login-wrap .login-franjas-abajo { bottom: 9%; left: -130px; }
.login-wrap .login-banda {
    position: absolute;
    display: block;
    height: 48px;
    border-radius: 3px;
    animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both;
}
.login-wrap .login-banda-1 {
    top: 0; left: 32%; width: 88%;
    background: var(--c-login-turquesa-suave);
}
.login-wrap .login-banda-2 {
    top: 62px; left: 6%; width: 108%;
    background: linear-gradient(100deg, var(--c-login-azul), var(--c-primario));
}
.login-wrap .login-banda-3 {
    top: 124px; left: 48%; width: 76%;
    background: var(--c-login-turquesa);
}
.login-wrap .login-banda-4 {
    top: 184px; left: 10%; width: 60%;
    background: var(--c-login-transparente);
    border: 1px solid var(--c-login-linea);
}
.login-wrap .login-franjas-abajo .login-banda-1 {
    left: -10%; width: 78%; background: var(--c-login-azul-suave);
}
.login-wrap .login-franjas-abajo .login-banda-2 { left: -15%; width: 105%; }
.login-wrap .login-franjas-abajo .login-banda-3 { left: 6%; width: 69%; }
.login-wrap .login-franjas-abajo .login-banda-4 { left: 60%; width: 48%; }

/* El tamaño del logo se conserva: 132 × 44, con respaldo textual del sistema. */
.login-wrap .login-marca {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    min-height: 44px;
    max-width: 100%;
    gap: 6px;
    font-size: 16px;
    font-weight: 700;
    animation: ctrl-stock-marca 200ms ease-out both;
}
.login-wrap .login-marca .marca-logo { width: 132px; height: 44px; max-width: 100%; object-fit: contain; }
.login-wrap .login-marca .marca-logo-oscuro { display: none; }
[data-bs-theme="dark"] .login-wrap .login-marca .marca-logo-claro { display: none; }
[data-bs-theme="dark"] .login-wrap .login-marca .marca-logo-oscuro { display: block; }
.login-wrap .login-marca:has(.marca-logo)::before { display: none; }

.login-wrap .login-card {
    position: relative;
    width: 100%;
    max-width: 400px;
    min-width: 0;
    padding: 28px;
    border: 1px solid var(--c-borde);
    border-radius: 10px;
    background: var(--c-superficie);
    box-shadow: 0 8px 24px rgb(var(--c-login-sombra-rgb) / .12);
    animation: ctrl-stock-tarjeta 240ms cubic-bezier(.2, .7, .3, 1) both;
}
.login-wrap .login-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    border-radius: 9px 9px 0 0;
    background: linear-gradient(90deg, var(--c-login-azul), var(--c-login-turquesa));
}
.login-wrap .login-card h1 { margin: 0 0 6px; font-size: 20px; font-weight: 600; line-height: 1.3; }
.login-wrap .login-card .subtitle { margin: 0 0 24px; color: var(--c-texto-suave); font-size: 13px; line-height: 1.5; }
.login-wrap .login-card label { display: block; margin: 0 0 6px; color: var(--c-texto-2); font-size: 13px; font-weight: 500; }
.login-wrap .login-card input[type="email"],
.login-wrap .login-card input[type="password"] {
    width: 100%;
    min-width: 0;
    min-height: 44px;
    margin: 0 0 16px;
    padding: 8px 12px;
    border: 1px solid var(--c-login-campo-borde);
    border-radius: 6px;
    background: var(--c-superficie);
    color: var(--c-texto);
    font: inherit;
    font-size: 16px;
    line-height: 1.5;
    transition: border-color 150ms, box-shadow 150ms;
}
.login-wrap .login-card input:focus {
    border-color: var(--c-login-foco);
    box-shadow: 0 0 0 3px rgb(var(--c-login-foco-rgb) / .35);
    outline: none;
}
.login-wrap .login-card input[aria-invalid="true"] { border-color: var(--c-error-marca); }
.login-wrap .login-card button[type="submit"]:not(.login-secundario) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    min-height: 44px;
    padding: 10px 16px;
    border: 0;
    border-radius: 6px;
    background: var(--c-primario);
    color: var(--c-login-sobre-boton);
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
    cursor: pointer;
    transition: background-color 150ms, box-shadow 150ms;
}
.login-wrap .login-card button[type="submit"]:not(.login-secundario):hover { background: var(--c-primario-hover); }
.login-wrap .login-card button[type="submit"]:not(.login-secundario):active { background: var(--c-primario-activo); }
.login-wrap .login-card button:focus-visible,
.login-wrap .login-card a:focus-visible {
    outline: 2px solid var(--c-login-foco);
    outline-offset: 3px;
}
.login-wrap .login-card button svg { width: 16px; height: 16px; flex: none; }
.login-wrap .login-card .alert { animation: none; overflow-wrap: anywhere; }
.login-wrap .login-contexto { margin: 2px 0 0; text-align: center; color: var(--c-texto-suave); font-size: 12px; line-height: 1.5; }
.login-wrap .login-card .help-text { color: var(--c-texto-suave); overflow-wrap: anywhere; }
.login-wrap .login-pie { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; }
.login-wrap .login-pie a { color: var(--c-enlace); text-underline-offset: 3px; }
.login-wrap .login-pie a:hover { color: var(--c-enlace-hover); }
.login-wrap .login-pie .login-secundario { min-width: 44px; min-height: 44px; }

/* En móvil la geometría acompaña desde los bordes, dejando libre el formulario. */
@media (max-width: 640px) {
    .login-wrap .login-franjas { width: 300px; opacity: .3; }
    .login-wrap .login-franjas-arriba { top: 2%; right: -220px; }
    .login-wrap .login-franjas-abajo { bottom: 1%; left: -220px; }
    .login-wrap .login-trama { background-size: 82px 60px; opacity: .5; }
}
@media (max-height: 560px) and (min-width: 641px) {
    .login-wrap .login-franjas { opacity: .25; }
    .login-wrap .login-franjas-arriba { top: -70px; right: -230px; }
    .login-wrap .login-franjas-abajo { bottom: -90px; left: -240px; }
}
@keyframes ctrl-stock-tarjeta { from { opacity: .85; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ctrl-stock-marca { from { opacity: .85; } to { opacity: 1; } }
@keyframes ctrl-stock-franja { from { opacity: 0; transform: translateX(12px); } to { opacity: 1; transform: translateX(0); } }
/* Franjas en movimiento (08/10/2026), tomado del acceso original de referencia (extra/style.css: animationLeftRight y
   animationRightLeft): cada franja va y viene 1000 px de forma continua, con su propio ritmo (2, 3 o 4 s) y aceleración
   suave; una franja azul fuerte queda quieta, como en la referencia. Las franjas están inclinadas, así que se deslizan a
   lo largo de su propia diagonal. Empieza después de la entrada de 700 ms. Solo transform: no mueve la distribución. */
@keyframes ctrl-stock-franja-der { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(1000px); } }
@keyframes ctrl-stock-franja-izq { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-1000px); } }
.login-wrap .login-banda { will-change: transform; }
/* Abajo a la izquierda (como el lado izquierdo de la referencia): hacia la derecha; la azul fuerte, quieta. */
.login-wrap .login-franjas-abajo .login-banda-1 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 3s ease-in-out 700ms infinite; }
.login-wrap .login-franjas-abajo .login-banda-3 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 2s ease-in-out 700ms infinite; }
.login-wrap .login-franjas-abajo .login-banda-4 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 3s ease-in-out 700ms infinite; }
/* Arriba a la derecha: la azul hacia la izquierda (2 s); las demás hacia la derecha con 4 y 3 s, como en la referencia. */
.login-wrap .login-franjas-arriba .login-banda-1 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 4s ease-in-out 700ms infinite; }
.login-wrap .login-franjas-arriba .login-banda-2 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-izq 2s ease-in-out 700ms infinite; }
.login-wrap .login-franjas-arriba .login-banda-3 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 4s ease-in-out 700ms infinite; }
.login-wrap .login-franjas-arriba .login-banda-4 { animation: ctrl-stock-franja 700ms cubic-bezier(.2, .7, .3, 1) both, ctrl-stock-franja-der 3s ease-in-out 700ms infinite; }
@media (prefers-reduced-motion: reduce) {
    .login-wrap .login-card, .login-wrap .login-marca, .login-wrap .login-franjas .login-banda { animation: none !important; }
    .login-wrap .login-card input, .login-wrap .login-card button, .login-wrap .login-card a { transition-duration: 1ms; }
}
@media (forced-colors: active) {
    .login-wrap .login-fondo, .login-wrap .login-card::before { display: none; }
    .login-wrap .login-card input:focus { outline: 2px solid; outline-offset: 2px; }
    .login-wrap .login-card button[type="submit"]:not(.login-secundario) { border: 1px solid; }
}
/* Envío en curso en el acceso: el giro de «ocupado» reemplaza a la flecha. */
.login-wrap .login-card button.ocupado svg { display: none; }

/* Productos → Ambos (2026-10-13): «Sin apartados (Disponible 100%)», columna «Salidas recientes» y su ventana. */
.tabla-ambos-lotes .sin-apartados { display: inline-flex; flex-direction: column; align-items: center; line-height: 1.2; font-weight: 600; white-space: nowrap; }
.tabla-ambos-lotes .sin-apartados-pct { font-size: 12px; font-weight: 500; opacity: .85; }
.tabla-ambos-lotes .celda-salidas { min-width: 190px; text-align: center; font-size: 13px; line-height: 1.3; }
.celda-salidas .salidas-resumen, .celda-salidas .salidas-ultima { display: block; }
.celda-salidas .salidas-ultima { color: var(--muted); font-size: 12px; }
.btn-salidas { margin-top: 3px; padding: 1px 10px; font-size: 12px; border-radius: 999px; border: 1px solid var(--border); background: var(--card-bg); color: inherit; cursor: pointer; }
.btn-salidas:hover { background: var(--c-relleno-2); }
.btn-salidas:focus-visible { outline: 2px solid var(--azul-borde); outline-offset: 1px; }
.salidas-pop { position: fixed; z-index: 1080; max-height: min(70vh, 560px); display: flex; flex-direction: column; background: var(--card-bg); color: var(--c-texto, inherit);
    border: 1px solid var(--c-borde-fuerte, var(--border)); border-radius: 10px; box-shadow: 0 12px 32px rgb(0 0 0 / .22); }
.salidas-pop:focus { outline: none; }
.salidas-pop-cab { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.salidas-pop-cuerpo { overflow: auto; padding: 8px 14px 12px; }
.salidas-caja { overflow-x: auto; }
.salidas-tabla { width: 100%; border-collapse: collapse; font-size: 13px; }
.salidas-tabla th, .salidas-tabla td { padding: 5px 8px; border-bottom: 1px solid var(--border); vertical-align: top; text-align: left; }
.salidas-tabla th { font-weight: 700; color: var(--muted); white-space: nowrap; }
.salidas-tabla .num { text-align: right; white-space: nowrap; }
.salidas-tabla .salidas-sub, .salidas-tabla .salidas-hora { display: block; font-size: 12px; color: var(--muted); }
.salidas-vacio, .salidas-pie, .salidas-enlaces { margin: 6px 0 0; font-size: 13px; color: var(--muted); }

/* Orden de columnas (columnas-orden.js y Apartado, 2026-10-13): arrastrar encabezados, línea de destino, restablecer. */
table[data-columnas-orden] > thead > tr > th:not(.columna-fija), #cobTabla thead th[data-col-id]:not(.cob-th-acc) { cursor: grab; }
.columnas-orden-arrastrando, .columnas-orden-arrastrando * { cursor: grabbing !important; user-select: none !important; }
th.columna-arrastrada { opacity: .5; }
.columnas-orden-linea { position: fixed; width: 3px; margin-left: -1px; background: var(--azul-solido, #2563eb); border-radius: 2px; z-index: 1070; pointer-events: none; box-shadow: 0 0 0 1px var(--card-bg); }
.columnas-orden-barra { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 6px; font-size: 13px; color: var(--muted); }
.menu-columnas .menu-separado { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 8px; }

/* Productos · Ambos: encabezados y datos centrados en las dos hojas generales. */
.tabla-total-centrada th, .tabla-total-centrada td { text-align: center !important; }

/* Conservar la posición al guardar (posicion.js, 2026-10-13): fila resaltada y aviso flotante. */
@keyframes filaRecien { 0%, 35% { background-color: var(--ambar-fondo-2, #fde68a); } 100% { background-color: transparent; } }
tr.fila-recien > td { animation: filaRecien 2.6s ease-out; }
.aviso-flotante { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 1090; width: max-content; max-width: min(640px, calc(100vw - 32px));
    display: flex; gap: 12px; align-items: flex-start; margin: 0; box-shadow: 0 10px 28px rgb(0 0 0 / .22); transition: opacity .35s; }
.aviso-flotante.saliendo { opacity: 0; }
.aviso-flotante .btn-close { flex: none; margin-left: auto; }
@media (prefers-reduced-motion: reduce) { tr.fila-recien > td { animation: none; outline: 2px solid var(--ambar-texto); outline-offset: -2px; } .aviso-flotante { transition: none; } }
