/* AI Camper — Design System v0.2.0
 *
 * Alineado con el STYLE_GUIDE de DashAI Priority Gate, que es el sistema
 * transversal de Trawlingweb (sidebar, tarjetas, claro+oscuro con data-theme,
 * misma escala de radios y sombras).
 *
 * Delta de color: el primario es ÁMBAR CARRETERA (#f59e0b). DashAI usa teal,
 * Voxscope magenta, Feedscale azul, SAT coral. El ámbar no es decorativo: es el
 * color de la variante Equilibrada, que es el diferencial del producto.
 *
 * ── ORDEN DE ESTA HOJA (v0.2.0) ──────────────────────────────────────────
 *
 * MÓVIL PRIMERO. Lo que hay fuera de toda media query ES el teléfono, tal
 * como se aprobó en la maqueta: una columna de cinco hijos —cabecera, control
 * segmentado, cuerpo con scroll, entrada y barra inferior— y nada más.
 *
 * El ESCRITORIO es la excepción, y vive entero en `@media (min-width: 821px)`
 * al final: reañade la barra lateral y pone chat y mapa en paralelo.
 *
 * Estaba al revés hasta el 17 de agosto de 2026, y era la causa de fondo de
 * todos los fallos de maquetación: el móvil eran 35 reglas peleándose con una
 * cadena flex pensada para el escritorio. Faltaba un `min-width: 0` aquí, un
 * `flex: 1` allá, y el mapa medía cero. Ninguno de esos fallos puede darse ya:
 * el teléfono no hereda nada que deshacer.
 *
 * Si añades una regla de layout, la pregunta es «¿cómo es en el teléfono?».
 * El escritorio se corrige después, abajo.
 */

[hidden] { display: none !important; }

:root {
  --primary: #f59e0b;
  --secondary: #d97706;
  --primary-soft: rgba(245, 158, 11, 0.10);

  --bg-main: #f5f4f1;
  --surface-main: #ffffff;
  --surface-2: #faf9f7;
  --text-main: #1c1917;
  --text-muted: #78716c;
  --glass: rgba(255, 255, 255, 0.85);
  --border: rgba(28, 25, 23, 0.10);
  --sombra-card: 0 1px 2px rgba(28,25,23,.05);

  --radius: 12px;
  --radius-lg: 16px;

  --exito: #22c55e;
  --aviso: #f59e0b;
  --error: #ef4444;
  --info: #3b82f6;

  /* Las tres variantes tienen color fijo en toda la app: mapa, tarjetas y
     leyenda. La Equilibrada comparte el primario a propósito. */
  --rapida: #3b82f6;
  --equilibrada: #f59e0b;
  --economica: #22c55e;
  --nucleo: #ef4444;
}

[data-theme="dark"] {
  --bg-main: #0c0a09;
  --surface-main: #1c1917;
  --surface-2: #231f1d;
  --text-main: #fafaf9;
  --text-muted: #a8a29e;
  --glass: rgba(28, 25, 23, 0.85);
  --border: rgba(250, 250, 249, 0.12);
  --sombra-card: 0 1px 2px rgba(0,0,0,.35);
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* La tipografía del sistema, no Inter. Es lo que hace que una pantalla parezca
   del teléfono y no una página web —SF en iOS, Roboto en Android, Segoe en
   Windows—, y viene anotado así en la maqueta aprobada. De paso desaparece la
   petición a Google Fonts, que bloqueaba el primer pintado. */
body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', system-ui, sans-serif;
  background: var(--bg-main);
  color: var(--text-main);
  font-size: 15px;
  line-height: 1.5;
  /* `dvh` y no `vh`.
     En Chrome de Android `100vh` es la altura de la ventana SIN la barra de
     direcciones, no la visible. Con la barra a la vista, los últimos ~56 px de
     la app quedan por debajo del corte —justo donde está la barra inferior—, y
     el usuario se queda sin navegación sin entender por qué. No sale en las
     capturas headless, que no tienen barra de direcciones: lo vio Óscar en su
     teléfono el 17-08-2026. `100vh` queda de respaldo para navegadores viejos. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ── Layout: la columna del teléfono ─────────────────
   Cinco hijos, de arriba abajo: cabecera, segmentado, cuerpo, entrada y barra.
   Solo el cuerpo scrollea; todo lo demás es `flex-shrink: 0`. */

.app-shell { display: flex; flex-direction: column; height: 100vh; height: 100dvh; overflow: hidden; }

/* En un teléfono la barra lateral no existe. Aplastarla arriba era exactamente
   lo que hacía que esto pareciera una web encogida. */
.sidebar {
  display: none;
  width: 220px;
  flex-shrink: 0;
  background: var(--surface-main);
  border-right: 1px solid var(--border);
  flex-direction: column;
  padding: 1.25rem 0;
}

.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0 1.25rem 1.25rem;
  border-bottom: 1px solid var(--border);
}

.sidebar-logo .icono {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: var(--primary-soft);
  border-radius: var(--radius);
  font-size: 20px;
}

.sidebar-logo strong { display: block; font-weight: 800; letter-spacing: -0.01em; }
.sidebar-logo small { color: var(--text-muted); font-size: 0.75rem; }

.sidebar nav { padding: 1rem 0.75rem; flex: 1; display: flex; flex-direction: column; gap: 0.15rem; }

.nav-item {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius);
  color: var(--text-muted);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 600;
  border: none; background: none; width: 100%; text-align: left;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.nav-item svg { width: 18px; height: 18px; }
