/* =============================================================================
   COMPONENTES · Vocabulario compartido del sistema "La Cinta"
   -----------------------------------------------------------------------------
   Todo lo que aparece en más de una página vive acá. Lo que aparece en una
   sola vive dentro de su propio .astro.

   Tres reglas que gobiernan este archivo:

   1. NO HAY TARJETAS GENÉRICAS. La unidad de superficie se llama PLACA y es
      una chapa: borde definido, esquina de 6 px como techo, sin sombra difusa
      encima del borde. Una placa dentro de otra placa nunca está bien.

   2. EL ESTADO SE CODIFICA POR MARCA, NO SÓLO POR COLOR. Cada estado
      operativo lleva además una trama o una forma propia. Es requisito de
      accesibilidad y es lo que hace que la cinta se lea en blanco y negro.

   3. LA PROCEDENCIA DEL DATO ES TIPOGRÁFICA. Lo verificado va en trazo lleno;
      lo provisorio, en trazo fino y con su sello. En un pliego, presentar un
      dato sin fijar como si estuviera fijado es el peor error posible.
   ========================================================================== */

/* =============================================================================
   CONTENEDORES Y RITMO
   ========================================================================== */

.envoltura {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.envoltura--ancha { max-width: var(--w-wide); }
.envoltura--angosta { max-width: var(--w-narrow); }

.seccion { padding-block: var(--space-section); }
.seccion--grande { padding-block: var(--space-section-lg); }
.seccion--pegada { padding-block: var(--sp-8); }

/* La banda que alterna en todas las páginas. Desde la revisión de identidad es
   papel verde y no gris frío: es la superficie que le da al segundo color de
   marca una presencia real, sin quitarle al azul ninguno de sus campos. */
.seccion--hundida { background: var(--color-surface-sunk); }

.seccion--profunda {
  background: var(--color-surface-inverse);
  color: var(--color-text-on-inverse);
}

/* El campo profundo verde. Va siempre acompañado de la clase de contexto
   `.on-verde`, que es la que cambia el vocabulario de los componentes de
   adentro; esta sólo pinta la superficie. */
.seccion--campo-verde {
  background: var(--color-surface-verde);
  color: var(--color-text-on-verde);
}

/* La línea que separa dos secciones del mismo color: una sola, a todo ancho. */
.seccion--con-linea { border-top: 1px solid var(--color-line); }

/* =============================================================================
   TÍTULO DE SECCIÓN
   Sin copete ni etiqueta encima. El título carga su propio peso; una etiqueta
   arriba lo debilita y le roba el primer renglón a la lectura.
   ========================================================================== */

.titulo-seccion {
  margin-bottom: var(--space-block);
}

/* El límite de medida va sobre el TÍTULO, no sobre el bloque: `ch` se calcula
   con el cuerpo del elemento que lo declara, así que 42ch puestos en el
   contenedor se medían con la tipografía de párrafo y le dejaban al título una
   columna de 350 px. Un h2 de 40 px partido en tres renglones dentro de una
   sección de 1400 no es una medida de lectura, es un error. */
.titulo-seccion h2,
.titulo-seccion h1 {
  margin-bottom: var(--sp-4);
  max-width: 26ch;
  text-wrap: balance;
}

.titulo-seccion__bajada {
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
  color: var(--color-text-soft);
  max-width: 56ch;
  margin: 0;
}

/* =============================================================================
   BOTONES
   Objetivo táctil de 48 px como piso en las acciones principales: el pliego
   pide botones grandes porque el sitio se usa durante una emergencia.
   ========================================================================== */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  min-height: 3rem;
  padding: var(--sp-3) var(--sp-6);
  border: 1px solid transparent;
  border-radius: var(--r-2);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-label);
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  max-width: 100%;
  /* Sin `nowrap`: una etiqueta larga en pantalla angosta tiene que partirse.
     Con `nowrap` el botón empujaba el ancho de todo el documento. */
  text-wrap: balance;
  transition: background-color var(--dur-1) var(--ease-out),
              border-color var(--dur-1) var(--ease-out),
              color var(--dur-1) var(--ease-out),
              transform var(--dur-1) var(--ease-out);
}

.boton:active { transform: translateY(1px); }

.boton svg { flex: none; }

/* Primario — el azul institucional. Es la acción del sistema. */
.boton--primario {
  background: var(--color-brand);
  border-color: var(--color-brand);
  color: var(--color-text-on-accent);
}
.boton--primario:hover {
  background: var(--azul-700);
  border-color: var(--azul-700);
  color: var(--color-text-on-accent);
}

