/* =============================================================================
   HEBB · Mockup 03 «ITINERARIO»
   Hoja 2 de 4 — Componentes de uso general.

   Regla transversal de esta hoja: ningún estado viaja solo en el color.
   Cada distintivo lleva icono o forma; cada fila en riesgo lleva además texto;
   cada error de formulario es persistente y está asociado por aria-describedby.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. SUPERFICIES
   Tarjetas con volumen: radio amplio, borde de 1 px y sombra teñida.
   -------------------------------------------------------------------------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-1);
}
.panel--alto { box-shadow: var(--sombra-2); }
.panel__cab {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-4) var(--e-5);
  border-bottom: 1px solid var(--borde);
}
.panel__cab h2, .panel__cab h3 { font-size: var(--txt-lg); }
.panel__cuerpo { padding: var(--e-5); }
.panel__cuerpo--ajustado { padding: var(--e-3); }
.panel__pie {
  padding: var(--e-3) var(--e-5);
  border-top: 1px solid var(--borde);
  background: var(--hundido);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  font-size: var(--txt-sm);
  color: var(--tinta-2);
}

/* Panel teñido: se usa para «lo que hay que hacer ahora». Es la única
   superficie con gradiente de marca, para que no compita consigo misma. */
.panel--foco {
  background:
    radial-gradient(120% 140% at 100% 0%, color-mix(in srgb, var(--primario) 16%, transparent), transparent 62%),
    var(--primario-sup);
  border-color: var(--primario-borde);
}

/* Arcos decorativos: forma geométrica de apoyo de la dirección de arte.
   Puramente ornamental, por eso aria-hidden en el marcado. */
.arco {
  position: absolute;
  border-radius: var(--r-full);
  border: 2px solid currentColor;
  opacity: .16;
  pointer-events: none;
}

/* -----------------------------------------------------------------------------
   2. BOTONES
   Altura mínima de 44 px en todos: se usan con el pulgar.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  min-height: var(--toque-min);
  padding: var(--e-3) var(--e-5);
  border-radius: var(--r-full);
  border: 1px solid transparent;
  background: transparent;
  color: var(--tinta);
  font-family: var(--fuente-cuerpo);
  font-size: var(--txt-sm);
  font-weight: var(--peso-fuerte);
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--mov-rapido) var(--curva),
              border-color var(--mov-rapido) var(--curva),
              transform var(--mov-rapido) var(--curva);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn svg { width: 18px; height: 18px; flex: none; }

.btn--primario { background: var(--primario); color: var(--tinta-inv); }
.btn--primario:hover { background: var(--primario-fuerte); }

/* Botón de acción principal del alumnado: es el «siguiente paso». Grande,
   ancho completo en móvil y con la mandarina de la marca. */
.btn--paso {
  background: var(--secundario);
  color: var(--tinta-fija);    /* 6,31:1 — verificado */
  font-size: var(--txt-base);
  min-height: 52px;
  padding-inline: var(--e-6);
  box-shadow: var(--sombra-2);
}
:root[data-tema="oscuro"] .btn--paso { color: var(--tinta-inv); }
.btn--paso:hover { filter: brightness(.94); }

.btn--contorno {
  border-color: var(--borde-fuerte);
  color: var(--tinta);
  background: var(--panel);
}
.btn--contorno:hover { background: var(--hundido); }

.btn--plano { color: var(--tinta-2); }
.btn--plano:hover { background: var(--hundido); color: var(--tinta); }

.btn--peligro { background: var(--riesgo); color: var(--blanco); }
:root[data-tema="oscuro"] .btn--peligro { color: var(--tinta-inv); }

.btn--sm { min-height: 36px; padding: var(--e-2) var(--e-4); font-size: var(--txt-xs); }
.btn--bloque { width: 100%; }
.btn--icono { padding: var(--e-2); min-width: var(--toque-min); }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}
/* Deshabilitado explicado: el motivo se enuncia junto al botón, nunca se
   deja al usuario adivinando. Ver .nota-bloqueo. */
