/* MOLDE DE LANDING — hoja de estilos.

   Sale de `demos/mar-del-plata/latercera-v2`, que a su vez es el sistema de
   `edison-lawn-tenis` (CSS + un solo IntersectionObserver, cero librerías) traducido a
   fondo oscuro. El reproductor de video con audio viene de `forzaclub`, y la banda con la
   foto casi clavada, de `Plantillas/panaderia-san-benedetto`.

   ── LO ÚNICO QUE SE TOCA POR CLIENTE ES LA PIEL ──
   La piel son los dos `@font-face` de acá abajo y el bloque `:root`. Todo lo demás del
   archivo está escrito contra esas variables y no hay que abrirlo. Si aparece la
   tentación de tocar una regla de más abajo para un cliente, casi siempre lo que falta es
   una variable nueva en `:root`.

   ── EL MOLDE ES DE FONDO OSCURO ──
   Esto es un techo conocido, no un descuido: los velos, los bordes y los textos apagados
   se calculan con `--tinta-rgb` y `--crema-rgb`, así que una piel clara se logra dando
   vuelta esos dos pares (tinta = el papel, crema = la tinta del texto). Anda, pero hay
   que mirar las capturas: las sombras siguen siendo negras y algunos velos quedan
   pesados. Si el negocio pide sí o sí una página clara y luminosa, el preset `astra` o
   `gastro` llegan más rápido que forzar este.

   ── POR QUÉ HAY VARIABLES `-rgb` ──
   Los velos, los bordes translúcidos y los brillos necesitan el color con alfa. Como
   `rgba()` no acepta un hex de una variable, cada color que se usa con transparencia
   viaja además en su versión "10, 14, 10". Van juntas y con el mismo valor: si se cambia
   `--tinta` hay que cambiar `--tinta-rgb`. */

/* ── Tipografías, servidas desde el proyecto ──
   Nunca desde Google Fonts: un <link> a un dominio ajeno son dos viajes encadenados
   —primero baja el CSS, y recién ahí empieza a bajar la fuente—. Los .woff2 van en
   `assets/fonts/` ya subseteados al alfabeto latino, y precargados desde el <head>.

   La DISPLAY se elige midiéndola contra el logo del cliente, que es el trabajo que no se
   puede automatizar. Si viene en un solo grosor (Anton, por ejemplo), los títulos NO
   llevan `font-weight: 700`: pedírselo hace que el navegador la engorde por su cuenta y
   la letra sale sucia, con los trazos embarrados. Por eso el peso de los títulos está
   fijado en 400 más abajo y se sube acá solo si la fuente elegida trae ese grosor de
   verdad.

   La manuscrita de guiño es opcional y la trae el preset `gastro`: acá no va, salvo que
   el logo del cliente tenga algo cursivo. Meterla porque queda linda es inventarle a la
   marca algo que no tiene. */
@font-face {
  font-family: 'Jost'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('assets/fonts/jost-600.woff2?v=1') format('woff2');
}
@font-face {
  font-family: 'Switzer'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('assets/fonts/switzer-400.woff2?v=1') format('woff2');
}
@font-face {
  font-family: 'Switzer'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('assets/fonts/switzer-500.woff2?v=1') format('woff2');
}
@font-face {
  font-family: 'Switzer'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('assets/fonts/switzer-600.woff2?v=1') format('woff2');
}
@font-face {
  font-family: 'Switzer'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('assets/fonts/switzer-700.woff2?v=1') format('woff2');
}

/* ── LA PIEL ──
   Los colores salen del logo del cliente (`armar.mjs preparar` los extrae y calcula el
   contraste de cada uno, pero no elige: elige el agente). Dos reglas que no se negocian:

   1. `--crema-soft` sobre `--tinta` tiene que dar 4,5:1 o más. Es el gris de todas las
      bajadas, o sea la mitad del texto de la página.
   2. El verde de WhatsApp (`--wa`) es SOLO de los botones que abren un chat. Si el acento
      del cliente también es verde, hay que separarlos bien —o correr el acento a otro
      lado—: si se mezclan, se deja de saber qué abre el WhatsApp. */
:root {
  --tinta: #F4F8F7;             /* el fondo base */
  --tinta-rgb: 244, 248, 247;     /* el mismo, para los velos y las sombras */
  --tinta-alt: #E6EFED;     /* la banda alterna: secciones con .alt */
  --panel: #FFFFFF;             /* tarjetas y bloques sobre cualquiera de los dos fondos */
  --crema: #11302C;             /* el texto */
  --crema-rgb: 17, 48, 44;     /* el mismo, para bordes y textos apagados */
  --crema-soft: #456260;   /* las bajadas. Contraste ≥ 4,5:1 sobre --tinta */
  --acento: #27AFA1;           /* el color de la marca: superficies y bandas */
  --acento-rgb: 39, 175, 161;
  --acento-hi: #0E7A70;     /* la versión clara: texto y detalles chicos sobre oscuro */
  --acento-hi-rgb: 14, 122, 112;
  --acento-2: #27AFA1;
  /* El color del texto que va ENCIMA de --acento-2 (la tira que se desplaza). No se deduce
     de la piel: --acento-2 suele ser un color claro y vistoso, así que el texto de la
     página no le sirve. Si la tira queda ilegible, es esta variable. */
  --acento-2-ink: #0B2A26;       /* el segundo acento, el que da el brillo */
  --acento-2-rgb: 39, 175, 161;
  --acento-3: #BEE6E0;       /* el terciario: links y detalles */
  --acento-3-hi: #DCF1EE;
  --wa: #25D366;                  /* el verde de WhatsApp: se reconoce antes de leer el botón */
  --wa-rgb: 37, 211, 102;
  --wa-ink: #04220F;           /* el texto adentro del botón de WhatsApp */
  --star: #E0A32A;               /* las estrellas de las opiniones */
  --display: 'Jost', 'Avenir Next', 'Century Gothic', system-ui, sans-serif;
  /* El peso con el que se dibujan los títulos. Va acá porque depende de la fuente elegida:
     una que viene en un solo grosor (Anton) tiene que quedarse en 400 —pedirle 700 hace que
     el navegador la engorde solo y la letra sale sucia—, y una variable puede ir a 600 o 700
     de verdad. */
  --display-peso: 600;
  /* El velo del hero y el color del texto que va encima. En una piel oscura repiten
     `--tinta-rgb` y `--crema`; en una clara van oscuro y blanco (ver el comentario del
     bloque .hero). */
  /* Cuánto aire llevan las letras de los títulos. Sale de la fuente elegida: una
     condensada se apretuja sola y no quiere nada, y una geométrica ancha —las de los
     logotipos en versalitas— necesita aire o se ve amontonada. */
  --display-tracking: .005em;
  /* El tope del titular del hero. Va acá porque el ancho de una fuente decide cuánto entra
     en un renglón: la misma frase que en una condensada entra en dos líneas, en una
     geométrica se parte en tres y rompe el bloque. */
  --h1-max: 5.4rem;
  --hero-velo: 10, 24, 23;
  --hero-tinta: #FFFFFF;
  --body: 'Switzer', system-ui, -apple-system, sans-serif;
  --maxw: 1140px;
  --radius: 14px;
  --ease: cubic-bezier(.22, 1, .36, 1);
  /* De qué color es la sombra y cuánta fuerza tiene. En una piel OSCURA la sombra es negra
     y a fondo (0,0,0 y 1); en una CLARA tiene que ser el marrón del papel y a un tercio, o
     queda un manchón sucio alrededor de cada tarjeta. Lo mismo el brillo de los botones:
     sobre fondo oscuro suma luz, sobre fondo claro resta. Por eso no son colores fijos. */
  /* La palabra más larga del h1 y el ancho medio de una mayúscula en la display elegida
     (Anton ~.42, Oswald ~.46, Alfa Slab ~.60, Archivo ~.62). Con los dos, el h1 de celular
     nunca se sale de la pantalla, sea cual sea el nombre del negocio. */
  /* Cuánto acento se lava sobre la foto del hero. Sube el color de marca, pero si la foto ya
     tiene ese color —una marca roja sobre una pila de ladrillos— hay que bajarlo o queda todo
     del mismo tono. Y el filete bajo el titular: va en 0 salvo que la marca lo tenga en su
     propio logotipo, como El Jardín. */
  --hero-lavado: .10;
  --h1-filete: 0;
  --h1-l2: 1em;
  --h1-l2-track: inherit;
  /* Cómo se separa del fondo una ficha (la chapa de puntaje, las reseñas, los cuatro
     puntos). En piel OSCURA lo hace la sombra: un filete no se vería. En piel CLARA es al
     revés — la sombra deja una banda sucia debajo de cada tarjeta y lo que limpia es un
     filete de 1px, que es como se ven las de San Benedetto. Las FOTOS no entran acá: una
     foto levantada de la página con sombra queda bien en las dos pieles. */
  --ficha-borde: rgba(17, 48, 44, .12);
  --ficha-sombra: 0 1px 2px rgba(17, 48, 44, .05), 0 10px 30px rgba(17, 48, 44, .06);
  --h2-min: 2.2rem;
  --h2-max: 3.5rem;
  --faq-fuente: var(--display);
  --faq-peso: 600;
  --faq-caja: none;
  --h1-chars: 12;
  --h1-ancho: .5;
  --sombra-rgb: 17, 48, 44;
  --sombra-k: .28;
  --glow-k: .18;
  --shadow: 0 14px 34px rgba(var(--sombra-rgb), calc(.5 * var(--sombra-k)));
  /* Alto de la banda con la foto casi clavada, y cuánto se corre la foto respecto del
     scroll. La deriva NO es decorativa: con 0 la foto queda clavada del todo y en Safari
     se siente pegajosa, porque ahí el motion atado al scroll corre en el hilo principal y
     queda un frame atrás. Ese atraso solo se nota en algo que debería estar quieto. */
  --banda: 54vh;
  --deriva: .4;
  /* Los brillos: en vez de repetir el mismo box-shadow en cinco lugares, viven acá. */
  --glow-acento: 0 0 28px rgba(var(--acento-hi-rgb), calc(.38 * var(--glow-k)));
  --glow-acento-2: 0 0 26px rgba(var(--acento-2-rgb), calc(.42 * var(--glow-k)));
}


* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--tinta);
  color: var(--crema);
  font-family: var(--body);
  font-size: 16.5px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
/* El `height: auto` no es de adorno: los <img> llevan width y height como atributos para
 * reservar el espacio y no mover la página al cargar, y sin esto el alto del atributo se
 * respeta al pie de la letra mientras el ancho lo achica `max-width`. Resultado: la foto
 * estirada a lo alto. Las reglas que sí fijan un alto (el hero, el marquee) son más
 * específicas y siguen ganando. */
img, video { max-width: 100%; height: auto; display: block; }
a { color: var(--acento-3-hi); }
h1, h2, h3 {
  font-family: var(--display); font-weight: var(--display-peso); line-height: 1.08;
  letter-spacing: var(--display-tracking); text-transform: uppercase; margin: 0 0 .5em;
}
p { margin: 0 0 1em; }

.wrap { max-width: var(--maxw); margin-inline: auto; padding-inline: clamp(1.1rem, 4vw, 2rem); }
.section { padding-block: clamp(3.5rem, 9vw, 6.5rem); }
/* Va por DEBAJO del alto del header bajado (~60px): la sección entra apenas por detrás
   del header y del bloque anterior no asoma nada. El aire lo pone el padding propio de
   la sección, que ya mide más de 100px. Con el valor "correcto" (8rem, que era la regla
   vieja) lo que se ve al tocar un link del nav es una tira del bloque anterior. */
.section[id] { scroll-margin-top: 2.5rem; }
/* Fuera del flujo para no empujar la foto del hero: el header es fixed y no ocupa lugar
   propio, así que la foto llega hasta el borde de arriba. */
#top { position: absolute; top: 0; height: 1px; width: 1px; }

.title { font-size: clamp(var(--h2-min), 5.2vw, var(--h2-max)); margin-bottom: 1.5rem; }
.lead { font-size: clamp(1.02rem, 2vw, 1.15rem); color: var(--crema-soft); max-width: 60ch; }
.alt { background: var(--tinta-alt); }

/* ── Header ──
   Arriba de todo es invisible y flota sobre la foto del hero; al bajar toma el fondo
   tinta con desenfoque. El velo degradado del ::before garantiza que el blanco se lea
   sobre cualquiera de las cuatro fotos del pase. El disparador es un centinela de 1px,
   no el evento scroll, que corre en cada frame. */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  background: rgba(var(--tinta-rgb), 0);
  /* Arriba de todo el header flota sobre la foto del hero, así que su texto va del color
     del hero; al bajar, cuando toma fondo propio, pasa al color de la página. Con una piel
     clara esto es lo que evita que el nav quede en gris oscuro sobre una foto oscura. */
  color: var(--hero-tinta);
  border-bottom: 1px solid transparent;
  transition: background .35s ease, border-color .35s ease, box-shadow .35s ease;
}
/* La barra del header no se encajona en el ancho del texto: con los 1140px del contenido,
   en una pantalla grande el logo y el botón de WhatsApp quedan flotando cerca del medio y
   la navegación se apretuja. El nav es cromo, no texto que haya que leer en línea corta,
   así que se estira y usa los bordes de la pantalla. */
.site-header .wrap {
  max-width: min(1560px, 100%);
  padding-inline: clamp(1.1rem, 3vw, 2.6rem);
}

.site-header::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(var(--hero-velo), .8), rgba(var(--hero-velo), 0) 92%);
  transition: opacity .35s ease;
}
.site-header.scrolled {
  background: rgba(var(--tinta-rgb), .88);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom-color: rgba(var(--crema-rgb), .1);
  box-shadow: 0 6px 24px rgba(var(--sombra-rgb), calc(.4 * var(--sombra-k)));
  color: var(--crema);
}
.site-header.scrolled::before { opacity: 0; }

/* Con el panel del menú abierto el header seguía transparente y el logo quedaba flotando
   sobre la foto del hero. `:has` lo pinta sin tocar el JS: el panel ya lleva su clase. */
/* Y el color del texto también: arriba del hero el header escribe con --hero-tinta, que en
   una piel CLARA es blanco. Con el panel abierto el fondo pasa a ser claro, así que sin esto
   el nombre del negocio desaparece — se ve sólo abriendo el menú, nunca en una captura. */
.site-header:has(.site-nav.abierto) { background: var(--tinta); color: var(--crema); }
.site-header:has(.site-nav.abierto)::before { opacity: 0; }

/* El achique toca el layout (padding y tamaño del logo) en vez de escalar: un scale es
   solo visual, el logo seguiría ocupando sus 46px y la barra no bajaría. Se puede porque
   el header es fixed y el recálculo no sale de estos cinco elementos. */
.header-in {
  position: relative; display: flex; align-items: center; gap: .8rem;
  padding-block: .75rem; transition: padding-block .35s ease;
}
.site-header.scrolled .header-in { padding-block: .6rem; }
/* El ancho y el redondeo salen de la proporción del archivo, que la calcula `armar.mjs`:
 * un escudo va cuadrado y redondo, y un logotipo apaisado va a lo largo y sin recorte. Con
 * el 50% fijo, a un logotipo la elipse le come la primera y la última letra. */
.mark {
  width: 51px; height: 46px; border-radius: 50%; flex: none;
  /* Sin esto, un logo que no llega al umbral de 'apaisado' (1.4) entra en una caja
     cuadrada y se estira. Con contain nunca se deforma, sea cual sea su proporción. */
  object-fit: contain;
  transition: width .35s ease, height .35s ease;
}
.site-header.scrolled .mark { width: 44px; height: 40px; }

/* Un logo de tinta oscura desaparece sobre la foto del hero, que es justo la primera pantalla.
   Si el proyecto trae `assets/logo-hero.webp` —el mismo logo con el texto en claro— se usa ese
   mientras el header está encima del hero, y se vuelve al normal al bajar. El símbolo de color
   se deja como está: lo que hay que aclarar es el logotipo, no la marca entera.
   Sin ese archivo no cambia nada, así que las páginas que no lo tienen siguen igual.
   Va con el panel del menú abierto también: ahí el fondo ya es claro y el logo claro
   desaparecería (25/08/2026). */
.mark-hero { display: none; }
.site-header:not(.scrolled):not(.menu-abierto) .mark-hero { display: block; }
/* El :not(:only-of-type) es lo que evita que el header quede SIN logo arriba del hero:
   si el proyecto no trae logo-hero, el .mark-base es el único <img> del brand y no se
   esconde. Antes esta regla lo ocultaba igual y la primera pantalla salía sin marca. */
.site-header:not(.scrolled):not(.menu-abierto) .mark-base:not(:only-of-type) { display: none; }

.brand { display: flex; align-items: center; gap: .7rem; min-height: 44px; text-decoration: none; color: inherit; }
.brand span { display: flex; flex-direction: column; line-height: 1.15; }
.brand b { font-family: var(--display); font-size: 1.16rem; font-weight: var(--display-peso); letter-spacing: .01em; text-transform: uppercase; }
.brand small {
  font-size: .72rem; color: inherit; opacity: .85; letter-spacing: .04em;
  /* La bajada del header va SIEMPRE en una línea. Partida en dos renglones desalinea el
     logo y hace crecer el header justo donde menos lugar hay. */
  white-space: nowrap;
}

.site-nav { margin-left: auto; display: flex; align-items: center; gap: 1.5rem; }
.site-nav a { font-size: .88rem; font-weight: 500; color: inherit; text-decoration: none; transition: color .2s, opacity .2s; }
/* Ya bajado, el header tiene fondo propio y los links pueden respirar un poco apagados;
   arriba, sobre la foto, van a full o se pierden. */
.site-header.scrolled .site-nav a { opacity: .9; }
/* El hover era --acento-3-hi, casi blanco: con el header bajado (fondo claro) desaparecía.
   Sobre la foto va el verde agua de la marca; con fondo claro, la versión oscura. */
.site-nav a:hover { color: var(--acento); }
.site-header.scrolled .site-nav a:hover { color: var(--acento-hi); opacity: 1; }
.soc { display: flex; gap: .7rem; margin-left: -.4rem; }
/* La palabra solo acompaña al ícono en el panel del celular: en la barra de escritorio
   el ícono solo alcanza y "Instagram" escrito al lado compite con los links. */
.soc-txt { display: none; }
.soc a { display: flex; align-items: center; justify-content: center; min-width: 24px; min-height: 44px; color: inherit; }
.soc svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.header-in .btn-wa { margin-left: 1.4rem; padding: .55rem 1rem; font-size: .85rem; }

