/* ============================================================
   BENNONI GELATO E CAFFÈ — styles.css
   ------------------------------------------------------------
   Sistema de diseño construido sobre la identidad de marca.
   Mobile-first · BEM · Custom Properties como design tokens.

   PALETA (muestreada del manual de marca)
     Carmín   #B22A44 — color primario, acción y acento
     Oro      #BA8E30 — trazo fino decorativo (aros del monograma)
     Cacao    #5C4736 — texto secundario
     Crema    #E5E1D6 — fondo alterno
     Hueso    #F7F9F6 — fondo base
     Espresso #1E070B — texto principal y fondos oscuros

   TIPOGRAFÍAS
     Dancing Script → logotipo y florituras (nunca texto corrido)
     Josefin Sans   → titulares
     Nunito Sans    → cuerpo
     Work Sans      → etiquetas de interfaz y versalitas
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ============================================================
   DESIGN TOKENS
============================================================ */
:root {
  /* ── Color de marca ── */
  --c-crimson:      #B22A44;
  --c-crimson-dark: #8E1F35;   /* hover: mantiene ≥7:1 sobre hueso   */
  --c-gold:         #BA8E30;   /* SOLO decorativo: 2.83:1 sobre hueso */
  --c-gold-text:    #8A6A1F;   /* variante legible: 4.77:1 ✓ AA       */
  --c-cocoa:        #5C4736;
  --c-cream:        #E5E1D6;
  --c-bone:         #F7F9F6;
  --c-espresso:     #1E070B;

  /* ── Roles semánticos ── */
  --bg:           var(--c-bone);
  --bg-alt:       var(--c-cream);
  --bg-dark:      var(--c-espresso);
  --surface:      #FFFFFF;
  --text:         var(--c-espresso);   /* 18.2:1 ✓ AAA */
  --text-soft:    var(--c-cocoa);      /*  8.2:1 ✓ AAA */
  --text-onDark:  var(--c-cream);      /* 14.7:1 ✓ AAA */
  --line:         rgba(92, 71, 54, 0.16);
  --line-gold:    rgba(186, 142, 48, 0.55);
  --danger:       #A61D2A;

  /* Tokens con requisito de contraste explícito.
     --field-border cumple WCAG 1.4.11 (3:1 para límites de componentes de
     interfaz): antes el borde era `transparent` y el campo se distinguía
     únicamente por su relleno #F7F9F6 sobre la tarjeta blanca — 1.06:1,
     prácticamente invisible.
     --placeholder cumple 1.4.3 (4.5:1); antes daba 2.07:1. */
  --field-border:  #9C8B7C;   /* 3.28:1 sobre blanco  ✓ 1.4.11 */
  --placeholder:   #75604E;   /* 5.60:1 sobre hueso   ✓ 1.4.3  */
  --focus-ring:      var(--c-crimson);   /*  6.00:1 sobre hueso    */
  --focus-ring-dark: var(--c-bone);      /* 18.19:1 sobre espresso */

  /* ── Tipografía ── */
  --f-script:  'Dancing Script', 'Segoe Script', cursive;
  --f-display: 'Josefin Sans', system-ui, sans-serif;
  --f-body:    'Nunito Sans', system-ui, sans-serif;
  --f-ui:      'Work Sans', system-ui, sans-serif;

  /* Escala fluida */
  --t-xs:   clamp(0.72rem, 0.68rem + 0.2vw, 0.79rem);
  --t-sm:   clamp(0.84rem, 0.8rem + 0.2vw, 0.92rem);
  --t-base: clamp(0.98rem, 0.94rem + 0.25vw, 1.08rem);
  --t-lg:   clamp(1.12rem, 1.05rem + 0.4vw, 1.3rem);
  --t-xl:   clamp(1.35rem, 1.2rem + 0.8vw, 1.85rem);
  --t-2xl:  clamp(1.8rem, 1.4rem + 1.8vw, 2.8rem);
  --t-3xl:  clamp(2.3rem, 1.7rem + 2.8vw, 4rem);
  --t-hero: clamp(2.6rem, 1.6rem + 5vw, 5.4rem);

  /* Espaciado */
  --s-1: 0.5rem;  --s-2: 1rem;    --s-3: 1.5rem;
  --s-4: 2.5rem;  --s-5: 4rem;    --s-6: 6rem;   --s-7: 8rem;

  /* Radios — suaves y redondeados, como una bola de gelato */
  --r-sm: 6px;  --r-md: 12px;  --r-lg: 20px;  --r-xl: 28px;  --r-pill: 999px;

  /* Sombras cálidas (tintadas en cacao, nunca gris neutro) */
  --sh-sm: 0 2px 8px rgba(30, 7, 11, 0.06);
  --sh-md: 0 10px 30px rgba(30, 7, 11, 0.10);
  --sh-lg: 0 24px 60px rgba(30, 7, 11, 0.16);

  /* Movimiento */
  --ease:      cubic-bezier(0.16, 1, 0.3, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --d-fast: 180ms;  --d-base: 320ms;  --d-slow: 620ms;
  --slide-duration: 900ms;

  /* Movimiento del menú.
     La apertura y el cierre son deliberadamente ASIMÉTRICOS: al abrir se
     usa una curva exponencial larga que decelera y "posa" el panel; al
     cerrar, una curva más recta y la mitad de tiempo. Abrir es un gesto
     que se contempla; cerrar es un gesto que se quiere resuelto ya. */
  --ease-menu-in:  cubic-bezier(0.22, 1, 0.36, 1);
  --ease-menu-out: cubic-bezier(0.62, 0, 0.35, 1);
  --d-menu-in:  620ms;
  --d-menu-out: 380ms;

  /* Layout */
  --wrap: 1220px;
  --header-h: 78px;
  --news-gap: 1.5rem;

  /* Punto de corte de la navegación.
     Fuente ÚNICA de verdad: main.js lo lee con getComputedStyle y construye
     su matchMedia a partir de aquí, de modo que CSS y JS no puedan
     desincronizarse al cambiar el valor. */
  --nav-bp: 860px;
}

/* ============================================================
   ESCALA DE PUNTOS DE CORTE
   ------------------------------------------------------------
   Seis, todos `min-width` (mobile-first estricto):

     380px   el CTA de la barra superior ya cabe junto al logo
     600px   dos columnas en rejillas de tarjetas
     660px   tres columnas en la rejilla del menú
     860px   la navegación pasa de panel a barra  (--nav-bp)
     920px   secciones a dos columnas: acerca, la casa, contacto
    1000px   rejillas al máximo de columnas

   Antes eran doce, con cinco cortes repartidos en apenas 80 px
   (580·600·620·640·660). Cada uno había nacido de un componente
   distinto sin mirar a los demás, de modo que al redimensionar la
   ventana el mismo salto visual ocurría cuatro veces seguidas.
   Menos cortes es además menos recálculo de estilos en cada resize.
============================================================ */

/* ============================================================
   BASE
============================================================ */
html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
  -webkit-text-size-adjust: 100%;

  /* ── Estabilidad del eje X ─────────────────────────────────
     `scrollbar-gutter: stable` reserva el hueco de la barra de scroll
     de forma permanente. Sin esto, cada vez que se bloquea el scroll
     —al abrir el menú y, sobre todo, al terminar el preloader— la barra
     desaparece y TODO el documento salta hacia la derecha el ancho de
     esa barra. Ese es el movimiento en el eje X que se percibía en
     cada carga de la página.

     `overflow-x: clip` en lugar de `hidden`: recorta el desbordamiento
     igual, pero no crea un contenedor de scroll, así que no rompe
     `position: sticky` ni genera un eje desplazable fantasma. Se
     declara en html Y en body porque el desbordamiento de body se
     propaga al viewport y dejarlo solo en uno de los dos no contiene
     de verdad. */
  scrollbar-gutter: stable;
  overflow-x: clip;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--f-body);
  font-size: var(--t-base);
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  /* Ninguna palabra larga puede ensanchar su contenedor y arrastrar el
     documento entero. Es la causa más común de desbordamiento lateral
     en pantallas de 320 px. */
  overflow-wrap: break-word;
}

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

/* Cada foto va envuelta en <picture> para ofrecer WebP con respaldo JPG.
   `display: contents` hace que el envoltorio desaparezca de la
   maquetación: la <img> sigue siendo, a todos los efectos, hija directa
   de la tarjeta, y las reglas de tamaño escritas para ella siguen
   valiendo sin tocarlas. */
picture { display: contents; }

/* Fundido de entrada de las fotos (lo activa ImageFade en main.js).
   El fondo crema ocupa el lugar de la foto mientras llega, de modo que
   la tarjeta nunca se ve como un recuadro blanco vacío. */
picture > img {
  background-color: var(--c-cream);
  opacity: 0;
  transition: opacity var(--d-slow) var(--ease-soft);
}
picture > img.is-loaded { opacity: 1; }

/* Sin JavaScript nadie añadirá `is-loaded`: las fotos deben verse igual. */
.no-js picture > img { opacity: 1; }
a   { color: inherit; text-decoration: none; }
ul[role="list"] { list-style: none; }
strong { font-weight: 600; }

/* ── REFINAMIENTO TIPOGRÁFICO ───────────────────────────────
   Detalles que no se ven de forma consciente pero que separan un
   sitio correcto de uno cuidado. */