.nota-bloqueo {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  font-size: var(--txt-xs);
  color: var(--tinta-2);
  margin-top: var(--e-2);
}
.nota-bloqueo svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--tinta-3); }

.grupo-btn { display: flex; flex-wrap: wrap; gap: var(--e-2); }

/* -----------------------------------------------------------------------------
   3. CAMPOS DE FORMULARIO
   Resuelve H-03 (etiquetas sin for), H-04 (errores efímeros) y H-39
   (obligatoriedad solo con asterisco).
   -------------------------------------------------------------------------- */
.campo { display: flex; flex-direction: column; gap: var(--e-2); margin-bottom: var(--e-4); }

.campo__eti {
  font-size: var(--txt-sm);
  font-weight: var(--peso-fuerte);
  color: var(--tinta);
}
/* La obligatoriedad se dice con palabra, no solo con asterisco. */
.campo__req {
  font-weight: var(--peso-normal);
  color: var(--tinta-3);
  font-size: var(--txt-xs);
}
.campo__ayuda { font-size: var(--txt-xs); color: var(--tinta-2); }

.entrada, .selector, .area {
  width: 100%;
  min-height: var(--toque-min);
  padding: var(--e-3) var(--e-4);
  background: var(--panel);
  color: var(--tinta);
  border: 1.5px solid var(--borde-fuerte);
  border-radius: var(--r-md);
  font-size: var(--txt-base);     /* 16 px: evita el zoom automático de iOS */
  transition: border-color var(--mov-rapido) var(--curva),
              box-shadow var(--mov-rapido) var(--curva);
}
.entrada::placeholder, .area::placeholder { color: var(--tinta-3); }
.entrada:hover, .selector:hover, .area:hover { border-color: var(--primario); }
.entrada:focus, .selector:focus, .area:focus {
  outline: none;
  border-color: var(--primario);
  box-shadow: var(--sombra-foco);
}
.area { min-height: 110px; resize: vertical; line-height: var(--interlinea-normal); }
.selector {
  appearance: none;
  padding-right: var(--e-10);
  /* Cheurón dibujado con gradientes: sin imagen externa ni fuente de iconos. */
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 21px) calc(50% + 2px), calc(100% - 15px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

/* Estado de error: borde grueso + franja lateral + icono + texto persistente.
   Cuatro señales, ninguna de ellas solo el color. */
.entrada[aria-invalid="true"],
.selector[aria-invalid="true"],
.area[aria-invalid="true"] {
  border-color: var(--riesgo);
  border-width: 2px;
  box-shadow: inset 4px 0 0 var(--riesgo);
}
.campo__error {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  font-size: var(--txt-sm);
  font-weight: var(--peso-medio);
  color: var(--riesgo);
}
.campo__error svg { width: 17px; height: 17px; flex: none; margin-top: 1px; }

.campo--ok .entrada { border-color: var(--exito-borde); }

/* Casillas y radios grandes, con etiqueta clicable completa. */
.opcion {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  padding: var(--e-3);
  min-height: var(--toque-min);
  border-radius: var(--r-md);
  cursor: pointer;
}
.opcion:hover { background: var(--hundido); }
.opcion input { width: 20px; height: 20px; margin: 2px 0 0; flex: none; accent-color: var(--primario); }
.opcion__txt { font-size: var(--txt-sm); }
.opcion__txt strong { display: block; font-weight: var(--peso-fuerte); color: var(--tinta); }
.opcion__txt span { color: var(--tinta-2); }

/* Opción tipo tarjeta, para respuestas de evaluación y elecciones importantes.
   Seleccionada = borde grueso + relleno + marca ✓, no solo tinte. */
.opcion-tarjeta {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  padding: var(--e-4);
  border: 2px solid var(--borde);
  border-radius: var(--r-md);
  background: var(--panel);
  cursor: pointer;
  transition: border-color var(--mov-rapido) var(--curva), background var(--mov-rapido) var(--curva);
}
.opcion-tarjeta:hover { border-color: var(--primario-borde); background: var(--hundido); }
.opcion-tarjeta input { width: 22px; height: 22px; margin: 0; flex: none; accent-color: var(--primario); }
.opcion-tarjeta:has(input:checked) {
  border-color: var(--primario);
  background: var(--primario-sup);
}
.opcion-tarjeta:has(input:focus-visible) { box-shadow: var(--sombra-foco); }

/* Interruptor. El estado se lee también por el texto «Activado/Desactivado». */
.interruptor { display: inline-flex; align-items: center; gap: var(--e-3); cursor: pointer; }
.interruptor input { position: absolute; opacity: 0; width: 0; height: 0; }
.interruptor__pista {
  width: 48px; height: 28px; flex: none;
  background: var(--borde-fuerte);
  border-radius: var(--r-full);
  position: relative;
  transition: background var(--mov-base) var(--curva);
}
.interruptor__pista::after {
  content: '';
  position: absolute;
  top: 3px; left: 3px;
  width: 22px; height: 22px;
  background: var(--perilla);
  border-radius: var(--r-full);
  box-shadow: var(--sombra-1);
  transition: transform var(--mov-base) var(--curva);
}
.interruptor input:checked + .interruptor__pista { background: var(--primario); }
.interruptor input:checked + .interruptor__pista::after { transform: translateX(20px); }
.interruptor input:focus-visible + .interruptor__pista { box-shadow: var(--sombra-foco); }

/* -----------------------------------------------------------------------------
   4. DISTINTIVOS
   Siempre texto; el icono o el punto son refuerzo. Nunca emoji (hallazgo H-20).
   -------------------------------------------------------------------------- */
.marca {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 3px var(--e-3);
  border-radius: var(--r-full);
  border: 1px solid var(--borde);
  background: var(--hundido);
  color: var(--tinta-2);
  font-size: var(--txt-xs);
  font-weight: var(--peso-fuerte);
  line-height: 1.5;
  white-space: nowrap;
}
.marca svg { width: 14px; height: 14px; flex: none; }
.marca--completado { background: var(--exito-sup); color: var(--exito); border-color: var(--exito-borde); }
.marca--curso     { background: var(--primario-sup); color: var(--primario); border-color: var(--primario-borde); }
.marca--rezagado  { background: var(--aviso-sup); color: var(--aviso); border-color: var(--aviso-borde); }
.marca--parado    { background: var(--riesgo-sup); color: var(--riesgo); border-color: var(--riesgo-borde); }
.marca--proximo   { background: var(--secundario-sup); color: var(--secundario-txt); border-color: var(--secundario-borde); }
.marca--solida    { background: var(--primario); color: var(--tinta-inv); border-color: transparent; }

.marca--rol-alumno    { background: var(--rol-alumno-sup); color: var(--rol-alumno); border-color: currentColor; }
.marca--rol-tutor     { background: var(--rol-tutor-sup); color: var(--rol-tutor); border-color: currentColor; }
.marca--rol-gestor    { background: var(--rol-gestor-sup); color: var(--rol-gestor); border-color: currentColor; }
.marca--rol-admin     { background: var(--rol-admin-sup); color: var(--rol-admin); border-color: currentColor; }
.marca--rol-inspector { background: var(--rol-inspector-sup); color: var(--rol-inspector); border-color: currentColor; }

/* -----------------------------------------------------------------------------
   5. AVISOS EN LÍNEA
   Sustituyen al toast de 4 segundos del campus actual (H-04, H-36).
   Persistentes, con encabezado, cuerpo y acción; role="alert" en el marcado.
   -------------------------------------------------------------------------- */
.aviso {
  display: flex;
  gap: var(--e-3);
  padding: var(--e-4);
  border-radius: var(--r-md);
  border: 1px solid var(--borde);
  border-left-width: 5px;      /* franja lateral: el estado también es forma */
  background: var(--hundido);
  font-size: var(--txt-sm);
  color: var(--tinta-2);
}
.aviso__icono { flex: none; width: 22px; height: 22px; margin-top: 1px; }
.aviso strong { display: block; color: var(--tinta); font-weight: var(--peso-fuerte); margin-bottom: 2px; }
.aviso--error   { background: var(--riesgo-sup);     border-color: var(--riesgo-borde);     border-left-color: var(--riesgo); }
.aviso--error strong, .aviso--error .aviso__icono { color: var(--riesgo); }
.aviso--ojo     { background: var(--aviso-sup);      border-color: var(--aviso-borde);      border-left-color: var(--aviso); }
.aviso--ojo strong, .aviso--ojo .aviso__icono { color: var(--aviso); }
.aviso--bien    { background: var(--exito-sup);      border-color: var(--exito-borde);      border-left-color: var(--exito); }
.aviso--bien strong, .aviso--bien .aviso__icono { color: var(--exito); }
.aviso--info    { background: var(--primario-sup);   border-color: var(--primario-borde);   border-left-color: var(--primario); }
.aviso--info strong, .aviso--info .aviso__icono { color: var(--primario); }

/* -----------------------------------------------------------------------------
   6. TABLAS
   Densas y operativas en escritorio; apiladas de verdad en móvil, no con
   scroll horizontal (H-13). El apilado conserva la semántica con role="…".
   -------------------------------------------------------------------------- */
.tabla-marco { border-radius: var(--r-lg); border: 1px solid var(--borde); overflow: hidden; background: var(--panel); }
.tabla-scroll { overflow-x: auto; position: relative; }

.tabla { width: 100%; border-collapse: collapse; font-size: var(--txt-sm); }
.tabla th, .tabla td { padding: var(--e-3) var(--e-4); text-align: left; vertical-align: middle; }
.tabla thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--hundido);
  color: var(--tinta-2);        /* 7,20:1 sobre hundido — no el primario (H-09) */
  font-size: var(--txt-xs);
  font-weight: var(--peso-negro);
  letter-spacing: .05em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--borde);
  white-space: nowrap;
}
.tabla tbody tr { border-bottom: 1px solid var(--borde); }
.tabla tbody tr:last-child { border-bottom: 0; }
.tabla tbody tr:hover { background: var(--hundido); }
.tabla td.num, .tabla th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* Ordenación por columna: botón real dentro del th, con aria-sort. */
.tabla__orden {
  display: inline-flex; align-items: center; gap: var(--e-1);
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit;
}
.tabla__orden svg { width: 13px; height: 13px; opacity: .5; }
[aria-sort="ascending"] .tabla__orden svg,
[aria-sort="descending"] .tabla__orden svg { opacity: 1; color: var(--primario); }
[aria-sort="descending"] .tabla__orden svg { transform: rotate(180deg); }

