/* Buslandia — estilos compartidos.
   Paleta: neutro con sesgo azul-verde, carmin para el trazado activo (contrasta
   fuerte contra el gris y el verde de las teselas de OSM), teal para lo bueno,
   ambar para lo aproximado. */

:root{
  --fondo:#eceff0; --panel:#ffffff; --panel2:#f6f8f8;
  --tinta:#18212a; --suave:#5d6b76; --linea:#d3dadd;
  --ruta:#d81e5b; --hecho:#9aa5ad; --ok:#0d7a6b; --aviso:#b0721a; --mal:#c0392b;
  --bus:#1565c0; --espera:#e53935; --yo:#0d7a6b;
  --sombra:0 2px 12px rgba(20,30,40,.10);
}
@media (prefers-color-scheme:dark){
  :root{
    --fondo:#0e1419; --panel:#161e25; --panel2:#1c252d;
    --tinta:#e6ecf0; --suave:#94a3ae; --linea:#26313a;
    --ruta:#ff5c86; --hecho:#5d6b76; --ok:#3fbfa9; --aviso:#d9a03f; --mal:#e57373;
    --bus:#64b5f6; --espera:#ff6b6b; --yo:#3fbfa9;
    --sombra:0 2px 14px rgba(0,0,0,.4);
  }
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; background:var(--fondo); color:var(--tinta);
  font-family:ui-sans-serif,system-ui,'Segoe UI',Roboto,sans-serif;
  line-height:1.5; -webkit-text-size-adjust:100%;
  /* En el celular el borde de la pantalla puede tener muescas y bordes curvos */
  --seguro-arriba:env(safe-area-inset-top,0px);
  --seguro-abajo:env(safe-area-inset-bottom,0px);
  --seguro-izq:env(safe-area-inset-left,0px);
  --seguro-der:env(safe-area-inset-right,0px);
  --cabecera:54px;
}
:focus-visible{outline:2px solid var(--ruta); outline-offset:2px}
@media (prefers-reduced-motion:reduce){ *{transition:none!important; animation:none!important} }

/* ---------- tipografia ---------- */
h1{font-size:22px; font-weight:650; margin:0; letter-spacing:-.01em; text-wrap:balance}
h2{font-size:15px; font-weight:650; margin:0}
.rotulo{font-size:11px; text-transform:uppercase; letter-spacing:.11em; color:var(--suave); font-weight:600}
.mono{font-family:ui-monospace,'Cascadia Code',Consolas,monospace; font-variant-numeric:tabular-nums}

