/* ════════════════════════════════════════════════════════════════════════════
   El panel de control de la obra: la Ruta 360.

   Va en su propia hoja y no dentro de index.html porque ya son trescientas
   líneas de estilo: mezcladas con el marcado, cada retoque obliga a leer la
   página entera para encontrar dónde toca.

   Dos reglas mandan sobre cualquier duda.

   La primera: las cifras son una CAPA sobre el índice de pantallas, nunca en su
   lugar. Si toda la API falla, el índice sigue entero y la plataforma se usa.

   La segunda: no se pinta un cero por lo que no se pudo contar. Un cero donde
   había un «no lo sé» diría «obra limpia» donde hay lotes bloqueados que nadie
   tuvo permiso para ver.
   ════════════════════════════════════════════════════════════════════════════ */

/* El panel es más ancho que el resto de la plataforma.
   ────────────────────────────────────────────────────
   No es un capricho: las siete puertas TIENEN que ir en una fila. Partidas en
   cuatro y tres dejan de leerse como un recorrido y pasan a ser dos grupos, que
   es exactamente lo contrario de lo que esta pantalla existe para decir. A 1240
   no caben; a 1560 sí, y el resto de pantallas —tablas y formularios— se quedan
   donde estaban, porque una línea de texto de 1560 píxeles no se lee. */
/* Ojo al renombrar: estos dos selectores nombran una clase que vive en OTRO fichero. Al
   pasar `.puertas` a `.etapas` dejaron de encajar y el panel volvió a 1240 sin decir nada
   —`:has` no falla, simplemente no aplica—, y las siete tarjetas se quedaron en 155 px con
   el nombre de la etapa recortado. */
main:has(.etapas){max-width:var(--ancho)}
.barra-marca:has(~ main .etapas) .barra-marca-inner{max-width:var(--ancho)}

/* El relieve de esta pantalla, en un solo sitio.
   ─────────────────────────────────────────────
   Se declara aquí y no se toca `--sombra`, que es de la casa entera: esta pantalla
   es una sucesión de bloques flotando sobre papel crema —la cinta de salud, siete
   tarjetas, el detalle, las dos tablas— y necesita más contraste de altura que una
   tabla sobre blanco. Con la sombra común, al 5% y al 6%, todo quedaba plano y la
   pantalla se leía como una sola lámina impresa. */
:root{
  --relieve:0 1px 2px rgba(22,35,58,.06),0 3px 10px rgba(22,35,58,.07);
  --relieve-alto:0 6px 14px rgba(22,35,58,.10),0 18px 36px rgba(22,35,58,.15);
}

/* ── Cabecera de obra ───────────────────────────────────────────────────── */
.obra-alto{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 6px}
.obra-alto .rotulo{font-size:11px;font-weight:700;color:var(--tinta-suave);
  text-transform:uppercase;letter-spacing:.06em;margin-bottom:2px}
.obra-alto select{min-width:min(370px,64vw);font-weight:600;max-width:100%}

/* Que el selector de obra NO pueda ensanchar la pantalla.
   ──────────────────────────────────────────────────────
   Los nombres de obra son largos — «Hotel Playa Bávaro · Punta Cana · Bloque A» —
   y en WebKit un <select> no se encoge por debajo de su opción más larga: reclama
   su ancho natural y arrastra consigo al contenedor. En un iPhone eso sacaba la
   página 146 px por la derecha y aparecía barra horizontal en TODAS las pantallas
   del panel. Chromium sí lo encoge, así que en el navegador de escritorio no se
   veía nada raro; lo cazó la comprobación con el motor de Safari.

   Hacen falta las dos reglas. El max-width limita al select, y el min-width:0
   desactiva el mínimo automático de los hijos flexibles: por omisión valen
   min-content, que aquí es justo el ancho del select, y sin tocarlo el contenedor
   se ensancha aunque el select ya no lo haga. */
.obra-alto > *{min-width:0;max-width:100%}

/* En el teléfono deja de ser una fila flexible y pasa a bloque.
   No basta con el max-width de arriba, y esto costó un despliegue comprobarlo: en un
   contenedor con flex-wrap, un ítem que no cabe ENVUELVE a su tamaño base en vez de
   encogerse, así que el select seguía reclamando sus 557 px aunque tuviera permiso para
   achicarse. En bloque no hay tamaño base que negociar: el select ocupa el ancho de la
   columna y ya está. En pantalla ancha sigue siendo fila, que es donde tiene sentido. */
@media (max-width:720px){
  .obra-alto{display:block;gap:10px}
  .obra-alto select{width:100%;min-width:0}
}

#sello{margin:0 0 18px;font-size:12.5px;color:var(--tinta-suave)}

/* ── Cinta de salud: los medidores y, al lado, el mapa por nivel ─────────── */
/* El mapa toma un ancho fijo y la franja el resto. Al revés —dejando que el mapa
   creciera— una tabla de dos filas se quedaba con media pantalla y los medidores
   se apretaban hasta necesitar arrastre lateral. */
.cinta-salud{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:14px;
  align-items:stretch;margin-bottom:26px}
@media (max-width:1240px){.cinta-salud{grid-template-columns:1fr}}

/* ── Franja de indicadores ──────────────────────────────────────────────── */
/* Rejilla que se reacomoda, NO una fila con desplazamiento lateral.
   ────────────────────────────────────────────────────────────────
   Era una fila flexible con `overflow-x:auto`, y eso escondía medidores: entre 760 y
   1160 px el último quedaba fuera de la vista y había que arrastrar para verlo. Una
   cifra que hay que ir a buscar es una cifra que nadie mira, y con la sexta celda
   —el tiempo medio— el problema llegaba hasta pantallas de 1600.
   Con `auto-fit` las celdas bajan de línea solas y siempre están todas a la vista.

   Los filetes los dibuja CADA CELDA con una sombra interior, y no el hueco de la rejilla
   sobre un fondo de línea. Ese truco —el que usaba la versión de teléfono— funciona
   mientras las celdas llenen todas las columnas; en cuanto la última fila va a medias, el
   fondo del contenedor asoma por las columnas vacías y deja un bloque beige del tamaño de
   dos medidores. Con la sombra interior, lo que no tiene celda se queda del color del
   papel, que es lo que debe ser. */
.franja{display:grid;grid-template-columns:repeat(auto-fit,minmax(186px,1fr));
  gap:0;background:var(--papel-alto);
  border:1px solid var(--linea);border-radius:var(--radio);box-shadow:var(--relieve);
  overflow:hidden;max-width:100%}
.franja > *{box-shadow:inset -1px 0 0 var(--linea),inset 0 -1px 0 var(--linea)}
/* El aro y su rótulo piden dos huecos: «Elementos certificados» no cabe en 186 px. */
.avance{grid-column:span 2}

/* En el teléfono la franja se APILA en dos columnas, no se desplaza de lado.
   ───────────────────────────────────────────────────────────────────────────
   Lo encontró la comprobación con el motor de Safari: en WebKit los medidores
   con ancho mínimo empujaban la PÁGINA entera hacia la derecha, mientras que en
   Chromium se quedaban dentro del desplazamiento de la franja. El mismo CSS, dos
   comportamientos — y el que rompe es el del iPhone, que es donde está casi toda
   la gente que va a usar esto.
   Apilar además es mejor de por sí: una tira de cifras que hay que arrastrar de
   lado esconde justamente las que están al final. */
@media (max-width:760px){
  .franja{grid-template-columns:1fr 1fr;grid-auto-flow:row dense}
  .avance{grid-column:1 / -1;min-width:0}
  .medidor{min-width:0}
  /* Un importe en pesos no cabe en media columna: «RD$232,050» a 26 px mide unos 143 px y a
     390 de ancho la celda deja unos 90. Se cortaban el importe y «Costo de la no calidad»
     (F08 de la QA del 11-sep-2026). La tarjeta del dinero ocupa la fila entera en el
     teléfono, y `dense` rellena el hueco que deja con el medidor siguiente para que
     ninguna fila quede a medias. En escritorio no cambia nada. */
  .medidor-ancho{grid-column:1 / -1}
}

/* El texto de un medidor encoge con su celda en vez de empujarla: sin `min-width:0` el
   bloque de texto no baja de lo que mide su palabra más larga, y la franja —que recorta lo
   que sobra— se comía el final. */
.medidor > div{min-width:0}
.medidor .que,.medidor .de{overflow-wrap:anywhere}

.avance{display:flex;align-items:center;gap:14px;padding:17px 22px;min-width:0}
.avance .aro{position:relative;width:62px;height:62px;flex:none}
.avance .aro svg{transform:rotate(-90deg)}
.avance .aro span{position:absolute;inset:0;display:grid;place-items:center;
  font-size:15px;font-weight:700;color:var(--tinta);font-variant-numeric:tabular-nums}
.avance .aro span.mudo{font-size:11px;font-weight:600;color:var(--tinta-suave);
  text-align:center;line-height:1.15}
.avance b{display:block;font-size:14.5px;font-weight:650;color:var(--tinta);line-height:1.3}
.avance i{display:block;font-style:normal;font-size:12.5px;color:var(--tinta-media);
  margin-top:2px;line-height:1.35}
/* Mismo caso que el enlace de pie de panel: va solo en su bloque, así que le toca el listón
   táctil de 24 px. Medía 19. */
.avance a{display:inline-flex;align-items:center;min-height:24px;margin-top:6px;
  font-size:12.5px;font-weight:600;color:var(--azul);text-decoration:none}
.avance a:hover{text-decoration:underline}

.medidor{display:flex;align-items:center;gap:13px;padding:17px 18px;min-width:0}
.medidor .icono{flex:none}

/* Los accesos a otras vistas, ahora en la barra de la obra. Antes eran una columna dentro
   de la cinta de indicadores: parecían una cifra más, se llevaban 150 px de la fila y
   dejaban un filete doble contra el último medidor. */
.accesos-obra{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}
.accesos-obra a{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;
  color:var(--tinta);text-decoration:none;border:1px solid var(--linea);
  border-radius:8px;padding:9px 14px;white-space:nowrap;background:var(--papel-alto)}
.accesos-obra a:hover,.accesos-obra a:focus-visible{border-color:var(--azul);
  color:var(--azul)}