/* ── Menú hamburguesa (solo celular) ── */
.burger {
  display: none; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  background: 0; border: 0; cursor: pointer;
  /* 44×44 es el mínimo tocable, y acá importa más que en ningún otro lado: es el único
     control del header en el celular. El dibujo sigue siendo el mismo, lo que crece es
     la caja que registra el dedo. */
  min-width: 44px; min-height: 44px; padding: 0; margin-right: -10px;
}
.burger span {
  width: 22px; height: 2px; border-radius: 2px; background: currentColor;
  transition: transform .3s var(--ease), opacity .2s ease;
}
/* Las tres barritas se cruzan en X: la del medio se apaga y las otras dos giran. */
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 899px) {
  /* El auto va acá y no en .site-nav: abajo de 900px el nav es `position: absolute`, así
     que no ocupa lugar en la fila y su margin-left no empuja nada. Sin esto la hamburguesa
     queda pegada al nombre del negocio en vez de irse al borde derecho. */
  .burger { display: flex; margin-left: auto; }
  .soc-txt { display: inline; }
  /* Panel sólido y no translúcido: arriba de todo el header es transparente sobre la foto
     del hero, y con fondo semitransparente el menú quedaría ilegible sobre la foto. */
  .site-nav {
    position: absolute; top: 100%; left: 0; right: 0; margin: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--panel); padding: .4rem 1.2rem 1.1rem;
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: 0 20px 40px rgba(var(--sombra-rgb), calc(.5 * var(--sombra-k)));
    /* El visibility no es decorativo: sin él el panel sigue en el flujo de foco y se
       tabula hacia links que están fuera de pantalla. */
    transform: translateY(-115%); visibility: hidden;
    transition: transform .4s var(--ease), visibility .4s;
  }
  .site-nav.abierto { transform: translateY(0); visibility: visible; }
  .site-nav a {
    display: block; color: var(--crema); font-size: 1.02rem; font-weight: 500;
    padding-block: .85rem; border-bottom: 1px solid rgba(var(--crema-rgb), .1);
  }
  /* El SVG va como bloque y el conjunto con line-height 1: un SVG inline se apoya en la
     línea base del texto y arrastra el hueco del descender, que lo dejaba un par de
     píxeles más arriba que la palabra. */
  .site-nav .soc { margin: .9rem 0 0; }
  .site-nav .soc a {
    display: inline-flex; align-items: center; gap: .55rem;
    /* --acento-hi y no --acento-3-hi: el panel del menú es `--panel`, que en una piel
       clara es BLANCO, y el tinte 3-hi es el más pálido de la paleta —sobre blanco
       queda en 1,2:1 y la palabra "Instagram" directamente no se ve—. `--acento-hi`
       es, por definición, el que contrasta contra el panel de cada piel. */
    color: var(--acento-hi); font-weight: 600; font-size: .98rem; line-height: 1;
    border-bottom: 0; padding-block: 0;
  }
  .site-nav .soc svg { display: block; width: 22px; height: 22px; }
  .header-in .btn-wa { margin-left: .6rem; margin-right: .2rem; order: 3; }
  /* Sin la bajada el nombre entra en un renglón; con ella el header del celular se
     partía en cuatro líneas y se comía media pantalla del hero. */
  .brand small { display: none; }
  .brand b { font-size: .98rem; }
  .mark, .site-header.scrolled .mark { width: 42px; height: 38px; }
}
@media (max-width: 560px) {
  /* En el celular el del header se saca: era un segundo círculo verde igual al flotante,
     en la misma pantalla. El flotante alcanza y queda donde llega el pulgar. */
  .header-in .btn-wa { display: none; }
}

/* ── Botones ──
   El verde de WhatsApp significa una sola cosa en toda la página: "esto te abre un
   chat". Ningún otro elemento lo usa. */
.btn-wa {
  display: inline-flex; align-items: center; gap: .55rem;
  background: var(--wa); color: var(--wa-ink);
  font-weight: 600; text-decoration: none;
  padding: .85rem 1.5rem; border-radius: 999px;
  position: relative; overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease;
  box-shadow: 0 6px 18px rgba(var(--wa-rgb), calc(.3 * var(--sombra-k))), var(--glow-acento);
  cursor: pointer;
}
.btn-wa svg { fill: var(--wa-ink); flex: none; }
@media (hover: hover) {
  .btn-wa:hover { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(var(--wa-rgb), calc(.5 * var(--sombra-k))), 0 0 40px rgba(var(--acento-hi-rgb), calc(.5 * var(--glow-k))); }
}
.btn-wa::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.42) 50%, transparent 60%);
  transform: translateX(-120%);
}
@media (hover: hover) { .btn-wa:hover::after { transition: transform .6s ease; transform: translateX(120%); } }
.btn-wa--xl { padding: 1rem 1.9rem; font-size: 1.04rem; }
.btn-wa--xl::after { animation: shine 4.5s ease-in-out infinite; }
@keyframes shine { 0%, 72% { transform: translateX(-120%); } 88%, 100% { transform: translateX(120%); } }

.btn-ghost {
  display: inline-flex; align-items: center; gap: .5rem;
  color: var(--crema); font-weight: 600; text-decoration: none;
  padding: .95rem 1.6rem; border-radius: 999px;
  border: 1.5px solid rgba(var(--crema-rgb), .5);
  transition: background .2s ease, transform .2s ease, border-color .2s ease;
}
@media (hover: hover) { .btn-ghost:hover { background: rgba(var(--crema-rgb), .12); border-color: var(--crema); transform: translateY(-2px); } }
/* Los del hero van del color del hero y no del de la página: están sobre el velo oscuro,
   así que con una piel clara el color de texto normal los deja invisibles. */
.hero-cta .btn-ghost { color: var(--hero-tinta); border-color: rgba(255, 255, 255, .55); }
@media (hover: hover) { .hero-cta .btn-ghost:hover { background: rgba(255, 255, 255, .16); border-color: var(--hero-tinta); } }

/* FAB flotante: círculo, solo ícono */
.wa-float {
  position: fixed; right: 1.1rem; bottom: max(1.25rem, env(safe-area-inset-bottom));
  z-index: 70; width: 3.5rem; height: 3.5rem; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  background: var(--wa); color: var(--wa-ink);
  box-shadow: 0 8px 22px rgba(var(--wa-rgb), calc(.45 * var(--sombra-k))), var(--glow-acento);
  transition: transform .2s ease;
}
.wa-float svg { fill: var(--wa-ink); }
@media (hover: hover) { .wa-float:hover { transform: scale(1.07); } }
.wa-float::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  border: 2px solid var(--wa); animation: pulse 2.2s ease-out infinite;
}
@keyframes pulse { 0% { transform: scale(1); opacity: .8; } 100% { transform: scale(1.55); opacity: 0; } }

/* ── Hero: foto a pantalla completa con pase de cuatro ── */
/* El hero tiene su propio par de colores y NO usa el de la página. Esto no es un lujo: en
   una piel oscura el velo oscurece la foto y el texto claro se lee, pero en una piel clara
   ese mismo velo la BLANQUEA y la foto desaparece detrás de una lechada. La salida es la
   que usa cualquier web clara con hero de foto: velo oscuro y texto blanco arriba, resto de
   la página claro. Con una piel oscura, `--hero-velo` y `--hero-tinta` valen lo mismo que
   `--tinta-rgb` y `--crema`, y no cambia nada. */
.hero {
  position: relative; min-height: 100svh;
  display: flex; align-items: flex-end;
  color: var(--hero-tinta); overflow: clip;
}
.hero-media { position: absolute; inset: 0; }
/* Las cuatro fotos apiladas; solo la que tiene .activa está visible. El cruce es un
   fundido largo para que no se sienta un cambio de diapositiva. */
