﻿/* ============================================================================
   ventaneros.cl — sistema visual.
   CSS plano, sin preprocesador y sin build.
   ----------------------------------------------------------------------------
   IDENTIDAD, Y POR QUÉ ES DISTINTA DE LAS LANDINGS DE LOS CLIENTES

   Las landings son cálidas (crema, terracota) porque venden confort de hogar.
   Este sitio es otra cosa: es una herramienta para encontrar a alguien cerca.
   Así que el marco es slate profundo y frío, y el mapa —que va con tiles
   claras— queda como la única superficie luminosa de la pantalla. Ese contraste
   entre el chrome oscuro y el mapa claro es lo que hace que se lea como un
   producto de mapas, y no como una página con un mapa incrustado.

   El acento es VERDE VIDRIO: el tono del canto de un vidrio float visto de
   perfil. Sale del propio tema en lugar de ser un color elegido al azar, y
   además no compite con el color de marca de ninguna empresa listada, que es un
   requisito real de un directorio.

   Los botones de WhatsApp NO van en el verde de WhatsApp. Ese verde
   amarillento pelea con el verde vidrio y ensucia la paleta; el isotipo ya dice
   de qué canal se trata, así que los botones siguen el sistema del sitio.

   ORGANIZACIÓN
   1. Tokens   2. Base   3. Header   4. Portada   5. Mapa y pines
   6. Controles (buscador y filtros)   7. Tarjetas   8. Sumarse   9. Footer
   ========================================================================= */

/* ── 1. Tokens ──────────────────────────────────────────────────────────── */
:root {
  --fondo: #0c1418;
  --fondo-alto: #101b21;
  --panel: #121d23;
  --panel-alto: #19272f;
  --borde: #223440;
  --borde-vivo: #2e4854;

  --texto: #e6eff2;
  --suave: #93a9b2;
  --tenue: #647c86;

  --acento: #37e0be;
  --acento-fuerte: #17c3a1;
  --acento-tinta: #05231e;
  --acento-10: rgba(55, 224, 190, 0.1);
  --acento-20: rgba(55, 224, 190, 0.2);

  --alerta: #ff7a6b;

  --ui: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --ancho: 84rem;
  --r: 1rem;
  --r-chico: 0.625rem;
  --header: 3.75rem;

  --suavizado: cubic-bezier(0.22, 1, 0.36, 1);
  --sombra: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 32px -16px rgba(0, 0, 0, 0.6);
}

/* ── 2. Base ────────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  background: var(--fondo);
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--ui);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
  height: auto;
}

a {
  color: inherit;
}

button {
  font-family: inherit;
}

[id] {
  scroll-margin-top: calc(var(--header) + 1rem);
}

:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
}

::selection {
  background: var(--acento-20);
}

.solo-lectores {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.saltar {
  position: absolute;
  left: -9999px;
}

.saltar:focus {
  left: 1rem;
  top: 1rem;
  z-index: 90;
  background: var(--acento);
  color: var(--acento-tinta);
  padding: 0.75rem 1.25rem;
  border-radius: 999px;
  font-size: 0.875rem;
  font-weight: 600;
}

.contenedor {
  width: 100%;
  max-width: var(--ancho);
  margin: 0 auto;
  padding-left: 1.125rem;
  padding-right: 1.125rem;
}

/* Números como instrumental: el mono alinea las distancias en columna y las
   hace leer como dato medido, no como texto. */
.num {
  font-family: var(--mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* Botones ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0 1.125rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--texto);
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s var(--suavizado), border-color 0.18s var(--suavizado),
    color 0.18s var(--suavizado), transform 0.18s var(--suavizado);
}

.btn:active {
  transform: scale(0.97);
}

.btn--acento {
  background: var(--acento);
  color: var(--acento-tinta);
}

.btn--acento:hover {
  background: var(--acento-fuerte);
}

.btn--linea {
  border-color: var(--borde-vivo);
  color: var(--texto);
}

.btn--linea:hover {
  background: var(--panel-alto);
  border-color: var(--acento);
  color: var(--acento);
}

.btn--fantasma {
  color: var(--suave);
}

.btn--fantasma:hover {
  background: var(--panel-alto);
  color: var(--texto);
}