/* `balance` reparte las palabras entre las líneas de un titular para
   evitar la línea huérfana de una sola palabra; `pretty` hace lo
   propio con el último renglón de cada párrafo. Los navegadores sin
   soporte simplemente ignoran la declaración. */
h1, h2, h3, h4,
.section__title,
.slide__title,
.form__title { text-wrap: balance; }

p, .lead, .section__sub { text-wrap: pretty; }


/* La escala óptica ajusta el grosor del trazo al tamaño de uso en las
   fuentes que la exponen: el display no se ve anémico ni el cuerpo
   emborronado. */
html { font-optical-sizing: auto; }

/* Selección de texto en color de marca en lugar del azul del sistema. */
::selection { background: var(--c-crimson); color: #fff; }  /* 6.35:1 ✓ */

/* Las citas y comillas cuelgan del margen para que el borde del bloque
   se lea ópticamente recto. */
blockquote, .lead { hanging-punctuation: first last; }

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Sobre las superficies espresso el carmín solo alcanza 3.03:1 contra el
   fondo, insuficiente para un indicador de foco fiable (WCAG 2.4.11 y
   1.4.11). En esos contextos el anillo se invierte a hueso: 18.19:1. */
.casa :focus-visible,
.footer :focus-visible,
.hero :focus-visible,
.marquee :focus-visible {
  outline-color: var(--focus-ring-dark);
}

/* ── Utilidades ── */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; top: -100%; left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  background: var(--c-crimson);
  color: #fff;
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  padding: 0.8rem 1.6rem;
  border-radius: var(--r-pill);
  box-shadow: var(--sh-md);
  transition: top var(--d-fast);
}
.skip-link:focus { top: 1rem; }

.container {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(1.1rem, 5vw, 2.5rem);
}

.anchor-alias { display: block; height: 0; scroll-margin-top: var(--header-h); }


/* ============================================================
   LOGOTIPO
   Activo de marca real (PNG de 640×165 con paleta indexada, 24 KB:
   no penaliza el LCP).
============================================================ */
.brand {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  /* La altura se fija aquí y el ancho se deduce de la proporción del
     archivo (3.88:1), así el logotipo nunca se deforma. */
  height: clamp(30px, 7vw, 40px);
}

.brand__logo {
  height: 100%;
  width: auto;
  transition: opacity var(--d-base) var(--ease-soft), scale var(--d-base) var(--ease);
}
.brand:hover .brand__logo { opacity: 0.82; scale: 1.02; }

/* En el pie se usa la variante en crema y oro. El carmín original
   sobre espresso solo alcanza 3.03:1 y se lee turbio. */
.brand--footer { height: clamp(34px, 9vw, 46px); }

.brand__tagline {
  display: block;
  margin-top: 0.55rem;
  font-family: var(--f-ui);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--c-gold);
}


/* ============================================================
   BOTÓN DE MENÚ (hamburguesa)
   ------------------------------------------------------------
   ⚠️ Estas reglas se perdieron en el refactor mobile-first del nav:
   el bloque quedó dentro del rango de líneas sustituido y no se
   reinsertó. Sin ellas el <button> se pintaba con los estilos por
   defecto del navegador y los tres <span> quedaban como elementos
   inline vacíos, de dimensión cero — de ahí el «punto» en lugar del
   icono. El clic seguía funcionando porque solo se perdió la
   apariencia, nunca el elemento ni su listener.
============================================================ */
.hamburger {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 48px;                 /* área táctil ≥44×44 — WCAG 2.5.5 */
  height: 48px;
  padding: 0;
  background: none;
  border: none;
  border-radius: var(--r-sm);
  cursor: pointer;
  touch-action: manipulation;  /* elimina el retardo de 300 ms al tocar */
  flex-shrink: 0;
}

.hamburger__bar {
  display: block;
  width: 25px;
  height: 2px;
  /* `flex-shrink: 0` es imprescindible: en un contenedor flex en
     columna las barras son elementos del eje principal y, sin él, sus
     2 px de alto pueden colapsar a cero al comprimirse el botón. */
  flex-shrink: 0;
  background: var(--c-crimson);
  border-radius: var(--r-pill);
  transform-origin: center;
  transition:
    transform 420ms var(--ease-menu-in),
    opacity 200ms var(--ease-soft);
}

/* Transformación a "✕" en dos tiempos: primero se retira la barra
   central, después giran las exteriores. Hacerlo simultáneo produce un
   cruce visual confuso; escalonarlo 90 ms lo convierte en un gesto
   legible. Al cerrar, el orden se invierte. */
.hamburger__bar:nth-child(2) { transition-delay: 160ms; }

.hamburger.is-open .hamburger__bar:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
  transition-delay: 0ms;
}
.hamburger.is-open .hamburger__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
  transition-delay: 90ms;
}
.hamburger.is-open .hamburger__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
  transition-delay: 90ms;
}


/* ============================================================
   BOTONES
============================================================ */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--text);
  --btn-bd: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.9rem 1.9rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1.5px solid var(--btn-bd);
  border-radius: var(--r-pill);
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  transition:
    background var(--d-base) var(--ease-soft),
    color var(--d-base) var(--ease-soft),
    border-color var(--d-base) var(--ease-soft),
    transform var(--d-fast) var(--ease),
    box-shadow var(--d-base);
}
.btn:active { transform: scale(0.97); }