.hero-media picture {
  position: absolute; inset: 0; display: block;
  opacity: 0; transition: opacity 1.2s ease;
}
.hero-media picture.activa { opacity: 1; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
/* Las fotos son 4:3 y el celular las recorta a lo alto. En la del plantel la gente está
   en la mitad de abajo, así que el encuadre se corre para no cortarles la cabeza. */
@media (max-width: 700px) {
  .hero-media picture:nth-child(2) img { object-position: center 62%; }
}
.hero::after {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(80% 55% at 22% 78%, rgba(var(--acento-rgb), var(--hero-lavado)), transparent 60%),
    linear-gradient(90deg, rgba(var(--hero-velo), .78) 0%, rgba(var(--hero-velo), .4) 58%, rgba(var(--hero-velo), .18) 100%),
    linear-gradient(200deg, rgba(var(--hero-velo), .3) 0%, rgba(var(--hero-velo), .52) 52%, rgba(var(--hero-velo), .9) 100%);
}
.hero-in { position: relative; z-index: 2; width: 100%; padding-block: clamp(3rem, 8vw, 5rem); }
.hero h1 {
  font-size: clamp(3.1rem, 9.2vw, var(--h1-max)); font-weight: var(--display-peso);
  line-height: .96; margin-bottom: .38em; color: var(--hero-tinta);
  text-shadow: 0 4px 30px rgba(0, 0, 0, .55);
}
/* El filete del logotipo, repetido DENTRO del titular, entre la marca y su bajada: es el
   gesto propio del cartel de El Jardín y de cualquier marca armada así. Va con --h1-l2, que
   achica y espacia la segunda línea: juntos reproducen el lockup del logotipo —la marca
   grande, el filete, la bajada chica— en vez de dos renglones del mismo tamaño.

   El alto y los márgenes se atan a --h1-filete con min() porque con el filete en 0 la barra
   no se veía pero el bloque SEGUÍA ocupando 7px + .6em: en un titular de 6.4rem eso son casi
   70px de aire metidos entre las dos líneas del nombre, en toda página que no use filete —o
   sea casi todas— y sin que nada avise (25/08/2026, Cuniberti). Con min() un filete real
   —siempre de decenas de px— da los mismos valores de antes, así que las páginas ya
   publicadas se reconstruyen idénticas. */
.hero h1 .ln:first-child::after {
  content: ''; display: block; background: var(--acento-2);
  width: var(--h1-filete); height: min(7px, var(--h1-filete));
  margin-block: min(.34em, var(--h1-filete)) min(.26em, var(--h1-filete));
}
.hero h1 .ln:last-child { font-size: var(--h1-l2); letter-spacing: var(--h1-l2-track); }
/* Sin opacidad: sobre una foto, bajarle aunque sea un 10% al blanco lo mete adentro del
   fondo. El contraste lo da el velo, no la transparencia del texto. */
.hero .lead { color: var(--hero-tinta); max-width: 48ch; font-size: clamp(1.05rem, 2.2vw, 1.2rem); }
.hero-cred {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.1rem;
  margin: 1.3rem 0 1.7rem; font-size: .92rem; font-weight: 500; color: var(--hero-tinta);
}
.hero-cred .stars { color: var(--star); letter-spacing: .12em; font-size: 1rem; }
.hero-cred .sep { opacity: .4; }
.hero-cta { display: flex; flex-wrap: wrap; gap: .9rem; align-items: center; }
/* El botón mide 30px aunque el punto sea de 9: abajo de 24px el dedo no acierta y
   Lighthouse lo marca como target chico. El punto lo dibuja el ::after. */
.hero-dots { display: flex; gap: .15rem; margin-top: calc(1.7rem - 7px); margin-bottom: -7px; margin-left: -.6rem; }
.hero-dots button {
  /* 34×44 en vez de 30×30: el punto que se ve mide 9px, lo que crece es la zona tocable. */
  width: 34px; height: 44px; padding: 0; border: 0; background: none;
  cursor: pointer; display: grid; place-items: center;
}
.hero-dots button::after {
  content: ''; width: 9px; height: 9px; border-radius: 999px;
  /* Sobre la foto del hero manda --hero-tinta, no --crema: en una piel clara --crema es el
     negro del texto, así que el punto quedaba negro sobre una foto oscura y no se veía. */
  background: color-mix(in srgb, var(--hero-tinta) 45%, transparent);
  transition: background .3s ease, width .3s ease;
}
.hero-dots button[aria-current="true"]::after { background: var(--acento-2); width: 24px; box-shadow: var(--glow-acento-2); }

/* ── Motion del hero ──
   El titular sube desde atrás del renglón: cada línea va en una cajita con el desborde
   oculto. El padding + margin negativo le da aire a las colas de las letras para que el
   recorte no se las coma, sin tocar el interlineado. */
.ln { display: block; overflow: hidden; padding-bottom: .09em; margin-bottom: -.09em; padding-top: .16em; margin-top: -.16em; }
@keyframes sube { from { transform: translateY(112%); } to { transform: none; } }
@keyframes entra { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.js-anim .hero .ln > span { display: block; animation: sube .8s var(--ease) both; }
.js-anim .hero .ln:nth-of-type(2) > span { animation-delay: .12s; }
.js-anim .hero .lead { animation: entra .55s var(--ease) .3s both; }
.js-anim .hero-cred { animation: entra .55s var(--ease) .42s both; }
.js-anim .hero-cta { animation: entra .55s var(--ease) .54s both; }
.js-anim .hero-dots { animation: entra .55s var(--ease) .66s both; }

/* Parallax y salida del hero atados al scroll, que corren fuera del hilo principal.
   El @supports no es opcional: sin él, un navegador que no entiende la línea de tiempo
   de scroll ejecuta la animación una vez al cargar, que es lo contrario de lo buscado. */
@supports (animation-timeline: scroll()) {
  @keyframes parallax { to { transform: translateY(7%); } }
  @keyframes heroSale { to { opacity: 0; transform: translateY(-40px); } }
  .js-anim .hero-media {
    animation: parallax linear both;
    animation-timeline: scroll(); animation-range: 0 100vh;
  }
  .js-anim .hero-in {
    animation: heroSale linear both;
    animation-timeline: scroll(); animation-range: 25vh 88vh;
  }
}

/* ── Venta: lo primero que se ve al bajar del hero ──
   El texto pesa más que la foto (1.15 contra 1) porque acá lo que vende son los cuatro
   puntos concretos del negocio. La foto acompaña. */
.venta-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(1.8rem, 5vw, 4rem); align-items: center; }
.venta-ph img {
  border-radius: var(--radius); width: 100%;
  height: clamp(340px, 42vw, 520px); object-fit: cover;
  box-shadow: var(--shadow);
}
.features {
  list-style: none; margin: 2rem 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: .9rem;
}
.features li {
  display: flex; align-items: center; gap: .8rem;
  background: var(--panel); border-radius: 12px; padding: .95rem 1.1rem;
  border: 1px solid var(--ficha-borde);
}
/* El ícono va en su propia chapita de color: sobre el panel oscuro un trazo suelto se
   pierde. Y son íconos dibujados, no emojis: el emoji lo dibuja cada sistema operativo a
   su manera y en pantalla grande se lee como un adorno pegado encima. */
.features svg {
  flex: none; width: 38px; height: 38px; padding: 8px; border-radius: 10px;
  background: rgba(var(--acento-hi-rgb), .14); color: var(--acento-hi);
  stroke: currentColor; fill: none; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.features b { font-weight: 600; font-size: .95rem; line-height: 1.25; }
.venta .btn-wa { margin-top: 2rem; }
@media (max-width: 1000px) { .features { grid-template-columns: 1fr; } }
@media (max-width: 860px) {
  .venta-grid { grid-template-columns: 1fr; }
  .venta-ph { order: -1; }
  /* En una sola columna el botón pegado a la izquierda queda descolgado debajo de una
     grilla de tarjetas que sí ocupa todo el ancho. Centrado cierra el bloque. */
  .venta .btn-wa { display: flex; margin-inline: auto; width: fit-content; }
}

/* ── Las tres líneas de negocio: bandas grandes con video ──
   Van como bandas y no como tarjetas porque cada una es un negocio distinto con su
   propio precio y su propia conversación de WhatsApp, y porque el material que hay
   para mostrarlas es video vertical, que en una tarjeta chica no se ve. */
.panel {
  display: grid; grid-template-columns: 1fr 1.05fr; gap: clamp(1.8rem, 5vw, 4rem); align-items: center;
  padding-inline: max(clamp(1.1rem, 4vw, 2rem), (100% - var(--maxw)) / 2);
}
/* Los servicios alternan el lado del medio para que no se lean como la misma plantilla
   repetida cuatro veces. El HTML de todos es igual —texto y después medio—, así que la
   inversión la hace el `order` y no el orden de los tags: así el que lee con lector de
   pantalla siempre escucha el título antes que "video de tal cosa".

   OJO: acá va -1, no 2. Con `order: 2` el medio queda IGUAL que sin la clase (el texto
   tiene order 0 y ya venía primero), y eso es exactamente lo que le pasaba a la primera
   versión de La Tercera: los cuatro servicios tenían el video a la derecha y la clase
   `panel--inv` no hacía nada. Se ve solo midiendo, no mirando una captura. */
.panel--inv .panel-media { order: -1; }
@media (max-width: 860px) {
  .panel { grid-template-columns: 1fr; }
  .panel-media, .panel--inv .panel-media { order: -1; }
}
.panel .lista { margin: 1.3rem 0 0; padding: 0; list-style: none; color: var(--crema-soft); font-size: .97rem; }
.panel .lista li { padding-left: 1.35rem; position: relative; margin-bottom: .45rem; }
.panel .lista li::before {
  content: ''; position: absolute; left: 0; top: .52em;
  width: 8px; height: 8px; border-radius: 50%; background: var(--acento-2);
}
.panel-quote {
  margin: 1.5rem 0 0; padding: 1.1rem 1.3rem; background: var(--panel);
  border-left: 3px solid var(--acento-3); border-radius: 0 10px 10px 0; font-size: .95rem;
}
.panel-quote .stars { color: var(--star); font-size: .85rem; letter-spacing: .1em; display: block; margin-bottom: .3rem; }
.panel-quote b { display: block; margin-top: .45rem; font-size: .82rem; color: var(--crema-soft); font-weight: 500; }
.panel .btn-wa { margin-top: 1.6rem; }

/* ── Reproductor de video (patrón de forzaclub) ──
   El video arranca CON AUDIO al tocar play, que es lo que se pidió. Por eso no puede
   autoreproducirse: ningún navegador deja arrancar con sonido sin que alguien toque algo.

   `preload="none"` es lo que hace que esto no pese: los tres mp4 suman 8 MB y no se baja
   ni un byte hasta que alguien aprieta play. Mientras tanto se ve el poster, que son 60K. */
.reel-player {
  position: relative; border-radius: 18px; overflow: hidden;
  aspect-ratio: 9 / 16; background: #000; box-shadow: var(--shadow);
  max-width: 380px; margin-inline: auto; width: 100%;
}
.reel-player video { width: 100%; height: 100%; object-fit: cover; }
/* Para el video que no viene vertical. Forzado al marco 9:16 el recorte se come casi la
   mitad del cuadro por los costados, así que ese reproductor toma la forma del video. */
.reel-player--cuadrado { aspect-ratio: 1; max-width: 440px; }
.reel-play, .reel-restart {
  position: absolute; border: 0; cursor: pointer; display: grid; place-items: center;
  transition: transform .2s ease, opacity .25s ease, background .2s ease;
}
/* El play va con el segundo acento y nunca con el verde de WhatsApp: un play verde haría
   dudar antes de tocarlo, porque en el resto de la página ese verde abre un chat. */
.reel-play {
  inset: 0; margin: auto; width: 76px; height: 76px; border-radius: 50%;
  background: var(--acento-2); color: var(--tinta);
  box-shadow: 0 10px 30px rgba(var(--sombra-rgb), calc(.55 * var(--sombra-k))), var(--glow-acento-2);
}
.reel-play svg { width: 34px; height: 34px; fill: currentColor; margin-left: 4px; }
@media (hover: hover) { .reel-play:hover { transform: scale(1.08); background: color-mix(in srgb, var(--acento-2) 88%, #fff); } }
/* Mientras corre, el botón central se va; al pausar o terminar vuelve, y ahí funciona
   como "reproducir de nuevo". */
.is-playing .reel-play { opacity: 0; pointer-events: none; transform: scale(.7); }
.reel-restart {
  right: .8rem; bottom: .8rem; width: 42px; height: 42px; border-radius: 50%;
  background: rgba(var(--tinta-rgb), .6); color: var(--crema);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  opacity: 0; pointer-events: none;
}
.reel-restart svg { width: 20px; height: 20px; fill: currentColor; }
.is-playing .reel-restart { opacity: 1; pointer-events: auto; }
.reel-restart:hover { background: rgba(var(--tinta-rgb), .85); }
/* Aviso de que tiene sonido: si no, el que lo toca en el celular a la noche se lleva
   un susto y lo primero que hace es cerrar la página. */
.reel-nota {
  text-align: center; font-size: .82rem; color: var(--crema-soft);
  margin: .8rem 0 0; display: flex; align-items: center; justify-content: center; gap: .4rem;
}
.reel-nota svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.8; }

/* ── Tira de texto que se desplaza (bloque opcional) ──
   Reusa el keyframe mq (-50%), que cierra sin salto porque el contenido está duplicado
   exacto en el HTML. No se frena con el mouse encima (pedido de Ciro, 22/09/2026): la tira
   y el carrusel siguen moviéndose siempre. */
.tira { overflow: hidden; background: var(--acento-2); padding-block: .95rem; }
.tira-track {
  display: flex; align-items: center; gap: 2.2rem; width: max-content;
  animation: mq 34s linear infinite;
}
.tira-track span {
  font-family: var(--display); font-weight: var(--display-peso); text-transform: uppercase;
  letter-spacing: .01em; font-size: clamp(.92rem, 1.8vw, 1.12rem);
  white-space: nowrap; color: var(--acento-2-ink);
}
.tira-track i { width: 9px; height: 9px; border-radius: 50%; background: color-mix(in srgb, var(--acento-2-ink) 55%, transparent); flex: none; }

/* ── Galería: carrusel de fotos (bloque opcional) ──
   Está hecha para fotos VERTICALES, porque es el formato que suele haber: si el material
   viene del Instagram del negocio, casi todo va a ser 4:5 o 9:16. Recortar eso a lo ancho
   pierde media foto. Con menos de 8 fotos buenas el bloque no va: el carrusel se repite
   antes de terminar de pasar y se nota. */
.mq { overflow: hidden; margin-top: 2.6rem; position: relative; }
.mq-track { display: flex; gap: 14px; width: max-content; animation: mq 46s linear infinite; }
.mq img { height: clamp(230px, 30vw, 330px); width: auto; border-radius: 12px; }
@keyframes mq { to { transform: translateX(-50%); } }
/* El keyframe recorre la mitad del track, no una distancia fija. En el celular las fotos
   son más bajas, el track queda más angosto y esa misma mitad son menos píxeles: con los
   46s de escritorio el carrusel se siente frenado. */
@media (max-width: 860px) { .mq-track { animation-duration: 30s; } }
.gal-ig { text-align: center; margin: 2rem 0 0; font-size: .95rem; color: var(--crema-soft); }
/* El handle va con la tinta plena y no heredando el gris de la bajada: es el único link de
   la sección y tiene que pesar más que el texto que lo presenta, no menos. Heredando
   --crema-soft quedaba más tenue que "Más en" y Lighthouse lo marcaba por contraste
   (a11y 96 en Cuniberti, 25/08/2026). El subrayado sí queda tenue, que es lo que lo hace
   leerse como link sin gritar. */
.gal-ig a { color: var(--crema); font-weight: 600; text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); text-underline-offset: 3px; }

/* ── Opiniones: fichas con formato de Google ──
   Es el bloque estándar de todas las landings del taller. Cinco piezas que no se
   negocian: la chapa de puntaje arriba, el logo de Google en cada ficha, la fecha
   ABSOLUTA de la reseña —"hace 2 meses" empieza a mentir al mes siguiente—, carrusel con
   scroll-snap en el celular y grilla de tres en escritorio, y la pista de deslizar solo
   en el celular. */
/* El título va centrado como la chapa de puntaje que tiene debajo: a la izquierda quedaba
   desalineado con el único elemento con el que comparte ancho. */
.opiniones .title { text-align: center; }
.g-resumen {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; justify-content: center;
  width: fit-content; margin: 0 auto; padding: 1rem 1.5rem;
  background: var(--panel); border-radius: var(--radius);
  border: 1px solid var(--ficha-borde); box-shadow: var(--ficha-sombra);
}
.g-logo { width: 1.5rem; height: 1.5rem; flex: none; }
.g-resumen .puntaje { font-family: var(--display); font-weight: 400; font-size: 2.3rem; line-height: 1; margin: 0; }
.estrellas-fijas { color: var(--star); letter-spacing: .06em; font-size: 1.02rem; }
.g-resumen small { display: block; color: var(--crema-soft); font-size: .86rem; }
.g-resumen a {
  margin-left: .4rem; font-weight: 600; font-size: .92rem;
  /* 44px de alto táctil. Es un link suelto en su propia línea, no uno metido dentro de un
     renglón de texto, así que la excepción de la norma no lo cubre y Lighthouse lo marca.
     El subrayado pasa de border-bottom a text-decoration para que el padding no lo despegue
     del texto: con border-bottom quedaba flotando 10px más abajo. */
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 .25rem;
  color: var(--acento-hi);
  text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px;
}
@media (hover: hover) { .g-resumen a:hover { color: var(--crema); } }

/* En celular el carrusel se sale del `.wrap` a propósito y se pone él mismo la sangría:
   así la primera ficha respeta el margen de la página, la última no queda pegada al borde
   y —lo importante— la siguiente asoma lo suficiente para que se entienda que hay más. Sin
   esto asomaban once píxeles, que no se leen como un carrusel sino como algo mal dibujado. */
.op-viewport {
  display: flex; gap: 1rem; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; margin-top: 1.8rem; padding-bottom: .5rem;
  --sangria: clamp(1.1rem, 4vw, 2rem);
  margin-inline: calc(-1 * var(--sangria));
  padding-inline: var(--sangria);
  scroll-padding-inline: var(--sangria);
}
.op-viewport::-webkit-scrollbar { display: none; }
/* En escritorio deja de ser carrusel: si no, las últimas fichas no se ven nunca. */
@media (min-width: 900px) {
  .op-viewport {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.2rem;
    overflow: visible; margin-top: 2.2rem; padding-bottom: 0;
    margin-inline: 0; padding-inline: 0;
  }
}
.op {
  /* `start` y no `center`: con la sangría de arriba, cada ficha frena alineada con el
     margen de la página, que es donde el ojo la espera. */
  flex: 0 0 min(340px, 84vw); scroll-snap-align: start;
  background: var(--panel); border-radius: var(--radius); padding: 1.4rem;
  display: flex; flex-direction: column; margin: 0;
  border: 1px solid var(--ficha-borde); box-shadow: var(--ficha-sombra);
  transition: transform .25s ease;
}
@media (hover: hover) { .op:hover { transform: translateY(-4px); } }
.op-cab { display: flex; align-items: center; gap: .7rem; margin-bottom: .85rem; }
.op-ava {
  width: 2.5rem; height: 2.5rem; flex: none; border-radius: 50%;
  display: grid; place-items: center; color: #fff;
  font-weight: 700; font-size: .88rem; line-height: 1;
}
.op-cab div { margin-right: auto; min-width: 0; }
.op cite { display: block; font-style: normal; font-weight: 600; font-size: .92rem; line-height: 1.3; }
.op small { display: block; color: var(--crema-soft); font-size: .8rem; }
.op .estrellas { color: var(--star); letter-spacing: .08em; font-size: 1rem; }
.op p { margin: .6rem 0 0; font-size: .97rem; color: rgba(var(--crema-rgb), .9); }
.pista { display: flex; align-items: center; gap: .4rem; margin-top: 1rem; font-size: .85rem; color: var(--crema-soft); }
.pista svg {
  width: 1rem; height: 1rem; stroke: currentColor; fill: none; stroke-width: 2;
  animation: desliza 1.6s ease-in-out infinite;
}
@keyframes desliza { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(5px); } }
@media (min-width: 900px) { .pista { display: none; } }

/* ── Ubicación ── */
.locale-grid { display: grid; grid-template-columns: 1fr 1.15fr; gap: clamp(1.8rem, 4vw, 3rem); align-items: center; }
.locale-info { display: flex; flex-direction: column; gap: 1.05rem; }
.locale-item { display: flex; gap: .8rem; align-items: flex-start; }
/* --acento-hi y no --acento-3-hi, por lo mismo que el ícono de redes del menú: el tinte 3-hi
   es el más pálido de la paleta y está pensado para fondo oscuro. En una piel clara estos
   tres íconos y el "Cómo llegar" quedaban en 1,1:1, o sea invisibles. `--acento-hi` es, por
   definición, el que contrasta contra el fondo de cada piel. */
.locale-item svg { flex: none; margin-top: .2rem; stroke: var(--acento-hi); fill: none; stroke-width: 1.8; width: 22px; height: 22px; }
.locale-item b { display: block; font-size: .95rem; }
.locale-item span { color: var(--crema-soft); font-size: .92rem; }
.locale-item a { color: var(--acento-hi); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, currentColor 45%, transparent); }
/* El fondo no es decorativo: hasta que el iframe recibe su src pinta blanco, y sin esto
   el hueco del mapa se ve como un rectángulo blanco en medio de una sección oscura. */
.locale-map {
  position: relative; border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--panel); overflow: hidden;
}
.locale-map iframe { width: 100%; height: 380px; border: 0; display: block; border-radius: var(--radius); }
@media (max-width: 860px) { .locale-grid { grid-template-columns: 1fr; } }