.btn--bloque {
  width: 100%;
}

.btn svg {
  width: 1.125rem;
  height: 1.125rem;
  flex: none;
}

/* ── 3. Header ──────────────────────────────────────────────────────────── */
.header {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 60;
  background: rgba(12, 20, 24, 0.86);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--borde);
}

.header__barra {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  height: var(--header);
}

.marca {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  text-decoration: none;
  margin-right: auto;
}

/* El isotipo: un cuadrado con un parteluz. Dice "ventana" con dos trazos. */
.marca__ico {
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.875rem;
  border-radius: 0.5rem;
  background: var(--acento-10);
  border: 1px solid var(--acento-20);
  color: var(--acento);
  flex: none;
}

.marca__ico svg {
  width: 1.125rem;
  height: 1.125rem;
}

.marca__texto {
  font-size: 1.0625rem;
  font-weight: 800;
  letter-spacing: -0.035em;
}

.marca__texto span {
  color: var(--acento);
}

.header__acciones {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* En celular el header tiene tres cosas peleando por el mismo ancho (marca,
   ubicación, botón): se recorta el padding del botón para que entren, sin
   tocar el texto. Desde tablet hay lugar de sobra y vuelve a su tamaño
   normal (ver breakpoint 40rem más abajo). */
.header__acciones .btn {
  padding: 0 0.875rem;
  font-size: 0.875rem;
}

/* ── 4. Portada ─────────────────────────────────────────────────────────── */
.portada {
  padding-top: 2rem;
  padding-bottom: 1.5rem;
  position: relative;
  overflow: hidden;
  isolation: isolate; /* el ::before y el fondo quedan encerrados acá, sin pisar el header sticky */
}

/* La foto va COMO FONDO de toda la sección, no en una tarjeta aparte. Se
   oscurece con un degradado propio para que el texto siga siendo legible y
   para que se funda con --fondo hacia abajo: así la página sigue leyéndose
   toda oscura, la foto es la superficie, no un elemento flotando encima. */
.portada__fondo {
  position: absolute;
  inset: 0;
  z-index: -2;
  /* La URL de la foto se fija inline en el markup (Ay.Media resuelve la ruta
     del sitio), acá solo el encuadre. */
  background-size: cover;
  background-position: center 30%;
}

.portada__fondo::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(12, 20, 24, 0.55) 0%, rgba(12, 20, 24, 0.82) 68%, var(--fondo) 100%),
    linear-gradient(90deg, rgba(12, 20, 24, 0.92) 0%, rgba(12, 20, 24, 0.55) 55%, rgba(12, 20, 24, 0.25) 100%);
}

/* Resplandor del acento sobre la foto: una sola nota de color, del lado que
   se lee primero. */
.portada::before {
  content: '';
  position: absolute;
  top: -14rem;
  left: -8rem;
  width: 34rem;
  height: 28rem;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(55, 224, 190, 0.16), transparent);
  pointer-events: none;
}

.portada__caja {
  position: relative;
  max-width: 34rem;
}

/* Frase corta de confianza, arriba del título: dice "esto es especializado"
   antes de que la persona lea el titular. Un dato, no una promesa. */
.portada__kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  margin: 0 0 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--suave);
}

.portada__kicker svg {
  width: 1rem;
  height: 1rem;
  color: var(--acento);
}

.portada h1 {
  margin: 0;
  font-size: 1.875rem;
  line-height: 1.1;
  font-weight: 800;
  letter-spacing: -0.04em;
  text-wrap: balance;
}

.portada h1 em {
  font-style: normal;
  color: var(--acento);
}

.portada p {
  margin: 0.875rem 0 0;
  color: var(--suave);
  text-wrap: pretty;
}

.portada__acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin-top: 1.25rem;
}

/* ── Fotos de material ─────────────────────────────────────────────────────
   La pieza con más personalidad de la página, y a propósito la única: todo
   lo demás es sobrio para que esto se lleve la mirada. Cada foto es un
   botón-filtro real. El degradado de fondo es el respaldo si la imagen no
   está: la tarjeta se sigue viendo terminada, no rota. */
.materiales {
  margin-top: 1.5rem;
}

.materiales__pregunta {
  margin: 0 0 0.625rem;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--texto);
}

