:root {
  --bg: #1a1a1a;
  --bg-panel: #242424;
  --accent: #f5a623;
  --texto: #f0f0f0;
  --obras: #ff8c00;
  --accidente: #e63946;
  --resto: #4a90d9;
  --highest: #c1121f;
  --ok: #43a047;
}

* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--texto);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  display: flex;
  flex-direction: column;
}

/* El panel de ayuda mueve el foco a su botón ✕ al abrirse (hace falta para que Tab funcione
   bien desde el principio con teclado), pero eso puede pintar el anillo de foco por defecto
   del navegador aunque se haya abierto con un toque, no con teclado. Se controla a mano con
   la clase "user-is-tabbing" (ver app.js): solo se añade tras un Tab real y se quita con
   cualquier puntero (ratón o toque). */
button:focus,
input:focus {
  outline: none;
}

body.user-is-tabbing button:focus,
body.user-is-tabbing input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.app-header {
  background: var(--bg-panel);
  border-bottom: 2px solid var(--accent);
  /* max() con env(safe-area-inset-top): en un navegador normal no cambia nada (el inset vale
     0), pero como PWA instalada en iOS con muesca/dynamic island evita que la cabecera quede
     debajo de ella. */
  padding: max(0.75rem, env(safe-area-inset-top)) 1.25rem 0.75rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.5rem;
}

.app-header h1 {
  margin: 0;
  font-size: 1.4rem;
  color: var(--accent);
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.version {
  font-size: 0.65rem;
  font-weight: 400;
  color: #808080;
}

.subtitle {
  margin: 0;
  font-size: 0.85rem;
  color: #b8b8b8;
  flex: 1 1 auto;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-left: auto;
}

.estado {
  font-size: 0.8rem;
  color: #b8b8b8;
  white-space: nowrap;
}

#btn-refrescar {
  background: var(--accent);
  color: #1a1a1a;
  border: none;
  border-radius: 6px;
  padding: 0.45rem 0.9rem;
  font-weight: 600;
  cursor: pointer;
  font-size: 0.85rem;
  transition: filter 0.15s ease;
}

#btn-refrescar:hover {
  filter: brightness(1.1);
}

#btn-refrescar:disabled {
  opacity: 0.6;
  cursor: default;
}

.help-btn {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid #808080;
  color: #808080;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
}

.help-btn svg {
  display: block;
  width: 13px;
  height: 13px;
}

.help-btn:hover,
.help-btn:active {
  border-color: var(--accent);
  color: var(--accent);
}

main {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
}

#mapa {
  position: absolute;
  inset: 0;
  background: var(--bg);
}

.controles-mapa {
  position: absolute;
  z-index: 1000;
  top: 1rem;
  right: 1rem;
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}

.buscador {
  position: relative;
}

#buscador-input {
  width: 200px;
  max-width: 42vw;
  background: rgba(36, 36, 36, 0.92);
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
  color: var(--texto);
  font-size: 0.85rem;
}

#buscador-input::placeholder {
  color: #808080;
}

#buscador-input:focus {
  border-color: var(--accent);
}

.buscador-sugerencias {
  position: absolute;
  z-index: 1;
  top: 100%;
  left: 0;
  right: 0;
  margin: 0.3rem 0 0;
  padding: 0.3rem 0;
  list-style: none;
  background: rgba(30, 30, 30, 0.98);
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  max-height: 220px;
  overflow-y: auto;
  font-size: 0.8rem;
}

.buscador-sugerencias li {
  padding: 0.4rem 0.7rem;
  cursor: pointer;
  color: var(--texto);
}

.buscador-sugerencias li:hover,
.buscador-sugerencias li.activa {
  background: var(--accent);
  color: #1a1a1a;
}

.buscador-sin-resultados {
  position: absolute;
  top: 100%;
  right: 0;
  margin: 0.3rem 0 0;
  padding: 0.3rem 0.6rem;
  background: rgba(36, 36, 36, 0.92);
  border: 1px solid #3a3a3a;
  border-radius: 6px;
  font-size: 0.75rem;
  color: var(--accidente);
  white-space: nowrap;
}

