/* =============================================================================
   componentes.css — Botones, campos, chips, tarjetas, carrusel y avisos

   Cada elemento visual se escribe una sola vez y se usa en todas las páginas
   (DECISIONES.md §5). Mobile primero: sin `@media` es el celular.
   ============================================================================= */

/* ─── Botones ──────────────────────────────────────────────────────────────── */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: var(--tactil);
  padding: var(--e2) var(--e5);
  border-radius: var(--radio);
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  border: 1px solid transparent;
  cursor: pointer;
}
.boton:hover { text-decoration: none; }

/* El acento es brillante: siempre lleva texto oscuro encima, nunca blanco
   (DECISIONES.md §1.4). */
.boton--acento { background: var(--accent); color: var(--text); }
.boton--acento:hover { filter: brightness(.94); }

.boton--primario { background: var(--primary); color: #fff; }
.boton--primario:hover { filter: brightness(1.2); }

.boton--texto { background: transparent; color: var(--text); padding-inline: var(--e3); }
.boton--texto:hover { color: var(--primary); }

.boton--borde { background: var(--surface); color: var(--primary); border-color: var(--border); }
.boton--borde:hover { border-color: var(--primary); }

.boton--whatsapp { background: var(--surface); color: #128C4B; border-color: #CBE7D6; }
.boton--whatsapp:hover { background: #F2FAF5; }

.boton--ancho  { width: 100%; }
.boton--grande { min-height: 52px; font-size: 1.02rem; }
/* Para acciones secundarias dentro de un formulario —copiar un día, agregar un
   turno—: más chico que el botón principal, pero con el alto táctil intacto. */
.boton--chico { min-height: var(--tactil); padding-inline: var(--e3); font-size: .85rem; }

/* Enlace que se comporta como botón chico y no ocupa lugar. */
.enlace-boton {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  padding: var(--e1) 0;
  border: 0;
  background: transparent;
  color: var(--primary);
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
}
.enlace-boton:hover { text-decoration: underline; }

/* ─── Enlaces con flecha ───────────────────────────────────────────────────── */

.enlace-mas {
  flex: none;
  font-size: .85rem;
  font-weight: 700;
  white-space: nowrap;
}
.enlace-mas::after { content: " →"; }

/* ─── Campos de formulario ─────────────────────────────────────────────────── */

.campo { display: grid; gap: var(--e1); }

.campo__fila { display: flex; align-items: baseline; justify-content: space-between; gap: var(--e2); }

.campo__etiqueta { font-size: .85rem; font-weight: 700; color: var(--text); }

.campo__caja {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  min-height: var(--tactil);
}
.campo__caja:focus-within { border-color: var(--primary); }

.campo__ico {
  position: absolute;
  left: var(--e3);
  color: var(--text-soft);
  pointer-events: none;
}
.campo__ico--derecha { left: auto; right: var(--e3); }

.campo__control {
  width: 100%;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: var(--e2) var(--e3) var(--e2) 2.6rem;
  min-height: var(--tactil);
  outline-offset: -2px;
  /* El buscador es una tarjeta blanca dentro del hero navy, que hereda texto
     blanco: sin esto, lo que se escribe y lo elegido en el select no se ven. */
  color: var(--text);
}
.campo__control::placeholder { color: #97A2AC; }

.campo__control--select {
  padding-left: var(--e3);
  padding-right: 2.6rem;
  appearance: none;
  cursor: pointer;
}

/* ─── Chips ────────────────────────────────────────────────────────────────── */

.chip {
  display: inline-block;
  padding: .15rem .55rem;
  border-radius: var(--radio-pastilla);
  font-size: .78rem;
  font-weight: 700;
  line-height: 1.5;
}

.chip--rubro { background: #EDF6DE; color: #3F5A18; }
a.chip--rubro:hover { background: var(--accent); color: var(--text); text-decoration: none; }

/* Sobre el navy del hero. */
.chip--hueco {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 var(--e4);
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--linea-primary);
  color: #fff;
  font-weight: 600;
}
.chip--hueco:hover { background: rgba(255, 255, 255, .16); text-decoration: none; }

.chips { margin-top: var(--e4); }
.chips__rotulo {
  display: block;
  margin-bottom: var(--e2);
  color: var(--sobre-primary-suave);
  font-size: .85rem;
}
.chips__lista { display: flex; flex-wrap: wrap; gap: var(--e2); }

/* ─── Insignia de verificado ───────────────────────────────────────────────── */

.insignia {
  position: absolute;
  top: var(--e3);
  right: var(--e3);
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--surface);
  color: #4B9B18;
  box-shadow: var(--sombra);
}
.insignia .ico { width: 1.4rem; height: 1.4rem; }

/* ─── Tarjeta de rubro ─────────────────────────────────────────────────────── */

.tarjeta-rubro {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: var(--e1);
  height: 100%;
  min-height: 108px;
  padding: var(--e3) var(--e2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  text-align: center;
}
.tarjeta-rubro:hover { border-color: var(--accent); text-decoration: none; }

/* En celular la tarjeta es una sola columna centrada, así que el envoltorio se
   borra y sus hijos se apilan con el ícono. En escritorio vuelve a existir y
   agrupa nombre y conteo al lado del ícono. */
.tarjeta-rubro__cuerpo { display: contents; }

.tarjeta-rubro__nombre {
  font-weight: 700;
  font-size: .82rem;
  line-height: 1.25;
  color: var(--text);
  hyphens: auto;
}
.tarjeta-rubro__dato { font-size: .74rem; color: var(--text-soft); }

/* ─── Tarjeta de comercio ──────────────────────────────────────────────────── */

.tarjeta-comercio {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  overflow: hidden;
}

.tarjeta-comercio__foto {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  background: #DCE6EC;
  color: rgba(0, 42, 65, .22);
}
.tarjeta-comercio__foto img { width: 100%; height: 100%; object-fit: cover; }

.tarjeta-comercio__cuerpo {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  flex: 1 1 auto;
  padding: var(--e4);
}

.tarjeta-comercio__nombre { margin: 0; font-size: 1.05rem; }
.tarjeta-comercio__nombre a { color: var(--text); }

.tarjeta-comercio__rubro { margin: 0; }

.tarjeta-comercio__bajada {
  margin: 0;
  color: var(--text-soft);
  font-size: .88rem;
  line-height: 1.45;
}

.tarjeta-comercio__dato {
  display: flex;
  align-items: flex-start;
  gap: var(--e2);
  margin: 0;
  color: var(--text-soft);
  font-size: .84rem;
}
.tarjeta-comercio__dato .ico { margin-top: .2em; }

/* El botón queda siempre al pie de la tarjeta, aunque la bajada sea corta. */
.tarjeta-comercio__cuerpo > .boton { margin-top: auto; width: 100%; }

/* ─── Fila de comercio (la variante compacta) ──────────────────────────────── */

.fila-comercio {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-height: 56px;
  padding: var(--e2) var(--e3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
}
.fila-comercio:hover { border-color: var(--accent); text-decoration: none; }

.fila-comercio__foto {
  width: 40px; height: 40px;
  flex: none;
  border-radius: var(--radio-chico);
  object-fit: cover;
}
.fila-comercio__cuerpo {
  display: flex;
  flex-direction: column;
  min-width: 0;                    /* si no, el nombre largo no deja encoger */
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  flex: 1 1 auto;
}
.fila-comercio__nombre {
  color: var(--text);
  font-weight: 600;
  font-size: .92rem;
  line-height: 1.3;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fila-comercio__flecha { color: var(--text-soft); }

.lista-comercios { display: grid; gap: var(--e2); }

/* ─── Carrusel ─────────────────────────────────────────────────────────────
   El desplazamiento es del navegador: `overflow-x` + `scroll-snap`, sin una
   línea de JavaScript (§0.5). La tarjeta ocupa el 85 % del ancho para que la
   siguiente se asome y se entienda que hay más. Este desborde es deliberado y
   está contenido; el de la página no existe. */

.carrusel { position: relative; }

.carrusel__pista {
  display: flex;
  gap: var(--e3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--e4);
  padding-bottom: var(--e3);
  /* El asomo se hace con margen negativo para que la primera tarjeta quede
     alineada con el resto del contenido y la última llegue al borde. */
  margin: 0 calc(var(--e4) * -1);
  padding-left: var(--e4);
  padding-right: var(--e4);
  scrollbar-width: none;
}
.carrusel__pista::-webkit-scrollbar { display: none; }

.carrusel__item {
  flex: 0 0 85%;
  max-width: 340px;
  scroll-snap-align: start;
  display: flex;
}
.carrusel__item > * { width: 100%; }

.carrusel__puntos {
  display: flex;
  justify-content: center;
  gap: var(--e2);
  margin-top: var(--e2);
}
.carrusel__punto {
  width: 8px; height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #C4CFD6;
  cursor: pointer;
}
.carrusel__punto--activo { background: var(--accent); }

/* ─── Avisos ───────────────────────────────────────────────────────────────── */

.aviso {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: var(--radio);
  padding: var(--e3) var(--e4);
  color: var(--text-soft);
  font-size: .9rem;
  text-align: left;
}
.aviso--suave { margin-bottom: var(--e4); }

.nota-dev {
  margin-top: var(--e5);
  padding: var(--e4) var(--e5);
  border: 1px dashed var(--border);
  border-radius: var(--radio);
  text-align: left;
  font-size: .9rem;
  color: var(--text-soft);
}
.nota-dev p:last-child { margin-bottom: 0; }

/* =============================================================================
   sm — 600 px
   ============================================================================= */

@media (min-width: 600px) {
  .carrusel__item { flex-basis: 46%; }
  .tarjeta-rubro { min-height: 120px; }
  .tarjeta-rubro__nombre { font-size: .85rem; }
  .tarjeta-rubro__dato { font-size: .75rem; }
  /* `minmax(0, 1fr)` y no `1fr`: el `auto` implícito de `1fr` no baja del
     contenido más ancho, y un nombre largo desborda la grilla. */
  .lista-comercios { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =============================================================================
   md — 900 px
   ============================================================================= */

@media (min-width: 900px) {

  .carrusel__pista {
    margin: 0;
    padding-left: 0;
    padding-right: 0;
  }
  .carrusel__item { flex-basis: calc((100% - var(--e3) * 3) / 4); max-width: none; }
  .carrusel__puntos { display: none; }

  /* Con el rubro en línea de a cuatro, la tarjeta puede ir en horizontal. */
  .tarjeta-rubro {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: var(--e3);
    min-height: 84px;
    padding: var(--e4) var(--e5);
    text-align: left;
  }
  .tarjeta-rubro__cuerpo { display: flex; flex-direction: column; min-width: 0; }
  .tarjeta-rubro__nombre { font-size: .98rem; }
  .tarjeta-rubro__dato { font-size: .82rem; }
  .ico--rubro { width: 2rem; height: 2rem; }

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

/* =============================================================================
   Sesión 7 — Listado, ficha y buscador
   Mobile primero: sin `@media` es el celular.
   ============================================================================= */

/* ─── Migas ────────────────────────────────────────────────────────────────
   En celular se desplazan en horizontal dentro de su propia caja, que es la
   excepción permitida de §0.5: el desborde es deliberado y está contenido. */

.migas {
  overflow-x: auto;
  scrollbar-width: none;
  padding: var(--e3) 0 0;
}
.migas::-webkit-scrollbar { display: none; }

.migas__lista {
  display: flex;
  align-items: center;
  gap: var(--e1);
  font-size: .8rem;
  white-space: nowrap;
}
.migas__paso { display: flex; align-items: center; gap: var(--e1); }
.migas__paso a { color: var(--text-soft); }
.migas__paso a:hover { color: var(--primary); }
.migas__paso [aria-current] { color: var(--text); font-weight: 700; }
.migas__flecha { color: #A9B4BD; }

/* ─── Chips de filtro y de subcategoría ───────────────────────────────────── */

.chip--filtro {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  min-height: 34px;
  padding: 0 var(--e3);
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 600;
}
.chip--filtro:hover { border-color: var(--primary); text-decoration: none; }
.chip--filtro--activo { background: var(--primary); border-color: var(--primary); color: #fff; }
.chip__num { color: var(--text-soft); font-weight: 400; }
.chip--filtro--activo .chip__num { color: var(--sobre-primary-suave); }

/* La fila de chips se desliza en horizontal en celular y se acomoda en varias
   líneas desde 600 px: son muchas subcategorías y apilarlas come media pantalla. */
.chips-rubro {
  display: flex;
  gap: var(--e2);
  margin: var(--e4) 0 0;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: var(--e2);
}
.chips-rubro::-webkit-scrollbar { display: none; }
.chips-rubro > * { flex: none; }

/* ─── Barra de orden y filtros ────────────────────────────────────────────── */

.barra-filtros {
  display: grid;
  gap: var(--e3);
  padding: var(--e3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  margin-bottom: var(--e5);
}

.campo--compacto .campo__etiqueta { font-size: .78rem; color: var(--text-soft); }

.filtros__resumen {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--tactil);
  padding: 0 var(--e3);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  font-size: .9rem;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.filtros__resumen::-webkit-details-marker { display: none; }
.filtros[open] > .filtros__resumen { border-color: var(--primary); }

.filtros__cuenta {
  display: grid;
  place-items: center;
  min-width: 20px; height: 20px;
  border-radius: var(--radio-pastilla);
  background: var(--accent);
  color: var(--text);
  font-size: .72rem;
}

.filtros__lista {
  display: grid;
  gap: var(--e1);
  padding: var(--e3) 0;
}

.filtro {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--tactil);
  padding: 0 var(--e2);
  border-radius: var(--radio-chico);
  font-size: .9rem;
  cursor: pointer;
}
.filtro:hover { background: var(--muted); }
.filtro input { width: 18px; height: 18px; accent-color: var(--primary); }
.filtro__cuerpo { display: flex; align-items: center; gap: var(--e2); }

.filtros__acciones { display: flex; gap: var(--e2); align-items: center; }

/* ─── La vidriera de los planes pagos ─────────────────────────────────────── */

.destacados { margin-bottom: var(--e5); }

.destacados__cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e2) var(--e3);
  margin-bottom: var(--e3);
}
.destacados__titulo { margin: 0; font-size: 1.1rem; }

.vidriera {
  display: grid;
  gap: var(--e3);
  padding: var(--e4);
  background: #F6FAEF;
  border: 1px solid #DCEBC2;
  border-radius: var(--radio);
  text-align: center;
  justify-items: center;
}
.vidriera__ico {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid #DCEBC2;
  color: #6FA82A;
}
.vidriera__titulo { margin: 0 0 var(--e1); font-weight: 800; }
.vidriera__bajada { margin: 0; color: var(--text-soft); font-size: .9rem; }

/* ─── Fila del listado ────────────────────────────────────────────────────── */

.listado__cabecera { margin-bottom: var(--e3); }
.listado__titulo { margin: 0 0 var(--e1); font-size: 1.05rem; }
.listado__nota {
  display: flex;
  align-items: center;
  gap: var(--e2);
  margin: 0;
  color: var(--text-soft);
  font-size: .8rem;
}

.listado__lista { display: grid; gap: var(--e2); }

.fila-listado {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--e2);
  padding: var(--e3);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
}
.fila-listado:hover { border-color: var(--accent); }

/* Cada parte tiene su celda fija. Sin esto, la fila de formas de operar
   —que ocupa las dos columnas— empuja los botones a una tercera fila, y la
   fila cambia de forma según el comercio tenga atributos o no. */
.fila-listado__enlace   { grid-column: 1; grid-row: 1; }
.fila-listado__acciones { grid-column: 2; grid-row: 1; }
.fila-listado__atributos { grid-column: 1 / -1; grid-row: 2; }

.fila-listado__enlace {
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
  min-width: 0;
  color: inherit;
}
.fila-listado__enlace:hover { text-decoration: none; }

.fila-listado__foto {
  width: 44px; height: 44px;
  flex: none;
  border-radius: var(--radio-chico);
  object-fit: cover;
}
.fila-listado__cuerpo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--e1);
  min-width: 0;
}

.fila-listado__titulo { min-width: 0; }
.fila-listado__nombre { font-weight: 700; font-size: .95rem; line-height: 1.3; color: var(--text); }
/* La insignia va dentro del nombre y fluye detrás de la última palabra. */
.fila-listado__nombre .visto { margin-left: var(--e1); }

.fila-listado__bajada,
.fila-listado__dato {
  color: var(--text-soft);
  font-size: .82rem;
  line-height: 1.35;
}
.fila-listado__dato { display: flex; align-items: flex-start; gap: var(--e1); }

/* La insignia de verificado, pegada al nombre (no después del chip de rubro). */
.visto { display: inline-flex; vertical-align: -.18em; color: #4B9B18; flex: none; }
.visto--grande .ico { width: 1.5rem; height: 1.5rem; }

/* Formas de operar. En celular llevan la etiqueta al lado del ícono: un ícono
   suelto a 360 px no se entiende. En escritorio queda solo el ícono. */
.fila-listado__atributos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e1);
}
.marca-atributo {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  padding: .1rem .5rem;
  border-radius: var(--radio-pastilla);
  background: var(--muted);
  color: var(--text-soft);
  font-size: .72rem;
}
.marca-atributo__texto { white-space: nowrap; }

.fila-listado__acciones { display: flex; align-items: center; gap: var(--e1); }

.boton-redondo {
  display: grid;
  place-items: center;
  width: var(--tactil); height: var(--tactil);
  flex: none;
  border-radius: var(--radio);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--primary);
}
.boton-redondo:hover { border-color: var(--primary); text-decoration: none; }
.boton-redondo--whatsapp { color: #128C4B; border-color: #CBE7D6; }

.fila-listado__ver {
  display: grid;
  place-items: center;
  width: 28px; height: var(--tactil);
  color: var(--text-soft);
}

/* ─── Paginación ──────────────────────────────────────────────────────────
   Numerada e idéntica en las dos pantallas (§6.1). En celular se muestran menos
   vecinos, pero es la misma lista: nada de «ver más». */

.paginacion {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--e1);
  margin-top: var(--e5);
}

.paginacion__lista { display: flex; align-items: center; gap: var(--e1); }

.paginacion__num,
.paginacion__salto {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e1);
  min-width: var(--tactil);
  height: var(--tactil);
  padding: 0 var(--e2);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  background: var(--surface);
  color: var(--text);
  font-size: .9rem;
  font-weight: 600;
}
.paginacion__num:hover,
.paginacion__salto:hover { border-color: var(--primary); text-decoration: none; }

.paginacion__num--activa {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.paginacion__puntos { color: var(--text-soft); padding: 0 var(--e1); }
.paginacion__atras { transform: rotate(180deg); }
.paginacion__texto { display: none; }

/* ─── Estados vacíos ──────────────────────────────────────────────────────── */

.vacio {
  display: grid;
  justify-items: center;
  gap: var(--e3);
  padding: var(--e7) var(--e4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  text-align: center;
}
.vacio__ico {
  display: grid;
  place-items: center;
  width: 84px; height: 84px;
  border-radius: 50%;
  background: var(--muted);
  color: #9AA6AF;
}
.vacio__ico .ico { width: 2.5rem; height: 2.5rem; }
.vacio__titulo { margin: 0; }
.vacio__texto { margin: 0; color: var(--text-soft); max-width: 42ch; }

/* ─── Cierre de listado: sumá tu comercio ─────────────────────────────────── */

.cierre {
  display: grid;
  gap: var(--e3);
  justify-items: center;
  padding: var(--e5) var(--e4);
  background: #F6FAEF;
  border: 1px solid #DCEBC2;
  border-radius: var(--radio);
  text-align: center;
}
.cierre__ico {
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--surface);
  color: #6FA82A;
}
.cierre__titulo { margin: 0 0 var(--e1); font-weight: 800; }
.cierre__bajada { margin: 0; color: var(--text-soft); font-size: .9rem; }

/* ─── Acordeón genérico (horarios) ────────────────────────────────────────── */

.acordeon__resumen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e2);
  min-height: var(--tactil);
  color: var(--primary);
  font-size: .88rem;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
}
.acordeon__resumen::-webkit-details-marker { display: none; }
.acordeon__chevron { transition: transform .15s ease; }
.acordeon[open] > .acordeon__resumen .acordeon__chevron { transform: rotate(180deg); }

/* ─── Campo de área y campo sin ícono ─────────────────────────────────────── */

.campo__control--simple { padding-left: var(--e3); }
.campo__control--area {
  padding: var(--e2) var(--e3);
  min-height: 84px;
  resize: vertical;
}

/* El honeypot de §4.8. Se esconde desde el CSS, no con `style=` (§0.2). */
/* El campo trampa de §4.8. **`display: none` y no «fuera de pantalla»**: el
   autocompletado de Chrome ignora lo que está con `display: none`, pero sí
   completa un campo que está a -9999px, y un campo trampa completado por el
   gestor de contraseñas rechaza a una persona de verdad. */
.trampa { display: none; }

.aviso--ok {
  border-left-color: #4B9B18;
  background: #F4FAEE;
  color: var(--text);
}

/* =============================================================================
   sm — 600 px
   ============================================================================= */

@media (min-width: 600px) {

  .chips-rubro { flex-wrap: wrap; overflow: visible; }

  .barra-filtros {
    grid-template-columns: minmax(200px, 260px) auto;
    align-items: end;
  }
  .filtros__lista { grid-template-columns: 1fr 1fr; }

  .vidriera {
    grid-template-columns: auto 1fr auto;
    align-items: center;
    text-align: left;
    justify-items: start;
    padding: var(--e4) var(--e5);
  }

  .cierre {
    grid-template-columns: auto 1fr auto;
    align-items: center;
    text-align: left;
    justify-items: start;
  }

  .paginacion__texto { display: inline; }

  .listado__cabecera {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--e3);
  }
  .listado__titulo { margin: 0; }
}

/* =============================================================================
   md — 900 px
   ============================================================================= */

@media (min-width: 900px) {

  .fila-listado {
    grid-template-columns: 1fr auto auto;
    gap: var(--e4);
    padding: var(--e3) var(--e4);
  }

  .fila-listado__enlace { align-items: center; }
  .fila-listado__foto { width: 52px; height: 52px; }
  .fila-listado__nombre { font-size: 1rem; }

  /* Con más ancho el ícono se explica solo y la etiqueta sobra: queda en el
     `title` y en el lector de pantalla. */
  .fila-listado__atributos { grid-column: 2; grid-row: 1; flex-wrap: nowrap; }
  .fila-listado__acciones  { grid-column: 3; grid-row: 1; }
  .marca-atributo { padding: 0; background: transparent; }
  .marca-atributo__texto {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .marca-atributo .ico { width: 1.25rem; height: 1.25rem; }

  .filtros__lista { grid-template-columns: repeat(4, 1fr); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   CUENTA (sesión 8)
   Todo lo de acá es la versión de celular. Las mejoras entran más abajo, con
   `min-width` (§0.5).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Avisos con ícono ──────────────────────────────────────────────────────
   El ícono va flotado y no en un `flex`: `.aviso` también lo usan páginas que
   llevan texto corrido con `<code>` adentro, y volverlas contenedor flex les
   partiría la frase en pedazos. */

.aviso > .ico { float: left; margin: .1rem var(--e2) 0 0; }

.aviso--ok    { border-left-color: #4B9B18; color: var(--text); }
.aviso--error { border-left-color: #C0392B; color: var(--text); }
.aviso--espera { border-left-color: #C79A1E; color: var(--text); }
.aviso--ok .ico    { color: #4B9B18; }
.aviso--error .ico { color: #C0392B; }
.aviso--espera .ico { color: #C79A1E; }

/* La confirmación de un envío. Más grande que un aviso al paso: es la única
   señal de que el formulario hizo algo, y tiene que leerse de un vistazo. */
.aviso--grande {
  display: flex;
  gap: var(--e3);
  align-items: flex-start;
  padding: var(--e4) var(--e5);
  font-size: 1rem;
}
/* Acá sí puede ser `flex`: es un aviso corto y propio, sin texto corrido con
   `<code>` adentro, que es lo que obliga al flotado en `.aviso` a secas. */
.aviso--grande > .ico { float: none; flex: 0 0 auto; margin: .15rem 0 0; }
.aviso--grande strong { display: block; font-size: 1.1rem; }
.aviso--grande p { margin: var(--e1) 0 0; color: var(--text-soft); font-size: .9rem; }
.aviso--grande:focus { outline: none; }
.aviso--grande:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Un botón que ya mandó. Se apaga con `disabled` desde `app.js`, y acá se le
   pone la cara: apagado pero no roto, y el cursor de espera. */
.boton[aria-busy="true"] { opacity: .7; cursor: progress; }

/* ─── Formularios ──────────────────────────────────────────────────────────
   Los campos ya están en «Campos de formulario», más arriba. Acá va lo que
   suma la cuenta: errores, ayuda, el ojo de la contraseña y el check. */

.formulario { display: grid; gap: var(--e4); text-align: left; }

.campo__ayuda { font-size: .8rem; color: var(--text-soft); }

.campo__error {
  font-size: .8rem;
  font-weight: 700;
  color: #C0392B;
}

.campo__control[aria-invalid="true"] { color: var(--text); }
.campo__caja:has(> [aria-invalid="true"]) { border-color: #C0392B; }

/* El campo de contraseña deja lugar al botón del ojo, a la derecha. */
.campo__caja:has(> .campo__ojo) .campo__control { padding-right: var(--tactil); }

.campo__ojo {
  position: absolute;
  right: 0;
  display: grid;
  place-items: center;
  width: var(--tactil);
  height: var(--tactil);
  border: 0;
  background: var(--surface);
  color: var(--text-soft);
  cursor: pointer;
}
.campo__ojo:hover { color: var(--primary); }

/* La marca «Verificado / No verificado» del campo de email. Va debajo del
   campo: adentro le come ancho al texto y corta el correo a 360 px. */
.campo__marca {
  justify-self: start;
  padding: .1rem .45rem;
  border-radius: var(--radio-chico);
  font-size: .75rem;
  font-weight: 700;
  white-space: nowrap;
}
.campo__marca--ok        { background: #EAF5E1; color: #3F7F14; }
.campo__marca--pendiente { background: var(--muted); color: var(--text-soft); }

/* Casilla de verificación. El área táctil es toda la línea, no solo el cuadro. */
.control-check {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--tactil);
  font-size: .9rem;
  color: var(--text-soft);
  cursor: pointer;
}
.control-check input { width: 1.15rem; height: 1.15rem; accent-color: var(--primary); }

/* ─── El email ya elegido, con «Cambiar» ───────────────────────────────────── */

.email-fijo {
  display: flex;
  align-items: center;
  gap: var(--e2);
  margin-bottom: var(--e4);
  padding: var(--e2) var(--e3);
  background: var(--muted);
  border-radius: var(--radio);
  font-size: .9rem;
  text-align: left;
}
.email-fijo__ico    { color: var(--text-soft); }
.email-fijo__valor  { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.email-fijo__cambiar { font-weight: 700; white-space: nowrap; }

/* «Corregir» es un botón y no un enlace —manda el email de vuelta al primer
   paso por POST, sin ponerlo en la dirección— pero se tiene que ver como el
   «Cambiar» de al lado: texto, no botón. */
button.email-fijo__cambiar {
  padding: 0;
  border: 0;
  background: none;
  color: var(--primary);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
button.email-fijo__cambiar:hover { text-decoration: underline; }

/* «Vas a crear tu cuenta con…»: la versión que tiene que verse. Es el último
   momento para notar un email mal escrito antes de crear la cuenta con él. */
.email-fijo--nuevo {
  padding: var(--e3);
  background: var(--surface);
  border: 2px solid var(--accent);
  font-size: 1rem;
}
.email-fijo--nuevo .email-fijo__valor { white-space: normal; overflow-wrap: anywhere; }

/* ─── Etiquetas de estado ──────────────────────────────────────────────────── */

.etiqueta {
  display: inline-block;
  padding: .1rem .5rem;
  border-radius: var(--radio-pastilla);
  font-size: .75rem;
  font-weight: 700;
}
.etiqueta--ok     { background: #EAF5E1; color: #3F7F14; }
.etiqueta--espera { background: #FDF3DF; color: #8A6416; }
.etiqueta--error  { background: #FBE9E7; color: #B23A2B; }

/* La insignia de verificado, en línea con el nombre y no encima de una foto. */
.insignia--linea {
  position: static;
  display: inline-grid;
  width: 1.15rem; height: 1.15rem;
  vertical-align: -.15rem;
  box-shadow: none;
}
.insignia--linea .ico { width: 1.15rem; height: 1.15rem; }

/* ─── Menú de la cuenta en la cabecera ─────────────────────────────────────── */

.usuario { position: relative; }

.usuario__boton {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--tactil);
  padding: 0 var(--e2);
  border-radius: var(--radio);
  font-weight: 700;
  font-size: .9rem;
  cursor: pointer;
  list-style: none;
}
.usuario__boton::-webkit-details-marker { display: none; }
.usuario__boton:hover { background: var(--muted); }

.usuario__avatar {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--muted);
  color: var(--primary);
}
.usuario__nombre { white-space: nowrap; }

.usuario__lista {
  position: absolute;
  top: calc(100% + var(--e1));
  right: 0;
  z-index: 40;
  min-width: 220px;
  padding: var(--e1);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radio);
  box-shadow: var(--sombra-media);
}

.usuario__link {
  display: flex;
  align-items: center;
  gap: var(--e2);
  width: 100%;
  min-height: var(--tactil);
  padding: 0 var(--e3);
  border: 0;
  border-radius: var(--radio-chico);
  background: transparent;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.usuario__link:hover { background: var(--muted); }
.usuario__link--salir { color: #C0392B; }
/* «¿Tenés un comercio? Sumalo a la guía»: invitación discreta, no una sección. */
.usuario__link--sumar { font-size: .85rem; color: var(--text-soft); }

/* El botón del ojo se dibuja oculto y lo muestra `app.js`: sin JavaScript no
   hace nada, y un botón que no hace nada confunde más de lo que ayuda. */
.campo__ojo { display: none; }
.js .campo__ojo { display: grid; }

/* =============================================================================
   Sesión 11 — Marcador de posición sin foto, y listados a dos columnas
   Mobile primero: sin `@media` es el celular.
   ============================================================================= */

/* ─── Cuando la ficha no tiene foto ────────────────────────────────────────── */

/* Es el caso normal, no la excepción: casi ninguna de las fichas importadas
   tiene imagen. El cuadrado con la inicial no identificaba nada y, sobre todo,
   no comunicaba que ahí falta algo. Va el símbolo de la guía centrado, con
   márgenes amplios y en la proporción que tendría la foto, para que las filas
   no salten según una tenga imagen y la otra no. */
.sin-foto {
  display: grid;
  place-items: center;
  background: #EDF2F5;
  color: var(--primary);
  overflow: hidden;
}

.sin-foto--cuadrado { border-radius: var(--radio-chico); }
.sin-foto--ancho    { width: 100%; height: 100%; aspect-ratio: 16 / 9; }

/* El margen alrededor del símbolo es lo que lo hace leer como marcador y no
   como logo pegado: sin aire parece un error de recorte. */
.sin-foto__simbolo {
  width: auto;
  max-width: 52%;
  max-height: 52%;
  object-fit: contain;
}
.sin-foto--cuadrado .sin-foto__simbolo { max-width: 58%; max-height: 58%; }

/* Los tamaños de cada lugar donde antes iba la inicial. */
.fila-comercio .sin-foto--cuadrado  { width: 40px; height: 40px; }
.fila-listado  .sin-foto--cuadrado  { width: 44px; height: 44px; }

/* ─── Listados: dos columnas en escritorio ─────────────────────────────────── */

/* Una sola columna de filas anchas deja media pantalla vacía a 1180 px y obliga
   a desplazar mucho para ver veinticuatro resultados. Dos columnas entran sin
   apretar: la fila ya reparte nombre, atributos y acciones en celdas fijas. */
@media (min-width: 900px) {

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

  .fila-listado  .sin-foto--cuadrado { width: 52px; height: 52px; }

  /* En escritorio el marcador va en gris y recupera el color cuando el mouse
     entra en la fila: llama la atención sin gritar en toda la página. En
     celular queda siempre a color, porque no hay `hover` (§0.5) y nada acá
     depende de él para funcionar. */
  .sin-foto__simbolo {
    filter: grayscale(1);
    opacity: .55;
    transition: filter .18s ease, opacity .18s ease;
  }
  .fila-listado:hover     .sin-foto__simbolo,
  .fila-comercio:hover    .sin-foto__simbolo,
  .tarjeta-comercio:hover .sin-foto__simbolo {
    filter: none;
    opacity: 1;
  }
}

/* Quien pidió menos movimiento no ve el cambio de color. */
@media (prefers-reduced-motion: reduce) {
  .sin-foto__simbolo { transition: none; }
}

/* =============================================================================
   Sesión 11 · parte 4 — Estadísticas de una ficha (§2.8)
   Mobile primero: sin `@media` es el celular.
   ============================================================================= */

.stats {
  margin-top: var(--e4);
  padding: var(--e4);
  background: var(--muted);
  border-radius: var(--radio);
}

.stats__titulo {
  display: flex;
  align-items: center;
  gap: var(--e2);
  margin: 0 0 var(--e3);
  font-size: .8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-soft);
}

.stats__vacio { margin: 0; font-size: .88rem; color: var(--text-soft); }

/* Dos columnas a 360 px: cuatro cifras en fila quedarían de tres píxeles. */
.stats__cifras {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e3);
  margin: 0;
  padding: 0;
  list-style: none;
}

.stats__cifra { display: grid; gap: .1rem; }
.stats__numero { font-size: 1.5rem; line-height: 1.1; color: var(--primary); }
.stats__rotulo { font-size: .76rem; line-height: 1.25; color: var(--text-soft); }

/* ─── La curva ─────────────────────────────────────────────────────────────── */

/* Treinta barras y nada más. Sin `<canvas>` y sin librería de gráficos: lo que
   hay que responder es «¿subió o bajó?», y para eso alcanza con la silueta. */
.stats__curva {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 64px;
  margin-top: var(--e4);
  padding-top: var(--e1);
  border-bottom: 1px solid var(--border);
}

.stats__barra {
  flex: 1 1 0;
  min-width: 0;
  border-radius: 2px 2px 0 0;
  background: var(--primary);
}

/* Once escalones en vez de una altura calculada: §0.2 no admite `style=` en el
   marcado, y en una franja de este ancho un décimo es más precisión de la que
   se puede ver. El día sin visitas deja una marca al ras, no un hueco: un hueco
   se lee como «acá falta un día» y no como «acá no vino nadie». */
.stats__barra--0  { height: 2px; background: var(--border); }
.stats__barra--1  { height: 10%; }
.stats__barra--2  { height: 20%; }
.stats__barra--3  { height: 30%; }
.stats__barra--4  { height: 40%; }
.stats__barra--5  { height: 50%; }
.stats__barra--6  { height: 60%; }
.stats__barra--7  { height: 70%; }
.stats__barra--8  { height: 80%; }
.stats__barra--9  { height: 90%; }
.stats__barra--10 { height: 100%; }

.stats__pie {
  display: flex;
  justify-content: space-between;
  gap: var(--e2);
  margin: var(--e1) 0 0;
  font-size: .72rem;
  color: var(--text-soft);
}

/* =============================================================================
   sm — 600 px
   ============================================================================= */

@media (min-width: 600px) {
  .stats__cifras { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stats__curva  { height: 84px; }
}

/* =============================================================================
   El mapa con el pin fijo (§6.6)

   Estaba en `paginas.css` y por eso el mapa de la ficha del panel no funcionaba:
   el panel carga `base`, `componentes` y `admin`, **no `paginas`**, así que el
   lienzo se quedaba en `height: 0` y el cartel «El mapa necesita JavaScript» no
   se ocultaba nunca. El JavaScript andaba; lo que faltaba eran estas reglas
   (22-09-2026). Acá lo ven los dos: el alta, que es pública, y el panel.

   El pin no es un marcador de Leaflet: es un elemento clavado en el centro que
   no captura el toque. El mapa se mueve por debajo.
   ============================================================================= */

.mapa-ajuste {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radio);
  overflow: hidden;
  background: var(--muted);
}

/* Sin JavaScript el lienzo no ocupa nada: lo que se ve es el cartel de abajo.
   `--vivo` lo pone `app.js` en el alta y `admin.js` en el panel. */
.mapa-ajuste__lienzo { height: 0; }
.mapa-ajuste--vivo .mapa-ajuste__lienzo { height: 240px; }

.mapa-ajuste__pin {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 500;
  /* La punta de la chincheta cae en el centro exacto, no su cuerpo. */
  transform: translate(-50%, -100%);
  color: #C0392B;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .35));
  pointer-events: none;
}
.mapa-ajuste--vivo .mapa-ajuste__pin { display: block; }

.mapa-ajuste__sin-js {
  margin: 0;
  padding: var(--e4);
  font-size: .88rem;
  color: var(--text-soft);
  text-align: center;
}
.mapa-ajuste--vivo .mapa-ajuste__sin-js { display: none; }

/* Leaflet dibuja su propio texto; que herede la tipografía del sitio. */
.leaflet-container { font-family: var(--fuente); font-size: .8rem; }

/* =============================================================================
   sm — 600 px
   ============================================================================= */

@media (min-width: 600px) {
  .mapa-ajuste--vivo .mapa-ajuste__lienzo { height: 300px; }
}

/* =============================================================================
   md — 900 px
   ============================================================================= */

@media (min-width: 900px) {
  .mapa-ajuste--vivo .mapa-ajuste__lienzo { height: 340px; }
}