/* La primera celda es un enlace real: se puede abrir en pestaña nueva y es
   alcanzable por teclado. Corrige H-06 (filas clicables con click en el tr). */
.tabla__enlace { font-weight: var(--peso-fuerte); color: var(--tinta); text-decoration: none; }
.tabla__enlace:hover { color: var(--primario); text-decoration: underline; }

/* Fila en riesgo: franja izquierda + fondo tenue. El texto de la celda de
   estado dice el motivo, así que el color es refuerzo, no información. */
.tabla tr.fila--riesgo { background: var(--riesgo-sup); box-shadow: inset 4px 0 0 var(--riesgo); }
.tabla tr.fila--riesgo:hover { background: color-mix(in srgb, var(--riesgo-sup) 80%, var(--tinta) 4%); }
.tabla tr.fila--sel { background: var(--activo); }

.tabla__pie {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
  justify-content: space-between;
  padding: var(--e-3) var(--e-4);
  border-top: 1px solid var(--borde);
  background: var(--hundido);
  font-size: var(--txt-sm);
  color: var(--tinta-2);
}

/* --- Apilado móvil: cada fila se convierte en una ficha ------------------- */
@media (max-width: 899px) {
  .tabla--apila thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .tabla--apila tbody tr {
    display: block;
    padding: var(--e-4);
    margin: var(--e-3);
    border: 1px solid var(--borde);
    border-radius: var(--r-md);
    background: var(--panel);
    box-shadow: var(--sombra-1);
  }
  .tabla--apila tbody td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--e-4);
    padding: var(--e-2) 0;
    border: 0;
    text-align: right;
  }
  /* La cabecera de columna se repone como etiqueta de cada dato. */
  .tabla--apila tbody td::before {
    content: attr(data-eti);
    flex: none;
    font-size: var(--txt-xs);
    font-weight: var(--peso-negro);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--tinta-3);
    text-align: left;
  }
  .tabla--apila tbody td.celda-titulo {
    display: block;
    text-align: left;
    padding-bottom: var(--e-3);
    margin-bottom: var(--e-2);
    border-bottom: 1px solid var(--borde);
    font-size: var(--txt-base);
  }
  .tabla--apila tbody td.celda-titulo::before { display: none; }
  .tabla--apila tr.fila--riesgo { box-shadow: inset 5px 0 0 var(--riesgo), var(--sombra-1); }
}