/* Panel de sucursales del WhatsApp. `<dialog>` nativo: el ::backdrop, el foco y el Escape
 * vienen de fábrica. Va con el ancho acotado porque es una lista para elegir, no una
 * sección: si ocupa toda la pantalla deja de leerse como un paso rápido. */
.wa-panel {
  width: min(92vw, 520px); max-height: 82vh; padding: 1.8rem; border: 0;
  border-radius: var(--radius); background: var(--panel); color: var(--crema);
  box-shadow: 0 24px 60px rgba(var(--sombra-rgb), calc(.45 * var(--sombra-k)));
}
.wa-panel::backdrop { background: rgba(var(--tinta-rgb), .72); }
.wa-panel h3 { font-family: var(--display); font-weight: var(--display-peso); font-size: 1.5rem; }
.wa-panel > p { color: var(--crema-soft); font-size: .93rem; margin: .5rem 0 1.3rem; }
.wa-panel-cerrar { float: right; }
.wa-panel-cerrar button {
  border: 0; background: none; color: var(--crema-soft); font-size: 1.6rem; line-height: 1;
  cursor: pointer; padding: 0 .2rem;
}
.wa-panel-cerrar button:hover { color: var(--crema); }
.wa-panel-lista { display: grid; gap: .55rem; max-height: 52vh; overflow-y: auto; }
.wa-panel-item {
  display: block; padding: .7rem .9rem; border-radius: calc(var(--radius) / 1.6);
  border: 1px solid rgba(var(--crema-rgb), .14); text-decoration: none; color: var(--crema);
  transition: border-color .18s ease, background .18s ease;
}
.wa-panel-item b { display: block; font-size: .96rem; }
.wa-panel-item span { color: var(--crema-soft); font-size: .85rem; }
@media (hover: hover) {
  .wa-panel-item:hover { border-color: var(--acento-hi); background: rgba(var(--acento-hi-rgb), .09); }
}

