/* ===========================================================================
 * pcenter — sistema de diseño
 *
 * Fuente única de la paleta y de los componentes compartidos. Antes cada
 * página traía su propio <style> con los colores escritos a mano (#2c3e50,
 * #ecf0f1, #dfe6e9…), repetidos en trece archivos y ya divergiendo entre sí.
 *
 * ORDEN DE CARGA: esta hoja va PRIMERO. Define los tokens en :root; las hojas
 * de módulo (compras.css) los consumen y ya no declaran paleta propia.
 *
 * DOS CONTEXTOS, porque el panel monta cada pestaña en un <iframe>:
 *   body.app-shell  el armazón — barra lateral + cabecera + pestañas
 *   body.page       el contenido de un iframe — sin barra, con su propio aire
 * Un iframe no hereda el CSS del padre: por eso las dos cosas viven aquí y
 * cada página enlaza esta misma hoja.
 * ======================================================================== */

:root {
    /* --- Azules: la identidad ------------------------------------------- */
    --azul-900: #0e2439;   /* barra lateral */
    --azul-800: #16385a;   /* hover de la barra */
    --azul-700: #1d4f7c;
    --azul-600: #2166a3;   /* acción principal */
    --azul-500: #2f7fc4;
    --azul-200: #bcd7ec;
    --azul-100: #e4eef7;
    --azul-050: #f2f7fc;

    /* --- Grises: la estructura ------------------------------------------ */
    --gris-900: #16202c;   /* texto */
    --gris-700: #3d4b5c;
    --gris-500: #64748b;   /* texto secundario */
    --gris-400: #94a3b3;
    --gris-300: #d3dbe4;   /* bordes */
    --gris-200: #e5eaf0;
    --gris-100: #eff2f6;
    --gris-050: #f7f9fb;   /* fondo de página */
    --blanco:   #ffffff;

    /* --- Semánticos ------------------------------------------------------
     * Los nombres cortos (--bg, --panel, --accent…) los consume compras.css,
     * que se portó del facturador. Se conservan a propósito para no reescribir
     * ese módulo entero; lo que cambió es el valor: el acento pasó de verde
     * (#1d6f5e) a azul. */
    --bg:          var(--gris-050);
    --panel:       var(--blanco);
    --border:      var(--gris-300);
    --border-soft: var(--gris-200);
    --text:        var(--gris-900);
    --text-soft:   var(--gris-500);

    --accent:      var(--azul-600);
    --accent-dark: var(--azul-700);
    --accent-soft: var(--azul-100);

    /* Estados. El verde sobrevive sólo aquí, para "va bien" — que es lo que
       de verdad significa; como color de marca competía con el azul. */
    --ok:        #1a7f4f;
    --ok-bg:     #e8f6ee;
    --warn:      #9a6100;
    --warn-bg:   #fdf3e0;
    --danger:    #b3261e;
    --danger-bg: #fdecea;

    --radius:    8px;
    --radius-sm: 5px;
    --shadow-sm: 0 1px 2px rgba(16, 32, 48, .06);
    --shadow-md: 0 2px 8px rgba(16, 32, 48, .10);
    --shadow-lg: 0 12px 32px rgba(16, 32, 48, .20);

    --sidebar-w: 216px;
    --fuente: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--fuente);
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--azul-600); }

/* ===========================================================================
 * ARMAZÓN
 * ======================================================================== */

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

/* --- Barra lateral ------------------------------------------------------ */

aside,
aside * { box-sizing: border-box; }

aside {
    /* admin.css (scaffold viejo) fija min-width y max-width en 150px: hay que
       sobrescribir las tres, no sólo width. */
    width: var(--sidebar-w);
    min-width: var(--sidebar-w);
    max-width: var(--sidebar-w);
    /* Sin esto flexbox comprime la barra cuando el contenido es ancho (tablas
       grandes) y se ve más angosta que en inicio. */
    flex-shrink: 0;
    background: var(--azul-900);
    color: #dce6f0;
    box-shadow: none;
}

/* Sólo cuando la barra es hija directa de <body> (layout de admin_home y
   compañía). Se excluye el scaffold viejo (admin_add_item, admin_category,
   admin_update_item), donde el <aside> va dentro de un div.flex bajo un
   <header> y admin.css ya calcula su altura con calc(100vh - 54px): ahí un
   min-height:100vh sobraría una barra de desplazamiento. */
body > aside {
    height: auto;
    min-height: 100vh;
}