/* ---------- controles ---------- */
button,.btn{
  font:inherit; font-weight:600; cursor:pointer; border:1px solid transparent;
  border-radius:9px; padding:11px 18px; background:var(--tinta); color:var(--fondo);
  transition:opacity .12s ease, transform .06s ease;
  /* 44 px es el mínimo para que un dedo acierte sin pelear */
  min-height:44px;
  touch-action:manipulation;
}
button:hover,.btn:hover{opacity:.88}
button:active,.btn:active{transform:translateY(1px)}
button:disabled{opacity:.45; cursor:not-allowed; transform:none}
button.suave,.btn.suave{background:var(--panel); color:var(--tinta); border-color:var(--linea)}
button.acento,.btn.acento{background:var(--ruta); color:#fff}
button.peligro,.btn.peligro{background:var(--mal); color:#fff}
button.chico,.btn.chico{padding:7px 13px; font-size:13px; border-radius:7px; min-height:38px}
/* .btn sobre un enlace: se ve como botón pero sigue siendo un enlace de verdad,
   así el navegador lo abre en otra pestaña solo, y el clic del medio funciona. */
a.btn{display:flex; align-items:center; justify-content:center; gap:7px; text-decoration:none}

input,select{
  font:inherit; width:100%; padding:11px 13px; border-radius:9px;
  border:1px solid var(--linea); background:var(--panel); color:var(--tinta);
  /* Menos de 16 px hace que el iPhone haga zoom solo al enfocar el campo */
  font-size:16px; min-height:46px;
}
@media (min-width:760px){ input,select{font-size:15px; min-height:44px} }
input::placeholder{color:var(--suave)}
label{display:block; font-size:13px; font-weight:600; margin:0 0 5px; color:var(--suave)}
.campo{margin-bottom:14px}

/* ---------- piezas ---------- */
.tarjeta{background:var(--panel); border:1px solid var(--linea); border-radius:12px; box-shadow:var(--sombra)}
.chip{display:inline-block; padding:2px 9px; border-radius:20px; font-size:11.5px; font-weight:650; white-space:nowrap}
.chip.ok{background:color-mix(in oklab,var(--ok) 17%,transparent); color:var(--ok)}
.chip.aviso{background:color-mix(in oklab,var(--aviso) 19%,transparent); color:var(--aviso)}
.chip.ruta{background:color-mix(in oklab,var(--ruta) 15%,transparent); color:var(--ruta)}
.chip.bus{background:color-mix(in oklab,var(--bus) 17%,transparent); color:var(--bus)}

.nota{
  padding:10px 13px; border-radius:9px; font-size:13px;
  background:color-mix(in oklab,var(--aviso) 13%,transparent); color:var(--tinta);
  border:1px solid color-mix(in oklab,var(--aviso) 32%,transparent);
}
.nota.mala{background:color-mix(in oklab,var(--mal) 13%,transparent); border-color:color-mix(in oklab,var(--mal) 34%,transparent)}
.nota.buena{background:color-mix(in oklab,var(--ok) 13%,transparent); border-color:color-mix(in oklab,var(--ok) 32%,transparent)}

.placa{
  display:grid; place-items:center; min-width:52px; height:34px; padding:0 8px; border-radius:6px;
  background:var(--tinta); color:var(--fondo); font-weight:700; font-size:16px;
  font-variant-numeric:tabular-nums; flex:none;
}

/* ---------- mapa ---------- */
/* El color exacto de la tierra en las teselas de OpenStreetMap. Importa que sea
   ESTE y no un gris del tema: con la cámara de navegación inclinada el mapa
   termina en alguna parte, y si el fondo es del mismo color que la tierra ese
   borde no se ve. Con un gris distinto se notaba el corte como una raya. */
:root{--suelo-mapa:#f2efe9}
@media (prefers-color-scheme:dark){
  /* el mismo color, ya pasado por el filtro que oscurece las teselas */
  :root{--suelo-mapa:#14171c}
}
#mapa{position:absolute; inset:0; background:var(--suelo-mapa)}
.leaflet-container{background:var(--suelo-mapa); font-family:inherit}
/* En modo oscuro se apagan las teselas para que el trazado no compita con ellas */
@media (prefers-color-scheme:dark){
  .leaflet-tile-pane{filter:invert(1) hue-rotate(180deg) brightness(.82) contrast(.92)}
}
.marca-num{
  background:var(--ruta); color:#fff; border-radius:50%; width:22px; height:22px;
  display:grid; place-items:center; font:650 11px/1 ui-sans-serif,system-ui;
  border:2px solid var(--panel); box-shadow:0 1px 4px rgba(0,0,0,.3);
}
.marca-bus{
  background:var(--bus); color:#fff; border-radius:7px; padding:3px 6px;
  font:650 11px/1.2 ui-sans-serif,system-ui; border:2px solid var(--panel);
  box-shadow:0 1px 5px rgba(0,0,0,.35); white-space:nowrap; text-align:center;
}
.marca-espera{
  background:var(--espera); border-radius:50%; width:15px; height:15px;
  border:2px solid var(--panel); box-shadow:0 0 0 4px color-mix(in oklab,var(--espera) 28%,transparent);
}
.marca-yo{
  background:var(--yo); border-radius:50%; width:17px; height:17px;
  border:3px solid var(--panel); box-shadow:0 0 0 6px color-mix(in oklab,var(--yo) 24%,transparent);
}
/* Navegando, el punto se vuelve una flecha que apunta para donde vas: es lo que
   da la sensación de ir navegando y no la de un punto suelto en el mapa. */
.marca-rumbo{
  width:30px; height:30px; display:grid; place-items:center;
  transition:transform .35s ease-out;
}
.marca-rumbo::before{
  content:''; width:0; height:0;
  border-left:9px solid transparent; border-right:9px solid transparent;
  border-bottom:22px solid var(--yo);
  filter:drop-shadow(0 0 2px var(--panel)) drop-shadow(0 0 3px rgba(0,0,0,.35));
}
.marca-rumbo.bus::before{border-bottom-color:var(--bus)}
/* Dónde subirse y dónde bajarse del bus. Tienen que cantar a la vista: son los
   dos momentos en que el usuario tiene que hacer algo. */
.marca-parada{
  display:flex; align-items:center; gap:5px; padding:4px 9px 4px 5px; border-radius:20px;
  background:var(--panel); border:2px solid var(--linea); box-shadow:0 2px 7px rgba(0,0,0,.3);
  font:650 12px/1 ui-sans-serif,system-ui; color:var(--tinta); white-space:nowrap;
}
.marca-parada b{
  display:grid; place-items:center; width:20px; height:20px; border-radius:50%;
  color:#fff; font-size:12px; flex:none;
}
.marca-parada.subir{border-color:var(--ok)}
.marca-parada.subir b{background:var(--ok)}
.marca-parada.bajar{border-color:var(--ruta)}
.marca-parada.bajar b{background:var(--ruta)}

/* Leyenda de los tramos del viaje, con el color de cada uno */
.leyenda-tramos{display:flex; flex-direction:column; gap:5px; margin-top:9px}
.leyenda-tramos div{display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--suave)}
.leyenda-tramos i{width:22px; height:5px; border-radius:3px; flex:none}
.leyenda-tramos i.pie{background:repeating-linear-gradient(90deg,var(--pie) 0 3px,transparent 3px 7px); height:5px}

.marca-ab{
  display:grid; place-items:center; width:27px; height:27px; border-radius:50% 50% 50% 6px;
  transform:rotate(-45deg); font:700 13px/1 ui-sans-serif,system-ui; color:#fff;
  border:2px solid var(--panel); box-shadow:0 2px 6px rgba(0,0,0,.35);
}
.marca-ab span{transform:rotate(45deg)}
.marca-ab.a{background:var(--ok)} .marca-ab.b{background:var(--ruta)}

/* ================================================================
   Pantallas con mapa: cabecera + hoja de contenido.
   Móvil primero. Los controles del mapa NO flotan sueltos sobre el
   mapa: viven dentro de la hoja, que es lo que se adapta al alto de
   la pantalla. Así en un celular no queda nada tapando el mapa ni
   botones sueltos por encima.
   ================================================================ */

.pantalla-mapa{
  overflow:hidden; overscroll-behavior:none;
  /* 100dvh, no 100vh: en el móvil la barra del navegador aparece y
     desaparece, y con vh el mapa queda cortado por debajo */
  --alto-mapa:calc(100dvh - var(--cabecera));
  --lente:calc(1.6 * var(--alto-mapa));    /* distancia de la cámara al suelo */
}
.pantalla-mapa #mapa{
  position:fixed; inset:0; top:var(--cabecera);
  height:var(--alto-mapa);
}

/* ---- zoom y crédito: FUERA del mapa ----
   Van como hermanos del mapa, no dentro. Así siguen derechos y en su sitio
   cuando la cámara se inclina y el mapa gira con el rumbo. */
.controles-mapa{
  position:fixed; z-index:15; right:calc(9px + var(--seguro-der));
  top:calc(var(--cabecera) + 9px + var(--seguro-arriba));
  display:flex; flex-direction:column; gap:5px;
}
.controles-mapa button{
  width:38px; height:38px; padding:0; font-size:19px; line-height:1; font-weight:600;
  background:var(--panel); color:var(--tinta); border:1px solid var(--linea);
  border-radius:9px; box-shadow:0 1px 4px rgba(0,0,0,.16);
}
.controles-mapa button:hover{background:var(--panel2)}
.credito-mapa{
  position:fixed; z-index:15; bottom:0; left:0; margin:0;
  max-width:62vw; padding:1px 5px; font-size:10px; line-height:1.5;
  color:var(--suave); background:color-mix(in oklab,var(--panel) 86%,transparent);
  border-top-right-radius:5px; pointer-events:auto;
}
.credito-mapa a{color:inherit}
/* En el celular la hoja tapa la parte de abajo: el crédito se sube encima. */
@media (max-width:759px){ .credito-mapa{bottom:calc(var(--alto-hoja,0px))} }

/* ---- cabecera ---- */
.barra-sup{
  position:fixed; top:0; left:0; right:0; z-index:20;
  min-height:var(--cabecera);
  padding:6px calc(10px + var(--seguro-der)) 6px calc(10px + var(--seguro-izq));
  padding-top:calc(6px + var(--seguro-arriba));
  display:flex; align-items:center; gap:8px;
  background:color-mix(in oklab,var(--panel) 94%,transparent);
  backdrop-filter:blur(9px); border-bottom:1px solid var(--linea);
}
.barra-sup .placa{min-width:36px; height:30px; font-size:14px; padding:0 6px}
.barra-sup .titulo{font-weight:650; font-size:14.5px; line-height:1.2}
.barra-sup .sub{font-size:11.5px; color:var(--suave); line-height:1.25}
.luz{width:8px; height:8px; border-radius:50%; background:var(--mal); flex:none}
.luz.on{background:var(--ok)}
/* En pantallas angostas los botones de la cabecera quedan solo con su icono */
.barra-sup .solo-icono{display:none}
@media (max-width:479px){
  .barra-sup .con-texto{display:none}
  .barra-sup .solo-icono{display:inline}
  .barra-sup button{padding:8px 10px; min-width:40px}
}

/* ---- hoja inferior ---- */
.hoja{
  position:fixed; z-index:20; left:0; right:0; bottom:0;
  display:flex; flex-direction:column;
  /* Tope al 62% de la pantalla: en un celular chico el contenido crecía hasta
     dejar el mapa en una franja inútil. Lo que no cabe se desplaza adentro. */
  max-height:min(62dvh, calc(100dvh - var(--cabecera) - 8px));
  background:var(--panel); border-top:1px solid var(--linea);
  border-radius:16px 16px 0 0; box-shadow:0 -3px 20px rgba(20,30,40,.16);
  transition:transform .22s ease;
}
.hoja > .cuerpo{
  overflow-y:auto; -webkit-overflow-scrolling:touch; overscroll-behavior:contain;
  padding:0 calc(14px + var(--seguro-izq)) calc(14px + var(--seguro-abajo)) calc(14px + var(--seguro-der));
}
/* Plegada: solo se ve la barra de control, y el mapa queda libre */
.hoja.plegada > .cuerpo{display:none}

/* Minimizada: NO se ve nada del menú, la pantalla entera es mapa. Lo único que
   queda es el botón redondo del bus, que lo trae de vuelta. */
.hoja.minimizada{display:none}

.flotante-bus{
  position:fixed; z-index:30;
  right:calc(12px + var(--seguro-der));
  bottom:calc(12px + var(--seguro-abajo));
  width:58px; height:58px; padding:0; border-radius:50%; font-size:27px; line-height:1;
  display:grid; place-items:center;
  background:var(--panel); color:var(--tinta); border:1px solid var(--linea);
  box-shadow:0 3px 15px rgba(20,30,40,.26);
}
/* Minimizado, el botón de Centrar tampoco se ve. Si el mapa dejó de seguirte,
   el bus late para que se note que hay que tocarlo para volver al menú. */
.flotante-bus.avisando{
  background:var(--ruta); color:#fff; border-color:transparent;
  animation:latir 1.8s ease-in-out infinite;
}
@media (prefers-reduced-motion:reduce){ .flotante-bus.avisando{animation:none} }

/* barra de agarre + controles del mapa, siempre visible */
.hoja .mango{
  flex:none; display:flex; align-items:center; gap:8px;
  padding:8px calc(12px + var(--seguro-der)) 8px calc(12px + var(--seguro-izq));
  border-bottom:1px solid transparent;
}
.hoja:not(.plegada) .mango{border-bottom-color:var(--linea)}
.hoja .tirador{
  flex:none; width:44px; height:26px; padding:0; border:none; background:transparent;
  display:grid; place-items:center; cursor:pointer; border-radius:8px;
}
.hoja .tirador::before{content:''; width:34px; height:4px; border-radius:3px; background:var(--linea)}
.hoja .tirador:hover::before{background:var(--suave)}
/* Minimizar: guarda el menú entero. Va aparte del tirador, que solo pliega. */
.hoja .minimizar{
  flex:none; width:38px; height:38px; padding:0; font-size:17px; line-height:1;
  background:transparent; color:var(--suave); border:1px solid var(--linea);
  border-radius:9px; display:grid; place-items:center;
}
.hoja .minimizar:hover{background:var(--panel2); color:var(--tinta)}

/* Segmentado de modos de mapa: reemplaza los botones que flotaban */
.modos{display:flex; gap:4px; margin-left:auto; background:var(--panel2);
  padding:3px; border-radius:10px}
.modos button{
  background:transparent; color:var(--suave); border:none; border-radius:8px;
  padding:8px 11px; font-size:13px; font-weight:600; min-height:38px;
  display:flex; align-items:center; gap:5px; white-space:nowrap;
}
.modos button.on{background:var(--panel); color:var(--tinta); box-shadow:var(--sombra)}
.modos button:disabled{opacity:.4}

/* Botón de centrar: solo existe navegando. Apagado mientras el mapa te sigue;
   encendido y latiendo apenas movés el mapa a mano, para que se note que hay
   que tocarlo para volver. */
.modos button#btnRecentrar{color:var(--suave)}
.modos button#btnRecentrar.suelto{
  background:var(--ruta); color:#fff; box-shadow:var(--sombra);
  animation:latir 1.8s ease-in-out infinite;
}
@keyframes latir{
  0%,100%{box-shadow:0 0 0 0 color-mix(in oklab,var(--ruta) 55%,transparent)}
  50%{box-shadow:0 0 0 7px color-mix(in oklab,var(--ruta) 0%,transparent)}
}
.modos .rotulo-modo{display:none}
@media (min-width:420px){ .modos .rotulo-modo{display:inline} }

/* Distintivo "3D" cuando la cámara va inclinada. Tocando el mismo botón de
   Navegación se alterna, así que conviene que se vea en cuál de las dos está. */
.modos button.tridi::after{
  content:"3D"; font-size:9.5px; font-weight:800; letter-spacing:.4px;
  background:var(--ruta); color:#fff; border-radius:4px; padding:1px 3px;
}

/* ---- avisos flotantes ---- */
.pantalla-mapa #avisos{
  position:fixed; z-index:40; left:50%; transform:translateX(-50%);
  top:calc(var(--cabecera) + 6px + var(--seguro-arriba));
  display:flex; flex-direction:column; gap:8px;
  /* El descuento de 108px deja libre la columna de los botones de zoom, a la
     derecha: centrados y anchos, los avisos los tapaban. */
  width:min(430px,calc(100vw - 108px)); pointer-events:none;
}
.pantalla-mapa #avisos > *{pointer-events:auto}
/* Cuando la hoja va al costado, los avisos se corren sobre el mapa: centrados
   en la pantalla quedaban tapando los botones de modo del panel. */