/* Sucursales. Mismo ítem que arriba, otro contenedor: en cuanto son más de cuatro
 * direcciones la columna deja de servir y hay que repartirlas a lo ancho. */
.suc-lead { margin-bottom: 2.4rem; }
.suc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 1.6rem 2rem; }
/* Con `.suc-nueva` a secas gana `.locale-item span`, que tiene un tipo de más, y la píldora
 * queda con el gris de las bajadas sobre el naranja: 1,24:1. El mismo empate de
 * especificidad que ya había apagado los reveals. */
.locale-item .suc-nueva {
  display: inline-block; margin-left: .5rem; padding: .12rem .45rem; border-radius: 999px;
  background: var(--acento-2); color: var(--acento-2-ink); font-size: .68rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; vertical-align: 2px;
}

/* ── Preguntas ──
   <details> nativo: el acordeón no necesita una línea de JS, y el que llega buscando el
   precio lo encuentra con Cmd+F aunque esté cerrado. */
/* Sin `margin-inline: auto`: centrada quedaba corrida a la derecha respecto del h2, que
   arranca en el borde del wrap, y se leía como un bloque desalineado. */
.faq { max-width: 820px; }
.faq details {
  border-bottom: 1px solid rgba(var(--crema-rgb), .12);
  padding: .3rem 0;
}
.faq summary {
  cursor: pointer; list-style: none; padding: 1.05rem 2.4rem 1.05rem 0;
  /* Una pregunta es una oración, no un título. Con una display condensada aguanta ir en
     mayúsculas; con un slab pesado, ocho seguidas son un muro. Por eso la fuente y la caja
     de las preguntas salen de la piel y no están clavadas acá. */
  font-family: var(--faq-fuente); font-weight: var(--faq-peso); font-size: 1.12rem;
  text-transform: var(--faq-caja); letter-spacing: .01em;
  position: relative; transition: color .2s;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--acento-hi); }
/* La cruz gira 45° al abrir y se convierte en una X. Dos barritas con ::after. */
.faq summary::after {
  content: ''; position: absolute; right: .4rem; top: 50%;
  width: 14px; height: 2px; background: var(--acento-hi);
  transform: translateY(-50%);
}
/* Las dos barritas tienen que cruzarse en el MISMO punto. La horizontal mide 14px con su
   borde derecho en .4rem, así que su centro cae en .4rem + 7px; la vertical mide 2px y su
   centro en right + 1px. De ahí el calc: con un valor suelto las barras quedaban separadas
   y el "+" se veía como un ⊢. */
.faq summary::before {
  content: ''; position: absolute; right: calc(.4rem + 6px); top: 50%;
  width: 2px; height: 14px; background: var(--acento-hi);
  transform: translateY(-50%); transition: transform .3s var(--ease), opacity .3s ease;
}
.faq details[open] summary::before { transform: translateY(-50%) rotate(90deg); opacity: 0; }
.faq details p { color: var(--crema-soft); margin: 0 0 1.05rem; font-size: .98rem; max-width: 66ch; }

/* ── CTA final ── */
/* El cierre va con una foto real del lugar y no con un fondo plano ni un dibujo: es el
   sitio al que estás invitando a venir, y un gráfico genérico pegado al pie no invita a
   nada. Elegir la mejor foto del atardecer o de la noche, si el negocio la tiene.

   Acá puede ir la foto MENOS nítida del set apaisado: queda detrás de un velo oscuro
   fuerte y de un titular enorme, así que el detalle no se ve. Lo que importa es el tema,
   no la definición. */
.cta-band {
  position: relative; color: var(--hero-tinta); background: var(--tinta);
  text-align: center; overflow: hidden;
  padding-block: clamp(5.5rem, 13vw, 9rem);
}
.cta-ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* En el celular la banda es mucho más angosta que la foto y el recorte centrado se come
   los costados. El object-position se ajusta a ojo por página, mirando la captura del
   celular: el valor de acá abajo es un punto de partida, no una constante. */
@media (max-width: 700px) { .cta-ph { object-position: 50% 45%; } }
/* Dos degradados encima: uno parejo que baja el brillo general y otro que funde los bordes
   con lo que hay arriba y con el pie de abajo, para que la banda no quede como un recorte
   pegado sino como parte de la página.

   Van con --hero-velo por el mismo motivo que el hero: es una foto con texto encima, así
   que el velo tiene que oscurecerla. Con el color de fondo de la página, una piel clara la
   tapaba entera y quedaba un rectángulo rosa con letras blancas invisibles. */
.cta-band::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(rgba(var(--hero-velo),.88), rgba(var(--hero-velo),.55) 40%, rgba(var(--hero-velo),.6) 60%, rgba(var(--hero-velo),.92)),
    radial-gradient(110% 80% at 50% 45%, rgba(var(--acento-rgb),.12), transparent 68%);
}
.cta-band .wrap { position: relative; z-index: 2; }
.cta-title {
  font-size: clamp(3rem, 9.5vw, var(--h1-max)); margin: 0 0 .3em; color: var(--hero-tinta);
  text-shadow: 0 0 44px rgba(var(--acento-hi-rgb), .5), 0 6px 24px rgba(0, 0, 0, .55);
}
.cta-band p { max-width: 46ch; margin-inline: auto; color: var(--hero-tinta); }
.cta-band .btn-wa { margin-top: 1.4rem; }
.cta-hours { margin-top: 1.6rem; max-width: none; font-size: .88rem; font-weight: 500; color: color-mix(in srgb, var(--hero-tinta) 78%, transparent); }

