/* ============================================================
   Hub Core — overrides locales
   Tailwind y Flowbite cargan vía CDN en el layout.
   Aquí van solo ajustes finos y utilidades que Tailwind no cubre.
   ============================================================ */

/* ─── Tokens de tema (RGB sin envolver para alpha-value de Tailwind) ─── */
:root,
[data-theme="dark"] {
  --bg-base:        2 6 23;        /* slate-950 */
  --surface-1:     15 23 42;       /* slate-900 */
  --surface-2:     30 41 59;       /* slate-800 */
  --surface-3:     51 65 85;       /* slate-700 */
  --sidebar-bg:    26 35 50;       /* gris medio custom — entre slate-900 y slate-800 */
  --fg-primary:   241 245 249;     /* slate-100 */
  --fg-secondary: 203 213 225;     /* slate-300 */
  --fg-muted:     148 163 184;     /* slate-400 */
  --fg-subtle:    100 116 139;     /* slate-500 */
  --edge:          30 41 59;       /* slate-800 */
  --edge-strong:   51 65 85;       /* slate-700 */
  --kpi-surface:   11 17 32;       /* entre slate-950 y slate-900: ficha KPI más oscura
                                      que surface-1, pero sin fundirse con el fondo */
  --scrollbar-track: #0b1220;
  --scrollbar-thumb: #334155;
  --scrollbar-thumb-hover: #475569;
  --autofill-text: #e2e8f0;
  --autofill-bg:   #1e293b;
}

[data-theme="light"] {
  --bg-base:       248 250 252;    /* slate-50 */
  --surface-1:     255 255 255;    /* white */
  --surface-2:     241 245 249;    /* slate-100 */
  --surface-3:     226 232 240;    /* slate-200 */
  --sidebar-bg:    226 232 240;    /* slate-200 — gris más oscuro contra body slate-50 */
  --fg-primary:     15 23 42;      /* slate-900 — texto principal (sin cambio, ya máximo) */
  --fg-secondary:   30 41 59;      /* slate-800 — bumped desde 700 para más legibilidad */
  --fg-muted:       71 85 105;     /* slate-600 — bumped desde 500 */
  --fg-subtle:     100 116 139;    /* slate-500 — bumped desde 400 (WCAG AA OK) */
  --edge:          226 232 240;    /* slate-200 */
  --edge-strong:   203 213 225;    /* slate-300 */
  --kpi-surface:   255 255 255;    /* en claro la ficha va en blanco: el contraste lo da
                                      el riel de color, no el fondo */
  --scrollbar-track: #f1f5f9;
  --scrollbar-thumb: #cbd5e1;
  --scrollbar-thumb-hover: #94a3b8;
  --autofill-text: #0f172a;
  --autofill-bg:   #ffffff;
}

html, body {
  font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::-webkit-scrollbar         { width: 10px; height: 10px; }
::-webkit-scrollbar-track   { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb   { background: var(--scrollbar-thumb); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }

input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-text-fill-color: var(--autofill-text);
  -webkit-box-shadow: 0 0 0 1000px var(--autofill-bg) inset;
  caret-color: var(--autofill-text);
}

[x-cloak] { display: none !important; }

/* Dashboard cards — Opción A: gradiente por módulo + lift on hover + fade-in staggered. */
.dash-card {
  transition: transform 0.22s ease, box-shadow 0.3s ease, filter 0.2s ease, border-color 0.2s ease;
  animation: dash-card-in 0.45s cubic-bezier(0.34, 1.4, 0.64, 1) backwards;
}
.dash-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 14px 32px -14px var(--dash-shadow, rgba(0, 0, 0, 0.25));
  filter: brightness(1.06) saturate(1.05);
}
@keyframes dash-card-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .dash-card { animation: none; }
  .dash-card:hover { transform: none; }
}

