/* =============================================
  Fuente global
  ============================================= */

@font-face {
  font-family: 'RobotoCondensed';
  src: url('../fonts/RobotoCondensed-Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

*, *::before, *::after {
  font-family: 'RobotoCondensed', sans-serif !important;
}

/* =============================================
  Botones de opciones — cursor pointer
  ============================================= */

.btn-ghost-primary,
.btn-ghost-danger,
.btn-ghost-secondary {
  cursor: pointer;
}

/* =============================================
  Input group — borde completo al activarse
  ============================================= */

.input-group:focus-within {
  outline: none;
  box-shadow: 0 0 0 0.2rem rgba(1, 37, 120, 0.25);
  border-radius: var(--bs-border-radius, 0.375rem);
}

.input-group:focus-within .input-group-text,
.input-group:focus-within .form-control,
.input-group:focus-within .form-select {
  border-color: #012578;
  box-shadow: none;
}

i.bi.bi-pencil.fs-2 {
color: blue;
}

.text-primary {
  color: blue!important;
}

.text-success {
  color: green!important;
}

.text-danger {
  color: red!important;
}

.text-white {
  color: white!important;
}

.text-warning {
  color: orange!important;
}

.text-info {
  color: cyan!important;
}

.text-purple {
  color: darkorchid!important;
}


.btn-ghost-images {
color: darkorchid;
}

.btn-ghost-primary {
color: green;
}

.btn-ghost-cart {
color: orange;
}

i.bi.bi-trash.fs-2 {
color: red;
}

@media (min-width: 992px) {
  .app-header {
      height: 70px;
  }
}

/* =============================================
  vue-good-table — thead
  ============================================= */

.vgt-table thead th {
  background: #012578 !important;
  color: #fff !important;
  border-color: #011a56 !important;
}

.vgt-global-search {
  background: #012578 !important;
  color: #fff !important;
  border-color: #011a56 !important;
}

.vgt-global-search__input .input-group-addon,
.vgt-global-search .vgt-input-group-addon,
.vgt-global-search span[class*="icon"],
.vgt-global-search .magnifying-glass {
  color: #fff !important;
  fill: #fff !important;
}

.vgt-global-search__input .input__icon .magnifying-glass {
  border-color: #fff !important;
}

.vgt-global-search__input .input__icon .magnifying-glass:before {
  background: #fff !important;
}

.vgt-table thead th .vgt-sort-btn,
.vgt-table thead th button {
  color: #fff !important;
}

/* =============================================
  vue-good-table — filas striped
  ============================================= */

.vgt-table.striped tbody tr:nth-child(even) td {
  background-color: #f5f8ff !important;
}

.vgt-table.striped tbody tr:nth-child(odd) td {
  background-color: #ffffff !important;
}

.vgt-table.striped tbody tr:hover td {
  background-color: #e8eeff !important;
}

table.vgt-table {
  font-size: 13px !important;
}

/* =============================================
   vue-good-table — responsive en móvil
   Evita que el cuerpo se envuelva y el header quede
   desalineado/cortado; la tabla se desplaza horizontal
   como una sola unidad manteniendo el header intacto.
   ============================================= */
.vgt-responsive {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.vgt-table thead th {
  white-space: nowrap;
}

@media (max-width: 767.98px) {
  table.vgt-table {
    width: max-content;
    min-width: 100%;
    max-width: none;
  }

  table.vgt-table td {
    white-space: nowrap;
  }
}

/* =============================================
   Menú de opciones de las tablas: no recortarlo ni taparlo
   ============================================= */
/* En escritorio el contenedor no recorta, así el dropdown de opciones
   se ve completo (en móvil se mantiene el scroll horizontal). */
@media (min-width: 768px) {
  .vgt-wrap .vgt-responsive {
    overflow: visible;
  }
}

/* El menú de opciones siempre por encima del footer, header, etc. */
.vgt-wrap .dropdown-menu {
  z-index: 1035;
}

/* Espacio entre la última fila y el footer de la tabla. */
.vgt-wrap__footer {
  margin-top: .5rem;
}

/* =============================================
   Dashboard (inicio): fondo gris con tarjetas blancas
   ============================================= */
body.dashboard-page .app-content {
  background-color: #dbdfe9 !important;
}

/* Nombre como enlace en las tablas → abre la edición */
a.vgt-link {
  color: #012578 !important;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}

a.vgt-link:hover {
  text-decoration: underline;
}

/* =============================================
   Buscador de tablas — mismo estilo en todo el sistema
   (input redondo con lupa y botón de limpiar).
   En móvil ocupa el ancho con un pequeño margen lateral.
   ============================================= */
.vgt-search-wrap {
  position: relative;
  width: 300px;
  max-width: 100%;
  margin: .75rem;
}

.vgt-search-wrap .vgt-search-icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #9ca3af;
  pointer-events: none;
}

.vgt-search-wrap .vgt-search-input {
  padding-left: 36px;
  padding-right: 36px;
  border-color: #062578;
}

.vgt-search-wrap .vgt-search-input:focus {
  border-color: #062578;
  box-shadow: 0 0 0 0.2rem rgba(6, 37, 120, .15);
}

.vgt-search-wrap .vgt-search-clear {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: transparent;
  color: #6c757d;
  line-height: 1;
  padding: 4px;
  cursor: pointer;
}

.vgt-search-wrap .vgt-search-clear:hover {
  color: #012578;
}

@media (max-width: 767.98px) {
  .vgt-search-wrap {
    width: auto;
    max-width: none;
  }
}

.card .card-header .card-title, .card .card-header .card-title .card-label {
  font-weight: 900;
}

/* =============================================
   Modal header — estilo btn-primary
   ============================================= */

.modal-header {
  background-color: var(--bs-background) !important;
  border-bottom-color: #011a56 !important;
  --bs-modal-header-padding: 1.25rem 1.25rem !important;
  border-top-left-radius: inherit !important;
  border-top-right-radius: inherit !important;
}

.modal-header .modal-title {
  color: #fff !important;
  font-size: 1.35rem !important;
  font-weight: 600!important;
}

.modal-header .btn-close {
  filter: invert(1) grayscale(100%) brightness(200%) !important;
}

/* =============================================
   form-label-group — floating labels
   ============================================= */

.form-label-group {
  position: relative;
  margin-bottom: 0;
}

.form-label-group > .form-control,
.form-label-group > .form-select {
  height: calc(3.5rem + 2px);
  padding: 1.125rem 0.75rem 0.25rem;
  line-height: 1.25;
}

.form-label-group > textarea.form-control {
  height: auto;
  padding-top: 1.75rem;
  padding-bottom: 0.5rem;
}

.form-label-group > .form-control-sm,
.form-label-group > .form-select-sm {
  height: calc(2.75rem + 2px);
  padding: 0.875rem 0.6rem 0.2rem;
  font-size: 0.875rem;
}

.form-label-group > label {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  padding: 1rem 0.75rem;
  pointer-events: none;
  border: 1px solid transparent;
  transform-origin: 0 0;
  transition: opacity .1s ease-in-out, transform .1s ease-in-out;
  color: #8899aa;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  font-size: 1rem;
}

/* Label flota: input con valor, con foco, o select/number/date */
.form-label-group > .form-control:focus ~ label,
.form-label-group > .form-control:not(:placeholder-shown) ~ label,
.form-label-group > .form-select ~ label,
.form-label-group > input[type="number"] ~ label,
.form-label-group > input[type="date"] ~ label,
.form-label-group > input[type="password"] ~ label,
.form-label-group > textarea.form-control:focus ~ label,
.form-label-group > textarea.form-control:not(:placeholder-shown) ~ label {
  transform: scale(0.78) translateY(-0.6rem) translateX(0.1rem);
  color: #012578;
  opacity: 0.9;
}

/* Autofill */
.form-label-group > .form-control:-webkit-autofill ~ label {
  transform: scale(0.78) translateY(-0.6rem) translateX(0.1rem);
  color: #012578;
  opacity: 0.9;
}

/* Asterisco en campos requeridos */
.form-label-group label.required::after {
  content: " *";
  color: #dc3545;
}

hr.dropdown-divider {
  border-top: 1px solid var(--bs-background) !important;
} 

@media (min-width: 992px) {
  .app-header-menu .menu>.menu-item>.menu-link {
    padding: 0;
    margin-right: 1rem;
  }
}


table {
  border-collapse: collapse !important;
}

table,
tbody, tfoot, th, thead{
  border-color: var(--bs-background) !important;
  border-style: solid !important;
  border-width: 1px !important;
}

.btn-close {
  border: 1px solid !important;
}

.modal {
  border: 1px solid var(--bs-background) !important;
  --bs-modal-border-color: var(--bs-background);
  --bs-modal-border-width: 1px;
}

.bi-xs { font-size: 1rem!important; }
.bi-sm { font-size: 1.5rem!important; }
.bi-md { font-size: 2rem!important; }
.bi-lg { font-size: 3rem!important; }
.bi-xl { font-size: 4rem!important; }

.dropdown-menu.show {
  border: 1px solid black !important;
}

.table:not(.table-bordered) td, .table:not(.table-bordered) th, .table:not(.table-bordered) tr {
  border-width: 0px!important;
}

.table-hover>tbody>tr:hover>* {
  --bs-table-bg-state: inherit!important;
}

.menu-item .menu-link .menu-title, .subheader {
  font-weight: 600 !important;
  font-size: 1.25rem !important;
}

.btn {
  font-weight: 600 !important;
}

.engage-btn {
  height: inherit !important;
}

.btn-check:active+.engage-btn, 
.btn-check:checked+.engage-btn, 
.engage-btn.active, .engage-btn.show, 
.engage-btn:active:not(.btn-active), 
.engage-btn:focus:not(.btn-active), 
.engage-btn:hover:not(.btn-active), 
.show>.engage-btn {
 background-color: #000 !important;
  color: white !important;
}

.engage-toolbar {
  right: 0px !important;
}

.engage-btn {
  border-radius: 12px 0px 0px 12px !important;
}

.engage-toggle {
  border-radius: 12px 0px 0px 12px !important;
}

.engage-toggle:hover {
  background-color: #000 !important;
  color: white !important;
}

.engage-toggle i:hover {
  color: black !important;
}

.engage-toggle i:hover {
  color: white !important;
}

.table:not(.table-bordered) td:first-child, .table:not(.table-bordered) th:first-child, .table:not(.table-bordered) tr:first-child {
  padding-left: 10px;
  font-weight: 600;
}
/* =============================================
   Modales — cuerpo desplazable y footer siempre visible
   =============================================
   Casi todos los modales del sistema envuelven header + body + footer
   dentro de un <form>. Bootstrap espera que esos tres sean hijos
   directos de .modal-content (que es flex column): al meter el <form>
   en medio, el form se comporta como un bloque normal, no se encoge,
   el .modal-body nunca recibe una altura limitada —así que no aparece
   su scroll— y el footer con Guardar/Cancelar queda fuera del recorte
   de .modal-content. En escritorio no se nota porque el formulario
   cabe; en móvil el modal se corta y no hay forma de guardar.

   La solución es que el <form> se comporte igual que el .modal-content
   que lo contiene: columna flex que se encoge. */
.modal-dialog-scrollable .modal-content > form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
  overflow: hidden;
}

/* En móvil se aplica el mismo comportamiento a TODOS los modales,
   lleven o no la clase modal-dialog-scrollable: se limita la altura al
   alto visible y el contenido largo se desplaza dentro del cuerpo.
   Se usa max-height (no height) para que los modales cortos —el de
   confirmar borrado, por ejemplo— sigan ajustándose a su contenido. */
@media (max-width: 767.98px) {
  /* 100dvh y no 100% para descontar las barras de Safari/Chrome móvil,
     que si no tapan el footer del modal. */
  .modal {
    height: 100dvh;
  }

  .modal-dialog {
    max-height: calc(100% - var(--bs-modal-margin) * 2);
  }

  .modal-content {
    max-height: 100%;
    overflow: hidden;
  }

  .modal-content > form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    max-height: 100%;
    overflow: hidden;
  }

  .modal-body {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* =============================================
   Encabezado fijo en las tablas
   =============================================
   El contenedor de contenido del tema venía con overflow:hidden, y eso lo
   convertía en el "scrollport" de referencia de position:sticky en lugar de la
   ventana. Con eso el encabezado nunca llegaba a fijarse al hacer scroll de la
   página y, peor, si el offset superior superaba la distancia hasta la tabla se
   desplazaba hacia abajo dejando un hueco arriba y montándose sobre las
   primeras filas. `clip` recorta exactamente igual que `hidden` pero no crea un
   contenedor de scroll, así que el sticky vuelve a resolverse contra la
   ventana. Los navegadores que no soporten `clip` se quedan en `hidden`, que es
   el comportamiento que ya había. */
#kt_app_content {
  overflow: clip;
}

/* El encabezado se pega justo debajo de la barra superior de la app.
   --app-header-h la publica y mantiene al día AdminLayout.vue. */
.vgt-table thead th,
.fs-table thead th {
  position: sticky;
  top: var(--table-sticky-top, var(--app-header-h, 70px));
  z-index: 3;
}

/* CONVENCIÓN: toda tabla que viva dentro de su propio contenedor desplazable
   (uno con overflow:auto y alto acotado) tiene que declarar
   --table-sticky-top: 0px EN LA MISMA REGLA que crea ese scroll. Ahí el
   scrollport ya no es la ventana sino ese contenedor, así que el offset de la
   barra superior no aplica: dejarlo empujaría el encabezado hacia abajo,
   tapando las primeras filas. Hoy lo declaran así Journal, Ledger,
   TrialBalance, ExchangeRate e Inventario. Si añades otro contenedor con
   scroll, decláralo junto a su overflow.
   Los modales se cubren aquí porque el scroll lo crea .modal-body, no una regla
   propia de cada pantalla. */
.modal {
  --table-sticky-top: 0px;
}

/* En móvil .vgt-responsive desplaza en horizontal, así que el scrollport es él
   y no la ventana: un offset superior solo serviría para tapar filas. */
@media (max-width: 767.98px) {
  .vgt-table thead th,
  .fs-table thead th {
    position: static;
  }
}

/* =============================================
   Barra de pestañas — oculta en móvil
   =============================================
   En pantallas chicas las pestañas de la sección (Productos, Categorías,
   Almacenes…) se reparten en varias líneas y se comen buena parte de la
   pantalla. Se ocultan por debajo de `lg`, que es justo donde aparece el botón
   del menú lateral: ese drawer ya ofrece todas y cada una de las pestañas de
   todas las secciones, así que no se pierde acceso a nada.

   La barra aportaba además el mt-n15 que sube el contenido sobre la franja
   superior; al ocultarla ese margen pasa al contenedor para que no quede un
   hueco vacío debajo del hero. */
@media (max-width: 991.98px) {
  .app-content-menu {
    display: none !important;
  }

  .div-mobile-dashboard-padding {
    margin-top: 30px !important;
  }

  #kt_app_toolbar {
    margin-top: -3.75rem;
  }

  /* Aire arriba de la tarjeta: sin la barra de pestañas, su primera fila (los
     botones de acción) quedaba pegada al borde superior.
     Se limita a las pantallas de listado, que son las que tienen el problema:
     su card-body va con p-0 y por eso el contenido llega hasta el borde. Las
     tarjetas con relleno propio —las del panel de inicio, por ejemplo— ya tienen
     su espaciado y con esto se les duplicaba. */
  #kt_app_toolbar > .card:has(> .card-body.p-0) {
    padding-top: 30px;
  }
}