.materiales__grilla {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.625rem;
  max-width: 32rem;
}

.material {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  min-height: 8.5rem;
  padding: 0.875rem;
  border: 1px solid var(--borde-vivo);
  border-radius: var(--r);
  overflow: hidden;
  background: linear-gradient(150deg, #24444d 0%, #10232a 100%);
  color: #fff;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s var(--suavizado);
}

.material:active {
  transform: scale(0.98);
}

.material img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--suavizado);
}

/* Oscurece solo la parte de abajo, donde va el texto: la foto se ve arriba
   y el nombre se lee sobre cualquier imagen. */
.material::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(12, 20, 24, 0) 25%, rgba(12, 20, 24, 0.9) 100%);
}

.material:hover img {
  transform: scale(1.05);
}

.material__nombre {
  font-size: 1.0625rem;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.material__dato {
  margin-top: 0.125rem;
  font-size: 0.8125rem;
  color: rgba(230, 239, 242, 0.78);
}

/* El círculo de arriba a la derecha dice "esto se puede marcar" antes de
   tocarlo, y se llena cuando el filtro está activo. */
.material__marca {
  position: absolute;
  top: 0.625rem;
  right: 0.625rem;
  display: grid;
  place-items: center;
  width: 1.625rem;
  height: 1.625rem;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  border-radius: 999px;
  background: rgba(12, 20, 24, 0.45);
  color: transparent;
  transition: background-color 0.18s, border-color 0.18s, color 0.18s;
}

.material__marca svg {
  width: 0.9375rem;
  height: 0.9375rem;
}

.material[aria-pressed='true'] {
  border-color: var(--acento);
  box-shadow: 0 0 0 2px var(--acento);
}

.material[aria-pressed='true'] .material__marca {
  border-color: var(--acento);
  background: var(--acento);
  color: var(--acento-tinta);
}

/* Contenedor de foto genérico (Cómo funciona, Súmate), con el mismo
   respaldo en degradado si la imagen falta. */
.foto {
  overflow: hidden;
  border-radius: var(--r);
  border: 1px solid var(--borde);
  background: linear-gradient(150deg, #24444d 0%, #10232a 100%);
}

.foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Estado de la ubicación: el sitio dice siempre desde dónde está midiendo.
   Sin esto, "a 3,4 km" es un número sin origen y no se puede confiar.
   Vive en el header, al lado de "Suma tu empresa". */
.ubicacion {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
  padding: 0.5rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.8125rem;
  color: var(--suave);
}

/* En celular el texto ("Pidiendo permiso de ubicación…", etc.) no entra al
   lado del logo y el botón sin romper el header en dos líneas: se oculta
   VISUALMENTE nada más (misma técnica que .solo-lectores), así que un lector
   de pantalla lo sigue anunciando aunque en la pantalla solo se vea el punto
   de estado. Desde tablet (ver breakpoint 40rem) hay espacio y se muestra
   completo. */
.ubicacion__texto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.ubicacion__punto {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--tenue);
  flex: none;
}

.ubicacion[data-estado='ok'] .ubicacion__punto {
  background: var(--acento);
  box-shadow: 0 0 0 3px var(--acento-20);
}

.ubicacion[data-estado='buscando'] .ubicacion__punto {
  background: var(--acento);
  animation: latido 1.2s ease-in-out infinite;
}

.ubicacion[data-estado='error'] .ubicacion__punto {
  background: var(--alerta);
}

@keyframes latido {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

/* ── 5. Mapa y pines ────────────────────────────────────────────────────── */
/* Barra del buscador: vive SOBRE el mapa, a todo el ancho de la página — no
   metida en el panel angosto de la lista. Es lo primero que alguien que ya
   sabe qué busca (su comuna, su empresa, qué material) necesita encontrar,
   antes del mapa y las tarjetas: "dónde" y "qué" en un solo bloque. */
.buscador-barra {
  padding: 0.875rem 0;
  background: var(--fondo);
  border-bottom: 1px solid var(--borde);
}

.buscador-barra .contenedor {
  display: grid;
  gap: 0.625rem;
}

.mapa-caja {
  position: relative;
  margin-top: 0;
}

.mapa {
  /* En celular el mapa acompaña, no domina: con 58svh la primera ficha (y su
     botón de WhatsApp) quedaba a más de una pantalla de distancia. */
  height: 40svh;
  min-height: 16rem;
  /*
   * Fondo propio DEBAJO de las tiles, no decorativo: si las tiles no cargan
   * —red mala, o el mapa embebido en un contexto que bloquea pedidos
   * externos— el mapa no queda como un rectángulo gris roto, sino como una
   * superficie diseñada donde los pines se siguen leyendo perfecto.
   */
  background-color: var(--fondo-alto);
  background-image: radial-gradient(circle at 50% 40%, rgba(55, 224, 190, 0.07), transparent 70%),
    linear-gradient(var(--borde) 1px, transparent 1px),
    linear-gradient(90deg, var(--borde) 1px, transparent 1px);
  background-size: 100% 100%, 3rem 3rem, 3rem 3rem;
  border-top: 1px solid var(--borde);
  border-bottom: 1px solid var(--borde);
  z-index: 0;
}

/*
 * Leaflet pinta un gris propio (.leaflet-container { background: #ddd }) sobre
 * el mismo elemento que .mapa. NO hay que taparlo con otro background acá:
 * background es una propiedad compuesta, así que "background: transparent"
 * borraba también el background-image de .mapa y la superficie de respaldo no
 * se veía nunca. Como site.css se carga DESPUÉS de leaflet.css y los dos
 * selectores tienen la misma especificidad, el background de .mapa ya le gana
 * solo. Acá queda únicamente la tipografía.
 */
.leaflet-container {
  font-family: var(--ui) !important;
}

.leaflet-control-attribution {
  background: rgba(12, 20, 24, 0.78) !important;
  color: var(--tenue) !important;
  font-size: 10.5px !important;
  padding: 2px 6px !important;
  border-radius: 6px 0 0 0;
}

.leaflet-control-attribution a {
  color: var(--suave) !important;
}

.leaflet-bar {
  border: 1px solid var(--borde-vivo) !important;
  border-radius: 0.625rem !important;
  overflow: hidden;
  box-shadow: var(--sombra) !important;
}

.leaflet-bar a {
  background: var(--panel) !important;
  color: var(--texto) !important;
  border-bottom-color: var(--borde) !important;
  width: 2rem !important;
  height: 2rem !important;
  line-height: 2rem !important;
}

.leaflet-bar a:hover {
  background: var(--panel-alto) !important;
  color: var(--acento) !important;
}

/* Pin propio. Es un div, no una imagen: así hereda el color del sistema y
   puede cambiar de estado (activo) sin pedir otro archivo. */
/*
 * La gota del pin: un cuadrado con tres esquinas redondas y una en punta,
 * girado para que la punta quede ABAJO, donde está la coordenada.
 *
 * El giro es de -45 grados, no de +45. La esquina en punta es la de abajo a la
 * izquierda; con +45 (sentido del reloj) esa esquina termina apuntando a la
 * izquierda y el pin parece un ojo acostado en lugar de un pin.
 */
.pin {
  position: relative;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 999px 999px 999px 2px;
  transform: rotate(-45deg);
  background: var(--acento);
  border: 2px solid var(--acento-tinta);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
  transition: transform 0.2s var(--suavizado), background-color 0.2s;
}

.pin::after {
  content: '';
  position: absolute;
  inset: 0.375rem;
  border-radius: 999px;
  background: var(--acento-tinta);
}

.pin--activo {
  background: #fff;
  transform: rotate(-45deg) scale(1.28);
  z-index: 500;
}

/* El pin de la persona: círculo con halo, distinto en forma de los de las
   empresas para que no haya confusión sobre cuál es uno mismo. */
.pin-yo {
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  background: #fff;
  border: 3px solid var(--acento);
  box-shadow: 0 0 0 6px rgba(55, 224, 190, 0.22), 0 2px 8px rgba(0, 0, 0, 0.5);
}

/* Clusters dibujados desde cero: no se incluyó el CSS por defecto de
   markercluster (círculos celestes) porque no tiene nada que ver con esta
   paleta. */
.grupo {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  background: rgba(55, 224, 190, 0.22);
  border: 1px solid var(--acento);
  box-shadow: 0 0 0 6px rgba(55, 224, 190, 0.08), 0 4px 14px rgba(0, 0, 0, 0.45);
  color: var(--texto);
  font-family: var(--mono);
  font-size: 0.8125rem;
  font-weight: 600;
}

.leaflet-cluster-anim .leaflet-marker-icon,
.leaflet-cluster-anim .leaflet-marker-shadow {
  transition: transform 0.3s ease-out, opacity 0.3s ease-in;
}

/* ── 6. Controles ───────────────────────────────────────────────────────── */
/*
 * El panel se monta sobre el borde inferior del mapa. Es lo que hace que la
 * pantalla se lea como una sola pieza en lugar de dos bloques apilados, y de
 * paso avisa que abajo hay contenido: el borde redondeado que tapa el mapa es
 * una señal de "esto se puede subir".
 */
.panel {
  position: relative;
  z-index: 10;
  margin-top: -1.25rem;
  border-radius: var(--r) var(--r) 0 0;
  background: var(--fondo);
  border-top: 1px solid var(--borde);
  padding: 0.625rem 1.125rem 0;
}

.panel__asa {
  width: 2.5rem;
  height: 0.25rem;
  margin: 0 auto 0.875rem;
  border-radius: 999px;
  background: var(--borde-vivo);
}

.buscador {
  position: relative;
}

.buscador svg {
  position: absolute;
  left: 0.875rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.125rem;
  height: 1.125rem;
  color: var(--tenue);
  pointer-events: none;
}

.buscador input {
  width: 100%;
  min-height: 2.875rem;
  padding: 0 2.5rem 0 2.75rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--panel);
  color: var(--texto);
  font-family: inherit;
  font-size: 0.9375rem;
  transition: border-color 0.18s, background-color 0.18s;
}

.buscador input::placeholder {
  color: var(--tenue);
}

.buscador input:focus {
  outline: none;
  border-color: var(--acento);
  background: var(--panel-alto);
}

.buscador__limpiar {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.875rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--tenue);
  cursor: pointer;
}