/* Emergencia — rojo. Reservado al canal de asistencia y a nada más. */
.boton--emergencia {
  background: var(--emergencia);
  border-color: var(--emergencia);
  color: #ffffff;
}
.boton--emergencia:hover {
  background: var(--emergencia-fuerte);
  border-color: var(--emergencia-fuerte);
  color: #ffffff;
}

/* Acento — naranja de obra. Acciones secundarias con carga operativa. */
.boton--acento {
  background: var(--verde-600);
  border-color: var(--verde-600);
  color: #ffffff;
}
.boton--acento:hover {
  background: var(--verde-700);
  border-color: var(--verde-700);
  color: #ffffff;
}

/* Contorno — la acción alternativa. Hereda el color del contexto. */
.boton--contorno {
  background: transparent;
  border-color: var(--color-line-strong);
  color: var(--color-text);
}
.boton--contorno:hover {
  border-color: var(--color-brand);
  color: var(--color-brand);
  background: var(--color-brand-soft);
}

/* Sólido claro — para usar sobre el campo profundo. */
.boton--claro {
  background: #ffffff;
  border-color: #ffffff;
  color: var(--azul-950);
}
.boton--claro:hover {
  background: var(--azul-50);
  border-color: var(--azul-50);
  color: var(--azul-950);
}

.boton--ancho { width: 100%; }

.boton--grande {
  min-height: 3.5rem;
  padding: var(--sp-4) var(--sp-7);
  font-size: var(--fs-base);
}

.boton--chico {
  min-height: 2.25rem;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-3xs);
}

/* =============================================================================
   PLACA · la unidad de superficie
   Una chapa atornillada, no una tarjeta blanda. Borde definido y sin sombra
   encima; la elevación se resuelve por borde O por sombra, nunca por las dos.
   ========================================================================== */

.placa {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--r-3);
  padding: var(--sp-6);
  min-width: 0;
}

.placa--densa { padding: var(--sp-5); }
.placa--holgada { padding: var(--sp-7); }
.placa--plana { background: transparent; }

/* Placa que además es enlace: el borde se compromete al pasar por encima. */
.placa--enlace {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}

.placa--enlace:hover {
  border-color: var(--color-accent);
  background: var(--color-accent-soft);
  color: inherit;
}

.on-dark .placa, .on-verde .placa {
  background: var(--color-surface);
  border-color: var(--color-line);
}

.on-dark .placa--enlace:hover,
.on-verde .placa--enlace:hover {
  border-color: var(--color-accent);
  background: var(--color-surface-inset);
}

/* =============================================================================
   ESCUDO DE RUTA
   El identificador de ruta nacional, dibujado como el que está clavado en la
   banquina. Es el ancla de reconocimiento más fuerte que tiene el sitio.
   ========================================================================== */

.escudo {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  padding: var(--sp-1) var(--sp-2) 0.3rem;
  background: var(--azul-950);
  color: #ffffff;
  border: 2px solid #ffffff;
  border-radius: var(--r-2);
  font-family: var(--font-display);
  line-height: 1;
  text-decoration: none;
  box-shadow: inset 0 0 0 1px var(--azul-950);
}

.escudo__sigla {
  font-size: 0.5rem;
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-wide);
  opacity: 0.82;
}

.escudo__numero {
  font-size: var(--fs-md);
  font-weight: var(--fw-black);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.escudo--chico { min-width: 2.125rem; }
.escudo--chico .escudo__sigla { font-size: 0.42rem; }
.escudo--chico .escudo__numero { font-size: var(--fs-sm); }

/* Sobre cualquiera de los dos campos profundos el escudo se invierte: el marco
   blanco desaparece contra la noche y el que aporta el contraste es el relleno.
   El borde sale del vocabulario del contexto, así que sobre el campo verde se
   tiñe de verde sin una regla más. */
.on-dark .escudo,
.on-verde .escudo {
  background: transparent;
  border-color: var(--color-line-strong);
  box-shadow: none;
}

/* =============================================================================
   PASTILLA DE ESTADO
   Cada estado lleva color + MARCA. La marca es un cuadrado con trama propia
   dibujado en `::before`: sólido, rayado, punteado, cruzado o hueco. Así el
   estado sobrevive a la impresión en blanco y negro, al daltonismo y a la
   pantalla al 40 % de brillo.
   ========================================================================== */

.pastilla {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.28rem var(--sp-3) 0.28rem var(--sp-2);
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-label);
  text-transform: uppercase;
  line-height: 1.4;
  white-space: nowrap;
}