/* Primario: carmín sólido — blanco sobre carmín = 6.35:1 ✓ AA */
.btn--primary { --btn-bg: var(--c-crimson); --btn-fg: #fff; --btn-bd: var(--c-crimson); }
.btn--primary:hover {
  --btn-bg: var(--c-crimson-dark);
  --btn-bd: var(--c-crimson-dark);
  box-shadow: 0 8px 22px rgba(178, 42, 68, 0.3);
}

/* Oro: texto espresso sobre oro = 6.42:1 ✓ AA
   (texto blanco sobre oro daría 3.0:1 y no pasaría) */
.btn--gold { --btn-bg: var(--c-gold); --btn-fg: var(--c-espresso); --btn-bd: var(--c-gold); }
.btn--gold:hover { --btn-bg: #a97e26; --btn-bd: #a97e26; box-shadow: 0 8px 22px rgba(186, 142, 48, 0.3); }

.btn--outline { --btn-fg: #fff; --btn-bd: rgba(255,255,255,0.55); }
.btn--outline:hover { --btn-bg: #fff; --btn-fg: var(--c-espresso); --btn-bd: #fff; }

.btn--ghost {
  --btn-bg: rgba(255,255,255,0.92);
  --btn-fg: var(--c-crimson);
  --btn-bd: rgba(255,255,255,0.92);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.btn--ghost:hover { --btn-bg: var(--c-crimson); --btn-fg: #fff; --btn-bd: var(--c-crimson); }

.btn--sm   { padding: 0.62rem 1.3rem; font-size: var(--t-xs); }
.btn--full { width: 100%; }

.btn__spinner {
  position: absolute;
  display: none;
  width: 17px; height: 17px;
  border: 2px solid rgba(255,255,255,0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.62s linear infinite;
}
.btn.is-loading .btn__label   { opacity: 0; }
.btn.is-loading .btn__spinner { display: block; }

/* Enlace con flecha animada */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-crimson);
}
.link-arrow::after {
  content: '→';
  transition: transform var(--d-base) var(--ease);
}
.link-arrow:hover { color: var(--c-crimson-dark); }
.link-arrow:hover::after { transform: translateX(5px); }


/* ============================================================
   TIPOGRAFÍA DE SECCIÓN
============================================================ */
.section { padding-block: clamp(3.5rem, 9vw, var(--s-7)); position: relative; }

.section__header { text-align: center; margin-bottom: var(--s-5); }

/* Eyebrow en Dancing Script: la floritura de la marca aplicada
   con moderación, solo como etiqueta corta. */
.eyebrow {
  display: inline-block;
  font-family: var(--f-script);
  font-weight: 700;
  font-size: clamp(1.15rem, 2.4vw, 1.5rem);
  color: var(--c-gold-text);
  line-height: 1;
  margin-bottom: 0.35rem;
}
.eyebrow--light { color: var(--c-gold); }

.section__title {
  font-family: var(--f-display);
  font-size: var(--t-3xl);
  font-weight: 200;
  line-height: 1.08;
  letter-spacing: -0.015em;
  color: var(--text);
}
.section__title em {
  font-style: normal;
  font-weight: 600;
  color: var(--c-crimson);
}
.section__title--light { color: var(--c-bone); }
.section__title--light em { color: var(--c-gold); }

/* Filete decorativo bajo los títulos centrados: eco del aro dorado */
.section__header .section__title::after {
  content: '';
  display: block;
  width: 62px; height: 1.5px;
  margin: 1.1rem auto 0;
  background: linear-gradient(90deg, transparent, var(--c-gold), transparent);
}

.section__sub {
  margin-top: 0.9rem;
  max-width: 46ch;
  margin-inline: auto;
  color: var(--text-soft);
}

.lead { font-size: var(--t-lg); color: var(--text-soft); line-height: 1.65; }

/* Cierre comercial de sección. Un solo botón centrado, separado por
   aire generoso: resuelve la función publicitaria sin repetir un CTA
   en cada tarjeta, que es lo que rompería el equilibrio minimalista. */
.section__cta {
  display: flex;
  justify-content: center;
  margin-top: clamp(2rem, 5vw, 3.25rem);
}


/* ============================================================
   REVEAL ON SCROLL
============================================================ */
[data-reveal] {
  opacity: 0;
  transition: opacity var(--d-slow) var(--ease), transform var(--d-slow) var(--ease);
}
[data-reveal="left"]  { transform: translateX(-42px); }
[data-reveal="right"] { transform: translateX(42px); }
[data-reveal="up"]    { transform: translateY(44px); }
[data-reveal].is-visible { opacity: 1; transform: none; }


/* ============================================================
   HEADER
============================================================ */
/* ⚠️ El header NO debe declarar backdrop-filter, filter, transform ni
   perspective. Cualquiera de esas propiedades lo convertiría en el bloque
   contenedor de sus descendientes `position: fixed`, y el panel del menú
   móvil dejaría de anclarse al viewport para anclarse a los 78 px del
   header — que es justamente el bug que se estaba corrigiendo.
   El desenfoque se traslada a una capa propia (::before) que no tiene
   descendientes, así que su bloque contenedor no afecta a nadie. */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 900;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: transparent;
  transition: box-shadow var(--d-slow);
}

.header::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(247, 249, 246, 0.72);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  transition: background var(--d-slow);
}

.header.is-scrolled { box-shadow: 0 1px 0 var(--line), var(--sh-sm); }
.header.is-scrolled::before { background: rgba(247, 249, 246, 0.97); }

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
}
/* ── NAVEGACIÓN · MOBILE-FIRST ──────────────────────────────
   El panel a pantalla completa es el estado BASE, no una excepción
   declarada con `max-width`. La barra horizontal de escritorio es la
   mejora progresiva que se añade a partir de --nav-bp.

   Antes ocurría al revés: el móvil cargaba primero las reglas de
   escritorio y después las sobrescribía todas, que es justo lo que la
   metodología mobile-first busca evitar — el dispositivo más limitado
   pagaba el coste de estilos que nunca llegaba a usar.

   El panel se ancla al viewport gracias a que .header ya no declara
   backdrop-filter. Ver la nota en la regla .header.                  */
.nav {
  display: flex;
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;

  /* Altura explícita en lugar de `bottom: 0`.
     100dvh sigue a la barra de URL de iOS/Android al contraerse y
     expandirse; 100vh queda como reserva para navegadores antiguos. */
  height: calc(100vh - var(--header-h));
  height: calc(100dvh - var(--header-h));

  flex-direction: column;
  align-items: center;

  /* `safe center` centra el contenido pero, cuando este no cabe, deja
     de centrarlo y lo alinea al inicio. Con `center` a secas el
     desbordamiento se produce hacia arriba y esos enlaces quedan
     fuera del alcance del scroll de forma permanente. */
  justify-content: center;
  justify-content: safe center;

  gap: clamp(1.25rem, 4vh, 2.2rem);
  padding: clamp(1.5rem, 5vh, 3rem) 1.25rem;
  padding-bottom: calc(clamp(1.5rem, 5vh, 3rem) + env(safe-area-inset-bottom, 0px));

  background: var(--c-bone);

  /* Red de seguridad: si aun así no cabe (móvil apaisado, o texto
     ampliado al 200 % según WCAG 1.4.4), el panel se desplaza por
     dentro sin arrastrar la página. */
  overflow-y: auto;
  overscroll-behavior: contain;

  transform: translateY(-100%);
  visibility: hidden;
  z-index: 10;

  /* `visibility` se conmuta de golpe, no de forma progresiva:
     al abrir es inmediata (0 s) y al cerrar espera a que termine el
     deslizamiento. Así los enlaces salen del orden de tabulación en
     el instante correcto, sin quedar enfocables mientras se ocultan. */
  transition:
    transform var(--d-menu-out) var(--ease-menu-out),
    visibility 0s linear var(--d-menu-out);
}

.nav.is-open {
  transform: translateY(0);
  visibility: visible;
  transition:
    transform var(--d-menu-in) var(--ease-menu-in),
    visibility 0s linear 0s;
}

/* ── Capa 1 · Filigrana de marca ──────────────────────────
   El logomark real, ampliado como marca de agua tras el menú.
   Sustituye a los dos aros que antes se dibujaban con CSS: aquellos
   eran una reconstrucción aproximada; este es el activo auténtico,
   con la "B" incluida y la desalineación exacta entre los dos aros.

   Opacidad al 9 %: los aros de CSS eran un trazo de 1.5 px y admitían
   un 40 %, pero esta versión trae la letra en carmín macizo. Al mismo
   valor competiría con el texto del menú en vez de acompañarlo. */
.nav::before {
  content: '';
  position: absolute;
  top: 42%;
  left: 50%;
  width: min(82vw, 440px);
  aspect-ratio: 1;
  background: url('../assets/logo/bennoni-logomark.png') center / contain no-repeat;
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  translate: -50% -50%;
  scale: 0.72;
  rotate: -14deg;
  transition:
    opacity var(--d-menu-out) var(--ease-menu-out),
    scale var(--d-menu-out) var(--ease-menu-out),
    rotate var(--d-menu-out) var(--ease-menu-out);
}

.nav.is-open::before {
  opacity: 0.09;
  scale: 1;
  rotate: 0deg;
  transition:
    opacity 900ms 200ms var(--ease-menu-in),
    scale 1200ms 200ms var(--ease-menu-in),
    rotate 1200ms 200ms var(--ease-menu-in);
}

.nav__list {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  width: 100%;
  list-style: none;
}

.nav__link {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;              /* área táctil cómoda (WCAG 2.5.5) */
  font-family: var(--f-display);
  font-size: var(--t-xl);
  font-weight: 300;
  letter-spacing: 0.01em;
  padding: 0.6rem 2rem;
  color: var(--text);
  transition: color var(--d-base) var(--ease-soft), letter-spacing var(--d-base) var(--ease);
}
.nav__link:hover,
.nav__link:active { color: var(--c-crimson); letter-spacing: 0.05em; }

/* Rombo dorado como marcador de sección activa — el mismo signo que
   ya usan la cinta de marca y la lista de la sección de café.
   La sección actual NO se señala solo con color (WCAG 1.4.1): hay
   además cambio de peso tipográfico y este marcador de forma. */
.nav__link::before {
  content: '◈';
  position: absolute;
  left: 0.4rem;
  font-size: 0.55em;
  color: var(--c-gold-text);
  opacity: 0;
  translate: -8px 0;
  transition: opacity var(--d-base) var(--ease), translate var(--d-base) var(--ease);
}
.nav__link[aria-current="page"] {
  color: var(--c-crimson);
  font-weight: 600;
}
.nav__link[aria-current="page"]::before { opacity: 1; translate: 0 0; }

.nav__cta {
  display: inline-flex;
  min-height: 48px;
  flex-shrink: 0;
}

/* ── Capa 2 · Entrada escalonada de los enlaces ───────────
   Cada elemento asciende y se revela 55 ms después del anterior,
   mientras el panel todavía está posándose. Ese solape es lo que
   produce la sensación de flujo: el contenido no espera a que el
   contenedor termine, lo acompaña.
   Solo `opacity` y `translate` → trabajo del compositor, sin layout. */
.nav__list li,
.nav__cta {
  opacity: 0;
  translate: 0 26px;
}

.nav__list li {
  transition:
    opacity var(--d-menu-out) var(--ease-menu-out),
    translate var(--d-menu-out) var(--ease-menu-out);
}

.nav__cta {
  /* Se listan también las propiedades del botón para que el hover
     siga animándose con normalidad una vez el panel está abierto. */
  transition:
    opacity var(--d-menu-out) var(--ease-menu-out),
    translate var(--d-menu-out) var(--ease-menu-out),
    background var(--d-base) var(--ease-soft),
    border-color var(--d-base) var(--ease-soft),
    color var(--d-base) var(--ease-soft);
}

.nav.is-open .nav__list li,
.nav.is-open .nav__cta {
  opacity: 1;
  translate: 0 0;
  transition-duration: 520ms;
  transition-timing-function: var(--ease-menu-in);
}

.nav.is-open .nav__list li:nth-child(1) { transition-delay: 150ms; }
.nav.is-open .nav__list li:nth-child(2) { transition-delay: 205ms; }
.nav.is-open .nav__list li:nth-child(3) { transition-delay: 260ms; }
.nav.is-open .nav__list li:nth-child(4) { transition-delay: 315ms; }
.nav.is-open .nav__list li:nth-child(5) { transition-delay: 370ms; }
.nav.is-open .nav__cta                  { transition-delay: 440ms; }

/* Al cerrar todos los retardos vuelven a cero: el contenido se
   desvanece en bloque y de inmediato. Escalonar también la salida
   alargaría el cierre y lo haría sentir pesado. */

.header__actions { display: flex; align-items: center; gap: 0.75rem; }

/* CTA de la barra superior — visibilidad progresiva.
   Antes estaba oculto por completo en móvil y la única vía para
   ordenar quedaba enterrada dentro del menú hamburguesa: el usuario
   tenía que abrir el menú para descubrir cómo comprar.
   Ahora aparece en cuanto hay sitio, primero abreviado. */
.header__cta { display: none; }
.header__cta-long { display: none; }

/* A partir de 380 px cabe la versión corta junto al logo y el botón
   de menú sin apretar ninguno de los tres. */
@media (min-width: 380px) {
  .header__cta { display: inline-flex; }
}


/* ── Viewports bajos: móvil apaisado o ventana reducida ──── */
@media (max-height: 560px) {
  .nav {
    justify-content: flex-start;
    justify-content: safe flex-start;
    gap: 0.75rem;
  }
  .nav__link { font-size: var(--t-lg); min-height: 44px; padding-block: 0.45rem; }
  .nav__cta  { min-height: 44px; }

  /* La filigrana estorba cuando el alto es escaso: se retira y se
     acorta el escalonado para que el menú esté listo antes. */
  .nav::before { display: none; }

  .nav.is-open .nav__list li:nth-child(1) { transition-delay: 100ms; }
  .nav.is-open .nav__list li:nth-child(2) { transition-delay: 140ms; }
  .nav.is-open .nav__list li:nth-child(3) { transition-delay: 180ms; }
  .nav.is-open .nav__list li:nth-child(4) { transition-delay: 220ms; }
  .nav.is-open .nav__list li:nth-child(5) { transition-delay: 260ms; }
  .nav.is-open .nav__cta                  { transition-delay: 310ms; }
}


/* ── Escritorio: la barra horizontal ────────────────────────
   Mejora progresiva a partir de --nav-bp. Aquí se deshace el panel
   y se recupera el flujo normal del documento. */
@media (min-width: 860px) {
  .nav {
    position: static;
    height: auto;
    flex: 1;
    flex-direction: row;
    justify-content: center;
    gap: 0;
    padding: 0;
    background: none;
    overflow: visible;
    transform: none;
    visibility: visible;
    transition: none;
    z-index: auto;
  }

  /* La filigrana y el panel escalonado no existen en escritorio */
  .nav::before { display: none; }

  .nav__list li,
  .nav__cta {
    opacity: 1;
    translate: none;
    transition-delay: 0ms;
  }

  .nav__list { flex-direction: row; gap: 0.15rem; width: auto; }

  .nav__link {
    display: block;
    min-height: 0;
    font-family: var(--f-ui);
    font-size: var(--t-sm);
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 0.5rem 1rem;
    color: var(--text-soft);
    transition: color var(--d-fast);
  }
  .nav__link:hover,
  .nav__link:active { letter-spacing: 0.03em; }
  .nav__link::before { display: none; }

  /* Subrayado dorado que crece desde el centro */
  .nav__link::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 0.15rem;
    width: 0;
    height: 1.5px;
    background: var(--c-gold);
    transform: translateX(-50%);
    transition: width var(--d-base) var(--ease);
  }
  .nav__link:hover { color: var(--c-crimson); }
  .nav__link:hover::after,
  .nav__link[aria-current="page"]::after { width: calc(100% - 2rem); }

  .nav__cta { display: none; }
  .header__cta { display: inline-flex; }
  .header__cta-long { display: inline; }
  .hamburger { display: none; }
}

/* ── Bloqueo de scroll con el menú abierto ──────────────────
   `overflow: hidden` sobre <body> no detiene el scroll en iOS Safari.
   El patrón fiable es fijar el body y compensar el desplazamiento
   guardado, que main.js restaura al cerrar. */
.is-nav-open,
.is-nav-open body { overflow: hidden; }

.is-nav-open body {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
}


/* ============================================================
   HERO SLIDER
============================================================ */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 600px;
  max-height: 940px;
  overflow: hidden;
  background: var(--c-espresso);
}