.btn-ubicacion {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: rgba(36, 36, 36, 0.92);
  border: 1px solid #3a3a3a;
  color: #b8b8b8;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-ubicacion svg {
  display: block;
  width: 17px;
  height: 17px;
}

.btn-ubicacion:hover,
.btn-ubicacion.activo {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-ubicacion:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Halo de precisión + punto de "tu ubicación": mismo lenguaje visual que Google/Apple Maps
   (punto sólido con borde blanco sobre un círculo translúcido), a propósito distinto en forma
   del resto de marcadores aunque el azul se parezca al de "Otras incidencias" — así no hay
   ambigüedad ni siquiera para quien no ve bien el color. */
.marcador-ubicacion {
  animation: pulso-ubicacion 2s ease-in-out infinite;
}

@keyframes pulso-ubicacion {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

@media (max-width: 600px) {
  .controles-mapa { top: 0.5rem; right: 0.5rem; }
  #buscador-input { width: 160px; max-width: 55vw; font-size: 0.8rem; }
}

.leyenda {
  position: absolute;
  z-index: 1000;
  /* Suficiente para despejar la atribución de Leaflet, anclada también a la esquina
     inferior (ver regla .leaflet-control-attribution más abajo). */
  bottom: 2.25rem;
  left: 1rem;
  background: rgba(36, 36, 36, 0.92);
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
  font-size: 0.8rem;
  max-width: 220px;
}

.leyenda h2 {
  margin: 0 0 0.4rem;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent);
}

.leyenda ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.leyenda li label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--texto);
  cursor: pointer;
  /* Toda la fila es clicable, no solo el checkbox: más fácil de acertar en móvil. */
  padding: 0.1rem 0;
}

.leyenda li label:hover {
  color: var(--accent);
}

.filtro-checkbox {
  accent-color: var(--accent);
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  cursor: pointer;
  margin: 0;
}

/* Se atenúa toda la fila (no solo el punto) cuando su tipo está oculto del mapa, para que
   quede claro de un vistazo qué se está filtrando — sin que la fila desaparezca o cambie de
   posición, que sería más difícil de volver a activar. */
.leyenda li:has(.filtro-checkbox:not(:checked)) label {
  opacity: 0.45;
}

.punto {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
}

.punto-obras { background: var(--obras); }
.punto-accidente { background: var(--accidente); }
.punto-resto { background: var(--resto); }
.punto-highest {
  background: var(--highest);
  box-shadow: 0 0 0 2px rgba(193, 18, 31, 0.4);
}

/* Atribución de Leaflet (Esri/OSM): con el texto por defecto (11px) y anclada a la
   esquina inferior derecha, en pantallas estrechas su ancho de contenido supera el del
   viewport y se desborda hacia la izquierda, quedando debajo de la leyenda. Se reduce el
   tamaño y se limita el ancho para que siempre quepa envuelta dentro de la pantalla. */
.leaflet-control-attribution {
  max-width: calc(100vw - 1rem);
  font-size: 0.65rem;
  line-height: 1.3;
}

/* Popups de Leaflet en tema oscuro */
.leaflet-popup-content-wrapper {
  background: var(--bg-panel);
  color: var(--texto);
  border-radius: 8px;
}

.leaflet-popup-tip {
  background: var(--bg-panel);
}

.leaflet-popup-content {
  margin: 0.75rem 0.9rem;
  font-size: 0.85rem;
  line-height: 1.4;
}

.popup-incidencia {
  position: relative;
  /* Hueco para el botón de compartir, anclado en esta misma esquina (ver .popup-compartir),
     para que no quede encima de la última fila de datos ni del badge de severidad. */
  padding-bottom: 1.9rem;
}

.popup-incidencia h3 {
  /* Dejar sitio a la "×" de cierre de Leaflet, arriba a la derecha del popup entero. */
  margin: 0 1.5rem 0.35rem 0;
  font-size: 0.95rem;
}

.popup-compartir {
  position: absolute;
  right: 0;
  bottom: 0;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid #808080;
  color: #808080;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.popup-compartir svg {
  display: block;
  width: 12px;
  height: 12px;
}

.popup-compartir:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.popup-incidencia dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.5rem;
}

