/* ==========================================================================
   componentes.css — Piezas reutilizables del design system: botones, estados
   y ayudas de tipografía. Usan las variables de tokens.css (no hay colores
   propios acá). Miralas todas juntas en guia-diseno.html.
   ========================================================================== */

/* --- Tipografía ----------------------------------------------------------
   La fuente y el cuerpo base ya se fijan en base.css (body). Acá va la escala
   de títulos y un par de ayudas de texto, para que todos los tableros usen los
   mismos tamaños. */

.titulo-xl {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.15;
  margin: 0;
}

.titulo-l {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  margin: 0;
}

.titulo-m {
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1.25;
  margin: 0;
}

.titulo-s {
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
}

.texto {
  font-size: 1rem;
  color: var(--texto);
}

.texto-suave {
  color: var(--texto-suave);
}

.texto-chico {
  font-size: 0.85rem;
}

.texto-numero {
  font-variant-numeric: tabular-nums;
}

/* --- Botones -------------------------------------------------------------
   Base + variantes. En un tablero los botones se usan poco (filtros, "descargar
   datos", "ver más"); estos alcanzan para eso. */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font: inherit;
  font-weight: 600;
  line-height: 1;
  min-height: var(--alto-control);
  padding: 0 16px;
  border-radius: var(--radio);
  border: 1px solid transparent;
  background: transparent;
  color: var(--texto);
  cursor: pointer;
  text-decoration: none;
  transition: filter 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.boton:hover {
  filter: brightness(0.96);
}

.boton:active {
  filter: brightness(0.92);
}

.boton:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.boton[disabled],
.boton.deshabilitado {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
}

/* Primario: acción principal. Usa el color de marca. Texto oscuro fijo (no
   blanco): a este tamaño de letra, el celeste no tiene contraste suficiente
   para texto blanco — ver --texto-sobre-marca en tokens.css. */
.boton--primario {
  background: var(--marca);
  color: var(--marca-texto);
  border-color: var(--marca);
}

/* Secundario: acción alternativa, con borde. */
.boton--secundario {
  background: var(--superficie);
  color: var(--texto);
  border-color: var(--borde);
}

.boton--secundario:hover {
  background: var(--fondo);
}

/* Sutil: para acciones terciarias, sin caja. --marca-enlace (no --marca): acá
   el celeste ES el texto, y el oficial no tiene contraste suficiente para eso. */
.boton--sutil {
  background: transparent;
  color: var(--marca-enlace);
  border-color: transparent;
}

.boton--sutil:hover {
  background: color-mix(in srgb, var(--marca) 12%, transparent);
}

/* Peligro: acciones destructivas (borrar, etc.). Usar con moderación. */
.boton--peligro {
  background: var(--grave);
  color: #ffffff;
  border-color: var(--grave);
}

/* Mapa: para el botón que lleva al mapa del tablero ("Ver mapa"). Color de
   acento (magenta, --acento) para que se distinga de la acción principal
   (celeste). Con un ícono: <span class="icono" aria-hidden="true">map</span>. */
.boton--mapa {
  background: var(--acento);
  color: var(--acento-texto);
  border-color: var(--acento);
}

/* Tamaños */
.boton--chico {
  min-height: 34px;
  padding: 0 12px;
  font-size: 0.85rem;
}

.boton--grande {
  min-height: 54px;
  padding: 0 22px;
  font-size: 1.05rem;
}

/* --- Etiquetas de estado (badges) ---------------------------------------- */

/* El color del estado va en el FONDO (un tinte) y en el PUNTO — nunca en el
   texto. Motivo: para que un amarillo pase contraste como texto hay que
   oscurecerlo tanto que deja de verse amarillo, y un "alerta" marrón no se
   reconoce de un vistazo. Con el texto en el neutro del tema, el color se
   mantiene real y de paso el contraste sube a 12-16:1. Ver ACCESIBILIDAD.md. */

.estado {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--texto);
}

/* El punto lleva --color-estado, que define cada variante de abajo. No usa
   currentColor: tomaría el neutro del texto y la etiqueta perdería el color. */
.estado::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-estado);
}