/* -----------------------------------------------------------------------------
   7. PESTAÑAS
   Semántica ARIA completa (H-15) y desplazamiento horizontal en móvil.
   -------------------------------------------------------------------------- */
.pestanas {
  display: flex;
  gap: var(--e-1);
  padding: var(--e-1);
  background: var(--hundido);
  border-radius: var(--r-full);
  overflow-x: auto;
  scrollbar-width: none;
  /* Imprescindible: sin él, los textos .oculto-visual (que son absolutos) no
     quedan recortados por este contenedor y arrastran el scroll horizontal
     de la página. Mismo motivo en .tabla-scroll y en la barra del mockup. */
  position: relative;
}
.pestanas::-webkit-scrollbar { display: none; }
.pestana {
  flex: none;
  display: inline-flex; align-items: center; gap: var(--e-2);
  min-height: 40px;
  padding: var(--e-2) var(--e-4);
  border: 0; background: none;
  border-radius: var(--r-full);
  color: var(--tinta-2);
  font-size: var(--txt-sm); font-weight: var(--peso-medio);
  cursor: pointer;
  white-space: nowrap;
}
.pestana:hover { color: var(--tinta); }
.pestana[aria-selected="true"] {
  background: var(--panel);
  color: var(--primario);
  font-weight: var(--peso-negro);
  box-shadow: var(--sombra-1);
}
.pestana__contador {
  font-size: var(--txt-eti);
  background: var(--canal); color: var(--tinta-2);
  padding: 1px 7px; border-radius: var(--r-full);
  font-variant-numeric: tabular-nums;
}
.panel-pestana[hidden] { display: none; }