@media (max-width:720px){.accesos-obra{display:none}}
.medidor .cifra{font-size:26px;font-weight:700;line-height:1;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--tinta)}
.medidor .cifra.alto{color:var(--oxido)}
.medidor .cifra.aviso{color:#8A6224}
.medidor .cifra.limpio{color:var(--nivel)}
.medidor .cifra.mudo{font-size:14px;font-weight:600;color:var(--tinta-suave)}
.medidor .que{font-size:13px;font-weight:600;color:var(--tinta);margin-top:3px;line-height:1.3}
.medidor .de{font-size:12px;color:var(--tinta-suave);margin-top:2px;line-height:1.3}

/* ── Mapa por nivel ─────────────────────────────────────────────────────────
   Dos porcentajes por planta y una pista que los reparte. La pista NO es una
   barra de avance: son dos medidas independientes sobre el mismo total, así que
   se apilan en la misma pista en vez de sumarse — un elemento detenido con un
   hallazgo grave cuenta en las dos y sumarlas pasaría del 100%. */
.mapa-calor{background:var(--papel-alto);border:1px solid var(--linea);
  border-radius:var(--radio);box-shadow:var(--relieve);padding:14px 16px 10px;
  display:flex;flex-direction:column;min-width:0;overflow-x:auto}
.mapa-calor h2{margin:0 0 10px;font-size:14px;font-weight:650;letter-spacing:-.01em;
  color:var(--tinta)}
/* El enlace de este pie se estiliza junto al del panel, más abajo: eran dos copias de la
   misma regla y la segunda se habría quedado sin el listón táctil al corregirlo. */
.mapa-calor .pie-panel{margin:auto 0 0;padding-top:10px;font-size:12px}
.mapa-calor .vacio-panel{padding:10px 0;text-align:left;line-height:1.45}

.tabla-mapa{width:100%;border-collapse:collapse;font-size:12px}
.tabla-mapa th[scope="col"]{font-size:9.5px;font-weight:700;color:var(--tinta-suave);
  text-transform:uppercase;letter-spacing:.04em;text-align:left;padding:0 6px 6px 0;
  border-bottom:1px solid var(--linea);font-weight:700;vertical-align:bottom}
.tabla-mapa th[scope="row"]{text-align:left;padding:8px 6px 8px 0;font-weight:650;
  color:var(--tinta);white-space:nowrap}
.tabla-mapa th[scope="row"] small{display:block;font-weight:400;font-size:10.5px;
  color:var(--tinta-suave)}
.tabla-mapa td{padding:8px 6px 8px 0;vertical-align:middle}
.tabla-mapa tr + tr th,.tabla-mapa tr + tr td{border-top:1px solid var(--linea)}
/* La fila de los que no tienen nivel no es un sitio de la obra: se marca como aparte. */
.tabla-mapa tr.sin-nivel th[scope="row"]{color:var(--tinta-media);font-weight:600;
  font-style:italic}

/* Los modificadores NO se llaman `aviso` ni `alto`: `aviso` es una caja de nota de la
   casa —fondo ámbar, filo izquierdo de 4 px y relleno de 12— y basta con ponérsela a una
   celda para heredarla entera. Pasó: un bloque ámbar de 59×52 en mitad de la tabla, y sin
   que nada fallara, porque la regla de aquí solo declaraba el color. */
.cifra-mapa{font-size:13px;font-weight:700;color:var(--tinta-suave);
  font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.cifra-mapa.hay-graves {color:#8A6224}
.cifra-mapa.hay-parados{color:var(--oxido)}
.cifra-mapa.hay-certificados{color:var(--nivel)}
.estado-nivel{width:1%;padding-right:0!important;text-align:right}

.pista{position:relative;height:6px;min-width:44px;border-radius:99px;
  background:var(--papel-hondo);overflow:hidden}
.pista i{position:absolute;top:0;left:0;height:100%;border-radius:99px}
.pista i.grave{background:var(--senal)}
.pista i.parado{background:var(--oxido)}
/* La barra del mapa por nivel es la del avance de la certificación (1-oct-2026): verde, como
   lo conforme en toda la suite. Antes repartía los problemas, y vacía se leía «0 % hecho». */
.pista i.certificado{background:var(--nivel)}
/* En un teléfono las seis columnas no caben: la tabla salía 30 px de su tarjeta y la marca de
   estado quedaba cortada (medido a 418 px). Se aparta la barra; la cifra en verde dice lo mismo. */
@media (max-width:520px){ .tabla-mapa .col-avance{display:none} }

/* Solo el icono: la palabra viaja en el `title` y en el texto para lectores. Con el rótulo
   dentro, la pastilla medía 85 px y sacaba la tabla 33 px fuera de su tarjeta. */
.marca-nivel{display:inline-grid;place-items:center;width:24px;height:24px;
  border-radius:99px;flex:none}
.marca-nivel.para  {background:var(--oxido-suave);color:var(--oxido)}
.marca-nivel.espera{background:var(--senal-suave);color:#8A6224}
.marca-nivel.mudo  {background:var(--papel-hondo);color:var(--tinta-media)}
.marca-nivel.bien  {background:var(--nivel-suave);color:var(--nivel)}
.marca-nivel svg{flex:none}

/* ── Asistente NCR ──────────────────────────────────────────────────────── */
.foco-ncr{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin:0 0 10px}
.foco-ncr b{font-size:13.5px;font-weight:650;color:var(--tinta);font-family:var(--mono)}

/* El defecto, con su medida y su tolerancia al lado: es lo que convierte «falló el
   recubrimiento» en un hecho comprobable. */
.defecto{display:grid;grid-template-columns:auto 1fr;gap:3px 10px;margin:0 0 12px;
  font-size:12.5px}
.defecto dt{color:var(--tinta-suave);white-space:nowrap}
.defecto dd{margin:0;color:var(--tinta)}
.defecto dd s{text-decoration:none;font-family:var(--mono);font-weight:600}

.precedente{padding:9px 0;border-top:1px solid var(--linea)}
.precedente u{display:block;text-decoration:none;font-size:9.5px;font-weight:700;
  color:var(--tinta-suave);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px}
.precedente p{margin:0;font-size:12.5px;color:var(--tinta);line-height:1.45}
.precedente p em{font-style:normal;color:var(--tinta-media)}
.precedente ul{margin:0;padding-left:17px}
.precedente li{font-size:12.5px;color:var(--tinta);line-height:1.45}
.precedente small{display:block;margin-top:5px;font-size:11px;color:var(--tinta-suave)}
/* Que no haya precedente es un dato, no un hueco: se dice, en el mismo tono con el que se
   dicen los eslabones vacíos de la trazabilidad. */
.sin-precedente{color:var(--tinta-media)!important;font-style:italic}
/* El veredicto de eficacia. «Se probó y NO funcionó» tiene que verse ANTES que el texto de
   la corrección: repetir lo que ya falló es peor que no proponer nada, y sin esta línea la
   acción anterior se lee como la buena. */
.eficacia{margin-top:6px!important;font-size:11.5px!important;font-weight:650}
.eficacia.ok  {color:var(--nivel)!important}
.eficacia.malo{color:var(--oxido)!important}
.eficacia.mudo{color:var(--tinta-suave)!important;font-weight:600}

/* ── Guardián de la certificación ───────────────────────────────────────── */
/* Aquí vivían las dos columnas apiladas —`.columna-izquierda` y `.columna-derecha`— y el
   reparto del alto sobrante que intentaba que la última tarjeta de la derecha cerrara a la
   altura de la de la izquierda. Ya no hacen falta: las cuatro tarjetas están en una sola
   rejilla (ver `.abajo`) y cada fila iguala a sus dos. */

.guardia{display:flex;align-items:center;gap:10px;padding:11px 13px;
  border-radius:var(--radio-chico);margin:0 0 12px}
.guardia.para{background:var(--oxido-suave);border:1px solid var(--oxido)}
.guardia.ok  {background:var(--nivel-suave);border:1px solid var(--nivel)}
.guardia .disco3d{flex:none}
.guardia.para svg,.guardia.para b{color:var(--oxido)}
.guardia.ok svg,.guardia.ok b{color:var(--nivel)}
.guardia b{display:block;font-size:13px;font-weight:650;line-height:1.3}
.guardia i{display:block;font-style:normal;font-size:12px;color:var(--tinta-media);
  margin-top:2px;line-height:1.4}
.guardia ul{margin:6px 0 0;padding-left:17px}
.guardia li{font-size:12.5px;color:var(--tinta);line-height:1.45}

.reglas{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.reglas li{padding:9px 11px;border:1px solid var(--linea);border-radius:var(--radio-chico);
  background:var(--papel)}
.reglas b{display:block;font-size:12.5px;font-weight:650;color:var(--tinta);line-height:1.35}
/* Una regla sin condiciones aprueba cualquier cosa: es lo contrario de lo que promete. */
.reglas .floja{display:block;font-style:normal;font-size:11px;font-weight:650;
  color:var(--oxido);margin-top:3px}
.condiciones{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.condiciones span{font-size:10.5px;font-weight:600;color:var(--tinta-media);
  background:var(--papel-hondo);border-radius:6px;padding:3px 7px;line-height:1.3}

/* La retícula de plano que llevaba detrás del título se retiró con el rediseño: ahora la
   cabecera comparte fila con la barra de avance y el filtro, y un fondo texturado bajo una
   barra de progreso la vuelve difícil de leer. `.ruta-cabe` y `.ruta-sub` se definen ahora
   en el bloque de la Ruta 360, más abajo. */
/* ══════════════════════════════════════════════════════════════════════════
   LA RUTA 360 · el recorrido de control como una sola tubería horizontal
   ══════════════════════════════════════════════════════════════════════════
   Antes eran siete tarjetas altas, cada una con cuatro filas rotuladas —«Qué se
   cuenta», «Pendientes», «Próxima acción»— repetidas siete veces. Ocupaban media
   pantalla y obligaban a leer las veintiocho filas para contestar la única
   pregunta que trae a alguien aquí: dónde está parado esto y quién tiene que
   mover ficha.

   El rediseño cambia el reparto, no los datos. Cada etapa enseña de entrada seis
   cosas —estado, avance, responsable, lo que falta, plazo y qué hacer— y guarda
   el resto detrás de un panel que se abre. Los rótulos desaparecen: un icono y
   una posición fija dicen lo mismo sin gastar una línea.

   Y el estado NUNCA se confía solo al color: cada uno lleva su icono y su
   palabra. Un tablero que solo distingue por color deja fuera a quien no
   distingue el rojo del verde, que en obra civil no es una minoría teórica. */

/* ── Cabecera del módulo ─────────────────────────────────────────────────── */
.ruta-cabecera{display:flex;align-items:flex-end;gap:18px;flex-wrap:wrap;
  margin-bottom:14px}
.ruta-cabecera .titulos{flex:1 1 320px;min-width:0}
.ruta-cabe{margin:0 0 3px;font-size:24px;font-weight:700;letter-spacing:-.02em;
  color:var(--tinta)}
.ruta-sub{margin:0;font-size:13.5px;color:var(--tinta-media)}

/* El avance global. La cifra va junto a la barra y no debajo: es la lectura de un
   vistazo, y separarlas obliga a mirar dos sitios para una sola idea. */
.ruta-avance{flex:1 1 260px;min-width:220px}
.ruta-avance .canal{height:7px;border-radius:99px;background:var(--papel-hondo);
  overflow:hidden;margin-bottom:6px}
.ruta-avance .canal i{display:block;height:100%;border-radius:99px;
  background:var(--nivel);transition:width .4s ease}
.ruta-avance .cifra{font-size:12.5px;color:var(--tinta-media);
  font-variant-numeric:tabular-nums}
.ruta-avance .cifra b{color:var(--tinta);font-weight:650}

/* Filtro y acceso al detalle completo. */
/* `flex:none` la deja con su ancho natural, pero nunca más ancha que la fila: a 360 px el
   filtro y «Ver las siete» sumaban 342 px en 320 de hueco y la página entera se desplazaba
   de lado 2 px (medido al verificar el F08 de la QA del 11-sep-2026). Si no caben, el enlace
   baja a la línea siguiente; en escritorio caben y no cambia nada. */
.ruta-mandos{display:flex;align-items:center;gap:8px;flex:none;flex-wrap:wrap;max-width:100%}
.ruta-filtro{display:inline-flex;background:var(--papel-hondo);border-radius:99px;
  padding:3px}
.ruta-filtro button{background:none;border:0;font:inherit;font-size:12px;
  font-weight:600;color:var(--tinta-media);padding:6px 13px;min-height:32px;
  border-radius:99px;cursor:pointer;white-space:nowrap}
.ruta-filtro button[aria-pressed="true"]{background:var(--papel-alto);
  color:var(--tinta);box-shadow:var(--sombra)}
.ruta-filtro button:focus-visible{outline:2px solid var(--senal);outline-offset:1px}
/* Pasó de <a> a <button> al convertirse en un mando de verdad, y con eso empezó a heredar
   el botón de la casa —fondo marino, texto blanco, 12 px de relleno y borde—, que aquí lo
   habría convertido en una pastilla oscura junto a las tres del filtro. Se apaga TODO lo
   que aquella regla declara, no solo el fondo: es la misma trampa que ya se pagó con
   `.decision .accion`, donde redeclarar dos de diez propiedades dejó el resto heredado. */
.ruta-todo{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;
  font-weight:600;color:var(--azul);text-decoration:none;padding:7px 4px;
  min-height:32px;white-space:nowrap;
  background:none;border:0;border-radius:0;font-family:inherit;cursor:pointer;
  transition:none}
.ruta-todo:hover{text-decoration:underline;background:none}
.ruta-todo:active{transform:none}
.ruta-todo:focus-visible{outline:2px solid var(--senal);outline-offset:2px}

/* ── El carril ───────────────────────────────────────────────────────────── */
/* La línea que une las siete no es adorno: dice que son un recorrido y no siete
   cosas sueltas. Va DETRÁS de las tarjetas y a la altura de sus encabezados, y
   se tiñe hasta donde llega el avance real. */
/* ── El carril y su hilo de avance ────────────────────────────────────────────
   El hilo va en una BANDA PROPIA sobre las tarjetas, y por eso el carril reserva
   arriba el sitio donde vive.

   Estaba dibujado a 26 px del borde del carril, que es justo dentro de las tarjetas:
   ellas van en blanco y por encima, así que lo tapaban entero. Todo funcionaba —el
   hilo tenía su color, su transición y hasta el avance calculado en verde— y no se
   veía ni un píxel. Una línea invisible no es una línea a medias: es exactamente lo
   mismo que no tenerla, y no había forma de notarlo salvo mirando la pantalla. */
/* El margen inferior le hace sitio al ARCO DE RETORNO, que se dibuja 22 px por debajo del
   pie de las tarjetas y fuera de la caja del carril. Estaba en 12, que con los 9 de la
   línea de abajo daban 21: un píxel menos que la curva, y el trazo punteado cruzaba por
   encima del contador «7 etapas». */
.carril{position:relative;margin-bottom:22px;padding-top:30px}
.carril::before,.carril::after{content:"";position:absolute;top:13px;height:2px;
  pointer-events:none;z-index:0}
.carril::before{left:34px;right:34px;background:var(--linea)}
.carril::after{left:34px;width:var(--recorrido,0%);background:var(--nivel);
  transition:width .4s ease}

.etapas{display:grid;gap:9px;grid-template-columns:repeat(7,minmax(0,1fr));
  position:relative;z-index:1}

/* Por debajo de 1180 las siete no caben sin que el nombre se parta: el carril
   pasa a desplazarse en horizontal y aparecen los botones de avance. La rejilla
   deja de repartir y cada tarjeta toma un ancho mínimo legible. */
@media (max-width:1080px){
  .etapas{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
    scroll-behavior:smooth;padding-bottom:4px;
    scrollbar-width:none;-ms-overflow-style:none}
  .etapas::-webkit-scrollbar{display:none}
  .etapas>.etapa{flex:0 0 232px;scroll-snap-align:start}
  .carril::before,.carril::after{display:none}

  /* El hueco del disco pasa del carril a la CINTA, y no es un retoque de espaciado.
     ──────────────────────────────────────────────────────────────────────────────
     El disco vive fuera de su tarjeta, treinta píxeles por encima. En pantalla ancha
     eso da igual; aquí la cinta es un contenedor con desplazamiento horizontal, y
     `overflow-x:auto` obliga al eje vertical a valer `auto` también — de modo que
     recorta por ARRIBA. Medido en un móvil de 430: el borde de la cinta caía en 349 y
     el disco empezaba en 322, así que de sus 28 píxeles solo asomaba el último. Las
     siete cifras estaban invisibles en todos los teléfonos, que es justo donde más se
     usa esto, y no había nada roto que mirar: el número tenía su color, su sitio y su
     sombra, simplemente lo tapaba el recorte.
     El relleno cuenta como área desplazable, así que dentro de él el disco se ve. */
  .carril{padding-top:0}
  .etapas{padding-top:30px}

  /* El chevron entre tarjetas se cuelga 15 px FUERA de su caja. Con la rejilla ancha
     eso cae en el hueco entre columnas; en la cinta que se desplaza, el de la última
     tarjeta visible sobresale por la derecha del carril y recorta la tarjeta (medido a
     375 px: 205 de contenido en 188 de caja). Aquí las tarjetas ya se separan con el
     desplazamiento, así que la flecha sobra además de estorbar. */
  .etapa:not(:last-child)::after{display:none}
}

/* ── Que la Ruta 360 quepa en un teléfono (24-sep-2026) ────────────────────
   Tres desbordes distintos y la misma pinta: el borde derecho de la tarjeta comido.
   Los tres son adornos colocados fuera de su caja o filas que no envuelven, y ninguno
   asomaba en el desplazamiento de la página, así que solo se ven midiendo cada
   contenedor por dentro. */
@media (max-width:640px){
  /* El grupo de filtros no envolvía: «Todas · Con alertas · …» medía 299 px en una caja
     de 285 y empujaba a toda la cabecera. */
  .ruta-filtro{flex-wrap:wrap;max-width:100%}
  .ruta-tarjeta .ruta-filtro{row-gap:8px}
}

/* Los botones de avance solo existen cuando hacen falta, y se colocan encima del
   carril sin robarle ancho. */
.carril-mando{position:absolute;top:50%;margin-top:-18px;width:36px;height:36px;
  border-radius:99px;border:1px solid var(--linea);background:var(--papel-alto);
  color:var(--tinta);display:none;place-items:center;cursor:pointer;
  box-shadow:0 2px 10px rgba(22,35,58,.14);z-index:3}
.carril-mando:focus-visible{outline:2px solid var(--senal);outline-offset:2px}
.carril-mando[disabled]{opacity:.35;cursor:default}
.carril-mando.izq{left:-14px}
.carril-mando.der{right:-14px}
@media (max-width:1080px){.carril-mando{display:grid}}

/* Los botones de avance se cuelgan 14 px FUERA del carril a cada lado. En pantalla ancha
   caen en el margen; en un teléfono se salen y arrastran el ancho del carril entero (299
   en una caja de 285, medido a 375). Se meten dentro y se apoyan sobre la cinta, que es
   donde el pulgar los busca.
   Va aquí, DESPUÉS de `.carril-mando.izq/.der`, y no con el resto de los arreglos de
   teléfono más arriba: misma especificidad, así que el que decide es el orden. Puesto
   antes, el navegador seguía aplicando los -14 px y la medición salía idéntica al defecto
   —sin error, sin aviso y con la regla escrita en el fichero—. */
/* En un teléfono los botones de avance sobran, y encima estorban.
   ─────────────────────────────────────────────────────────────────────────
   Colgados fuera del carril se salían de la pantalla; metidos dentro quedan ENCIMA de la
   primera y la última tarjeta, tapando justo el nombre de la etapa y su sello de estado
   (visto en el aparato el 24-sep-2026). No hay sitio para ellos: a 384 px el carril mide
   lo que una tarjeta y media.
   La cinta ya se desliza con el dedo y la siguiente tarjeta asoma por el borde, que es
   como se dice «hay más» sin ocupar nada. Se conservan de 641 px en adelante, donde hay
   ratón y margen a los lados. La condición es el ancho y no `pointer:coarse` porque el
   ancho se puede medir aquí y el tipo de puntero no. */
@media (max-width:640px){
  .carril-mando{display:none}
}

/* ── La tarjeta de etapa ─────────────────────────────────────────────────── */
/* La tarjeta se DESPEGA del papel, y en tres peldaños.
   ───────────────────────────────────────────────────
   La sombra común de la casa —`--sombra`, dos capas al 5% y al 6%— está pensada
   para una tabla sobre fondo blanco, donde apenas hace falta insinuar el borde.
   Sobre el papel crema y a tamaño real no se ve: las siete tarjetas quedaban
   pegadas al fondo y la elegida se distinguía solo por el filo oscuro, que es
   justamente lo que no se mira cuando se recorre la tira de un vistazo.
   Aquí la altura es información —cuál está viva, cuál se está señalando, cuál
   se eligió— así que cada estado tiene su propia sombra, y se nota.

   No se toca `--sombra`: la usan las diecisiete pantallas, y subirla ahí
   cambiaría el peso visual de toda la plataforma para arreglar una. */
.etapa{position:relative;background:var(--papel-alto);border:1px solid var(--linea);
  border-radius:var(--radio);
  box-shadow:0 1px 2px rgba(22,35,58,.06),0 3px 10px rgba(22,35,58,.07);
  display:flex;flex-direction:column;min-width:0;text-align:left;
  font:inherit;color:inherit;padding:0;cursor:pointer;
  transition:opacity .18s ease,border-color .18s ease,box-shadow .18s ease,
             transform .18s ease}
.etapa:focus-visible{outline:2px solid var(--senal);outline-offset:2px}
.etapa:hover{transform:translateY(-2px);
  box-shadow:0 4px 10px rgba(22,35,58,.08),0 12px 24px rgba(22,35,58,.10)}

/* Al elegir una, las demás se atenúan LIGERAMENTE: bajar más las apagaría, y el
   sentido de la tira es poder comparar la elegida con las otras seis.
   Estaba en .62, que de ligero no tenía nada: las seis quedaban lavadas y con ellas
   la tira entera, que es justo lo que le quitaba cuerpo a la pantalla. Ahora que la
   elegida se distingue además por altura —sombra larga y cuatro píxeles arriba—, la
   atenuación no tiene que hacer sola todo el trabajo y puede ser de verdad suave. */
.carril.hay-elegida .etapa{opacity:.78}
.carril.hay-elegida .etapa.elegida{opacity:1}
.etapa.elegida,.etapa.elegida:hover{border-color:var(--tinta);
  transform:translateY(-4px);
  box-shadow:0 6px 14px rgba(22,35,58,.10),0 18px 36px rgba(22,35,58,.15)}

/* La etapa que un filtro deja fuera se retira del carril, no se apaga: una
   tarjeta apagada sigue ocupando sitio y se sigue intentando leer. */
.etapa[hidden]{display:none!important}

/* Nivel 1 · encabezado compacto: número, icono, nombre y estado */
/* El nombre NO se recorta con puntos suspensivos: envuelve. Medido en una pantalla de
   1440 —de las más comunes— el carril mide 1137 px porque la barra lateral se lleva 248,
   y a 155 px por tarjeta «Inspeccionar» se quedaba en «Inspecci…». Un recorte en el
   nombre de la etapa es el peor sitio donde ahorrar: es lo primero que se busca.
   El encabezado lleva alto mínimo de dos líneas para que las siete queden alineadas
   aunque solo una necesite la segunda. */
.etapa-cabe{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:7px;
  padding:10px 10px 7px;min-height:52px}

/* El número sube a la banda del hilo, centrado sobre su tarjeta: es el punto de esa
   etapa en el recorrido, no una viñeta del encabezado. Es un DISCO MACIZO del color
   de su estado, con el dígito en blanco y un halo del color del papel para que el
   hilo pase por detrás sin cruzarle la cifra.

   El halo es `border` y no un anillo de `box-shadow`, y la diferencia importa: las
   sombras se apilan en orden, la primera delante, así que un anillo opaco de 4 px
   declarado antes que la sombra difusa se la come casi entera y el disco vuelve a
   verse plano. Con `border` la sombra se proyecta desde el filo exterior y el disco
   queda de verdad levantado sobre el hilo.

   Antes eran discos de tono pastel con la cifra en color. Se veían limpios y
   decían menos: a tamaño real, siete pastillas claras sobre papel crema se leen
   como adorno del encabezado y no como los mojones de un recorrido. */
.etapa-n{position:absolute;top:-30px;left:50%;transform:translateX(-50%);
  width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  font-size:12px;font-weight:700;line-height:1;z-index:2;
  background:var(--tinta-media);color:#fff;
  border:4px solid var(--papel);
  box-shadow:0 3px 7px rgba(22,35,58,.26);
  transition:background .18s ease,box-shadow .18s ease,transform .18s ease}

/* La elegida no cambia de color —su estado se sigue leyendo— sino que se acerca:
   crece un punto, gana el aro marino y proyecta más sombra. Cambiarle el relleno a
   marino, como en la maqueta, la marcaría igual de bien pero borraría el estado
   justo en la etapa que se está mirando. */
.etapa.elegida .etapa-n{transform:translateX(-50%) scale(1.14);
  box-shadow:0 0 0 2px var(--tinta),0 4px 10px rgba(22,35,58,.30)}
.etapa-icono{flex:none;color:var(--tinta-suave);display:grid;place-items:center}
.etapa-cabe h3{margin:0;font-size:13.5px;font-weight:650;letter-spacing:-.015em;
  line-height:1.2;min-width:0;overflow-wrap:anywhere}

/* El estado, con su icono y su palabra. Envuelve por la misma razón que el nombre:
   «Alcance incompleto» y «Trabajo detenido» no caben en una línea a este ancho. */
.sello{display:flex;align-items:flex-start;gap:5px;margin:0 10px 9px;font-size:11px;
  font-weight:650;padding:4px 9px;border-radius:11px;width:fit-content;
  max-width:calc(100% - 20px);line-height:1.3}
.sello span{min-width:0;overflow-wrap:anywhere}
.sello svg{flex:none;margin-top:1px}

/* Los cinco estados. Cada uno tiñe el número, el icono y el filo de la tarjeta,
   siempre acompañados de su propio icono dentro del sello. */
/* El relleno del disco. Sobre blanco, el verde da 5,1 de contraste, el óxido 5,4 y
   el azul 6,9 — todos por encima del 4,5 que pide una cifra de 12 px.
   El ámbar del logotipo NO: `--senal` sobre blanco da 2,7 y el dígito se pierde a
   pleno sol, que es donde se usa esto. Por eso el estado de espera se rellena con
   el ámbar oscuro que la hoja ya usa para su texto (5,5), no con el de la marca.
   Misma razón para el estado mudo: `--tinta-suave` da 3,1, así que el disco sin
   estado se rellena con `--tinta-media`, que da 7,0 y a un metro se ve igual de gris. */
.etapa.ok     .etapa-n{background:var(--nivel)}
.etapa.para   .etapa-n{background:var(--oxido)}
.etapa.espera .etapa-n{background:#8A6224}
.etapa.curso  .etapa-n{background:var(--azul)}
.etapa.ok      .etapa-icono{color:var(--nivel)}
.etapa.para    .etapa-icono{color:var(--oxido)}
.etapa.espera  .etapa-icono{color:#8A6224}
.etapa.curso   .etapa-icono{color:var(--azul)}
/* El filo va del MISMO tono que el disco y el icono de su estado. El de espera se había
   quedado con `--senal`, el ámbar del logotipo, mientras el disco, el icono, el sello y el
   botón usaban el ámbar oscuro: la tarjeta llevaba dos códigos de color a la vez y era la
   única de las cinco que lo hacía. Aquí no es cuestión de contraste —un filo de 3 px no
   lleva texto— sino de que un estado se diga con un color, no con dos. */
.etapa.ok    {border-top:3px solid var(--nivel)}
.etapa.para  {border-top:3px solid var(--oxido)}
.etapa.espera{border-top:3px solid #8A6224}
.etapa.curso {border-top:3px solid var(--azul)}
.etapa.mudo  {border-top:3px solid var(--linea)}

.sello.ok    {background:var(--nivel-suave);color:var(--nivel)}
.sello.para  {background:var(--oxido-suave);color:var(--oxido)}
.sello.espera{background:var(--senal-suave);color:#8A6224}
.sello.curso {background:var(--azul-suave);color:var(--azul)}
.sello.mudo  {background:var(--papel-hondo);color:var(--tinta-suave)}

/* Nivel 2 · el resumen. Sin rótulos: la posición y el icono los sustituyen. */
.etapa-resumen{padding:0 11px 10px;display:flex;flex-direction:column;gap:7px;
  flex:1}
/* Ojo con los nombres: comun.css ya tiene `.barra` —la franja de acciones FIJA al pie de
   la ventana, con position:fixed y z-index:20— y `.dato` —texto monoespaciado—. Llamar
   igual a estas dos costó el defecto que se vio en pantalla: la barra de avance de la
   tarjeta heredaba el position:fixed que aquí no se redeclara, se anclaba al fondo de la
   ventana y tapaba el botón de la etapa. Ninguna medida lo delataba: la tarjeta no
   desbordaba, el botón estaba en su sitio y con su texto, y las pruebas seguían verdes;
   solo se veía MIRANDO la pantalla. De ahí el prefijo: estas piezas son de la etapa. */
.etapa-barra{display:flex;align-items:center;gap:7px}
.etapa-barra .canal{flex:1;height:5px;border-radius:99px;background:var(--papel-hondo);
  overflow:hidden}
.etapa-barra .canal i{display:block;height:100%;border-radius:99px;background:var(--azul)}
.etapa-barra .canal i.ok{background:var(--nivel)}
.etapa-barra .canal i.para{background:var(--oxido)}
.etapa-barra em{font-style:normal;font-size:11px;font-weight:700;color:var(--tinta);
  font-variant-numeric:tabular-nums;flex:none}

.etapa-dato{display:flex;align-items:flex-start;gap:6px;font-size:11.5px;
  color:var(--tinta-media);line-height:1.35;min-width:0}
.etapa-dato svg{flex:none;margin-top:1px;color:var(--tinta-suave)}
.etapa-dato span{min-width:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical}
.etapa-dato.alerta{color:var(--oxido);font-weight:600}
.etapa-dato.alerta svg{color:var(--oxido)}
.etapa-dato.mudo,.etapa-dato.mudo svg{color:var(--tinta-suave)}

/* Nivel 3 · la acción. Dice lo que se va a hacer, no «ver detalle». */
.etapa-pie{margin-top:auto;padding:9px 11px;border-top:1px solid var(--linea);
  display:flex;flex-direction:column;gap:6px}
.accion{display:flex;align-items:center;justify-content:center;gap:6px;
  min-height:34px;padding:7px 10px;border-radius:9px;text-decoration:none;
  font-size:12px;font-weight:650;background:var(--tinta);color:#fff;
  text-align:center;line-height:1.25}
.accion:hover{background:#20304D}
.etapa.para  .accion{background:var(--oxido)}
.etapa.ok    .accion{background:var(--nivel)}
.etapa.espera .accion{background:#A87A2E}
.etapa.mudo  .accion{background:var(--tinta-suave)}
.accion:focus-visible{outline:2px solid var(--senal);outline-offset:2px}
.accion svg{flex:none}

.mas{background:none;border:0;font:inherit;font-size:11.5px;font-weight:600;
  color:var(--tinta-media);cursor:pointer;padding:4px;min-height:28px;
  display:flex;align-items:center;justify-content:center;gap:5px;border-radius:7px}
.mas:hover{background:var(--papel-hondo);color:var(--tinta)}
.mas:focus-visible{outline:2px solid var(--senal);outline-offset:1px}
.mas svg{transition:transform .15s ease}
.mas[aria-expanded="true"] svg{transform:rotate(180deg)}

/* El panel expandible, dentro de la propia tarjeta. */
.etapa-mas{padding:0 11px 11px;font-size:11.5px;color:var(--tinta-media);
  line-height:1.45;border-top:1px dashed var(--linea);margin:0 0 0}
.etapa-mas dl{margin:9px 0 0;display:grid;grid-template-columns:auto 1fr;
  gap:4px 9px}
.etapa-mas dt{color:var(--tinta-suave);white-space:nowrap}
.etapa-mas dd{margin:0;color:var(--tinta)}

/* El contador «4 de 7», siempre visible: al desplazar el carril dice dónde se
   está sin tener que contar tarjetas. */
.carril-cuenta{display:flex;align-items:center;justify-content:center;gap:5px;
  margin-top:9px;font-size:12px;color:var(--tinta-media);
  font-variant-numeric:tabular-nums}
.carril-cuenta b{color:var(--tinta);font-weight:650}

/* ── El detalle de la etapa elegida ──────────────────────────────────────── */
/* Va debajo del carril y no en un lateral: en una pantalla de obra el ancho es
   lo escaso, y un panel lateral estrecharía las siete tarjetas justo cuando se
   está comparando entre ellas. */
.detalle-etapa{background:var(--papel-alto);border:1px solid var(--linea);
  border-left:4px solid var(--tinta);border-radius:var(--radio);
  box-shadow:var(--relieve);padding:14px 16px;margin-bottom:13px}
.detalle-etapa.para  {border-left-color:var(--oxido)}
.detalle-etapa.ok    {border-left-color:var(--nivel)}
.detalle-etapa.espera{border-left-color:var(--senal)}
.detalle-etapa.curso {border-left-color:var(--azul)}
.detalle-etapa h4{margin:0 0 3px;font-size:15px;font-weight:650;
  display:flex;align-items:center;gap:8px}
.detalle-etapa .cerrar{margin-left:auto;background:none;border:0;cursor:pointer;
  color:var(--tinta-suave);padding:4px;border-radius:7px;min-height:28px;
  min-width:28px;display:grid;place-items:center}
.detalle-etapa .cerrar:hover{background:var(--papel-hondo);color:var(--tinta)}
.detalle-etapa .cerrar:focus-visible{outline:2px solid var(--senal)}
.detalle-rejilla{display:grid;grid-template-columns:repeat(auto-fit,minmax(178px,1fr));
  gap:11px;margin-top:11px}
.detalle-rejilla > div{min-width:0}
.detalle-rejilla dt{font-size:11px;color:var(--tinta-suave);margin-bottom:2px;
  display:flex;align-items:center;gap:5px}
.detalle-rejilla dd{margin:0;font-size:13px;color:var(--tinta);line-height:1.4}
.detalle-rejilla dd.alerta{color:var(--oxido);font-weight:650}

/* ── El retorno de la 5 a la 4 ───────────────────────────────────────────── */
/* Escrito Y dibujado. La flecha curva sale del encabezado de la 5 y vuelve al de
   la 4; el texto se queda porque en una rejilla que se recoloca según el ancho
   —o que se desplaza en horizontal— una flecha acaba apuntando a donde no debe,
   y entonces solo queda la frase para decirlo. */
.arco-retorno{position:absolute;top:0;left:0;width:100%;height:100%;
  pointer-events:none;z-index:2;overflow:visible}
@media (max-width:1080px){.arco-retorno{display:none}}

.retorno{margin:0 0 4px;display:flex;align-items:flex-start;gap:11px;
  background:var(--oxido-suave);border:1px dashed var(--oxido);
  border-radius:var(--radio);padding:10px 14px}
.retorno svg{flex:none;margin-top:1px}
.retorno p{margin:0;font-size:12.5px;line-height:1.5;color:var(--tinta)}
.retorno b{color:var(--oxido)}

/* ── Las dos tablas de abajo ────────────────────────────────────────────── */
/* Una rejilla de dos columnas para las cuatro tarjetas, y el cuadro por nivel a lo ancho.
   Antes eran dos columnas apiladas por separado —dos en la izquierda, tres en la derecha—:
   cada una crecía por su cuenta y las tarjetas de una misma fila empezaban y terminaban en
   alturas distintas, que es lo que se veía torcido. En rejilla, las dos de una fila miden
   igual porque la fila las iguala. */
.abajo{display:grid;gap:16px;grid-template-columns:1.25fr 1fr;align-items:stretch;margin-top:22px}
.abajo > .panel-ancho{grid-column:1 / -1}
@media (max-width:1100px){.abajo{grid-template-columns:1fr}}

/* Lo vacío se centra en el hueco de la tarjeta, que es lo que iguala las dos de una fila:
   una tarjeta alta con su aviso pegado arriba y un palmo de fondo debajo se lee como un
   error de maquetación. Solo cuando el cuerpo es un aviso de vacío; con filas, manda la
   lista. */
.abajo > .panel > div:has(> .vacio-panel){flex:1;display:flex;flex-direction:column;
  justify-content:center}

/* El pie se apoya en el fondo: así los enlaces de las dos tarjetas de una fila quedan a la
   misma altura en vez de donde acabe el contenido de cada una. */
.abajo > .panel > .pie-panel{margin:auto 0 0;padding-top:12px}
.pie-con-enlace{display:flex;align-items:center;justify-content:space-between;gap:10px;
  flex-wrap:wrap}
.pie-con-enlace span:empty{display:none}

/* La lista de decisiones esconde su buscador y su cabecera cuando no hay ni una fila: un
   buscador sobre una tabla vacía y cinco rótulos de columna sin nada debajo son el ruido
   que hacía parecer rota la pantalla. `display` de la clase gana al atributo `hidden`, así
   que hay que decirlo. */
.mando-decisiones[hidden],.cabe-decision[hidden]{display:none}

/* El panel se declara contenedor para que lo que lleva dentro pueda medirse contra ÉL y
   no contra la ventana. La fila de decisiones se plegaba con `@media (max-width:900px)`,
   que mira el navegador — pero este panel vive en la columna ancha de una rejilla de dos,
   así que en una ventana de 1500 px él solo tiene 680. Cinco columnas ahí dejaban el
   asunto en 124 px y la cadena de trazabilidad partida en cuatro renglones, con la media
   consulta convencida de que había sitio de sobra. */
.panel{background:var(--papel-alto);border:1px solid var(--linea);
  border-radius:var(--radio);box-shadow:var(--relieve);padding:16px 18px 14px;
  container-type:inline-size;
  /* Columna flex para que la botonera de páginas pueda apoyarse en el fondo con
     `margin-top:auto`. Sin esto el hueco sobrante caía DEBAJO de ella. */
  display:flex;flex-direction:column}
.panel h2{margin:0 0 2px;font-size:16px;font-weight:650;letter-spacing:-.01em;
  display:flex;align-items:center;gap:8px}
.panel .pie-panel{margin:12px 0 0;font-size:12.5px}

/* El enlace del pie de un panel va SOLO en su bloque: es un botón de «llévame allí», no una
   palabra dentro de una frase, así que la excepción de WCAG 2.2 para enlaces en línea no le
   aplica y tiene que llegar a los 24 px de alto. Medía 16.
   La misma cuenta que ya hizo comun.css con las casillas; aquí se había quedado fuera. */
.panel .pie-panel a,
.mapa-calor .pie-panel a{color:var(--azul);text-decoration:none;font-weight:600;
  display:inline-flex;align-items:center;min-height:24px}
.panel .pie-panel a:hover,
.mapa-calor .pie-panel a:hover{text-decoration:underline}

/* ── Decisiones que requieren atención ──────────────────────────────────── */
/* ── Buscar y ordenar ───────────────────────────────────────────────────────── */
.mando-decisiones{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:0 0 10px}
.buscar-decision{flex:1 1 260px;display:flex;align-items:center;gap:8px;min-width:0;
  padding:8px 12px;background:var(--papel-alto);border:1px solid var(--linea);
  border-radius:99px;color:var(--tinta-suave)}
.buscar-decision:focus-within{border-color:var(--tinta);color:var(--tinta-media)}
.buscar-decision svg{flex:none}
.buscar-decision input{flex:1;min-width:0;border:0;background:none;font:inherit;
  font-size:13px;color:var(--tinta);outline:none}
.buscar-decision input::placeholder{color:var(--tinta-suave)}
.orden-decision{display:flex;align-items:center;gap:7px;font-size:12px;
  color:var(--tinta-media);white-space:nowrap}
.orden-decision select{font:inherit;font-size:12.5px;padding:7px 10px;border-radius:9px;
  border:1px solid var(--linea);background:var(--papel-alto);color:var(--tinta)}

/* El plazo. Vencido se tiñe: es la única columna que dice si algo ya llega tarde, y
   leerla exige poder distinguirlo sin comparar fechas mentalmente. */
.plazo{font-size:12px;color:var(--tinta-media);line-height:1.35}
.plazo.vencido{color:var(--oxido);font-weight:650}

/* ── Páginas ────────────────────────────────────────────────────────────────── */
/* La botonera se apoya en el FONDO de la tarjeta, no flota detrás del último registro.
   El panel de decisiones se estira hasta el alto de la columna de al lado —941 px medidos—
   pero la lista solo ocupa lo que ocupan sus filas, así que la barra quedaba a media
   tarjeta con 234 px de vacío DEBAJO. El hueco existe igual; lo que cambia es de qué lado
   de la barra cae, y debajo no sirve a nadie: deja el control flotando y la tarjeta con el
   fondo desocupado.
   `margin-top:auto` en una columna flex la empuja al suelo. Cuando la lista es larga y
   llena la tarjeta no sobra nada que repartir y la regla no hace nada, que es lo correcto. */
.paginas{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;padding:12px 0 2px;border-top:1px solid var(--linea);margin-top:auto}
.paginas:empty{display:none}
.cuenta-paginas{font-size:12px;color:var(--tinta-media)}
.botones-pagina{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.botones-pagina button{min-width:32px;min-height:32px;padding:0 9px;font:inherit;
  font-size:12.5px;border-radius:8px;border:1px solid var(--linea);
  background:var(--papel-alto);color:var(--tinta-media);cursor:pointer}
.botones-pagina button:hover:not([disabled]){border-color:var(--tinta);color:var(--tinta)}
.botones-pagina button:focus-visible{outline:2px solid var(--senal);outline-offset:2px}
.botones-pagina button[disabled]{opacity:.4;cursor:default}
/* La página en la que uno está se rellena, no solo se marca con el borde: en una fila de
   ocho números iguales, un borde un tono más oscuro no se encuentra. */
.botones-pagina button.aqui{background:var(--tinta);border-color:var(--tinta);color:#fff;
  font-weight:650}
.botones-pagina .salto{padding:0 2px;color:var(--tinta-suave);font-size:12.5px}

/* La acción lleva ancho ACOTADO y no `auto`. Con `auto` la columna se lleva el ancho que
   pida su contenido —«Atender la no conformidad» más la nota— y el `1fr` del asunto se
   queda con las migajas: los títulos se partían letra a letra en una columna de dos
   dedos. La rejilla no avisa de eso; reparte lo que hay y sigue. */
/* La última columna crece con el botón más largo en vez de quedarse en 150 px fijos.
   Con el ancho fijo, «Atender la no conformidad» medía 183 px —el enlace lleva
   `white-space:nowrap`— y se salía 33 px de su celda, por encima de lo que hubiera a la
   derecha; los otros dos rótulos (122 px y 116 px) sí cabían, así que los tres botones
   quedaban además de anchos distintos y sin alinear entre filas. `max-content` toma la
   medida del rótulo más ancho de la tabla y la aplica a todas las filas: nadie desborda y
   la columna queda a plomo. El mínimo de 150 px se conserva para que con rótulos cortos la
   columna no se estreche y la nota de debajo no se parta en tres líneas. */
/* CORRECCIÓN al párrafo de arriba: `max-content` era demasiado. La celda de acción no
   contiene solo el rótulo del botón — debajo lleva la nota de a quién le toca, y el
   `max-content` de la celda es esa FRASE sin partir, no el botón: 254 px en vez de los
   ~190 que pide el rótulo más ancho. Con 680 px de fila, esos 254 dejaban la columna del
   asunto en 70 px, y ahí la cadena de trazabilidad se apilaba en cuatro renglones de
   192 px de alto con los códigos recortados. El botón dejó de desbordar y el desborde se
   mudó al vecino.
   200 px es el rótulo más ancho medido —«Atender la no conformidad», 183 px— con su aire;
   la nota de debajo se parte en dos líneas, que es lo suyo, y el asunto recupera su sitio. */
.decision,.cabe-decision{display:grid;
  grid-template-columns:100px minmax(0,1fr) 116px 92px 200px;gap:12px;
  padding:13px 0;border-bottom:1px solid var(--linea);align-items:start}
.decision:last-of-type{border-bottom:0}
.cabe-decision{padding:6px 0 7px;font-size:10.5px;font-weight:700;color:var(--tinta-suave);
  text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--linea)}
.cabe-decision span:last-child{text-align:right}
/* Se pliega por el ancho DEL PANEL, no por el de la ventana. Con la media consulta, en un
   portátil de 1500 px el panel tenía 680 y seguía repartiendo cinco columnas: cabían de
   ancho pero no de contenido. El umbral es 780 px porque por debajo de eso el asunto baja
   de 200 y la cadena deja de leerse de corrido — medido, no elegido de memoria.
   La media consulta se conserva de respaldo para el navegador que no entienda
   `container-type`: hace lo de antes, que era razonable, en vez de nada. */
/* La lista guarda el alto de una página llena para que la botonera no se mueva al pasar
   de página. El valor lo mide el guion —`reservarAlto`, en panel.js— porque depende de
   cuánto ocupe cada asunto; aquí solo se decide si se usa. */
#decisiones{min-height:var(--alto-lista,0)}

@container (max-width:780px){.cabe-decision{display:none}
  .decision{grid-template-columns:1fr;gap:8px}
  /* En el panel estrecho la reserva se apaga: ahí las filas se apilan y una página llena
     mide media pantalla, así que guardar ese hueco para la última página sería dejar el
     móvil en blanco por debajo del único registro. */
  #decisiones{min-height:0}}
@supports not (container-type:inline-size){
  @media (max-width:900px){.cabe-decision{display:none}
    .decision{grid-template-columns:1fr;gap:8px}}}

/* Quien pide la decision. No es decorativo: no es lo mismo que la pare el sistema
   por una regla que que la pare una persona esperando una firma. */
.origen{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--tinta-media);
  min-width:0;padding-top:2px}
.origen svg{flex:none;color:var(--tinta-suave)}
.origen span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.prioridad{display:flex;align-items:center;gap:7px;font-size:10.5px;font-weight:700;
  letter-spacing:.03em;padding:4px 8px;border-radius:6px;width:fit-content}
.prioridad.critica{background:var(--oxido-suave);color:var(--oxido)}
.prioridad.espera{background:var(--senal-suave);color:#8A6224}
.prioridad.revision{background:var(--azul-suave);color:var(--azul)}

.decision .asunto{min-width:0}
.decision .asunto b{display:block;font-size:13.5px;font-weight:650;color:var(--tinta);
  line-height:1.35}
.decision .asunto i{display:block;font-style:normal;font-size:12.5px;
  color:var(--tinta-media);margin-top:2px;line-height:1.35}

/* ── SIGNATURE: la cadena de trazabilidad, que enseña dónde se rompe ─────────
   De qué cuelga cada decisión: elemento → inspección → hallazgo → certificado.
   Es literalmente el §85, y es una SECUENCIA: cada eslabón cuelga del anterior.

   Se dibujaba como cuatro cajas sueltas del mismo tamaño, apiladas y con la
   etiqueta encima del código. Eso perdía lo único que el nombre promete —el
   orden— y daba al eslabón que falta el mismo peso visual que al que existe:
   «CERTIFICADO —» ocupaba tanto como «NCR-DO-2026-000007». Medido en la celda
   estrecha: 192 px de alto por fila, cuatro renglones, códigos recortados.

   Ahora se lee de corrido, como una cadena: rótulo pequeño, código en mono, y
   un eslabón dibujado entre uno y otro. Lo que falta no desaparece —que un
   hallazgo NO tenga ensayo es un dato, y esconderlo haría creer que sí lo
   tiene— pero pesa lo que debe: se apaga y el enlace que lo precede se ABRE,
   así que la cadena se ve interrumpida justo donde está rota. Esa apertura es
   el gesto: nadie tiene que leer cuatro cajas para saber que falta el
   certificado, se ve en la línea. ──────────────────────────────────────────── */
.cadena{display:flex;flex-wrap:wrap;align-items:baseline;
  column-gap:0;row-gap:5px;margin-top:7px}

.eslabon{display:inline-flex;align-items:baseline;gap:5px;min-width:0}

/* El enlace entre eslabones. Va en el ::before del siguiente y no en el ::after
   del anterior para que al partirse la línea el gancho baje CON su eslabón en
   vez de quedarse colgando al final del renglón de arriba. */
.eslabon + .eslabon::before{content:"";width:13px;height:1px;flex:none;
  background:var(--linea);margin:0 7px;align-self:center}

.eslabon u{text-decoration:none;font-size:9.5px;font-weight:700;
  color:var(--tinta-suave);text-transform:uppercase;letter-spacing:.05em}
.eslabon s{text-decoration:none;font-size:11.5px;font-weight:600;
  color:var(--tinta);font-family:var(--mono);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}

/* El eslabón que falta. Se llama `roto` y NO `vacio` a propósito: `.vacio` es la
   clase del estado vacío de la casa —vive en comun.css con relleno de 24 px,
   texto centrado y 14 px de cuerpo— y al compartir nombre estos eslabones la
   heredaban en silencio: los que faltaban salían centrados y con otro cuerpo
   que los que existían. Un eslabón que falta no es una pantalla vacía. */
.eslabon.roto u,.eslabon.roto s{color:var(--tinta-suave);font-weight:600}
.eslabon.roto + .eslabon::before,.eslabon.roto::before{background:transparent;
  border-top:1px dashed var(--linea)}

.eslabon.marcado s{color:var(--oxido)}

/* La celda de acción de una decisión NO es el botón de una etapa, aunque compartan
   nombre. `.accion` de la Ruta 360 es un botón: flex centrado, fondo marino, relleno y
   alto mínimo. Aquí es solo el hueco que contiene un enlace y una nota debajo, y lo que
   no se redeclare se hereda — la celda salía pintada de marino, con el enlace y la nota
   metidos dentro en fila. Se apaga lo heredado explícitamente en vez de renombrar la
   clase, que obligaría a tocar el guion; y se apaga TODO lo que el botón declara, no
   solo lo que a primera vista molesta. */
.decision .accion{display:block;background:none;padding:0;min-height:0;border-radius:0;
  text-align:right;min-width:0;font-weight:400;line-height:1.4}
/* Todos los botones miden lo mismo y su rótulo va centrado. Se dimensionaban por su
   texto, así que los tres salían distintos —«Atender la no conformidad» 183 px,
   «Revisar y decidir» 122, «Resolver el lote» 116— y alineados a la derecha: tres
   bordes izquierdos en tres sitios distintos, uno debajo de otro. En una tabla de
   decisiones eso se lee como si unas acciones pesaran más que otras, y no es así: la
   importancia la dice la prioridad de la fila, no el largo del rótulo.
   Ocupan la columna entera —200 px, fijados para el rótulo más ancho— y el texto se
   centra dentro. La columna queda a plomo y los botones son un blanco más grande, que
   en una pantalla que se usa con prisa no sobra. */
.decision .accion a{display:block;background:var(--tinta);color:#fff;
  text-decoration:none;font-size:12.5px;font-weight:600;padding:8px 14px;
  border-radius:8px;white-space:nowrap;text-align:center}
.decision .accion a.urge{background:var(--oxido)}
.decision .accion a:hover,.decision .accion a:focus-visible{opacity:.9}
/* La nota se centra con su botón. Alineada a la derecha bajo un botón centrado quedaba
   descolgada: dos ejes distintos en una celda de 200 px. */
.decision .accion small{display:block;margin-top:5px;font-size:11px;
  color:var(--tinta-suave);text-align:center}
@media (max-width:760px){.decision .accion{text-align:left}}

/* ── Próximos hitos ─────────────────────────────────────────────────────── */
.hito{display:grid;grid-template-columns:46px 1fr auto auto;gap:12px;padding:12px 0;
  border-bottom:1px solid var(--linea);align-items:center}
.hito:last-of-type{border-bottom:0}
.hito .fecha{text-align:center}
.hito .fecha b{display:block;font-size:19px;font-weight:700;color:var(--tinta);
  line-height:1;font-variant-numeric:tabular-nums}
.hito .fecha i{display:block;font-style:normal;font-size:10px;font-weight:700;
  color:var(--tinta-suave);text-transform:uppercase;letter-spacing:.05em;margin-top:2px}
.hito.vencido .fecha b,.hito.vencido .fecha i{color:var(--oxido)}
.hito .que{min-width:0}
.hito .que b{display:block;font-size:13px;font-weight:650;color:var(--tinta);
  line-height:1.35}
.hito .que i{display:block;font-style:normal;font-size:12px;color:var(--tinta-media);
  margin-top:2px;line-height:1.35}
.hito .quien{font-size:11.5px;color:var(--tinta-media);text-align:right;min-width:0;
  max-width:110px}
.hito .quien u{display:block;text-decoration:none;font-size:9.5px;font-weight:700;
  color:var(--tinta-suave);text-transform:uppercase;letter-spacing:.04em}
.hito .marca-hito{font-size:11px;font-weight:650;padding:4px 9px;border-radius:99px;
  white-space:nowrap}
@media (max-width:520px){.hito{grid-template-columns:46px 1fr auto}.hito .quien{display:none}}
.hito .marca-hito.para{background:var(--oxido-suave);color:var(--oxido)}
.hito .marca-hito.espera{background:var(--senal-suave);color:#8A6224}
.hito .marca-hito.curso{background:var(--azul-suave);color:var(--azul)}

.vacio-panel{padding:22px 0;text-align:center;font-size:13px;color:var(--tinta-suave)}

/* ── Pie ────────────────────────────────────────────────────────────────── */
.pie-ruta{display:flex;align-items:center;justify-content:center;gap:10px;
  flex-wrap:wrap;margin:24px 0 0;padding:14px 0;border-top:1px solid var(--linea);
  font-size:12.5px;color:var(--tinta-suave)}
.pie-ruta svg{color:var(--tinta-suave)}
.pie-ruta span{white-space:nowrap}

/* Quien pide menos movimiento no ve ninguno: ni el realce de la tarjeta elegida, ni el
   desplazamiento suave del carril, ni el crecimiento de las barras. */
@media (prefers-reduced-motion:reduce){
  .etapa,.etapa:hover,.etapa.elegida,.etapa.elegida:hover{transition:none;transform:none}
  /* El disco conserva su `transform`: el translateX(-50%) es lo que lo CENTRA sobre la
     tarjeta, no un efecto. Anularlo aquí junto con los demás le habría corrido medio
     disco a la izquierda en las siete etapas. Se le quita solo la transición.
     La sombra se queda en todos: el relieve no se mueve, y es lo que dice cuál está
     elegida cuando el desplazamiento desaparece. */
  .etapa-n{transition:none}
  .etapas{scroll-behavior:auto}
  .ruta-avance .canal i,.carril::after{transition:none}
  .mas svg{transition:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   REDISEÑO DEL TABLERO (19-sep-2026) · relieve ligero
   ══════════════════════════════════════════════════════════════════════════
   Las tarjetas se levantan del papel con tres cosas y nada más: un filo de 1 px, una
   base de 3 px en el color de su estado y una sombra corta y difusa de baja opacidad.
   Sin brillos, sin extrusiones y sin perspectiva: el texto se sigue leyendo recto.
   Va al final de la hoja a propósito, para imponerse a las reglas de la versión
   anterior sin reescribirlas una a una. */
:root{
  --carta-filo:#E6E0D5;
  --carta-base:#DDD6C9;
  --carta-sombra:0 1px 1px rgba(22,35,58,.04),0 4px 12px -2px rgba(22,35,58,.10);
  --carta-sombra-alta:0 2px 3px rgba(22,35,58,.06),0 10px 22px -6px rgba(22,35,58,.18);
}

/* ── Cabecera: título a la izquierda, obra a la derecha ─────────────────── */
.tablero-cab{display:flex;align-items:flex-end;justify-content:space-between;gap:18px 28px;
  flex-wrap:wrap;margin:8px 0 18px}
/* Es un <header>: comun.css le pone el filete ámbar de las cabeceras de pantalla. */
.tablero-cab::after{display:none}
.tablero-cab{padding:0}
.tablero-titulos{flex:1 1 360px;min-width:0}
.tablero-titulos h1{margin:0;font-size:clamp(24px,4.4vw,31px);font-weight:760;
  letter-spacing:-.025em;line-height:1.1;color:var(--tinta)}
.tablero-titulos p{margin:6px 0 0;font-size:16px;color:var(--tinta-media)}
.tablero-cab .obra-alto{display:grid;grid-template-columns:minmax(0,auto) auto;
  align-items:end;gap:4px 12px;margin:0;max-width:100%}
.obra-elige{min-width:0}
.obra-elige .rotulo{display:block;text-transform:none;letter-spacing:0;font-size:13px;
  font-weight:600;color:var(--tinta-media);margin:0 0 5px}
.obra-caja{position:relative;min-width:0}
.obra-caja svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);
  color:var(--tinta-media);pointer-events:none}
/* Solo el de la obra, que es el que lleva el icono: el del país (27-sep-2026) caía también
   aquí y, con 380 px de mínimo, se montaba 134 px sobre la caja de la obra. */
.tablero-cab .obra-caja select{padding-left:44px;min-width:min(380px,70vw);
  box-shadow:var(--carta-sombra)}
.tablero-cab #sello{grid-column:1 / -1;grid-row:2;margin:2px 0 0;font-size:12px}
.tablero-cab .accesos-obra{margin-left:0;grid-column:2;grid-row:1;flex-wrap:nowrap}
.tablero-cab .accesos-obra a{box-shadow:var(--carta-sombra);min-height:46px}
@media (max-width:720px){
  .tablero-cab .obra-alto{display:block}
  .tablero-cab .obra-alto select{min-width:0;width:100%}
}

/* ── Cinta de salud: el protagonista y sus acompañantes ─────────────────── */
.cinta-salud{display:block;margin-bottom:22px}
.franja{display:block;background:none;border:0;box-shadow:none;overflow:visible;border-radius:0}
.franja > *{box-shadow:none}
.franja-prin{display:grid;gap:16px;align-items:stretch;
  grid-template-columns:minmax(0,2.1fr) repeat(3,minmax(0,1fr))}
.franja-prin > .avance,.franja-prin > .medidor{
  background:var(--papel-alto);border:1px solid var(--carta-filo);
  border-bottom:3px solid var(--carta-base);border-radius:14px;
  box-shadow:var(--carta-sombra)}
.franja-prin > .medidor{padding:20px 20px;align-items:flex-start}
.franja-prin > .medidor .icono{width:46px;height:46px;border-radius:50%;display:grid;
  place-items:center;background:linear-gradient(#FBF9F5,#EFEAE1);
  box-shadow:inset 0 1px 0 #fff,0 1px 2px rgba(22,35,58,.08)}
.franja-prin > .medidor .cifra{font-size:30px}
.franja-prin > .medidor .que{font-size:14.5px}

/* «Elementos certificados»: más grande que el resto y con la base en verde. */
.franja-prin > .avance{grid-column:auto;gap:26px;padding:22px 30px;
  border-bottom-color:#9CC4AC;box-shadow:var(--carta-sombra-alta);
  background:linear-gradient(180deg,#FFFFFF 0%,#FCFBF8 100%)}
.aro.aro-grande{width:148px;height:148px;border-radius:50%;
  filter:drop-shadow(0 2px 2px rgba(22,35,58,.10)) drop-shadow(0 6px 10px rgba(46,125,79,.14))}
.aro.aro-grande::before{content:"";position:absolute;inset:17px;border-radius:50%;
  background:radial-gradient(circle at 50% 35%,#FFFFFF 0%,#F6F4EF 100%);
  box-shadow:inset 0 2px 4px rgba(22,35,58,.10)}
.avance .aro.aro-grande{width:148px;height:148px}
.avance .aro.aro-grande span{font-size:34px;font-weight:780;letter-spacing:-.02em}
.avance .aro.aro-grande span.mudo{font-size:15px}
.avance-cuerpo{min-width:0}
/* «Ver las siete» sale solo cuando hay algo que restaurar: su display pisaba el hidden. */
.ruta-todo[hidden]{display:none}
.avance .avance-cuerpo b{font-size:clamp(22px,2.1vw,30px);font-weight:760;letter-spacing:-.02em;
  line-height:1.15}
.avance .avance-cuerpo i{font-size:17px;margin-top:6px;color:var(--tinta-media)}
.avance a.ver-certificados{white-space:nowrap;display:inline-flex;align-items:center;gap:12px;margin-top:18px;
  min-height:52px;padding:12px 26px;border-radius:11px;background:var(--tinta);color:#fff;
  font-size:17px;font-weight:650;text-decoration:none;
  box-shadow:0 2px 0 #0B1424,0 6px 14px -4px rgba(22,35,58,.35);
  transition:transform .15s ease,box-shadow .15s ease,background .15s ease}
.avance a.ver-certificados:hover{background:var(--tinta-hover);text-decoration:none;
  transform:translateY(-1px);box-shadow:0 3px 0 #0B1424,0 10px 18px -6px rgba(22,35,58,.40)}
.avance a.ver-certificados:active{transform:translateY(1px);
  box-shadow:0 1px 0 #0B1424,0 3px 8px -4px rgba(22,35,58,.35)}
.avance a.ver-certificados:focus-visible{outline:2px solid var(--senal);outline-offset:3px}

/* La tira de abajo: los cuatro medidores de consulta, en una línea con filetes. */
.franja-sec{display:flex;flex-wrap:wrap;margin-top:14px;padding:6px 4px;
  border-top:1px solid var(--linea);border-bottom:1px solid var(--linea)}
.franja-sec > .medidor{flex:1 1 220px;padding:8px 18px;gap:10px;align-items:center;
  border-left:1px solid var(--linea)}
.franja-sec > .medidor:first-child{border-left:0}
.franja-sec > .medidor .icono svg{width:18px;height:18px}
.franja-sec > .medidor > div{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 8px}
.franja-sec .medidor .cifra{order:2;font-size:15px;font-weight:700}
.franja-sec .medidor .cifra.mudo{font-size:13px}
.franja-sec .medidor .que{order:1;margin:0;font-weight:600;font-size:13px}
.franja-sec .medidor .que::after{content:":"}
.franja-sec .medidor .de{order:3;flex-basis:100%;margin:0;font-size:11.5px}

@media (max-width:1240px){
  .franja-prin{grid-template-columns:repeat(3,minmax(0,1fr))}
  .franja-prin > .avance{grid-column:1 / -1}
}
@media (max-width:760px){
  .franja-prin{grid-template-columns:1fr}
  .franja-prin > .avance{padding:18px;gap:16px;align-items:center}
  .avance .aro.aro-grande{width:104px;height:104px}
  .aro.aro-grande svg{width:104px;height:104px}
  .aro.aro-grande::before{inset:12px}
  .avance .aro.aro-grande span{font-size:24px}
  .avance a.ver-certificados{margin-top:12px;min-height:46px;padding:10px 18px;font-size:15.5px}
  .franja-sec{display:grid;grid-template-columns:1fr}
  .franja-sec > .medidor{border-left:0;border-top:1px solid var(--linea)}
  .franja-sec > .medidor:first-child{border-top:0}
}
/* El aro 3D (30-sep-2026, iPhone del dueño): la regla de arriba encoge .aro.aro-grande, que ya
   no existe; el aro de ahora mide sus 200 px y empujaba «Ver certificados» fuera de la tarjeta.
   En el teléfono la tarjeta se apila: el aro arriba y centrado, el texto y el botón debajo, con
   el botón a lo ancho. */
@media (max-width:520px){
  .franja-prin > .avance{flex-direction:column;align-items:stretch}
  .avance .aro3d{align-self:center;width:min(200px,62vw)!important}
  .avance .aro3d svg{width:100%}
  .avance a.ver-certificados{display:flex;justify-content:center;width:100%;white-space:normal}
}

/* ── La Ruta 360 en una sola tarjeta ─────────────────────────────────────── */
.ruta-tarjeta{background:var(--papel-alto);border:1px solid var(--carta-filo);
  border-radius:16px;box-shadow:var(--carta-sombra);padding:20px 24px 20px;margin-bottom:22px;
  min-width:0}
.ruta-tarjeta .ruta-cabecera{align-items:center;margin-bottom:6px}
.ruta-tarjeta .ruta-cabe{font-size:24px;font-weight:740}
.ruta-tarjeta .ruta-sub{font-size:16px;color:var(--azul)}
.ruta-tarjeta .ruta-sub b{font-weight:650}
.ruta-tarjeta .ruta-avance .canal{height:10px;margin:0;background:#E8E6E1}
.ruta-tarjeta .ruta-filtro{background:none;gap:8px;padding:0}
.ruta-tarjeta .ruta-filtro button{border:1px solid var(--linea);background:#F1F4F8;
  padding:8px 18px;min-height:38px;font-size:13px}
.ruta-tarjeta .ruta-filtro button[aria-pressed="true"]{background:var(--nivel-suave);
  border-color:#B7D4C1;color:var(--nivel);box-shadow:none}

/* El carril: discos sobre el borde superior de cada tarjeta y un chevrón entre ellas. */
.ruta-tarjeta .carril{padding-top:22px;margin-bottom:10px}
.ruta-tarjeta .carril::before,.ruta-tarjeta .carril::after{top:21px}
.ruta-tarjeta .etapas{gap:22px}
.etapa{align-items:center;text-align:center;padding:30px 10px 0;
  background:linear-gradient(180deg,#FFFFFF 0%,#FCFAF6 100%);
  border:1px solid var(--carta-filo);border-bottom:3px solid var(--carta-base);
  border-radius:14px;box-shadow:var(--carta-sombra)}
.etapa.ok,.etapa.para,.etapa.espera,.etapa.curso,.etapa.mudo{border-top:1px solid var(--carta-filo)}
.etapa.ok    {border-bottom-color:var(--nivel)}
.etapa.para  {border-bottom-color:var(--oxido)}
.etapa.espera{border-bottom-color:#C8944B}
.etapa.curso {border-bottom-color:var(--azul)}
.etapa.mudo  {border-bottom-color:var(--carta-base)}
.etapa:hover{transform:translateY(-1px);box-shadow:var(--carta-sombra-alta)}
.etapa.elegida,.etapa.elegida:hover{border-color:var(--tinta);transform:translateY(-2px);
  box-shadow:0 0 0 1px var(--tinta),var(--carta-sombra-alta)}
.carril.hay-elegida .etapa{opacity:.9}
.etapa:not(:last-child)::after{content:"";position:absolute;top:50%;right:-15px;width:8px;
  height:9px;border-top:2px solid var(--tinta-suave);border-right:2px solid var(--tinta-suave);
  transform:translateY(-50%) rotate(45deg);pointer-events:none}
.etapa-n{top:-16px;width:32px;height:32px;font-size:14px;border-width:3px;border-color:#fff;
  box-shadow:0 2px 5px rgba(22,35,58,.22)}
.etapa-icono{width:64px;height:64px;border-radius:18px;margin:0 auto 10px;
  background:linear-gradient(160deg,#FFFFFF 0%,#F1EDE6 100%);
  box-shadow:inset 0 1px 0 #fff,0 1px 2px rgba(22,35,58,.08),0 4px 8px -4px rgba(22,35,58,.16)}
.etapa-icono svg{stroke-width:1.5}
.etapa > h3{margin:0 0 8px;font-size:16px;font-weight:720;letter-spacing:-.015em;
  color:var(--tinta);line-height:1.2;overflow-wrap:anywhere}
.etapa .sello{margin:0 auto 8px;font-size:11.5px;padding:4px 8px;text-align:left}
/* El estado parte por palabras, no por letras: «correccione / s» no se lee. */
.etapa .sello span{overflow-wrap:normal;word-break:normal;hyphens:auto}
.etapa-resumen{padding:0 4px 8px;width:100%;align-items:stretch}
.etapa-dato{justify-content:center;text-align:center;font-size:12px}
.etapa-pie{width:100%;border-top:0;padding:4px 8px 12px;align-items:center}
.ver-detalle{display:inline-flex;align-items:center;gap:6px;min-height:28px;
  font-size:13.5px;font-weight:600;color:var(--azul)}
.etapa:hover .ver-detalle{text-decoration:underline}

@media (max-width:1080px){
  .ruta-tarjeta .carril{padding-top:0}
  .ruta-tarjeta .etapas{gap:22px;padding:22px 4px 6px}
  .etapas>.etapa{flex:0 0 190px}
}

/* En un teléfono, las siete etapas en REJILLA y no en cinta.
   ─────────────────────────────────────────────────────────────────────────
   La cinta que se desplaza deja media tarjeta partida contra el borde derecho, y ahí no
   se lee «hay más»: se lee «esto está cortado». Lo reportaron así dos veces desde el
   aparato, con la segunda tarjeta a medias enseñando «Pla…» y «0 punto(s…». Y con razón
   —en una pantalla de 384 px no hay nada alrededor que sugiera que eso se arrastra—.

   Dos columnas: las siete caben en cuatro filas, se ven enteras y no hay que descubrir
   ningún gesto. Se pierde la lectura de «recorrido» que da la cinta, pero esa lectura ya
   la daban la barra de avance y el «2 de 7 etapas completadas» de arriba.

   `overflow-x` vuelve a `visible` a propósito: era lo que obligaba al eje vertical a
   valer `auto` y recortaba por arriba el disco del número. Sin cinta, el disco necesita
   que el relleno superior siga donde está. */
@media (max-width:640px){
  .etapas{display:grid;grid-template-columns:1fr 1fr;
    overflow-x:visible;scroll-snap-type:none}
  .ruta-tarjeta .etapas{gap:26px 12px;padding:22px 2px 6px}
  .etapas>.etapa{flex:none;scroll-snap-align:none}
}

/* El detalle: la etapa elegida con su acción principal a la derecha. */
.detalle-etapa{border:1px solid var(--carta-filo);border-left:4px solid var(--tinta);
  border-radius:12px;box-shadow:var(--carta-sombra);background:#FDFCF9}
.detalle-etapa.espera{border-left-color:#C8944B}
.detalle-cabe{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.detalle-icono{width:48px;height:48px;border-radius:14px;display:grid;place-items:center;
  flex:none;color:var(--tinta);background:linear-gradient(160deg,#FFFFFF,#F1EDE6);
  box-shadow:inset 0 1px 0 #fff,0 1px 2px rgba(22,35,58,.10)}
.detalle-etapa.ok .detalle-icono{color:var(--nivel)}
.detalle-etapa.para .detalle-icono{color:var(--oxido)}
.detalle-etapa.espera .detalle-icono{color:#8A6224}
.detalle-titulo{flex:1 1 260px;min-width:0}
.detalle-titulo h4{flex-wrap:wrap}
.detalle-accion{display:inline-flex;align-items:center;gap:8px;min-height:44px;
  padding:10px 22px;border-radius:10px;background:var(--tinta);color:#fff;font-size:14.5px;
  font-weight:650;text-decoration:none;box-shadow:0 2px 0 #0B1424,0 6px 12px -6px rgba(22,35,58,.35);
  transition:transform .15s ease,background .15s ease}
.detalle-accion:hover{background:var(--tinta-hover);transform:translateY(-1px)}
.detalle-accion:focus-visible{outline:2px solid var(--senal);outline-offset:3px}
.detalle-etapa .cerrar{margin-left:0}

/* ── Abajo: las tarjetas, con el mismo relieve ───────────────────────────── */
.panel,.mapa-calor{border-color:var(--carta-filo);box-shadow:var(--carta-sombra);border-radius:14px}
.mapa-calor.panel{padding:16px 18px 12px}

/* ── Pie: garantías a la izquierda y la verificación a la derecha ─────────── */
footer.pie-ruta{justify-content:flex-start}
.pie-ruta .verificar{margin-left:auto;display:inline-flex;align-items:center;gap:6px;
  min-height:32px;font-size:13px;font-weight:600;color:var(--azul);text-decoration:none}
.pie-ruta .verificar:hover{text-decoration:underline}
.pie-ruta .verificar:focus-visible{outline:2px solid var(--senal);outline-offset:2px}
@media (max-width:720px){ .pie-ruta span{white-space:normal} .pie-ruta .verificar{margin-left:0} }



/* ── Segunda pasada contra la maqueta (19-sep-2026) ──────────────────────────
   Iconos 3D en las etapas (Fluent Emoji, MIT: ver marca/ruta/LEEME.md), títulos de
   panel con icono, estados vacíos de una línea y el estado de certificación en casillas. */
.etapa-icono{width:64px;height:64px;background:none;box-shadow:none;border-radius:0;margin:0 auto 8px}
.etapa-icono img{width:60px;height:60px;display:block;
  filter:drop-shadow(0 3px 4px rgba(22,35,58,.14))}
.etapa.mudo .etapa-icono img{filter:grayscale(.35) drop-shadow(0 3px 4px rgba(22,35,58,.10))}

/* La etapa que pide atención se señala con su propio color, no solo con el filo marino. */
.etapa.elegida.espera,.etapa.elegida.espera:hover{border-color:#C8944B;
  box-shadow:0 0 0 1px #C8944B,var(--carta-sombra-alta)}
.etapa.elegida.para,.etapa.elegida.para:hover{border-color:var(--oxido);
  box-shadow:0 0 0 1px var(--oxido),var(--carta-sombra-alta)}

.panel h2,.mapa-calor h2{display:flex;align-items:center;gap:10px;font-size:17px;font-weight:700}
.panel h2::after,.mapa-calor h2::after{display:none}
.cuenta-titulo{display:inline-grid;place-items:center;min-width:28px;height:26px;padding:0 9px;
  border-radius:99px;background:#ECEEF1;font-size:13px;font-weight:700;color:var(--tinta)}

.vacio-panel.vacio-ok{display:flex;flex-direction:column;align-items:center;gap:4px;padding:18px 0}
.vacio-ok svg{width:38px;height:38px;padding:9px;border-radius:50%;background:#E8EDF3;color:var(--tinta-media)}
.vacio-ok b{font-size:15px;font-weight:500;color:var(--tinta)}
.vacio-ok span{font-size:12.5px;color:var(--tinta-media)}

.casillas{list-style:none;margin:0 0 4px;padding:0;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.casillas li{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--linea);
  border-radius:9px;background:#fff;font-size:12.5px;color:var(--tinta);line-height:1.3}
.casillas li .disco3d{flex:none}
.casillas li.floja{color:var(--oxido);border-color:var(--oxido);grid-column:1 / -1}
.guardia{border-radius:10px}

/* El retorno: una nota de regla, no una alarma. */
.retorno{background:#F1F4F8;border:1px solid #E1E7EF;border-radius:10px;color:var(--azul)}
.retorno b{color:var(--tinta)}
.retorno p{color:var(--tinta-media)}

@media (prefers-reduced-motion:reduce){
  .etapa,.etapa:hover,.etapa.elegida,.etapa.elegida:hover{transition:none;transform:none}
  .avance a.ver-certificados,.avance a.ver-certificados:hover,.avance a.ver-certificados:active,
  .detalle-accion,.detalle-accion:hover{transition:none;transform:none}
}

/* ── La portada en 3D (28-sep-2026) ───────────────────────────────────────────
   «La barra con el porcentaje alcanzado y en 3D, y los gráficos de las flechas en 3D».
   Clases nuevas a propósito: .aro y .icono traen de arriba tamaños y giros (rotate(-90deg))
   que un dibujo en perspectiva no quiere heredar. */
.aro3d{position:relative;flex:none;filter:drop-shadow(0 8px 12px rgba(46,125,79,.16))}
.aro3d svg{display:block;height:auto}
.aro3d span{position:absolute;left:0;right:0;transform:translateY(-50%);text-align:center;
  font-size:32px;font-weight:800;letter-spacing:-.02em;color:var(--tinta);pointer-events:none;
  font-variant-numeric:tabular-nums}
.aro3d span.mudo{font-size:14px;font-weight:600;color:var(--tinta-suave)}
.icono3d{flex:none;display:grid;place-items:center;width:64px;height:60px;margin:-6px -4px 0 -6px}
.disco3d{display:block;filter:drop-shadow(0 4px 6px rgba(22,35,58,.14))}
.barra3d{min-height:40px;filter:drop-shadow(0 4px 6px rgba(22,35,58,.10))}
.barra3d svg{display:block}

/* ── La portada en fichas (28-sep-2026), como el Tablero y Analítica ─────────────
   Cada ficha lleva arriba la franja del color de su estado (data-tono), y la tira de
   consulta deja de ser un renglón para ser cuatro fichas con su disco 3D. */
.franja-prin > .medidor,.franja-sec.fichas > .medidor{position:relative;overflow:hidden}
.medidor[data-tono]::before{content:"";position:absolute;inset:0 0 auto 0;height:4px;background:#C4BCAD}
.medidor[data-tono="limpio"]::before{background:linear-gradient(90deg,#2E8B4F,#5DB57D)}
.medidor[data-tono="aviso"]::before{background:linear-gradient(90deg,#E0A932,#F0C66A)}
.medidor[data-tono="alto"]::before{background:linear-gradient(90deg,#C8473A,#E27A6D)}
.medidor[data-tono="azul"]::before{background:linear-gradient(90deg,#3A6EA5,#6F9BCB)}
.franja-sec.fichas{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;margin-top:16px;
  padding:0;background:none;border:0;box-shadow:none}
.franja-sec.fichas > .medidor{flex:none;display:flex;align-items:center;gap:12px;padding:16px 16px 14px;
  border:1px solid var(--carta-filo);border-bottom:3px solid var(--carta-base);border-left:1px solid var(--carta-filo);
  border-radius:14px;background:var(--papel-alto);box-shadow:var(--carta-sombra)}
.franja-sec.fichas > .medidor:first-child{border-left:1px solid var(--carta-filo)}
.franja-sec.fichas > .medidor > div{display:block}
.franja-sec.fichas .medidor .cifra{font-size:24px;font-weight:750}
.franja-sec.fichas .medidor .cifra.mudo{font-size:15px}
.franja-sec.fichas .medidor .que{margin:3px 0 0;font-size:13.5px;font-weight:650}
.franja-sec.fichas .medidor .que::after{content:none}
.franja-sec.fichas .medidor .de{margin:2px 0 0;font-size:12px}
.franja-sec.fichas .icono3d{width:56px;height:52px;margin:0}
.franja-sec.fichas .disco3d{width:56px;height:52px}
@media (max-width:1100px){ .franja-sec.fichas{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (max-width:640px){ .franja-sec.fichas{grid-template-columns:1fr} }

/* El disco del título de cada panel (29-sep-2026): el mismo disco en perspectiva del resto de
   la suite, en lugar de la moneda plana con degradado. */
.panel h2 .h2-disco{flex:none;display:inline-flex}
.mapa-calor h2 .h2-disco{flex:none;display:inline-flex}
.h2-disco .disco3d{display:block;filter:drop-shadow(0 3px 5px rgba(22,35,58,.16))}