.nav-marca {
    padding: 18px 16px 16px;
    text-align: center;
    border-bottom: 1px solid rgba(255, 255, 255, .09);
}
.nav-marca img { height: 56px; display: block; margin: 0 auto 10px; }
.nav-marca span {
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .10em;
    text-transform: uppercase;
    color: var(--gris-400);
}

.nav-item {
    padding: 11px 16px;
    display: flex;
    align-items: center;
    gap: 11px;
    color: #c9d7e5;
    text-decoration: none;
    font-size: 13.5px;
    /* El separador es un borde interior tenue, no una línea sólida por fila:
       trece rayas claras hacían que el menú se leyera como una tabla. */
    border-left: 3px solid transparent;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}

.nav-item:hover,
.nav-item:focus-visible {
    background: var(--azul-800);
    color: var(--blanco);
    border-left-color: var(--azul-500);
    outline: none;
}

.nav-item.activo {
    background: var(--azul-800);
    color: var(--blanco);
    border-left-color: var(--azul-500);
    font-weight: 600;
}

.nav-item svg {
    width: 19px;
    height: 19px;
    flex-shrink: 0;
    opacity: .85;
}
.nav-item:hover svg,
.nav-item.activo svg { opacity: 1; }

/* --- Zona principal ----------------------------------------------------- */

.main-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;   /* evita que el iframe fuerce desplazamiento horizontal */
    background: var(--bg);
}

.main-header {
    background: var(--blanco);
    border-bottom: 1px solid var(--border);
    padding: 12px 22px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}

.main-header h1 {
    font-size: 17px;
    font-weight: 600;
    margin: 0;
    color: var(--gris-900);
    letter-spacing: -.01em;
}

.header-left { display: flex; align-items: center; gap: 12px; }
.header-left img { height: 34px; }

.user-info {
    color: var(--text-soft);
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.user-info strong { color: var(--gris-900); font-weight: 600; }
.user-info a { color: var(--azul-600); }

/* Enlace para reabrir el resumen del día (sólo en admin_home). Se coloca a la
   izquierda del bloque de identidad, con el mismo peso visual que «Cerrar
   sesión» pero en azul: es una acción de consulta, no de salida. */
.main-header .ver-resumen {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: auto;
    margin-right: 4px;
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--azul-600);
    background: var(--blanco);
    text-decoration: none;
    font-size: 12.5px;
    white-space: nowrap;
}
.main-header .ver-resumen:hover {
    border-color: var(--azul-200);
    background: var(--azul-050);
}
@media (max-width: 620px) {
    .main-header .ver-resumen { font-size: 0; gap: 0; padding: 6px; }
}

/* Cerrar sesión, junto al nombre. Antes vivía en el menú lateral, entre las
   secciones de trabajo, donde se leía como una sección más. */
.user-info a.salir {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-left: 8px;
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--gris-700);
    background: var(--blanco);
    text-decoration: none;
    font-size: 12.5px;
    white-space: nowrap;
}
.user-info a.salir:hover {
    color: var(--danger);
    border-color: var(--danger);
    background: var(--danger-bg);
}
.user-info a.salir svg { flex-shrink: 0; }

/* En pantallas estrechas se deja sólo el icono: el nombre ya identifica la
   sesión y la barra de arriba no da para más. El `font-size: 0` colapsa el
   texto del enlace; el SVG no se ve afectado porque lleva width/height propios. */
@media (max-width: 620px) {
    .user-info a.salir { font-size: 0; gap: 0; padding: 6px; }
}

/* Pastilla con la inicial: identifica la sesión de un vistazo, que es lo que
   antes obligaba a leer el nombre completo. */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px; height: 30px;
    border-radius: 50%;
    background: var(--azul-100);
    color: var(--azul-700);
    font-weight: 700;
    font-size: 12.5px;
    margin-right: 8px;
    vertical-align: middle;
}

/* --- Pestañas ----------------------------------------------------------- */

.tabs {
    background: var(--blanco);
    padding: 0 22px;
    border-bottom: 1px solid var(--border);
}

.tab-list {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
    flex-wrap: wrap;
    gap: 2px;
}

/* Pestañas subrayadas en vez de "carpetas": las cajas con borde competían
   visualmente con las tablas que hay debajo. */