.estado--ok {
  --color-estado: var(--ok);
  background: color-mix(in srgb, var(--ok) 14%, transparent);
}

.estado--alerta {
  --color-estado: var(--alerta);
  background: color-mix(in srgb, var(--alerta) 14%, transparent);
}

.estado--grave {
  --color-estado: var(--grave);
  background: color-mix(in srgb, var(--grave) 14%, transparent);
}

.estado--neutro {
  --color-estado: var(--texto-suave);
  background: color-mix(in srgb, var(--texto-suave) 12%, transparent);
}
/* --- Saltar al contenido -------------------------------------------------
   Primer elemento del <body>. Queda fuera de pantalla hasta que recibe el
   foco con Tab; ahí aparece arriba a la izquierda. Apunta al <main id="contenido">.
   Permite a quien navega con teclado o lector de pantalla saltear el header. */

.saltar-contenido {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 100;
  padding: 10px 16px;
  border-radius: var(--radio);
  background: var(--marca);
  color: var(--marca-texto);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}

.saltar-contenido:focus-visible {
  transform: none;
  outline: 2px solid var(--texto);
  outline-offset: 2px;
}

/* --- Barra de filtros ----------------------------------------------------
   Contenedor de filtros (select, input) + botón "Aplicar". Cada filtro es un
   .filtro con su <label for>: nunca solo placeholder. Los estilos de
   select/input están acotados a .filtros para no afectar a otros formularios. */

.filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 20px;
  background: var(--superficie);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
}

.filtro {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 160px;
}

.filtro label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--texto-suave);
}

.filtros select,
.filtros input {
  font: inherit;
  color: var(--texto);
  background-color: var(--fondo);
  border: 1px solid var(--texto-suave);
  border-radius: var(--radio);
  height: var(--alto-control);
  padding: 0 12px;
}

/* La flecha del select la dibujamos nosotros para separarla del borde derecho
   (la del navegador queda pegada). */
.filtros select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 42px;
  background-image: var(--flecha-select);
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px;
}

.filtros select:focus-visible,
.filtros input:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* --- Avisos (callouts) ---------------------------------------------------
   Mensaje destacado dentro de la página. Mismo criterio que .estado: el color
   va en el borde y en el tinte de fondo, el texto queda en --texto. El ícono
   (distinto en cada variante) evita depender solo del color.
   Gravedad → rol: .aviso--grave y --alerta llevan role="alert"; el resto,
   role="status" (o ninguno si el aviso ya estaba al cargar la página). */

.aviso {
  --color-estado: var(--marca);
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 16px;
  margin-bottom: 12px;
  color: var(--texto);
  background: color-mix(in srgb, var(--color-estado) 12%, var(--superficie));
  border: 1px solid color-mix(in srgb, var(--color-estado) 45%, transparent);
  border-left: 5px solid var(--color-estado);
  border-radius: var(--radio);
}

.aviso .icono {
  flex: none;
  margin-top: 1px;
}

.aviso p {
  margin: 0;
}

.aviso strong {
  display: block;
}

.aviso--info {
  --color-estado: var(--marca);
}

.aviso--ok {
  --color-estado: var(--ok);
}

.aviso--alerta {
  --color-estado: var(--alerta);
}

.aviso--grave {
  --color-estado: var(--grave);
}

/* --- Pestañas ------------------------------------------------------------
   Patrón ARIA de tabs: un .pestanas[role=tablist] con botones .pestana
   [role=tab][aria-selected] y un .panel-pestana[role=tabpanel] por cada uno.
   La seleccionada se distingue por el subrayado Y el peso de la letra, no
   solo por el color. Navegación con ←/→ (la resuelve el JS de cada tablero). */

.pestanas {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  border-bottom: 1px solid var(--borde);
}

.pestana {
  font: inherit;
  font-weight: 500;
  color: var(--texto-suave);
  background: transparent;
  border: 0;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  padding: 10px 16px;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

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

.pestana[aria-selected="true"] {
  color: var(--texto);
  font-weight: 700;
  border-bottom-color: var(--marca);
}

.pestana:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: -2px;
  border-radius: var(--radio) var(--radio) 0 0;
}

.panel-pestana {
  padding-top: 16px;
}