/* Override de tipografía dentro de dash-cards: las cards son más compactas
   ahora (p-4 + icon 40px), por lo que reducimos el text-2xl que los widgets
   usan por default a text-xl. Los widgets siguen funcionando standalone fuera
   del dashboard sin perder tamaño. */
.dash-card .text-2xl { font-size: 1.25rem; line-height: 1.75rem; }

/* Mostrar/ocultar elementos según el tema actual.
   Uso: <img data-theme-show="dark"> aparece solo en dark; "light" solo en light. */
[data-theme="dark"]  [data-theme-show="light"] { display: none !important; }
[data-theme="light"] [data-theme-show="dark"]  { display: none !important; }

/* ─── Badges semánticos en light mode ────────────────────────────────────
   Las paletas Tailwind (emerald/rose/amber/sky/violet/indigo) en su shade
   300/400 se diseñaron para texto claro sobre fondo oscuro. En light mode
   quedan ilegibles. Override quirúrgico: oscurecemos los shades 300/400
   cuando data-theme="light" y subimos un poco la opacidad de los fondos
   tinted para mantener presencia. */
[data-theme="light"] .text-brand-400   { color: rgb(21 86 182) !important; } /* brand-800 — códigos de doc en light, más legibles que el azul claro */
[data-theme="light"] .text-brand-300   { color: rgb(23 74 144) !important; } /* brand-900 — usado en hover sobre brand-400 */
[data-theme="light"] .hover\:text-brand-400:hover { color: rgb(21 86 182) !important; }
[data-theme="light"] .hover\:text-brand-300:hover { color: rgb(23 74 144) !important; }
[data-theme="light"] .text-emerald-300 { color: rgb(4 120 87)  !important; } /* emerald-700 */
[data-theme="light"] .text-emerald-400 { color: rgb(5 150 105) !important; } /* emerald-600 */
[data-theme="light"] .text-rose-300    { color: rgb(159 18 57) !important; } /* rose-700 */
[data-theme="light"] .text-rose-400    { color: rgb(190 18 60) !important; } /* rose-700 */
[data-theme="light"] .text-amber-300   { color: rgb(180 83 9)  !important; } /* amber-700 */
[data-theme="light"] .text-amber-400   { color: rgb(217 119 6) !important; } /* amber-600 */
[data-theme="light"] .text-sky-300     { color: rgb(3 105 161) !important; } /* sky-700 */
[data-theme="light"] .text-sky-400     { color: rgb(2 132 199) !important; } /* sky-600 */
[data-theme="light"] .text-violet-300  { color: rgb(91 33 182) !important; } /* violet-700 */
[data-theme="light"] .text-violet-400  { color: rgb(124 58 237) !important; } /* violet-600 */
[data-theme="light"] .text-indigo-300  { color: rgb(67 56 202) !important; } /* indigo-700 */
[data-theme="light"] .text-indigo-400  { color: rgb(79 70 229) !important; } /* indigo-600 */

/* Bumps de opacidad de los fondos tinted (de /10 → /20) para que el badge
   "se vea" sobre fondo claro sin perder el efecto pastel. */
[data-theme="light"] .bg-emerald-500\/10 { background-color: rgb(16 185 129 / 0.20) !important; }
[data-theme="light"] .bg-rose-500\/10    { background-color: rgb(244 63 94  / 0.20) !important; }
[data-theme="light"] .bg-amber-500\/10   { background-color: rgb(245 158 11 / 0.20) !important; }
[data-theme="light"] .bg-sky-500\/10     { background-color: rgb(14 165 233 / 0.20) !important; }
[data-theme="light"] .bg-violet-500\/10  { background-color: rgb(139 92 246 / 0.20) !important; }
[data-theme="light"] .bg-indigo-500\/10  { background-color: rgb(99 102 241 / 0.20) !important; }
[data-theme="light"] .bg-emerald-500\/15 { background-color: rgb(16 185 129 / 0.25) !important; }
[data-theme="light"] .bg-rose-500\/15    { background-color: rgb(244 63 94  / 0.25) !important; }
[data-theme="light"] .bg-amber-500\/15   { background-color: rgb(245 158 11 / 0.25) !important; }
[data-theme="light"] .bg-emerald-500\/20 { background-color: rgb(16 185 129 / 0.30) !important; }
[data-theme="light"] .bg-rose-500\/20    { background-color: rgb(244 63 94  / 0.30) !important; }
[data-theme="light"] .bg-amber-500\/20   { background-color: rgb(245 158 11 / 0.30) !important; }
[data-theme="light"] .bg-sky-500\/20     { background-color: rgb(14 165 233 / 0.30) !important; }
[data-theme="light"] .bg-violet-500\/20  { background-color: rgb(139 92 246 / 0.30) !important; }