.tab-link {
    display: inline-block;
    padding: 11px 15px 9px;
    background: none;
    border: none;
    border-bottom: 2.5px solid transparent;
    text-decoration: none;
    color: var(--text-soft);
    font-size: 13.5px;
    cursor: pointer;
    transition: color .12s ease, border-color .12s ease;
}

.tab-link:hover { color: var(--gris-900); }

.tab-link:focus-visible {
    outline: 2px solid var(--azul-500);
    outline-offset: -2px;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

/* Conviven DOS convenciones para marcar la pestaña activa: las páginas
   modernas usan aria-selected (correcto para lectores de pantalla) y las
   viejas una clase .active que mueve su propio JS. Se estilan las dos: migrar
   el JS de cinco páginas es otro trabajo, y mientras tanto una de las dos
   familias se quedaría sin resaltado. */
.tab-link[aria-selected="true"],
.tab-link.active {
    color: var(--azul-700);
    font-weight: 600;
    border-bottom-color: var(--azul-600);
    /* Las páginas viejas traen su .tab-link.active con fondo blanco y borde de
       carpeta; gana por especificidad, así que hay que anularlo aquí. */
    background: none;
    border-top: none;
    border-left: none;
    border-right: none;
}

.iframe-wrapper { position: relative; flex-grow: 1; background: var(--bg); }

.iframe-loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    background: var(--bg);
    color: var(--text-soft);
    font-size: 13px;
    transition: opacity .15s ease;
}
.iframe-loading.hidden { opacity: 0; pointer-events: none; }

/* El giro va en un ::before para que lo hereden las cinco pantallas con
   pestañas sin tocarles el HTML. Algunos informes tardan segundos y un
   «Cargando…» quieto no distingue entre «está trabajando» y «se colgó». */
.iframe-loading::before {
    content: '';
    width: 22px;
    height: 22px;
    border: 3px solid var(--azul-100);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: pcenter-giro .7s linear infinite;
}
@keyframes pcenter-giro { to { transform: rotate(360deg); } }

/* Quien pide menos animación ve el borde quieto, no un disco girando. */
@media (prefers-reduced-motion: reduce) {
    .iframe-loading::before { animation: none; }
}

.iframe-wrapper iframe {
    border: none;
    width: 100%;
    height: 100%;
    display: block;
}

/* Las cinco páginas viejas (caja, informes, documentos, tickets, registro) NO
   envuelven el iframe en .iframe-wrapper: lo cuelgan directo de .main-content
   y lo miden con `height: calc(100vh - 120px)`, un número a ojo que se
   desajusta en cuanto la cabecera cambia de alto. Como .main-content ya es un
   flex column, dejar que el iframe crezca es exacto y no hay que adivinar. */
.main-content > iframe {
    border: none;
    width: 100%;
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
    display: block;
    background: var(--bg);
}

/* --- Menú móvil --------------------------------------------------------- */

.menu-toggle {
    display: none;
    position: fixed;
    top: 10px; left: 10px;
    z-index: 1001;
    background: var(--azul-900);
    color: var(--blanco);
    border: none;
    border-radius: var(--radius-sm);
    padding: 8px 10px;
    cursor: pointer;
}
.menu-toggle svg { width: 22px; height: 22px; display: block; }

.sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(14, 36, 57, .45);
    z-index: 999;
}
.sidebar-overlay.active { display: block; }

@media (max-width: 700px) {
    .menu-toggle { display: block; }

    aside {
        position: fixed;
        top: 0; left: 0;
        width: 250px;
        max-width: 82%;
        height: 100vh;
        transform: translateX(-100%);
        transition: transform .25s ease;
        z-index: 1000;
        overflow-y: auto;
    }
    aside.open { transform: translateX(0); }

    .main-content { padding-top: 46px; }
    .main-header { padding-left: 58px; }

    /* Con muchas pestañas (Almacén tiene siete) el ajuste por filas come media
       pantalla en el teléfono: mejor una sola fila desplazable. Venía de
       admin_productos, que era la única que lo tenía. */
    .tabs { padding: 0 12px; }
    .tab-list { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .tab-list li { flex-shrink: 0; }
}

/* ===========================================================================
 * CONTENIDO (páginas dentro del iframe)
 * ======================================================================== */

body.page { padding: 18px 20px 40px; }

.page-head { margin-bottom: 16px; }
.page-head h2 {
    font-size: 18px;
    font-weight: 600;
    margin: 0 0 3px;
    letter-spacing: -.01em;
}
.page-head .sub { color: var(--text-soft); font-size: 12.5px; margin: 0; }

h3.seccion {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-soft);
    margin: 26px 0 9px;
}