.panel-pestana[hidden] {
  display: none;
}

/* --- Estado vacío --------------------------------------------------------
   Cuando una tabla, un filtro o una sección no tiene nada que mostrar: ícono +
   título + una línea que explique por qué y qué hacer. El ícono es decorativo
   (aria-hidden). Para el título usá el nivel que siga en la jerarquía. */

.vacio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 32px 16px;
  text-align: center;
  background: var(--superficie);
  border: 1px dashed var(--borde);
  border-radius: var(--radio);
}

.vacio[hidden] {
  display: none;
}

.vacio .icono {
  font-size: 40px;
  color: var(--texto-suave);
}

.vacio h3,
.vacio h4 {
  margin: 0;
  font-size: 1.1rem;
}

.vacio p {
  margin: 0;
  max-width: 45ch;
  color: var(--texto-suave);
}

.vacio .boton {
  margin-top: 8px;
}

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

/* --- Botón en píldora ----------------------------------------------------
   Modificador de .boton para acciones tipo "chip" (los del footer que abren
   los modales). Se usa junto a .boton--secundario. */

.boton--pildora {
  border-radius: 999px;
  padding: 10px 18px;
}

.boton--pildora .icono {
  color: var(--marca-enlace);
}

.boton--pildora img {
  width: 20px;
  height: 20px;
}

/* --- Modal ---------------------------------------------------------------
   Sobre <dialog>: el navegador ya resuelve el foco atrapado, Esc para cerrar y
   devolver el foco al botón que lo abrió. js/pie.js lo abre y cierra al
   tocar afuera. Estructura:
     <dialog class="modal" aria-labelledby="…">
       <div class="modal-cuerpo">
         <header class="modal-cabecera"><h2 id="…">…</h2>
           <form method="dialog"><button class="modal-cerrar" aria-label="Cerrar">…</button></form>
         </header>
         …contenido…
       </div>
     </dialog> */

.modal {
  width: min(720px, calc(100% - 32px));
  max-height: calc(100% - 32px);
  padding: 0;
  border: 0;
  border-radius: 24px;
  background: var(--superficie);
  color: var(--texto);
}

.modal::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

.modal-cuerpo {
  padding: 24px 28px 28px;
}

.modal-cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.modal-cabecera h2 {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: 1.4rem;
  line-height: 1.2;
}

.modal-cabecera h2 img {
  width: 28px;
  height: 28px;
}

.modal-cabecera form {
  margin: 0;
}

.modal-cerrar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--fondo);
  color: var(--texto);
  cursor: pointer;
}

.modal-cerrar:hover {
  filter: brightness(0.94);
}

.modal-cerrar:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

.modal-cuerpo > p {
  margin: 0 0 20px;
  color: var(--texto-suave);
}

.modal-cuerpo h3 {
  margin: 0 0 12px;
}

.modal-cuerpo a {
  color: var(--marca-enlace);
  font-weight: 600;
}

/* Texto que solo leen los lectores de pantalla (ej.: "se abre en una pestaña nueva"). */
.solo-lectores {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.modal-cuerpo > p + p {
  margin-top: -8px;   /* párrafos seguidos: menos aire entre ellos */
}

/* Grilla de íconos de ODS dentro del modal. Los íconos NO se deforman ni se
   recortan: solo cambian de tamaño manteniendo la proporción. */
.ods-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ods-grilla img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 600px) {
  .modal-cuerpo {
    padding: 20px;
  }

  .ods-grilla {
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  }
}

/* --- Contenedor de gráfico ------------------------------------------------
   Lo llena js/graficos.js (Grafico.crear). Necesita un alto fijo: sin él, el
   gráfico no tiene dónde dibujarse. Va dentro de un .panel. */

.grafico {
  width: 100%;
  height: 300px;
}

.grafico--alto {
  height: 420px;
}

/* --- Mapa ----------------------------------------------------------------
   Contenedor de un mapa de Leaflet; lo llena js/mapa.js (Mapa.crear). Como el
   .grafico, necesita alto fijo. Las reglas de abajo visten los controles de
   Leaflet (zoom, atribución, tooltip, leyenda) con los colores del sistema. */