.popup-incidencia dt {
  color: #a0a0a0;
}

.popup-incidencia dd {
  margin: 0;
}

.badge-severidad {
  display: inline-block;
  margin-top: 0.4rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  background: var(--highest);
  color: #fff;
}

/* Marcador de severidad máxima: pulso animado */
.marcador-highest {
  animation: pulso 1.4s ease-in-out infinite;
  transform-origin: center;
}

@keyframes pulso {
  0% { opacity: 1; }
  50% { opacity: 0.55; }
  100% { opacity: 1; }
}

.help-overlay {
  position: fixed;
  inset: 0;
  z-index: 1200;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(0, 0, 0, 0.6);
}

/* [hidden] y .help-overlay{display:flex} tienen la misma especificidad; sin este :not(), la
   regla de abajo gana por venir después en la cascada y el overlay bloquea clics en toda la
   página incluso con el atributo hidden puesto. */
.help-overlay:not([hidden]) {
  display: flex;
}

.panel {
  background: var(--bg-panel);
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  padding: 1rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
}

.panel-title {
  margin: 0;
  font-size: 1.1rem;
  color: var(--accent);
}

.help-panel {
  position: relative;
  width: 100%;
  max-width: 420px;
  max-height: 80vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Scrollbar oscura a juego con el tema, en vez del gris claro por defecto del sistema — se
   nota sobre todo en Windows/Linux de escritorio (macOS ya usa una superpuesta y fina que
   apenas destaca sobre el fondo oscuro). Firefox vía scrollbar-width/-color, el resto vía
   ::-webkit-scrollbar. */
.help-panel,
.buscador-sugerencias {
  scrollbar-width: thin;
  scrollbar-color: #4a4a4a var(--bg-panel);
}

.help-panel::-webkit-scrollbar,
.buscador-sugerencias::-webkit-scrollbar {
  width: 8px;
}

.help-panel::-webkit-scrollbar-track,
.buscador-sugerencias::-webkit-scrollbar-track {
  background: var(--bg-panel);
  border-radius: 999px;
}

.help-panel::-webkit-scrollbar-thumb,
.buscador-sugerencias::-webkit-scrollbar-thumb {
  background: #4a4a4a;
  border-radius: 999px;
  border: 2px solid var(--bg-panel);
}

.help-panel::-webkit-scrollbar-thumb:hover,
.buscador-sugerencias::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}

.panel-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 22px;
  height: 22px;
  border: none;
  background: none;
  color: #808080;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.panel-close svg {
  display: block;
  width: 14px;
  height: 14px;
}

.panel-close:hover {
  color: var(--texto);
}

.help-content h3 {
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #b8b8b8;
  margin: 1.1rem 0 0.4rem;
}

.help-content h3:first-of-type {
  margin-top: 0.8rem;
}

.help-content p {
  font-size: 0.85rem;
  line-height: 1.55;
  margin: 0 0 0.5rem;
}

.help-content .punto {
  vertical-align: -1px;
}

.help-content a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dashed var(--accent);
}

.lista-panel {
  max-width: 480px;
}

.lista-controles {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.8rem 0 0.7rem;
}

.lista-contador {
  font-size: 0.75rem;
  color: #b8b8b8;
}

.lista-orden {
  display: flex;
  gap: 0.4rem;
}

.lista-orden-btn {
  /* min-height 44px: el tamaño táctil mínimo recomendado (WCAG 2.5.5) — con el padding de
     antes (0.3rem, ~24px de alto total) el botón se tocaba con dificultad en un móvil real,
     aunque en las pruebas automatizadas (que hacen click exacto al píxel) pareciera ir bien. */
  min-height: 44px;
  padding: 0.5rem 0.9rem;
  border: 1px solid #3a3a3a;
  border-radius: 999px;
  background: none;
  color: #b8b8b8;
  font-size: 0.8rem;
  cursor: pointer;
}

.lista-orden-btn.activo {
  border-color: var(--accent);
  color: var(--accent);
}

.lista-orden-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.lista-orden-aviso {
  margin: -0.3rem 0 0.7rem;
  font-size: 0.7rem;
  color: #808080;
}