.slider { position: absolute; inset: 0; }

.slide {
  position: absolute;
  inset: 0;
  display: grid;
  align-items: end;
  padding-bottom: clamp(6rem, 16vh, 10rem);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: scale(1.03);
  transition:
    opacity var(--slide-duration) var(--ease),
    transform var(--slide-duration) var(--ease),
    visibility var(--slide-duration);
}
.slide.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: scale(1);
  z-index: 2;
}
.slide.is-exiting { opacity: 0; visibility: visible; transform: scale(0.98); z-index: 1; }

/* La imagen se extiende por debajo para dar recorrido al parallax */
.slide__bg {
  position: absolute;
  inset: -12% 0;
  background-color: var(--c-cocoa);
  background-size: cover;
  background-position: center;
}

/* Velo doble: oscurece por abajo y tinta ligeramente de espresso.
   Garantiza contraste del texto sobre cualquier fotografía. */
.slide__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(30,7,11,0.93) 0%, rgba(30,7,11,0.6) 38%, rgba(30,7,11,0.18) 72%, rgba(30,7,11,0.32) 100%),
    linear-gradient(105deg, rgba(30,7,11,0.5) 0%, transparent 62%);
}

.slide__content { position: relative; z-index: 3; max-width: 700px; }

.slide__badge,
.slide__title,
.slide__text,
.slide__actions { opacity: 0; }

.slide.is-active .slide__badge   { animation: riseIn 0.65s 0.15s var(--ease) forwards; }
.slide.is-active .slide__title   { animation: riseIn 0.75s 0.30s var(--ease) forwards; }
.slide.is-active .slide__text    { animation: riseIn 0.65s 0.46s var(--ease) forwards; }
.slide.is-active .slide__actions { animation: riseIn 0.6s  0.60s var(--ease) forwards; }

.slide__badge {
  display: inline-block;
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--c-cream);
  padding: 0.4rem 1rem;
  border: 1px solid var(--line-gold);
  border-radius: var(--r-pill);
  background: rgba(30, 7, 11, 0.35);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  margin-bottom: 1.3rem;
}

.slide__title {
  font-family: var(--f-display);
  font-size: var(--t-hero);
  font-weight: 200;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: #fff;
  margin-bottom: 1.1rem;
}
.slide__title em {
  display: block;
  font-family: var(--f-script);
  font-style: normal;
  font-weight: 700;
  color: var(--c-gold);
  /* El script necesita algo más de aire por sus ascendentes */
  line-height: 1.15;
  margin-top: 0.1em;
}

.slide__text {
  font-size: var(--t-lg);
  color: rgba(247, 249, 246, 0.9);
  max-width: 44ch;
  margin-bottom: 2rem;
}

.slide__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ── Controles ── */
.slider__controls {
  position: absolute;
  left: 0; right: 0;
  bottom: 2.2rem;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.slider__btn {
  width: 44px; height: 44px;               /* WCAG 2.5.5: mínimo 44×44 */
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* 4.6:1 contra la escena oscura — supera el 3:1 que exige 1.4.11 para
     el límite de un control de interfaz. */
  border: 1px solid rgba(247, 249, 246, 0.55);
  background: rgba(30, 7, 11, 0.42);
  color: #fff;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  transition: background var(--d-base), border-color var(--d-base), color var(--d-base), transform var(--d-fast);
}
.slider__btn:hover {
  background: var(--c-crimson);
  border-color: var(--c-crimson);
  transform: scale(1.09);
}

.slider__btn--toggle { margin-left: auto; }
.slider__btn--toggle .icon-play { display: none; }
.slider__btn--toggle[aria-pressed="true"] .icon-pause { display: none; }
.slider__btn--toggle[aria-pressed="true"] .icon-play  { display: block; }

.slider__dots { display: flex; align-items: center; gap: 2px; }

/* Objetivo táctil de 24×24 (WCAG 2.5.8) con el punto visible a 7 px.
   El área se amplía con relleno transparente en lugar de engordar el
   indicador: la estética minimalista se conserva y el dedo acierta.
   Es la misma solución que usan los puntos del carrusel de noticias;
   aquí faltaba por propagar. */
.slider-dot {
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  touch-action: manipulation;
}
.slider-dot::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: rgba(247, 249, 246, 0.55);   /* 5.1:1 sobre la escena ✓ */
  transition: background var(--d-base), width var(--d-base) var(--ease);
}
.slider-dot:hover::before { background: rgba(247, 249, 246, 0.85); }

/* El activo se alarga además de cambiar de color: el estado no se
   comunica solo con el tono (WCAG 1.4.1). */
.slider-dot[aria-current="true"] { width: 44px; }
.slider-dot[aria-current="true"]::before {
  width: 30px;
  background: var(--c-gold);
}

.slider__progress {
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: rgba(247, 249, 246, 0.14);
  z-index: 10;
}
.slider__progress-bar {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--c-crimson), var(--c-gold));
}


/* ============================================================
   CINTA DE MARCA (marquee)
============================================================ */
.marquee {
  background: var(--c-espresso);
  color: var(--c-cream);
  padding-block: 0.9rem;
  overflow: hidden;
  border-block: 1px solid rgba(186, 142, 48, 0.25);
}
.marquee__track {
  display: flex;
  align-items: center;
  gap: 2.2rem;
  width: max-content;
  animation: marquee 34s linear infinite;
}
.marquee__track span {
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  white-space: nowrap;
}
.marquee__track .marquee__dot { color: var(--c-gold); letter-spacing: 0; }


/* ============================================================
   ACERCA
============================================================ */
.about__grid { display: grid; gap: var(--s-5); align-items: center; }
@media (min-width: 920px) { .about__grid { grid-template-columns: 0.95fr 1.05fr; gap: var(--s-6); } }

.about__media { position: relative; }

/* Marco con el doble filete dorado desplazado: el mismo recurso
   gráfico de los aros del logotipo, llevado al rectángulo. */
.about__frame {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  aspect-ratio: 4/5;
  box-shadow: var(--sh-lg);
}
/* El marco dorado desplazado sobresale del bloque de imagen. En móvil
   ese saliente medía exactamente lo mismo que el padding del contenedor
   (1.1rem por debajo de 352 px), así que su borde de 1.5 px caía justo
   fuera del viewport y abría scroll horizontal. Por debajo del punto en
   que el padding crece, el marco no sale. */