@media (min-width:760px){
  .pantalla-mapa #avisos{left:auto; right:16px; transform:none; width:min(400px,calc(100vw - 440px))}
}
@media (max-height:520px) and (orientation:landscape){
  .pantalla-mapa #avisos{left:auto; right:12px; transform:none; width:min(380px,calc(100vw - 380px))}
}

/* Pantallas bajitas (celulares chicos): la hoja cede más espacio al mapa, si no
   queda una franja de mapa demasiado angosta para ver por dónde va uno. */
@media (max-height:700px){
  .hoja{max-height:min(55dvh, calc(100dvh - var(--cabecera) - 8px))}
}

/* En celular la hoja tapa la parte de abajo: la atribución de OpenStreetMap y
   la escala se suben por encima de ella. --alto-hoja lo mantiene el JS. */
@media (max-width:759px){
  .pantalla-mapa .leaflet-bottom{bottom:var(--alto-hoja,0px); transition:bottom .22s ease}
}

/* ---- tablet y PC: la hoja pasa a ser tarjeta lateral ---- */
@media (min-width:760px){
  .hoja{
    left:calc(14px + var(--seguro-izq)); right:auto; bottom:14px;
    width:390px; max-height:calc(100dvh - var(--cabecera) - 28px);
    border-radius:14px; border:1px solid var(--linea);
  }
  .hoja .tirador{display:none}
  .hoja .mango{padding-top:12px}
  .modos{margin-left:0; width:100%}
  .modos button{flex:1; justify-content:center}
}