.buscador__limpiar:hover {
  background: var(--panel-alto);
  color: var(--texto);
}

/* Con dos chips (PVC, Aluminio) alcanza con que hagan wrap si no entran; el
   truco de sangrar a los bordes con scroll horizontal quedó en el panel
   angosto de antes, acá ya no aplica (el espaciado entre buscador y chips lo
   da el gap de .buscador-barra .contenedor). Si el día de mañana se suman
   más materiales y dejan de entrar en una fila, ahí sí conviene volver al
   scroll horizontal. */
.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  flex: none;
  min-height: 2.625rem;
  padding: 0 1rem;
  border: 1px solid var(--borde);
  border-radius: 999px;
  background: var(--panel);
  color: var(--suave);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.18s, border-color 0.18s, color 0.18s;
}

.chip:hover {
  border-color: var(--borde-vivo);
  color: var(--texto);
}

.chip[aria-pressed='true'] {
  background: var(--acento-10);
  border-color: var(--acento);
  color: var(--acento);
}

/* El tilde aparece SOLO en el chip activo. Mostrándolo siempre, un filtro
   apagado se leía como si ya estuviera seleccionado. */
.chip svg {
  width: 1rem;
  height: 1rem;
  display: none;
}

.chip[aria-pressed='true'] svg {
  display: block;
}