.pastilla::before {
  content: '';
  width: 0.6rem;
  height: 0.6rem;
  flex: none;
  border: 1.5px solid currentColor;
  border-radius: 1px;
}

/* -----------------------------------------------------------------------------
   LOS SIETE ESTADOS: los seis del requerimiento más «Desvío» (02/10/2026)
   Normal · Precaución · Demoras · Obras · Corte parcial · Desvío · Corte total.

   Cada uno lleva ADEMÁS del color una trama propia, y la trama no es adorno:
   es lo que hace que el estado siga siendo legible impreso en blanco y negro,
   con la pantalla al mínimo de brillo, o para alguien que no distingue el rojo
   del verde. El color nunca es el único portador de la información.
   -------------------------------------------------------------------------- */

/* Normal — sólido. Nada que informar. */
.pastilla--normal,
.pastilla--fluido { color: var(--sig-fluido); background: var(--sig-fluido-bg); }
.pastilla--normal::before,
.pastilla--fluido::before { background: currentColor; }

/* Precaución — rayado a 45°. */
.pastilla--precaucion { color: var(--sig-precaucion); background: var(--sig-precaucion-bg); }
.pastilla--precaucion::before {
  background: repeating-linear-gradient(
    45deg, currentColor 0 2px, transparent 2px 4px
  );
}

/* Demoras — rayado horizontal: la fila de vehículos vista de costado. */
.pastilla--demoras { color: var(--sig-demoras); background: var(--sig-demoras-bg); }
.pastilla--demoras::before {
  background: repeating-linear-gradient(
    0deg, currentColor 0 1.5px, transparent 1.5px 3.5px
  );
}

/* Obras — rayado inverso, el mismo del cartel de obra. */
.pastilla--obras,
.pastilla--obra { color: var(--sig-obra); background: var(--sig-obra-bg); }
.pastilla--obras::before,
.pastilla--obra::before {
  background: repeating-linear-gradient(
    -45deg, currentColor 0 2px, transparent 2px 4px
  );
}

/* Corte parcial — media marca llena. Pasa la mitad. */
.pastilla--corte-parcial { color: var(--sig-corte); background: var(--sig-corte-bg); }
.pastilla--corte-parcial::before {
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50%);
}

/* Desvío — rayado vertical: barreras de canalización. Del rojo de los cortes,
   porque en el mapa va con ellos; la trama lo distingue del corte parcial y
   del total sin depender del color. Mismo par de colores que el corte, ya
   verificado en verificar-contraste.mjs. Séptimo estado, del 02/10/2026. */
.pastilla--desvio { color: var(--sig-corte); background: var(--sig-corte-bg); }
.pastilla--desvio::before {
  background: repeating-linear-gradient(
    90deg, currentColor 0 1.5px, transparent 1.5px 3.5px
  );
}

/* Corte total — cruzado. Cerrado. */
.pastilla--corte-total,
.pastilla--corte { color: var(--sig-corte); background: var(--sig-corte-bg); }
.pastilla--corte-total::before,
.pastilla--corte::before {
  background:
    repeating-linear-gradient(45deg, currentColor 0 1.5px, transparent 1.5px 3.5px),
    repeating-linear-gradient(-45deg, currentColor 0 1.5px, transparent 1.5px 3.5px);
}

/* Informativo — hueco. */
.pastilla--info { color: var(--sig-info); background: var(--sig-info-bg); }

/* -----------------------------------------------------------------------------
   ESTADOS DE OBRA · programada / en ejecución / finalizada
   -------------------------------------------------------------------------- */
.pastilla--programada { color: var(--sig-info); background: var(--sig-info-bg); }
.pastilla--programada::before { border-style: dashed; }

.pastilla--ejecucion { color: var(--sig-obra); background: var(--sig-obra-bg); }
.pastilla--ejecucion::before {
  background: repeating-linear-gradient(
    -45deg, currentColor 0 2px, transparent 2px 4px
  );
}

.pastilla--finalizada { color: var(--sig-fluido); background: var(--sig-fluido-bg); }
.pastilla--finalizada::before { background: currentColor; }