.about__media::before {
  content: '';
  position: absolute;
  inset: 1.1rem 0 -1.1rem 1.1rem;
  border: 1.5px solid var(--c-gold);
  border-radius: var(--r-xl);
  z-index: -1;
}
@media (min-width: 600px) {
  .about__media::before { inset: 1.1rem -1.1rem -1.1rem 1.1rem; }
}
.about__frame img { width: 100%; height: 112%; object-fit: cover; }


.about__copy > p { color: var(--text-soft); margin-bottom: 1rem; }
.about__copy .lead { margin-block: 1.4rem; color: var(--text); }
.about__copy .section__title { margin-top: 0.2rem; }



/* Los tres ejes de significado del manual de marca, presentados como
   promesa al cliente. Sustituyen a las estadísticas numéricas que
   había antes ("62 años de oficio"), que eran inventadas. */
.about__pillars {
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  margin-block: 2rem;
  padding-block: 1.6rem;
  border-block: 1px solid var(--line);
  list-style: none;
}
.about__pillars li { display: flex; flex-direction: column; gap: 0.15rem; }
.about__pillars strong {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  font-weight: 600;
  color: var(--c-crimson);
}
.about__pillars span { font-size: var(--t-sm); color: var(--text-soft); }


/* ============================================================
   NOTICIAS
============================================================ */
.news { background: var(--bg-alt); }

.news-wrap { position: relative; }

.news-track {
  display: flex;
  gap: var(--news-gap);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: clamp(1.1rem, 5vw, 2.5rem);
  padding-inline: clamp(1.1rem, 5vw, 2.5rem);
  padding-block: 0.5rem 1.75rem;
  cursor: grab;
  list-style: none;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.news-track::-webkit-scrollbar { display: none; }
.news-track.is-grabbing { cursor: grabbing; scroll-snap-type: none; }

.news-card {
  flex: 0 0 clamp(272px, 78vw, 348px);
  scroll-snap-align: start;
}
.news-card article {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-sm);
  transition: transform var(--d-base) var(--ease), box-shadow var(--d-base);
}
.news-card:hover article { transform: translateY(-7px); box-shadow: var(--sh-lg); }

.news-card__media { position: relative; aspect-ratio: 3/2; overflow: hidden; }
.news-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease); }
.news-card:hover .news-card__media img { transform: scale(1.07); }

.news-card__tag {
  position: absolute;
  top: 0.85rem; left: 0.85rem;
  font-family: var(--f-ui);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;
  background: var(--c-crimson);
  padding: 0.3rem 0.75rem;
  border-radius: var(--r-pill);
}

.news-card__body { padding: 1.4rem; display: flex; flex-direction: column; flex: 1; }
.news-card__body h3 {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 0.5rem;
}
.news-card__body p { font-size: var(--t-sm); color: var(--text-soft); margin-bottom: 1rem; flex: 1; }

/* Botones del carrusel */
.carousel-btn {
  position: absolute;
  top: 33%;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--c-crimson);
  cursor: pointer;
  z-index: 5;
  box-shadow: var(--sh-md);
  transition: background var(--d-base), color var(--d-base), transform var(--d-fast), opacity var(--d-base);
}
.carousel-btn:hover { background: var(--c-crimson); color: #fff; transform: scale(1.1); }
.carousel-btn[disabled] { opacity: 0.28; pointer-events: none; }
.carousel-btn--prev { left: 0.4rem; }
.carousel-btn--next { right: 0.4rem; }

/* ── Indicadores de posición del carrusel ───────────────────
   Las flechas dicen "hay más"; los puntos dicen "cuánto más y dónde
   estás". Sin ellos el carrusel no comunica su extensión, y en móvil
   —donde el gesto es deslizar y las flechas pesan menos— eran la
   única referencia que faltaba. */
.news-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  margin-top: 0.4rem;
}

.news-dot {
  /* El área táctil es de 24×24 (WCAG 2.5.8) aunque el punto visible
     mida 8: el objetivo se amplía con padding transparente en lugar
     de engordar el indicador y romper la estética minimalista. */
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  touch-action: manipulation;
}
.news-dot::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  /* 3.30:1 sobre crema ✓ WCAG 1.4.11. Al 0.28 anterior daban 1.53:1 y
     eran imperceptibles: el usuario no llegaba a saber cuántas noticias
     había, que es justo lo que estos puntos existen para comunicar.
     El alfa mínimo sobre crema es 0.64; se usa 0.66 con margen. */
  background: rgba(92, 71, 54, 0.66);
  transition: background var(--d-base), width var(--d-base) var(--ease);
}
.news-dot:hover::before { background: rgba(92, 71, 54, 0.82); }

/* El activo se alarga además de cambiar de color: la posición no se
   comunica solo con el tono (WCAG 1.4.1). */
.news-dot[aria-current="true"] { width: 40px; }
.news-dot[aria-current="true"]::before {
  width: 26px;
  background: var(--c-crimson);
}


/* ============================================================
   MENÚ — rejilla tipo Pinterest
============================================================ */
.hl-grid {
  display: grid;
  /* `dense` permite al navegador rellenar un hueco con una tarjeta
     posterior más pequeña. Sin esto, la tarjeta ancha de Carnes —que
     necesita dos columnas— salta de fila cuando solo queda una libre y
     deja un agujero: uno en 2 columnas y otro en 3. En 4 columnas la
     rejilla ya encaja sola y esta regla no cambia nada.
     El precio es que el orden visual puede adelantar una tarjeta
     respecto al orden del código; como cada una se lee por sí sola, no
     afecta a la comprensión ni al recorrido con teclado. */
  grid-auto-flow: row dense;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 210px;
  gap: 0.9rem;
  list-style: none;
}
@media (min-width: 660px) { .hl-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 250px; gap: 1.1rem; } }
@media (min-width: 1000px) { .hl-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 285px; } }

.hl-card { position: relative; }
.hl-card article {
  position: relative;
  height: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-sm);
}
.hl-card--tall { grid-row: span 2; }
.hl-card--wide { grid-column: span 2; }

.hl-card img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.85s var(--ease); }
.hl-card:hover img { transform: scale(1.08); }

.hl-card__body {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.35rem;
  padding: 1.15rem;
  color: #fff;
  background: linear-gradient(to top, rgba(30,7,11,0.94) 0%, rgba(30,7,11,0.55) 45%, rgba(30,7,11,0.05) 100%);
  transition: background var(--d-slow);
}

.hl-card__cat {
  font-family: var(--f-ui);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--c-gold);
}
.hl-card__body h3 {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.2;
}
.hl-card__body p {
  font-size: var(--t-xs);
  color: rgba(247, 249, 246, 0.85);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hl-card__body .btn { align-self: flex-start; margin-top: 0.4rem; }

/* En dispositivos con hover real, descripción y CTA se revelan al pasar
   el cursor. En táctil quedan SIEMPRE visibles: nunca se ocultan tras
   una interacción que ese dispositivo no puede producir. */
@media (hover: hover) and (pointer: fine) {
  .hl-card__body p {
    max-height: 0;
    opacity: 0;
    transition: max-height var(--d-slow) var(--ease), opacity var(--d-base);
  }
  .hl-card__body .btn {
    opacity: 0;
    transform: translateY(9px);
    transition: opacity var(--d-base) 80ms, transform var(--d-base) 80ms,
                background var(--d-base), color var(--d-base), border-color var(--d-base);
  }
  .hl-card:hover .hl-card__body p,
  .hl-card:focus-within .hl-card__body p { max-height: 5rem; opacity: 1; }

  .hl-card:hover .hl-card__body .btn,
  .hl-card:focus-within .hl-card__body .btn { opacity: 1; transform: none; }

  .hl-card:hover .hl-card__body,
  .hl-card:focus-within .hl-card__body {
    background: linear-gradient(to top, rgba(30,7,11,0.97) 0%, rgba(30,7,11,0.72) 55%, rgba(30,7,11,0.25) 100%);
  }
}


/* ============================================================
   FAVORITOS
============================================================ */
.favorites { background: var(--bg-alt); }

.fav-grid {
  display: grid;
  gap: clamp(1rem, 2.2vw, 1.6rem);
  list-style: none;
  grid-template-columns: 1fr;
}
@media (min-width: 600px)  { .fav-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .fav-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.fav {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--sh-sm);
  transition: transform var(--d-base) var(--ease), box-shadow var(--d-base), opacity var(--d-slow);
}
.fav:hover { transform: translateY(-6px); box-shadow: var(--sh-lg); }

.fav__rank {
  position: absolute;
  top: 0.85rem; left: 0.85rem;
  z-index: 2;
  width: 34px; height: 34px;
  display: grid;
  place-items: center;
  font-family: var(--f-display);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--c-crimson);
  background: rgba(247, 249, 246, 0.94);
  border-radius: 50%;
  box-shadow: var(--sh-sm);
}

.fav__media { aspect-ratio: 1; overflow: hidden; }
.fav__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease); }
.fav:hover .fav__media img { transform: scale(1.07); }

.fav__body { padding: 1.25rem; display: flex; flex-direction: column; flex: 1; }
.fav__body h3 {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 0.2rem;
}

.fav__body p { font-size: var(--t-sm); color: var(--text-soft); flex: 1; margin-bottom: 0.85rem; }