/* -----------------------------------------------------------------------------
   8. ESTADOS: vacío, carga y permiso denegado
   -------------------------------------------------------------------------- */
.vacio {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--e-3);
  padding: var(--e-10) var(--e-5);
  text-align: center;
}
.vacio__arte { width: 132px; height: 108px; margin-bottom: var(--e-2); }
.vacio h3 { font-size: var(--txt-lg); }
.vacio p { color: var(--tinta-2); font-size: var(--txt-sm); max-width: 44ch; }

/* Esqueleto de carga: usa tokens, por lo que no rompe en oscuro (H-19). */
.esq {
  background: linear-gradient(90deg, var(--hundido) 25%, var(--canal) 50%, var(--hundido) 75%);
  background-size: 200% 100%;
  animation: brillo 1.4s linear infinite;
  border-radius: var(--r-sm);
  color: transparent;
}
@keyframes brillo { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.esq--linea { height: 12px; margin-bottom: var(--e-2); }
.esq--titulo { height: 20px; width: 55%; margin-bottom: var(--e-3); }
.esq--bloque { height: 92px; }
@media (prefers-reduced-motion: reduce) { .esq { animation: none; background: var(--canal); } }

/* -----------------------------------------------------------------------------
   9. DIÁLOGOS
   Confirmación destructiva: el foco entra en «Cancelar» y el botón destructivo
   no es el más llamativo (H-12).
   -------------------------------------------------------------------------- */
.dialogo {
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  padding: 0;
  background: var(--panel);
  color: var(--tinta);
  box-shadow: var(--sombra-3);
  max-width: 480px;
  width: calc(100% - var(--e-8));
}
.dialogo::backdrop { background: var(--velo); }
.dialogo__cab { padding: var(--e-5) var(--e-5) var(--e-3); }
.dialogo__cuerpo { padding: 0 var(--e-5) var(--e-5); color: var(--tinta-2); font-size: var(--txt-sm); }
.dialogo__pie {
  display: flex; justify-content: flex-end; gap: var(--e-2);
  padding: var(--e-4) var(--e-5);
  border-top: 1px solid var(--borde);
  background: var(--hundido);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* -----------------------------------------------------------------------------
   10. AVATARES
   Iniciales sobre superficie teñida: sin imágenes remotas.
   -------------------------------------------------------------------------- */
.avatar {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  border-radius: var(--r-full);
  background: var(--primario-sup);
  color: var(--primario);
  font-family: var(--fuente-titular);
  font-weight: var(--peso-negro);
  font-size: var(--txt-sm);
  letter-spacing: 0;
}
.avatar--sm { width: 32px; height: 32px; font-size: var(--txt-xs); }
.avatar--lg { width: 64px; height: 64px; font-size: var(--txt-xl); }
.avatar--xl { width: 88px; height: 88px; font-size: var(--txt-2xl); }
.avatar--tutor { background: var(--secundario-sup); color: var(--secundario-txt); }
.avatar--exito { background: var(--exito-sup); color: var(--exito); }

/* -----------------------------------------------------------------------------
   11. REJILLAS DE CONTENIDO
   -------------------------------------------------------------------------- */
.rejilla { display: grid; gap: var(--e-4); }
.rejilla--2 { grid-template-columns: 1fr; }
.rejilla--3 { grid-template-columns: 1fr; }
.rejilla--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rejilla--auto { grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }

@media (min-width: 768px) {
  .rejilla--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rejilla--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rejilla--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1100px) {
  .rejilla--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rejilla--partida { grid-template-columns: minmax(0, 1fr) 340px; }
  .rejilla--partida-ancha { grid-template-columns: minmax(0, 1fr) 400px; }
}

/* -----------------------------------------------------------------------------
   12. CIFRAS DESTACADAS
   -------------------------------------------------------------------------- */
.kpi {
  display: flex; flex-direction: column; gap: var(--e-1);
  padding: var(--e-4) var(--e-5);
  background: var(--panel);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-1);
  position: relative;
  overflow: hidden;
}
.kpi__eti { font-size: var(--txt-xs); font-weight: var(--peso-fuerte); color: var(--tinta-2); }
.kpi__valor {
  font-family: var(--fuente-titular);
  font-size: var(--txt-2xl);
  font-weight: var(--peso-negro);
  letter-spacing: -.03em;
  line-height: 1;
}
.kpi__pie { font-size: var(--txt-xs); color: var(--tinta-3); display: flex; align-items: center; gap: var(--e-1); }
.kpi__pie svg { width: 14px; height: 14px; }
.kpi--riesgo .kpi__valor { color: var(--riesgo); }
.kpi--exito .kpi__valor { color: var(--exito); }
.kpi--aviso .kpi__valor { color: var(--aviso); }

/* -----------------------------------------------------------------------------
   13. CABECERA DE PÁGINA
   -------------------------------------------------------------------------- */
.pag-cab { margin-bottom: var(--e-6); }
.pag-cab h1 { font-size: var(--txt-3xl); font-weight: var(--peso-negro); letter-spacing: -.032em; }
.pag-cab__desc { color: var(--tinta-2); margin-top: var(--e-2); max-width: 62ch; }
.pag-cab__acciones { margin-top: var(--e-4); }
@media (min-width: 768px) {
  .pag-cab { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--e-6); }
  .pag-cab__acciones { margin-top: 0; }
}