.resumen {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 1.125rem 0 0.75rem;
}

.resumen__cuenta {
  font-size: 0.8125rem;
  color: var(--tenue);
}

.resumen__cuenta strong {
  color: var(--texto);
}

.orden {
  font-size: 0.8125rem;
  color: var(--tenue);
}

/* ── 7. Tarjetas ────────────────────────────────────────────────────────── */
.lista {
  list-style: none;
  margin: 0;
  padding: 0 0 1.5rem;
  display: grid;
  gap: 0.75rem;
}

.ficha {
  position: relative;
  border: 1px solid var(--borde);
  border-radius: var(--r);
  background: var(--panel);
  padding: 1rem;
  transition: border-color 0.18s var(--suavizado), background-color 0.18s var(--suavizado);
}

.ficha:hover {
  border-color: var(--borde-vivo);
  background: var(--panel-alto);
}

/* Cuando se toca un pin, su tarjeta se marca. El vínculo en los dos sentidos
   entre mapa y lista es lo que hace que esto se sienta armado y no dos
   componentes conviviendo. */
.ficha.activa {
  border-color: var(--acento);
  background: var(--panel-alto);
  box-shadow: 0 0 0 1px var(--acento), var(--sombra);
}

.ficha[hidden] {
  display: none;
}

.ficha__cabeza {
  display: flex;
  align-items: center;
  gap: 0.875rem;
}