/* ============================================================
   LA CASA DE 1948 — bloque oscuro, el único de la página
============================================================ */
.casa {
  background: var(--c-espresso);
  color: var(--text-onDark);
  position: relative;
  overflow: hidden;
}
/* Halo dorado muy tenue para que el bloque no se lea plano */
.casa::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 55% at 78% 42%, rgba(186, 142, 48, 0.14), transparent 68%);
  pointer-events: none;
}

.casa__grid { position: relative; z-index: 1; display: grid; gap: var(--s-5); align-items: center; }
@media (min-width: 920px) { .casa__grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); } }

.casa__copy > p { color: rgba(229, 225, 214, 0.82); margin-bottom: 1rem; }

/* El párrafo de entrada sigue el mismo tratamiento que en Acerca —
   un escalón por encima del texto informativo— pero invertido para
   la superficie espresso. Hueso sobre espresso: 18.19:1. */
.casa__copy .lead { color: var(--c-bone); margin-bottom: 1.25rem; }
.casa__copy .section__title { margin-block: 0.2rem 1.5rem; }

.casa__list { display: flex; flex-direction: column; gap: 1.15rem; margin-block: 2rem; list-style: none; }
.casa__list li { display: flex; gap: 0.9rem; align-items: flex-start; }
.casa__icon { color: var(--c-gold); font-size: 1rem; line-height: 1.5; flex-shrink: 0; }
.casa__list strong { display: block; color: var(--c-bone); font-weight: 600; margin-bottom: 0.15rem; }
.casa__list span { font-size: var(--t-sm); color: rgba(229, 225, 214, 0.72); }


.casa__visual { position: relative; }
.casa__frame {
  border-radius: var(--r-xl);
  overflow: hidden;
  aspect-ratio: 4/5;
  box-shadow: var(--sh-lg);
}
.casa__frame img { width: 100%; height: 112%; object-fit: cover; }

.casa__chip {
  position: absolute;
  padding: 0.85rem 1.15rem;
  background: rgba(247, 249, 246, 0.96);
  color: var(--c-espresso);
  border-radius: var(--r-md);
  box-shadow: var(--sh-md);
  font-size: var(--t-sm);
  font-weight: 600;
  animation: bob 5s ease-in-out infinite;
}
.casa__chip strong {
  display: block;
  font-family: var(--f-ui);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--c-gold-text);
  margin-bottom: 0.1rem;
}
.casa__chip--a { left: 0.8rem; bottom: 1.8rem; }
.casa__chip--b { right: 0.8rem; top: 1.8rem; animation-delay: 2.5s; }
@media (min-width: 920px) {
  .casa__chip--a { left: -1.4rem; }
  .casa__chip--b { right: -1.4rem; }
}


/* ============================================================
   SERVICIOS
============================================================ */
.svc-grid { display: grid; gap: 1rem; grid-template-columns: 1fr; list-style: none; }
@media (min-width: 600px) { .svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 920px) { .svc-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.svc {
  position: relative;
  padding: 2rem 1.75rem;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
  overflow: hidden;
  transition: transform var(--d-base) var(--ease), box-shadow var(--d-base), opacity var(--d-slow);
}
/* Filete dorado superior que se despliega al hover */
.svc::before {
  content: '';
  position: absolute;
  inset: 0 auto auto 0;
  width: 0; height: 3px;
  background: linear-gradient(90deg, var(--c-crimson), var(--c-gold));
  transition: width var(--d-slow) var(--ease);
}
.svc:hover { transform: translateY(-5px); box-shadow: var(--sh-md); }
.svc:hover::before { width: 100%; }

.svc__icon {
  display: grid;
  place-items: center;
  width: 58px; height: 58px;
  margin-bottom: 1.2rem;
  color: var(--c-crimson);
  background: rgba(178, 42, 68, 0.07);
  border-radius: 50%;
}
.svc h3 {
  font-family: var(--f-display);
  font-size: var(--t-lg);
  font-weight: 600;
  margin-bottom: 0.55rem;
}
.svc p { font-size: var(--t-sm); color: var(--text-soft); }


/* ============================================================
   CONTACTO
============================================================ */
.contact { background: var(--bg-alt); }

.contact__grid { display: grid; gap: var(--s-5); }
@media (min-width: 920px) { .contact__grid { grid-template-columns: 1fr 1fr; gap: var(--s-6); align-items: start; } }

.contact__info .section__title { margin-block: 0.2rem 1.2rem; }
.contact__info .lead { margin-bottom: 2rem; }

.contact__list { display: flex; flex-direction: column; gap: 1.4rem; font-style: normal; }
.contact__row { display: flex; gap: 1rem; align-items: flex-start; }

.contact__icon {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  flex-shrink: 0;
  color: var(--c-crimson);
  background: var(--surface);
  border-radius: 50%;
  box-shadow: var(--sh-sm);
}
.contact__row strong {
  display: block;
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-gold-text);
  margin-bottom: 0.2rem;
}
.contact__row span { font-size: var(--t-sm); color: var(--text-soft); }
.contact__row a { color: var(--text); transition: color var(--d-fast); }
.contact__row a:hover { color: var(--c-crimson); }

.contact__social { display: flex; gap: 1rem; }
.contact__social a { font-size: var(--t-sm); color: var(--text-soft); }

/* ── Formulario ── */
.contact__form-card {
  background: var(--surface);
  border-radius: var(--r-xl);
  padding: clamp(1.5rem, 4vw, 2.6rem);
  box-shadow: var(--sh-md);
}
.form__title {
  font-family: var(--f-display);
  font-size: var(--t-xl);
  font-weight: 600;
  margin-bottom: 0.4rem;
}
.form__intro { font-size: var(--t-sm); color: var(--text-soft); margin-bottom: 1.8rem; }

.form__group { display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 1.15rem; }
.form__group label {
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-soft);
}
.form__opt { font-weight: 400; text-transform: none; letter-spacing: 0; opacity: 0.7; }

.form__group input,
.form__group select,
.form__group textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: var(--f-body);
  font-size: var(--t-sm);
  color: var(--text);
  background: var(--c-bone);
  border: 1.5px solid var(--field-border);
  border-radius: var(--r-md);
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--d-fast), background var(--d-fast), box-shadow var(--d-fast);
}
.form__group select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235C4736' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9rem center;
  padding-right: 2.6rem;
  cursor: pointer;
}
.form__group textarea { resize: vertical; min-height: 118px; }

.form__group input:focus,
.form__group select:focus,
.form__group textarea:focus {
  background: #fff;
  border-color: var(--c-crimson);
  box-shadow: 0 0 0 4px rgba(178, 42, 68, 0.1);
}
.form__group input::placeholder,
.form__group textarea::placeholder { color: var(--placeholder); }

.form__error {
  display: block;
  min-height: 1em;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--danger);
}
.form__group.has-error input,
.form__group.has-error select,
.form__group.has-error textarea { border-color: var(--danger); background: #fff; }

.form__done {
  margin-top: 1rem;
  padding: 0.95rem 1.2rem;
  text-align: center;
  font-size: var(--t-sm);
  font-weight: 600;
  color: #fff;
  background: var(--c-crimson);
  border-radius: var(--r-md);
}
.form__done[hidden] { display: none; }

/* Campo trampa contra robots: invisible y sin ocupar espacio. No se usa
   `display: none` porque muchos robots detectan ese truco y se saltan el
   campo, que es justo lo que no interesa. */
.form__trap {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Aviso de privacidad simplificado: se informa en el momento en que se
   piden los datos, no solo en una página aparte. */
.form__legal {
  margin-top: 0.9rem;
  text-align: center;
  font-size: var(--t-xs);
  color: var(--text-soft);
}
.form__legal a,
.form__fail a {
  color: var(--c-crimson);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

/* Fallo o formulario sin destino. Fondo claro con borde de peligro en
   lugar de un bloque rojo: no es un éxito y no debe parecerlo. El
   teléfono queda siempre a mano como vía alternativa. */
.form__fail {
  margin-top: 1rem;
  padding: 0.95rem 1.2rem;
  text-align: center;
  font-size: var(--t-sm);
  color: var(--text);
  background: #fff;
  border: 1.5px solid var(--danger);
  border-radius: var(--r-md);
}
.form__fail[hidden] { display: none; }


/* ============================================================
   FOOTER
============================================================ */
.footer { background: var(--c-espresso); color: var(--text-onDark); }

.footer__grid {
  display: grid;
  gap: var(--s-4);
  padding-top: var(--s-6);
  padding-bottom: var(--s-4);
}
@media (min-width: 600px) { .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-5); } }
@media (min-width: 1000px) { .footer__grid { grid-template-columns: 1.7fr 1fr 1fr 1.3fr; } }

.footer__brand p {
  margin-top: 1.1rem;
  font-size: var(--t-sm);
  color: rgba(229, 225, 214, 0.7);
  max-width: 34ch;
}

.footer__social { display: flex; gap: 0.6rem; margin-top: 1.4rem; }
.footer__social a {
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  font-family: var(--f-ui);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--c-cream);
  border: 1px solid rgba(186, 142, 48, 0.60);   /* 3.0:1 ✓ 1.4.11 */
  border-radius: 50%;
  transition: background var(--d-fast), color var(--d-fast), border-color var(--d-fast);
}
.footer__social a:hover { background: var(--c-gold); color: var(--c-espresso); border-color: var(--c-gold); }

.footer__head {
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--c-gold);
  margin-bottom: 1.1rem;
}