/* ---- celular acostado: poco alto, se usa a lo ancho ---- */
@media (max-height:520px) and (orientation:landscape){
  .hoja{
    left:calc(8px + var(--seguro-izq)); right:auto; bottom:8px; top:calc(var(--cabecera) + 8px);
    width:min(330px,46vw); max-height:none; border-radius:12px; border:1px solid var(--linea);
  }
  .hoja .tirador{display:none}
  :root{--cabecera:46px}
}

/* ================================================================
   Vista de navegación inclinada, como la de Waze o DiDi.

   La cámara baja del cenit y se pone casi al nivel de la calle, y el mapa gira
   con el rumbo del GPS: uno siempre va "hacia arriba" de la pantalla, que es lo
   que hace que se entienda de un vistazo por dónde doblar.

   Leaflet no sabe rotar ni inclinar, así que se transforma el contenedor: se le
   aplica perspectiva, se inclina y se gira. El `scale` es necesario porque al
   girar un rectángulo quedan esquinas vacías, y hay que agrandarlo para que siga
   tapando la pantalla.

   Detalle importante: las marcas se contrarrestan (`rotate` y `rotateX` al
   revés) para que queden PARADAS mirando al usuario. Sin eso, los carteles de
   "bajate acá" quedarían acostados sobre el pavimento e ilegibles.
   ================================================================ */