/* --- Panel -------------------------------------------------------------- */

.panel {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 15px 17px;
    margin-bottom: 15px;
    box-shadow: var(--shadow-sm);
}

/* --- Tarjetas de cifra -------------------------------------------------- */

.resumen { display: flex; gap: 11px; flex-wrap: wrap; margin-bottom: 15px; }

.tarjeta {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    border-left: 3px solid var(--azul-500);
    padding: 11px 15px;
    min-width: 155px;
    box-shadow: var(--shadow-sm);
}
.tarjeta .etq {
    display: block;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-soft);
    margin-bottom: 2px;
}
.tarjeta .val {
    font-size: 20px;
    font-weight: 600;
    letter-spacing: -.02em;
    color: var(--gris-900);
    /* Cifras de ancho fijo: sin esto las columnas de números bailan al
       actualizarse. */
    font-variant-numeric: tabular-nums;
}
.tarjeta.alarma { border-left-color: var(--danger); background: var(--danger-bg); }
.tarjeta.alarma .val { color: var(--danger); }
.tarjeta.bueno  { border-left-color: var(--ok); background: var(--ok-bg); }
.tarjeta.bueno .val { color: var(--ok); }
.tarjeta.aviso  { border-left-color: var(--warn); background: var(--warn-bg); }
.tarjeta.aviso .val { color: var(--warn); }

/* --- Tablas ------------------------------------------------------------- */

.tabla-wrap {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: auto;
    box-shadow: var(--shadow-sm);
}

table.datos {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

table.datos th {
    background: var(--gris-100);
    text-align: left;
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .045em;
    color: var(--gris-700);
    padding: 9px 10px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 1;
}

table.datos td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--border-soft);
}

table.datos tbody tr:last-child td { border-bottom: none; }
table.datos tbody tr:hover { background: var(--azul-050); }

table.datos .num {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

table.datos tr.critico { background: var(--danger-bg); }
table.datos tr.critico:hover { background: #fbe0dd; }
.agotado { color: var(--danger); font-weight: 600; }
.positivo { color: var(--ok); font-weight: 600; }
.atenuado { color: var(--gris-400); }

/* --- Botones ------------------------------------------------------------ */

.btn,
.btn-primary,
.btn-outline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 15px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-family: inherit;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    border: 1px solid transparent;
    transition: background .12s ease, border-color .12s ease;
}

.btn-primary { background: var(--azul-600); color: var(--blanco); }
.btn-primary:hover { background: var(--azul-700); }

.btn-outline {
    background: var(--blanco);
    color: var(--gris-700);
    border-color: var(--border);
}
.btn-outline:hover { background: var(--gris-100); border-color: var(--gris-400); }

.btn-primary:disabled,
.btn-outline:disabled { opacity: .55; cursor: not-allowed; }

.btn-mini {
    padding: 2px 8px;
    font-size: 11.5px;
    border-radius: 4px;
    border: 1px solid var(--border);
    background: var(--blanco);
    color: var(--gris-700);
    cursor: pointer;
    font-family: inherit;
}
.btn-mini:hover { background: var(--azul-100); border-color: var(--azul-200); }

/* --- Distintivos -------------------------------------------------------- */

.badge {
    display: inline-block;
    padding: 1.5px 7px;
    border-radius: 20px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .02em;
    background: var(--azul-100);
    color: var(--azul-700);
}
.badge.ok     { background: var(--ok-bg);     color: var(--ok); }
.badge.aviso  { background: var(--warn-bg);   color: var(--warn); }
.badge.malo   { background: var(--danger-bg); color: var(--danger); }
.badge.gris   { background: var(--gris-200);  color: var(--gris-500); }

/* --- Formularios y filtros ---------------------------------------------- */

.filtros {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 13px 15px;
    display: flex;
    flex-wrap: wrap;
    gap: 13px;
    align-items: flex-end;
    margin-bottom: 15px;
    box-shadow: var(--shadow-sm);
}

.filtros label,
.field label {
    display: block;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .045em;
    color: var(--text-soft);
    margin-bottom: 4px;
}

input[type=text], input[type=number], input[type=date],
input[type=search], select, textarea {
    padding: 7px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    background: var(--blanco);
    transition: border-color .12s ease, box-shadow .12s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--azul-500);
    box-shadow: 0 0 0 3px var(--azul-100);
}