.nav-item:hover { background: var(--bg-main); color: var(--text-main); }
.nav-item.activo { background: var(--primary); color: #fff; }
.nav-item.activo:hover { background: var(--secondary); }
.nav-item[disabled], .nav-item.deshabilitado { opacity: 0.45; cursor: not-allowed; }
.nav-item[disabled]:hover, .nav-item.deshabilitado:hover { background: none; color: var(--text-muted); }

.sidebar-pie { padding: 0 0.75rem; display: flex; flex-direction: column; gap: 0.4rem; }
.lema {
  color: var(--text-muted); font-size: 0.72rem; line-height: 1.45;
  padding: 0.85rem 0.75rem 0; border-top: 1px solid var(--border); margin-top: 0.6rem;
}

.columna-principal { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
main { flex: 1; min-height: 0; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }

/* ── Cabecera del teléfono ───────────────────────────
   Título de la sección y avatar. Nada más: todo lo que no es navegar vive en
   la hoja del avatar. En escritorio se oculta —allí manda la barra lateral—. */

/* Franja estrecha: a la izquierda quién eres, al lado dónde estás. Todo el
   espacio que se le quite aquí lo gana el contenido, que es lo que se mira. */
.app-header {
  display: flex; align-items: center; gap: 0.6rem;
  flex-shrink: 0;
  padding: calc(0.35rem + env(safe-area-inset-top)) 0.85rem 0.35rem;
  background: var(--surface-main);
  border-bottom: 1px solid var(--border);
}
.app-header .avatar { width: 30px; height: 30px; font-size: 0.72rem; }
/* `.nombre-app` y no `.marca`: ese nombre ya lo usaba la palomita de selección
   de Guardadas, con `display: none`, y se la comía entera. Una clase genérica
   en una hoja de 800 líneas colisiona tarde o temprano. */
.app-header .nombre-app {
  font-size: 0.95rem; font-weight: 500; letter-spacing: -0.01em;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.app-header .nombre-app b { font-weight: 800; color: var(--text-main); }

/* ── Navegación inferior ─────────────────────────────
   Donde llega el pulgar, como en Twitter o LinkedIn. */

.barra-inferior {
  display: flex;
  flex-shrink: 0;
  background: var(--surface-main);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}
.barra-inferior a,
.barra-inferior button {
  flex: 1; min-width: 0;
  padding: 0.35rem 0.15rem 0.3rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.12rem;
  text-decoration: none;
  background: none; border: none; cursor: pointer;
  font: inherit; font-size: 0.62rem; font-weight: 600;
  color: var(--text-muted);
}
.barra-inferior svg { width: 19px; height: 19px; }
.barra-inferior a[aria-current="page"] { color: var(--secondary); }
.barra-inferior a:active,
.barra-inferior button:active { background: var(--surface-2); }

/* «Nueva ruta», en el centro y destacada. Es la acción que nadie encontraba, y
   por no encontrarla se pedían destinos nuevos dentro de una conversación
   abierta, machacando la ruta que ya tenía guardada. */
.barra-inferior .nueva-ruta { color: var(--secondary); }
.barra-inferior .nueva-ruta svg {
  width: 30px; height: 30px;
  padding: 5px; margin-top: -2px;
  border-radius: 50%;
  background: var(--primary); color: #fff;
}
.barra-inferior .nueva-ruta:active svg { transform: scale(0.92); }

.avatar {
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%; border: none; cursor: pointer;
  background: linear-gradient(140deg, var(--primary), var(--secondary));
  color: #fff; font-size: 0.8rem; font-weight: 700;
  display: grid; place-items: center;
}
.avatar:active { transform: scale(0.94); }
.avatar.grande { width: 44px; height: 44px; font-size: 1rem; }

/* El «+» de la cabecera móvil no tenía estilo: salía el botón nativo del
   navegador, un rectángulo blanco sobre fondo oscuro. */
.icono-btn {
  width: 34px; height: 34px; flex-shrink: 0;
  border: none; border-radius: 50%;
  background: var(--surface-2); color: var(--text-main);
  display: grid; place-items: center; cursor: pointer;
}
.icono-btn svg { width: 19px; height: 19px; }
.icono-btn:active { transform: scale(0.94); background: var(--primary-soft); }

/* ── Hoja de cuenta ──────────────────────────────────
   Todo lo que no es navegar: vehículo, conversación nueva, tema y salir. */

.velo {
  position: fixed; inset: 0; z-index: 900;
  background: rgba(12, 10, 9, 0.45);
  opacity: 0; pointer-events: none; transition: opacity 0.18s;
}
.velo.abierto { opacity: 1; pointer-events: auto; }

.hoja {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 901;
  max-width: 460px; margin: 0 auto;
  background: var(--surface-main);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 0.6rem 1rem calc(1.2rem + env(safe-area-inset-bottom));
  transform: translateY(110%);
  transition: transform 0.24s cubic-bezier(0.32, 0.72, 0, 1);
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.18);
}
.hoja.abierta { transform: translateY(0); }

.asa { width: 34px; height: 4px; border-radius: 2px; background: var(--border); margin: 0 auto 0.85rem; }

.perfil { display: flex; align-items: center; gap: 0.65rem; padding-bottom: 0.85rem; border-bottom: 1px solid var(--border); }
.perfil .nom { font-size: 0.92rem; font-weight: 700; }
.perfil .veh { font-size: 0.74rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.opciones { display: flex; flex-direction: column; padding-top: 0.35rem; }
.opcion {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.7rem 0.2rem;
  border: none; background: transparent; cursor: pointer;
  font: inherit; font-size: 0.9rem; color: var(--text-main); text-align: left;
  border-radius: var(--radius);
}
.opcion:active { background: var(--surface-2); }
.opcion svg { width: 18px; height: 18px; color: var(--text-muted); flex-shrink: 0; }
.opcion .cola { margin-left: auto; font-size: 0.77rem; color: var(--text-muted); }
.opcion.salir, .opcion.salir svg { color: #dc2626; }

/* La hoja de exportación reutiliza .hoja y .opcion, pero necesita cabecera y
   agrupar por aplicación: casi nunca es un enlace, son varios tramos. */
.hoja-cab { padding: 0 0.2rem 0.7rem; border-bottom: 1px solid var(--border); }
.hoja-cab h3 { font-size: 1rem; font-weight: 800; }
.hoja-cab p { font-size: 0.78rem; color: var(--text-muted); margin-top: 0.1rem; }

.exp-grupo { padding-top: 0.7rem; }
.exp-grupo + .exp-grupo { border-top: 1px solid var(--border); margin-top: 0.3rem; }
.exp-titulo {
  font-size: 0.7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-muted);
  padding: 0 0.2rem 0.15rem;
}
.exp-nota { font-size: 0.73rem; color: var(--text-muted); padding: 0 0.2rem 0.35rem; line-height: 1.4; }

/* Los enlaces de la hoja se comportan como las opciones de cuenta. */
a.opcion { text-decoration: none; }
a.opcion .cola svg { width: 14px; height: 14px; vertical-align: middle; }

/* Con varios tramos la lista crece: la hoja tiene que poder desplazarse sin
   comerse la pantalla. */
.hoja { max-height: 82vh; max-height: 82dvh; overflow-y: auto; }

/* ── Botones ─────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  padding: 0.6rem 1rem;
  border-radius: var(--radius);
  font-family: inherit; font-size: 0.88rem; font-weight: 600;
  cursor: pointer; border: 1px solid transparent;
  transition: opacity 0.15s, background 0.15s;
}
.btn:hover { opacity: 0.85; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; }

.btn-primary { background: var(--primary); color: #fff; }
.btn-ghost { background: transparent; color: var(--text-main); border-color: var(--border); }
.btn-ghost:hover { background: var(--bg-main); opacity: 1; }

.btn-icono {
  width: 34px; height: 34px; padding: 0;
  border-radius: 50%; border: 1px solid var(--border);
  background: transparent; color: var(--text-muted);
  display: grid; place-items: center; cursor: pointer;
}
.btn-icono:hover { background: var(--bg-main); color: var(--text-main); }
.btn-icono svg { width: 16px; height: 16px; }

/* ── Vistas y hero ───────────────────────────────────── */

.vista { display: none; flex: 1; min-height: 0; min-width: 0; }
.vista.activa { display: flex; }

.hero { padding: 1.5rem 1.75rem 1rem; }
.hero h1 { font-size: 1.5rem; font-weight: 800; letter-spacing: -0.02em; }
.hero p { color: var(--text-muted); font-size: 0.9rem; margin-top: 0.15rem; }

/* ── Planificador: chat + mapa ─────────────────────────
   En el teléfono no caben los dos a la vez: se alternan con el control
   segmentado. Los paneles se ocultan con la propiedad `hidden` desde
   planificador.js —`[hidden] { display: none !important }` está arriba—, así
   que aquí NO puede haber un `display: none` de partida: dejaría el mapa
   invisible para siempre. */

#vista-planificador { flex-direction: column; }

.panel-chat, #vista-planificador .panel-mapa {
  width: 100%; flex: 1; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  background: var(--surface-main);
}

/* Control segmentado Conversación / Mapa. */
/* Dos pastillas pequeñas con su icono, no una barra de lado a lado.
   Ocupando todo el ancho pesaban como navegación principal de la app, y no lo
   son: son dos vistas de la ruta a la que acompañan.
   Viven a la derecha del nombre del viaje, en su misma fila: en una fila propia
   se llevaban una franja del centro de la pantalla para dos botones. */
.pestanas {
  display: flex; gap: 3px;
  flex-shrink: 0; align-self: center;
  margin: 0 0 0 auto;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
}
/* Solo el icono. Debajo del nombre del viaje, con dos opciones y una activa,
   la palabra no aporta: el bot y el mapa se entienden solos y ocupan la mitad. */
.pestanas button {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 40px; height: 30px;
  background: transparent; border: none; border-radius: 999px;
  color: var(--text-muted); cursor: pointer;
}
.pestanas button svg { width: 17px; height: 17px; }
.pestanas button.activo {
  background: var(--surface-main); color: var(--text-main);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10);
}

/* Sobra en el teléfono: el título ya está en la cabecera de la app. */
.panel-cabecera {
  display: none;
  padding: 1.1rem 1.25rem;
  border-bottom: 1px solid var(--border);
  background: var(--glass);
  backdrop-filter: blur(8px);
}
.panel-cabecera h1 { font-size: 1.15rem; font-weight: 800; letter-spacing: -0.01em; }
.panel-cabecera p { color: var(--text-muted); font-size: 0.82rem; margin-top: 0.1rem; }

.mensajes { flex: 1; min-width: 0; overflow-y: auto; padding: 1.1rem; display: flex; flex-direction: column; gap: 0.85rem; }

.mensaje { display: flex; }
.mensaje.tu { justify-content: flex-end; }

.burbuja {
  max-width: 90%;
  padding: 0.75rem 0.95rem;
  border-radius: var(--radius-lg);
  font-size: 0.89rem;
  border: 1px solid var(--border);
  background: var(--bg-main);
}
.mensaje.tu .burbuja { background: var(--primary); color: #fff; border-color: transparent; border-bottom-right-radius: 4px; }
.mensaje.ia .burbuja { border-bottom-left-radius: 4px; }

.burbuja p + p { margin-top: 0.55rem; }
.burbuja strong { font-weight: 700; }
.burbuja ul, .burbuja ol { margin: 0.5rem 0 0.5rem 1.1rem; }
.burbuja li { margin: 0.15rem 0; }
.burbuja a { color: var(--primary); font-weight: 600; }
.mensaje.tu .burbuja a { color: #fff; text-decoration: underline; }

.burbuja table { width: 100%; border-collapse: collapse; margin: 0.6rem 0; font-size: 0.82rem; }
.burbuja th, .burbuja td { padding: 0.35rem 0.5rem; border-bottom: 1px solid var(--border); text-align: left; }
.burbuja th { font-weight: 700; color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; }

/* El aviso de que Rutila ha llevado esto a un viaje nuevo. No es de nadie —ni
   del usuario ni de Rutila—, así que va centrado y sin cola: lo que dice es
   dónde ha quedado la ruta anterior, y eso tiene que verse a la primera. */
.mensaje.sistema { justify-content: center; }
.mensaje.sistema .burbuja {
  max-width: 100%;
  background: var(--primary-soft);
  border-color: var(--primary);
  font-size: 0.83rem;
  text-align: center;
}

.apunte { color: var(--text-muted); font-size: 0.8rem; }
.error { color: var(--error); }

.herramientas { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.5rem; }
.chip {
  font-size: 0.68rem; font-weight: 700;
  padding: 0.15rem 0.45rem;
  border-radius: 6px;
  background: var(--primary-soft);
  color: var(--secondary);
}

/* Comparativa de variantes dentro de la burbuja.
   Tal cual la maqueta: al leer «te recomiendo la Económica» tienes ahí mismo el
   tiempo y el coste de cada una, sin cambiar de pestaña. El borde superior
   mantiene el color que la variante tiene en el mapa y en la tira detallada. */
.variantes-mini { display: flex; gap: 0.4rem; margin-top: 0.6rem; }

/* Son botones, no tarjetas: pulsar una es el momento de decisión del producto.
   Antes el usuario terminaba de leer la respuesta y no tenía dónde pulsar. */
.v-mini {
  flex: 1; min-width: 0;
  padding: 0.5rem 0.55rem;
  border: 1px solid var(--border);
  border-top: 3px solid var(--text-muted);
  border-radius: 10px;
  background: var(--surface-main);
  font: inherit; color: inherit; text-align: left;
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s;
}
.v-mini:hover { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.10); }
.v-mini:active { transform: scale(0.97); }
.v-mini:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.v-mini.rapida { border-top-color: var(--rapida); }
.v-mini.equilibrada { border-top-color: var(--equilibrada); }
.v-mini.economica { border-top-color: var(--economica); }
/* La recomendada, marcada también en su caja: el veredicto de arriba dice el
   nombre, pero al pulsar se busca la caja, no el nombre. */
.v-mini.elegida { border-color: var(--text-main); }

/* El veredicto: qué ruta recomendamos y por qué, pintado por el código.
   Va ANTES de las tres cajas porque es la conclusión, y la conclusión se lee
   primero; las cajas son el detalle que la sostiene. */
.veredicto {
  margin: 0.6rem 0 0.5rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--color-ruta, var(--primary));
  border-radius: 10px;
  background: var(--surface-2);
}
.veredicto.rapida { --color-ruta: var(--rapida); }
.veredicto.equilibrada { --color-ruta: var(--equilibrada); }
.veredicto.economica { --color-ruta: var(--economica); }
.veredicto .cabeza {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.86rem; font-weight: 600;
}
.veredicto .cabeza svg { width: 16px; height: 16px; color: var(--color-ruta, var(--primary)); flex-shrink: 0; }
.veredicto .cabeza strong { color: var(--color-ruta, var(--primary)); }
.veredicto ul { margin: 0.35rem 0 0; padding-left: 1rem; }
.veredicto .razones li { font-size: 0.78rem; line-height: 1.5; }
.veredicto .razones li.pero { color: var(--text-muted); }
/* Por qué NO las otras. En gris y más pequeño: es el contrapeso, no el
   titular — pero sin él una recomendación es una orden. */
.veredicto .descartes {
  margin-top: 0.4rem; padding-top: 0.4rem;
  border-top: 1px solid var(--border);
  list-style: none; padding-left: 0;
}
.veredicto .descartes li { font-size: 0.72rem; color: var(--text-muted); line-height: 1.5; }

.v-mini .nom {
  font-size: 0.68rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.v-mini .val { font-size: 0.82rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.v-mini .aux { font-size: 0.66rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* Dentro de la burbuja del usuario el fondo es ámbar: el color de texto se
   hereda y dejaría las cajas ilegibles. No debería pasar —la comparativa solo
   la pinta Rutila— pero cuesta una línea asegurarlo. */
.mensaje.tu .v-mini { color: var(--text-main); }

.cargando { display: flex; gap: 0.28rem; padding: 0.2rem 0; }
.cargando i {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-muted);
  animation: latido 1.3s infinite;
}
.cargando i:nth-child(2) { animation-delay: 0.18s; }
.cargando i:nth-child(3) { animation-delay: 0.36s; }
@keyframes latido { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }

/* Los botones, centrados con la caja de texto, no pegados a su base.
   Con flex-end quedaban descolgados al fondo —la caja son dos líneas de alto y
   ellos 34 px— y con el texto escrito el de enviar se hundía todavía más. */
.entrada {
  display: flex; gap: 0.5rem; align-items: center;
  padding: 0.85rem 1rem calc(0.85rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
  background: var(--surface-main);
}
.entrada textarea {
  flex: 1; resize: none;
  font-family: inherit; font-size: 0.9rem; line-height: 1.45;
  padding: 0.6rem 0.85rem;
  background: var(--bg-main);
  color: var(--text-main);
  border: 1px solid var(--border);
  border-radius: 20px;
  max-height: 140px;
}
.entrada textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

/* El botón de enviar era un <button> sin estilo: se veía el botón nativo del
   navegador, gris y con borde, al lado de un campo redondeado. Lo destapó la
   primera captura de la app a 390 px. */
#btn-enviar {
  width: 38px; height: 38px; flex-shrink: 0;
  border: none; border-radius: 50%;
  background: var(--primary); color: #fff;
  display: grid; place-items: center;
  cursor: pointer;
}
#btn-enviar svg { width: 17px; height: 17px; }
#btn-enviar:disabled { opacity: 0.45; cursor: default; }
#btn-enviar:active { transform: scale(0.94); }

/* ── Mapa y variantes ────────────────────────────────── */

.panel-mapa { flex: 1; display: flex; flex-direction: column; min-width: 0; }
#mapa { flex: 1; min-height: 0; background: var(--bg-main); }

.variantes {
  display: flex; gap: 0.75rem;
  padding: 0.7rem 0.85rem;
  min-width: 0;
  flex-wrap: nowrap;
  overflow-x: auto;
  border-top: 1px solid var(--border);
  background: var(--surface-main);
}
.variantes:empty { display: none; }

/* De cuándo son los euros de la ruta abierta.
   Fuera de .variantes a propósito: esa es una tira horizontal con scroll y
   aquí dentro el aviso saldría como una tarjeta más. */
#aviso-precios:empty { display: none; }

.aviso-precios {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  padding: 0.65rem 0.85rem;
  border-top: 1px solid var(--border);
  background: var(--primary-soft);
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--text-main);
}
.aviso-precios i {
  flex: 0 0 auto;
  width: 16px; height: 16px;
  margin-top: 0.15rem;
  color: var(--aviso);
}
.aviso-precios strong { font-weight: 700; }
/* Cada matiz en su línea: el mensaje tiene dos mitades —lo que cambia y lo que
   no— y de corrido se lee como una sola advertencia. */
.aviso-precios .matiz,
.aviso-precios .impactos { display: block; color: var(--text-muted); }
.aviso-precios .impactos { margin-top: 0.15rem; font-variant-numeric: tabular-nums; }
/* ── Categorías de peaje, un bloque por país ─────────── */

.conf-subtitulo {
  font-size: 0.9rem; font-weight: 800; letter-spacing: -0.01em;
  margin-top: 1.1rem;
}

.conf-peajes { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.5rem; }

.conf-peaje-pais {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.7rem 0.85rem;
  background: var(--surface-2);
}
.conf-peaje-pais .cabecera {
  display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem;
}
.conf-peaje-pais .conf-ayuda { margin: 0.15rem 0 0.4rem; }

/* La categoría que se está aplicando, y de dónde sale. Que se vea distinta
   cuando es comprobada es el punto: la diferencia entre lo que dice la tabla y
   lo que te cobran son 48 euros de cada 100 en Francia. */
.conf-peaje-pais .ahora {
  font-size: 0.78rem; font-weight: 700;
  color: var(--text-muted);
  white-space: nowrap;
}
.conf-peaje-pais .ahora.comprobada { color: var(--exito); }

.tarjeta {
  flex: 0 0 auto; min-width: 250px; max-width: 82vw;
  background: var(--surface-main);
  border: 1px solid var(--border);
  border-top: 3px solid var(--text-muted);
  border-radius: var(--radius);
  padding: 0.85rem 0.95rem;
}
.tarjeta.rapida { border-top-color: var(--rapida); }
.tarjeta.equilibrada { border-top-color: var(--equilibrada); box-shadow: 0 0 0 1px var(--primary-soft); }
.tarjeta.economica { border-top-color: var(--economica); }

.tarjeta h3 { font-size: 0.95rem; font-weight: 800; margin-bottom: 0.5rem; }
.dato { display: flex; justify-content: space-between; gap: 0.5rem; font-size: 0.82rem; padding: 0.15rem 0; }
.dato span:first-child { color: var(--text-muted); }
.dato strong { font-weight: 700; }
.estimado, .pendiente { color: var(--text-muted); font-style: italic; }

.rodeadas {
  margin-top: 0.5rem; padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.76rem; color: var(--text-muted); line-height: 1.4;
}
.rodeadas strong { color: var(--text-main); }

/* ── Paradas y Guardadas ─────────────────────────────────
   Este bloque existía y el rediseño móvil lo perdió: app.css se reescribió
   entero y estas reglas no viajaron. Resultado, las dos secciones se pintaban
   con los estilos por defecto del navegador —texto de borde a borde, sin
   tarjetas ni separadores—. Se ve en las capturas del 16 de agosto. */

#vista-paradas { flex-direction: column; }

/* En columna el eje principal es el vertical: sin `flex: 1` el panel mide lo
   que mida su contenido y debajo queda un socavón hasta la barra. */
.paradas-panel {
  width: 100%; flex: 1; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  background: var(--surface-main);
}

/* El mapa de Paradas no cabe en el teléfono; la lista ya dice el desvío. */
#vista-paradas .panel-mapa { display: none; }

/* El hero repetía palabra por palabra lo que ya dice la cabecera de la app:
   «Paradas / Dónde dormir…» dos veces seguidas en 390 px de ancho. */
.paradas-panel .hero { display: none; }

.paradas-controles {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--border);
}
.grupo-filtro { display: flex; gap: 0.35rem; flex-wrap: wrap; }

.filtro {
  padding: 0.32rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-main);
  color: var(--text-main);
  font-family: inherit; font-size: 0.78rem; font-weight: 600;
  cursor: pointer;
}
.filtro:hover { border-color: var(--primary); }
.filtro.activo { background: var(--primary); border-color: var(--primary); color: #fff; }

/* Los filtros de ruta (Prisa · Calma · Ahorro) llevan SU color, el mismo de la
   línea en el mapa y del borde de su tarjeta. Apagados, un punto del color
   delante; encendido, el color relleno. Tres pastillas ámbar idénticas no
   decían de qué ruta eran las paradas que estabas mirando. */
.filtro.ruta { display: inline-flex; align-items: center; gap: 0.35rem; }
.filtro.ruta::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--color-ruta, var(--text-muted));
}
.filtro.ruta.rapida { --color-ruta: var(--rapida); }
.filtro.ruta.equilibrada { --color-ruta: var(--equilibrada); }
.filtro.ruta.economica { --color-ruta: var(--economica); }
.filtro.ruta:hover { border-color: var(--color-ruta, var(--primary)); }
.filtro.ruta.activo {
  background: var(--color-ruta, var(--primary));
  border-color: var(--color-ruta, var(--primary));
  color: #fff;
}
.filtro.ruta.activo::before { background: #fff; }

/* `.lista` es la de Guardadas; `.paradas-lista`, la de Paradas. Mismo scroll:
   son el «cuerpo» de la maqueta, lo único que se desplaza en la pantalla. */
.paradas-lista, .lista {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 0.85rem 0.85rem calc(0.85rem + env(safe-area-inset-bottom));
}
.resumen { color: var(--text-muted); font-size: 0.8rem; margin-bottom: 0.85rem; }

.parada {
  background: var(--surface-main);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.85rem 1rem;
  margin-bottom: 0.7rem;
}
.parada-cab, .parada-top { display: flex; align-items: flex-start; gap: 0.6rem; }
.parada-cab > i, .parada-cab > svg,
.parada-top > i, .parada-top > svg {
  width: 18px; height: 18px; flex-shrink: 0; margin-top: 0.15rem; color: var(--primary);
}
.parada h3, .parada-cab h3 { font-size: 0.92rem; font-weight: 700; line-height: 1.3; }
.parada-cab .ubicacion, .lugar { color: var(--text-muted); font-size: 0.76rem; margin-top: 0.15rem; }

/* «sin nombre en el mapa»: el rótulo lo hemos puesto nosotros a partir del tipo.
   Va discreto y detrás del lugar — es una advertencia sobre el nombre, no un
   defecto del sitio. */
.sin-rotulo {
  display: inline-block; margin-left: 0.4rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--border); border-radius: 999px;
  font-size: 0.66rem; line-height: 1.5;
  color: var(--text-muted);
}
.sin-rotulo:first-child { margin-left: 0; }