/* Sobre el campo profundo: fondo translúcido del propio matiz, texto claro. */
.on-dark .pastilla--normal,
.on-dark .pastilla--fluido,
.on-dark .pastilla--finalizada,
.on-verde .pastilla--normal,
.on-verde .pastilla--fluido,
.on-verde .pastilla--finalizada { color: #7fd6a8; background: rgb(23 102 63 / 0.30); }
.on-dark .pastilla--precaucion, .on-verde .pastilla--precaucion { color: #f2c869; background: rgb(138 86 0 / 0.34); }
.on-dark .pastilla--demoras, .on-verde .pastilla--demoras { color: #f7b25e; background: rgb(161 92 0 / 0.34); }
/* Obras sobre campo profundo: el violeta claro de la escala, sobre el violeta
   oscuro al 34%. Compuesto sobre el campo da 5,74:1 en azul y 5,61:1 en verde. */
.on-dark .pastilla--obras,
.on-dark .pastilla--obra,
.on-dark .pastilla--ejecucion,
.on-verde .pastilla--obras,
.on-verde .pastilla--obra,
.on-verde .pastilla--ejecucion { color: #b492de; background: rgb(90 47 138 / 0.34); }
.on-dark .pastilla--corte-parcial,
.on-dark .pastilla--corte-total,
.on-dark .pastilla--corte,
.on-dark .pastilla--desvio,
.on-verde .pastilla--desvio,
.on-verde .pastilla--corte-parcial,
.on-verde .pastilla--corte-total,
.on-verde .pastilla--corte { color: #ff8f9b; background: rgb(179 18 31 / 0.32); }
.on-dark .pastilla--info,
.on-dark .pastilla--programada,
.on-verde .pastilla--info,
.on-verde .pastilla--programada { color: var(--azul-200); background: rgb(1 68 127 / 0.44); }

/* =============================================================================
   SELLO DE PROCEDENCIA
   La donación del "listón de procedencia": lo conocido y lo inferido no se
   dibujan igual. Acá, lo verificado va en trazo lleno y lo provisorio en trazo
   fino punteado, con su sello al lado. El requerimiento es explícito: no
   inventar información institucional. Esto lo hace visible.
   ========================================================================== */

.sello {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tk-label);
  text-transform: uppercase;
  line-height: 1.3;
  padding: 0.15rem 0.5rem;
  border-radius: var(--r-1);
  vertical-align: middle;
}

.sello--verificado {
  color: var(--sig-info);
  background: var(--sig-info-bg);
  border: 1px solid color-mix(in oklab, var(--sig-info) 24%, transparent);
}

.sello--provisorio {
  color: var(--obra-700);
  background: var(--obra-50);
  border: 1px dashed color-mix(in oklab, var(--obra-700) 40%, transparent);
}

.sello--pendiente {
  color: var(--n-600);
  background: var(--n-100);
  border: 1px dashed var(--n-300);
}

.on-dark .sello--verificado, .on-verde .sello--verificado {
  color: var(--azul-200); background: rgb(1 68 127 / 0.42);
  border-color: rgb(156 193 232 / 0.32);
}
.on-dark .sello--provisorio, .on-verde .sello--provisorio {
  color: var(--obra-300); background: rgb(157 75 0 / 0.30);
  border-color: rgb(255 159 69 / 0.42);
}
.on-dark .sello--pendiente,
.on-verde .sello--pendiente {
  color: var(--color-text-soft); background: var(--color-surface-inset);
  border-color: var(--color-line-strong);
}

/* Un dato provisorio dentro de un texto corrido: subrayado punteado, para que
   se note sin romper la lectura. */
.provisorio {
  text-decoration: underline dashed
    color-mix(in oklab, var(--verde-600) 60%, transparent);
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}

.on-dark .provisorio, .on-verde .provisorio {
  text-decoration-color: color-mix(in oklab, var(--verde-300) 65%, transparent);
}

/* =============================================================================
   CIFRA
   Un número del corredor con su unidad y su procedencia. La unidad nunca
   compite con la cifra: va en mono, más chica, y en el color de acento.
   ========================================================================== */

.cifra {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.cifra__valor {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-black);
  line-height: 1;
  letter-spacing: var(--tk-tight);
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

.cifra__unidad {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-accent);
  letter-spacing: 0;
}

.cifra__etiqueta {
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--color-text-soft);
  max-width: 24ch;
}

/* =============================================================================
   ETIQUETA DE SEÑAL
   Mayúsculas cortas, muy espaciadas. Se usa para rotular un bloque de datos,
   nunca encima de un título.
   ========================================================================== */

.etiqueta {
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-wide);
  text-transform: uppercase;
  color: var(--color-text-faint);
  line-height: 1.4;
}

.etiqueta--acento { color: var(--color-accent); }
.etiqueta--marca { color: var(--color-brand); }

/* =============================================================================
   TABLAS DE DATOS
   Tarifas, categorías, progresivas. Densas pero respirables; la cabecera es
   una franja del campo profundo, no una fila gris.
   ========================================================================== */

.tabla-envoltura {
  overflow-x: auto;
  border: 1px solid var(--color-line);
  border-radius: var(--r-3);
  background: var(--color-surface);
  /* Nunca hacemos scrollear la página entera: la tabla scrollea sola. */
  -webkit-overflow-scrolling: touch;
}

.tabla {
  min-width: 34rem;
  font-size: var(--fs-sm);
}

.tabla thead th {
  background: var(--azul-950);
  color: var(--color-text-on-inverse);
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-label);
  text-transform: uppercase;
  padding: var(--sp-3) var(--sp-4);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

.tabla tbody th,
.tabla tbody td {
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--color-line);
  vertical-align: baseline;
}

.tabla tbody tr:nth-child(even) { background: var(--color-surface-sunk); }

.tabla tbody th {
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.tabla .num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tabla caption {
  caption-side: bottom;
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-3xs);
  line-height: var(--lh-normal);
  color: var(--color-text-faint);
  text-align: left;
  border-top: 1px solid var(--color-line);
}

/* LA TABLA QUE ENTRA ENTERA EN EL TELÉFONO (octubre de 2026). Pedido del
   cliente para el cuadro tarifario y las tablas de estaciones de peaje: sin
   scroll lateral, aunque haya que apretar los textos. El `min-width: 34rem` de
   `.tabla` dejaba fuera de la pantalla la última columna —la tarifa al
   público, el estado de la estación—, del otro lado del deslizamiento. Las
   tablas sin este modificador conservan el suyo. Es el mismo de Mesopotámico.

   SE APRIETA EN DOS ESCALONES, y sólo lo que hace falta en cada uno. Lo que
   cede es el texto de las celdas; la fila (`tbody th`) y los importes y
   kilómetros (`.num`) no envuelven nunca: «Categoría / 1» o un precio partido
   se leen mal. Un nombre largo de estación sí envuelve: su celda lleva
   `.tabla__envuelve`. */
.tabla--ajustada { min-width: 0; }

/* Debajo de 40 rem, el relleno: la cabecera envuelve en dos renglones
   («Tarifa al / público») y las celdas cortan con guion. */
@media (max-width: 40rem) {
  .tabla--ajustada thead th {
    padding: var(--sp-2);
    white-space: normal;
    letter-spacing: var(--tk-normal);
    vertical-align: bottom;
  }

  /* La cabecera de un importe lleva `.num`, y `.tabla .num` le pone `nowrap`
     con más peso que la regla de arriba. */
  .tabla--ajustada thead .num { white-space: normal; }

  .tabla--ajustada tbody th,
  .tabla--ajustada tbody td { padding: var(--sp-3) var(--sp-2); }

  .tabla--ajustada .tabla__envuelve { white-space: normal; }

  .tabla--ajustada tbody td:not(.num) {
    hyphens: auto;
    overflow-wrap: anywhere;
  }

  /* «KILÓMETRO» y «EN SERVICIO» son una palabra y una pastilla que no
     cortaban: sumaban 60 px a una tabla que no los tenía. */
  .tabla--ajustada thead th { hyphens: auto; }

  /* La pastilla envuelve entre palabras («EN / SERVICIO»), nunca adentro de
     una: el `overflow-wrap: anywhere` de la celda partía «PREVI / STA». */
  .tabla--ajustada .pastilla {
    white-space: normal;
    overflow-wrap: normal;
    hyphens: manual;
    letter-spacing: var(--tk-normal);
    padding-inline: var(--sp-2);
  }
}

/* LAS COLUMNAS QUE SE APILAN. Una tabla de seis columnas no entra en 320 px ni
   apretada. Debajo de 30 rem, la columna marcada `.tabla__col-aparte` se oculta
   y su dato pasa a un segundo renglón de la celda vecina (`.tabla__apilado`):
   la ruta debajo del nombre de la estación, la provincia debajo de la
   localidad. No se pierde ningún dato. */
.tabla--ajustada .tabla__apilado { display: none; }

@media (max-width: 30rem) {
  .tabla--ajustada .tabla__col-aparte { display: none; }

  /* El cuadradito de la pastilla: el color ya dice el estado, y son 14 px. */
  .tabla--ajustada .pastilla::before { display: none; }
  .tabla--ajustada .pastilla { padding-inline: var(--sp-1); }

  /* Un kilómetro no es un importe: baja a 12 px, el piso del Art. 61.7, y la
     tabla de seis columnas entra a 320 px. Los importes del cuadro, no. */
  .tabla--ajustada .num--km { font-size: var(--fs-3xs); }

  .tabla--ajustada .tabla__apilado {
    display: block;
    font-weight: var(--fw-regular);
    font-size: var(--fs-3xs);
    color: var(--color-text-soft);
  }
}

/* Debajo de 26 rem —casi todos los teléfonos—, el cuerpo: la fila baja a 13 px
   y el texto de las celdas a 12, que es el piso del Art. 61.7; de ahí no pasa.
   Los importes y los kilómetros quedan como están. */
@media (max-width: 26rem) {
  .tabla--ajustada tbody th { font-size: var(--fs-2xs); }

  .tabla--ajustada tbody td:not(.num) {
    font-size: var(--fs-3xs);
    line-height: var(--lh-snug);
  }

  .tabla--ajustada tbody th,
  .tabla--ajustada tbody td { padding-inline: var(--sp-1); }

  .tabla--ajustada tr > :first-child { padding-left: var(--sp-2); }
  .tabla--ajustada tr > :last-child { padding-right: var(--sp-1); }
}

/* =============================================================================
   AVISO
   Bloque de nota. Sin barra de color al costado: el fondo teñido y el ícono ya
   dicen de qué se trata, y una barra gorda a la izquierda es el recurso que
   usa todo el mundo cuando no confía en su propia jerarquía.
   ========================================================================== */

.aviso {
  display: flex;
  gap: var(--sp-4);
  padding: var(--sp-5);
  border-radius: var(--r-3);
  background: var(--color-brand-soft);
  border: 1px solid color-mix(in oklab, var(--color-brand) 20%, transparent);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
}

.aviso__icono { flex: none; color: var(--color-brand); margin-top: 0.1rem; }

/* Los avisos suelen llevar el correo de Atención al Usuario, que son 44
   caracteres sin un solo espacio: sin esto arrastra el ancho de la página. */
.aviso p { max-width: 62ch; overflow-wrap: anywhere; }
.aviso > div { min-width: 0; }

.aviso--obra {
  background: var(--obra-50);
  border-color: color-mix(in oklab, var(--obra-600) 26%, transparent);
}
.aviso--obra .aviso__icono { color: var(--obra-700); }

.on-dark .aviso,
.on-verde .aviso {
  background: var(--color-surface-inset);
  border-color: var(--color-line-strong);
}
.on-dark .aviso__icono, .on-verde .aviso__icono { color: var(--color-brand); }

/* =============================================================================
   REJILLAS
   Nombradas por la relación que expresan, no por la cantidad de columnas.
   ========================================================================== */

.rejilla {
  display: grid;
  gap: var(--sp-5);
}

/* Cada modificador declara su propio `display: grid`. Son autosuficientes a
   propósito: un modificador que sólo funciona acompañado de su clase base es
   una trampa, y basta con olvidarse la base una vez para que la página se
   apile en una columna sin que nada avise. */
.rejilla--pares,
.rejilla--anchas,
.rejilla--cifras,
.rejilla--principal-apoyo {
  display: grid;
  gap: var(--sp-5);
}

.rejilla--pares { grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); }
.rejilla--anchas { grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr)); }
.rejilla--cifras { grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr)); }