/* Rectángulo apaisado y no un cuadrado chico: los logos reales son más
   anchos que altos, y el logo es lo que el cliente reconoce de un vistazo,
   así que le damos el tamaño que le corresponde en la ficha. */
.ficha__logo {
  display: grid;
  place-items: center;
  flex: none;
  width: 5.5rem;
  height: 3.5rem;
  border-radius: 0.625rem;
  background: var(--fondo-alto);
  border: 1px solid var(--borde);
  overflow: hidden;
}

.ficha__logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.375rem;
}

/* Sin logo cargado, la inicial en el acento. Mejor que un ícono genérico
   repetido en toda la lista. */
.ficha__inicial {
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--acento);
}

/* Con logo cargado (la imagen cargó bien: ver onload en Default.aspx), fondo
   blanco y se tapa la inicial. Un logo pensado para fondo claro se pierde
   sobre --fondo-alto, así que acá no sirve la misma base oscura del resto de
   la tarjeta. */
.ficha__logo--imagen {
  background: #fff;
}

.ficha__logo--imagen .ficha__inicial {
  display: none;
}

.ficha__id {
  min-width: 0;
  flex: 1 1 auto;
}

.ficha__nombre {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  overflow-wrap: break-word;
}

.ficha__lugar {
  margin: 0.125rem 0 0;
  font-size: 0.875rem;
  color: var(--suave);
}

.ficha__dist {
  flex: none;
  text-align: right;
  font-size: 1rem;
  color: var(--acento);
  white-space: nowrap;
}

/* Sin ubicación conocida no hay distancia que mostrar: el hueco se colapsa en
   lugar de mostrar un guión o un cero, que serían datos falsos. */
.ficha__dist:empty {
  display: none;
}

.etiquetas {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.875rem;
}

.etiqueta {
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--borde);
  border-radius: 0.3125rem;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--suave);
}

/* Jerarquía sin ambigüedad: WhatsApp ocupa todo el ancho y es lo más alto
   de la ficha (3rem, cómodo para el pulgar); el sitio web va debajo, más
   bajo y con borde, para que nunca compita con el contacto. */
.ficha__acciones {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.875rem;
}

.ficha__acciones .btn {
  width: 100%;
  padding: 0 0.875rem;
}

.ficha__acciones .btn--acento {
  min-height: 3rem;
  font-size: 0.9375rem;
  font-weight: 700;
}

.ficha__acciones .btn--acento svg {
  width: 1.25rem;
  height: 1.25rem;
}

.ficha__acciones .btn--linea {
  min-height: 2.5rem;
  font-size: 0.875rem;
}

.ficha__ver {
  position: absolute;
  inset: 0;
  border: 0;
  background: none;
  cursor: pointer;
  border-radius: var(--r);
  /* Cubre la tarjeta para que tocar cualquier parte la centre en el mapa, pero
     queda DEBAJO de los botones, que tienen su propia acción. */
  z-index: 0;
}

.ficha__cabeza,
.etiquetas,
.ficha__acciones {
  position: relative;
  z-index: 1;
  pointer-events: none;
}

.ficha__acciones .btn {
  pointer-events: auto;
}

.vacio {
  padding: 2.5rem 1rem;
  text-align: center;
  border: 1px dashed var(--borde-vivo);
  border-radius: var(--r);
  color: var(--suave);
}

.vacio strong {
  display: block;
  color: var(--texto);
  margin-bottom: 0.375rem;
}

/* ── 7.5. Cómo funciona ─────────────────────────────────────────────────── */
/* Tres pasos numerados (es una secuencia de verdad) junto a una foto de una
   instalación, que ancla la idea de "gente real que hace ventanas". */
.como-funciona {
  padding: 2.5rem 0;
  border-top: 1px solid var(--borde);
}