/* Migas: la ruta importa cuando el producto es un recorrido. */
.migas { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2); font-size: var(--txt-xs); color: var(--tinta-3); margin-bottom: var(--e-3); }
.migas a { color: var(--tinta-2); text-decoration: none; }
.migas a:hover { color: var(--primario); text-decoration: underline; }
.migas svg { width: 13px; height: 13px; }

/* -----------------------------------------------------------------------------
   14. LISTAS DE DATOS
   -------------------------------------------------------------------------- */
.datos { display: grid; gap: var(--e-3); }
.dato { display: flex; justify-content: space-between; align-items: baseline; gap: var(--e-4); padding-bottom: var(--e-3); border-bottom: 1px solid var(--borde); }
.dato:last-child { border-bottom: 0; padding-bottom: 0; }
.dato__eti { font-size: var(--txt-sm); color: var(--tinta-2); }
.dato__valor { font-size: var(--txt-sm); font-weight: var(--peso-fuerte); text-align: right; }

/* -----------------------------------------------------------------------------
   15. BARRA DE FILTROS
   -------------------------------------------------------------------------- */
.filtros {
  display: flex; flex-wrap: wrap; gap: var(--e-3);
  padding: var(--e-4);
  background: var(--panel);
  border: 1px solid var(--borde);
  border-radius: var(--r-lg);
  margin-bottom: var(--e-4);
}
.filtros .campo { margin-bottom: 0; flex: 1 1 190px; }
.filtros__acciones { display: flex; gap: var(--e-2); align-items: flex-end; flex-wrap: wrap; }