/* Estructura principal/apoyo: el contenido manda, la columna lateral acompaña. */
.rejilla--principal-apoyo {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-8);
}

/* Los hijos de una rejilla tienen `min-width: auto` por defecto, que equivale a
   su ancho mínimo de contenido: la pista puede encoger a cero, pero el hijo no,
   y se sale. Es la causa más frecuente de scroll horizontal en el celular. */
.rejilla > *,
.rejilla--pares > *,
.rejilla--anchas > *,
.rejilla--cifras > *,
.rejilla--principal-apoyo > * {
  min-width: 0;
}

@media (min-width: 62rem) {
  .rejilla--principal-apoyo {
    grid-template-columns: minmax(0, 1.65fr) minmax(17rem, 1fr);
    gap: var(--sp-9);
  }
}

/* =============================================================================
   LISTA DE DEFINICIÓN
   Ficha técnica: ruta, kilómetro, sentido, categoría. Alineada en dos columnas
   para que la vista baje por los valores sin releer las etiquetas.
   ========================================================================== */

.ficha {
  display: grid;
  grid-template-columns: minmax(7rem, auto) minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-5);
  margin: 0;
  font-size: var(--fs-sm);
}

.ficha dt {
  font-family: var(--font-display);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--tk-label);
  text-transform: uppercase;
  color: var(--color-text-faint);
  padding-top: 0.22rem;
}