.como-funciona__grilla {
  display: grid;
  gap: 1.5rem;
  align-items: center;
}

.como-funciona__foto {
  aspect-ratio: 16 / 9;
}

.como-funciona h2 {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.15;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.pasos {
  list-style: none;
  counter-reset: paso;
  margin: 1.25rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.125rem;
}

.pasos li {
  counter-increment: paso;
  position: relative;
  padding-left: 3rem;
}

.pasos li::before {
  content: counter(paso);
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 2.125rem;
  height: 2.125rem;
  border-radius: 999px;
  background: var(--acento-10);
  border: 1px solid var(--acento-20);
  color: var(--acento);
  font-weight: 800;
  font-size: 0.9375rem;
}

.pasos h3 {
  margin: 0.125rem 0 0;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

.pasos p {
  margin: 0.125rem 0 0;
  font-size: 0.9375rem;
  color: var(--suave);
}

.sumarse__foto {
  aspect-ratio: 16 / 9;
  margin-bottom: 1.25rem;
}

/* ── 8. Sumarse ─────────────────────────────────────────────────────────── */
.sumarse {
  border-top: 1px solid var(--borde);
  background: var(--fondo-alto);
  padding-top: 3rem;
  padding-bottom: 3rem;
}

.sumarse__grilla {
  display: grid;
  gap: 1.75rem;
}

.sumarse h2 {
  margin: 0;
  font-size: 1.5rem;
  line-height: 1.15;
  font-weight: 800;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.sumarse p {
  margin: 0.75rem 0 0;
  color: var(--suave);
  text-wrap: pretty;
}

.puntos {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.625rem;
  font-size: 0.9375rem;
  color: var(--suave);
}

.puntos li {
  display: flex;
  gap: 0.625rem;
}

.puntos svg {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1875rem;
  color: var(--acento);
}

.formulario {
  border: 1px solid var(--borde);
  border-radius: var(--r);
  background: var(--panel);
  padding: 1.25rem;
}

.campos {
  display: grid;
  gap: 0.875rem;
}

.campo label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--suave);
  margin-bottom: 0.3125rem;
}

.campo .req {
  color: var(--acento);
}

.campo input,
.campo textarea {
  width: 100%;
  padding: 0.6875rem 0.875rem;
  border: 1px solid var(--borde);
  border-radius: var(--r-chico);
  background: var(--fondo-alto);
  color: var(--texto);
  font-family: inherit;
  font-size: 0.9375rem;
  transition: border-color 0.18s, background-color 0.18s;
}

.campo textarea {
  min-height: 5.5rem;
  resize: vertical;
}

.campo input::placeholder,
.campo textarea::placeholder {
  color: var(--tenue);
}

.campo input:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--acento);
  background: var(--panel-alto);
}

.campo--mal input,
.campo--mal textarea {
  border-color: var(--alerta);
}

.campo__error {
  display: block;
  margin-top: 0.3125rem;
  font-size: 0.8125rem;
  color: var(--alerta);
}

.aviso {
  margin: 0;
  padding: 0.6875rem 0.875rem;
  border: 1px solid rgba(255, 122, 107, 0.35);
  border-radius: var(--r-chico);
  background: rgba(255, 122, 107, 0.08);
  font-size: 0.875rem;
  color: var(--alerta);
}

.legal {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--tenue);
}

.listo {
  text-align: center;
  padding: 1.5rem 0;
}

.listo__ico {
  display: inline-grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  background: var(--acento-10);
  border: 1px solid var(--acento-20);
  color: var(--acento);
}

.listo__ico svg {
  width: 1.5rem;
  height: 1.5rem;
}

.listo h3 {
  margin: 1rem 0 0;
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.listo p {
  margin: 0.5rem auto 0;
  max-width: 22rem;
}

/* ── 9. Footer ──────────────────────────────────────────────────────────── */
.footer {
  border-top: 1px solid var(--borde);
  padding-top: 2rem;
  padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
  color: var(--tenue);
  font-size: 0.8125rem;
}

.footer__fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
}

.footer__fila p {
  margin: 0;
}

.footer a {
  text-decoration: none;
}

.footer a:hover {
  color: var(--suave);
}

