/**
 * Campus Latino Real — G10K4-MVP.1.1
 * PRESENTACIÓN DEL MÓDULO DE FACTURACIÓN
 *
 * POR QUÉ EXISTE ESTA HOJA
 * ------------------------
 * El módulo de facturación emitía 46 clases y 41 no tenían una sola
 * regla. La pantalla funcionaba y era ilegible: la bandeja pintaba cada
 * comprobante DOS veces —la tabla de escritorio y las tarjetas de
 * móvil a la vez— porque las clases que debían alternarlas no existían.
 *
 * POR QUÉ ACOTADA, Y NO GLOBAL
 * ----------------------------
 * Varias de esas clases tienen nombres genéricos que otros módulos ya
 * usan sin estilo: `.muted` en quince módulos, `.actions` en ocho,
 * `.tabs` en cinco, `.toolbar` en tres, `.panel` y `.filters` en dos.
 * Definirlas globalmente cambiaría de golpe la apariencia de media
 * aplicación, y eso no es lo que este encargo autoriza.
 *
 * Por eso TODO aquí cuelga de `.billing-scope`, que el módulo pone en
 * su raíz y en el cuerpo de sus modales. Fuera de facturación, nada
 * cambia. El día que el Colegio quiera unificar ese vocabulario, será
 * una decisión consciente y no un efecto secundario.
 *
 * LO QUE NO ESTÁ AQUÍ
 * -------------------
 * Los botones. El módulo pasó a usar `.btn`, `.btn--primary` y
 * `.btn--ghost`, que son los componentes probados de Campus, con sus
 * estados de hover, foco y deshabilitado ya resueltos. Reutilizarlos es
 * mejor que redefinirlos.
 *
 * Sin framework, sin dependencias: sólo los tokens que ya existen.
 */

/* =====================================================================
   1 · PRIMITIVAS DEL MÓDULO
   ===================================================================== */

.billing-scope .muted {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.billing-scope .stack--tight { gap: var(--space-xs); }

.billing-scope .numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.billing-scope .panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}

.billing-scope .toolbar,
.billing-scope .actions,
.billing-scope .form-actions,
.billing-scope .filters__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
}

.billing-scope .form-actions { margin-top: var(--space-sm); }

/* =====================================================================
   2 · INDICADORES
   ===================================================================== */

.billing-scope .kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-sm);
}

.billing-scope .kpi-grid > * {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
}

.billing-scope .kpi__value {
  display: block;
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-semibold);
  line-height: 1.1;
  color: var(--color-text);
}

.billing-scope .kpi__label {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* =====================================================================
   3 · FILTROS Y PESTAÑAS
   ===================================================================== */

.billing-scope .filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-sm);
  align-items: end;
}

.billing-scope .filters__actions { grid-column: 1 / -1; }

.billing-scope .tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-md);
}

/* =====================================================================
   4 · LA BANDEJA · TABLA Y TARJETAS, NUNCA LAS DOS
   =====================================================================
   Éste es el defecto que cerró G10K4-MVP.1.1. El punto de ruptura es
   720 px, el mismo que ya usa `responsive.css`: no se inventa uno
   nuevo.
   ===================================================================== */

