/*
 * Las páginas del simulador: mapa, andén y administración.
 *
 * Se carga después de style.css y da por hechas sus variables y su reset. La
 * regla de no hacer scroll nunca sigue en pie aquí: estas tres páginas son
 * pantallas, no documentos. La única que se desplaza es la portada.
 */

/* ── Barra con navegación ────────────────────────── */
.barra--nav {
  justify-content: space-between;
  gap: 1rem;
}

.barra a.marca {
  color: inherit;
  text-decoration: none;
}

/*
 * De enlaces ya no lleva ninguno: en el mapa, el andén y el tren esta barra es
 * donde viven los mandos de la pantalla —la voz y el tema, en ese orden— y por
 * eso van juntos y no repartidos. El hueco de antes era de separar secciones de
 * un menú, y entre dos píldoras hacía que cada una pareciera de otra cosa.
 */
.barra__enlaces {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/*
 * En un móvil los botones se quedan en su símbolo, igual que en la portada: la
 * palabra sobra cuando dos píldoras compiten por el ancho con la marca, y el
 * aria-label la sigue diciendo entera para quien no ve el símbolo.
 */
@media (max-width: 720px) {
  .barra .tema__texto { display: none; }
}


/* ── Aviso de conexión ───────────────────────────── */
/*
 * data-conexion lo pone el consumidor de SSE. Una pantalla colgada sin decirlo
 * es peor que una pantalla en blanco: si se cae, se ve.
 */
.aviso-conexion {
  position: absolute;
  inset: auto 0 0;
  display: none;
  padding: 0.6rem 1rem;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--carbon);
  background: var(--rojo);
}
body[data-conexion="caida"] .aviso-conexion { display: block; }
body[data-conexion="caida"] .diagrama,
body[data-conexion="caida"] .anden__tabla { opacity: 0.35; }

/* ── El diagrama ─────────────────────────────────── */
.diagrama {
  width: 100%;
  height: 100%;
  color: var(--tinta);
}

.diagrama__linea {
  stroke-width: 8;
  transition: opacity 0.25s;
}

/*
 * Una línea apagada desde la leyenda. Se va con un fundido y no de golpe, que es
 * un cambio grande del plano. La visibility espera a que termine el fundido y
 * entonces la saca del todo: sin ella, una estación invisible seguiría cogiendo el
 * tabulador y el puntero, que es de las cosas que se notan sin saber por qué.
 */
.diagrama__linea[data-oculta="si"],
.estacion[data-oculta="si"] {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s, visibility 0s 0.25s;
}

/* ── El callejero de Tunja ───────────────────────── */
/*
 * El fondo del mapa geográfico. La ciudad aparece al ritmo de --mapa, que es lo que
 * dice cuánto se ha ido el plano del esquema hacia Tunja; aquí solo se dice de qué
 * color y de qué grosor va cada rango de calle.
 *
 * Va con las variables del tema y no con un gris fijo: un fondo de mapa que no
 * cambia al pasar a oscuro es lo que hace que un mapa oscuro parezca barato.
 */
.diagrama__calles {
  opacity: var(--mapa, 0);
  pointer-events: none;
}