/* ── Pie ── */
.site-footer { background: color-mix(in srgb, var(--tinta) 88%, #000); color: rgba(var(--crema-rgb), .86); font-size: .92rem; }
.footer-grid { display: grid; grid-template-columns: 1.3fr 1fr 1.1fr; gap: 2.5rem; align-items: start; padding-block: 3.5rem 2.5rem; }
.f-col { display: flex; flex-direction: column; gap: .55rem; align-items: flex-start; }
/* Al lado del nombre y no encima: así los títulos de las tres columnas arrancan a la
   misma altura. Antes el escudo empujaba el de la primera media cabeza para abajo y las
   tres quedaban desalineadas. */
.f-marca { display: flex; align-items: center; gap: .6rem; }
/* object-fit por lo mismo que la marca del header: sin él, un logo que no es cuadrado
   se estira dentro de la caja. Es el mismo archivo y tiene que verse igual arriba. */
.f-logo { width: 44px; height: 40px; border-radius: 50%;
  object-fit: contain; flex: none; }
.f-col b { display: flex; align-items: center; min-height: 40px; color: var(--crema); font-family: var(--display); font-weight: 400; font-size: 1.14rem; line-height: 1.1; text-transform: uppercase; letter-spacing: .01em; margin-bottom: .55rem; }
.f-col p { margin: 0; max-width: 30ch; color: rgba(var(--crema-rgb), .78); }
.f-col a {
  display: inline-flex; align-items: center; min-height: 44px;
  color: rgba(var(--crema-rgb), .68); text-decoration: none; transition: color .2s;
}
.f-col a:hover { color: var(--acento-hi); }
.footer-bar {
  display: flex; justify-content: space-between; gap: 1rem;
  padding-block: 1.3rem; font-size: .8rem; color: rgba(var(--crema-rgb), .78);
  border-top: 1px solid rgba(var(--crema-rgb), .1);
}
/* El subrayado va siempre, no solo en hover: un link dentro de un renglón de texto no
   puede distinguirse solo por el color. Lighthouse lo marca como link-in-text-block y
   baja la accesibilidad de 100 a 96. */
.firma a {
  color: rgba(var(--crema-rgb), .92); text-decoration: underline;
  text-decoration-color: rgba(var(--crema-rgb), .28);
  text-underline-offset: 3px; transition: color .2s, text-decoration-color .2s;
}
.firma a:hover { color: var(--acento-hi); text-decoration-color: var(--acento-hi); }
@media (max-width: 720px) {
  .footer-grid { grid-template-columns: 1fr; text-align: center; }
  .f-col { align-items: center; }
  /* En una columna el nombre es un texto suelto dentro del flex, así que se estira y se
     lleva todo el ancho: el `justify-content` no tiene nada que centrar y el logo queda
     contra el borde. Con un nombre corto no se nota; con uno de dos renglones, sí.
     Apilado se centran los dos, entre en una línea o en tres. */
  .f-marca { flex-direction: column; justify-content: center; gap: .5rem; }
  .footer-bar { flex-direction: column; text-align: center; gap: .3rem; }
}

/* ── Reveals ──
   El JS solo agrega .visible y un --i con el orden dentro de la tanda; el resto es CSS.
   Los estados ocultos cuelgan de .js-anim, así que sin JS la página se ve entera y quieta. */
/* Todos los selectores de acá pesan lo mismo que `.js-anim .visible` (dos clases). No es
   casual: si alguno llevara un tipo o una clase de más le ganaría al estado visible y ese
   elemento no aparecería nunca —ya pasó con `.js-anim .faq details`, que dejaba las seis
   preguntas invisibles—. Lo que hay que revelar y no tiene clase propia recibe `.reveal`
   desde el JS, justamente para no romper este equilibrio. */
.js-anim .reveal, .js-anim .stat,
.js-anim .venta-ph, .js-anim .panel-media, .js-anim .locale-map {
  opacity: 0; transform: translateY(22px);
}
/* El botón entra SOLO con opacidad, sin transform. Su hover ya usa transform, y como
   `.js-anim .visible` tiene la misma especificidad y viene después en el archivo, le
   pisaba el translateY(-2px) y el botón quedaba sin hover. */
.js-anim .panel .btn-wa, .js-anim .venta .btn-wa { opacity: 0; }
.js-anim .panel .btn-wa.visible, .js-anim .venta .btn-wa.visible { opacity: 1; transition: opacity .5s var(--ease), transform .2s ease, box-shadow .2s ease; }

.js-anim .visible {
  opacity: 1; transform: none;
  transition: opacity .5s var(--ease), transform .6s var(--ease);
  transition-delay: calc(var(--i, 0) * .07s);
}

/* Títulos: cada palabra sube desde atrás de su renglón. */
.title .w {
  display: inline-block; overflow: hidden; vertical-align: bottom;
  padding-bottom: .1em; margin-bottom: -.1em;
  padding-top: .18em; margin-top: -.18em;
}
.js-anim .title .w > span { display: inline-block; transform: translateY(112%); }
.js-anim .title.visible .w > span {
  transform: none;
  transition: transform .7s var(--ease);
  transition-delay: calc(var(--i, 0) * .05s);
}

/* Las estrellas de cada opinión aparecen de a una. El disparador es el contenedor y no
   cada ficha: en el celular las fichas viven en un carrusel horizontal y las de la
   derecha nunca entran a pantalla, así que un reveal por ficha las dejaría invisibles
   hasta que alguien deslice. El orden va escrito acá porque siempre son seis. */
.js-anim .op .estrellas { opacity: 0; }
.js-anim .op-viewport.visible .estrellas {
  opacity: 1; transition: opacity .4s ease;
  transition-delay: calc(var(--j, 0) * .09s + .3s);
}
.js-anim .op:nth-child(2) .estrellas { --j: 1; }
.js-anim .op:nth-child(3) .estrellas { --j: 2; }
.js-anim .op:nth-child(4) .estrellas { --j: 3; }
.js-anim .op:nth-child(5) .estrellas { --j: 4; }
.js-anim .op:nth-child(6) .estrellas { --j: 5; }

/* El video entra apenas agrandado y se asienta. Va en la propiedad `scale` y no dentro
   de `transform` a propósito: así no se pisa con el translateY de la entrada. */
.js-anim .panel-media .reel-player { scale: 1.06; }
.js-anim .panel-media.visible .reel-player {
  scale: 1; transition: scale 1.1s var(--ease);
  transition-delay: calc(var(--i, 0) * .07s);
}

/* ── Mobile: centrado ── */
@media (max-width: 899px) {
  .hero-in, .hero-cta, .hero-cred, .hero-dots { justify-content: center; text-align: center; }
  .hero h1, .hero .lead { margin-inline: auto; }
  .hero h1 .ln:first-child::after { margin-inline: auto; }
  .title, .lead { text-align: center; margin-inline: auto; }
  .panel > div:not(.panel-media) { text-align: center; }
  /* La lista NO se centra ítem por ítem. Con `inline-block` cada viñeta arranca donde la
     deja su propio largo —medido en la misma lista: 98, 37, 54 y 100px— y se lee como un
     texto desalineado. Lo que se centra es el bloque entero, y adentro los ítems quedan
     alineados entre sí, igual que en escritorio. */
  .panel .lista { width: fit-content; max-width: 100%; margin-inline: auto; text-align: left; }
  .panel .lista li { display: list-item; }
  .panel-quote { text-align: left; }
  /* Las fichas de opinión NO se centran: el texto de una reseña se lee alineado a la
     izquierda. Sí se centra la pista de deslizar, que acompaña al carrusel. */
  .pista { justify-content: center; }
}

/* ── Mobile: el hero tiene que ENTRAR ──
   En una pantalla de 390×640 el titular a dos líneas, la bajada a cuatro renglones y la
   chapa de Google empujaban los tres botones abajo del pliegue: se veía una foto linda y
   ninguna forma de escribir. Todo lo de acá abajo es recortar aire para que el botón de
   WhatsApp quede arriba del pliegue, que es lo único que la página tiene que lograr. */
@media (max-width: 700px) {
  /* El contenido se centra en vez de apoyarse abajo. Con la alineación al pie, en un
     teléfono alto quedaban 280px de foto vacía entre el header y el titular y casi nada
     abajo: todo el aire junto arriba. Centrado se reparte, y el padding de arriba mayor que
     el de abajo lo deja apenas por debajo del medio, que es donde el velo tapa mejor. */
  .hero { align-items: center; }
  .hero-in { padding-block: 3.4rem 1.4rem; }
  /* En un teléfono la foto es vertical y el velo del hero es horizontal: el lado derecho
     queda casi sin tapar y el titular termina apoyado sobre la parte más clara de la foto.
     Acá el degradado se da vuelta y tapa de arriba abajo, que es como se lee la pantalla. */
  .hero::after {
    background:
      radial-gradient(90% 42% at 50% 72%, rgba(var(--acento-rgb), .26), transparent 66%),
      linear-gradient(180deg, rgba(var(--hero-velo), .84) 0%, rgba(var(--hero-velo), .68) 46%, rgba(var(--hero-velo), .92) 100%);
  }
  /* 16ch estaba calibrado para una display ancha. Con una condensada (Oswald, Anton) entran
     más letras en el mismo ancho, y el tope angosto partía el titular en una línea de más. */
  /* 12.4vw entraban ~14 caracteres por línea en un teléfono, así que cualquier titular de
     dos frases se partía en cuatro renglones y se comía media pantalla. Con 11vw entran 18,
     que es lo que mide una frase de hero, y el titular sigue siendo lo más grande de todo. */
  /* El `max-width: 18ch` acota la caja pero NO parte una palabra: un titular con una
     palabra de quince letras —"MULTIMATERIALES"— se sale de la pantalla y se corta, sin
     que nada avise. Por eso el tamaño también se limita por la palabra más larga del h1,
     que `armar.mjs` deja en `--h1-chars`, y por lo ancha que sea la display, en
     `--h1-ancho`. Lo que gana es el menor de los dos. */
  .hero h1 {
    font-size: min(clamp(2.35rem, 11vw, 3.7rem),
                   calc(90vw / (var(--h1-chars) * var(--h1-ancho))));
    margin-bottom: .3em; max-width: 18ch;
  }
  .hero .lead { font-size: 1.06rem; line-height: 1.5; max-width: 32ch; margin-bottom: 0; }
  .hero-cred { margin: .9rem 0 1.25rem; gap: .35rem .7rem; font-size: .86rem; }
  /* El punto separador quedaba solo al final del renglón cuando la dirección bajaba de
     línea. Acá el salto es a propósito y el punto sobra. */
  .hero-cred .sep { display: none; }
  .hero-cred > span:last-child { flex-basis: 100%; }
  .hero-cta { gap: .6rem; }
  .hero-cta .btn-ghost { padding: .8rem 1.25rem; font-size: .95rem; }
  .hero-dots { margin-top: 1.1rem; }
  /* En el celular el botón grande partía el texto en dos renglones y el logo quedaba
     chico y lejos: menos aire a los costados, logo y letra un poco más grandes. */
  .btn-wa--xl { padding: .95rem 1.5rem; gap: .65rem; font-size: 1.08rem; }
  .btn-wa--xl svg { width: 23px; height: 23px; }
}

/* ── Mobile: motion más suave ──
   Todo el motion se calibró mirando una pantalla ancha, y en el celular la misma receta
   se lee brusca por tres motivos distintos. Acá se corrige cada uno; en escritorio no
   cambia nada. */
@media (max-width: 899px) {
  /* 1) La curva. La de escritorio arranca disparada y frena largo: en 390px de ancho ese
     arranque se siente un tirón. Esta sale del mismo lado pero con menos violencia. */
  :root { --ease: cubic-bezier(.33, 1, .68, 1); }

  /* 2) El recorrido. 22px sobre una pantalla de 390px pesan el doble que sobre una de
     1400px: lo que en el monitor es un deslizamiento, en el celular es un salto. */
  .js-anim .reveal, .js-anim .stat,
  .js-anim .venta-ph, .js-anim .panel-media, .js-anim .locale-map { transform: translateY(12px); }

  /* 3) El escalonado. Se pensó para filas de 2 a 4 columnas, donde reparte la entrada a
     lo ancho. Acá todo se apila en una sola columna y ese mismo retraso acumulado
     convierte la sección en una fila de espera. */
  .js-anim .visible { transition-delay: calc(var(--i, 0) * .03s); }
  .js-anim .title.visible .w > span { transition-delay: calc(var(--i, 0) * .025s); }
}

/* En una sola columna el título queda entre la foto de arriba y el texto de abajo, y con las
   medidas de escritorio el aire quedaba repartido al revés: pegado arriba y suelto abajo. Se
   agranda el hueco entre la foto y el bloque de texto, y se achica el de abajo del título. */
@media (max-width: 860px) {
  .venta-grid, .panel, .locale-grid { gap: 2.6rem; }
  .title { margin-bottom: 1.05rem; }
}

/* ── Banda con la foto casi clavada (bloque opcional) ──
   Viene de `Plantillas/panaderia-san-benedetto`, que a su vez la vio en `laalvear.com.ar`.
   La foto mide una pantalla de alto adentro de una banda que mide menos, así que la banda
   funciona como una ventana: mientras scrolleás ves otra parte de la misma foto.

   Alvear lo hace con `background-attachment: fixed`, que en iOS no anda —por eso ellos lo
   apagan en el celular—. Acá va con una animación atada al scroll, que corre en el
   compositor y sí anda en el teléfono.

   Sin soporte (navegador viejo) o sin `.js-anim` (movimiento reducido) la foto queda
   quieta y centrada, que es una foto normal: no se rompe nada.

   `clip` y NO `hidden`: `hidden` convierte a la banda en un contenedor de scroll, y
   entonces el view-timeline se mide contra la banda —que no scrollea nunca— y la foto
   queda pegada a la página en vez de quieta. */
.banda {
  position: relative; height: var(--banda); overflow: clip;
  display: grid; place-items: center; text-align: center; background: var(--tinta-alt);
}
.banda-img {
  position: absolute; top: 0; left: 0; width: 100%; height: 100vh; object-fit: cover;
  transform: translateY(calc((var(--banda) - 100vh) / 2));
}
.banda::after { content: ''; position: absolute; inset: 0; background: rgba(var(--tinta-rgb), .58); }
.banda-txt { position: relative; z-index: 1; color: var(--crema); padding-inline: 1.5rem; }
.banda-txt h2 {
  font-size: clamp(1.8rem, 5vw, 3rem); margin: 0;
  text-shadow: 0 2px 24px rgba(var(--tinta-rgb), .5);
}
.banda-txt p { margin: .6rem 0 0; color: var(--crema); opacity: .9; }
/* Media pantalla es demasiado para un bloque que no vende nada. */
@media (max-width: 760px) { :root { --banda: 42vh; } }

/* De dónde salen los dos valores del keyframe, que son una cuenta y no prueba y error:
   con `v` = dónde está el borde de arriba de la banda en la pantalla, la foto tiene que ir
   a `t(v) = -v(1 - deriva) - deriva * (100vh - banda) / 2`. El primer término es el que la
   mantiene quieta (con deriva 0 es -v, o sea clavada); el segundo recentra el recorrido
   para que la foto no descubra el borde de la banda en ninguno de los dos extremos. Y `v`
   va de `100vh` (la banda recién asoma por abajo) a `-banda` (terminó de salir por
   arriba), que son justo el 0% y el 100% del `view()`.

   Cómo se verifica: parar el scroll a mitad de la banda, scrollear 300px y volver a medir.
   Si está bien, la banda recorre cientos de píxeles y la foto se mueve casi nada. */
@supports (animation-timeline: view()) {
  /* El reloj lo marca la BANDA, no la foto: con `animation-timeline: view()` a secas el
     sujeto es la foto, que mide 100vh, y el recorrido se mide sobre esos 100vh — la foto
     terminaba yendo más lento que el scroll en vez de quedarse quieta. */
  .banda { view-timeline-name: --banda; view-timeline-axis: block; }
  @keyframes bandaFija {
    from { transform: translateY(calc(-100vh * (1 - var(--deriva))
      - var(--deriva) * (100vh - var(--banda)) / 2)); }
    to { transform: translateY(calc(var(--banda) * (1 - var(--deriva))
      - var(--deriva) * (100vh - var(--banda)) / 2)); }
  }
  .js-anim .banda-img { animation: bandaFija linear both; animation-timeline: --banda; }
}

/* ── Reduced motion ──
   El JS no agrega .js-anim en este caso, así que los estados ocultos ni existen. Acá solo
   quedan los loops infinitos, que son de CSS puro y hay que apagar a mano. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .mq, .tira { overflow-x: auto; }
  .mq-track, .tira-track { animation: none; }
  .btn-wa--xl::after { animation: none; }
  .wa-float::after { animation: none; }
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* ── Ajustes propios de la piel (heredados de Cops) ──────────────────────────────────────────────────
   `construir` regenera styles.css desde el molde en cada corrida, así que estos
   ajustes viven acá y los pega al final `./construir.sh`. No editar styles.css.  */

/* El velo del molde está calibrado para fotos de local con luz cálida y poca luz. Las de
   COPS son al revés: una sala de espera blanca con ventanales, o sea que la cualidad que
   hay que mostrar es justamente la luz. Con el velo de fábrica la foto se apaga y el hero
   arranca pareciendo de otra marca que la página, que es clara.
   Van los DOS, escritorio y celular, con sus media queries: el del molde para celular da
   vuelta el degradado —vertical, porque la foto en un teléfono es vertical— y una regla
   suelta acá abajo se lo pisaría, dejando el lado derecho del titular sin tapar. */
@media (min-width: 701px) {
  .hero::after {
    background:
      radial-gradient(80% 55% at 22% 78%, rgba(var(--acento-rgb), .08), transparent 60%),
      linear-gradient(90deg, rgba(var(--hero-velo), .70) 0%, rgba(var(--hero-velo), .34) 58%, rgba(var(--hero-velo), .10) 100%),
      linear-gradient(200deg, rgba(var(--hero-velo), .14) 0%, rgba(var(--hero-velo), .30) 52%, rgba(var(--hero-velo), .74) 100%);
  }
}
@media (max-width: 700px) {
  .hero::after {
    background:
      radial-gradient(90% 42% at 50% 72%, rgba(var(--acento-rgb), .10), transparent 66%),
      linear-gradient(180deg, rgba(var(--hero-velo), .74) 0%, rgba(var(--hero-velo), .52) 46%, rgba(var(--hero-velo), .86) 100%);
  }
}

/* Los links de contacto del pie salían en 4,36:1 sobre el fondo del pie: a dos centésimas
   del mínimo de 4,5, o sea que Lighthouse baja accesibilidad de 100 a 96 y —lo que
   importa— el teléfono se lee flojo justo donde alguien lo va a copiar. Con .78 quedan en
   5,7:1 y siguen leyéndose como secundarios frente al texto del pie. */
.f-col a { color: rgba(var(--crema-rgb), .78); }

/* El nombre completo del centro son tres renglones, y "ODONTOLÓGICO" a 11vw toca los dos
   bordes de un teléfono de 390px: no desborda, pero se lee apretado. */
@media (max-width: 700px) { .hero h1 { font-size: 10.1vw; } }

/* ── Tratamientos: lista numerada (copiada del Ateneo, con las variables de esta piel) ──
   Los servicios sin material propio van todos en UNA sección. Se lee como catálogo, no
   como cuatro secciones gemelas. */
.acts .title { max-width: 18ch; }
.act {
  width: min(var(--maxw), 100% - 2.6rem); margin: 4rem auto 0;
  display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1fr); gap: clamp(1.8rem, 5vw, 3.5rem); align-items: center;
}
.act.invertida .act-foto { order: 2; }
.act-foto { position: relative; }
.act-foto img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 14px; }
/* el filete de acento al costado de la foto */
.act-foto::before { content: ''; position: absolute; left: -14px; top: 26px; bottom: 26px; width: 3px; background: var(--acento); }
.act.invertida .act-foto::before { left: auto; right: -14px; }
.act-num { font-family: var(--display); font-weight: 600; font-size: .95rem; letter-spacing: .28em; color: var(--acento-hi); }
.act-txt h3 { margin: .55rem 0 1rem; font-size: clamp(1.4rem, 3vw, 1.85rem); }
.act-txt p { color: var(--crema-soft); max-width: 48ch; }
.act .lista { list-style: none; margin: 1.2rem 0 0; padding: 0; display: grid; gap: .45rem; color: var(--crema-soft); font-size: .97rem; }
.act .lista li { position: relative; padding-left: 1.35rem; }
.act .lista li::before { content: ''; position: absolute; left: 0; top: .52em; width: 8px; height: 8px; border-radius: 50%; background: var(--acento-2); }
@media (max-width: 760px) {
  .act { grid-template-columns: 1fr; gap: 1.4rem; margin-top: 3rem; }
  .act.invertida .act-foto { order: 0; }
  .act-foto::before, .act.invertida .act-foto::before { left: -10px; right: auto; }
}