.pantalla-mapa{--giro:0deg; --inclina:0deg}

/* Plano no lleva transformación ninguna: así el mapa se dibuja nítido, sin pasar
   por la GPU. La transición de "sin transformar" a inclinado se anima igual. */
.pantalla-mapa #mapa{
  transform-origin:50% 50%;
  transition:transform .45s cubic-bezier(.22,.61,.36,1);
}

/* Al inclinar la cámara hace falta mapa MÁS ALLÁ del borde de la pantalla: lo
   que antes estaba al frente ahora se ve a lo lejos. Por eso el contenedor se
   agranda a 2.5 veces la pantalla manteniendo el mismo centro — el usuario
   queda exactamente donde estaba, solo que ahora hay paisaje adelante.
   Ojo: agrandar el contenedor NO cambia la escala del mapa (Leaflet conserva el
   centro y los píxeles por metro), solo añade zona fuera de pantalla. */
.pantalla-mapa.tridi #mapa{
  /* CUADRADO, y de tres veces el alto visible. Cuadrado porque el mapa además
     gira con el rumbo: si fuera alargado, al ir en diagonal el borde del
     contenedor entraría en pantalla. Con el lado igual en las dos direcciones
     hay siempre el mismo mapa hacia adelante, se vaya hacia donde se vaya. */
  /* 2.6 veces: lo justo para que no se vea el borde, sin pedir teselas de más.
     Lo poco que falte hasta el horizonte lo tapa la neblina de más abajo. */
  --lado:calc(2.6 * var(--alto-mapa));
  width:var(--lado); height:var(--lado); right:auto;
  left:calc(50vw - var(--lado) / 2);
  top:calc(var(--cabecera) + var(--alto-mapa) / 2 - var(--lado) / 2);
  --inclina:45deg;
  /* El usuario baja al 65% de lo que se VE del mapa, como en Waze: uno va abajo
     y el camino que falta ocupa el resto de la pantalla. En el celular hay que
     descontar la hoja de abajo, o el usuario quedaría escondido detrás. */
  --baja:calc(0.15 * (var(--alto-mapa) - var(--alto-hoja,0px)));
  transform:translateY(var(--baja))
            perspective(var(--lente))
            rotateX(var(--inclina))
            rotate(var(--giro));
  backface-visibility:hidden;
}

/* Las marcas se enderezan para que queden PARADAS mirando al usuario. Sin esto
   los carteles de "bajate acá" quedarían acostados sobre el pavimento. Se
   deshacen los dos giros en orden inverso; la perspectiva sí se les deja, así
   las paradas lejanas se ven más chiquitas, que es lo que da la sensación 3D. */
.pantalla-mapa.tridi .leaflet-marker-icon > div,
.pantalla-mapa.tridi .leaflet-popup{
  transform:rotate(calc(-1 * var(--giro))) rotateX(calc(-1 * var(--inclina)));
  transform-origin:center bottom;
}
/* Neblina del horizonte. Hace dos cosas a la vez: le da profundidad a la vista
   —lo lejano se desvanece, como en Waze— y tapa el borde del contenedor, que por
   más grande que se haga siempre termina en alguna parte. Sin ella, en algunos
   rumbos se vería el corte del mapa como una línea recta en el aire. */
.pantalla-mapa.tridi::before{
  content:""; position:fixed; z-index:5; pointer-events:none;
  left:0; right:0; top:var(--cabecera);
  height:calc(0.26 * var(--alto-mapa));
  background:linear-gradient(to bottom,
    var(--suelo-mapa) 0%,
    color-mix(in oklab,var(--suelo-mapa) 84%,transparent) 30%,
    color-mix(in oklab,var(--suelo-mapa) 42%,transparent) 62%,
    transparent 100%);
}

/* En pantalla ancha la hoja va al costado, no abajo: no le quita alto al mapa. */
@media (min-width:760px){
  .pantalla-mapa.tridi #mapa{--baja:calc(0.15 * var(--alto-mapa))}
}