.calle {
  stroke: var(--fantasma);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* La jerarquía es lo que convierte cuatrocientos trazos grises en una ciudad
   reconocible: sin ella no se distingue una avenida de un callejón. */
.calle[data-clase="principal"] { stroke-width: 2.4; opacity: 0.95; }
.calle[data-clase="secundaria"] { stroke-width: 1.6; opacity: 0.7; }
.calle[data-clase="terciaria"] { stroke-width: 1.1; opacity: 0.5; }
.calle[data-clase="barrio"] { stroke-width: 0.7; opacity: 0.32; }

/* ── Las avenidas de Tunja ───────────────────────── */
/*
 * El suelo del esquema. El plano de metro no tiene ciudad debajo —para eso deforma
 * las distancias— y un recorrido de bus puesto encima flota: se ve que sube y que
 * tuerce, pero no por dónde. Con la Norte, la Oriental, la Universitaria y la
 * Olímpica debajo, ese mismo trazo dice algo.
 *
 * Líneas continuas, finas y del gris de fondo: son la referencia contra la que se
 * mira lo demás, no una capa que compita con ello. Sin nombres, por ahora — en un
 * plano tan poblado como este acaban debajo de una vía o de una chapa, y un rótulo a
 * medio leer es peor que ninguno.
 *
 * Se ven cuando el plano es esquema y hay buses puestos: sobre Tunja está el
 * callejero entero, con estas cuatro dentro de él y en su sitio de verdad, y sin
 * recorrido que seguir no hay nada que orientar. Las dos condiciones se multiplican,
 * que es lo que hace que al cambiar de modo con los buses puestos se vayan al mismo
 * ritmo que llega la ciudad.
 */
.diagrama__avenidas {
  opacity: calc((1 - var(--mapa, 0)) * var(--buses, 0));
  pointer-events: none;
}

.avenida {
  stroke: var(--fantasma);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── Las rutas de bus ────────────────────────────── */
/*
 * Un recorrido está dibujado dos veces y nunca se ven las dos a la vez: sobre Tunja,
 * el recorrido de verdad calle por calle; sobre el esquema, una línea de metro. No
 * son el mismo dibujo movido —no tienen los mismos puntos—, así que se turnan
 * fundiéndose, que además es lo honesto: son dos respuestas distintas.
 *
 * --buses dice si se han pedido y --mapa, cuál de los dos toca. Se multiplican al
 * anidarse: el grupo de fuera lleva la primera y cada uno de dentro, la segunda.
 */
.diagrama__buses {
  opacity: var(--buses, 0);
  /* No se tocan: se eligen desde la lista del panel, que es donde tienen nombre.
     Aquí solo estorbarían el hover de las estaciones que llevan encima. */
  pointer-events: none;
}

.diagrama__buses--mapa { opacity: var(--mapa, 0); }
.diagrama__buses--esquema { opacity: calc(1 - var(--mapa, 0)); }

/*
 * El recorrido de verdad, para el mapa. Ninguno puesto hasta que se pide: quién está
 * puesto lo dice mapa.js con data-puesta, que es también quien lo dice en la lista.
 * Las dos caras responden a lo mismo y con un :hover del CSS se separarían.
 */
.ruta-bus {
  stroke: var(--color-ruta);
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-opacity: 0;
  transition: stroke-opacity 0.2s;
}
.ruta-bus[data-puesta="si"] { stroke-opacity: 1; }

/*
 * Los paraderos: por dónde se sube uno al bus.
 *
 * Solo en el mapa. En el esquema el recorrido va enderezado y un punto sobre él no
 * diría dónde esperar, diría dónde cae ese punto en un dibujo.
 *
 * Del color del papel por dentro y del de la ruta por fuera, como las cabeceras y
 * como los aros de las estaciones: en este plano un punto hueco es siempre un sitio
 * donde el vehículo se detiene. Más pequeños que una cabecera porque son treinta y
 * ella es una, y lo que hay que encontrar primero es dónde empieza el recorrido.
 */
.paraderos-bus {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0s 0.2s;
}
.paraderos-bus[data-puesta="si"] {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s;
}

.paradero-bus {
  fill: var(--carbon);
  stroke: var(--color-ruta);
  stroke-width: 1.6;
}

/*
 * Y la línea de metro, para el esquema. Va entera en un grupo —la línea, su funda,
 * los aros de sus paradas y sus dos cabeceras— porque se encienden y se apagan
 * juntas: son un solo recorrido, no cinco cosas que coinciden.
 */
.linea-bus {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0s 0.2s;
}
.linea-bus[data-puesta="si"] {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s;
}

.linea-bus__via {
  stroke: var(--color-ruta);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/*
 * La funda: el mismo trazo, más grueso y del color del papel, por debajo. Estas
 * líneas pasan por encima de las del metro —es donde tienen que ir: un bus que
 * acompaña al metro se dibuja sobre su vía— y sin ella un recorrido naranja sobre la
 * Línea 1, que también es naranja, sería invisible justo en el tramo que más
 * interesa.
 */
.linea-bus__funda {
  stroke: var(--carbon);
  stroke-width: 8.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/*
 * El aro de una estación por la que pasa el bus. Es lo que convierte la línea en un
 * plano de metro: sin él se ve por dónde va, con él se ve dónde para.
 *
 * Por fuera del punto de la estación, que se dibuja encima con su color y su chapa:
 * el aro asoma alrededor como el anillo de una parada compartida.
 */
.linea-bus__parada {
  fill: none;
  stroke: var(--color-ruta);
  stroke-width: 3;
}

/*
 * Dónde empieza y dónde acaba el recorrido.
 *
 * El principio va hueco y el final relleno, que es como se marcan las cabeceras en
 * cualquier plano: el aro dice «de aquí sale» y el disco «hasta aquí llega». Con
 * una ruta que se dobla sobre sí misma, es lo único que dice en qué dirección se
 * está leyendo el trazo.
 *
 * Dentro de un .recorrido las lleva el grupo, así que estas reglas solo actúan sobre
 * las del mapa, que van sueltas.
 */
.cabecera-bus {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0s 0.2s;
}
.cabecera-bus[data-puesta="si"],
.linea-bus .cabecera-bus {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s;
}

.cabecera-bus__marca {
  fill: var(--carbon);
  stroke: var(--color-ruta);
  stroke-width: 3;
}
.cabecera-bus[data-punta="fin"] .cabecera-bus__marca { fill: var(--color-ruta); }

/* Con halo del color del papel: el nombre cae sobre el callejero y sobre su propio
   trazo, y sin él se lee a trozos. Mismo recurso que las chapas de las estaciones. */
.cabecera-bus__nombre {
  fill: var(--tinta);
  font-family: var(--display);
  font-size: 12px;
  font-weight: 700;
  paint-order: stroke;
  stroke: var(--carbon);
  stroke-width: 3.5px;
  stroke-linejoin: round;
}

/* ── Estaciones ──────────────────────────────────── */
.estacion { cursor: pointer; transition: opacity 0.25s; }
.estacion__toque { fill: transparent; }

/*
 * La marca crece con un scale en vez de con el radio: los intercambios son
 * trazados repartidos por color y no tienen radio que animar, así que crecer es
 * lo único que sirve igual para las dos formas.
 */
.estacion__marca {
  transition: transform 0.15s;
  transform-box: view-box;
}

.estacion__punto {
  fill: var(--carbon);
  stroke-width: 3;
  transition: fill 0.15s, stroke 0.15s;
}

/* Un intercambio no es de ninguna línea: es de todas las que pasan por él, y se
   reparte el círculo entre ellas. El aro lo despega de las vías. */
.estacion__aro { fill: var(--carbon); }
.estacion__sector { stroke: none; }

/* La chapa del código, como en un plano impreso */
.insignia__texto {
  fill: #ffffff;
  font-family: var(--display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
/*
 * El ámbar de la Línea 1 es demasiado claro para llevar texto blanco encima.
 * Se decide por el color de la propia línea, no por cuál es, para que una línea
 * nueva de color claro herede el arreglo sin tocar nada.
 */
.insignia[data-linea] rect { stroke: var(--carbon); stroke-width: 1.5; }
.insignia__texto { paint-order: stroke; stroke: rgba(0, 0, 0, 0.35); stroke-width: 2.5px; }

/*
 * El nombre solo sale al apuntar, al tabular o al tocar. Dieciocho nombres a la
 * vez tapan el plano; de uno en uno se lee perfectamente.
 */
.estacion__nombre {
  fill: var(--tinta);
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  paint-order: stroke;
  stroke: var(--carbon);
  stroke-width: 5px;
  stroke-linejoin: round;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
}

.estacion:hover .estacion__nombre,
.estacion:focus-visible .estacion__nombre,
.estacion[data-abierta="si"] .estacion__nombre {
  opacity: 1;
}

.estacion:hover .estacion__marca { transform: scale(1.35); }

/*
 * La estación abierta en la ficha se queda marcada: grande y rellena de su
 * propio color. Un punto blanco o negro no dice de qué línea es y encima se
 * confunde con el estado normal de un intercambio.
 */
.estacion[data-abierta="si"] .estacion__marca { transform: scale(1.6); }
.estacion[data-abierta="si"] .estacion__punto {
  fill: var(--color-estacion);
  stroke: var(--carbon);
}

.estacion:focus { outline: none; }
.estacion:focus-visible .estacion__marca { transform: scale(1.35); }
.estacion:focus-visible .estacion__punto {
  stroke: var(--acento);
  stroke-width: 4;
}

/* ── Los trenes ──────────────────────────────────── */
/*
 * Solo el disco del tren es sensible. El halo y la matrícula se dibujan encima
 * del plano y, si capturaran el ratón, le robarían el clic a la estación que
 * tienen debajo — que es más grande y más importante.
 */
.tren { pointer-events: none; }
.tren__toque {
  pointer-events: auto;
  fill: transparent;
  cursor: pointer;
}

.tren__halo {
  opacity: 0.18;
}
.tren__cuerpo {
  stroke: var(--carbon);
  stroke-width: 2.5;
}
.tren__flecha {
  fill: var(--carbon);
}

/*
 * La matrícula solo al apuntar. Con siete trenes en el plano, siete etiquetas
 * fijas tapan más de lo que informan; el tren se reconoce por su color y su
 * posición, y el nombre solo hace falta cuando se va a tocar.
 */
.tren__matricula {
  fill: var(--tinta);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  paint-order: stroke;
  stroke: var(--carbon);
  stroke-width: 4px;
  stroke-linejoin: round;
  opacity: 0;
  transition: opacity 0.15s;
}
.tren:hover .tren__matricula { opacity: 1; }

/* Al apuntarlo se agranda un poco: así se ve cuál se va a abrir */
.tren__cuerpo { transition: r 0.15s; }
.tren:hover .tren__cuerpo { r: 9; }

/* Parado en una estación: el halo late, como un tren con las puertas abiertas */
.tren[data-estado="detenido"] .tren__halo,
.tren[data-estado="terminal"] .tren__halo {
  animation: latido 1.6s ease-in-out infinite;
}

@keyframes latido {
  0%, 100% { opacity: 0.14; r: 12; }
  50%      { opacity: 0.32; r: 16; }
}

/* Pausado: se queda gris y quieto, para que se note que no es que vaya lento */
.tren[data-pausado="si"] .tren__cuerpo { fill: var(--tenue) !important; }
.tren[data-pausado="si"] .tren__halo { animation: none; opacity: 0.08; }

/* ── Mapa ────────────────────────────────────────── */
.mapa {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  gap: clamp(0.5rem, 2vw, 1.25rem);
  padding: clamp(0.5rem, 2vh, 1.25rem);
}

.mapa__lienzo {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  /* El plano se mueve con una transformación: lo que sale por los bordes se
     recorta aquí, o se metería debajo del panel. */
  overflow: hidden;
  /* El gesto del plano es el zoom, no el desplazamiento de la página */
  touch-action: none;
  overscroll-behavior: contain;
}

/* ── Mandos del zoom ─────────────────────────────── */
.mapa__mandos {
  position: absolute;
  z-index: 3;
  right: 0.5rem;
  bottom: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.mapa__mandos button {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  font-family: var(--display);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--tenue);
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  border: 1px solid var(--linea);
  border-radius: 8px;
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: color 0.15s, border-color 0.15s;
}
.mapa__mandos button:hover { color: var(--tinta); border-color: var(--tenue); }
/* Con el plano entero a la vista, encuadrar no hace nada */
.mapa__lienzo[data-zoom="no"] #zTodo { opacity: 0.35; pointer-events: none; }
/* El único mando que no es una acción sino un estado: o se está sobre el mapa
   de Tunja o no, y encendido quiere decir que sí. */
.mapa__mandos button[aria-pressed="true"] {
  color: var(--acento);
  border-color: var(--acento);
}
/* En horizontal el panel está siempre puesto: no hay nada que abrir */
#zPanel { display: none; }

/* El aviso de licencia de OpenStreetMap. Solo con el callejero a la vista: en el
   esquema no hay ni un dato suyo que atribuir. */
.mapa__atribucion {
  position: absolute;
  z-index: 3;
  left: 0.6rem;
  bottom: 0.5rem;
  margin: 0;
  font-size: 0.68rem;
  color: var(--tenue);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}
/*
 * Sale cuando hay algo que atribuir, y ahora eso ya no es solo el mapa: en el esquema
 * con los buses puestos están los recorridos de Tunja en Bus. Las avenidas del
 * esquema no cuentan —están dibujadas a mano—, y en el plano de metro a secas no hay
 * un solo dato de nadie, así que el aviso sobra.
 */
body[data-base="geo"] .mapa__atribucion,
body[data-buses="si"] .mapa__atribucion { opacity: 0.85; pointer-events: auto; }
.mapa__atribucion a { color: inherit; text-decoration: none; }
.mapa__atribucion a:hover { color: var(--tinta); text-decoration: underline; }

/* La de los recorridos, solo con los buses puestos: apagados no hay ni un dato
   suyo en pantalla que atribuir. Con los dos avisos la línea se hace larga, así
   que se le pone techo: antes que meterse debajo de los mandos, que doble. */
.mapa__atribucion { max-width: min(62%, 30rem); line-height: 1.35; }
.mapa__atribucion .buses { display: none; }
body[data-buses="si"] .mapa__atribucion .buses { display: inline; }

.mapa__panel {
  flex: none;
  width: clamp(180px, 22vw, 260px);
  display: flex;
  flex-direction: column;
  gap: clamp(0.6rem, 2vh, 1.1rem);
  padding: clamp(0.75rem, 2vh, 1.1rem);
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--panel);
}

.mapa__cifra {
  font-size: clamp(2rem, 6vh, 3rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}

.leyenda {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
/* Cada línea es un interruptor: apagarla la quita del plano con sus trenes. El
   sitio donde se lee qué es cada color es el sitio donde uno quiere quitarlo. */
.linea {
  width: 100%;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.15rem 0.25rem;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
  transition: opacity 0.15s;
}
.linea:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }

.leyenda__color {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-linea);
}
.leyenda__nombre { color: var(--tenue); }
.leyenda__cuenta { color: var(--tinta); font-size: 0.9rem; }

/*
 * Apagada se queda a la vista pero desvaída, y con el color hueco. Tiene que
 * poder volver a encenderse desde el mismo sitio, así que no puede desaparecer;
 * y tiene que distinguirse de un vistazo de la que sí está, o el plano parecería
 * que perdió una línea él solo.
 */
.linea[aria-pressed="false"] { opacity: 0.45; }
.linea[aria-pressed="false"] .leyenda__color {
  background: none;
  box-shadow: inset 0 0 0 2px var(--color-linea);
}
.linea[aria-pressed="false"] .leyenda__nombre { text-decoration: line-through; }

/*
 * La lista de rutas de bus, debajo de las líneas del metro.
 *
 * Solo con los buses puestos: apagados no hay en el plano nada a lo que señalar, y
 * una lista de veintiséis filas que no encienden nada solo ocupa el panel.
 */
.rutas {
  display: none;
  /* Crece con lo que sobre y se desborda por dentro: veintiséis filas no caben en
     una pantalla baja, y sin esto empujarían el panel fuera de la ventana. */
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
  gap: 0.5rem;
}
body[data-buses="si"] .rutas { display: flex; }

.rutas__lista {
  list-style: none;
  padding: 0;
  margin: 0;
  overflow-y: auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

/* El color de la ruta lo lleva la fila entera, para que lo hereden su cabecera y
   sus dos sentidos sin repetirlo en cada uno. */
.ruta { display: flex; flex-direction: column; }

.rutas__lista button {
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  text-align: left;
  color: var(--tenue);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.rutas__lista button:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 1px;
}

.ruta__cabecera {
  width: 100%;
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.28rem 0.35rem;
  font-size: 0.82rem;
}

/* La pastilla del color, del mismo tamaño que el punto de las líneas del metro:
   son dos leyendas seguidas y no tienen por qué verse como dos cosas distintas. */
.ruta__color {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-ruta);
  opacity: 0.6;
  transition: opacity 0.15s;
}
.ruta__numero { color: var(--tinta); font-size: 0.8rem; }
/* El corredor cede: es lo único de la fila que puede acortarse sin perder de qué
   ruta se habla, y el título lo enseña entero. */
.ruta__corredor {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.ruta__flecha {
  font-size: 0.7rem;
  transition: transform 0.15s;
}
.ruta__flecha::before { content: "▸"; }
.ruta__cabecera[aria-expanded="true"] .ruta__flecha { transform: rotate(90deg); }

/* Los sentidos, sangrados bajo su ruta y con una guía del color que los ata a
   ella: sueltos, en una lista larga, no se sabría de quién cuelgan. */
.ruta__sentidos {
  list-style: none;
  margin: 0.1rem 0 0.35rem 0.75rem;
  padding: 0 0 0 0.6rem;
  border-left: 2px solid color-mix(in srgb, var(--color-ruta) 45%, transparent);
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.sentido {
  width: 100%;
  display: block;
  padding: 0.26rem 0.4rem;
}
/* A dónde va, y debajo por qué lado. Las dos líneas hacen falta: "Norte → Sur" no
   dice por dónde se pasa, y "Green Hills – Retén Sur" no dice cuál de los dos es
   hasta que se ve al lado el que va al revés. */
.sentido__hacia {
  display: block;
  font-size: 0.78rem;
  color: var(--tinta);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.sentido__cardinal { display: block; font-size: 0.68rem; }

/* Señalado es lo que se está enseñando ahora mismo en el plano, venga de que se
   eligió o de que el puntero está encima. */
.rutas__lista button[data-senalada="si"] {
  color: var(--tinta);
  background: color-mix(in srgb, var(--color-ruta) 18%, transparent);
}
.ruta__cabecera[data-senalada="si"] .ruta__color { opacity: 1; }

/*
 * La ruta cuyo recorrido está puesto en el plano, marcada con el mismo aro que
 * llevan el sentido elegido y su pastilla en la ficha: en toda la pantalla, el aro
 * quiere decir "esto es lo elegido".
 *
 * Se queda aunque se recoja el desplegable y aunque el puntero se vaya a otra, que
 * es justo cuando hace falta: recoger una ruta es un clic fácil de dar sin querer,
 * y sin la marca no quedaría en la lista ni rastro de cuál se estaba viendo.
 */
.ruta__cabecera[data-elegida="si"] { box-shadow: inset 0 0 0 1px var(--color-ruta); }
.ruta__cabecera[data-elegida="si"] .ruta__color { opacity: 1; }
.ruta__cabecera[data-elegida="si"] .ruta__corredor { color: var(--tinta); }

/* Elegido y solo apuntado se distinguen: el elegido se queda cuando el puntero se
   va, y sin marca propia no habría forma de saber cuál era. */
.sentido[aria-pressed="true"] { box-shadow: inset 0 0 0 1px var(--color-ruta); }

.mapa__nota {
  margin-top: auto;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--tenue);
}
.mapa__nota a { color: var(--acento); }

/* Con trenes en servicio, el cartel de "no hay trenes" sobra */
body[data-flota="activa"] .mapa__nota { display: none; }

/* ── Ficha de la estación ────────────────────────── */
/*
 * Sale al tocar una estación del plano. Hoy enseña sus códigos, sus líneas y lo
 * que haya en red.json sobre salidas, vías y conexiones con MoviTunja; los
 * apartados que no tengan datos lo dicen en vez de desaparecer, para que se vea
 * qué falta por llenar.
 *
 * En horizontal ocupa el sitio del panel: misma caja y mismo ancho, uno en
 * lugar del otro. Antes vivía dentro del <aside> y le heredaba la caja; ahora
 * la lleva puesta, que es lo que le permite ser hermana suya y no hija.
 */
.ficha-estacion {
  flex: none;
  width: clamp(180px, 22vw, 260px);
  min-height: 0;
  display: none;
  flex-direction: column;
  gap: 0.9rem;
  padding: clamp(0.75rem, 2vh, 1.1rem);
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--panel);
  overflow-y: auto;
}
body[data-estacion="si"] .ficha-estacion { display: flex; }
body[data-estacion="si"] .mapa__panel { display: none; }

/* En horizontal la ficha es una columna del panel: no hay nada que arrastrar */
.ficha-estacion__asa { display: none; }

.ficha-estacion__cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5rem;
}

.ficha-estacion h2 {
  font-size: clamp(1.05rem, 2.6vh, 1.35rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.ficha-estacion__codigos {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.45rem;
}
.codigo {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.16rem 0.5rem;
  border-radius: 5px;
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 0 2px rgba(0, 0, 0, 0.45);
}

.ficha-estacion__cerrar {
  flex: none;
  width: 1.7rem;
  height: 1.7rem;
  display: grid;
  place-items: center;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--tenue);
  background: none;
  border: 1px solid var(--linea);
  border-radius: 6px;
  cursor: pointer;
}
.ficha-estacion__cerrar:hover { color: var(--tinta); border-color: var(--tenue); }

.bloque {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--linea);
}
.bloque ul {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
  line-height: 1.45;
}
.bloque li { color: var(--tinta); }
.bloque li span { display: block; color: var(--tenue); font-size: 0.78rem; }
.bloque p {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--fantasma);
  font-style: italic;
}

/*
 * Los buses que paran en la estación, dentro de la ficha.
 *
 * Una fila por ruta y dentro sus sentidos, no una fila por sentido: por Las Nieves
 * pasan cuarenta y un recorridos, y cuarenta y una filas no son una lista.
 *
 * El color va en una guía a la izquierda y no en el número: hay rutas amarillas y
 * rutas cal, y un número escrito de su color no se lee ni sobre el fondo claro ni
 * sobre el oscuro. Así el color acompaña sin tener que ser legible él mismo.
 */
/*
 * En columna y no en fila: con los sentidos uno debajo de otro y del mismo ancho,
 * lo que se compara —que es a dónde va cada uno— queda alineado. En fila, el
 * segundo caía debajo por falta de sitio y los dos salían de tamaños distintos
 * según lo largo que fuera su nombre.
 */
.conexiones {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.25rem;
  padding-left: 0.5rem;
  border-left: 3px solid var(--color-ruta);
}
.conexiones__numero {
  color: var(--tinta);
  font-size: 0.75rem;
}

.conexion {
  width: 100%;
  text-align: center;
  padding: 0.15rem 0.5rem;
  border: 1px solid color-mix(in srgb, var(--color-ruta) 40%, transparent);
  border-radius: 999px;
  background: none;
  font: inherit;
  font-size: 0.72rem;
  color: var(--tenue);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.conexion[data-senalada="si"] {
  color: var(--tinta);
  background: color-mix(in srgb, var(--color-ruta) 22%, transparent);
}
.conexion[aria-pressed="true"] { border-color: var(--color-ruta); }
.conexion:focus-visible { outline: 2px solid var(--acento); outline-offset: 1px; }

/* Las próximas llegadas, dentro de la ficha */
.ficha-estacion__llegadas {
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.ficha-estacion__llegadas li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.82rem;
}
.ficha-estacion__llegadas .mono { color: var(--tenue); font-size: 0.75rem; }
.ficha-estacion__llegadas b {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.ficha-estacion__ir {
  margin-top: auto;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--linea);
  border-radius: 8px;
  text-align: center;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--tinta);
  text-decoration: none;
}
.ficha-estacion__ir:hover { border-color: var(--acento); color: var(--acento); }

/*
 * En vertical no hay sitio para poner nada al lado del plano: en un teléfono
 * cada milímetro que no sea plano es un milímetro de plano perdido. El panel se
 * guarda en un cajón y la ficha sube desde abajo; los dos por encima del mapa,
 * que se queda con la pantalla entera y no se mueve cuando salen.
 */
@media (max-aspect-ratio: 1/1) {
  /* El plano se lo queda todo: el panel y la ficha van por encima, no al lado */
  .mapa { padding: 0.5rem; }
  /*
   * El panel no cabe al lado del plano y como tira de abajo cortaba los nombres
   * de las líneas. Pasa a ser un cajón que sale del lado, del mismo borde en el
   * que están los mandos, y por dentro se lee igual que en horizontal.
   *
   * Se desliza con transform, que es gratis para el compositor; podía hacerlo
   * desde que la ficha salió de dentro, porque un transform en el padre le
   * habría cambiado el marco de referencia a un hijo fijo.
   */
  .mapa__panel {
    position: absolute;
    z-index: 4;
    top: 0.5rem;
    /* A la izquierda de la columna de mandos: su ancho, su margen y aire */
    right: 4.25rem;
    width: min(18.5rem, calc(100vw - 5.5rem));
    max-height: calc(100% - 1rem);
    padding: 0.85rem;
    overflow-y: auto;
    box-shadow: 0 8px 28px rgb(0 0 0 / 0.3);
    opacity: 0;
    pointer-events: none;
    transform: translateX(calc(100% + 4.75rem));
    transition: transform 0.25s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.2s;
  }
  body[data-leyenda="si"] .mapa__panel {
    opacity: 1;
    pointer-events: auto;
    transform: none;
  }
  /* La ficha ya no está dentro: el cajón va por su cuenta */
  body[data-estacion="si"] .mapa__panel { display: flex; }

  /*
   * Nada de esto parte en dos líneas: "Línea 2 · Occidente – Oriente" partido
   * no se lee, y el ancho del cajón está puesto para que quepa entero.
   */
  .mapa__cifra { font-size: 2rem; }
  .leyenda li,
  .mapa__estado .panel__etiqueta { white-space: nowrap; }
  .leyenda__nombre { overflow: hidden; text-overflow: ellipsis; }

  /* En el cajón manda un solo desplazamiento, el suyo: dos zonas que se
     desplazan por separado, con el dedo y una dentro de la otra, es un enredo. */
  .rutas { flex: none; }
  .rutas__lista { overflow: visible; }

  /*
   * La ficha deja de ser una columna del panel y pasa a ser una hoja que sube
   * desde abajo, por encima del plano. Antes empujaba el mapa hacia arriba: al
   * tocar una estación, el plano cambiaba de tamaño y de sitio justo cuando se
   * quería mirarlo. Ahora el plano no se entera.
   *
   * Se queda siempre en el árbol —fuera de la pantalla— para poder animar el
   * subir y el bajar; visibility la saca del tabulador mientras está abajo.
   */
  .ficha-estacion {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 10;
    display: flex;
    /* De borde a borde: sin esto gana el ancho de columna que trae de
       horizontal y la hoja saldría estrecha, pegada a un lado. */
    width: auto;
    max-height: 68vh;
    max-height: 68svh;
    /* Sin aire arriba: ese hueco lo pone el asa, que va pegada al borde */
    padding: 0 clamp(0.9rem, 4vw, 1.4rem) calc(1rem + env(safe-area-inset-bottom));
    gap: 0.75rem;
    background: var(--panel);
    border: 0;
    border-top: 1px solid var(--linea);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 30px rgb(0 0 0 / 0.28);
    overscroll-behavior: contain;
    visibility: hidden;
    transform: translateY(100%);
    transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1), visibility 0.28s;
  }
  body[data-estacion="si"] .ficha-estacion {
    visibility: visible;
    transform: translateY(0);
  }
  /* Arriba, que abajo es donde sube la hoja de la estación */
  .mapa__mandos {
    top: 0.5rem;
    bottom: auto;
  }
  #zPanel { display: grid; }
  #zPanel[aria-expanded="true"] {
    color: var(--carbon);
    background: var(--acento);
    border-color: var(--acento);
  }

  /*
   * La barrita se ve de 4 px pero se agarra de 20: el dedo no apunta tan fino.
   * Va pegada arriba —sticky— para poder bajar la hoja aunque se haya bajado
   * leyendo una estación con muchas salidas.
   */
  .ficha-estacion__asa {
    position: sticky;
    top: 0;
    z-index: 1;
    flex: none;
    display: grid;
    place-items: center;
    height: 1.4rem;
    background: var(--panel);
    cursor: grab;
    touch-action: none;
  }
  .ficha-estacion__asa::before {
    content: "";
    width: 2.5rem;
    height: 0.25rem;
    border-radius: 999px;
    background: var(--linea);
  }
  /* El asa ya baja la hoja de un gesto; la × sobra y quita sitio al nombre */
  .ficha-estacion__cerrar { display: none; }
  .ficha-estacion h2 { font-size: 1.25rem; }
  .ficha-estacion__ir { margin-top: 0.35rem; padding: 0.7rem 0.8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ficha-estacion { transition: none; }
}

/* ── Andén ───────────────────────────────────────── */
.anden {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: clamp(0.6rem, 2vh, 1.5rem) clamp(0.75rem, 3vw, 2rem);
  gap: clamp(0.5rem, 2vh, 1.25rem);
}

/*
 * Dos filas: arriba la etiqueta con las chapas y el reloj; abajo el nombre, que
 * se queda con el ancho entero. Es una rejilla y no una fila de cajas porque el
 * nombre tiene que cruzar por debajo de las tres, no repartirse el sitio con
 * ellas.
 *
 * Centrado y no por la línea base: entre una etiqueta de 0.65rem y un reloj que
 * puede ir a 1.6rem, la línea base deja el reloj colgando de lo alto.
 */
.anden__cabecera {
  flex: none;
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "etiqueta lineas hora"
    "nombre   nombre nombre";
  align-items: center;
  column-gap: clamp(0.5rem, 2vw, 1rem);
  padding-bottom: clamp(0.4rem, 1.5vh, 0.9rem);
  border-bottom: 1px solid var(--linea);
}
.anden__cabecera > .panel__etiqueta { grid-area: etiqueta; }
.anden__lineas { grid-area: lineas; }
.anden__hora { grid-area: hora; }
.anden__estacion { grid-area: nombre; }

.anden__estacion {
  font-size: clamp(1.3rem, 4.5vh, 2.6rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  /* Es el único control de la pantalla: cambiar de estación. Sin adornos —al
     pasajero no le dice nada— pero con cursor, para quien la instala. */
  cursor: pointer;
}

.anden__lineas {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
/*
 * Chapa con el código de la línea, no un punto de color. Es la misma forma que
 * la del mapa (.codigo), y por la misma razón: el color solo no basta para
 * decir de qué línea es una estación.
 */
.anden__insignia {
  padding: 0.14rem 0.5rem;
  border-radius: 999px;
  font-family: var(--display);
  font-size: clamp(0.68rem, 1.6vh, 0.85rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.03em;
  color: #fff;
  /* La Línea 1 es ámbar y se come el texto blanco; la sombra lo despega sin
     tener que saber de qué línea se trata. */
  text-shadow: 0 0 2px rgb(0 0 0 / 0.45);
  white-space: nowrap;
}

.anden__hora {
  font-family: var(--mono);
  font-size: clamp(1rem, 3vh, 1.6rem);
  color: var(--tenue);
}

/* La tabla de llegadas */
.anden__tabla {
  flex: 1;
  min-height: 0;
  list-style: none;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(0.35rem, 1.2vh, 0.75rem);
  transition: opacity 0.3s;
}

.llegada {
  flex: none;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: clamp(0.6rem, 2vw, 1.25rem);
  padding: clamp(0.5rem, 1.6vh, 1rem) clamp(0.6rem, 2vw, 1.1rem);
  border: 1px solid var(--linea);
  border-left-width: 5px;
  border-radius: 8px;
  background: var(--panel);
}

.llegada__linea {
  font-family: var(--mono);
  font-size: clamp(0.8rem, 2vh, 1rem);
  font-weight: 500;
  text-transform: uppercase;
}

.llegada__destino {
  font-size: clamp(1rem, 3.2vh, 1.9rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.llegada__destino::before {
  content: "→ ";
  color: var(--tenue);
}

.llegada__tiempo {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
  font-variant-numeric: tabular-nums;
}
.llegada__valor {
  font-size: clamp(1.4rem, 4.5vh, 2.8rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
}
.llegada__unidad {
  font-size: clamp(0.7rem, 1.8vh, 1rem);
  color: var(--tenue);
}

/* El próximo tren manda: es lo que se lee desde el fondo del andén */
.llegada--proxima .llegada__valor { color: var(--acento); }

/* Con el tren en el andén, la fila entera se enciende */
.llegada--anden {
  border-color: var(--verde);
  background: color-mix(in srgb, var(--verde) 12%, var(--panel));
}
.llegada--anden .llegada__valor {
  font-size: clamp(1.1rem, 3.2vh, 1.9rem);
  color: var(--verde);
}
.llegada--anden .llegada__unidad { display: none; }

.anden__vacio {
  flex: 1;
  display: grid;
  place-content: center;
  text-align: center;
  gap: 0.5rem;
  color: var(--tenue);
}
.anden__vacio p { font-size: clamp(1rem, 3vh, 1.4rem); color: var(--tinta); }
.anden__vacio span { font-size: 0.9rem; }
.anden__vacio a { color: var(--acento); }

/* Selector de estación, cuando la página se abre sin ?estacion= */
.selector {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(0.6rem, 2vh, 1.2rem);
  padding: clamp(1rem, 4vh, 2.5rem) clamp(1rem, 4vw, 2rem);
}
.selector h1 {
  flex: none;
  font-size: clamp(1.2rem, 3.5vh, 1.8rem);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.selector__lista {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.5rem;
  align-content: start;
}
.selector__lista a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--linea);
  border-radius: 8px;
  background: var(--panel);
  color: var(--tinta);
  text-decoration: none;
  font-size: 0.95rem;
  transition: border-color 0.15s, background 0.15s;
}
.selector__lista a:hover { border-color: var(--acento); background: var(--tecla); }
.selector__puntos { display: flex; gap: 3px; }
.selector__punto { width: 8px; height: 8px; border-radius: 50%; }

/* La vista manda qué se ve: el selector o el andén */
body[data-vista="anden"] .selector,
body[data-vista="eligiendo"] .anden { display: none; }

/* ── Administración ──────────────────────────────── */
.admin {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: clamp(0.6rem, 2vw, 1.25rem);
  padding: clamp(0.6rem, 2vh, 1.25rem);
  overflow: hidden;
}

.admin__lateral {
  flex: none;
  width: clamp(230px, 28vw, 330px);
  display: flex;
  flex-direction: column;
  gap: clamp(0.6rem, 2vh, 1rem);
  overflow-y: auto;
}

/*
 * Ida y Vuelta se reparten el ancho a partes iguales, igual que el Entrar /
 * Crear cuenta del portal: no son un filtro colgado de una esquina sino las dos
 * mitades de una misma decisión, y con el ancho de sus palabras "Ida" salía
 * bastante más chico que "Vuelta" y no se leían como opciones del mismo peso.
 */
#sentidos button { flex: 1 1 0; min-width: 0; }

.admin__flota {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--linea);
  border-radius: 10px;
  background: var(--panel);
  overflow: hidden;
}

.admin__cabecera {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.6rem, 2vh, 1rem);
  border-bottom: 1px solid var(--linea);
}

/* Lo único que se desplaza en toda la página, y por dentro */
.admin__lista {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  list-style: none;
  padding: clamp(0.5rem, 1.5vh, 0.85rem);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.tren-fila {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--linea);
  border-left-width: 4px;
  border-radius: 8px;
  background: var(--hueco);
}
.tren-fila[data-pausado="si"] { opacity: 0.55; }

.tren-fila__matricula {
  font-family: var(--mono);
  font-size: 0.9rem;
  font-weight: 500;
}
.tren-fila__donde {
  font-size: 0.85rem;
  color: var(--tenue);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tren-fila__acciones { display: flex; gap: 0.3rem; }
.tren-fila__acciones a,
.tren-fila__acciones button {
  font-family: var(--display);
  font-size: 0.75rem;
  color: var(--tenue);
  background: none;
  border: 1px solid var(--linea);
  border-radius: 6px;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.tren-fila__acciones a { text-decoration: none; }
.tren-fila__acciones a:hover,
.tren-fila__acciones button:hover { color: var(--tinta); border-color: var(--tenue); }
.tren-fila__acciones button.peligro:hover { color: var(--rojo); border-color: var(--rojo); }

.admin__vacio {
  flex: 1;
  display: grid;
  place-content: center;
  text-align: center;
  padding: 2rem;
  color: var(--tenue);
  font-size: 0.9rem;
  line-height: 1.6;
}

.admin__aviso {
  flex: none;
  padding: 0.6rem 0.8rem;
  border-radius: 8px;
  font-size: 0.85rem;
  background: color-mix(in srgb, var(--rojo) 18%, var(--panel));
  color: var(--tinta);
}
.admin__aviso[data-tono="ok"] {
  background: color-mix(in srgb, var(--verde) 18%, var(--panel));
}

/* La nota de que esto todavía no pide credenciales */
/* Quién está dentro. Discreto: importa saberlo, no mirarlo. */
.admin__quien {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.85rem;
  border: 1px solid var(--linea);
  border-radius: 8px;
  font-size: 0.8rem;
  color: var(--tenue);
}
.admin__quien span { color: var(--tinta); }
.admin__quien button {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--tenue);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.admin__quien button:hover { color: var(--tinta); }

/* ── La puerta de la consola ─────────────────────── */
/* La consola no se desplaza, así que la puerta ocupa lo que queda bajo la barra
   y centra su caja. El overflow es para pantallas muy bajas, no para la vista
   normal: ahí cabe entera. */
.puerta {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 5vh, 3rem) 1rem;
}
.puerta__caja {
  width: min(420px, 100%);
  padding: clamp(1.25rem, 4vw, 2rem);
}
.puerta__caja h1 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0.4rem 0 0.6rem;
}
.puerta__texto {
  color: var(--tenue);
  font-size: 0.9rem;
  line-height: 1.6;
  margin-bottom: 1.25rem;
}
.puerta__caja form { display: flex; flex-direction: column; gap: 0.75rem; }
.puerta__pie {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--linea);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--tenue);
}
.puerta__pie a { color: var(--acento); }

@media (max-aspect-ratio: 1/1) {
  .admin { flex-direction: column; }
  .admin__lateral { width: auto; flex: none; }
}

/* ── Pantalla de a bordo ─────────────────────────── */
/*
 * La tira que va dentro del vagón. Se diseña para una pantalla muy ancha y muy
 * baja —las alargadas que van sobre las puertas— y de ahí sale todo lo demás:
 * dos bloques en fila, tipografía enorme y ni un elemento que no se lea de pie
 * y en movimiento.
 *
 * En una pantalla normal o en vertical se apila, pero el caso que manda es el
 * apaisado extremo.
 */
.bordo {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

body[data-vista="eligiendo"] .bordo,
body[data-vista="tren"] .selector { display: none; }

.bordo__cabecera {
  flex: none;
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 2vw, 1.5rem);
  padding: clamp(0.35rem, 1.6vh, 0.8rem) clamp(0.75rem, 2.5vw, 1.75rem);
  border-bottom: 1px solid var(--linea);
  background: var(--panel);
}

/* La línea, con su color de verdad */
.bordo__linea {
  flex: none;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--color-linea, var(--acento));
  color: #fff;
  font-size: clamp(0.7rem, 1.8vh, 0.95rem);
  font-weight: 700;
  text-shadow: 0 0 2px rgba(0, 0, 0, 0.4);
  white-space: nowrap;
}

.bordo__destino {
  flex: 1;
  min-width: 0;
  font-size: clamp(0.85rem, 2.2vh, 1.2rem);
  font-weight: 500;
  color: var(--tenue);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bordo__hora {
  flex: none;
  font-size: clamp(0.85rem, 2.2vh, 1.2rem);
  color: var(--tenue);
}

/* La hora y la megafonía van juntas: en apaisado cierran la fila por la derecha */
.bordo__pie {
  flex: none;
  display: flex;
  align-items: center;
  gap: clamp(0.4rem, 1.2vw, 0.9rem);
}

/*
 * En vertical la cabecera se apila y se centra: la línea de titular, debajo a
 * dónde va, y debajo la hora con la megafonía. Es el orden en que se mira de
 * pie en un vagón, y ya no compite por el ancho con nada.
 */
@media (max-aspect-ratio: 1/1) {
  .bordo__cabecera {
    flex-direction: column;
    align-items: center;
    gap: 0.45rem;
    padding: 0.7rem 1rem 0.85rem;
    /* La barra de arriba ya es la banda elevada; dos seguidas se leen como una */
    background: none;
  }
  /*
   * De titular. Se mide en vw y no en vh porque lo que la aprieta es el ancho:
   * "Línea 2 · Occidente – Oriente" cabe justo en un teléfono corriente. Y por
   * si acaso no cabe —una pantalla más estrecha, una línea con nombre más
   * largo—, parte en dos líneas equilibradas en vez de salirse.
   */
  .bordo__linea {
    max-width: 100%;
    padding: 0.35rem 1.1rem;
    font-size: clamp(1.05rem, 4.2vw, 1.5rem);
    line-height: 1.25;
    text-align: center;
    white-space: normal;
    text-wrap: balance;
  }
  .bordo__destino {
    /* Sin flex:1, que en columna crecería a lo alto en vez de a lo ancho */
    flex: none;
    max-width: 100%;
    font-size: clamp(0.95rem, 2.4vh, 1.15rem);
    text-align: center;
  }
  /* Con el selector de locutor puesto son tres cosas: que bajen antes de salirse */
  .bordo__pie {
    gap: 0.6rem;
    flex-wrap: wrap;
    justify-content: center;
  }
}

.bordo__cuerpo {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(0.75rem, 3vh, 2rem);
  padding: clamp(0.6rem, 3vh, 2rem) clamp(0.75rem, 3vw, 2.5rem);
}

.bordo__ahora {
  flex: none;
  min-width: 0;
}

/* Lo único que hay que poder leer desde el otro extremo del vagón */
.bordo__estacion {
  font-size: clamp(1.8rem, 11vh, 5.5rem);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.035em;
  margin: 0.15em 0 0.1em;
}

.bordo__detalle {
  font-size: clamp(0.9rem, 3vh, 1.6rem);
  font-weight: 500;
  color: var(--acento);
}

/* Parado: el aviso se pone en verde, que es lo que dice "puedes bajar" */
body[data-estado="detenido"] .bordo__detalle,
body[data-estado="terminal"] .bordo__detalle { color: var(--verde); }
body[data-estado="programado"] .bordo__detalle { color: var(--tenue); }

/* ── El recorrido ────────────────────────────────── */
.recorrido {
  flex: none;
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: 0;
}

.recorrido__parada {
  flex: 1;
  min-width: 0;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.3rem, 1.2vh, 0.6rem);
  padding-top: 0.5rem;
}

/* El hilo que une las paradas: medio a cada lado, para que no sobresalga */
.recorrido__parada::before,
.recorrido__parada::after {
  content: "";
  position: absolute;
  top: calc(0.5rem + 6px);
  height: 4px;
  background: var(--color-linea);
  opacity: 0.35;
}
.recorrido__parada::before { left: 0; right: 50%; }
.recorrido__parada::after { left: 50%; right: 0; }
.recorrido__parada:first-child::before,
.recorrido__parada:last-child::after { display: none; }

.recorrido__punto {
  position: relative;
  z-index: 1;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--carbon);
  border: 3px solid var(--color-linea);
  transition: width 0.2s, height 0.2s;
}

.recorrido__nombre {
  font-size: clamp(0.55rem, 1.6vh, 0.85rem);
  line-height: 1.25;
  text-align: center;
  color: var(--tenue);
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

/* Por donde ya pasamos se apaga; lo que falta queda a media luz */
.recorrido__parada[data-parada="pasada"] { opacity: 0.32; }
.recorrido__parada[data-parada="pasada"] .recorrido__punto {
  background: var(--color-linea);
}

.recorrido__parada[data-parada="actual"] .recorrido__punto {
  width: 22px;
  height: 22px;
  background: var(--color-linea);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-linea) 30%, transparent);
}
.recorrido__parada[data-parada="actual"] .recorrido__nombre {
  color: var(--tinta);
  font-weight: 700;
}

/* Con el tren parado, la estación late */
body[data-estado="detenido"] .recorrido__parada[data-parada="actual"] .recorrido__punto,
body[data-estado="terminal"] .recorrido__parada[data-parada="actual"] .recorrido__punto {
  animation: latido-parada 1.6s ease-in-out infinite;
}

@keyframes latido-parada {
  0%, 100% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-linea) 30%, transparent); }
  50%      { box-shadow: 0 0 0 11px color-mix(in srgb, var(--color-linea) 8%, transparent); }
}