/* ── Niños: banda a sangre (copiada del Ateneo) ──
   Corta el ritmo de la página en seco, después de dos secciones de foto al lado del texto. */
.banda { position: relative; min-height: 82vh; display: grid; place-items: center; overflow: hidden; background: #0B2320; scroll-margin-top: 2.5rem; }
.banda-foto { position: absolute; inset: 0; }
.banda-foto img { width: 100%; height: 100%; object-fit: cover; opacity: .7; }
.banda::after { content: ''; position: absolute; inset: 0; background: rgba(8, 30, 27, .45); }
.banda-txt { position: relative; z-index: 2; color: #fff; text-align: center; width: min(800px, 100% - 2.6rem); padding: 7rem 0; text-shadow: 0 2px 24px rgba(0, 0, 0, .5); }
.banda-txt h2 { color: #fff; font-size: clamp(2rem, 6vw, 3.4rem); }
.banda-txt p { margin: 1.4rem auto 0; max-width: 52ch; color: rgba(255, 255, 255, .9); font-size: 1.06rem; }

/* El teléfono de "Dónde estamos" es un link dentro de un renglón: sin esto mide 20px de
   alto y el dedo no le acierta. */
.locale-item b a { display: inline-flex; align-items: center; min-height: 44px; color: inherit; }
/* Pero esos 44px bajaban el número respecto del ícono y el subrayado quedaba colgando al
   pie de la caja. El margen negativo devuelve el renglón a su alto real (el área táctil
   sigue siendo de 44px) y el subrayado pasa a ser del texto. */
.locale-item b a {
  margin-block: calc((1lh - 44px) / 2);
  border-bottom: 0; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
}