.billing-scope .table-wrapper {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.billing-scope .table-wrapper table {
  width: 100%;
  border-collapse: collapse;
}

.billing-scope .table-wrapper th,
.billing-scope .table-wrapper td {
  padding: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

.billing-scope .table-wrapper th {
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
  white-space: nowrap;
}

.billing-scope .cell-main {
  display: block;
  font-weight: var(--font-weight-medium);
  color: var(--color-text);
}

.billing-scope .cell-sub {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* Las tarjetas son la representación de móvil. */
.billing-scope .card-list {
  display: grid;
  gap: var(--space-sm);
}

.billing-scope .record-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  display: grid;
  gap: var(--space-xs);
}

.billing-scope .record-card__header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: baseline;
  justify-content: space-between;
}

.billing-scope .record-card__title {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.billing-scope .record-card__sub {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

.billing-scope .record-card__amount {
  font-weight: var(--font-weight-semibold);
  font-variant-numeric: tabular-nums;
}

.billing-scope .record-card__grid {
  display: grid;
  grid-template-columns: minmax(7rem, auto) 1fr;
  gap: 0.15rem var(--space-sm);
  font-size: var(--font-size-sm);
}

/* --- EL INTERRUPTOR. Una sola representación a la vez. --- */
.billing-scope .card-list--mobile { display: none; }
.billing-scope .table-wrapper--desktop { display: block; }

@media (max-width: 720px) {
  .billing-scope .table-wrapper--desktop { display: none; }
  .billing-scope .card-list--mobile { display: grid; }
}

/* =====================================================================
   5 · EL DETALLE
   =====================================================================
   `detail-grid` tiene que aguantar un folio fiscal de 36 caracteres sin
   desbordar el documento. A partir de 720 px es de dos columnas; por
   debajo, el valor cae bajo su etiqueta y puede partirse.
   ===================================================================== */

.billing-scope .detail-section { margin-bottom: var(--space-md); }

.billing-scope .detail-section > h3,
.billing-scope .detail-section > h4 {
  margin: 0 0 var(--space-xs);
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
}

.billing-scope .detail-grid {
  display: grid;
  grid-template-columns: minmax(8rem, 14rem) 1fr;
  gap: 0.2rem var(--space-md);
  align-items: baseline;
}

.billing-scope .detail-grid > dt {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.billing-scope .detail-grid > dd {
  margin: 0;
  min-width: 0;
  /* Un UUID no lleva espacios: sin esto empuja el ancho del documento. */
  overflow-wrap: anywhere;
  word-break: break-word;
}

@media (max-width: 720px) {
  .billing-scope .detail-grid { grid-template-columns: 1fr; }
  .billing-scope .detail-grid > dd { margin-bottom: var(--space-xs); }
}

/* =====================================================================
   5 bis · LAS TRES DESCARGAS · G10K4-MVP.2C.1
   =====================================================================
   Tres botones, y el más largo —«Descargar PDF Colegio Latino»— no cabe
   junto a otro en 375 px. El flex-wrap que ya tienen los dejaría en dos
   filas desiguales, con uno suelto y más estrecho que los demás.

   Por debajo de 720 px se apilan a ancho completo: tres objetivos del
   mismo tamaño, que es lo que se pulsa bien con el pulgar. En escritorio
   siguen en fila, como el resto de `form-actions` del módulo.
   ===================================================================== */

@media (max-width: 720px) {
  .billing-scope [data-billing-downloads] {
    flex-direction: column;
    align-items: stretch;
  }
  .billing-scope [data-billing-downloads] .btn { width: 100%; }
}

/* =====================================================================
   6 · TRAZABILIDAD
   ===================================================================== */

.billing-scope .timeline {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--space-md);
  border-left: 2px solid var(--color-border);
  display: grid;
  gap: var(--space-sm);
}

.billing-scope .timeline > li { position: relative; }

.billing-scope .timeline > li::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-md) - 5px);
  top: 0.45em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-border);
}

.billing-scope .timeline__when {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

.billing-scope .timeline__what {
  display: block;
  font-weight: var(--font-weight-medium);
}

.billing-scope .timeline__who {
  display: block;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* =====================================================================
   7 · AVISOS Y LISTAS DE COMPROBACIÓN
   ===================================================================== */

.billing-scope .callout {
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-surface);
}

.billing-scope .callout > p { margin: 0; }
.billing-scope .callout > p + p { margin-top: var(--space-xs); }

.billing-scope .callout--warning {
  border-left-color: var(--color-warning);
  background: var(--color-warning-bg);
}

.billing-scope .callout--danger {
  border-left-color: var(--color-danger);
  background: var(--color-danger-bg);
}

.billing-scope .checklist {
  margin: 0;
  padding-left: var(--space-md);
  display: grid;
  gap: 0.2rem;
  font-size: var(--font-size-sm);
}

/* =====================================================================
   8 · CARGA Y PAGINACIÓN
   ===================================================================== */

.billing-scope .skeleton-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-sm);
}

.billing-scope .skeleton--card {
  height: 4.5rem;
  border-radius: var(--radius-md);
}

.billing-scope .pagination__status {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  font-variant-numeric: tabular-nums;
}

/* =====================================================================
   9 · NADA DESBORDA EL DOCUMENTO
   ===================================================================== */

.billing-scope table { max-width: 100%; }
.billing-scope img, .billing-scope pre { max-width: 100%; }

/* =====================================================================
   10 · G10K4-MVP.2D.1 · EL ASISTENTE
   ===================================================================== */

/* El buscador del Paso 1. En escritorio el campo y los botones van en
   línea; por debajo de 720 px se apilan a ancho completo, igual que ya
   hacen los tres botones de la ficha desde MVP.2C.1. */
.billing-scope .billing-wizard-search {
  display: grid;
  gap: var(--space-xs);
}

@media (min-width: 720px) {
  .billing-scope .billing-wizard-search {
    grid-template-columns: 1fr auto;
    align-items: end;
  }
}