.mapa {
  position: relative;
  isolation: isolate;          /* los z-index internos de Leaflet no tapan al resto de la página */
  width: 100%;
  height: 420px;
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--fondo);
  font-family: var(--fuente);
}

/* Leaflet pinta el fondo de gris (#ddd) en su propia hoja, que se carga después: de
   ahí el doble selector, para ganar. Es lo que se ve donde no hay mosaicos. */
.mapa.leaflet-container {
  background: var(--fondo);
}

.mapa .leaflet-tile-pane {
  filter: var(--filtro-mapa);
}

.mapa.leaflet-container:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: -2px;
}

.mapa .leaflet-bar {
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: none;
  overflow: hidden;
}

.mapa .leaflet-bar a {
  width: 34px;
  height: 34px;
  line-height: 34px;
  background: var(--superficie);
  color: var(--texto);
  border-bottom-color: var(--borde);
}

.mapa .leaflet-bar a:hover,
.mapa .leaflet-bar a:focus-visible {
  background: var(--fondo);
  color: var(--texto);
}

.mapa .leaflet-bar a.leaflet-disabled {
  background: var(--superficie);
  color: var(--texto-suave);
  opacity: 0.55;
}

.mapa.leaflet-container .leaflet-control-attribution {
  background: color-mix(in srgb, var(--superficie) 88%, transparent);
  color: var(--texto-suave);
  font-family: var(--fuente);
  font-size: 0.72rem;
  border-radius: var(--radio) 0 0 0;
  padding: 2px 8px;
}

.mapa.leaflet-container .leaflet-control-attribution a {
  color: var(--marca-enlace);
}

.mapa-tooltip {
  background: var(--superficie);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: 12px;
  padding: 8px 12px;
  font-family: var(--fuente);
  font-size: 0.85rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
}

.mapa-tooltip small {
  display: block;
  max-width: 260px;
  margin-top: 4px;
  white-space: normal;
  color: var(--texto-suave);
  font-size: 0.75rem;
  line-height: 1.35;
}

.mapa-etiqueta span {
  position: absolute;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  pointer-events: none;
  color: var(--texto);
  font-family: var(--fuente);
  font-size: 0.78rem;
  font-weight: 700;
  /* Un halo del color de la superficie mantiene el nombre legible sobre cualquier tono del mapa. */
  text-shadow: 0 0 3px var(--superficie), 0 0 3px var(--superficie), 0 0 6px var(--superficie);
}

.mapa-tooltip.leaflet-tooltip-top::before {
  border-top-color: var(--superficie);
}

.mapa-leyenda {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  margin: 0 0 12px 12px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--superficie) 90%, transparent);
  color: var(--texto-suave);
  font-family: var(--fuente);
  font-size: 0.78rem;
}

.mapa-leyenda i {
  display: block;
  width: 110px;
  height: 10px;
  border-radius: 999px;
}

/* Mapa ampliado: ocupa toda la ventana (botón "Ampliar mapa" de js/mapa.js). */
.mapa.mapa--ampliado {
  position: fixed;
  inset: 0;
  z-index: 1000;
  width: 100%;
  height: 100%;
  border-radius: 0;
}

html.mapa-ampliado-activo {
  overflow: hidden;
}

.mapa .mapa-ampliar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  background: var(--superficie);
  color: var(--texto);
  cursor: pointer;
}

.mapa .mapa-ampliar:hover,
.mapa .mapa-ampliar:focus-visible {
  background: var(--fondo);
}

.mapa .mapa-ampliar .icono {
  font-size: 22px;
}

/* Selector de capas. El ícono de Leaflet es negro: en modo oscuro se aclara. */
.mapa.leaflet-container .leaflet-control-layers {
  background: var(--superficie);
  color: var(--texto);
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  box-shadow: none;
  font-family: var(--fuente);
  font-size: 0.85rem;
}

.mapa .leaflet-control-layers-toggle {
  filter: var(--filtro-escudo);
}

.mapa .leaflet-control-layers-expanded {
  padding: 8px 12px;
}

.mapa .leaflet-control-layers-list label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  cursor: pointer;
}

.mapa .leaflet-control-layers-list input {
  accent-color: var(--marca);
}