.icono-inline {
  width: 13px;
  height: 13px;
  vertical-align: -2px;
  color: #b8b8b8;
}

.lista-incidencias {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.lista-item__boton {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid #3a3a3a;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
  color: var(--texto);
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}

.lista-item__boton:hover {
  border-color: var(--accent);
}

.lista-item__boton .punto {
  flex-shrink: 0;
}

.lista-item__contenido {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  font-size: 0.8rem;
}

.lista-item__contenido strong {
  font-size: 0.85rem;
}

.lista-item__detalle {
  color: #a0a0a0;
  font-size: 0.75rem;
}

.lista-item__distancia {
  flex-shrink: 0;
  font-size: 0.75rem;
  color: #b8b8b8;
  white-space: nowrap;
}

.api-status-hint {
  margin: 0 0 0.6rem;
  font-size: 0.75rem;
  color: #b8b8b8;
}

.api-status-list {
  list-style: none;
  margin: 0 0 0.75rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.api-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.api-status-row__value {
  font-weight: 600;
  text-align: right;
  min-width: 0;
  flex-shrink: 1;
}

.api-status-row__value--pending { color: #808080; }
.api-status-row__value--ok { color: var(--ok); }
.api-status-row__value--slow { color: var(--accent); }
.api-status-row__value--error { color: var(--accidente); }

/* 3 puntos animados en vez de texto tipo "Comprobando…": tamaño fijo, no depende del idioma
   ni se sale en móvil como podría pasar con "…" según la fuente. */
.loading-dots {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.loading-dots__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  animation: loading-dots-bounce 1.2s infinite ease-in-out both;
}

.loading-dots__dot:nth-child(2) { animation-delay: 0.15s; }
.loading-dots__dot:nth-child(3) { animation-delay: 0.3s; }

@keyframes loading-dots-bounce {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
  40% { transform: scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .loading-dots__dot { animation: none; opacity: 1; }
}

.api-status-recheck {
  display: block;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid #3a3a3a;
  border-radius: 6px;
  background: none;
  color: #b8b8b8;
  font-size: 0.75rem;
  cursor: pointer;
}

.api-status-recheck:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.update-banner {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* Por encima de la leyenda y los controles de Leaflet (z-index 1000): un aviso de versión
     nueva debe verse aunque el mapa tenga overlays propios abiertos. */
  z-index: 1100;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.6rem 1rem max(0.6rem, env(safe-area-inset-bottom));
  background: var(--bg-panel);
  border-top: 1px solid var(--accent);
  color: var(--texto);
  font-size: 0.8rem;
  text-align: center;
}

/* [hidden] y display:flex puestos directamente en la misma clase empatan en especificidad,
   así que sin el :not() el aviso se vería aunque tuviera el atributo hidden. */
.update-banner:not([hidden]) {
  display: flex;
}

.update-banner button {
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent);
  color: #1a1a1a;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}

.update-banner button:hover {
  filter: brightness(1.1);
}

@media (max-width: 600px) {
  .app-header h1 { font-size: 1.15rem; }
  .subtitle { display: none; }
  .leyenda { left: 0.5rem; bottom: 1.75rem; max-width: 170px; font-size: 0.72rem; }
  .leaflet-control-attribution { font-size: 0.55rem; }

  /* Estado + Actualizar + Lista + Ayuda en la misma fila que el título, tan compacta como en
     v0.8.0 (antes de que existiera el botón de Lista) — la fila completa iba a su propia línea
     con el estado a la izquierda y los botones agrupados a la derecha (space-between), nunca
     3 líneas. La solución anterior (forzar el estado a su propia línea entera) evitaba el
     desbordamiento pero hacía la cabecera bastante más alta de lo necesario. */
  .header-actions {
    width: 100%;
    justify-content: space-between;
    gap: 0.5rem;
  }
  .estado {
    /* En vez de forzar su propia línea, el texto se recorta con "…" si no cupiera en un móvil
       muy estrecho (<~340px) — así Actualizar/Lista/Ayuda nunca pierden su sitio ni se salen
       de la pantalla, sin necesidad de una segunda fila en los móviles normales. */
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  #btn-refrescar,
  .help-btn {
    flex-shrink: 0;
  }
}