.footer__col ul { list-style: none; }
.footer__col li { margin-bottom: 0.55rem; }
.footer__col a { font-size: var(--t-sm); color: rgba(229, 225, 214, 0.75); transition: color var(--d-fast); }
.footer__col a:hover { color: var(--c-gold); }
.footer__col > p a { text-decoration: underline; text-underline-offset: 0.15em; }
.footer__col > p { font-size: var(--t-sm); color: rgba(229, 225, 214, 0.7); margin-bottom: 1rem; }



/* Newsletter */
.nl { display: flex; gap: 0.5rem; }
.nl input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 1.05rem;
  font-family: var(--f-body);
  font-size: var(--t-sm);
  color: var(--c-cream);
  background: rgba(247, 249, 246, 0.07);
  /* 3.0:1 sobre espresso ✓ WCAG 1.4.11. El formulario de contacto ya
     se había corregido; este campo se quedó atrás con el mismo fallo. */
  border: 1px solid rgba(186, 142, 48, 0.60);
  border-radius: var(--r-pill);
  outline: none;
  transition: border-color var(--d-fast), background var(--d-fast);
}
.nl input::placeholder { color: rgba(229, 225, 214, 0.72); }  /* 7.86:1 ✓ 1.4.3 */
.nl input:focus { border-color: var(--c-gold); background: rgba(247, 249, 246, 0.12); }

.nl button {
  width: 44px; height: 44px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  font-size: 1.05rem;
  color: var(--c-espresso);
  background: var(--c-gold);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--d-fast), transform var(--d-fast);
}
.nl button:hover { background: #d6a743; transform: scale(1.07); }
.nl button.is-done { background: #4E8F6B; color: #fff; }

.nl__msg {
  display: block;
  margin-top: 0.65rem;
  min-height: 1em;
  font-size: var(--t-xs);
  color: var(--c-gold);
}

.footer__bottom { border-top: 1px solid rgba(229, 225, 214, 0.12); padding-block: 1.3rem; }
.footer__bottom-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.footer__bottom small { font-size: var(--t-xs); color: rgba(229, 225, 214, 0.55); }

.footer__bottom nav { display: flex; gap: 1.3rem; }
.footer__bottom nav a { font-size: var(--t-xs); color: rgba(229, 225, 214, 0.55); }
.footer__bottom nav a:hover { color: var(--c-gold); }


/* ============================================================
   BACK TO TOP
============================================================ */
.to-top {
  position: fixed;
  right: 1.3rem;
  bottom: 1.6rem;
  z-index: 850;
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  color: #fff;
  background: var(--c-crimson);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: var(--sh-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(14px);
  transition:
    opacity var(--d-base), visibility var(--d-base),
    transform var(--d-base) var(--ease), background var(--d-base);
}
.to-top.is-visible { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }
.to-top:hover { background: var(--c-crimson-dark); }
.to-top[hidden] { display: none; }


/* ============================================================
   PRELOADER Y ANIMACIÓN DE REVELADO
   ------------------------------------------------------------
   Regla de oro: el overlay está en display:none por defecto. Solo se
   muestra si el script del <head> logró añadir `js-loading` al <html>.
   Sin JavaScript no hay pantalla de carga y el sitio se ve completo:
   nunca se retiene contenido detrás de algo que podría no retirarse.
============================================================ */
.preloader { display: none; }

.js-loading .preloader,
.preloader.is-out {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 9999;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  background: var(--c-bone);
  /* El clip parte de un círculo mayor que la pantalla; al salir se
     contrae hasta cero sobre el centro del monograma. */
  clip-path: circle(150% at 50% 42%);
}

/* Bloqueo de scroll mientras carga */
.js-loading body { overflow: hidden; }

/* ── El logomark ────────────────────────────────────────── */
.preloader__mark {
  position: relative;
  width: clamp(136px, 40vw, 184px);
  aspect-ratio: 1;
  opacity: 0;
  /* Dos animaciones sin conflicto: preIn gobierna opacity y translate,
     markBreath solo scale. La respiración arranca cuando la entrada ya
     ha terminado. */
  animation:
    preIn 700ms 60ms var(--ease) forwards,
    markBreath 3.4s 900ms ease-in-out infinite;
}

.preloader__mark img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Capa base: el logotipo apagado, como huella de lo que va a llegar. */
.preloader__mark-ghost { opacity: 0.14; }

/* Capa de progreso. La máscara cónica arranca a las 12 en punto
   (-0.25turn) y descubre el logotipo en sentido horario. El segundo
   punto de parada en 0 se recorta al valor del primero, lo que produce
   un borde neto en lugar de un degradado. main.js escribe --fill.
   Si el navegador no soporta máscaras, la capa se ve completa: el
   logotipo aparece entero, que es una degradación aceptable. */
.preloader__mark-fill {
  --fill: 0turn;
  -webkit-mask-image: conic-gradient(from -0.25turn, #000 var(--fill), rgba(0,0,0,0) 0);
          mask-image: conic-gradient(from -0.25turn, #000 var(--fill), rgba(0,0,0,0) 0);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Filete de progreso bajo la marca. */
.preloader__rule {
  position: relative;
  width: clamp(150px, 40vw, 200px);
  height: 1.5px;
  margin-top: 2.1rem;
  /* El oro de marca no alcanza 3:1 sobre hueso ni al 100 % (2.83:1),
     así que el canal vacío se dibuja en cacao: 3.02:1 ✓ 1.4.11.
     El relleno sí conserva el degradado carmín→oro. */
  background: rgba(92, 71, 54, 0.60);
  border-radius: var(--r-pill);
  overflow: hidden;
  opacity: 0;
  animation: preIn 700ms 300ms var(--ease) forwards;
}
.preloader__rule-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--c-crimson), var(--c-gold));
  transition: width 200ms linear;
}

/* ── Rótulos ────────────────────────────────────────────── */
.preloader__pct {
  margin-top: 0.65rem;
  font-family: var(--f-ui);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--c-gold-text);
  font-variant-numeric: lining-nums tabular-nums;
  opacity: 0;
  animation: preIn 700ms 460ms var(--ease) forwards;
}

/* ── Salida ─────────────────────────────────────────────── */
/* Primero se retiran los rótulos, después el fondo se contrae sobre el
   punto donde estaba el monograma. El sitio no aparece de golpe: emerge
   por el mismo aro que acaba de completarse. */
.preloader.is-out .preloader__mark,
.preloader.is-out .preloader__rule,
.preloader.is-out .preloader__pct {
  animation: preOutMark 360ms var(--ease-menu-out) forwards;
}

.preloader.is-out {
  animation: preOutVeil 820ms 260ms var(--ease-menu-in) forwards;
  pointer-events: none;
}

/* ── Entrada de la interfaz ─────────────────────────────── */
/* IMPORTANTE: no se anima `transform` sobre .header ni sobre
   .header__inner. Cualquiera de los dos se convertiría en bloque
   contenedor del panel de navegación `position: fixed`. Se anima la
   opacidad del header (que no crea bloque contenedor) y el
   desplazamiento de sus hijos por separado. */
.header { opacity: 1; }
.js-loading .header { opacity: 0; }

.brand,
.header__actions,
.nav__list { transition: translate 800ms 260ms var(--ease); }
.js-loading .brand,
.js-loading .header__actions,
.js-loading .nav__list { translate: 0 -16px; }

/* La animación de entrada del hero queda en pausa, no cancelada: al
   retirar `js-loading` reanuda desde su fotograma cero y encadena con
   el cierre del velo, en lugar de haberse consumido tras el overlay. */
.js-loading .slide.is-active .slide__badge,
.js-loading .slide.is-active .slide__title,
.js-loading .slide.is-active .slide__text,
.js-loading .slide.is-active .slide__actions { animation-play-state: paused; }

.js-loading .marquee__track { animation-play-state: paused; }


/* ============================================================
   KEYFRAMES
============================================================ */
@keyframes preIn {
  from { opacity: 0; translate: 0 14px; }
  to   { opacity: 1; translate: 0 0; }
}

@keyframes preOutMark {
  to { opacity: 0; scale: 1.14; }
}

/* Respiración sutil del logomark durante la espera. Amplitud del 3,5 %:
   suficiente para que la pantalla no parezca congelada si la red va
   lenta, insuficiente para llamar la atención sobre sí misma. */
@keyframes markBreath {
  0%, 100% { scale: 1; }
  50%      { scale: 1.035; }
}

@keyframes preOutVeil {
  from { clip-path: circle(150% at 50% 42%); }
  to   { clip-path: circle(0% at 50% 42%); }
}

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes riseIn {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 1; transform: none; }
}

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}