.footer__nota {
  margin: 1rem 0 0;
  max-width: 44rem;
  line-height: 1.6;
}

/* ── Accesibilidad de movimiento ────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Breakpoints ────────────────────────────────────────────────────────── */
@media (min-width: 40rem) {
  .contenedor {
    padding-left: 1.75rem;
    padding-right: 1.75rem;
  }

  .header__barra {
    gap: 0.75rem;
  }

  .header__acciones .btn {
    padding: 0 1.125rem;
    font-size: 0.9375rem;
  }

  .ubicacion {
    padding: 0.4375rem 0.75rem 0.4375rem 0.625rem;
  }

  .ubicacion__texto {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: nowrap;
    border: 0;
  }

  .portada {
    padding-top: 2.25rem;
    padding-bottom: 1.75rem;
    min-height: 19rem;
    display: flex;
    align-items: center;
  }

  .portada h1 {
    font-size: 2.5rem;
  }

  .portada p {
    font-size: 1.0625rem;
  }

  .mapa {
    height: 46svh;
  }

  .panel {
    padding-left: 1.75rem;
    padding-right: 1.75rem;
  }

  .filtros {
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
    flex-wrap: wrap;
    overflow: visible;
  }

  .lista {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .material {
    min-height: 9.5rem;
  }

  .material__nombre {
    font-size: 1.1875rem;
  }

  .sumarse__grilla {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2.5rem;
    align-items: start;
  }

  .formulario {
    padding: 1.75rem;
  }

  .campos--doble {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/*
 * Desde 64rem cambia el esquema: en vez de mapa arriba y lista abajo, dos
 * columnas con el mapa FIJO a la derecha. Es lo que permite recorrer la lista
 * sin perder de vista el mapa, que en escritorio es la ventaja real de tener
 * más pantalla.
 */
@media (min-width: 64rem) {
  /*
   * En el HTML el mapa viene ANTES de la lista, porque en celular ese es el
   * orden correcto: primero el mapa a sangre, después las tarjetas. En
   * escritorio la lista tiene que ir a la izquierda, y en vez de duplicar el
   * markup o reordenar con flex, se asignan las celdas de la grilla de forma
   * explícita. El DOM queda en un solo orden, que es el que también leen un
   * lector de pantalla y el buscador.
   */
  .doble {
    display: grid;
    grid-template-columns: minmax(0, 27rem) minmax(0, 1fr);
    gap: 1.75rem;
    align-items: start;
    max-width: var(--ancho);
    margin: 0 auto;
    padding: 0 1.75rem;
  }

  .doble > .mapa-caja {
    grid-column: 2;
    grid-row: 1;
  }

  .doble > .col-lista {
    grid-column: 1;
    grid-row: 1;
  }

  .panel {
    padding-left: 0;
    padding-right: 0;
  }

  .portada {
    padding-top: 2rem;
    padding-bottom: 1.75rem;
  }

  /* Texto a la izquierda, fotos de material a la derecha: llena el ancho que
     antes quedaba vacío y deja la portada más baja, con el mapa más arriba. */
  .portada__caja {
    max-width: none;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 30rem);
    column-gap: 3.5rem;
    align-items: start;
  }

  .portada__caja > .materiales {
    grid-column: 2;
    grid-row: 1 / span 4;
    align-self: center;
    margin-top: 0;
  }

  .portada h1 {
    font-size: 3rem;
  }

  .mapa-caja {
    position: sticky;
    top: calc(var(--header) + 1.75rem);
    margin-top: 0;
  }

  .mapa {
    height: calc(100svh - var(--header) - 3.5rem);
    min-height: 28rem;
    border: 1px solid var(--borde);
    border-radius: var(--r);
    overflow: hidden;
  }

  .panel {
    margin-top: 0;
    border: 0;
    border-radius: 0;
    background: none;
    padding-top: 0;
  }

  .panel__asa {
    display: none;
  }

  .lista {
    grid-template-columns: minmax(0, 1fr);
  }

  .como-funciona__grilla {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
  }

  .como-funciona__foto {
    aspect-ratio: 4 / 3;
  }

  .footer__nota {
    margin-top: 0.75rem;
  }
}

@media (min-width: 80rem) {
  .doble {
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
  }
}