.parada[data-clave] { transition: border-color 0.14s; }
.parada[data-clave]:hover { border-color: var(--primary); }

.etapa-badge {
  margin-left: auto; flex-shrink: 0;
  font-size: 0.68rem; font-weight: 700;
  padding: 0.2rem 0.55rem; border-radius: 6px;
  background: var(--primary-soft); color: var(--secondary);
}

.parada-datos {
  display: flex; flex-wrap: wrap; gap: 0.35rem 0.9rem;
  margin-top: 0.55rem; font-size: 0.78rem; color: var(--text-muted);
}
.parada-datos span { display: inline-flex; align-items: center; gap: 0.25rem; }
.parada-datos svg { width: 13px; height: 13px; }

.servicios { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.5rem; }

.parada-pie {
  margin-top: 0.55rem; padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: 0.74rem; color: var(--text-muted);
}
.parada-pie a { color: var(--primary); font-weight: 600; }
.verificado, .sin-verificar { display: inline-flex; align-items: center; gap: 0.25rem; }
.verificado { color: var(--exito); font-weight: 600; }
.sin-verificar { color: var(--text-muted); }
.parada-pie svg { width: 13px; height: 13px; }

/* Barra de selección de Guardadas. */
.barra-lista {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.7rem 0.85rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.barra-lista .acciones { display: flex; align-items: center; gap: 0.5rem; width: 100%; }

/* De qué ruta son las paradas que se están viendo. Va arriba del todo porque
   la sección siempre muestra las de la conversación abierta, y con más de una
   guardada eso hay que decirlo. Lleva al chat de esa ruta. */
.de-la-ruta {
  text-decoration: none; color: inherit;
  background: var(--surface-2);
  gap: 0.65rem;
}
.de-la-ruta:active { background: var(--primary-soft); }
.de-la-ruta > svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--primary); }
.de-la-ruta > svg:last-child { color: var(--text-muted); width: 16px; height: 16px; margin-left: auto; }
.de-la-ruta .cual { min-width: 0; display: flex; flex-direction: column; }
.de-la-ruta strong {
  font-size: 0.88rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.de-la-ruta small { font-size: 0.72rem; color: var(--text-muted); }
.barra-lista .cuenta { flex: 1; font-size: 0.78rem; color: var(--text-muted); }
.filtro.peligro { border-color: #dc2626; color: #dc2626; }
.filtro.peligro:hover:not(:disabled) { background: #dc2626; color: #fff; }
.filtro:disabled { opacity: 0.45; cursor: default; }

/* La marca de seleccionada solo existe en modo selección: fuera de él, un
   círculo vacío en cada tarjeta es ruido permanente por una acción rara. */
.marca { display: none; }
.seleccionando .parada { cursor: pointer; }
.seleccionando .marca {
  display: grid; place-items: center;
  margin-left: auto; flex-shrink: 0;
  width: 22px; height: 22px;
  border: 2px solid var(--border); border-radius: 50%;
  color: transparent;
}
.seleccionando .marca svg { width: 13px; height: 13px; }
.seleccionando .parada.marcada { border-color: var(--primary); background: var(--primary-soft); }
.seleccionando .parada.marcada .marca { background: var(--primary); border-color: var(--primary); color: #fff; }

#mapa-paradas { flex: 1; min-height: 0; background: var(--bg-main); }

.estado-vacio {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 2.5rem 1.25rem; color: var(--text-muted); gap: 0.5rem;
}
.estado-vacio svg { width: 40px; height: 40px; opacity: 0.4; }
.estado-vacio h3 { font-size: 1rem; font-weight: 700; color: var(--text-main); }
.estado-vacio p { font-size: 0.85rem; max-width: 30ch; }

/* ── Login ───────────────────────────────────────────── */

.login-body { display: grid; place-items: center; min-height: 100vh; min-height: 100dvh; padding: 1.5rem; overflow: auto; }
.login-caja {
  width: 100%; max-width: 340px;
  background: var(--surface-main);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 2rem 1.75rem;
}
.login-caja h1 { font-size: 1.35rem; font-weight: 800; text-align: center; }
.login-caja p.sub { color: var(--text-muted); font-size: 0.85rem; text-align: center; margin: 0.3rem 0 1.5rem; }

/* La nota de "acceso por invitacion". Separada del formulario por una linea
   para que se lea como informacion y no como un error del intento anterior. */
.login-acceso {
  margin: 1.5rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--borde, rgba(255,255,255,0.1));
  color: var(--text-muted);
  font-size: 0.8rem;
  line-height: 1.5;
  text-align: center;
}
.login-acceso a { color: var(--acento, #f59e0b); }
.campo { margin-bottom: 0.85rem; }
.campo label {
  display: block; font-size: 0.78rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--text-muted); margin-bottom: 0.3rem;
}
.campo input {
  width: 100%; padding: 0.6rem 0.8rem;
  font-family: inherit; font-size: 0.9rem;
  background: var(--bg-main); color: var(--text-main);
  border: 1px solid var(--border); border-radius: 8px;
}
.campo input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }

/* ═══════════════════════════════════════════════════════
   ESCRITORIO — la excepción, no la base
   ═══════════════════════════════════════════════════════

   Todo lo anterior es el teléfono. Aquí se reañade la barra lateral, se ponen
   chat y mapa en paralelo, y se retiran cabecera y barra inferior, que en una
   pantalla ancha no pintan nada.

   Ningún selector de este bloque necesita `!important` ni pelearse con nada:
   son valores distintos para las mismas propiedades. Si hace falta un truco
   aquí, es señal de que la regla del teléfono está mal planteada. */

@media (min-width: 821px) {

  .app-shell { flex-direction: row; }
  .sidebar { display: flex; }
  .app-header, .barra-inferior, .pestanas { display: none; }

  /* ── Planificador ────────────────────────────────── */

  #vista-planificador { flex-direction: row; }

  .panel-chat {
    width: 420px; flex: 0 0 auto;
    border-right: 1px solid var(--border);
  }
  #vista-planificador .panel-mapa { width: auto; flex: 1; }

  .panel-cabecera { display: block; }
  .entrada textarea { border-radius: var(--radius); }
  .burbuja { max-width: 88%; }

  /* Con sitio de sobra, las variantes se reparten el ancho en vez de pedir
     scroll horizontal. */
  .variantes { padding: 0.85rem; }
  .tarjeta { flex: 1 1 0; min-width: 210px; max-width: none; }

  /* ── Paradas ─────────────────────────────────────── */

  #vista-paradas { flex-direction: row; }

  .paradas-panel {
    width: 440px; flex: 0 0 auto;
    border-right: 1px solid var(--border);
  }
  #vista-paradas .panel-mapa { display: flex; }
  .paradas-panel .hero { display: block; }
  .paradas-controles { padding: 0 1.25rem 0.9rem; border-bottom: 1px solid var(--border); }
  .paradas-lista, .lista { padding: 1rem 1.25rem; }
  .estado-vacio { padding: 3rem 1.5rem; }

  /* ── Hoja de cuenta ──────────────────────────────── */

  /* Una lámina pegada al borde inferior de un monitor se ve fuera de sitio:
     aquí es un diálogo centrado. */
  .hoja {
    top: 50%; bottom: auto; left: 50%; right: auto;
    transform: translate(-50%, -46%) scale(0.98);
    width: 380px;
    border-radius: var(--radius-lg);
    padding: 1.1rem 1.25rem 1.25rem;
    opacity: 0;
    transition: opacity 0.16s, transform 0.16s;
  }
  .hoja.abierta { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .hoja .asa { display: none; }
}

/* El botón de «Estoy aquí», junto al campo de escribir. Se enciende cuando la
   posición ya está compartida, para que se vea que Rutila la tiene. */
#btn-aqui.activo { background: var(--primary); color: #fff; }
#btn-aqui.buscando { opacity: 0.5; }
#btn-aqui.buscando svg { animation: latido 1.1s infinite; }

/* El botón de conversación nueva, con su palabra al lado.
   Un «+» suelto junto al avatar no dice qué hace: se lee como «añadir algo».
   Y lo que hace importa —empieza un viaje nuevo en vez de machacar el que
   tienes guardado—, así que se nombra. */
.icono-btn.con-texto {
  width: auto; border-radius: 999px;
  padding: 0 0.7rem 0 0.55rem;
  gap: 0.3rem;
  grid-auto-flow: column; align-items: center;
  font: inherit; font-size: 0.78rem; font-weight: 600;
}
.icono-btn.con-texto svg { width: 16px; height: 16px; }

/* A qué viaje pertenece el chat.
   Sin color no se lee como pertenencia, se lee como una fila más. Gris cuando
   todavía no hay ruta —«Viaje nuevo» es información, no un hueco— y ámbar en
   cuanto la hay, que es el color del producto. */
.de-la-ruta.viaje { flex-shrink: 0; }
/* El nombre se queda con todo el ancho sobrante y empuja las pestañas al borde;
   si el destino es largo, se corta él, no ellas. */
.de-la-ruta.viaje .cual { flex: 1; }
.de-la-ruta.viaje.con-ruta {
  background: var(--primary-soft);
  border-bottom-color: var(--primary);
}
.de-la-ruta.viaje.con-ruta > svg { color: var(--secondary); }
.de-la-ruta.viaje.con-ruta strong { color: var(--text-main); }
.de-la-ruta.viaje:not(.con-ruta) > svg { color: var(--text-muted); }
.de-la-ruta.viaje:not(.con-ruta) strong { color: var(--text-muted); font-weight: 600; }

/* «Hay mapa nuevo que ver». Un punto, no texto: escribirlo en el botón borraba
   el icono que Lucide acababa de pintar dentro. */
.pestanas button.hay-novedad { position: relative; }
.pestanas button.hay-novedad::after {
  content: ''; position: absolute; top: 4px; right: 7px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--primary);
}

/* `.vista` es flex sin dirección declarada, o sea FILA. Sin esto la barra de
   título y el cuerpo salían uno al lado del otro, con el formulario aplastado
   en una columna de 150 px. Le pasa a cualquier sección nueva. */
#vista-configuracion { flex-direction: column; }

/* ── Configuración ───────────────────────────────────────
   El vehículo y la cuenta. Formulario de móvil: campos grandes, en rejilla de
   dos, y cada grupo con la línea que explica por qué ese número importa —el
   alto decide por qué túneles pasas, no es un dato de inventario—. */
.conf-cuerpo {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 0.85rem 0.85rem calc(1rem + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 0.85rem;
}
.conf-bloque {
  background: var(--surface-main);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.85rem;
  display: flex; flex-direction: column; gap: 0.6rem;
}
.conf-bloque h2 {
  display: flex; align-items: center; gap: 0.45rem;
  font-size: 0.92rem; font-weight: 700;
}
.conf-bloque h2 svg { width: 17px; height: 17px; color: var(--primary); }

.rejilla { display: grid; grid-template-columns: 1fr 1fr; gap: 0.55rem; }
.campo { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.campo.ancho { grid-column: 1 / -1; }
.campo span { font-size: 0.72rem; color: var(--text-muted); font-weight: 600; }
.campo input, .campo select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  font: inherit; font-size: 0.9rem;
  color: var(--text-main); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 10px;
  font-variant-numeric: tabular-nums;
}
.campo input:focus, .campo select:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

/* Las líneas de ayuda no son relleno: cada una evita un error concreto que ya
   ha pasado —el alto sin la baca puesta, la velocidad del límite en vez de la
   real—. Van en gris y pequeñas, debajo de su grupo. */
.conf-ayuda { font-size: 0.72rem; color: var(--text-muted); line-height: 1.5; }
.conf-nota {
  font-size: 0.78rem; line-height: 1.5;
  padding: 0.5rem 0.6rem; border-radius: 10px;
  background: var(--primary-soft); color: var(--text-main);
}

.conf-peaje {
  display: flex; flex-direction: column; gap: 0.5rem;
  padding-top: 0.6rem; border-top: 1px solid var(--border);
}
.conf-check { display: flex; align-items: center; gap: 0.5rem; font-size: 0.82rem; }
.conf-check input { width: 18px; height: 18px; accent-color: var(--primary); flex-shrink: 0; }

.conf-fila {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  font-size: 0.85rem;
}
.conf-fila span { color: var(--text-muted); }

.conf-acciones { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.conf-estado { font-size: 0.75rem; color: var(--text-muted); }
.conf-estado.bien { color: #16a34a; }
.conf-estado.mal { color: #dc2626; }
.btn-ghost.peligro { color: #dc2626; border-color: #dc2626; }

/* Borrar la cuenta. Va al final y separado por una línea porque no es una
   preferencia más: se lleva las rutas, las conversaciones y el vehículo, y
   pegado al resto se pulsa sin querer. */
.conf-borrar {
  margin-top: 1.6rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--border);
}
.conf-borrar .conf-subtitulo { margin-top: 0; color: #dc2626; }
.conf-borrar .conf-ayuda { margin: 0.3rem 0 0.7rem; }

@media (min-width: 821px) {
  .conf-cuerpo { max-width: 640px; }
}