/* La escala en metros no tiene sentido con la cámara inclinada: cada franja de
   la pantalla está a distinta distancia. Los botones de zoom y el crédito de
   OpenStreetMap viven fuera del mapa, así que no se inclinan. */
.pantalla-mapa.tridi .leaflet-control-container{display:none}

@media (prefers-reduced-motion:reduce){
  .pantalla-mapa #mapa{transition:none}
}

/* ---------- cartel de alerta ----------
   Sale cuando el usuario tiene que bajarse o cambiar de transporte. Va arriba,
   grande y en color fuerte: está pensado para despertar a alguien que se
   quedó dormido en el bus, no para decorar. */
.cartel-alerta{
  position:fixed; z-index:60; left:50%; transform:translateX(-50%);
  top:calc(var(--cabecera) + 8px + var(--seguro-arriba));
  width:min(460px, calc(100vw - 20px));
  display:flex; align-items:flex-start; gap:10px;
  padding:14px 14px 15px; border-radius:13px;
  background:var(--espera); color:#fff;
  box-shadow:0 6px 26px rgba(0,0,0,.35);
  animation:entra-cartel .25s ease-out, latido-cartel 1.4s ease-in-out 3;
}
.cartel-alerta .titulo{margin:0 0 3px; font-size:18px; font-weight:700; line-height:1.2}
.cartel-alerta .texto{margin:0; font-size:14px; opacity:.95; line-height:1.4}
.cartel-alerta button{
  flex:none; background:rgba(255,255,255,.22); color:#fff; border:none;
  border-radius:9px; padding:7px 11px; font-size:15px; min-height:36px;
}
@keyframes entra-cartel{ from{opacity:0; transform:translate(-50%,-14px)} to{opacity:1; transform:translate(-50%,0)} }
@keyframes latido-cartel{ 0%,100%{box-shadow:0 6px 26px rgba(0,0,0,.35)}
  50%{box-shadow:0 6px 26px rgba(0,0,0,.35), 0 0 0 9px color-mix(in oklab,var(--espera) 40%,transparent)} }
@media (prefers-reduced-motion:reduce){ .cartel-alerta{animation:none} }

/* ---------- utilidades ---------- */
.fila{display:flex; align-items:center; gap:10px}
.fila.entre{justify-content:space-between}
.columna{display:flex; flex-direction:column; gap:10px}
.crece{flex:1; min-width:0}
.oculto{display:none!important}
.recorta{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.centro{text-align:center}
.chiquito{font-size:12.5px; color:var(--suave)}
.cargando{display:inline-block; width:15px; height:15px; border:2px solid var(--linea);
  border-top-color:var(--ruta); border-radius:50%; animation:girar .7s linear infinite}
@keyframes girar{to{transform:rotate(360deg)}}

/* ================================================================
   Alertas del camino: huecos, lluvia, retenes, fotomultas, choques,
   autos varados. Las pone cualquiera y las ve todo el mundo.
   ================================================================ */

/* ---- la chinche en el mapa ---- */
.marca-alerta{
  position:relative; width:34px; height:40px;
  display:grid; place-items:center;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.35));
}
/* La gota de la chinche se dibuja con CSS: un cuadrado con tres esquinas
   redondas y una en punta, girado 45°. Así no hace falta ninguna imagen. */
.marca-alerta::before{
  content:''; position:absolute; inset:0 0 6px 0;
  background:var(--tono); border:2px solid #fff;
  border-radius:50% 50% 50% 4px; transform:rotate(45deg);
}
.marca-alerta .glifo{
  position:relative; font-size:17px; line-height:1; margin-bottom:6px;
  /* el emoji va derecho aunque la gota esté girada */
  filter:drop-shadow(0 1px 1px rgba(0,0,0,.4));
}
/* Con gente diciendo que ya pasó se muestra apagada: sigue ahí, pero en duda. */
.marca-alerta.dudosa{opacity:.62}
.marca-alerta .votos{
  position:absolute; top:-3px; right:-3px; z-index:2;
  min-width:16px; height:16px; padding:0 3px; border-radius:9px;
  background:#fff; color:var(--tono); border:1.5px solid var(--tono);
  font:800 10px/14px ui-sans-serif,system-ui; text-align:center;
}

/* ---- el globo al tocar la chinche ---- */
.globo-alerta{min-width:210px}
.globo-alerta .que{margin:0 0 3px; font-size:15px; font-weight:700;
  display:flex; align-items:center; gap:6px}
.globo-alerta .que .ico{font-size:18px}
.globo-alerta .quien{margin:0 0 10px; font-size:12.5px; color:var(--suave)}
.globo-alerta .nota-votos{margin:7px 0 0; font-size:11.5px; color:var(--suave); line-height:1.4}
.globo-alerta button{width:100%}