.filtros input[type=number] { width: 86px; }
.filtros select { max-width: 270px; }

/* --- Avisos ------------------------------------------------------------- */

.alert {
    padding: 10px 13px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    margin-bottom: 12px;
    border-left: 3px solid;
}
.alert-error   { background: var(--danger-bg); border-color: var(--danger); color: #7d1a15; }
.alert-warning { background: var(--warn-bg);   border-color: var(--warn);   color: #6d4500; }
.alert-ok      { background: var(--ok-bg);     border-color: var(--ok);     color: #135c39; }
.alert-info    { background: var(--azul-100);  border-color: var(--azul-500); color: var(--azul-800); }

/* --- Paginación y notas ------------------------------------------------- */

.paginacion {
    margin-top: 14px;
    display: flex;
    gap: 8px;
    align-items: center;
    font-size: 13px;
}
.paginacion a {
    padding: 6px 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--gris-700);
    background: var(--blanco);
}
.paginacion a:hover { background: var(--azul-100); border-color: var(--azul-200); }
.paginacion .actual { color: var(--text-soft); }

.hint  { color: var(--text-soft); font-size: 12px; }
.vacio { color: var(--text-soft); padding: 26px 0; text-align: center; }

.nota {
    font-size: 12px;
    color: var(--text-soft);
    line-height: 1.65;
    margin-top: 14px;
    padding: 12px 14px;
    background: var(--gris-100);
    border-radius: var(--radius-sm);
    border-left: 3px solid var(--gris-300);
}
.nota strong { color: var(--gris-700); }
.nota code {
    background: var(--blanco);
    padding: 1px 5px;
    border-radius: 3px;
    border: 1px solid var(--border);
    font-size: 11.5px;
}

/* --- Modales ------------------------------------------------------------ */

.modal-fondo {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(14, 36, 57, .5);
    z-index: 2000;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.modal-fondo.abierto { display: flex; }

.modal-caja {
    background: var(--panel);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 20px 22px;
    max-width: 100%;
    max-height: 92vh;
    overflow: auto;
}
.modal-caja h3 {
    margin: 0 0 4px;
    font-size: 16px;
    font-weight: 600;
}

/* Ficha de producto dentro de un modal ------------------------------------- *
 * Nacieron en la pantalla de compras (clic derecho sobre una línea) y ahora
 * las usa también Almacén → Lista de productos, así que viven aquí. Mientras
 * `css/compras.css` conserve su copia idéntica, la de allí gana por orden de
 * carga; al reformar esa pantalla hay que borrar el duplicado.
 *
 * Dos columnas, como `admin/item.php`: datos a la izquierda, precios a la
 * derecha. En una sola columna habría que desplazarse para comparar el costo
 * con los precios, que es justo lo que se viene a mirar. */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
@media (max-width: 700px) { .grid-2 { grid-template-columns: 1fr; } }

/* Descripción y Otro detalle, a todo el ancho: son los dos campos de texto
   largo (40 y 50 caracteres) y en media caja se leían a trozos. */
.ficha-ancho { margin-top: .6rem; }
.ficha-ancho .field { margin-bottom: .6rem; }
.ficha-ancho input { width: 100%; }

.ficha-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.4rem;
    margin-top: .6rem;
}
@media (max-width: 820px) {
    .ficha-cols { grid-template-columns: 1fr; gap: .8rem; }
}

.ficha-h {
    font-size: .72rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-soft);
    margin: 0 0 .6rem;
    padding-bottom: .3rem;
    border-bottom: 1px solid var(--border);
}

table.precios { width: 100%; border-collapse: collapse; }
table.precios th {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--text-soft);
    font-weight: 600;
    text-align: left;
    padding: .3rem .4rem;
}
table.precios th.num { text-align: right; }
table.precios td { padding: 2px 4px; font-size: .84rem; }
table.precios td:first-child { color: var(--text-soft); white-space: nowrap; }
table.precios input {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: .3rem .4rem;
    font-size: .84rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
table.precios input:focus { border-color: var(--accent); outline: none; }

.barra-acciones {
    display: flex;
    gap: 9px;
    align-items: center;
    margin-top: 15px;
    padding-top: 14px;
    border-top: 1px solid var(--border-soft);
}

/* ===========================================================================
 * IMPRESIÓN
 *
 * POR QUÉ HACE FALTA: sin esto el navegador imprime el documento SIN fondos
 * —es su comportamiento por omisión— así que los encabezados de tabla, las
 * tarjetas de cifras y los avisos salen en blanco y el documento pierde la
 * estructura que lo hace legible. Un estado de cuenta guardado en PDF no se
 * parecía a lo que se ve en pantalla.
 *
 * Aplica a todo lo que use esta hoja: estados de cuenta de clientes y de
 * proveedores, análisis, informes.
 * ======================================================================== */

@media print {
    /* Que los fondos SÍ se impriman. Es la regla que arregla el grueso del
       problema; el resto son ajustes de página. */
    *, *::before, *::after {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    @page { margin: 12mm; }

    body,
    body.page {
        background: var(--blanco);
        padding: 0;
        margin: 0;
        font-size: 11.5px;
    }

    /* El armazón del panel no es contenido: si alguien imprime desde la
       pantalla completa, la barra lateral y las pestañas sobran. */
    aside,
    .tabs,
    .menu-toggle,
    .sidebar-overlay,
    .paginacion,
    .filtros,
    .barra-acciones,
    .no-print {
        display: none !important;
    }

    .main-content { display: block; }
    .main-header { border-bottom: 1px solid var(--border); padding: 0 0 8px; }

    /* En pantalla la caja recorta a 480px con barra propia; al imprimir eso
       cortaría la tabla por la mitad. Se abre entera. */
    .tabla-wrap {
        overflow: visible !important;
        max-height: none !important;
        border: none;
        box-shadow: none;
        border-radius: 0;
    }

    /* `sticky` no tiene sentido en papel y descoloca el encabezado. Con
       `table-header-group` se repite arriba de cada página, que es lo que
       hace legible una tabla larga. */
    table.datos th,
    table.lineas th {
        position: static !important;
    }
    table.datos thead,
    table.lineas thead,
    thead {
        display: table-header-group;
    }
    table.datos tr, table.datos td, table.datos th,
    table.lineas tr, table.lineas td, table.lineas th,
    tr, td, th {
        page-break-inside: avoid;
    }

    /* Membrete de la empresa: logo a la izquierda, datos a la derecha, con el
       mismo filete azul que el PDF del chatbot. Sale SOLO al imprimir; en
       pantalla el documento ya vive dentro del panel. */
    .membrete-fila { display: table-row; }
    .membrete-fila th {
        background: none !important;
        border: none !important;
        border-bottom: 2px solid var(--azul-700) !important;
        padding: 0 0 8px !important;
        font-weight: normal;
        text-transform: none;
        letter-spacing: normal;
        font-size: 9.5px;
        color: var(--gris-900);
    }
    .membrete {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 20px;
    }
    .membrete-logo img { width: 156px; height: auto; display: block; }
    .membrete-lema {
        font-size: 8px;
        font-weight: bold;
        color: var(--azul-700);
        margin-top: 3px;
        letter-spacing: .01em;
    }
    .membrete-datos { text-align: right; line-height: 1.5; white-space: nowrap; }
    .membrete-nombre { font-size: 13px; font-weight: bold; margin-bottom: 3px; }

    /* Membrete de los estados de cuenta (cliente, rango de fechas). Va dentro
       del mismo <thead> para repetirse en cada página, pero es cabecera de
       DOCUMENTO, no de columna: sin el fondo gris de los th. */
    .thead-print-header th {
        background: none !important;
        border-bottom: none;
    }

    /* Las sombras no se imprimen y en algunos motores dejan bandas grises. */
    .panel, .tarjeta, .tabla-wrap, .modal-caja {
        box-shadow: none !important;
    }
    .panel { break-inside: avoid; }

    /* Los enlaces en papel no se pulsan: subrayarlos sólo añade ruido. */
    a { text-decoration: none; color: inherit; }

    /* Un modal abierto ocupa la pantalla; al imprimir tiene que fluir como
       contenido normal o sale una página en negro. */
    .modal-fondo {
        position: static;
        display: block;
        background: none;
        padding: 0;
    }
    .modal-caja {
        width: auto !important;
        max-width: none;
        max-height: none;
        overflow: visible;
    }
}

/* El membrete sólo tiene sentido en papel: en pantalla el documento ya vive
   dentro del panel, que identifica de sobra dónde está uno.
   Va dentro de `@media screen` y NO como regla suelta: suelta se aplicaría
   también al imprimir y, por ir después del bloque @media print, ganaría —
   dejando el membrete oculto justo donde hace falta. */
@media screen {
    .membrete-fila { display: none; }
}