/* ============================================================
   PREFERS-REDUCED-MOTION
   Se anula todo el movimiento no esencial y se garantiza que
   ningún contenido dependa de una animación para ser visible.
============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    /* Anular la duración no basta: sin esto los retardos del escalonado
       del menú (hasta 440 ms) y de la entrada del hero seguirían
       aplicándose, y el contenido tardaría en aparecer aunque ya no
       hubiera animación que ver. */
    animation-delay: 0ms !important;
    transition-delay: 0ms !important;
  }
  html { scroll-behavior: auto; }

  [data-reveal] { opacity: 1; transform: none; }
  .slide__badge, .slide__title, .slide__text, .slide__actions { opacity: 1; }
  .marquee__track { animation: none; transform: none; }
  .news-track { scroll-behavior: auto; }

  /* El menú aparece y desaparece sin coreografía: el contenido nunca
     depende de una animación para ser visible. */
  .nav__list li,
  .nav__cta { opacity: 1; translate: none; }
  .nav::before { display: none; }

  /* El preloader se mantiene —sigue habiendo espera real que comunicar—
     pero sin barrido de clip ni desplazamientos: solo un fundido.
     El arco de progreso conserva su valor porque es información, no
     decoración. */
  .preloader__mark,
  .preloader__rule,
  .preloader__pct { opacity: 1; animation: none; translate: none; scale: none; }

  .preloader.is-out {
    animation: none;
    clip-path: none;
    opacity: 0;
    transition: opacity 200ms linear;
  }
  .preloader.is-out .preloader__mark,
    .preloader.is-out .preloader__rule,
    .preloader.is-out .preloader__pct { animation: none; }

  .js-loading .brand,
  .js-loading .header__actions,
  .js-loading .nav__list { translate: none; }
}


/* ============================================================
   MODO DE COLORES FORZADOS (Windows High Contrast)
   El sistema sustituye toda la paleta por la del usuario. Los
   elementos dibujados con `background` o `border-color` desaparecen,
   porque el sistema los reemplaza. Hay que reconstruirlos con las
   palabras clave del sistema para que sigan siendo perceptibles.
============================================================ */
@media (forced-colors: active) {
  /* La filigrana del menú es una imagen decorativa: en modo forzado
     se retira antes que arriesgar que quede como una mancha opaca. */
  .nav::before { display: none; }

  /* Botones dibujados solo con relleno: sin borde quedarían como
     texto suelto, sin límite visible que los identifique. */
  .btn,
  .slider__btn,
  .carousel-btn,
  .to-top,
  .nl button,
  .hamburger { border: 1px solid ButtonText; }

  .hamburger__bar { background: ButtonText; }

  /* Estados activos que se comunican por color: en modo forzado el
     color se pierde, así que se refuerzan con borde. */
  .slider-dot[aria-current="true"],
  .nav__link[aria-current="page"] { outline: 2px solid Highlight; }

  /* El velo del hero y los degradados de las tarjetas se eliminan:
     el sistema garantiza el contraste del texto por su cuenta. */
  .slide__scrim,
  .hl-card__body { background: Canvas; }

  .form__group input,
  .form__group select,
  .form__group textarea { border-color: CanvasText; }

  :focus-visible { outline-color: Highlight; }
}
@media print {
  .header, .slider__controls, .to-top, .marquee,
  .carousel-btn, .nl, .hamburger { display: none !important; }
  body { background: #fff; color: #000; }
  .hero { height: auto; min-height: 0; }
}


/* ============================================================
   COMPLEMENTOS DE SECCIÓN
   Servicios, promoción, contacto, pie y la casa.
============================================================ */

/* Nota secundaria dentro de una tarjeta de servicio: las
   restricciones (no transferencias, no mascotas) se leen pero no
   compiten con la información principal. */
.svc__note {
  display: inline-block;
  margin-top: 0.35rem;
  font-size: 0.92em;
  color: var(--c-gold-text);
}

/* Promoción permanente del helado gratis. Estaba enterrada en el
   catálogo y es uno de los ganchos más fuertes del negocio, así que
   se le da un bloque propio en vez de una línea más. */
.promo {
  margin-top: clamp(2rem, 5vw, 3rem);
  padding: clamp(1.75rem, 5vw, 2.5rem);
  text-align: center;
  background: var(--c-crimson);
  color: #fff;
  border-radius: var(--r-xl);
  box-shadow: var(--sh-md);
}
.promo__eyebrow {
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-bottom: 0.6rem;
}
.promo__title {
  font-family: var(--f-display);
  font-size: var(--t-2xl);
  font-weight: 200;
  line-height: 1.2;
  text-wrap: balance;
}
.promo__title strong { font-weight: 600; }
.promo__note {
  margin-top: 0.75rem;
  font-size: var(--t-sm);
  opacity: 0.85;
}

/* Enlace a Google Maps dentro de la ficha de dirección */
.contact__map {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.5rem;
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--c-crimson);
  transition: gap var(--d-base) var(--ease);
}
.contact__map:hover { gap: 0.7rem; }

/* Los cuatro teléfonos en columna: en móvil cada uno es un objetivo
   táctil independiente y debe tener holgura suficiente. */
.contact__phones { display: flex; flex-direction: column; gap: 0.1rem; }
.contact__phones a {
  display: inline-block;
  padding-block: 0.35rem;      /* ≥24 px de alto — WCAG 2.5.8 */
  font-variant-numeric: lining-nums tabular-nums;
}

/* Bloque de dirección y horario del pie */
.footer__address {
  font-style: normal;
  font-size: var(--t-sm);
  color: rgba(229, 225, 214, 0.75);
  line-height: 1.7;
}
.footer__hours {
  margin-top: 0.9rem;
  font-size: var(--t-sm);
  color: rgba(229, 225, 214, 0.75);
}
.footer__hours strong { color: var(--c-cream); }
.footer__tel {
  display: inline-block;
  margin-top: 1rem;
  font-family: var(--f-display);
  font-size: var(--t-lg);
  color: var(--c-gold);
  font-variant-numeric: lining-nums tabular-nums;
  transition: opacity var(--d-fast);
}
.footer__tel:hover { opacity: 0.8; }

/* Cierre de la sección de la casa: la cita de custodia del patrimonio */
.casa__note {
  margin-top: 1.5rem;
  padding-left: 1rem;
  border-left: 2px solid var(--c-gold);
  font-size: var(--t-sm);
  font-style: italic;
  color: rgba(229, 225, 214, 0.78);
}


/* ============================================================
   PÁGINAS LEGALES
   Aviso de privacidad y términos. Reutilizan header y pie; el cuerpo
   es una sola columna de lectura a ~70 caracteres por línea.
============================================================ */
.legal-page__header .header__inner { justify-content: space-between; }

.legal {
  max-width: 70ch;
  margin-inline: auto;
  padding-top: calc(var(--header-h) + clamp(2rem, 6vw, 4rem));
  padding-bottom: var(--s-6);
}

.legal h1 {
  font-family: var(--f-display);
  font-size: var(--t-3xl);
  font-weight: 200;
  line-height: 1.08;
  letter-spacing: -0.015em;
}

.legal__updated {
  margin-top: 0.75rem;
  font-family: var(--f-ui);
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-gold-text);
}

.legal h2 {
  margin-top: 2.6rem;
  margin-bottom: 0.7rem;
  font-family: var(--f-display);
  font-size: var(--t-xl);
  font-weight: 600;
  line-height: 1.2;
  color: var(--c-crimson);
}

.legal h3 {
  margin-top: 1.4rem;
  margin-bottom: 0.4rem;
  font-family: var(--f-ui);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.legal p,
.legal li { color: var(--text-soft); }
.legal p  { margin-bottom: 1rem; }
.legal ul { margin: 0 0 1rem 1.25rem; }
.legal li { margin-bottom: 0.4rem; }
.legal strong { color: var(--text); }

.legal a {
  color: var(--c-crimson);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.legal a:hover { color: var(--c-crimson-dark); }

/* Dato que el negocio aún debe proporcionar. Resalta a propósito: no
   debe pasar desapercibido ni llegar así a producción. */
.legal__todo {
  padding: 0.05em 0.35em;
  font-weight: 600;
  color: var(--text);
  background: rgba(186, 142, 48, 0.25);
  border-radius: 4px;
}


/* ============================================================
   AVISO DE COOKIES
   Lo inserta js/consent.js. Aparece abajo, sin bloquear la página:
   no es un muro, es una pregunta. Hasta que se responde, ni Google
   Analytics ni el pixel de Meta se han descargado.
============================================================ */
.cookies {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 950;
  background: var(--surface);
  border-top: 1px solid var(--line-gold);
  box-shadow: 0 -10px 30px rgba(30, 7, 11, 0.12);

  /* Entra deslizándose desde abajo. Empieza fuera de la pantalla para
     que no dé un salto al aparecer. */
  transform: translateY(100%);
  transition: transform var(--d-slow) var(--ease);
}
.cookies.is-visible { transform: none; }

.cookies__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding-block: 1.1rem;
  padding-bottom: calc(1.1rem + env(safe-area-inset-bottom, 0px));
}

.cookies__text {
  font-size: var(--t-sm);
  color: var(--text-soft);
  max-width: 78ch;
}
.cookies__text strong { color: var(--text); }
.cookies__text a {
  color: var(--c-crimson);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.cookies__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.cookies__actions .btn { flex: 1 1 auto; }

/* Rechazar no se esconde ni se disfraza: misma altura y misma
   legibilidad que aceptar. Una opción difícil de ver sería un
   consentimiento arrancado, no dado. */
.cookies__decline {
  --btn-bg: transparent;
  --btn-fg: var(--text-soft);
  --btn-bd: rgba(92, 71, 54, 0.6);     /* 3.4:1 sobre blanco ✓ 1.4.11 */
}
.cookies__decline:hover {
  --btn-bg: var(--c-cream);
  --btn-fg: var(--text);
  --btn-bd: var(--c-cocoa);
}

@media (min-width: 720px) {
  .cookies__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
  }
  .cookies__actions .btn { flex: 0 0 auto; }
}

/* Botón del aviso de privacidad para cambiar la decisión ya tomada. */
.legal__cookies-reset { margin-bottom: 1rem; }