/* ---- cartel de "tocá el mapa" ---- */
.banda-alerta{
  position:fixed; z-index:45; left:50%; transform:translateX(-50%);
  top:calc(var(--cabecera) + 8px + var(--seguro-arriba));
  width:min(430px, calc(100vw - 24px));
  display:flex; align-items:center; gap:10px;
  padding:11px 13px; border-radius:12px;
  background:var(--tinta); color:var(--fondo);
  box-shadow:0 4px 18px rgba(0,0,0,.3); font-size:14px; font-weight:600;
}
.banda-alerta .texto{flex:1; min-width:0}
.banda-alerta .cancelar{
  flex:none; padding:7px 11px; min-height:36px; font-size:12.5px;
  background:transparent; color:var(--fondo); border:1px solid currentColor; border-radius:8px;
}
/* Mientras se espera el toque, el cursor lo dice. */
.leaflet-container.senalando{cursor:crosshair}

/* ---- cuadro de diálogo ---- */
.dialogo-alerta{
  border:none; padding:0; background:transparent; max-width:min(420px, calc(100vw - 24px));
}
.dialogo-alerta::backdrop{background:rgba(12,18,24,.55); backdrop-filter:blur(2px)}
.dialogo-alerta .caja-dialogo{
  background:var(--panel); color:var(--tinta); border:1px solid var(--linea);
  border-radius:16px; padding:20px; box-shadow:0 10px 40px rgba(0,0,0,.3);
}
.dialogo-alerta h3{margin:0 0 8px; font-size:17px; line-height:1.35}
.dialogo-alerta .ico-grande{margin:0 0 6px; font-size:38px; line-height:1; text-align:center}
.dialogo-alerta .duo-dialogo{display:grid; grid-template-columns:1fr 1fr; gap:9px; margin-top:16px}
@media (max-width:359px){ .dialogo-alerta .duo-dialogo{grid-template-columns:1fr} }

/* ---- lista de qué se vio ---- */
.tipos-alerta{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin:14px 0}
@media (max-width:379px){ .tipos-alerta{grid-template-columns:1fr} }
.tipo-alerta{
  display:flex; align-items:center; gap:9px; text-align:left;
  padding:12px 11px; min-height:56px; font-size:13.5px; font-weight:650;
  background:var(--panel); color:var(--tinta);
  border:1px solid var(--linea); border-left:5px solid var(--tono); border-radius:11px;
}
.tipo-alerta:hover{background:var(--panel2); border-color:var(--tono)}
.tipo-alerta .glifo{font-size:23px; line-height:1; flex:none}

/* ================================================================
   Cuenta, modo amigable, amigos, enemigos y charla.
   ================================================================ */

/* El diálogo genérico comparte estilo con el de las alertas. */
.dialogo-app{border:none; padding:0; background:transparent; max-width:min(460px, calc(100vw - 20px))}
.dialogo-app::backdrop{background:rgba(12,18,24,.55); backdrop-filter:blur(2px)}
.dialogo-app .caja-dialogo{
  background:var(--panel); color:var(--tinta); border:1px solid var(--linea);
  border-radius:16px; padding:20px; box-shadow:0 10px 40px rgba(0,0,0,.3);
  max-height:min(86dvh, 720px); overflow-y:auto;
}
.dialogo-app h3{margin:0 0 10px; font-size:17px}
.dialogo-app .duo-dialogo{display:grid; grid-template-columns:1fr 1fr; gap:9px; margin-top:14px}
@media (max-width:359px){ .dialogo-app .duo-dialogo{grid-template-columns:1fr} }

/* ---- avatar ---- */
.avatar{border-radius:50%; object-fit:cover; flex:none; display:grid; place-items:center;
  background:var(--panel2); border:1px solid var(--linea); font-size:19px; overflow:hidden}
.avatar.vacio.chofer{background:color-mix(in oklab,var(--bus) 22%,transparent); border-color:var(--bus)}

/* ---- cuenta ---- */
.cab-cuenta{display:flex; align-items:center; gap:12px; margin-bottom:12px}
.fijo-correo{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 12px;
  padding:10px 12px; border-radius:10px; background:var(--panel2); border:1px solid var(--linea);
}
.fijo-correo .rotulo{flex:none}
.fijo-correo .valor{font-weight:650; font-size:13.5px; word-break:break-all}

.datos-cuenta{display:flex; flex-direction:column; gap:7px; margin:0 0 12px}
.fila-dato{
  display:flex; align-items:center; gap:10px; padding:9px 11px;
  border:1px solid var(--linea); border-radius:10px; background:var(--panel);
}
.fila-dato .glifo{font-size:17px; flex:none}
.fila-dato .rotulo{display:block}
.fila-dato .valor{display:block; font-size:14px; font-weight:600}
.fila-dato .valor i{font-weight:400; color:var(--suave)}
.fila-dato .candado{font-size:16px; flex:none; opacity:.75}
.fila-dato .candado.abierto{opacity:1}

/* Candado como botón: es el control de privacidad, tiene que sentirse tocable. */
.fila-editar{margin-bottom:11px}
.con-candado{display:flex; align-items:center; gap:8px}
.con-candado input{min-width:0}
.candado-btn{
  flex:none; width:46px; min-height:46px; padding:0; font-size:19px; line-height:1;
  background:var(--panel2); color:var(--tinta); border:1px solid var(--linea); border-radius:10px;
}
.candado-btn.abierto{
  background:color-mix(in oklab,var(--ok) 16%,transparent);
  border-color:color-mix(in oklab,var(--ok) 45%,transparent);
}