/* Botones: CSS plano (no @apply — Tailwind se carga vía CDN runtime que no procesa directivas de build). */
.btn-primary,
.btn-secondary,
.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  cursor: pointer;
  border: 0;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}
.btn-primary {
  background-color: #1582f5; /* brand-600 */
  color: #fff;
  font-weight: 500;
}
.btn-primary:hover { background-color: #1269e0; /* brand-700 */ }

.btn-secondary {
  background-color: rgb(var(--surface-2));
  color: rgb(var(--fg-primary));
}
.btn-secondary:hover { background-color: rgb(var(--surface-3)); }

.btn-danger {
  background-color: #e11d48; /* rose-600 */
  color: #fff;
}
.btn-danger:hover { background-color: #be123c; /* rose-700 */ }

.btn-primary:disabled,
.btn-secondary:disabled,
.btn-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── Componentes: campos de formulario y tarjetas ─────────────────────────
   Mismo criterio que los .btn-* de arriba: CSS plano, porque Tailwind entra por
   CDN en runtime y no procesa @apply.

   Motivo: la cadena de clases del input estaba repetida 331 veces y la de la
   tarjeta 165, en 64 variantes distintas que ya habían divergido entre sí.
   Cambiar el estilo de los campos era una edición en 331 lugares.

   Estas clases codifican SOLO la base compartida (fondo, borde, radio, padding).
   Todo lo variable — w-full, font-mono, text-right, pl-10 para el icono de
   búsqueda, p-5/p-4 en las tarjetas — sigue siendo utilidad de Tailwind.

   Van envueltas en :where() a propósito. :where() aporta especificidad CERO, así
   que CUALQUIER utilidad de Tailwind (0,1,0) le gana siempre, sin depender del
   orden de fuente. Esto no es cosmético: 288 campos dependen de que `w-full`,
   `pl-10` (input con icono de búsqueda) o `py-1` pisen la base, y el CDN de
   Tailwind inyecta su <style> en runtime — su posición relativa a este archivo
   no es algo sobre lo que convenga apostar.

   Los estados sí llevan especificidad propia (:focus, :disabled) y por eso
   funcionan normalmente. */

:where(.input, .select, .textarea) {
  padding: 0.5rem 0.75rem;          /* px-3 py-2 */
  border-radius: 0.5rem;            /* rounded-lg */
  background-color: rgb(var(--surface-2));
  color: rgb(var(--fg-primary));
  border: 1px solid rgb(var(--edge-strong));
  outline: none;                    /* el foco de teclado lo pinta :focus-visible más abajo */
  transition: border-color 0.15s ease-in-out;
}

/* Afordancia para quien usa mouse: :focus-visible NO dispara al clickear, así
   que sin esto el campo clickeado no daría ninguna señal de estar activo.
   Reemplaza al `focus:border-brand-500` que traían ~90 de los usos. */
:where(.input, .select, .textarea):focus {
  border-color: #2ea1ff;            /* brand-500 */
}

:where(.input, .select, .textarea):disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

:where(.input, .textarea)::placeholder {
  color: rgb(var(--fg-subtle));
}

:where(.card) {
  background-color: rgb(var(--surface-1));
  border: 1px solid rgb(var(--edge));
  border-radius: 0.75rem;           /* rounded-xl */
}

/* ─── Contenedor de scroll para tablas ──────────────────────────────────────
   Las tablas de facturas / clientes / inventario tienen 8 columnas y en un
   teléfono simplemente desbordan el layout. Esto las hace desplazables en
   horizontal en vez de romper la página.

   OJO al aplicarla: overflow-x crea un contexto de scroll que RECORTA lo
   posicionado en absoluto dentro. No usar en tablas que contengan dropdowns,
   comboboxes o menús de acción (ej. el editor de líneas de factura) — ahí el
   arreglo correcto es la vista de tarjetas en móvil, no el scroll. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;   /* no encadenar el scroll al body al llegar al borde */
}

/* En impresión el scroll no existe: que la tabla fluya completa. */
@media print {
  .table-wrap { overflow-x: visible !important; }
}

/* ─── Foco visible global (accesibilidad / navegación por teclado) ──────────
   Los módulos usan `outline-none` en ~211 líneas para matar el outline feo del
   browser, pero en la mayoría no lo reemplazan por nada: el operador que tabula
   entre 15 campos de una factura no ve dónde está parado.

   Esta regla lo resuelve de forma central, sin tocar los módulos. Usa
   :focus-visible (no :focus) para que el foco NO aparezca al hacer click con el
   mouse — solo al navegar por teclado, que es cuando hace falta.

   `!important` es deliberado: `.outline-none` de Tailwind tiene la misma
   especificidad (0,1,0) y el CDN inyecta su <style> en runtime, así que el
   orden de fuente no es confiable. Mismo criterio que los overrides de badges
   en light mode más arriba. */
:root,
[data-theme="dark"]  { --focus-ring: #59beff; }  /* brand-400 — contraste sobre superficies oscuras */
[data-theme="light"] { --focus-ring: #1269e0; }  /* brand-700 — contraste sobre superficies claras */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible,
[contenteditable]:focus-visible {
  outline: 2px solid var(--focus-ring) !important;
  outline-offset: 2px !important;
}

/* Inputs y selects: además del outline, un halo suave. Sin offset, porque un
   outline separado del borde en campos contiguos de un form se lee como ruido. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline-offset: 0 !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--focus-ring) 30%, transparent);
}

/* Los iconos de acción en tablas van dentro de <a>; sin esto el outline se
   dibuja pegado al glifo y casi no se ve. */
td a:focus-visible,
th a:focus-visible {
  outline-offset: 3px !important;
}

/* El outline no debe imprimirse nunca. */
@media print {
  *:focus-visible { outline: none !important; box-shadow: none !important; }
}

@media print {
  aside, header, footer, .no-print { display: none !important; }
  main { margin: 0 !important; padding: 0 !important; }
}

/* ─── DataTables (Tailwind plugin) override a tokens del proyecto ───────────
   dataTables.tailwindcss.css usa la variante `dark:` de Tailwind basada en
   prefers-color-scheme. Si el usuario tiene Windows en modo dark pero el
   theme del proyecto está forzado a light, los controles salen oscuros.
   Aquí mapeamos a `var(--surface-2)` etc. para respetar [data-theme].
   ============================================================================ */
div.dt-container { color: rgb(var(--fg-primary)); font-size: 0.875rem; }

div.dt-container .dt-search input,
div.dt-container .dt-length select,
div.dt-container input[type="search"],
div.dt-container select {
  background-color: rgb(var(--surface-2));
  color: rgb(var(--fg-primary));
  border: 1px solid rgb(var(--edge-strong));
  border-radius: 0.5rem;
  padding: 0.35rem 0.6rem;
  outline: none;
}
div.dt-container input:focus,
div.dt-container select:focus {
  border-color: #1582f5; /* brand-600 */
  box-shadow: 0 0 0 2px rgba(21, 130, 245, 0.25);
}

div.dt-container .dt-info,
div.dt-container .dt-length label,
div.dt-container .dt-search label {
  color: rgb(var(--fg-muted));
}

/* Tabla: header + striping basado en tokens (anula el bg-gray-* del plugin) */
div.dt-container table.dataTable thead th,
div.dt-container table.dataTable thead td {
  background-color: rgb(var(--surface-2) / 0.5);
  color: rgb(var(--fg-muted));
  border-bottom: 1px solid rgb(var(--edge-strong));
}
div.dt-container table.dataTable tbody tr {
  background-color: transparent !important;
}
div.dt-container table.dataTable.stripe tbody tr.odd,
div.dt-container table.dataTable.display tbody tr.odd {
  background-color: rgb(var(--surface-2) / 0.35) !important;
}
div.dt-container table.dataTable tbody tr:hover,
div.dt-container table.dataTable.hover tbody tr:hover,
div.dt-container table.dataTable.display tbody tr:hover {
  background-color: rgb(var(--surface-2) / 0.6) !important;
}
div.dt-container table.dataTable tbody td {
  border-top: 1px solid rgb(var(--edge));
}

/* ── Sidebar: hover "premium" con el color de identidad de cada módulo ────────
   El color viene por la variable --mod-color (seteada en nav.php desde el
   module.json). Solo aplica a items NO activos (.is-active mantiene bg-brand).
   Funciona en dark/light y en el modo colapsado (riel de iconos). */
#hubcore-nav .nav-item {
  position: relative;
  transition: background-color .18s ease, color .18s ease;
}
/* Barra de acento a la izquierda (crece en vertical al hacer hover) */
#hubcore-nav .nav-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  height: 62%;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--mod-color, #94a3b8);
  transform: translateY(-50%) scaleY(0);
  transform-origin: center;
  transition: transform .18s ease;
  pointer-events: none;
}
/* Tinte de fondo con el propio color del módulo (14%) + texto pleno */
#hubcore-nav .nav-item:not(.is-active):hover {
  background: color-mix(in srgb, var(--mod-color, #94a3b8) 14%, transparent);
  color: rgb(var(--fg-primary));
}
#hubcore-nav .nav-item:not(.is-active):hover::before {
  transform: translateY(-50%) scaleY(1);
}
/* El icono del módulo se aviva un poco en hover */
#hubcore-nav .nav-item:not(.is-active):hover i {
  filter: brightness(1.15) saturate(1.12);
}
/* Fallback si el navegador no soporta color-mix() */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
  #hubcore-nav .nav-item:not(.is-active):hover {
    background: rgb(var(--surface-3) / 0.7);
  }
}
/* Respetar preferencia de menos movimiento */
@media (prefers-reduced-motion: reduce) {
  #hubcore-nav .nav-item,
  #hubcore-nav .nav-item::before,
  #hubcore-nav .nav-item i { transition: none; }
  #hubcore-nav .nav-item:not(.is-active):hover::before { transform: translateY(-50%) scaleY(1); }
}