.ficha dd {
  margin: 0;
  min-width: 0;
  color: var(--color-text);
  line-height: var(--lh-normal);
  /* Correos y dominios son cadenas largas sin espacios: sin esto, su ancho
     mínimo intrínseco arrastra la rejilla y con ella el ancho de la página. */
  overflow-wrap: anywhere;
}

.ficha dt { min-width: 0; overflow-wrap: anywhere; }

/* =============================================================================
   SELLO DE ACTUALIZACIÓN
   El pliego exige mostrar fecha y hora de la última actualización de la
   información operativa. Va en mono porque es una medida, no una frase.
   ========================================================================== */

.actualizado {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-3xs);
  color: var(--color-text-faint);
  letter-spacing: 0;
}

.actualizado::before {
  content: '';
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--sig-fluido);
  flex: none;
}

.on-dark .actualizado::before, .on-verde .actualizado::before { background: #7fd6a8; }

/* =============================================================================
   ENTRADA AL SCROLL
   El estado de partida lo pone el script (`data-entrada="espera"`), nunca la
   hoja de estilos: si el JavaScript no carga, el atributo no existe, ninguna
   de estas reglas aplica y el contenido se ve entero. Es la diferencia entre
   una animación y una página en blanco.
   ========================================================================== */

[data-entrada='espera'] {
  opacity: 0;
  transform: translateY(1.25rem);
}

[data-entrada='visible'] {
  opacity: 1;
  transform: none;
  transition:
    opacity 520ms var(--ease-traza),
    transform 620ms var(--ease-traza);
}

/* Hermanos escalonados dentro de un mismo bloque, con el retraso acotado: si
   el último tarda un segundo, la sección se siente lenta, no elegante. */
[data-entrada='visible'] > [data-escalonar] { animation: escalonar 480ms var(--ease-traza) both; }
[data-entrada='visible'] > [data-escalonar]:nth-child(1) { animation-delay: 40ms; }
[data-entrada='visible'] > [data-escalonar]:nth-child(2) { animation-delay: 100ms; }
[data-entrada='visible'] > [data-escalonar]:nth-child(3) { animation-delay: 160ms; }
[data-entrada='visible'] > [data-escalonar]:nth-child(4) { animation-delay: 210ms; }
[data-entrada='visible'] > [data-escalonar]:nth-child(5) { animation-delay: 250ms; }
[data-entrada='visible'] > [data-escalonar]:nth-child(n + 6) { animation-delay: 280ms; }

@keyframes escalonar {
  from { opacity: 0; transform: translateY(0.75rem); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  [data-entrada='espera'],
  [data-entrada='visible'] {
    opacity: 1;
    transform: none;
    transition: none;
  }
  [data-entrada='visible'] > [data-escalonar] { animation: none; }
}

/* ==========================================================================
   COMPARTIDO ENTRE PAGINAS
   --------------------------------------------------------------------------
   Estas cuatro piezas vivian cada una en la hoja de UNA pagina y las dibujaban
   DOS. La segunda no cargaba esa hoja, asi que las dibujaba sin estilo: no
   fallaba nada, simplemente se veian como un error de maqueta.

   En October el CSS se declara por pagina y los parciales heredan lo que haya
   cargado quien los incluye; una clase que cruza de una pagina a otra no tiene
   dueno natural y termina aca, que es la capa compartida.

   Lo encontro `npm run hojas`, que existe desde entonces.
   ====================================================================== */

  /* El boton que cierra una tabla o una lista larga. Lo usan `/nuestro-tramo`
     y la ficha de estacion. */
  .tabla-boton { margin-top: var(--sp-6); }

  .enlace-bloque {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-height: 2.75rem;
    margin-right: var(--sp-6);
    font-family: var(--font-display);
    font-size: var(--fs-3xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tk-label);
    text-transform: uppercase;
    line-height: 1.3;
  }



  /* --- Formas de pago -------------------------------------------------------- */
  .formas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
    gap: var(--sp-4);
    margin-bottom: var(--sp-6);
  }

  .forma {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--sp-4);
    padding: var(--sp-5);
    border: 1px solid var(--color-line);
    border-radius: var(--r-3);
    background: var(--color-surface);
  }

  .forma--principal {
    background: var(--azul-950);
    border-color: var(--azul-800);
    color: var(--color-text-on-inverse);
  }

  .forma__ico { color: var(--color-accent); margin-top: 0.1rem; }
  .forma--principal .forma__ico { color: var(--verde-300); }

  .forma__nombre {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    margin: 0 0 var(--sp-2);
    font-size: var(--fs-md);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--tk-snug);
  }

  .forma--principal .forma__nombre { color: #ffffff; }

  .forma__marca {
    /* verde-700 y no verde-500: con texto blanco encima, el 500 se queda en
       4,1:1 y no llega al mínimo del Art. 61.7. */
    background: var(--verde-700);
    color: #ffffff;
    font-family: var(--font-display);
    font-size: var(--fs-3xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tk-label);
    text-transform: uppercase;
    padding: 0.12rem var(--sp-3);
    border-radius: var(--r-1);
  }

  .forma__detalle {
    margin: 0;
    font-size: var(--fs-sm);
    line-height: var(--lh-normal);
    color: var(--color-text-soft);
  }

  .forma--principal .forma__detalle { color: #b9cee2; }

  /* Lista de datos: rotulo arriba, valor debajo. La usan `/institucional` y la
     ficha de estacion. */
  .datos { display: grid; gap: 0; margin: 0; }

  @media (min-width: 60rem) {
    .datos { grid-template-columns: 1fr 1fr; gap: 0 var(--sp-9); }
  }

  .dato {
    display: grid;
    gap: 0.2rem;
    padding-block: var(--sp-4);
    border-top: 1px solid var(--color-line);
  }

  .dato dt {
    font-family: var(--font-display);
    font-size: var(--fs-3xs);
    font-weight: var(--fw-bold);
    letter-spacing: var(--tk-label);
    text-transform: uppercase;
    color: var(--color-text-faint);
  }

  .dato dd {
    margin: 0;
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
    word-break: break-word;
  }

/* --- Sección libre --------------------------------------------------------
   La que agrega un editor desde Contenido → Páginas, al final de la página
   (partials/site/secciones-extra.htm). Mismo cuerpo de texto que la
   presentación de /institucional. */
.seccion-libre__cuerpo {
  max-width: var(--w-prose);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  color: var(--color-text-soft);
}

.seccion-libre__cuerpo > * { margin-block: 0; }
.seccion-libre__cuerpo > * + * { margin-top: var(--sp-4); }
.seccion-libre__boton { margin-top: var(--sp-6); }

/* --- Botones de descarga ---------------------------------------------------
   partials/ui/descargas.htm: los documentos de las secciones libres de
   /institucional y los de /programa-de-integridad. Una rejilla y no una fila:
   los rótulos son largos («Política del Canal de Denuncias e
   Investigaciones») y en fila cada botón tomaba un ancho distinto. Con
   columnas parejas se leen como una lista. */
.descargas {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  margin: var(--sp-6) 0 0;
}

.descargas li { margin: 0; }

.descargas__boton {
  width: 100%;
  height: 100%;
  justify-content: flex-start;
  text-align: left;
}

/* --- Banners ---------------------------------------------------------------
   partials/site/banners.htm (punto 15). Sin banners vigentes no se dibuja
   nada: estas reglas no afectan ninguna página hasta que el editor cargue uno. */

  .banners {
    background: var(--color-surface-sunk);
    border-block: 1px solid var(--color-line);
  }

  .banners__caja {
    display: grid;
    gap: var(--sp-3);
    padding-block: var(--sp-4);
  }

  .banner {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    color: inherit;
    text-decoration: none;
  }

  a.banner:hover .banner__texto { text-decoration: underline; }

  .banner__imagen {
    flex: none;
    width: min(100%, 22rem);
    height: auto;
    border-radius: var(--r-3);
  }

  .banner__texto {
    font-size: var(--fs-base);
    line-height: var(--lh-normal);
    font-weight: var(--fw-semibold);
  }

  @media (max-width: 40rem) {
    .banner { flex-direction: column; align-items: flex-start; }
  }