/*
 * El caso que manda: la pantalla alargada de encima de las puertas. Ahí el
 * nombre y el recorrido van uno al lado del otro, no apilados, y el nombre se
 * come todo el alto que pueda.
 */
@media (min-aspect-ratio: 5/2) {
  .bordo__cuerpo {
    flex-direction: row;
    align-items: center;
    gap: clamp(1rem, 4vw, 3.5rem);
  }
  .bordo__ahora { flex: 0 1 40%; }
  .recorrido { flex: 1; align-self: center; }
  .bordo__estacion { font-size: clamp(2rem, 20vh, 7rem); }
  .recorrido__nombre { -webkit-line-clamp: 3; }
}

/* En vertical el recorrido no cabe en fila: se pone en columna */
@media (max-aspect-ratio: 3/4) {
  .recorrido {
    flex-direction: column;
    align-items: stretch;
    overflow-y: auto;
    min-height: 0;
    flex: 1;
  }
  .recorrido__parada {
    flex: none;
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
    padding: 0.28rem 0;
  }
  .recorrido__parada::before,
  .recorrido__parada::after {
    top: auto;
    left: 6px;
    right: auto;
    width: 4px;
    height: 50%;
  }
  .recorrido__parada::before { top: 0; }
  .recorrido__parada::after { bottom: 0; }
  .recorrido__nombre { text-align: left; font-size: 0.95rem; -webkit-line-clamp: 1; }
}

.bordo__retirado {
  flex: none;
  padding: 0.8rem 1rem;
  text-align: center;
  background: color-mix(in srgb, var(--rojo) 18%, var(--panel));
}
.bordo__retirado a { color: var(--acento); }

/* Pista de dónde va cada tren, en el selector */
.selector__pista {
  display: block;
  font-size: 0.78rem;
  color: var(--tenue);
}
.selector__vacio {
  flex: none;
  color: var(--tenue);
  font-size: 0.9rem;
}
.selector__vacio a { color: var(--acento); }

/* ── Entrar con Google, cuando llegue ─────────────── */
/*
 * Sale en los dos logins que hay —el del portal y el de la consola— y va
 * deshabilitado diciéndolo. Enseñarlo funcionando cuando no lo está sería peor
 * que no enseñarlo: así se ve que está previsto y que todavía no toca.
 *
 * Se apoya en .form__acciones button.ghost, que ya le da la forma; esto solo
 * coloca el logotipo y la etiqueta.
 */
.google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
}
.google:disabled { cursor: not-allowed; }
.google svg { flex: none; }

.google__nota {
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  background: var(--hueco);
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