/* La paginación del asistente usa la misma caja que la de la bandeja:
   una sola regla, y no dos que algún día se separen. */
.billing-scope [data-billing-wizard-pagination] {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  justify-content: space-between;
}

/* El formulario del importe fiscal. Va dentro de su sección y no se
   escapa del ámbito de facturación. */
.billing-scope .billing-fiscal-form {
  display: grid;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

@media (min-width: 720px) {
  .billing-scope .billing-fiscal-form {
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    align-items: end;
  }
  .billing-scope .billing-fiscal-form > p,
  .billing-scope .billing-fiscal-form > .toolbar {
    grid-column: 1 / -1;
  }
}

/* A 375 px nada se sale: el importe es tabular y los campos no pasan
   del ancho de su caja. */
.billing-scope [data-billing-fiscal-input] {
  font-variant-numeric: tabular-nums;
}

.billing-scope [data-billing-fiscal-form] input,
.billing-scope .billing-wizard-search input {
  max-width: 100%;
}

/* =====================================================================
   G10K4-MVP.2E.3 · FACTURA MANUAL (M2)

   Seis clases, y las seis con regla: el guardián de
   test-g10k4mvp11-emission-ui-css exige que ninguna clase que el módulo
   pinta se quede sin CSS, y tiene razón —el incidente que lo motivó fue
   una bandeja que mostraba cada comprobante dos veces—.

   Todo lo demás se pinta con clases que ya existían: card, field,
   field-grid, radio-row, checkbox-row, toolbar, detail-section,
   detail-grid, table-wrapper, data-table, record-card, alert, callout,
   hint, numeric y el resto. No se inventó un sistema nuevo para una
   pantalla.
   ===================================================================== */

/* El selector de modalidad. Dos tarjetas de igual peso: ninguna de las
   dos vías es «la secundaria». En móvil se apilan. */
.billing-scope .billing-mode-grid {
  display: grid;
  gap: var(--space-sm);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .billing-scope .billing-mode-grid { grid-template-columns: 1fr 1fr; }
}

.billing-scope .billing-mode-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* El botón al fondo, para que las dos tarjetas lo alineen aunque sus
   textos midan distinto. */
.billing-scope .billing-mode-card .btn { margin-top: auto; }

.billing-scope .billing-mode-card__title {
  margin: 0;
  font-size: var(--font-size-md, 1rem);
  font-weight: 600;
}

/* Cada concepto, una tarjeta. Compacta a propósito: una factura con
   cuatro conceptos no puede obligar a bajar cuatro pantallas. */
.billing-scope .billing-manual-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.billing-scope .billing-manual-item + .billing-manual-item {
  margin-top: var(--space-sm);
}

/* Los impuestos de un concepto. En escritorio van en línea; en móvil,
   apilados, porque cuatro campos en una fila de 360px no se leen. */
.billing-scope .billing-manual-taxes {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-left: var(--space-sm);
  border-left: 2px solid var(--color-border, #e2e8f0);
}

.billing-scope .billing-manual-tax {
  display: grid;
  gap: var(--space-xs);
  grid-template-columns: 1fr;
  align-items: end;
}

@media (min-width: 720px) {
  .billing-scope .billing-manual-tax {
    grid-template-columns: repeat(2, minmax(0, 1fr)) auto auto;
  }
}

.billing-scope .billing-manual-tax + .billing-manual-tax {
  padding-top: var(--space-xs);
  border-top: 1px dashed var(--color-border, #e2e8f0);
}

/* =====================================================================
   9 · G10K4-MVP.2E.5.1 · EL ASISTENTE DE «NUEVA FACTURA»
   =====================================================================
   Las cuatro reglas de abajo existen porque se midió la causa de cada
   defecto en el navegador, no porque «se veía mal»:

   · UX-01 el buscador medía 220px de alto;
   · UX-03 la tabla de conceptos desbordaba SIEMPRE;
   · UX-03 el complemento educativo entraba a dos columnas en una celda;
   · §2/§3 el paso 1 era una columna infinita y las acciones quedaban
     al final de un cuerpo muy largo.

   Todo va bajo .billing-scope o .modal--xwide. Ni un selector alcanza
   otro módulo de Campus, y ni un color nuevo: todo sale de tokens.css.
   ===================================================================== */

/* --- UX-01 ----------------------------------------------------------
   El buscador de alumno es un CAMPO de formulario. Llevaba
   `class="search-input"`, que es la clase del CONTENEDOR del buscador
   de una barra de filtros y aporta `flex: 1 1 220px`; dentro de un
   .field, que es `display:flex; flex-direction:column`, ese flex-basis
   cae sobre el eje VERTICAL y el campo medía 220px de alto.

   Estas medidas son LAS MISMAS que `.field input[type="text"]` de
   components.css. No se reutiliza esa regla porque enumera tipos y no
   incluye `search` —carencia real del sistema, declarada en el informe
   y no corregida aquí para no restyling silencioso de Finanzas—. */
.billing-scope .billing-search-field {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 0.65rem 0.8rem;
  font-size: var(--font-size-base);
  background: var(--color-surface);
  min-height: 44px;
  width: 100%;
}

.billing-scope .billing-search-field:focus-visible { border-color: var(--color-blue); }

/* --- UX-03 ----------------------------------------------------------
   `.data-table` trae `min-width: 560px` (components.css:194) para el
   modo tabla de una página completa. Dentro del diálogo el cuerpo mide
   menos que eso en móvil, así que la tabla desbordaba aunque sólo
   hubiera un concepto. Mismo remedio que `.withdrawal-flow .data-table`
   y por la misma razón: el mínimo sobra cuando el ancho lo manda el
   diálogo. */
.modal--xwide .billing-scope .table-wrapper .data-table { min-width: 0; }

/* El complemento educativo venía como `detail-grid` —dos columnas,
   `minmax(8rem,14rem) 1fr`— DENTRO de una celda de una tabla de seis
   columnas. Dos columnas dentro de una celda estrecha es exactamente lo
   que cortaba la información de conceptos. Dentro de una celda va a una
   sola columna; fuera de la tabla sigue a dos. */
.modal--xwide .billing-scope .table-wrapper .detail-grid {
  grid-template-columns: 1fr;
  gap: 0;
}

/* Las columnas numéricas no deben partirse; la descripción sí. Así la
   tabla reparte el ancho donde hay texto largo y no donde hay cifras. */
.modal--xwide .billing-scope .table-wrapper .data-table td.numeric,
.modal--xwide .billing-scope .table-wrapper .data-table th.numeric {
  white-space: nowrap;
}

/* --- §2 · los cinco datos fiscales, en tarjeta --------------------- */
.billing-scope .billing-fiscal-card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-sm);
  background: var(--color-surface-muted, var(--color-surface));
}

.billing-scope .billing-fiscal-card__title {
  margin: 0 0 var(--space-xs);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-secondary);
  font-weight: var(--font-weight-semibold);
}