/* Filtros aplicados como fichas retirables: el estado del filtrado es visible. */
.ficha-filtro {
  display: inline-flex; align-items: center; gap: var(--e-2);
  padding: var(--e-1) var(--e-2) var(--e-1) var(--e-3);
  background: var(--primario-sup);
  color: var(--primario);
  border: 1px solid var(--primario-borde);
  border-radius: var(--r-full);
  font-size: var(--txt-xs); font-weight: var(--peso-fuerte);
}
.ficha-filtro button {
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border: 0; border-radius: var(--r-full);
  background: color-mix(in srgb, var(--primario) 18%, transparent);
  color: inherit; cursor: pointer;
}
.ficha-filtro button:hover { background: color-mix(in srgb, var(--primario) 32%, transparent); }
.ficha-filtro svg { width: 12px; height: 12px; }

/* -----------------------------------------------------------------------------
   16. BARRA DE ACCIONES EN LOTE
   -------------------------------------------------------------------------- */
.lote {
  position: sticky;
  bottom: var(--e-4);
  z-index: 30;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-3);
  padding: var(--e-3) var(--e-4);
  margin: var(--e-4) 0 0;
  background: var(--tinta);
  color: var(--blanco);
  border-radius: var(--r-lg);
  box-shadow: var(--sombra-3);
}
:root[data-tema="oscuro"] .lote { background: var(--activo); border: 1px solid var(--primario-borde); color: var(--tinta); }
.lote .btn { color: inherit; border-color: currentColor; }
.lote .btn--primario { background: var(--primario); border-color: transparent; color: var(--tinta-inv); }

/* -----------------------------------------------------------------------------
   17. PAGINACIÓN
   -------------------------------------------------------------------------- */
.pagina { display: flex; align-items: center; gap: var(--e-1); }
.pagina button, .pagina a {
  min-width: 40px; min-height: 40px;
  display: grid; place-items: center;
  border: 1px solid var(--borde); border-radius: var(--r-sm);
  background: var(--panel); color: var(--tinta-2);
  font-size: var(--txt-sm); text-decoration: none; cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.pagina button:hover, .pagina a:hover { background: var(--hundido); color: var(--tinta); }
.pagina [aria-current="page"] { background: var(--primario); border-color: var(--primario); color: var(--tinta-inv); font-weight: var(--peso-negro); }

/* -----------------------------------------------------------------------------
   18. CONTENEDOR DE CÓDIGO / CLAVES TÉCNICAS
   -------------------------------------------------------------------------- */
code, .clave {
  font-family: var(--fuente-mono);
  font-size: .875em;
  background: var(--hundido);
  border: 1px solid var(--borde);
  border-radius: var(--r-xs);
  padding: 1px 6px;
  color: var(--tinta-2);
}
