/* Wö Kàpi · componentes reutilizables
   1. Botón flotante de WhatsApp  (js/whatsapp.js)
   2. Grilla de Instagram         (js/instagram.js + api/instagram.js)
   3. Reseñas en carrusel         (js/resenas.js + api/resenas.js)
   Carga después de ajustes.css. Usa los tokens de :root de wo-kapi.webflow.css;
   los valores de respaldo son los mismos por si una página no los trae. */

/* ============================================================
   1. WhatsApp flotante
   48 px: los 44 pt de Apple y los 48 dp de Material. Habla el lenguaje
   de .cta del sitio (borde crema, radio de 10, sombra dura), no el de un
   círculo genérico. Glifo blanco sobre --green 5,3:1; relleno contra la
   crema 4,9:1; borde crema contra #2b2b2b 13,2:1. El verde #25D366 queda
   afuera: con glifo blanco da 1,98:1.
   Se esconde sin transición: con un fundido de 120 ms quedaba encima de
   texto en 24 de 501 cuadros al hacer scroll. Solo aparece con fundido.
   ============================================================ */
.wa-flotante {
  position: fixed;
  right: calc(16px + env(safe-area-inset-right, 0px));
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 900;                       /* debajo de la navbar (1000) y del salto al contenido (2000) */
  display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  background: var(--green, #5c7159);
  color: var(--light, #f8f9d8);
  border: 3px solid var(--light, #f8f9d8);
  border-radius: 10px;                /* el radio de .cta */
  box-shadow: 0 4px 0 var(--dark, #2b2b2b);           /* la sombra dura de .cta */
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 1; visibility: visible;
  transition: opacity .12s linear;    /* solo al aparecer */
}
.wa-flotante svg { width: 26px; height: 26px; display: block; }
.wa-flotante:hover { box-shadow: 0 6px 0 var(--dark, #2b2b2b); }
.wa-flotante:focus-visible { outline: 3px solid var(--black, #2b2b2b); outline-offset: 2px; }
.wa-flotante[data-oculto] { opacity: 0; visibility: hidden; pointer-events: none; transition: none; }
@media (prefers-reduced-motion: reduce) { .wa-flotante { transition: none; } }
@media (forced-colors: active) { .wa-flotante { border-color: ButtonText; } }
@media print { .wa-flotante { display: none; } }
/* WCAG 2.4.11, técnica C43: el foco de teclado no queda debajo de la barra
   fija de arriba (80 px) ni del botón flotante de abajo. La carta tiene el
   suyo en carta.css (html:has(> body.pagina-carta), que pesa más). */
html { scroll-padding-top: 96px; scroll-padding-bottom: 88px; }

/* ============================================================
   Bandas de reseñas e Instagram: crema, titular Recoleta en caja alta
   (en el HTML van en caja normal) y el contenedor del sitio.
   ============================================================ */
.ig, .resenas {
  background: var(--light, #f8f9d8);
  color: var(--black, #2b2b2b);
  /* Un enlace a #resenas no aterriza tapado por la barra: lo resuelve el
     scroll-padding-top de html (arriba). Un scroll-margin acá se sumaría. */
}
/* El aire vertical: si la sección es una .banda del sistema (el inicio desde el 1 de octubre),
   lo pone ajustes.css (--aire-banda, y --aire-seccion entre dos bandas crema seguidas); si no,
   el de acá. :where() deja la especificidad de .ig y .resenas. */
.ig:where(:not(.banda)) { padding: 104px 0; }
/* El aire de la banda de reseñas sale de la escala del sitio (sección 3). */
/* Dos bandas crema seguidas comparten el aire. */
.resenas + .ig,
.ig.ig--junta { padding-top: 0; }
/* La ola oscura del export (.fill-move-up) solo se ve si abajo hay crema. */
.fill-move-up:has(+ .resenas),
.fill-move-up:has(+ .ig) { background: var(--light, #f8f9d8); }

.ig__titulo, .resenas__titulo {
  margin: 0;
  color: var(--black, #2b2b2b);
  font-family: Recoletaalt Webfont, Georgia, serif;
  font-weight: 700;
  font-size: 48px;
  line-height: 1.1;
  text-transform: uppercase;
  text-wrap: balance;
}

/* Enlaces de texto de las dos bandas: 18px, verde (4,93:1 sobre crema), 44px de toque. */
.ig__seguir,
.resenas__acciones a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--green, #5c7159);
  font-size: 18px;
  font-weight: 700;
  line-height: 1.3;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
}
.ig__seguir:hover,
.resenas__acciones a:hover { color: var(--orange, #93542a); }

@media (max-width: 991px) {
  .ig:where(:not(.banda)) { padding: 88px 0; }
  .ig__titulo, .resenas__titulo { font-size: 40px; }
}
@media (max-width: 767px) {
  .ig:where(:not(.banda)) { padding: 72px 0; }
  .ig__titulo, .resenas__titulo { font-size: 32px; }
}

/* ============================================================
   2. Grilla de Instagram
   Base: 3 x 2 con 20 px desde 768 y 2 x 3 con 8 px debajo.
   .ig--fila: 6 en fila desde 992 (home, 16 px de gap: spec del home).
   En contacto (.contacto .ig--fila): 12 px desde 992 y 3 x 2 con 6 px
   debajo, para que la banda no crezca en celular (spec de reseñas e
   Instagram, 3.4). Sin bordes, radios, pies de foto, contadores ni capas
   sobre la foto: el .tile del sitio lleva borde de 6 y radio de 10, y acá
   no se hereda.
   ============================================================ */
.ig__cabeza {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 32px;
  margin-bottom: 36px;
}
.ig__grilla {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ig__grilla li { margin: 0; padding: 0; }
.ig__foto {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  /* mientras carga la foto: tostado al 30 % (la marca no tiene lino) */
  background: rgba(196, 154, 108, .3);
}
.ig__foto img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  transition: opacity .2s ease;
}
.ig__foto:hover img { opacity: .86; }
.ig__foto:focus-visible { outline: 3px solid var(--black, #2b2b2b); outline-offset: 3px; }

@media (min-width: 992px) {
  .ig--fila .ig__grilla { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 16px; }
  .contacto .ig--fila .ig__grilla { gap: 12px; }
}
@media (max-width: 767px) {
  .ig__cabeza { margin-bottom: 24px; }
  .ig__grilla { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
}
@media (max-width: 991px) {
  .contacto .ig--fila .ig__grilla { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
  .ig__foto img { transition: none; }
}

/* ============================================================
   3. Reseñas: carrusel de tarjetas verdes
   Pedido de Fede (25 set 2026). Todas las tarjetas son iguales.
   - Tarjeta: fondo --green y texto --light, 4,93:1 (AA). Todo el texto de
     la tarjeta va en --light entero: con cualquier transparencia baja de 4,5.
     Radio 8, sin sombra ni borde.
   - Pista horizontal nativa con scroll-snap. Arranca alineada con el titular
     y se estira hasta el borde de la ventana (--resenas-margen) para que la
     tarjeta siguiente asome: dos enteras y un tercio a 1440, una y media en
     tableta, 86 % del contenido en celular. Gap 24. El alto es parejo porque
     las tarjetas son ítems flex de la misma fila.
   - Sin JS es una franja que se desliza, con su barra. Con JS (la sección
     lleva data-carrusel) la barra se va y aparecen los botones, solo si hay
     tarjetas fuera de la vista. Si entran todas (pantallas muy anchas),
     resenas.js marca data-cabe: sin botones y sin relleno final, así la fila
     no se desliza hacia la nada.
   - Estructura (patrón APG): .resenas__carrusel es la región del carrusel y
     encierra la pista y los botones; los enlaces a Google van afuera.
   - Escala: banda 120 / 96 / 72 (escritorio, tableta, celular); titular a
     pista 40; pista a botones y enlaces 32 (28 en celular). En el inicio la
     sección es una .banda del sistema y el aire lo pone ajustes.css; el
     título, la cita, la firma y las flechas del inicio están en home.css.
   ============================================================ */
.resenas {
  --resenas-y: 120px;
  --resenas-gap: 24px;
  /* Del borde del contenido al de la ventana. Esto es el respaldo sin JS
     (main-container: 1300 de ancho y 24 de relleno); resenas.js lo mide. */
  --resenas-margen: max(24px, calc((100vw - 1300px) / 2 + 24px));
  --resena-ancho: clamp(480px, calc((100vw - var(--resenas-margen) - 2 * var(--resenas-gap)) / 2.33), 560px);
  /* --resena-ajustada: resenas.js la pone cuando a las tarjetas les faltan
     40 px o menos para entrar todas; si no, manda --resena-ancho. */
  --resena-relleno: 40px;
  /* Si 100vw cuenta la barra de scroll (Windows), la pista pasaría el borde
     de la ventana unos píxeles: se recorta acá y no hay scroll horizontal. */
  overflow-x: hidden;
  overflow-x: clip;
}
.resenas:where(:not(.banda)) { padding-top: var(--resenas-y); padding-bottom: var(--resenas-y); }
.resenas__titulo { margin-bottom: 40px; max-width: 22ch; }

/* ---- Pista ------------------------------------------------------------- */
.resenas__pista {
  display: flex;
  gap: var(--resenas-gap);
  /* 8 px arriba y abajo para el anillo de foco, sin sumar aire visible. */
  margin: -8px calc(-1 * var(--resenas-margen));
  padding: 8px var(--resenas-margen);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--resenas-margen);
}
.resenas__pista[hidden] { display: none; }
/* Todas las tarjetas a la vista: sin relleno final no queda nada que
   deslizar. resenas.js lo decide; sin JS, lo mismo en CSS para dos
   tarjetas desde 1200 y tres desde 2252 (560 + 24 + 560 + 24 + 560 más los
   márgenes). */
.resenas[data-cabe] .resenas__pista { padding-inline-end: 0; }
@media (min-width: 1200px) {
  .resenas__pista:not(:has(> :nth-child(3))) { padding-inline-end: 0; }
}
@media (min-width: 2252px) {
  .resenas__pista:not(:has(> :nth-child(4))) { padding-inline-end: 0; }
}
.resenas[data-carrusel] .resenas__pista { scrollbar-width: none; }
.resenas[data-carrusel] .resenas__pista::-webkit-scrollbar { display: none; }
.resenas__pista:focus { outline: none; }
.resenas__pista:focus-visible { outline: 3px solid var(--black, #2b2b2b); outline-offset: -3px; }

/* ---- Tarjeta ----------------------------------------------------------- */
.resena {
  flex: 0 0 var(--resena-ajustada, var(--resena-ancho));
  display: flex;
  min-width: 0;
  margin: 0;
  padding: var(--resena-relleno);
  border-radius: 8px;
  background: var(--green, #5c7159);
  color: var(--light, #f8f9d8);
  scroll-snap-align: start;
}
.resena > figure {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}
/* La comilla de apertura, grande y en Recoleta. Es marca, no texto: el
   lector de pantalla no la lee. Las reseñas de Google llevan estrellas. */
.resena > figure::before {
  content: "\201C";
  content: "\201C" / "";
  display: block;
  height: 40px;
  margin: 0 0 20px;
  font-family: Recoletaalt Webfont, Georgia, serif;
  font-weight: 700;
  font-size: 96px;
  line-height: 1;
  color: var(--light, #f8f9d8);
}
.resena--google > figure::before { content: none; }
/* wo-kapi.webflow.css pinta todo <blockquote> de negro con una textura y
   40 px de relleno: acá se limpia completo. */
.resena__cita {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-family: Recoletaalt Webfont, Georgia, serif;
  font-weight: 700;
  font-size: 22px;
  line-height: 1.35;
  max-width: none;
  text-wrap: pretty;
}
.resena__cita p { margin: 0; }
/* La firma baja al pie de la tarjeta: en una fila las firmas quedan a la
   misma altura. webflow.css centra los figcaption. */
.resena__autor,
.resena__firma {
  margin: auto 0 0;
  padding-top: 28px;
  color: inherit;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  text-align: left;
  text-transform: none;
}
.resena a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.resena a:hover { text-decoration-thickness: 2px; }
.resena a:focus-visible { outline: 3px solid var(--light, #f8f9d8); outline-offset: 2px; }

/* ---- Reseñas vivas de Google -------------------------------------------
   La política de Places pide la atribución «Google Maps» junto a las
   reseñas (va al final del aviso, bajo los enlaces), foto, nombre y enlace
   del autor, fecha, enlace de cada reseña a Google Maps y un aviso del
   orden. La nota y la cantidad van dentro del enlace a todas las reseñas.
   Nada de esto se guarda: llega en cada visita. */
.resena__estrellas {
  margin: 0 0 20px;
  color: var(--light, #f8f9d8);
  font-size: 22px;
  letter-spacing: 4px;
  line-height: 1;
}
/* Más de 8 renglones se cortan; el enlace de la tarjeta pasa a decir
   «Leé la reseña completa en Google Maps» (resenas.js). */
.resena--google .resena__cita p {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 8;
  line-clamp: 8;
  overflow: hidden;
}
.resena__firma { display: flex; flex-direction: column; gap: 8px; font-weight: 400; }
.resena__quien { display: flex; align-items: center; gap: 12px; }
.resena__avatar {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  max-width: none;
  border-radius: 8px;
  object-fit: cover;
  background: rgba(196, 154, 108, .3);
}
.resena__firma .resena__autor { display: block; margin: 0; padding: 0; font-weight: 700; }
/* 44 px de toque sin mover la firma: el relleno sale con margen negativo. */
.resena__autor a { display: inline-block; padding: 12px 0; margin: -12px 0; }
.resena__fecha { display: block; margin-top: 2px; font-size: 16px; line-height: 1.3; }
.resena__detalle { margin: 0; font-size: 16px; line-height: 1.5; }
.resena__detalle a { display: inline-flex; align-items: center; min-height: 44px; }

/* El logo oficial GoogleMaps_Logo_DarkGray (#1F1F1F, 15,33:1 sobre crema),
   sin modificar, a 18 px de alto, al final de la oración del aviso («…según
   [Google Maps]»), con el aire que pide Google: 10 px a los lados y arriba,
   5 abajo. */
.gmp-logo {
  display: inline-block;
  width: auto;
  height: 18px;
  max-width: none;
  margin: 10px 10px 5px;
  vertical-align: middle;
}
/* Si el logo no carga, la atribución en texto con el estilo exigido. */
.gmp-atribucion {
  margin-left: 6px;
  font-family: Roboto, "Helvetica Neue", Arial, sans-serif;
  font-style: normal;
  font-weight: 400;
  font-size: 16px;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  color: #5e5e5e;
}
/* Debajo de los enlaces: de dónde salen las reseñas, con la atribución. */
.resenas__aviso {
  margin: 24px 0 0;
  max-width: 64ch;
  color: rgba(43, 43, 43, .85);   /* carbón al 85 %: 8,3:1 sobre crema */
  font-size: 16px;
  line-height: 1.5;
}
.resenas__aviso p { margin: 0; }

/* ---- Botones y enlaces bajo la pista -----------------------------------
   Los botones están dentro de la región del carrusel y los enlaces afuera,
   pero desde 768 se ven en la misma fila: los botones a la derecha, 32 px
   bajo las tarjetas (la pista tiene 8 de relleno y -8 de margen), y los
   enlaces le dejan ese lugar libre (data-con-controles, resenas.js). */
.resenas__carrusel { position: relative; }
.resenas__controles {
  position: absolute;
  top: calc(100% + 24px);
  right: 0;
  display: flex;
  gap: 12px;
}
.resenas__controles[hidden] { display: none; }
.resenas__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 40px;
  min-height: 48px;
  margin: 32px 0 0;
}
.resenas[data-con-controles] .resenas__acciones { padding-right: 140px; }
/* Borde y flecha --green sobre crema: 4,93:1. */
.resenas__boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 2px solid var(--green, #5c7159);
  border-radius: 6px;
  background: transparent;
  color: var(--green, #5c7159);
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.resenas__boton svg { display: block; width: 24px; height: 24px; }
.resenas__boton:hover { background: var(--green, #5c7159); color: var(--light, #f8f9d8); }
.resenas__boton:focus-visible { outline: 3px solid var(--black, #2b2b2b); outline-offset: 3px; }
/* En el extremo: aria-disabled (no disabled) para que el foco no se pierda. */
.resenas__boton[aria-disabled="true"],
.resenas__boton[aria-disabled="true"]:hover {
  border-color: rgba(92, 113, 89, .35);
  background: transparent;
  color: rgba(92, 113, 89, .45);
  cursor: default;
}

/* Tableta y escritorio chico: una tarjeta y media. */
@media (max-width: 1199px) {
  .resenas {
    --resena-ancho: min(560px, calc((100vw - var(--resenas-margen) - var(--resenas-gap)) / 1.45));
    --resena-relleno: 36px;
  }
}
@media (max-width: 991px) {
  .resenas { --resenas-y: 96px; }
}
/* Celular: 86 % del contenido, así asoma la siguiente; botones arriba de
   los enlaces, debajo de la pista. */
@media (max-width: 767px) {
  .resenas {
    --resenas-y: 72px;
    --resenas-margen: 16px;
    /* 86 % del contenido, en vw para que no cambie con el relleno final. */
    --resena-ancho: calc((100vw - 2 * var(--resenas-margen)) * .86);
    --resena-relleno: 32px;
  }
  .resena > figure::before { height: 34px; margin-bottom: 16px; font-size: 80px; }
  .resena__cita { font-size: 19px; line-height: 1.4; }
  .resena__estrellas { margin-bottom: 16px; }
  .resena__autor,
  .resena__firma { padding-top: 24px; }
  /* Botones debajo de la pista, a la izquierda, y los enlaces debajo. */
  .resenas__controles { position: static; margin-top: 28px; }
  .resenas__acciones { flex-direction: column; align-items: flex-start; gap: 4px; min-height: 0; margin-top: 28px; }
  .resenas[data-con-controles] .resenas__acciones { padding-right: 0; margin-top: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .resenas__boton { transition: none; }
}
@media (forced-colors: active) {
  .resena { border: 1px solid CanvasText; }
  .resenas__boton[aria-disabled="true"] { border-color: GrayText; color: GrayText; }
}