/* Cinco datos en una sola columna son cinco renglones; a dos columnas
   son tres. Sólo cuando hay sitio. */
@media (min-width: 720px) {
  .modal--xwide .billing-scope .billing-fiscal-card .detail-grid {
    grid-template-columns: minmax(7rem, auto) 1fr minmax(7rem, auto) 1fr;
  }
}

/* --- §3 · las acciones, visibles ----------------------------------- */
.billing-scope .toolbar--sticky {
  position: sticky;
  bottom: 0;
  z-index: 1;
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-sm);
  margin-top: var(--space-sm);
}

/* Participa en el flujo, así que NO tapa contenido: se queda pegada
   abajo mientras el cuerpo del diálogo se desplaza. El último bloque
   del cuerpo recupera el aire que la barra ocupa. */
.billing-scope .toolbar--sticky + .muted { padding-bottom: var(--space-xs); }

/* --- §2 · el paso 1 usa el ancho ----------------------------------
   Emisor es un campo; Receptor es un sub-formulario con buscador y
   lista. Por eso NO es 1fr 1fr: la columna de Emisor se queda en lo
   que necesita y Receptor se lleva el resto. Sólo a partir de 1024px,
   que es donde .modal--xwide ya tiene ancho de sobra. */
.billing-scope .billing-wizard-cols {
  display: grid;
  gap: 0 var(--space-lg);
  grid-template-columns: 1fr;
}

@media (min-width: 1024px) {
  .modal--xwide .billing-scope .billing-wizard-cols {
    grid-template-columns: minmax(15rem, 20rem) 1fr;
    align-items: start;
  }
}

/* --- UX-03 · los codigos de bloqueo tampoco desbordan ---------------
   Medido a 375px: «BILLING_MANUAL_PRODUCT_CODE_MISSING:1» no lleva ni
   un espacio, asi que no parte y empujaba el cuerpo del dialogo 4px
   fuera. Mismo remedio —y misma razon— que `.detail-grid > dd`, que ya
   lo hacia por los UUID fiscales: una cadena sin espacios no puede
   decidir el ancho de la pantalla. */
.billing-scope .callout { overflow-wrap: anywhere; }
