/* ============================================================
   OFICON — Sistema Contable Web Empresarial (Desarrollado por DEXTRA)
   Estilos principales
   ============================================================ */

/* Evita que elementos con x-show sean visibles antes de que Alpine inicialice */
[x-cloak] { display: none !important; }

/* ── Selector desplegable de cuenta con búsqueda ("hsel") ─────
   Reemplaza al <select> nativo en selectores de cuenta contable
   (plan de cuentas, modales de "agregar cuenta", configuración de
   cuentas de cobro/pago en importación de ventas/compras, etc.):
   un <select> con decenas de cuentas resulta difícil de recorrer,
   mientras que este buscador filtra por código o nombre. Centralizado
   aquí (antes duplicado por página) para que cualquier vista lo use
   sin repetir el CSS. */
.hsel { position: relative; }
.hsel-trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  padding: 0.46rem 0.75rem; border: 1px solid var(--border); border-radius: 6px;
  background: var(--s2); cursor: pointer; font-size: 0.88rem; color: var(--dark);
  transition: border-color .15s;
}
.hsel-trigger:hover, .hsel-open .hsel-trigger { border-color: var(--primary); }
.hsel-trigger:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.hsel-val { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hsel-arrow { width: 10px; height: 6px; flex-shrink: 0; color: var(--secondary); transition: transform .2s; }
.hsel-open .hsel-arrow { transform: rotate(180deg); }
.hsel-panel {
  position: fixed; z-index: 700;
  background: var(--s2); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.12); overflow: hidden;
  width: 480px; max-width: 90vw;
}
.hsel-search-wrap { padding: 0.5rem; border-bottom: 1px solid var(--border); }
.hsel-search {
  width: 100%; padding: 0.38rem 0.65rem; border: 1px solid var(--border); border-radius: 5px;
  font-size: 0.83rem; background: var(--s1); color: var(--dark); outline: none; box-sizing: border-box;
}
.hsel-search:focus { border-color: var(--primary); }
.hsel-list { max-height: 50vh; overflow-y: auto; }
.hsel-opt {
  display: flex; align-items: center; gap: 0.45rem;
  padding: 0.38rem 10px; cursor: pointer; font-size: 0.84rem;
  transition: background .1s; white-space: nowrap; overflow: hidden;
}
.hsel-opt:hover { background: var(--hover, #f1f5f9); }
.hsel-opt.hsel-selected { background: #eff6ff; }
/* Resaltado con teclado (↑↓) en listas de sugerencias que no usan la clase
   base ".hsel-opt" (ej. buscador de Cuenta en /comprobantes/crear) — regla
   genérica para que el resaltado se vea sin depender de esa clase. */
.hsel-selected { background: #eff6ff; }
.hsel-opt-root { font-style: italic; color: var(--secondary); font-size: 0.82rem; }
.hsel-code { font-family: monospace; color: var(--primary); font-weight: 600; font-size: 0.82rem; flex-shrink: 0; }
.hsel-name { overflow: hidden; text-overflow: ellipsis; }
.hsel-empty { padding: 0.75rem 1rem; color: var(--secondary); font-size: 0.83rem; font-style: italic; }
/* Cuenta de pago/cobro "en blanco" que en realidad contabilizará con la
   cuenta global configurada (Config. de cuentas contables): se muestra en
   gris/cursiva, como una marca de agua, para no confundirla con una cuenta
   elegida a propósito para esa factura — a pedido de Edson (27/07/2026): se
   puede modificar NIT por NIT o factura por factura, pero mientras no se
   toque, se contabiliza con la global igual. */
.hsel-val-global { font-style: italic; color: var(--t4); }

/* Variables */
:root {
  --primary:    #6366f1;
  --primary-dk: #4f46e5;
  --primary-hover: #3b82f6;
  --secondary:  #64748b;
  --success:    #16a34a;
  --danger:     #dc2626;
  --warning:    #d97706;
  --info:       #0891b2;
  --light:      #f8fafc;
  --dark:       #1e293b;
  --border:     #e2e8f0;
  --sidebar-w:  208px;
  --topbar-h:   36px;
  /* Botón "compacto" (topbar de acciones, filter-bar, contenedores
     embebidos) — antes cada pantalla que necesitaba este tamaño volvía a
     escribir "padding:0.18rem 0.55rem;font-size:0.75rem" a mano en su
     propio <style>, y ya se había desviado en algún lado (0.5rem/0.72rem
     en vez de 0.55rem/0.75rem). Centralizado acá — a pedido de Edson
     (31/07/2026: "optimizar" el CSS de botones repetido en cada página).
     Ver .btn-compact / .topbar-actions .btn / .filter-bar .btn más abajo. */
  --btn-compact-padding:   0.18rem 0.55rem;
  --btn-compact-font-size: 0.75rem;
  /* Sidebar independiente — se sobreescribe por tema */
  --sb-bg:      var(--s2);
  --sb-t1:      var(--t1);
  --sb-t2:      var(--t3);
  --sb-t3:      var(--t4);
  --sb-border:  var(--b1);
  --sb-hover:   var(--b2);
  /* Tema dinámico — sobreescritas por el script de restore en main.php */
  --ta:     #6366f1;
  --tb:     #4f46e5;
  --ta-r:   99; --ta-g: 102; --ta-b: 241;
  --page-bg:#f1f5f9;
  --s1:#f8fafc; --s2:#ffffff; --s3:#f1f5f9; --s4:#e2e8f0;
  --b1:rgba(0,0,0,.06); --b2:rgba(0,0,0,.09); --b3:rgba(0,0,0,.12); --b4:rgba(0,0,0,.15);
  --t1:#0f172a; --t2:#1e293b; --t3:#475569; --t4:#64748b; --t5:#94a3b8;
  --card-bg:#ffffff; --row-border:rgba(0,0,0,.06); --row-even:rgba(0,0,0,.025);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 14px; }
body { font-family: 'Segoe UI', system-ui, sans-serif; background: var(--s1); color: var(--t2); line-height: 1.5; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── Barras de desplazamiento temáticas ─────────────────── */
* { scrollbar-width: thin; scrollbar-color: var(--b3) var(--s1); }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-track { background: var(--s1); }
*::-webkit-scrollbar-thumb { background: var(--b4); border-radius: 5px; }
*::-webkit-scrollbar-thumb:hover { background: var(--t5); }
*::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

/* ── Topbar ─────────────────────────────────────────── */
.topbar {
  position: fixed; top: 0; left: var(--sidebar-w); right: 0;
  min-height: var(--topbar-h); height: auto;
  background: var(--s2); border-bottom: 1px solid var(--b2);
  display: flex; align-items: center;
  padding: 0.15rem 0.85rem; z-index: 100; gap: 0.5rem; flex-wrap: wrap;
}
.topbar-left  { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
.topbar-right { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; margin-left: auto; }
.topbar-page-title { font-size: 1.05rem; font-weight: 700; color: var(--t1); white-space: nowrap; }
.topbar-actions {
  display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; min-width: 0;
}
.topbar-actions .btn,
.topbar-right .btn,
/* Clase explícita para usar el mismo tamaño compacto en botones que NO
   viven dentro de .topbar-actions/.topbar-right/.filter-bar (embebidos,
   paneles de acciones propios, etc.) — reemplaza las declaraciones a mano
   que había en embed.php, reportes/index.php, reportes/libro_mayor.php y
   comprobantes/importar_ventas_lote.php. */
.btn-compact {
  padding: var(--btn-compact-padding); font-size: var(--btn-compact-font-size);
}
/* Pantallas con muchos botones de acción (p. ej. Activos fijos) se veían
   amontonados/desordenados junto al título y al menú de usuario cuando no
   entraban todos en una sola línea. En vez de un ancho fijo de pantalla
   (antes "@media (max-width: 1440px)"): ese umbral no tiene en cuenta
   CUÁNTOS botones tiene cada pantalla — con solo 1-2 (ej. Estado de
   resultados: "⚙ Agrupación"/"← Reportes") sobraba espacio de sobra a
   1280px y aun así se enviaban a su propia fila, separándolos del título
   sin necesidad. Ahora un script en layouts/main.php mide en cada pantalla
   si el título + los botones + el menú de usuario entran de verdad en una
   sola línea, y solo si NO entran agrega esta clase ".wrap-actions" al
   <header class="topbar"> — los botones de acción pasan entonces a su
   propia fila completa (ordenados como "soldados en fila" y bajando de
   línea entre ellos si hace falta), con el título/menú de usuario arriba. */
.topbar.wrap-actions .topbar-actions { flex-basis: 100%; order: 3; justify-content: flex-start; }
.topbar.wrap-actions .topbar-right   { order: 2; }
.breadcrumb   { font-size: 0.8rem; color: var(--t4); }
.breadcrumb span + span::before { content: ' › '; }

/* ── Sidebar ─────────────────────────────────────────── */
.sidebar {
  position: fixed; top: 0; left: 0; bottom: 0; width: var(--sidebar-w);
  background: var(--sb-bg); color: var(--sb-t2); display: flex; flex-direction: column;
  overflow-y: auto; z-index: 200;
  scrollbar-color: var(--sb-hover) var(--sb-bg);
  transition: background 0.25s, left 0.22s ease, transform 0.22s ease;
}
.sidebar::-webkit-scrollbar-track { background: var(--sb-bg); }
.sidebar::-webkit-scrollbar-thumb { background: var(--sb-hover); }
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--sb-t3); }
.sidebar nav { scrollbar-color: var(--sb-hover) var(--sb-bg); }
.sidebar nav::-webkit-scrollbar { width: 9px; }
.sidebar nav::-webkit-scrollbar-track { background: var(--sb-bg); }
.sidebar nav::-webkit-scrollbar-thumb { background: var(--sb-hover); border-radius: 5px; }
.sidebar nav::-webkit-scrollbar-thumb:hover { background: var(--sb-t3); }
/* Reducido 20% (a pedido de Edson, 19/08/2026: "reduce el contenedor de
   Casa matriz en /dashboard en un 20%") — es el bloque de logo+nombre de
   empresa arriba del todo del sidebar (visible en TODAS las pantallas, no
   solo /dashboard, porque vive en layouts/main.php). Se achicó
   proporcionalmente: padding, gap, tamaño de fuente, logo y subtítulo,
   todos al 80% de sus valores originales (1rem→0.8rem, 1.25rem→1rem,
   0.75rem→0.6rem, 36px→29px, 0.7rem→0.56rem). Reducido OTRO 20% el mismo
   día ("reduce el campo donde esta Casa matriz, en un 20%") — otra vez
   proporcional, al 80% de los valores de arriba (0.8rem→0.64rem,
   1rem→0.8rem, 0.6rem→0.48rem, 29px→23px, 0.56rem→0.45rem). */
.sidebar-brand {
  padding: 0.64rem 0.8rem; border-bottom: 1px solid var(--sb-border);
  display: flex; align-items: center; gap: 0.48rem;
  font-size: 0.64rem; font-weight: 700; color: var(--sb-t1);
}
.sidebar-brand img { width: 23px; height: 23px; border-radius: 6px; object-fit: cover; }
.sidebar-brand .brand-sub { font-size: 0.45rem; font-weight: 400; color: var(--sb-t3); }

/* ── Nav groups (collapsible sidebar sections) ───────── */
/* Simplificado a pedido de Edson (27/07/2026): "toda la barra lateral del
   menú que sea de un solo color, solo el submenu sea un tono distinto".
   Se sacó la franja de color y el tintado del encabezado — el encabezado
   de grupo se ve igual que el resto de la barra (mismo color, incluido su
   hover). Lo ÚNICO distinto es el fondo de .nav-group-body (el bloque de
   hijos, visible solo cuando el grupo está abierto), un tono más oscuro
   que el resto del sidebar. */
.nav-group {
  border-bottom: 1px solid var(--sb-border);
}

.nav-group-header {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 0.55rem 1.25rem;
  background: transparent;
  border: none; cursor: pointer;
  color: var(--sb-t2); font-size: 0.68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.07em; text-align: left;
  transition: color 0.15s, background 0.15s;
}
.nav-group-header:hover { background: var(--sb-hover); color: var(--sb-t1); }
.nav-group-header-label { display: flex; align-items: center; gap: 0.45rem; }
.nav-group-header-label svg { width: 14px; height: 14px; flex-shrink: 0; }
.nav-group-arrow {
  display: inline-block; font-size: 0.65rem; line-height: 1;
  transition: transform 0.2s; transform: rotate(-90deg); color: var(--sb-t3);
}
.nav-group-arrow.open { transform: rotate(0deg); }
.nav-group-body {
  overflow: hidden;
  /* El único tono distinto de todo el sidebar: el bloque de hijos. */
  background: color-mix(in srgb, var(--sb-bg) 82%, black 18%);
}

/* nav items */
.nav-item { display: flex; align-items: center; gap: 0.625rem; padding: 0.5rem 1.25rem; cursor: pointer; border-radius: 0; transition: background 0.15s; color: var(--sb-t2); font-size: 0.85rem; }
.nav-item:hover { background: var(--sb-hover); color: var(--sb-t1); text-decoration: none; }
.nav-item.active { background: var(--primary); color: #fff; }
.nav-item svg { width: 16px; height: 16px; flex-shrink: 0; }
.nav-item-sub  { padding-left: 2rem; font-size: 0.82rem; }
.nav-item-sub2 { padding-left: 2.75rem; font-size: 0.78rem; color: var(--sb-t3); }
/* Indicador de "estás acá" dentro del submenu — a pedido de Edson
   (27/07/2026): en vez del mismo relleno sólido que usan los ítems de
   primer nivel, el ítem activo dentro de un grupo lleva una barra de color
   a la izquierda + fondo tintado suave, para que se note cuál es la
   página activa sin romper el color único del resto de la barra. */
.nav-item-sub.active {
  background: color-mix(in srgb, var(--primary) 20%, transparent);
  color: var(--sb-t1);
  font-weight: 600;
  border-left: 3px solid var(--primary);
  padding-left: calc(2rem - 3px);
}
.nav-item-sub2.active { padding-left: calc(2.75rem - 3px); }
.nav-item-sub2:hover { color: var(--sb-t1); }
/* Iconos sueltos fuera de .btn/.nav-item */
summary svg, .card-title svg { width: 16px; height: 16px; flex-shrink: 0; }
/* legacy — keep for any stray nav-submenu references */
.nav-submenu { padding-left: 2.5rem; }
.nav-submenu .nav-item { padding: 0.375rem 1rem; font-size: 0.8rem; }

/* ── Main content ─────────────────────────────────────── */
.main-content {
  margin-left: var(--sidebar-w);
  padding-top: var(--topbar-h);
  min-height: 100vh;
  /* Evita scroll horizontal por tablas anchas */
  overflow-x: hidden;
}
.page-body { padding: 0.3rem 1rem 1rem; }
.page-header { margin-bottom: 1.25rem; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; }
.page-title  { font-size: 1.25rem; font-weight: 600; color: var(--t1); }
.page-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }

/* ── Cards ───────────────────────────────────────────── */
.card { background: var(--s2); border: 1px solid var(--b2); border-radius: 8px; overflow: hidden; }
.card-header { padding: 0.875rem 1.25rem; border-bottom: 1px solid var(--b2); display: flex; align-items: center; justify-content: space-between; }
.card-collapsible.collapsed { display: none; }
.card-title  { font-weight: 600; font-size: 0.95rem; color: var(--t1); }
.card-body   { padding: 1.25rem; }
.card-footer { padding: 0.875rem 1.25rem; border-top: 1px solid var(--b2); background: var(--s3); }

/* Tarjetas de listado (tabla): el arreglo real no es limitarles el ancho a
   la fuerza — es que la TABLA reparta bien su propio espacio. Por defecto
   (auto-layout) una tabla estira TODAS las columnas por igual, así que
   Código/NIT/Tipo/Estado/Acciones (que no necesitan espacio) terminaban
   con huecos enormes: eso era lo que se veía "esparcido". La utilidad
   .col-fit (abajo) fija esas columnas angostas a su contenido y deja que
   la columna de texto largo (Nombre, Glosa...) absorba el resto — así la
   tarjeta puede usar el ancho disponible sin verse rara, sin importar
   cuántas columnas tenga la tabla ni qué tan ancha esté la pantalla.
   Sigue habiendo un techo (--content-max-w) pero ahora es solo un
   salvavidas raro (tablas de 2-3 columnas en un monitor gigante), no la
   regla principal. Aplica a cualquier tarjeta DENTRO de .page-body con una
   tabla, a cualquier profundidad (varias pantallas envuelven la tarjeta en
   un <div style="display:contents"> para Alpine.js — exigir "hija
   directa" no la alcanzaba, ese fue el bug la primera vez). Las tarjetas
   con tabla DENTRO de un modal se anulan aparte, para llenar el modal. */
.col-fit { white-space: nowrap; width: 1%; }

:root { --content-max-w: 1100px; }
.page-body .card:has(.table-responsive) {
  width: 100%;
  max-width: min(var(--content-max-w), 100%);
  margin-left: auto;
  margin-right: auto;
  align-self: center; /* por si el contenedor de la pantalla es flex (column) */
  transition: max-width 0.22s ease;
  box-shadow: 0 1px 3px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.04);
}
.modal-overlay .card,
.modal-box .card {
  width: 100% !important;
  max-width: 100% !important;
  align-self: stretch !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  box-shadow: none !important;
}

/* ── KPI Cards ───────────────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.kpi-card { background: var(--s2); border: 1px solid var(--b2); border-radius: 8px; padding: 1.25rem; }
.kpi-label  { font-size: 0.75rem; color: var(--t4); font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; display: flex; align-items: center; gap: 0.35rem; }
/* Sin esto el <svg> de icon() (sin width/height propios) queda sin
   restricción de tamaño y el navegador lo agranda solo — mismo problema que
   ya se resolvió para .nav-item svg / .btn svg / .card-title svg / .alert
   svg / .modal-title svg. Reportado por Edson (17/08/2026) en
   /puntos-venta/{id}: "los iconos salen muy grandes"; afecta a cualquier
   .kpi-label con icon() en toda la app (ver.php, libro_mayor.php,
   caja/index.php). */
.kpi-label svg { width: 14px; height: 14px; flex-shrink: 0; }
.kpi-value  { font-size: 1.6rem; font-weight: 700; color: var(--t1); margin: 0.25rem 0; }
.kpi-sub    { font-size: 0.75rem; color: var(--t4); }
.kpi-danger .kpi-value { color: var(--danger); }
.kpi-warn   .kpi-value { color: var(--warning); }
.kpi-good   .kpi-value { color: var(--success); }

/* ── Buttons ─────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.45rem 0.9rem; border-radius: 6px; font-size: 0.83rem; font-weight: 500; border: 1px solid transparent; cursor: pointer; transition: all 0.15s; line-height: 1.4; white-space: nowrap; }
.btn svg { width: 14px; height: 14px; }
.btn-primary   { background: var(--primary);   color: #fff; border-color: var(--primary); }
.btn-primary:hover { background: var(--primary-dk); border-color: var(--primary-dk); }
.btn-secondary { background: var(--s3); color: var(--t2); border-color: var(--b3); }
.btn-secondary:hover { background: var(--s4); }
.btn-success   { background: var(--success); color: #fff; }
.btn-danger    { background: var(--danger);  color: #fff; }
.btn-warning   { background: var(--warning); color: #fff; }
/* Solo el ícono en rojo, sin fondo — para acciones destructivas dentro de
   listas/tablas donde un botón rojo sólido por fila se ve muy pesado. */
.btn-ghost-danger { background: transparent; border-color: transparent; color: var(--danger); }
.btn-ghost-danger:hover:not(:disabled) { background: #fef2f2; border-color: #fecaca; }
.btn-ghost-danger:disabled { color: #fca5a5; opacity: 0.6; }
[data-dark] .btn-ghost-danger:hover:not(:disabled) { background: rgba(220,38,38,.15); border-color: rgba(220,38,38,.3); }
/* Resalte genérico para filas/ítems clicables en listas y menús desplegables
   (antes vivía duplicado dentro de comprobantes/form.php; se promueve aquí
   para poder usarse en cualquier vista, ej. el menú "Mi Perfil" del topbar). */
.hover-bg:hover { background: rgba(var(--ta-r),var(--ta-g),var(--ta-b),.10); }
/* Filas del árbol de plan de cuentas en el selector de cuenta (buscar/navegar
   al registrar un comprobante o al mapear cuentas en Importar Ventas/Compras).
   Antes vivía solo dentro de comprobantes/form.php; se promueve aquí para
   poder reutilizar el mismo selector (campoCuenta() en app/config/app.php)
   en cualquier pantalla. */
.arbol-item { padding: 0.38rem 10px; font-size: 0.84rem; display: flex; align-items: center; gap: 0.45rem; transition: background .1s; }
.arbol-item .monospace { color: var(--primary); font-weight: 600; font-size: 0.82rem; flex-shrink: 0; }
.arbol-item-mov { cursor: pointer; background: none; }
.arbol-item-mov:hover { background: var(--hover, #f1f5f9); }
.arbol-item-grupo { cursor: default; font-weight: 600; color: var(--t4); background: var(--s3); }
.btn-sm { padding: 0.3rem 0.65rem; font-size: 0.78rem; }
.btn-xs { padding: 0.2rem 0.5rem; font-size: 0.72rem; }
.btn[disabled], .btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── Forms ───────────────────────────────────────────── */
.form-grid  { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }
.form-group { display: flex; flex-direction: column; gap: 0.25rem; }
.form-group.span-2 { grid-column: span 2; }
.form-group.span-full { grid-column: 1 / -1; }
/* Etiqueta al lado del campo (no encima): para formularios cortos donde
   ahorrar alto vertical importa más que el ancho — ej. los "datos generales"
   de un comprobante, para dejarle más espacio en pantalla al detalle de
   abajo. Apilado de nuevo en pantallas angostas. */
.form-grid.form-grid-inline .form-group { flex-direction: row; align-items: center; gap: 0.5rem; }
.form-grid.form-grid-inline .form-group label { white-space: nowrap; flex-shrink: 0; margin: 0; }
.form-grid.form-grid-inline .form-group .form-control { flex: 1; width: auto; }

/* Grilla de cuentas (campoCuenta() en app/config/app.php, usado en Importar
   Ventas/Compras): cada bloque (Debe, Haber) es su PROPIA grilla de 2
   columnas — la columna de etiqueta se ajusta al contenido (max-content) de
   ESE bloque nada más, así "Cobro" en el Debe no hereda el ancho de la
   etiqueta más larga del Haber ni viceversa (eso era lo que dejaba un hueco
   "entre" ambos bloques). La columna del selector es de ancho fijo, igual
   en los 7/5 campos. Las etiquetas, alineadas a la derecha, quedan pegadas
   a su propio ícono de carpeta sin perder la alineación vertical entre
   filas del mismo bloque. */
.cuentas-grid { display: grid; grid-template-columns: max-content max-content; gap: 0.5rem 0.5rem; align-items: center; }
.cuenta-label { white-space: nowrap; text-align: right; font-size: 0.78rem; color: var(--t4); }
@media (max-width: 768px) {
  .cuentas-grid { grid-template-columns: 1fr; }
  .cuentas-grid .cuenta-label { text-align: left; }
}
@media (max-width: 768px) {
  .form-grid.form-grid-inline .form-group { flex-direction: column; align-items: stretch; }
}
label { font-size: 0.8rem; font-weight: 500; color: var(--t3); }
label .req { color: var(--danger); }
.form-control {
  padding: 0.45rem 0.75rem; border: 1px solid var(--b3); border-radius: 6px;
  font-size: 0.85rem; background: var(--s3); color: var(--t1); outline: none; width: 100%;
  transition: border-color 0.15s;
}
.form-control:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37,99,235,0.1); }
.form-control[readonly] { background: var(--s3); color: var(--t4); }
.form-control.is-invalid { border: 1px solid #dc2626; box-shadow: 0 0 0 1px #dc2626; }
.form-control.is-invalid:focus { border-color: #dc2626; box-shadow: 0 0 0 3px rgba(220,38,38,0.15); }
select.form-control { cursor: pointer; }
textarea.form-control { resize: vertical; min-height: 80px; }

/* ── Tables ──────────────────────────────────────────── */
.table-responsive { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: 0.83rem; }
.table th { padding: 0.625rem 0.875rem; background: var(--s3); border-bottom: 2px solid var(--b3); text-align: left; font-weight: 600; color: var(--t3); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }
.table td { padding: 0.6rem 0.875rem; border-bottom: 1px solid var(--row-border); vertical-align: middle; }
.table tbody tr:nth-child(even) td { background: var(--row-even); }
.table tbody tr:hover { background: var(--b2); }
.table .text-right  { text-align: right; }
.table .text-center { text-align: center; }
.table .monospace   { font-family: monospace; font-size: 0.8rem; }

/* ── Barra superior fija (título + filtros) ───────────── */
/* .sticky-toolbar envuelve el filter-bar para que quede inmóvil
   (pegado justo bajo el topbar) al hacer scroll en el área de tabla. */
.sticky-toolbar {
  position: sticky;
  top: var(--topbar-h);
  z-index: 20;
  background: var(--s1);
  padding-bottom: 0.3rem;
}

/* ── Tabla con scroll interno y encabezado fijo ───────── */
/* .table-scroll crea su PROPIA área de scroll acotada.
   El thead se fija con top:0 relativo a ese contenedor.
   Descuento: topbar(60) + page-body padding(14+21=35) +
   filter-bar sticky(~62) + footer(42) + margen(6) = ~205px  */
.table-scroll {
  overflow-y: auto;
  max-height: calc(100vh - 205px);
  min-height: 200px;
}

/* ── Reportes de página fija (sin scroll de página) ─────
   Varios reportes (Libro mayor, Saldo por auxiliar, Gastos no
   deducibles...) no dejan que TODA la página se desplace — la fijan a la
   altura visible de la ventana y solo el área de datos (la tabla) tiene su
   propio scroll interno, para que filtros/encabezados de columna queden
   siempre visibles sin importar cuántas filas haya. Cada uno repetía este
   mismo bloque de CSS a mano en su propio $extraCss (con un offset en px
   ligeramente distinto cada vez, según cuánto más alto tenga esa pantalla
   en particular) — se centraliza acá: cualquier vista solo necesita poner
   la clase "rpt-fixed-page" en algún elemento que ya renderice (el marcador
   en sí no necesita estilo propio, alcanza con que exista en el documento,
   ver ":has()" abajo) y, si el offset por defecto (19px) no le sirve,
   agregar TAMBIÉN "rpt-offset-30" (u otro modificador que se necesite) en
   ese mismo elemento. */
:root { --rpt-offset: 19px; }
html:has(.rpt-offset-30) { --rpt-offset: 30px; }
body:has(.rpt-fixed-page) { overflow: hidden !important; }
body:has(.rpt-fixed-page) .main-content { padding-bottom: 0 !important; }
body:has(.rpt-fixed-page) .page-body {
  padding: 0.3rem 0.5rem 0 !important;
  display: flex;
  flex-direction: column;
  height: calc(100vh - var(--topbar-h) - var(--rpt-offset));
}
/* La barra de filtros (".filter-bar", con o sin su propio id encima, como
   "#panelFiltrosMayor" en Libro mayor) no debe encogerse dentro de este
   flex-column — si no, le roba alto al área de scroll de abajo. */
body:has(.rpt-fixed-page) .filter-bar { flex-shrink: 0; }
/* El área que sí se desplaza (la tabla de datos) — mismo patrón repetido
   con distintos ids en cada reporte (antes "#saldoAuxScroll",
   "#ndTblScroll", etc., todos con exactamente este mismo CSS). El
   "max-height:none" pisa el límite genérico de ".table-scroll" (ver arriba,
   "calc(100vh - 205px)") para los reportes que combinan ambas clases —
   acá el alto ya lo fija el flex:1 del propio contenedor de página fija,
   así que ese límite genérico sobra (y, sin pisarlo, competía con el
   cálculo real dando un alto más chico de lo que corresponde). Inofensivo
   para cualquier otro elemento que no tenga ese límite de por sí. */
.rpt-scroll-area { flex: 1; min-height: 0; overflow: auto; max-height: none !important; }
/* En páginas con filter-bar sticky integrada, usar el override inline */
.table-sticky thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--s4);
  box-shadow: 0 2px 0 var(--b3);
  color: var(--t1);
  font-weight: 700;
}
/* Fila de totales (tfoot) fija abajo del área de scroll, igual que el
   encabezado queda fijo arriba — para que la suma siempre quede visible
   aunque haya muchos lotes/meses cargados. */
.table-sticky tfoot td {
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: var(--s4);
  box-shadow: 0 -2px 0 var(--b3);
}
.table thead th { text-align: left; }

/* ── Badges / Estado ──────────────────────────────────── */
.badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.2rem 0.6rem; border-radius: 20px; font-size: 0.72rem; font-weight: 600; }
.badge-success    { background: #dcfce7; color: #15803d; }
.badge-danger     { background: #fee2e2; color: #b91c1c; }
.badge-warning    { background: #fef3c7; color: #92400e; }
.badge-info       { background: #e0f2fe; color: #0369a1; }
.badge-secondary  { background: #f1f5f9; color: #475569; }
.badge-primary    { background: #dbeafe; color: #1d4ed8; }
/* Modo oscuro — badges con colores adaptados */
[data-dark] .badge-success   { background: rgba(22,163,74,.20);  color: #86efac; }
[data-dark] .badge-danger    { background: rgba(220,38,38,.20);  color: #fca5a5; }
[data-dark] .badge-warning   { background: rgba(217,119,6,.20);  color: #fde68a; }
[data-dark] .badge-info      { background: rgba(8,145,178,.20);  color: #67e8f9; }
[data-dark] .badge-secondary { background: var(--s3); color: var(--t3); }
[data-dark] .badge-primary   { background: rgba(var(--ta-r),var(--ta-g),var(--ta-b),.25); color: var(--ta); }

/* ── Alerts / Flash ──────────────────────────────────── */
.alert { padding: 0.75rem 1rem; border-radius: 6px; margin-bottom: 1rem; display: flex; align-items: flex-start; gap: 0.75rem; font-size: 0.85rem; }
/* Sin esto, un <svg> sin width/height propios (como los que devuelve icon())
   renderiza a su tamaño por defecto del navegador (~300x150px) en vez de
   verse como un ícono chico — se notó "enorme" en los banners info de
   /aprobaciones y /roadmap, pero afecta a CUALQUIER icon('...') suelto
   dentro de un .alert en toda la app (ver icon() en app/config/app.php). */
.alert svg { width: 20px; height: 20px; flex-shrink: 0; }
.alert-success { background: #dcfce7; color: #15803d; border: 1px solid #bbf7d0; }
.alert-danger   { background: #fee2e2; color: #b91c1c; border: 1px solid #fecaca; }
.alert-warning  { background: #fef3c7; color: #92400e; border: 1px solid #fde68a; }
.alert-info     { background: #e0f2fe; color: #0369a1; border: 1px solid #bae6fd; }
/* Modo oscuro — alerts con colores adaptados */
[data-dark] .alert-success { background: rgba(22,163,74,.15);  color: #86efac; border-color: rgba(22,163,74,.3); }
[data-dark] .alert-danger  { background: rgba(220,38,38,.15);  color: #fca5a5; border-color: rgba(220,38,38,.3); }
[data-dark] .alert-warning { background: rgba(217,119,6,.15);  color: #fde68a; border-color: rgba(217,119,6,.3); }
[data-dark] .alert-info    { background: rgba(8,145,178,.15);  color: #67e8f9; border-color: rgba(8,145,178,.3); }

/* ── Comprobante (tabla debe/haber) ───────────────────── */
.comp-table { border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.comp-table .comp-header { background: var(--s4); color: var(--t1); padding: 0.75rem 1rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--b3); }
.comp-table .comp-row { display: grid; grid-template-columns: 3fr 4fr 1.5fr 1.5fr 1fr; border-bottom: 1px solid var(--border); }
.comp-table .comp-row-header { background: var(--s3); font-size: 0.72rem; font-weight: 600; text-transform: uppercase; color: var(--t4); letter-spacing: 0.05em; }
.comp-table .comp-cell { padding: 0.55rem 0.75rem; border-right: 1px solid var(--b2); }
.comp-table .comp-cell:last-child { border-right: none; }
.comp-table .comp-total { background: rgba(var(--ta-r),var(--ta-g),var(--ta-b),.10); font-weight: 700; }

/* ── Pagination ──────────────────────────────────────── */
.pagination { display: flex; gap: 0.25rem; align-items: center; flex-wrap: wrap; }
.pagination .page-item { display: inline-flex; }
.pagination .page-link { padding: 0.35rem 0.75rem; border: 1px solid var(--b3); border-radius: 5px; font-size: 0.8rem; color: var(--primary); background: var(--s2); }
.pagination .page-link:hover { background: var(--s3); }
.pagination .page-link.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.pagination .page-link.disabled { color: var(--t5); cursor: default; }

/* ── Toast notifications ──────────────────────────────── */
.toast-container { position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 9999; display: flex; flex-direction: column; gap: 0.5rem; }
.toast { padding: 0.75rem 1.25rem; border-radius: 8px; font-size: 0.85rem; min-width: 260px; max-width: 380px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); animation: slideIn 0.3s ease; display: flex; align-items: flex-start; gap: 0.75rem; }
.toast-success { background: #22c55e; color: #fff; }
.toast-error   { background: var(--danger); color: #fff; }
.toast-warning { background: var(--warning); color: #fff; }
.toast-info    { background: var(--primary); color: #fff; }
@keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: none; opacity: 1; } }

/* ── Ícono e ícono de ayuda "?" (helper ayuda() en app/config/app.php) ──
   Reemplaza los textos de ayuda que antes quedaban siempre visibles debajo
   de un campo (<small class="text-muted">...</small>): el ícono ocupa un
   espacio mínimo junto al label, y el texto solo aparece en un popover al
   pasar el mouse, enfocar con teclado, o hacer click (ver public/js/ayuda.js). */
.help-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--s3); color: var(--t4); border: 1px solid var(--border);
  font-size: 0.68rem; font-weight: 700; line-height: 1; cursor: help;
  vertical-align: middle; margin-left: 0.3rem; user-select: none;
}
.help-icon:hover, .help-icon:focus { background: var(--primary); color: #fff; border-color: var(--primary); outline: none; }
.ayuda-popover {
  position: fixed; z-index: 1000; max-width: 280px; background: var(--s2); color: var(--t1);
  border: 1px solid var(--border); border-radius: 8px; padding: 0.55rem 0.75rem;
  font-size: 0.8rem; line-height: 1.35; box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  white-space: pre-line;
}

/* ── Modal ───────────────────────────────────────────── */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 500; display: flex; align-items: center; justify-content: center; }
.modal-box { background: var(--s2); color: var(--t1); border-radius: 10px; padding: 1.5rem; min-width: 400px; max-width: 90vw; max-height: 90vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
.modal-title { font-size: 1.05rem; font-weight: 600; margin-bottom: 1rem; display: flex; align-items: center; gap: 0.4rem; }
.modal-title svg { width: 18px; height: 18px; flex-shrink: 0; }
.modal-footer { margin-top: 1.25rem; display: flex; gap: 0.5rem; justify-content: flex-end; }

/* ── Utils ───────────────────────────────────────────── */
.text-right  { text-align: right !important; }
.text-center { text-align: center !important; }
.text-muted  { color: var(--t4); font-size: 0.8rem; }
.text-danger { color: var(--danger); }
.text-success{ color: var(--success); }
.text-warning{ color: var(--warning); }
.fw-bold { font-weight: 700; }
.d-flex  { display: flex; }
.gap-1   { gap: 0.5rem; }
.gap-2   { gap: 1rem; }
.align-center { align-items: center; }
.justify-between { justify-content: space-between; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mb-1 { margin-bottom: 0.5rem; }
.mb-2 { margin-bottom: 1rem; }
.hidden { display: none !important; }

/* ── Filters bar ─────────────────────────────────────── */
.filter-bar { background: var(--s2); border: 1px solid var(--b2); border-radius: 8px; padding: 0.35rem 0.85rem; margin-bottom: 0.3rem; display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; }
/* Antes TODOS los campos (texto, select, fecha) compartían min-width:140px
   más flex:1, así que un select como "Estado" (pocas opciones cortas) o un
   <input type="date"> terminaban con el mismo ancho forzado que el buscador
   de texto — se veían desproporcionados y descuadraban los botones de la
   fila. Ahora solo el texto/búsqueda crece para llenar el espacio sobrante;
   los select y las fechas se ajustan a su propio contenido. */
.filter-bar .form-control { padding: 0.18rem 0.5rem; font-size: 0.75rem; }
.filter-bar input[type="text"].form-control,
.filter-bar input[type="search"].form-control { min-width: 110px; max-width: 240px; flex: 1; }
.filter-bar select.form-control { min-width: 0; width: auto; flex: 0 0 auto; }
/* 115px era más de lo que el campo necesita para mostrar "dd/mm/aaaa" +
   el ícono de calendario (probado en vivo en varias pantallas: a 100px
   entra completo, sin recortarse) — se achica para no gastar espacio de
   más en ninguna barra de filtros del sistema (Comprobantes, Cuentas por
   cobrar/pagar, reportes, etc.). Se incluye también ".ld-filters" (Libro
   diario trae su propia barra de filtros, con look distinto al de
   ".filter-bar", pero el campo de fecha debe medir lo mismo que en
   cualquier otro reporte — antes se quedaba afuera de esta regla y se
   veía con el ancho por defecto del navegador, más ancho que el resto). */
.filter-bar input[type="date"].form-control,
.ld-filters input[type="date"].form-control { min-width: 0; width: 100px; flex: 0 0 auto; }
/* Edson probó la forma de píldora (border-radius:999px) acá y no le gustó
   (05/08/2026) — quiere el mismo formato cuadrado/compacto que ya usan los
   botones del topbar de Reportes (Diario, Mayor, Comprobantes, Saldo
   auxiliar, Tipos de cambio, Presupuesto, Sumas y saldos, E. Resultados —
   ver #rptBotonesArriba en reportes/index.php, que son ".topbar-actions
   .btn" y NO tienen su propio border-radius: heredan el 6px de ".btn" en
   general, arriba en este mismo archivo). No hace falta ninguna regla acá:
   ".filter-bar .btn"/".filter-bar .form-control" ya caen solos en ese
   mismo 6px de ".btn"/".form-control" al no overridearlo — eso es
   justamente lo que los iguala a los botones del topbar. */
.filter-bar .btn { flex-shrink: 0; padding: var(--btn-compact-padding); font-size: var(--btn-compact-font-size); }
/* La etiqueta (ej. "Buscar cuenta", "Tipo") va al lado del campo, no encima
   — en una barra de filtros sobra espacio horizontal, así que apilarlas
   verticalmente solo agrega alto innecesario. En pantallas angostas, donde
   ya no sobra espacio, vuelve a apilarse (ver media query más abajo). */
.filter-bar .form-group { flex-direction: row; align-items: center; }
.filter-bar .form-group label { white-space: nowrap; margin: 0; }
@media (max-width: 768px) {
  .filter-bar .form-group { flex-direction: column; align-items: stretch; }
}

/* ── Reportes financieros (Balance General, Estado de Resultados,
   Evolución del Patrimonio) ──────────────────────────────
   Antes cada reporte reimplementaba sus propios colores/bordes/sangrías
   inline, con pequeñas diferencias entre sí (naranja para "PASIVO", cian
   para "PATRIMONIO", bordes de subtotal de distinto grosor/color, el
   total final a veces oscuro y a veces celeste...) — a pedido de Edson
   (31/07/2026: "no me gusta la estructura... mejora, que salga bien
   ordenado uniforme"), estas clases centralizan las 4 piezas visuales que
   se repiten en los 3 reportes, con el MISMO criterio en todos:
     .rf-seccion       encabezado de sección (INGRESOS, PASIVO, etc.)
     .rf-subtotal      subtotal de una sección (Total ingresos, Total Pasivo)
     .rf-destacada     total intermedio destacado (ej. Utilidad Bruta)
     .rf-total-general el total final de la página (oscuro, el más fuerte)
     .rf-thead-oscuro  encabezado de tabla oscuro (modo mensual/por centros)
     .rf-nivel-1..5    sangría por nivel de cuenta (mismo paso que ya
                        usaba Balance General: 0.5rem base + 1.1rem por nivel)
   Todas actúan sobre <tr> (aplican a sus <td>/<th> vía selector hijo) para
   poder pisar solo estilos de fila sin tocar los inline dinámicos que sí
   deben seguir variando por dato (ej. font-weight según si la cuenta tiene
   hijos). */
.rf-seccion > td, .rf-seccion > th {
  background: #f1f5f9; font-weight: 700; padding: 0.5rem 0.875rem;
  font-size: 0.82rem; letter-spacing: 0.05em; color: #1e293b;
}
.rf-subtotal > td {
  background: #f8fafc; font-weight: 700; border-top: 2px solid #e2e8f0;
}
.rf-destacada > td { background: #eff6ff; font-weight: 700; }
.rf-total-general > td {
  background: #1e293b; color: #fff; font-weight: 700; font-size: 0.95rem;
}
.rf-thead-oscuro > th { background: #1e293b; color: #fff; }
.rf-nivel-1 { padding-left: 0.5rem !important; }
.rf-nivel-2 { padding-left: 1.6rem !important; }
.rf-nivel-3 { padding-left: 2.7rem !important; }
.rf-nivel-4 { padding-left: 3.8rem !important; }
.rf-nivel-5 { padding-left: 4.9rem !important; }

/* ── Columna de Notas (Balance General / Estado de Resultados) ──
   Antes el número de nota salía pegado al nombre de la cuenta, como un
   badge inline ("Cuenta X (Nota 3)") — a pedido de Edson (05/08/2026:
   "las notas deberían tener una columna y no estar pegado a la cuenta"),
   ahora es su propia columna angosta al final de la fila. Se deja vacía
   cuando la cuenta no tiene nota vinculada (no "—", para no ensuciar la
   tabla de guiones). */
.rf-notas-col { width: 62px; text-align: center; font-size: 0.78rem; font-weight: 600; color: var(--primary); white-space: nowrap; }

/* ── Alinear la columna de montos entre tarjetas apiladas (Balance
   General: ACTIVO arriba, PASIVO Y PATRIMONIO debajo) ──────────────
   Cada tarjeta es un <table> HTML aparte, así que el navegador calcula el
   ancho de la columna "Cuenta" de cada una por separado según el largo de
   sus propios nombres de cuenta — si una tabla tiene nombres más largos
   que la otra, la columna de montos termina en una posición horizontal
   distinta entre ambas, aunque las tarjetas midan lo mismo (a pedido de
   Edson, 05/08/2026: "que todos los números estén en una sola columna").
   Fijando el mismo ancho de "Código"/"Cuenta" en las dos tablas, lo que
   sobra (el monto, alineado a la derecha) siempre arranca en el mismo
   punto en ambas — se ven como una sola columna continua al estar
   apiladas. */
.rf-codigo-col { width: 88px; }
.rf-cuenta-col { width: 320px; }
@media (max-width: 700px) { .rf-cuenta-col { width: auto; } }

/* ── Selector "N columnas" (Balance General, Estado de Resultados,
   Flujo de Efectivo) ──────────────────────────────────────────
   A pedido de Edson (05/08/2026: "que se pueda sacar reportes en 1, 2, 3
   o 4 columnas o lo que aplique"): un grupo de botones tipo segmented
   control que arma los bloques del reporte (ej. Activo / Pasivo y
   Patrimonio en Balance General) lado a lado en 1 a N columnas, según
   cuántos bloques tenga cada reporte. La preferencia se guarda en
   localStorage (una key por reporte) y se lee igual en pantalla y en la
   plantilla de impresión/PDF correspondiente, para que ambas coincidan
   sin tener que ida y vuelta por el servidor. .rf-blocks-grid es el
   contenedor real: su grid-template-columns lo fija JS según el botón
   activo, este CSS solo se encarga del look del selector y de que, si
   JS no llegó a correr por algún motivo, el contenedor caiga a 1 columna
   (apilado) en vez de quedar sin estilo. */
.rf-cols-switch { display: inline-flex; align-items: center; gap: 0.35rem; flex-shrink: 0; }
.rf-cols-switch-label { font-size: 0.85rem; font-weight: 600; color: var(--t2, #64748b); white-space: nowrap; }
.rf-cols-switch-btns { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.rf-cols-switch-btns button {
  border: none; background: var(--s2); color: var(--dark); cursor: pointer;
  font-size: 0.82rem; font-weight: 600; padding: 0.3rem 0.65rem; line-height: 1;
  border-right: 1px solid var(--border);
}
.rf-cols-switch-btns button:last-child { border-right: none; }
.rf-cols-switch-btns button:hover { background: var(--s3, #f1f5f9); }
.rf-cols-switch-btns button.activo { background: var(--primary); color: #fff; }
.rf-blocks-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (max-width: 900px) { .rf-blocks-grid { grid-template-columns: 1fr !important; } }
@media print { .rf-cols-switch { display: none !important; } }

/* Título de sección editable del Estado de Resultados (a pedido de Edson,
   31/07/2026: "el texto INGRESOS OPERATIVOS debería poder modificar por
   ejemplo Ingresos por ventas") — se ve como el título normal (hereda color/
   negrita/tamaño de .rf-seccion) hasta que se hace foco, ahí muestra que es
   editable. .solo-print es el texto plano equivalente que solo se ve al
   imprimir (el <input> tiene .no-print y desaparece en @media print).
   Nota (01/08/2026): el selector "mover de sección", los subtítulos
   personalizados y el arrastrar-soltar del ER se sacaron — la estructura
   ahora sale del plan de cuentas real (ver
   ReportesController::erEstructuraAcumulado()); para reclasificar una
   cuenta se edita en Plan de Cuentas, no en este reporte. */
.input-titulo-seccion {
  background: transparent; border: none; border-bottom: 1px dashed transparent;
  font: inherit; font-weight: 700; letter-spacing: 0.05em; color: inherit;
  padding: 0; width: 100%; max-width: 340px;
}
.input-titulo-seccion:hover { border-bottom-color: var(--b4); }
.input-titulo-seccion:focus { border-bottom-color: var(--primary); outline: none; }
.solo-print { display: none; }
@media print { .solo-print { display: inline !important; } }

/* ── Semáforo ────────────────────────────────────────── */
.semaforo { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.semaforo-green  { background: var(--success); }
.semaforo-yellow { background: var(--warning); }
.semaforo-red    { background: var(--danger); }

/* ── Footer ─────────────────────────────────────────── */
.app-footer {
  position: fixed; bottom: 0; left: var(--sidebar-w); right: 0;
  background: transparent; border: none;
  display: flex; align-items: center; justify-content: center;
  padding: .15rem 1rem .2rem; z-index: 99; pointer-events: none;
}
.app-footer-inner {
  display: inline-flex; align-items: center; gap: .55rem; flex-wrap: wrap; justify-content: center;
  /* Mismo color que el menú lateral (a pedido de Edson, 06/08/2026: "que
     sea del mismo color del menú lateral") — "var(--sb-bg)" es la MISMA
     variable que usa ".sidebar" (app.css, más arriba) para su fondo, así
     que quedan siempre iguales aunque "--sb-bg" cambie de valor más
     adelante (ej. un tema oscuro). Pisa el pedido anterior (31/07/2026:
     "que el fondo del footer resalte más, antes era var(--s2) casi igual al
     fondo de la página") — "--sb-bg" hoy vale justo var(--s2), así que
     vuelve a lo de antes de ese cambio, ahora a propósito. */
  background: var(--sb-bg); border: 1px solid var(--b4); border-radius: 999px;
  padding: .2rem .8rem;
  box-shadow: 0 2px 12px rgba(0,0,0,.14), 0 1px 3px rgba(0,0,0,.08);
  pointer-events: auto;
}
/* Claros y en negrita, LOS TRES por igual (a pedido de Edson, 06/08/2026:
   "que sean claros en negrita a todos"; y después "con el fondo azul no se
   lee bien" — "var(--t4)" es de la paleta GENERAL de la página (pensada
   para texto oscuro sobre fondo claro), pero el fondo de este footer ya es
   "var(--sb-bg)" (el mismo azul del menú lateral, ver más abajo) — un
   sistema de colores INDEPENDIENTE ("Sidebar independiente", ver
   layouts/main.php donde el tema pisa "--sb-bg/--sb-t1/--sb-t2/--sb-t3" por
   separado de "--t1..--t5"), así que había que usar el texto claro DE ESE
   MISMO sistema ("--sb-t1", el más claro de los tres — el que ya usa
   ".nav-item:hover"/".nav-group-header:hover" del menú lateral — no
   "--t4"), para que el contraste contra el azul sea el correcto en
   cualquier tema, no solo en el que se probó. */
.app-footer-item { display: inline-flex; align-items: center; gap: .3rem; color: var(--sb-t1); font-size: .71rem; font-weight: 700; }
.app-footer-item svg { width:11px !important; height:11px !important; opacity:.65; flex-shrink:0; }
/* Pedido anterior (31/07/2026): el usuario logueado resaltaba más oscuro
   que el resto — reemplazado por el pedido de arriba (06/08/2026), que
   pide justo lo contrario: los tres iguales, claros. */
.app-footer-item-usuario { color: var(--sb-t1); font-weight: 700; }
.app-footer-item-usuario svg { opacity: .8; }
.app-footer-sep { width: 1px; height: 14px; background: var(--b3); flex-shrink: 0; }
.main-content { padding-bottom: 42px; }

/* ── Print ───────────────────────────────────────────── */
@media print {
  .sidebar, .topbar, .page-actions, .no-print, .filter-bar { display: none !important; }
  .main-content { margin: 0 !important; padding: 0 !important; }
  .page-body { padding: 0 !important; }
  .card { border: none !important; box-shadow: none !important; }
  body { background: #fff !important; font-size: 12px; }
  .table th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* Las tablas con scroll interno deben mostrarse completas al imprimir,
     no recortadas a lo que estaba visible en pantalla. */
  .table-scroll { max-height: none !important; overflow: visible !important; }
  .sticky-toolbar { position: static !important; background: none !important; }
}

/* ── Responsive ──────────────────────────────────────── */
@media (max-width: 768px) {
  :root { --sidebar-w: 0px; }
  .sidebar { transform: translateX(-100%); transition: transform 0.15s; }
  .sidebar.open { transform: none; --sidebar-w: 208px; }
  .topbar { left: 0; }
  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .hide-mobile { display: none; }
}

/* ── Ocultar/mostrar menú lateral (escritorio) ─────────
   El usuario puede esconder el sidebar con el botón ☰ del topbar.
   Al esconderlo, el contenido principal y el topbar se expanden para
   aprovechar todo el ancho de pantalla — la preferencia se recuerda
   (localStorage) entre recargas y navegación entre páginas. */
.sidebar, .topbar, .main-content { transition: left 0.12s ease, margin-left 0.12s ease, transform 0.12s ease; }
@media (min-width: 769px) {
  body.sidebar-collapsed .sidebar      { transform: translateX(-100%); }
  body.sidebar-collapsed .topbar       { left: 0; }
  body.sidebar-collapsed .main-content { margin-left: 0; }
  body.sidebar-collapsed .app-footer   { left: 0; }
}

/* ── Organigrama — árbol visual ─────────────────────────
   A pedido de Edson (27/07/2026): "que se genere como un organigrama como
   tal con las líneas y demás que definan responsabilidad, inmediato
   superior, subalternos". Técnica estándar de árbol 100% CSS sobre
   <ul><li> anidados (ver app/views/organigrama/index.php): cada <li> dibuja
   su propia línea vertical de bajada y un tramo de la línea horizontal que
   lo conecta con sus hermanos, usando solo bordes — no hace falta canvas
   ni ninguna librería de gráficos. */
.org-chart-wrap { overflow-x: auto; padding: 1rem 0.5rem; }
.org-tree, .org-tree ul {
  display: flex;
  justify-content: center;
}
.org-tree ul { padding-top: 20px; position: relative; }
.org-tree li {
  list-style: none;
  text-align: center;
  position: relative;
  padding: 20px 10px 0 10px;
  white-space: nowrap;
}
/* Tramo de línea horizontal que conecta cada puesto con sus hermanos, más
   el tramo vertical que baja desde esa horizontal hasta la caja. */
.org-tree li::before,
.org-tree li::after {
  content: '';
  position: absolute;
  top: 0; right: 50%;
  border-top: 1px solid var(--border);
  width: 50%; height: 20px;
}
.org-tree li::after {
  right: auto; left: 50%;
  border-left: 1px solid var(--border);
}
.org-tree li:only-child::before,
.org-tree li:only-child::after {
  display: none;
}
.org-tree li:only-child { padding-top: 0; }
.org-tree li:first-child::before,
.org-tree li:last-child::after {
  border: 0 none;
}
.org-tree li:last-child::before {
  border-right: 1px solid var(--border);
  border-radius: 0 6px 0 0;
}
.org-tree li:first-child::after {
  border-radius: 6px 0 0 0;
}
/* Tronco que baja del puesto padre hacia la fila de sus subalternos */
.org-tree ul ul::before {
  content: '';
  position: absolute;
  top: 0; left: 50%;
  border-left: 1px solid var(--border);
  width: 0; height: 20px;
}
/* Los puestos de primer nivel (sin superior) no cuelgan de nada — sin línea
   entrante, aunque haya varios uno al lado del otro. */
.org-tree > ul { padding-top: 0; }
.org-tree > ul > li {
  padding-top: 0;
}
.org-tree > ul > li::before,
.org-tree > ul > li::after {
  display: none;
}
.org-tree .org-node {
  display: inline-block;
  min-width: 170px;
  max-width: 220px;
  white-space: normal;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.75rem;
  background: var(--s1, #fff);
  text-align: center;
}