/* ---- gente en el mapa ---- */
.marca-gente{
  position:relative; width:30px; height:30px; border-radius:50%;
  display:grid; place-items:center; font-size:15px;
  background:var(--panel); border:2.5px solid var(--yo);
  box-shadow:0 1px 6px rgba(0,0,0,.35);
}
.marca-gente img{width:100%; height:100%; border-radius:50%; object-fit:cover}
/* El conductor se distingue de un vistazo: borde azul de bus y forma cuadrada. */
.marca-gente.chofer{border-color:var(--bus); border-radius:9px}
.marca-gente .estrella{
  position:absolute; top:-6px; right:-5px; font-size:12px; line-height:1;
  color:#f5b301; text-shadow:0 1px 2px rgba(0,0,0,.5);
}

/* ---- globo de una persona ---- */
.globo-gente{min-width:220px}
.globo-gente .cab{display:flex; align-items:center; gap:10px; margin-bottom:9px}
.globo-gente .nombre{margin:0; font-size:15px; font-weight:700; display:flex; align-items:center; gap:6px}
.globo-gente .chiquito{margin:1px 0 0}
.datos-vistos{display:flex; flex-direction:column; gap:4px; margin:0 0 11px;
  padding:9px 10px; background:var(--panel2); border-radius:9px}
.datos-vistos .dato{margin:0; font-size:13px}
.datos-vistos .dato.vacio{color:var(--suave); font-style:italic}
.acciones-gente{display:flex; flex-direction:column; gap:8px}
.acciones-gente .duo-dialogo{margin-top:0}
.acciones-gente button{font-size:13px; padding:9px 11px; min-height:42px}

/* ---- listas de amigos y enemigos ---- */
.lista-gente{display:flex; flex-direction:column; gap:8px}
.fila-gente{
  display:flex; align-items:center; gap:11px; padding:10px 11px;
  border:1px solid var(--linea); border-radius:11px; background:var(--panel);
}
.fila-gente .nombre{margin:0; font-size:14.5px; font-weight:650}
.fila-gente .chiquito{margin:1px 0 0; display:flex; align-items:center; gap:5px}
.luz-estado{width:9px; height:9px; border-radius:50%; display:inline-block; flex:none}
.luz-estado.verde{background:var(--ok); box-shadow:0 0 0 3px color-mix(in oklab,var(--ok) 26%,transparent)}
.luz-estado.gris{background:var(--hecho)}
.fila-gente .nube{
  position:relative; flex:none; width:46px; min-height:46px; padding:0; font-size:19px;
  background:var(--panel2); color:var(--tinta); border:1px solid var(--linea); border-radius:12px;
}
.fila-gente .nube .globito{
  position:absolute; top:-4px; right:-4px; min-width:18px; height:18px; padding:0 4px;
  border-radius:10px; background:var(--ruta); color:#fff;
  font:800 11px/18px ui-sans-serif,system-ui;
}

/* ---- charla ---- */
.caja-charla{display:flex; flex-direction:column; padding:0!important; overflow:hidden!important}
.cab-charla{
  display:flex; align-items:center; gap:10px; padding:12px 14px;
  border-bottom:1px solid var(--linea); background:var(--panel2);
}
.cab-charla .nombre{margin:0; font-size:15px; font-weight:700}
.cab-charla .chiquito{margin:1px 0 0}
.mensajes{
  flex:1; min-height:180px; max-height:min(52dvh, 380px); overflow-y:auto;
  padding:12px 14px; display:flex; flex-direction:column; gap:7px;
  background:var(--fondo);
}
.mensaje{
  max-width:82%; padding:8px 11px; border-radius:13px; font-size:14px; line-height:1.4;
  display:flex; align-items:flex-end; gap:7px; word-break:break-word;
}
.mensaje.mio{align-self:flex-end; background:var(--ruta); color:#fff; border-bottom-right-radius:4px}
.mensaje.suyo{align-self:flex-start; background:var(--panel); border:1px solid var(--linea);
  border-bottom-left-radius:4px}
.mensaje .hora{font-size:10px; opacity:.7; flex:none; white-space:nowrap}
.fila-enviar{display:flex; gap:8px; padding:11px 12px; border-top:1px solid var(--linea)}
.fila-enviar input{min-width:0}
.fila-enviar button{flex:none}

/* ---- botones del menú, con globito de aviso ---- */
.bloque-social{display:flex; flex-direction:column; gap:8px; margin-top:10px}
.con-globito{position:relative}
.con-globito[data-cuantos]:not([data-cuantos=""])::after{
  content:attr(data-cuantos);
  position:absolute; top:4px; right:6px; min-width:18px; height:18px; padding:0 4px;
  border-radius:10px; background:var(--ruta); color:#fff;
  font:800 11px/18px ui-sans-serif,system-ui;
}
button.on{background:var(--ok); color:#fff; border-color:transparent}
/* Al invitado se le avisa que esto necesita cuenta, en vez de fallar callado. */
button[data-sin-cuenta]{opacity:.55}

/* Eliminar la cuenta: separado del resto y en rojo. Es lo único que no se
   puede deshacer, así que no puede parecerse a los demás botones. */
.zona-peligro{
  margin-top:16px; padding-top:14px; border-top:1px solid var(--linea);
}
.zona-peligro .chiquito{margin:7px 0 0; text-align:center}