/* ─── Módulo Reportes: fichas KPI y mosaicos del catálogo ─────────────────
   Todo esto vive en app.css y NO en clases de Tailwind a propósito: app.css
   se carga aparte y no pasa por el build (ver build-css.md), así que agregar
   un matiz nuevo no obliga a recompilar tailwind.build.css. Con utilidades
   sueltas (bg-emerald-800 y compañía) el color no existiría hasta el próximo
   build y el mosaico saldría gris sin avisar.
   ────────────────────────────────────────────────────────────────────── */

/* Fichas KPI — composición vertical: ícono y etiqueta arriba, valor abajo a
   ancho completo. Apilar le devuelve ~55px de ancho útil al número, que es lo
   que se recortaba en monitores de 1366px. El color identifica la métrica
   desde el riel; el valor va neutro, que contrasta mejor sobre fondo oscuro. */
.kpi-card {
  background: rgb(var(--kpi-surface));
  border: 1px solid rgb(var(--edge));
  border-top: 3px solid var(--kpi-hue);
  border-radius: 10px;
  padding: 12px 14px 13px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  min-width: 0;
}
.kpi-crown { display: flex; align-items: center; gap: 7px; min-width: 0; }
.kpi-crown > i {
  font-size: 13px; width: 14px; flex-shrink: 0; text-align: center;
  color: var(--kpi-hue-lo);
}
.kpi-label {
  font-size: 10px; font-weight: 500; text-transform: uppercase;
  letter-spacing: 0.075em; line-height: 1.35;
  color: rgb(var(--fg-muted)); min-width: 0;
}
.kpi-value {
  font-size: 20px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.15;
  color: rgb(var(--fg-primary));
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

/* `brand` acá es el azul de Hub Core (#2ea1ff), no el oro de Enterprise. */
.kpi-brand   { --kpi-hue: #2ea1ff; --kpi-hue-lo: #59beff; }
.kpi-emerald { --kpi-hue: #10b981; --kpi-hue-lo: #34d399; }
.kpi-amber   { --kpi-hue: #f59e0b; --kpi-hue-lo: #fbbf24; }
.kpi-sky     { --kpi-hue: #0ea5e9; --kpi-hue-lo: #38bdf8; }
.kpi-rose    { --kpi-hue: #f43f5e; --kpi-hue-lo: #fb7185; }
.kpi-violet  { --kpi-hue: #8b5cf6; --kpi-hue-lo: #a78bfa; }

[data-theme="light"] .kpi-brand   { --kpi-hue-lo: #1556b6; }
[data-theme="light"] .kpi-emerald { --kpi-hue-lo: #047857; }
[data-theme="light"] .kpi-amber   { --kpi-hue-lo: #b45309; }
[data-theme="light"] .kpi-sky     { --kpi-hue-lo: #0369a1; }
[data-theme="light"] .kpi-rose    { --kpi-hue-lo: #be123c; }
[data-theme="light"] .kpi-violet  { --kpi-hue-lo: #6d28d9; }

/* Mosaicos del catálogo — color pleno por familia temática: cuerpo en el
   matiz 800, franja del ícono en el 900. El anillo de hover se pinta
   sobreescribiendo --tw-ring-color, así el `ring-1 ring-transparent
   hover:ring-2` que ya trae el tile sigue funcionando sin tocarlo. */
.rt-body   { background: var(--rt-body); }
.rt-stripe { background: var(--rt-stripe); }
.rt:hover  { --tw-ring-color: var(--rt-ring); }

.rt-ventas     { --rt-body: #065f46; --rt-stripe: #064e3b; --rt-ring: #34d399; }
.rt-factura    { --rt-body: #92400e; --rt-stripe: #78350f; --rt-ring: #fbbf24; }
.rt-cobranza   { --rt-body: #9f1239; --rt-stripe: #881337; --rt-ring: #fb7185; }
.rt-inventario { --rt-body: #075985; --rt-stripe: #0c4a6e; --rt-ring: #38bdf8; }
.rt-personas   { --rt-body: #5b21b6; --rt-stripe: #4c1d95; --rt-ring: #a78bfa; }
.rt-sistema    { --rt-body: #115e59; --rt-stripe: #134e4a; --rt-ring: #2dd4bf; }
.rt-sql        { --rt-body: #3730a3; --rt-stripe: #312e81; --rt-ring: #818cf8; }
.rt-template   { --rt-body: #5b21b6; --rt-stripe: #4c1d95; --rt-ring: #a78bfa; }
.rt-off        { --rt-body: #1e293b; --rt-stripe: #0f172a; --rt-ring: transparent; }