/* =============================================
   Barra superior de los módulos
   =============================================
   Acciones arriba alineadas a la derecha y el buscador debajo, ocupando el
   ancho disponible en móvil. Antes convivían tres variantes de utilidades para
   resolver esto (d-flex + justify-content-between, flex-column-reverse +
   flex-md-row, y una tercera con border-bottom), lo que daba un resultado
   distinto en cada módulo. */
.module-toolbar {
  display: flex;
  flex-direction: column-reverse; /* en el DOM el buscador va primero */
  align-items: stretch;
}

/* align-items:flex-end porque algunos módulos ponen aquí filtros con etiqueta
   (fechas, selects) junto a los botones, y deben apoyarse en la misma línea. */
.module-toolbar-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: flex-end;
  gap: .5rem;
  padding: .75rem .75rem 0;
}

/* ─────────────────────────────────────────────────────────────────────────────
   Carga de las tablas

   vue-good-table pinta su propio rótulo "Loading..." flotando sobre la tabla,
   en inglés y sin forma de traducirlo salvo pasándole un slot en cada una de
   las 25 tablas. Se oculta: el aviso de carga lo da TableEmptyState, en el
   cuerpo de la tabla y en español.

   Lo que sí se conserva es el atenuado de .is-loading (opacity + pointer-events
   de la librería), que es el único aviso cuando la tabla ya tiene filas y se
   está recargando.
   ──────────────────────────────────────────────────────────────────────────── */
.vgt-loading { display: none; }
