/* ==========================================================================
   SPABAR — Design System
   Brand: navy #273569 · sand #DCD6D0 (extracted from spabar.net)
   ========================================================================== */

/* ---------- Tokens ---------- */
:root{
  /* Core palette */
  --ink:        #0B0F24;
  --ink-soft:   #171D3A;
  --navy:       #273569;
  --navy-lift:  #33447F;
  --sand:       #DCD6D0;
  --sand-deep:  #C6BEB6;
  --rose:       #C08C86;
  --rose-soft:  #E4C9C4;
  --white:      #FFFFFF;
  /* --cream es color de TEXTO sobre navy (menú, footer, hero), no un fondo.
     Por eso sigue siendo hueso: es lo que se lee sobre azul.              */
  --cream:      #F7F4EF;

  /* ---- Superficies ----
     UNA sola superficie clara en todo el sitio: blanco puro. Antes había
     tres tonos casi iguales (cream de fondo, paper de tarjeta, chip de
     etiqueta) y la diferencia era tan corta que no leía como jerarquía:
     leía como suciedad, unas zonas grises y otras un poco más blancas.
     Ahora nada se separa por relleno. Todo se separa por FILETE.         */
  --paper:      var(--white);
  --chip:       var(--white);
  --bg:         var(--white);

  /* Semantic */
  --fg:         var(--ink);
  --muted:      #6B7089;
  /* Sobre blanco puro estos filetes rinden ~#E0E1E6 y ~#EBECEF: se notan
     sin pesar. Sobre el cream anterior quedaban lavados, y por eso hacía
     falta el relleno.                                                    */
  --line:       rgba(11,15,36,.14);
  --line-soft:  rgba(11,15,36,.09);
  /* Grosor del filete. 1px es lo único que rinde nítido en pantalla
     normal; donde hay densidad real para dibujarlo, .8px afina el trazo
     sin que se rompa.                                                    */
  --hair:       1px;

  /* Type */
  --serif: "DM Serif Display", "Times New Roman", serif;
  --sans:  "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --fs-mega:  clamp(3.25rem, 12vw, 11rem);
  --fs-h1:    clamp(2.5rem, 7.2vw, 6.5rem);
  --fs-h2:    clamp(2rem, 5vw, 4.25rem);
  --fs-h3:    clamp(1.5rem, 2.6vw, 2.5rem);
  --fs-h4:    clamp(1.15rem, 1.6vw, 1.5rem);
  --fs-body:  clamp(0.975rem, 1.05vw, 1.125rem);
  --fs-lead:  clamp(1.05rem, 1.5vw, 1.375rem);
  --fs-small: 0.8125rem;
  --fs-micro: 0.6875rem;

  /* Space */
  --gut: clamp(1.25rem, 4vw, 4.5rem);
  --sec: clamp(5.5rem, 12.5vw, 12rem);
  --maxw: 1560px;

  /* Motion */
  --e-out: cubic-bezier(.16,1,.3,1);
  --e-io:  cubic-bezier(.65,.05,.36,1);
  --e-soft: cubic-bezier(.4,0,.2,1);
  /* expo.out: arranca disparado y se posa. Es la curva de los titulares:
     con stagger corto lee como UN gesto, no como piezas sueltas.       */
  --e-hero: cubic-bezier(.19,1,.22,1);
  /* expo.inOut para salidas: sale rápido y frena, sin dar tirones.     */
  --e-exit: cubic-bezier(.76,0,.24,1);
  /* Para HOVERS largos. La expo.out de las entradas arranca disparada: en un
     reveal eso es un gesto, pero bajo el cursor lee como un chasquido. Ésta
     tiene salida suave y una cola larguísima — la cosa "se abre" en vez de
     saltar, y vuelve igual de calmada al salir el puntero.               */
  --e-silk: cubic-bezier(.32,.72,0,1);

  --radius: 2px;
  /* Tarjetas con imagen embebida: la imagen va metida `--media-pad` hacia
     dentro, así que el radio de la tarjeta es el de la imagen + ese hueco.
     De esa forma las dos curvas quedan concéntricas y no "pellizcadas".   */
  /* filete de 1px. Sin este token, cada `border:var(--hair) solid …` era una
     declaración inválida y el navegador dejaba las tarjetas SIN borde.     */
  --hair: 1px;

  --media-pad:    8px;
  --radius-media: 11px;
  --radius-lg:    calc(var(--radius-media) + var(--media-pad));  /* 19px */

  --nav-h: 84px;
}

/* En pantallas de alta densidad sí hay píxeles físicos para dibujar medio
   trazo: el filete baja a .8px y el borde se lee como una línea impresa,
   no como un recuadro. En 1x se queda en 1px porque .8px lo redondearía
   igual, pero de forma irregular entre navegadores.                     */
@media (min-resolution: 2dppx){
  :root{ --hair: .8px }
}

/* ---------- Reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html,body{margin:0;padding:0}
body{
  background:var(--bg);
  color:var(--fg);
  font-family:var(--sans);
  font-size:var(--fs-body);
  line-height:1.6;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
  overflow-x:clip;
  overscroll-behavior-x:none;
  font-feature-settings:"ss01","cv01";
}
/* ---------- Cero arrastre lateral ----------
   `overflow-x:hidden` no basta: el viewport SIGUE siendo un contenedor de
   scroll, así que en iOS Safari el dedo arrastra la página entera y las capas
   fijas (barra, burbujas, velos) se repintan a destiempo — el efecto de
   "lienzo roto". `clip` no crea contenedor de scroll: el gesto deja de
   existir. Va en html Y en body porque en cuanto el html no es `visible` el
   overflow del body ya no se propaga al viewport.
   `hidden` queda delante como respaldo de Safari < 16, que tira la línea
   `clip` por no entenderla.
   Y como el html deja de ser `visible`, `body.is-locked` ya no puede bloquear
   el scroll de la página por propagación: lo hace el `:has()` de abajo.     */
html{
  overflow-x:hidden;
  overflow-x:clip;
  overscroll-behavior-x:none;
  /* La calle de la barra queda reservada siempre: al abrir el menú o el visor
     el scroll se bloquea, la barra se va y sin esto la página entera daba un
     salto de 15 px. En móvil la barra flota y no reserva nada.              */
  scrollbar-gutter:stable
}
html:has(body.is-locked){overflow:hidden}
body.is-locked{overflow:hidden}
h1,h2,h3,h4,h5,p,figure,blockquote{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
img,video,svg{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}

/* ---------- Contrato de iconos ----------
   injectIcons() mete el SVG dentro de [data-ico] SIN width ni height. Un SVG
   inline sin dimensiones y con viewBox se dibuja al 100% del ancho disponible:
   por eso un icono de 20px salía a pantalla completa allí donde nadie había
   escrito una regla propia (.pillar__ico, .gal__zoom...). Esta es la red:
   1em ata el icono al tipo de su contenedor, y cualquier `.x svg{width:…}`
   posterior en la hoja lo afina sin pelear por especificidad.            */
[data-ico]{display:inline-flex;align-items:center;justify-content:center;flex:none;line-height:0}
[data-ico] > svg{width:1em;height:1em;flex:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,textarea,select{font:inherit;color:inherit}
::selection{background:var(--navy);color:var(--cream)}
/* foco visible coherente en todo el sitio (el navegador ya no pinta naranja) */
:focus-visible{outline:2px solid var(--rose);outline-offset:3px}

/* ---------- Layout ---------- */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gut)}
.wrap--narrow{max-width:1100px}
.section{padding-block:var(--sec)}
/* Ritmo corto. El respiro editorial de --sec (hasta 176 px arriba y abajo)
   es correcto para leer una historia y es un impuesto en una página donde
   la gente viene a resolver algo: en contacto sumaba más de 350 px de aire
   por sección. Aquí el aire se reduce a la mitad justa. */
.section--tight{padding-block:clamp(2.5rem,6vw,4.75rem)}
.section--tight .shead{margin-bottom:clamp(1.5rem,3vw,2.5rem)}
.grid{display:grid;gap:clamp(1.25rem,3vw,3rem)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g12{grid-template-columns:repeat(12,1fr)}

/* ---------- Type utilities ---------- */
.serif{font-family:var(--serif);font-weight:400;letter-spacing:-.015em;line-height:.98}
.mega{font-family:var(--serif);font-size:var(--fs-mega);line-height:.86;letter-spacing:-.03em}
.h1{font-family:var(--serif);font-size:var(--fs-h1);line-height:.96;letter-spacing:-.022em}
.h2{font-family:var(--serif);font-size:var(--fs-h2);line-height:1.02;letter-spacing:-.02em}
.h3{font-family:var(--serif);font-size:var(--fs-h3);line-height:1.1;letter-spacing:-.015em}
.h4{font-size:var(--fs-h4);font-weight:600;line-height:1.25;letter-spacing:-.01em}
.lead{font-size:var(--fs-lead);line-height:1.5;color:var(--muted);font-weight:400}
.muted{color:var(--muted)}
.italic{font-style:italic}
.tnum{font-variant-numeric:tabular-nums}

/* ---------- Transicion entre paginas ----------
   Navegacion entre documentos con View Transitions: el contenido hace un
   cross-fade corto y la barra + el boton flotante quedan FUERA del snapshot
   raiz, asi que no parpadean ni se vuelven a montar al cambiar de pagina.
   Navegador sin soporte: salto instantaneo de siempre, nada se rompe.

   La otra mitad de esto NO esta aqui: el navegador saca la foto de la barra
   nueva en cuanto el documento puede pintar, MUCHO antes de que corra main.js.
   Mientras la barra se generaba desde JS esa foto salia vacia y el menu
   aparecia de golpe al terminar la transicion — daba igual lo fino que fuera
   este bloque. Por eso el <header> va escrito a mano en cada .html. */
@view-transition{navigation:auto}

/* La barra y la burbuja de WhatsApp son cromo persistente: NO se disuelven al
   cambiar de página. Por defecto el navegador cruza dos fotos distintas de la
   MISMA barra (transparente sobre el hero ↔ cápsula blanca, 88 px ↔ 72 px) y
   además interpola su tamaño: durante un tercio de segundo se veían dos menús
   mezclados, estirados, con el chip todavía en el link de la página anterior.
   Ese era el parpadeo. Grupo sin animación → la barra ni se mueve ni se
   estira; `old` oculta y `new` opaca desde el primer fotograma → sólo se ve
   la barra nueva, ya correcta. La navegación deja de "montar" el menú. */
.nav{view-transition-name:nav}
.wa{view-transition-name:wa}
::view-transition-group(nav),
::view-transition-group(wa){animation:none}
::view-transition-old(nav),
::view-transition-old(wa){animation:none;opacity:0}
::view-transition-new(nav),
::view-transition-new(wa){animation:none;opacity:1}
::view-transition-old(nav),::view-transition-old(wa),
::view-transition-new(nav),::view-transition-new(wa){mix-blend-mode:normal}

/* El contenido sí cruza, pero sin bajón. Antes la página vieja se apagaba en
   .16 s y la nueva tardaba .32 s en llegar: entre las dos había un tramo con
   ambas a medio gas y se veía el fondo del navegador — el "flash" al tocar
   una sección. Ahora la vieja se queda opaca debajo y la nueva entra encima:
   en ningún fotograma hay menos de una página completa en pantalla.

   `mix-blend-mode:normal` NO es decorativo: la hoja del navegador pone
   `plus-lighter` en estas dos capas para que un cross-fade simétrico no baje
   de brillo. Aquí la vieja se queda al 100 %, así que sumar la nueva encima
   quemaría la imagen a blanco. Con `normal` la nueva simplemente tapa. */
::view-transition-old(root),
::view-transition-new(root){mix-blend-mode:normal}
::view-transition-old(root){animation:none;opacity:1}
::view-transition-new(root){animation:vt-in .34s var(--e-out) both}
@keyframes vt-in{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}

/* ---------- Nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:800;
  height:var(--nav-h);display:flex;align-items:center;
  transition:height .5s var(--e-out),background-color .5s var(--e-out),
             box-shadow .5s var(--e-out),color .4s var(--e-out);
}
.nav{padding-inline:var(--gut)}
.nav__in{
  width:100%;max-width:calc(var(--maxw) - var(--gut) * 2);margin-inline:auto;
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:.35rem;border-radius:999px;background:transparent;
  transition:padding .5s var(--e-out),background-color .5s var(--e-out),
             box-shadow .5s var(--e-out),backdrop-filter .5s var(--e-out)
}
/* Un solo archivo de logo (1200×468, nítido en retina). La variante clara sale
   de un filtro sobre el mismo PNG: misma geometría exacta, sin salto de ancho
   al cambiar de barra transparente a barra clara.                          */
.nav__logo{
  position:relative;display:flex;align-items:center;z-index:2;line-height:0;
  padding:.25rem;margin:-.25rem;border-radius:var(--radius)
}
.nav__logo img{
  height:32px;width:auto;display:block;
  transition:filter .4s var(--e-out),opacity .3s var(--e-out)
}
.nav--over:not(.is-scrolled) .nav__logo img{filter:brightness(0) invert(1)}
.nav__logo:hover img{opacity:.62}
.nav__logo:focus-visible{outline:2px solid currentColor;outline-offset:2px}
.nav__links{position:relative;display:flex;align-items:center;gap:.15rem}
.nav__link{
  position:relative;isolation:isolate;z-index:1;
  font-size:.8125rem;font-weight:600;letter-spacing:.02em;white-space:nowrap;
  padding:.55rem clamp(.6rem,1vw,.95rem);border-radius:999px;
  background:transparent;
  transition:color .35s var(--e-out),background-color .45s var(--e-out)
}

/* ---- Chip de la sección actual: CSS puro, cero JS ----
   Es un `background` del propio link, no una pieza aparte que haya que medir
   y colocar. Por eso está pintado en el PRIMER fotograma de cada página, antes
   de que main.js exista: al cambiar de sección el chip ya viene puesto en el
   sitio correcto en vez de aparecer medio segundo después.

   Reposo sobre barra clara: cápsula navy, texto crema.
   Reposo sobre el hero oscuro: cápsula blanca, texto navy — que es lo que se
   ve en Inicio y lo que NO debe cambiar por pasar el ratón por otro link. El
   único que cambia con el scroll es el relleno, y lo hace en .45 s junto con
   la barra, así que van al mismo compás. */
.nav__link[aria-current="page"]{background:var(--navy);color:var(--cream)}
.nav--over:not(.is-scrolled) .nav__link[aria-current="page"]{
  background:var(--white);color:var(--navy)
}
.nav__link:focus-visible{outline:2px solid var(--rose);outline-offset:2px}

/* ---- Chip deslizante: SÓLO hover/foco ----
   En reposo está apagado y sin medir. Antes descansaba sobre la página actual,
   y eso obligaba a medirlo al arrancar: crecía desde 0 px en la esquina, y
   volvía a saltar cuando terminaban de cargar las fuentes y los links
   cambiaban de ancho. Ahora la sección actual la marca el CSS de arriba y este
   chip no tiene nada que hacer hasta el primer hover, cuando el layout lleva
   rato quieto.

   `is-snap` apaga sólo la geometría, nunca el fundido: así el chip puede
   encenderse ya colocado (primera aparición) o seguir a un link que se mueve
   (la barra encogiendo con el scroll) sin perder el fade. */
.nav__pill{
  position:absolute;top:0;left:0;width:0;height:0;z-index:0;pointer-events:none;
  border-radius:999px;opacity:0;
  background:color-mix(in oklab, currentColor 13%, transparent);
  transition:transform .42s var(--e-out),width .42s var(--e-out),
             height .3s var(--e-out),opacity .2s linear
}
.nav__pill.is-on{opacity:1}
.nav__pill.is-snap{transition:opacity .2s linear}

/* fallback sin JS: chip propio en hover/focus. El link de la sección actual ya
   lleva el suyo pintado arriba, así que se queda fuera. */
html:not(.navpill) .nav__link:not([aria-current="page"])::before{
  content:"";position:absolute;inset:0;z-index:-1;border-radius:999px;
  background:color-mix(in oklab, currentColor 13%, transparent);
  transform:scale(.82);opacity:0;
  transition:transform .45s var(--e-out),opacity .3s var(--e-out)
}
html:not(.navpill) .nav__link:not([aria-current="page"]):hover::before,
html:not(.navpill) .nav__link:not([aria-current="page"]):focus-visible::before{transform:scale(1);opacity:1}

.nav__right{display:flex;align-items:center;gap:.6rem}
/* barra al hacer scroll: cápsula flotante con relleno claro y alto contraste */
.nav.is-scrolled{height:72px}
.nav.is-scrolled .nav__in{
  padding:.4rem .45rem .4rem 1.15rem;
  background:rgba(255,255,255,.9);
  backdrop-filter:blur(20px) saturate(1.5);
  -webkit-backdrop-filter:blur(20px) saturate(1.5);
  /* La cápsula flota SOBRE el contenido que pasa por debajo: aquí el filete
     solo no basta, necesita despegarse. Se queda el mismo filete que las
     tarjetas y una sombra muy corta, lo justo para levantarla del papel. */
  box-shadow:0 0 0 var(--hair) var(--line),
             0 10px 28px rgba(11,15,36,.07)
}
/* dark hero variant */
.nav--over{color:var(--cream)}
.nav--over.is-scrolled{color:var(--ink)}

@media (prefers-reduced-motion: reduce){
  .nav__pill{transition:opacity .2s linear}
}

.burger{
  display:none;width:44px;height:44px;place-items:center;position:relative;z-index:2;
  border-radius:999px;transition:background-color .35s var(--e-out)
}
.burger:hover{background:color-mix(in oklab, currentColor 15%, transparent)}
.burger:focus-visible{outline:2px solid var(--rose);outline-offset:2px}
.burger i{display:block;width:22px;height:1.5px;background:currentColor;position:absolute;transition:transform .4s var(--e-out),opacity .3s}
.burger i:nth-child(1){transform:translateY(-4px)}
.burger i:nth-child(2){transform:translateY(4px)}
body.menu-open .burger i:nth-child(1){transform:rotate(45deg)}
body.menu-open .burger i:nth-child(2){transform:rotate(-45deg)}

/* ---------- Menu overlay ---------- */
.menu{
  position:fixed;inset:0;z-index:790;background:var(--navy);color:var(--cream);
  clip-path:inset(0 0 100% 0);visibility:hidden;
  display:flex;flex-direction:column;justify-content:center;
  padding:calc(var(--nav-h) + 2rem) var(--gut) 2rem
}
.menu__grid{
  width:100%;max-width:var(--maxw);margin-inline:auto;
  display:grid;grid-template-columns:1.4fr .8fr;gap:clamp(2rem,6vw,6rem);align-items:end
}
.menu__list li{overflow:hidden;padding:.4em .12em;margin:-.3em -.12em}
.menu__list a{
  display:inline-block;font-family:var(--serif);
  font-size:clamp(2rem,6.2vw,5rem);line-height:1.08;letter-spacing:-.025em;
  transform:translateY(170%);position:relative;transition:color .4s var(--e-out)
}
.menu__list a .idx{
  font-family:var(--sans);font-size:.75rem;font-weight:700;letter-spacing:.2em;
  vertical-align:super;opacity:.4;margin-right:.6rem
}
.menu__list a:hover{color:var(--sand)}
.menu__aside{display:flex;flex-direction:column;gap:2rem;padding-bottom:1rem}
.menu__aside h5{font-size:var(--fs-micro);letter-spacing:.22em;text-transform:uppercase;opacity:.5;margin-bottom:.6rem;font-weight:700}
.menu__aside a:hover{color:var(--sand)}
.menu__socials{display:flex;flex-wrap:wrap;gap:.5rem;font-size:.8125rem;font-weight:600}
.menu__socials a{
  display:inline-flex;align-items:center;gap:.5rem;
  padding:.5rem .9rem;border-radius:999px;
  border:1px solid rgba(247,244,239,.2);
  transition:background-color .4s var(--e-out),border-color .4s var(--e-out),color .3s
}
.menu__socials a svg{width:16px;height:16px;flex:none}
.menu__socials a:hover{background:var(--brand,var(--cream));border-color:var(--brand,var(--cream));color:#fff}

/* ---------- Buttons ----------
   Hover limpio: el relleno crece desde el punto exacto por donde entra el
   cursor y se retira hacia donde sale. El botón NUNCA persigue al puntero.

   El relleno vive en el FONDO del propio botón, no en una capa hija.
   Dos cajas redondeadas apiladas se suavizan (antialias) por separado, así
   que el píxel del canto mezcla hijo + fondo del padre: eso dejaba un filo
   claro alrededor de la píldora al pintarse de navy. Con un único
   radial-gradient sólo hay una curva que suavizar contra la página: cero filo.
   Además el disco se mide contra la esquina más lejana (100% = cubre seguro),
   así que aunque el cursor entre o salga por fuera de la caja —--my puede ser
   negativo— el relleno siempre termina de pintar el botón entero.
   La línea de las variantes con borde es un anillo interior (inset box-shadow):
   no añade caja ni segunda curva, y se apaga antes de que el relleno la alcance. */
@property --p{syntax:"<number>";inherits:true;initial-value:0}
/* nivel de relleno (0–1) de los iconos que se llenan como una copa: mismo
   truco que el botón — el color vive en el fondo del propio elemento, no en
   una capa hija, para que el canto redondo se suavice una sola vez. */
@property --lvl{syntax:"<number>";inherits:false;initial-value:0}

.btn{
  --btn-bg:var(--navy); --btn-fg:var(--cream); --btn-fg-hi:var(--white);
  --btn-fill:var(--rose); --btn-line:transparent;
  --p:0; --mx:50%; --my:50%;
  --btn-line-a:clamp(0, calc(1 - var(--p) * 2.2), 1);
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:.7rem;
  padding:1.05rem 1.9rem;border-radius:999px;overflow:hidden;isolation:isolate;
  font-size:.8125rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  /* El fondo base salta al color del relleno en el último 6% del gesto. El
     relleno es un degradado radial recortado por un canto redondo: en los
     píxeles fraccionarios del borde el navegador mezcla el degradado con lo
     que hay DEBAJO, y ese debajo era el color de reposo — quedaba un hilo
     claro perfilando el botón lleno, que es el "borde sucio". Al llegar a
     0.94 el círculo ya cubre el 94% del radio, así que el cambio de base
     ocurre bajo el relleno y sólo se nota en que la costura desaparece. */
  background-color:color-mix(in oklab, var(--btn-bg),
    var(--btn-fill) calc(clamp(0, (var(--p) - .94) * 17, 1) * 100%));
  background-image:radial-gradient(circle at var(--mx) var(--my),
    var(--btn-fill) 0 calc(var(--p) * 100%),
    transparent calc(var(--p) * 100.4%));
  box-shadow:inset 0 0 0 1px
    color-mix(in srgb, var(--btn-line) calc(var(--btn-line-a) * 100%), transparent);
  color:color-mix(in oklab, var(--btn-fg), var(--btn-fg-hi) calc(var(--p) * 100%));
  transform:translateY(calc(var(--p) * -2px));
  transition:--p .5s var(--e-out),color .3s var(--e-out),scale .18s var(--e-soft);
  will-change:transform
}
.btn svg{width:17px;height:17px;transform:translateX(calc(var(--p) * 6px))}
.btn:active{scale:.975}
.btn:focus-visible{outline:2px solid var(--rose);outline-offset:3px}

@media (hover:hover){
  .btn:hover{--p:1}
}
.btn:focus-visible{--p:1}

/* navy → rosa */
.btn--ghost{
  --btn-bg:transparent;--btn-fg:currentColor;--btn-fg-hi:var(--cream);
  --btn-fill:var(--navy);--btn-line:currentColor
}
/* sobre superficie oscura el relleno navy se pierde contra el fondo: se invierte.
   Los tokens van aqui y no como color inline, si no el color-mix del texto no aplica. */
.hero__cta .btn--ghost,
.ph--dark .btn--ghost{
  --btn-fg:var(--cream);--btn-fg-hi:var(--navy);
  --btn-fill:var(--cream);--btn-line:var(--cream)
}
/* El botón claro vive SIEMPRE sobre superficie oscura (footer, menú, hero,
   la banda navy de galería). Rellenarlo de navy lo hacía desaparecer contra
   ese fondo: quedaba el texto flotando y el hilo crema del canto, que leía
   como un fallo de dibujo. Se rellena de rosa crema — sube el contraste con
   el fondo en vez de perderlo — y el texto se queda oscuro, que sobre
   #E4C9C4 es la lectura más limpia. */
.btn--light{
  --btn-bg:var(--cream);--btn-fg:var(--navy);--btn-fg-hi:var(--ink);
  --btn-fill:var(--rose-soft)
}
.btn--sm{padding:.72rem 1.3rem;font-size:.6875rem}
.btn--wide{padding-inline:2.6rem}

@media (prefers-reduced-motion: reduce){
  .btn{transition:--p .01s linear,color .01s linear}
}

/* text link with arrow */
.tlink{
  display:inline-flex;align-items:center;gap:.55rem;font-size:.8125rem;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;position:relative;padding-bottom:.4rem
}
.tlink::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;background:currentColor;
  transform-origin:right;transform:scaleX(1);transition:transform .5s var(--e-out)
}
.tlink:hover::after{transform:scaleX(0);transform-origin:left}
.tlink svg{width:16px;height:16px;transition:transform .5s var(--e-out)}
.tlink:hover svg{transform:translate(4px,-4px)}

/* ---------- Reveal primitives ----------
   CSS-driven + IntersectionObserver. No dependen de GSAP ni de rAF:
   si la pestaña arranca en segundo plano o el CDN falla, el contenido
   igual queda visible y legible. GSAP sólo añade parallax y scrub.     */
.r-line{
  display:block;overflow:hidden;
  /* La máscara recortaba descendentes (p, g, q), tildes y el vuelo de las
     itálicas porque los títulos usan line-height < 1. Ampliamos la caja de
     recorte y la compensamos con márgenes negativos: cero impacto en la
     maquetación, cero glifos cortados. */
  padding:.34em .22em;margin:-.34em -.22em
}
.r-line > span{display:block}
.r-mask{overflow:hidden;position:relative}
.r-mask > img,.r-mask > video{will-change:transform}

.js .r-fade{
  opacity:0;transform:translate3d(0,30px,0) scale(.988);
  transition:opacity .8s var(--e-out),transform 1.05s var(--e-hero)
}
.js .r-fade.is-in{opacity:1;transform:none}

.js .r-clip{clip-path:inset(0 0 100% 0);transition:clip-path 1.25s var(--e-out)}
.js .r-clip.is-in{clip-path:inset(0 0 0% 0)}

.js [data-stagger] > *{
  opacity:0;transform:translate3d(0,32px,0) scale(.99);
  transition:opacity .75s var(--e-out),transform 1s var(--e-hero)
}
.js [data-stagger].is-in > *{opacity:1;transform:none}

/* Variante "barrido": la fila se descubre de izquierda a derecha en vez de
   subir. Para listas largas — 24 precios subiendo a la vez es una ola; 24
   descubriéndose es una carta que se está escribiendo. */
.js [data-stagger="wipe"] > *{
  opacity:0;transform:none;clip-path:inset(0 100% 0 0);
  transition:opacity .45s var(--e-out),clip-path .9s var(--e-out)
}
.js [data-stagger="wipe"].is-in > *{opacity:1;clip-path:inset(0 0 0 0)}

/* ---- Titulares: la unidad que se mueve es la PALABRA, no la línea ----
   Antes subía el bloque entero de cada línea con 75 ms entre ellas: dos
   losas despegando por turnos, que es justo lo que se veía "a saltos".
   Ahora cada palabra sale de debajo de su máscara con un giro corto desde
   la esquina inferior izquierda y un retardo propio (--wd) que el JS
   calcula sobre línea + palabra. El desfase total va tope ~.6 s, así que
   lee como un solo gesto en cascada y no como piezas sueltas.
   Sólo transform: una capa compuesta por palabra, cero layout, cero pintado.
   El desplazamiento lleva +.9em porque .r-line acolcha .34em para no cortar
   descendentes: sin ese extra asomaría la coronilla de la palabra.      */
.js [data-split] .w{
  transform:translate3d(0,calc(106% + .9em),0) rotate(5deg);
  transform-origin:0% 100%;
  transition:transform 1.15s var(--e-hero);
  transition-delay:var(--wd,0s)
}
.js [data-split].is-in .w{transform:none}

/* Los .r-line son bloques hermanos con margen vertical negativo. En flujo
   normal esos márgenes COLAPSAN (gana el más negativo, no la suma) y las
   líneas del titular se separaban .34em de más. En columna flex no colapsan. */
[data-split="1"]{display:flex;flex-direction:column}

/* Relevo de titulares del slider: la portada nueva entra desde abajo (regla
   de arriba) y la anterior sale por arriba, como un rodillo. La salida usa
   su propio escalonado (--wo), más apretado: irse rápido, llegar con calma. */
.js [data-split].is-out .w{
  transform:translate3d(0,calc(-106% - .9em),0) rotate(-4deg);
  transition:transform .46s var(--e-exit);
  transition-delay:var(--wo,0s)
}
.js .hero__sub.is-out{
  opacity:0;transform:translate3d(0,-14px,0);
  transition:opacity .3s var(--e-exit),transform .38s var(--e-exit)
}
.js .hero__cta.is-out{
  opacity:0;transform:translate3d(0,-10px,0);
  transition:opacity .26s var(--e-exit),transform .34s var(--e-exit)
}

/* will-change sólo mientras dura el gesto: el JS pone .is-anim al lanzar y
   lo quita al terminar. Mantener 40 capas vivas todo el scroll es lo que
   hace que la siguiente animación arranque con tirón. */
.js .is-anim .w,
.js .is-anim.r-fade,
.js .is-anim[data-stagger] > *{will-change:transform}

/* si algo va mal (sin JS, sin IO, rAF congelado) todo queda visible */
html.no-motion .r-fade,
html.no-motion [data-stagger] > *{opacity:1 !important;transform:none !important}
html.no-motion .r-clip{clip-path:none !important}
html.no-motion [data-split] .w{transform:none !important}

/* ---------- Hero ---------- */
.hero{
  position:relative;min-height:100svh;display:flex;align-items:center;
  overflow:hidden;color:var(--cream);isolation:isolate;
  padding-block:clamp(6rem,12vw,9rem) clamp(5rem,10vw,7rem)
}
.hero__media{position:absolute;inset:-8% 0 -8%;z-index:-2;will-change:transform}
/* El <canvas> del glass-slider lo inserta el motor aquí dentro, con estilos en
   línea. El <img> es el LCP, la textura 0 y el respaldo permanente: su
   object-position lo escribe el JS para replicar el encuadre del shader. */
.hero__media img{width:100%;height:100%;object-fit:cover}
.hero__poster{position:absolute;inset:0;z-index:0}
/* Desborda a propósito por arriba y por abajo: el hero recorta (overflow
   hidden) y así el velo cubre siempre hasta el borde, sin franjas claras. */
.hero__scrim{
  position:absolute;inset:-14% 0;z-index:-1;
  /* Paradas corridas para compensar el desborde: 11% y 89% del velo son el
     borde superior e inferior reales del hero. */
  background:
    linear-gradient(180deg,rgba(11,15,36,.55) 11%,rgba(11,15,36,.28) 41%,rgba(11,15,36,.72) 89%),
    radial-gradient(120% 62% at 50% 50%,rgba(11,15,36,.42) 0%,rgba(11,15,36,0) 70%)
}
.hero__in{
  width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gut);
  display:flex;flex-direction:column;align-items:center;text-align:center
}
.hero__title{
  font-family:var(--serif);font-size:var(--fs-mega);line-height:.85;letter-spacing:-.035em;
  color:var(--white)
}
.hero__title em{font-style:italic;color:var(--white)}
.hero__row{
  display:flex;flex-direction:column;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(1.1rem,2.2vw,1.6rem);margin-top:clamp(1.75rem,3.2vw,2.75rem)
}
/* Cada portada trae su propia bajada y no todas ocupan las mismas líneas.
   Reservamos tres y centramos dentro: así los botones no saltan al cambiar. */
.hero__sub{
  max-width:46ch;font-size:var(--fs-lead);color:rgba(247,244,239,.86);line-height:1.45;
  min-height:calc(1.45em * 3);display:flex;align-items:center;justify-content:center
}
.hero__cta{justify-content:center}

/* Paginador del slider. Cada barra es la cadencia de su portada: el JS le
   escribe un scaleX de 0 a 1 a 60 Hz, así que sólo toca el compositor.
   Trazo fino (1 px) y corto: la marca de tiempo se lee, no compite con el
   titular. Lo memorable pasa en el CAMBIO de portada, no cada frame:
   - la activa se ESTIRA al doble de ancho y engorda a 2 px,
   - la que termina se DRENA hacia la derecha en vez de saltar a cero.
   El ancho sólo cambia 4 veces por vuelta y sobre 4 cajas absolutas, así
   que ese layout es irrelevante; el relleno sigue siendo compositor puro. */
.hero__pager{
  position:absolute;left:50%;bottom:clamp(1.5rem,3.5vw,2.75rem);transform:translateX(-50%);
  z-index:3;display:flex;align-items:center;gap:.55rem
}
.hero__pg{
  position:relative;width:clamp(16px,2.2vw,26px);padding:.85rem 0;
  -webkit-tap-highlight-color:transparent;
  transition:width .75s var(--e-hero)
}
.hero__pg.is-on{width:clamp(34px,5vw,62px)}
.hero__pg::before,.hero__pg i{
  content:"";position:absolute;left:0;right:0;top:50%;height:1px;margin-top:-.5px;
  transition:height .45s var(--e-hero),margin-top .45s var(--e-hero)
}
.hero__pg::before{background:rgba(247,244,239,.24);transition:background-color .45s var(--e-out)}
.hero__pg i{background:var(--sand);transform:scaleX(0);transform-origin:left}
/* Sólo la activa mueve píxeles: es la única con capa propia. */
.hero__pg.is-on i{height:2px;margin-top:-1px;will-change:transform}
.hero__pg:hover::before{background:rgba(247,244,239,.5)}
.hero__pg.is-on::before{background:rgba(247,244,239,.4)}
.hero__pg:focus-visible{outline:2px solid var(--sand);outline-offset:6px}
html.no-motion .hero__pg,
html.no-motion .hero__pg i,
html.no-motion .hero__pg::before{transition:none !important}

/* ---------- Marquee ----------
   Una sola cinta para toda la web: mismo tamaño, mismo ritmo y mismas letras
   RELLENAS. La versión anterior alternaba una frase en contorno itálico —
   letras huecas que a este cuerpo se leían como un error de render — y se
   desvanecía por los lados con una máscara, que sobre fondo claro dejaba las
   palabras a medio borrar. Fuera las dos cosas: el corte es limpio contra el
   borde, y lo que da ritmo es el separador (un diamante limpio) y el acento
   rosé alterno, que sigue siendo tinta sólida. El logotipo salía de separador
   y ahí se leía como una marca de agua repetida: mejor una figura neutra.

   La única diferencia entre la cinta clara y la navy son tres tokens.       */
.marquee{
  --mq-ink:var(--navy);
  --mq-accent:var(--rose);
  --mq-line:var(--line-soft);
  --mq-bg:var(--paper);
  position:relative;overflow:hidden;white-space:nowrap;
  border-block:var(--hair) solid var(--mq-line);
  padding-block:clamp(.9rem,2vw,1.6rem);background:var(--mq-bg)
}
.marquee--navy{
  --mq-ink:var(--cream);
  --mq-accent:var(--sand);
  --mq-line:rgba(247,244,239,.16);
  --mq-bg:var(--navy);
  color:var(--cream)
}
.marquee__track{display:inline-flex;gap:0;will-change:transform}
.marquee__track span{
  font-family:var(--serif);font-style:normal;
  font-size:clamp(1.75rem,4.2vw,3.5rem);line-height:1.05;letter-spacing:-.025em;
  color:var(--mq-ink);
  padding-inline:clamp(.65rem,1.6vw,1.35rem);
  display:inline-flex;align-items:center;gap:clamp(.65rem,1.6vw,1.35rem)
}
/* Ritmo por color, nunca por contorno: una sí, una no en el acento — pero
   siempre tinta sólida. */
.marquee__track span:nth-child(even){color:var(--mq-accent)}
/* separador = diamante limpio (rombo sólido, sin dependencias de fuente) */
.marquee__track span::after{
  content:"";flex:none;
  width:clamp(.5rem,1.05vw,.82rem);aspect-ratio:1;
  background:var(--mq-ink);opacity:.42;
  clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)
}
/* Bucle de reserva en CSS puro, para cuando no hay GSAP: mismo recorrido que
   el de JS. --mq-w lo escribe initMarquee al medir; el 50% de reserva vale
   porque la cinta siempre es el contenido duplicado exacto. */
@keyframes mq-left{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(calc(var(--mq-w,50%) * -1),0,0)}
}
@keyframes mq-right{
  from{transform:translate3d(calc(var(--mq-w,50%) * -1),0,0)}
  to{transform:translate3d(0,0,0)}
}
.marquee--css .marquee__track{animation:mq-left var(--mq-dur,32s) linear infinite}
.marquee--css[data-dir="right"] .marquee__track{animation-name:mq-right}
@media (prefers-reduced-motion:reduce){
  .marquee__track{transform:none !important;animation:none !important}
}

/* ---------- Section head ---------- */
.shead{display:grid;gap:clamp(1rem,2.5vw,2rem);margin-bottom:clamp(2.5rem,5vw,4.5rem)}
.shead--split{grid-template-columns:1.15fr .85fr;align-items:end}
.shead__title{max-width:16ch}
.shead__aside{max-width:46ch}

/* ---------- Intro / about split ---------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2rem,5vw,5.5rem);align-items:center}
.split--wide{grid-template-columns:.95fr 1.05fr}
.figure{position:relative;overflow:hidden;border-radius:var(--radius-lg)}
.figure img{width:100%;height:100%;object-fit:cover;transform:scale(1.14);will-change:transform}
.figure--tall{aspect-ratio:3/4}
.figure--wide{aspect-ratio:4/3}
.figure--sq{aspect-ratio:1/1}
.figure__cap{
  position:absolute;left:1rem;bottom:1rem;padding:.55rem 1rem;border-radius:999px;
  background:rgba(255,255,255,.92);backdrop-filter:blur(8px);
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:var(--navy)
}

/* ==========================================================================
   INTRO — "el díptico"

   Cabecera compacta arriba y, debajo, una composición de tres piezas que
   cuelgan del mismo filete: foto apaisada, ficha de cifras y foto cuadrada
   apoyada en la línea de base. Una sola voz grande —el titular—; las cifras
   acompañan.

   Antes eran cinco piezas en fila con tres cifras de 7rem. Dos motivos para
   cambiarlo: esas cifras competían con el titular en la misma pantalla, y
   decían lo mismo que la banda de estadísticas que llega dos secciones más
   abajo. Lo que se conserva del original es el desfase — sin él esto serían
   tres cajas alineadas.
   ========================================================================== */
.intro{position:relative;padding-block:var(--sec)}

.intro__head{
  display:grid;grid-template-columns:1.15fr .85fr;
  gap:clamp(1.5rem,4vw,4.5rem);align-items:end
}
.intro__title{max-width:15ch}
.intro__title em{font-style:italic;color:var(--rose)}
.intro__aside{max-width:44ch;padding-bottom:.35rem}
.intro__aside .lead{font-size:1.0625rem;line-height:1.6}

/* ── El díptico ───────────────────────────────────────────────────────────
   Antes: cinco piezas en una fila —tres cifras de 7rem y dos fotos de 232px
   apretadas entre ellas—. Dos problemas reales: las cifras pesaban tanto
   como el titular (dos voces gritando la misma frase) y decían exactamente
   lo mismo que la banda de estadísticas de más abajo.

   Ahora mandan las fotos y las cifras son ficha técnica. Se conserva lo
   único que valía de la versión anterior: las piezas cuelgan de un mismo
   filete y una de ellas baja a la línea de base. Ese desfase es el gesto;
   lo que cambia es quién lleva la voz.                                    */
.dip{
  display:grid;
  grid-template-columns:minmax(0,5.8fr) minmax(180px,3fr) minmax(0,3.2fr);
  gap:clamp(1.25rem,3vw,3.25rem);
  align-items:end;
  margin-top:clamp(2.25rem,4.5vw,3.75rem);
  padding-top:clamp(1.75rem,3.5vw,3rem);
  border-top:var(--hair) solid var(--line)
}

.dip__plate{position:relative;margin:0}
/* La apaisada cuelga del filete; la vertical se apoya abajo. */
.dip__plate--wide{align-self:start}
.dip__plate--tall{align-self:end;margin-bottom:clamp(1.25rem,2.5vw,2.25rem)}

/* Recorta el MARCO, no la figura: así el chip puede salirse del borde sin
   que la máscara de entrada (micro.css lo engancha por ser padre directo
   de la imagen) se lo coma. */
.dip__frame{
  display:block;position:relative;overflow:hidden;
  border-radius:var(--radius-lg);background:var(--sand)
}
/* Las proporciones no son decorativas: son las que producen el desfase. La
   apaisada cuelga del filete y mide más alto que la segunda, así que la
   segunda —apoyada abajo— arranca ~110px por debajo de la línea. Con dos
   piezas de altura parecida el zigzag desaparece y quedan dos cajas. */
.dip__plate--wide .dip__frame{aspect-ratio:5/4}
.dip__plate--tall .dip__frame{aspect-ratio:1/1}
.dip__frame img{
  width:100%;height:100%;object-fit:cover;display:block
}
/* Velo bajo el pie. El text-shadow solo no salvaba un pie hueso sobre la
   esquina clara de una foto. */
.dip__frame::after{
  content:"";position:absolute;inset:auto 0 0;height:45%;pointer-events:none;
  background:linear-gradient(rgba(11,15,36,0),rgba(11,15,36,.46))
}
.dip__cap{
  position:absolute;left:clamp(.85rem,1.6vw,1.25rem);bottom:.85rem;z-index:2;
  font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  font-weight:700;color:var(--cream);text-shadow:0 1px 12px rgba(11,15,36,.5)
}

/* ── La ficha ─────────────────────────────────────────────────────────────
   Renglones separados por filete, cifra en serif y etiqueta en micro. Cabe
   entre las dos fotos y se lee como pie de página de la composición, no
   como titular rival.                                                     */
.ledger{
  list-style:none;margin:0;padding:0;align-self:end;
  padding-bottom:clamp(1.25rem,2.5vw,2.25rem)
}
.ledger__item{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  align-items:baseline;gap:.85rem;
  padding-block:clamp(.7rem,1.5vw,1.1rem);
  border-top:var(--hair) solid var(--line-soft)
}
.ledger__item:first-child{border-top:0;padding-top:0}
.ledger__item:last-child{padding-bottom:0}
.ledger__n{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2rem,3.4vw,3.5rem);line-height:.85;letter-spacing:-.04em;
  color:var(--navy);font-variant-numeric:tabular-nums
}
.ledger__item:nth-child(2) .ledger__n{color:var(--rose)}
.ledger__l{
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;color:var(--muted);line-height:1.5
}

/* --- Chip "Copa de Rosé": el remate de marca, cosido a la foto --- */
.pour{
  display:flex;align-items:center;gap:.8rem;white-space:nowrap;
  padding:.6rem 1.1rem .6rem .6rem;
  background:var(--paper);color:var(--navy);
  border:var(--hair) solid var(--line);border-radius:999px;
  transition:transform .7s var(--e-out),border-color .5s var(--e-out)
}
/* Colgando del borde inferior de la apaisada, mordiéndolo: una etiqueta
   cosida a la imagen. Flotando encima tapaba foto; al lado era una caja
   más en la fila. La sombra la despega del borde sin dibujar un marco. */
.dip__pour{
  position:absolute;z-index:3;
  right:clamp(1rem,2.2vw,1.9rem);bottom:0;transform:translateY(46%);
  box-shadow:0 10px 30px -14px rgba(11,15,36,.4)
}
.dip__plate--wide:hover .dip__pour{transform:translateY(46%) translateY(-4px);border-color:var(--rose)}
/* nivel de vino dentro de la copa: sube al pasar el cursor por la foto.
   Va en el fondo del propio círculo (no en una capa hija recortada) para que
   el canto no deje el filo claro del fondo asomando bajo el vino. */
.pour__ico{
  --lvl:.36;
  position:relative;overflow:hidden;
  flex:none;width:34px;height:34px;border-radius:50%;
  display:grid;place-items:center;color:var(--navy);
  background-color:var(--rose-soft);
  background-image:linear-gradient(to top,
    rgba(192,140,134,.98) 0,
    rgba(228,201,196,.95) calc(var(--lvl) * 100%),
    transparent calc(var(--lvl) * 100% + 1px));
  transition:--lvl 1s var(--e-out)
}
.dip__plate--wide:hover .pour__ico{--lvl:.84}
/* Sin hover en las fotos del dip: se quedan quietas a propósito. */
.pour__ico svg{width:17px;height:17px}
.pour__txt{display:grid;gap:.15rem;line-height:1}
.pour__txt strong{font-family:var(--serif);font-size:1.15rem;line-height:1}
.pour__txt span{
  font-size:.625rem;letter-spacing:.16em;text-transform:uppercase;
  font-weight:700;opacity:.62
}

/* ---------- Manifiesto (por qué somos distintos) ---------- */
/* Mismo gesto que el índice del reel (.reel__row), y por la misma razón: en
   una lista de filas anchas lo que se lee como cuidado es que NADA cambie de
   tamaño al pasar el cursor. Antes la foto crecía de 148 px a 250 px — animar
   `width` obliga a rehacer la caja en cada fotograma, y ése era el tirón que
   se sentía tosco. Ahora la foto ocupa siempre su columna y el hover sólo
   mueve color, un empujón de milímetros y un zoom DENTRO del recorte: todo
   compuesto, cero reflow. */
.man{border-top:var(--hair) solid var(--line)}
.man__row{
  position:relative;isolation:isolate;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) clamp(132px,15vw,196px) auto;
  gap:clamp(1.25rem,3vw,2.75rem);align-items:center;
  --man-py:clamp(1.35rem,2.6vw,2rem);
  --man-px:clamp(.75rem,1.6vw,1.35rem);
  padding-block:var(--man-py);
  padding-inline:var(--man-px);
  margin-inline:calc(-1 * var(--man-px));
  border-bottom:var(--hair) solid var(--line);
  cursor:pointer
}
/* Lavado de ARENA, no de rosa. El rosa a media opacidad sobre una banda de
   1500 px tiraba a chicle; la arena es el papel de la casa un tono más denso y
   deja que el color lo pongan sólo el filete, el número y el ícono. */
.man__row::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  border-radius:var(--radius-media);
  background:var(--sand);opacity:.5;
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .75s var(--e-silk)
}
/* Filete de acento que se DIBUJA sobre el separador, en vez de encenderse. */
.man__row::after{
  content:"";position:absolute;left:0;right:0;bottom:calc(-1 * var(--hair));
  height:var(--hair);background:var(--rose);pointer-events:none;
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .7s var(--e-out)
}
.man__n{
  font-size:clamp(1.5rem,2.6vw,2.25rem);line-height:1;color:var(--rose);
  font-variant-numeric:tabular-nums;width:2.5ch;flex:none;
  /* La entrada mueve `translate` (con el retardo heredado de --sd); el hover
     sólo cambia color. Propiedades distintas para que el hover nunca herede el
     retardo de la cascada de entrada. */
  translate:0 0;
  transition:translate .65s var(--e-hero) calc(var(--sd,0s) + .06s),
             opacity .6s var(--e-silk) calc(var(--sd,0s) + .06s),
             color .5s var(--e-out)
}
.man__txt{
  display:grid;gap:.5rem;max-width:60ch;translate:0 0;
  transition:translate .65s var(--e-hero) calc(var(--sd,0s) + .11s),
             opacity .6s var(--e-silk) calc(var(--sd,0s) + .11s)
}
.man__t{display:flex;align-items:center;gap:.7rem;transition:transform .6s var(--e-silk)}
.man__ico{
  width:20px;height:20px;color:var(--navy);flex:none;display:block;
  transition:color .5s var(--e-out)
}
.man__ico svg{width:100%;height:100%}
.man__txt p{color:var(--muted);font-size:.9375rem;line-height:1.6}
/* Cada fila lleva a su página. Dos anclas al mismo destino y con papeles
   distintos: `.man__link` envuelve el titular y es la que ve el lector de
   pantalla y el tabulador; `.man__hit` es una lámina transparente que cubre la
   fila entera para que valga hacer clic en cualquier punto — va oculta a
   accesibilidad y fuera del orden de tabulación para no anunciar el mismo
   enlace dos veces.
   La lámina NO puede ser un ::after del titular: `.man__txt` lleva `translate`,
   que crea bloque contenedor, y el inset:0 se quedaba encerrado en la columna
   de texto sin llegar nunca a la foto. */
.man__link{color:inherit;text-decoration:none}
.man__link:focus-visible{outline:2px solid var(--rose);outline-offset:4px;border-radius:4px}
/* Insets negativos = el relleno de la fila. `inset:0` se ancla a la caja de
   relleno y dejaba muerta la franja de arriba y abajo: justo donde cae el
   cursor cuando apuntas al filete que separa una fila de otra. */
.man__hit{
  position:absolute;display:block;z-index:2;
  /* `inset:0` en un absoluto se ancla a la caja de RELLENO, o sea que la
     lámina ya cubre el padding entero de la fila. Con insets negativos se
     salía 12 px por cada lado y en móvil eso era scroll horizontal de la
     página: la fila ya está sacada a sangre con su margin negativo.        */
  inset:0
}
/* Botón circular SIEMPRE visible, igual que en el reel. Una flecha que sólo
   aparece al pasar el cursor obliga a descubrir que la fila era clicable; el
   disco lo dice de entrada y el hover se limita a rellenarlo. */
.man__go{
  width:clamp(36px,3.2vw,44px);aspect-ratio:1;border-radius:50%;flex:none;
  display:grid;place-items:center;
  border:var(--hair) solid var(--line);color:var(--navy);background:var(--white);
  transition:background-color .5s var(--e-out),color .5s var(--e-out),
             border-color .5s var(--e-out),transform .55s var(--e-out)
}
.man__go svg{width:14px;height:14px;margin-left:1px}
.man__img{
  width:100%;aspect-ratio:4/3;overflow:hidden;
  border-radius:var(--radius-media);background:var(--sand)
}
.man__img img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--e-silk)}

/* Los hovers sólo existen donde hay cursor: en táctil `:hover` se queda
   pegado tras el toque y la fila se queda encendida hasta que tocas otra. */
@media (hover:hover) and (pointer:fine){
  /* Cuatro cambios, todos del mismo tipo (color o milímetros) y todos con la
     misma curva. Se cayeron: el atenuado de las filas vecinas (parpadeaba la
     lista entera con cada barrido del ratón), la rotación del ícono y el
     crecimiento de la foto. */
  .man__row:hover::before{transform:scaleX(1)}
  .man__row:hover::after{transform:scaleX(1)}
  .man__row:hover .man__n{color:var(--navy)}
  .man__row:hover .man__t{transform:translate3d(.3rem,0,0)}
  .man__row:hover .man__ico{color:var(--rose)}
  .man__row:hover .man__img img{transform:scale(1.06)}
  .man__row:hover .man__go{
    background:var(--navy);border-color:transparent;color:var(--cream);
    transform:scale(1.06)
  }
}

/* Teclado: el mismo estado. Va fuera del @media porque el foco existe en todas
   partes, también en táctil con teclado conectado. */
.man__row:focus-within::before{transform:scaleX(1)}
.man__row:focus-within::after{transform:scaleX(1)}
.man__row:focus-within .man__n{color:var(--navy)}
.man__row:focus-within .man__ico{color:var(--rose)}
.man__row:focus-within .man__go{
  background:var(--navy);border-color:transparent;color:var(--cream)
}

/* Entrada. La fila sube como bloque (retardo inline de initReveals) y dentro
   el número y el texto llegan con centésimas de desfase: el mismo gesto
   contado en tres tiempos en vez de una losa. La foto no entra aquí — ya la
   destapa .mi-media con su clip-path y su barrido. */
.js .man[data-stagger] > .man__row{
  opacity:0;transform:translate3d(0,16px,0);
  transition:opacity .6s var(--e-silk),transform .8s var(--e-hero)
}
.js .man[data-stagger].is-in > .man__row{opacity:1;transform:none}
.js .man[data-stagger] .man__n,
.js .man[data-stagger] .man__txt{opacity:0;translate:0 16px}
.js .man[data-stagger].is-in .man__n,
.js .man[data-stagger].is-in .man__txt{opacity:1;translate:0 0}
html.no-motion .man__n,
html.no-motion .man__txt{opacity:1 !important;translate:none !important}
@media (prefers-reduced-motion:reduce){
  .man__row::before,.man__row::after{display:none}
  .man__n,.man__txt{opacity:1 !important;translate:none !important;transition:none}
  .man__img img{transition:none}
}

/* ==========================================================================
   PILARES — "Cómo trabajamos" (nosotros)

   Mismo principio que el .ledger: tres columnas hermanas separadas por FILETE,
   no por caja. Nada tiene relleno propio, así que la sección respira igual
   sobre blanco que sobre --bg-paper y no aparecen tres rectángulos grises
   flotando. La jerarquía la hacen el índice, el disco del icono y el aire.

   El separador es un pseudo-elemento y no un `border-left` a propósito: un
   borde ya está dibujado cuando el bloque entra, un pseudo puede DIBUJARSE
   de arriba abajo escalonado con la cascada de [data-stagger].
   ========================================================================== */
.pillars{
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(1.75rem,4vw,4rem);
  border-top:var(--hair) solid var(--line);
  padding-top:clamp(2.25rem,4.5vw,3.5rem)
}
.pillar{
  position:relative;
  display:grid;gap:clamp(.85rem,1.5vw,1.15rem);align-content:start;
  padding-left:clamp(1.25rem,2.6vw,2.5rem)
}
.pillar:first-child{padding-left:0}

.pillar + .pillar::before{
  content:"";position:absolute;left:0;top:.2rem;bottom:.2rem;width:var(--hair);
  background:var(--line-soft);
  transform:scaleY(0);transform-origin:top;
  transition:transform 1.1s var(--e-out)
}
.pillars.is-in .pillar + .pillar::before{transform:scaleY(1)}
/* los filetes entran DETRÁS de su columna, no a la vez: la rejilla se arma
   de izquierda a derecha en lugar de encenderse de golpe */
.pillars.is-in .pillar:nth-child(2)::before{transition-delay:.22s}
.pillars.is-in .pillar:nth-child(3)::before{transition-delay:.34s}

/* índice + icono comparten línea: el número ancla la columna a la izquierda */
.pillar__top{display:flex;align-items:center;gap:.9rem}
.pillar__n{
  font-size:var(--fs-micro);letter-spacing:.2em;font-weight:800;
  color:var(--rose);font-variant-numeric:tabular-nums;line-height:1
}
/* el rosé sube desde abajo como el nivel de la copa en .pour__ico, en vez de
   encenderse de golpe: es el mismo gesto de marca repetido. Igual que allí,
   el relleno es el fondo del círculo: una sola curva que suavizar, sin filo. */
.pillar__ico{
  --lvl:0;
  position:relative;flex:none;overflow:hidden;
  width:clamp(44px,3.6vw,52px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;
  color:var(--navy);border:var(--hair) solid var(--line);
  background-image:linear-gradient(to top,
    var(--rose-soft) 0 calc(var(--lvl) * 100%),
    transparent calc(var(--lvl) * 100% + 1px));
  transition:border-color .6s var(--e-out),--lvl .8s var(--e-out)
}
.pillar__ico svg{width:21px;height:21px;transition:transform .8s var(--e-out)}
.pillar:hover .pillar__ico{border-color:var(--rose);--lvl:1}
.pillar:hover .pillar__ico svg{transform:rotate(-8deg) scale(1.09)}

.pillar .h4{max-width:18ch}
.pillar p{color:var(--muted);font-size:.9375rem;line-height:1.65;max-width:40ch}
.pillar .tlink{color:var(--navy)}

/* ==========================================================================
   LA CARTA — explorador de servicios del home

   La versión anterior era una caja de alto fijo con DOS scrolls internos
   (el índice y la ficha). Un scroll dentro de una página que ya scrollea es
   una trampa: la rueda se come el gesto equivocado, en táctil compite con el
   scroll de la página, y visualmente convierte una sección editorial en un
   widget. Aquí no hay ni una sola caja con overflow.

   La altura la manda el CONTENIDO: tres columnas hermanas — índice, foto y
   ficha — estiradas a la misma fila. La foto no tiene alto propio, se estira
   con la fila; la ficha tampoco, crece con sus precios. Cambiar de categoría
   cambia la altura, y eso es correcto: una carta de 24 tratamientos ocupa
   más que una de 3.
   ========================================================================== */
.srv{padding-block:var(--sec)}
.srv .shead{margin-bottom:clamp(1.75rem,3vw,2.5rem)}
/* Dos líneas, siempre: el <br> del texto manda el corte y este ancho impide
   que la línea larga ("Todo lo que necesitas,") vuelva a partirse. 16ch —el
   tope del resto de titulares— la partía en tres. */
.srv .shead__title{max-width:22ch}

/* Una sola retícula para toda la sección: cinco columnas y un único gutter que
   comparten el índice y la ficha. Con chips de ancho libre el borde derecho
   quedaba dentado y nada se alineaba con la foto de abajo; en rejilla, diez
   categorías son exactamente 5 × 2 y las medianas caen donde las de la ficha. */
.carta{--cg:clamp(.8rem,1.5vw,1.35rem);margin-top:clamp(1.5rem,3vw,2.5rem)}

/* ── Índice: diez chips numerados ───────────────────────────────────────── */
/* grid-auto-rows:1fr iguala las dos filas a la más alta: en cuanto un nombre
   largo envuelve, la fila de arriba crecía y la de abajo no, y volvía el
   escalón que se quería quitar. */
.carta__index{
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  grid-auto-rows:1fr;gap:var(--cg);align-items:stretch;
  margin-bottom:clamp(1.5rem,3vw,2.25rem)
}
/* auto · 1fr · auto: el nombre se come el sobrante y el "desde" queda pegado
   al borde, así los precios forman columna a lo largo de la fila. */
.carta__i{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:.55rem;text-align:left;
  padding:.68rem 1.05rem;border:var(--hair) solid var(--line);border-radius:999px;
  color:var(--muted);
  transition:background-color .4s var(--e-out),border-color .4s var(--e-out),
             color .4s var(--e-out),transform .4s var(--e-out)
}
.carta__i:hover{border-color:var(--navy);color:var(--fg);transform:translateY(-1px)}
.carta__i.is-on{background:var(--navy);border-color:transparent;color:var(--cream)}
.carta__i:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.carta__n{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.14em;
  font-variant-numeric:tabular-nums;color:var(--sand-deep);
  transition:color .35s var(--e-out)
}
.carta__i.is-on .carta__n{color:var(--rose)}
/* Se le deja envolver: con celdas de ancho igual, "Depilación Láser Diodo"
   cae en dos renglones antes que forzar cinco columnas desiguales. */
.carta__nm{
  font-family:var(--sans);font-size:.875rem;font-weight:700;
  letter-spacing:.01em;line-height:1.2;color:inherit
}
.carta__fr{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.05em;
  font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--muted);
  padding-left:.6rem;border-left:var(--hair) solid var(--line);
  transition:color .35s var(--e-out)
}
.carta__i.is-on .carta__fr{color:var(--cream);opacity:.7;border-left-color:rgba(255,255,255,.28)}

/* ── Caja de la categoría abierta ───────────────────────────────────────── */
/* Misma retícula de cinco y mismo gutter que el índice: la foto ocupa dos
   columnas y la ficha tres, así el canto de la foto cae justo en la mediana
   entre el chip 2 y el 3. Ahí es donde antes no cuadraba nada. */
.carta__box{
  display:grid;grid-template-columns:repeat(5,minmax(0,1fr));
  column-gap:var(--cg);row-gap:clamp(1.25rem,3vw,2rem);align-items:stretch
}
.carta__box > *{min-width:0}
.carta__media{grid-column:span 2}
/* La ficha se estira hasta el canto inferior de la foto y su pie va con
   margin-top:auto — las dos columnas cierran en la misma línea en vez de
   dejar la foto colgando 240px por debajo. */
.carta__panel{grid-column:span 3;align-self:stretch}

/* ── Foto ───────────────────────────────────────────────────────────────── */
/* Retrato de proporción fija, pegado arriba y sticky: si dejáramos que se
   estirara con la fila, una categoría de 24 tratamientos la convertiría en una
   tira de 1:3. Al ser sticky acompaña a la lista de precios mientras bajas —
   que es exactamente lo que hacía el scroll interno, pero con el scroll de la
   página, que es el que el usuario ya está usando. */
/* Cuadrada, no 4/5: a dos columnas de cinco el retrato salía 690px de alto
   contra una ficha de 450 y descuadraba la fila. align-self:start la fija —
   al desplegar las 24 tarifas crece la ficha, no la foto. */
.carta__media{
  position:sticky;top:calc(var(--nav-h) + 1.25rem);align-self:start;
  overflow:hidden;border-radius:var(--radius-lg);
  background:var(--sand);aspect-ratio:1/1
}
.carta__fig{
  position:absolute;inset:0;opacity:0;transform:scale(1.07);
  transition:opacity .75s var(--e-out),transform 1.2s var(--e-out)
}
.carta__fig.is-on{opacity:1;transform:scale(1)}
.carta__fig img{width:100%;height:100%;object-fit:cover;display:block}
.carta__media::after{
  content:"";position:absolute;inset:auto 0 0 0;height:42%;pointer-events:none;
  background:linear-gradient(transparent,rgba(11,15,36,.55))
}
.carta__badge{
  position:absolute;left:1rem;bottom:.85rem;z-index:2;color:var(--cream);
  font-family:var(--serif);font-size:2rem;line-height:1;letter-spacing:-.02em
}
.carta__badge sup{
  font-family:var(--sans);font-size:.32em;font-weight:700;
  letter-spacing:.1em;opacity:.72;margin-left:.2em
}
/* El nombre sobre la foto cose las tres columnas: al pasar por el índice
   cambian a la vez la foto, el número y este pie. */
.carta__cap{
  position:absolute;right:1rem;bottom:1.1rem;left:4.5rem;z-index:2;text-align:right;
  color:var(--cream);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.16em;text-transform:uppercase
}

/* ── Ficha ──────────────────────────────────────────────────────────────── */
.carta__panel{display:flex;flex-direction:column}
.carta__eye{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--rose)
}
.carta__name{margin-top:.55rem}
.carta__tag{color:var(--muted);font-size:.9375rem;line-height:1.6;margin-top:.8rem;max-width:54ch}

/* columns y no grid: con 24 tratamientos el flujo por columnas reparte solo,
   y `break-inside:avoid` impide que una fila se parta por la mitad. */
.carta__prices{margin-top:clamp(1.25rem,2.4vw,1.9rem);columns:2;column-gap:clamp(1.5rem,3vw,2.75rem)}
/* Recorte por defecto: seis tarifas — tres filas en dos columnas. El resto se
   pide con el botón; volcar 24 de golpe era lo que desbordaba la sección. */
.carta__prices.is-clip .carta__p:nth-child(n+7){display:none}
.carta__p{
  display:flex;align-items:baseline;gap:.6rem;break-inside:avoid;
  padding:.66rem 0;border-bottom:1px dashed var(--line-soft);font-size:.9375rem;
  transition:padding-left .4s var(--e-out)
}
.carta__p:hover{padding-left:.45rem}
.carta__p b{font-weight:500;min-width:0;line-height:1.35}
.carta__p i{flex:1}
.carta__p em{
  font-style:normal;font-weight:700;color:var(--navy);white-space:nowrap;
  font-variant-numeric:tabular-nums;transition:color .35s var(--e-out)
}
.carta__p:hover em{color:var(--rose)}
/* Al cambiar de categoría los precios se descubren de izquierda a derecha,
   escalonados. El retardo lo escribe el JS en --d. */
.carta__panel.is-swap .carta__p{
  opacity:0;clip-path:inset(0 100% 0 0);
  animation:cartaIn .55s var(--e-out) forwards;animation-delay:var(--d,0s)
}
@keyframes cartaIn{to{opacity:1;clip-path:inset(0 0 0 0)}}

.carta__more{
  flex:none;
  display:inline-flex;align-items:center;gap:.5rem;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.16em;text-transform:uppercase;
  color:var(--navy);padding:.55rem .95rem;border-radius:999px;
  border:var(--hair) solid var(--line);
  transition:border-color .35s var(--e-out),background-color .35s var(--e-out),color .35s var(--e-out)
}
.carta__more:hover{border-color:var(--navy);background:var(--sand)}
.carta__more:focus-visible{outline:2px solid var(--navy);outline-offset:2px}
.carta__more svg{width:1em;height:1em;transition:transform .4s var(--e-out)}
.carta__more[aria-expanded="true"] svg{transform:rotate(180deg)}

/* Un solo renglón de cierre en vez de tres llamadas apiladas a la izquierda.
   Las dos acciones de lectura van juntas a la izquierda y "Reservar" se va al
   canto derecho de la ficha — que es el mismo canto que la foto y la retícula,
   así el pie cruza la ficha entera en lugar de amontonarse en 370 de 780px.
   El filete lo separa de la última tarifa sin repetir el punteado. */
.carta__foot{
  margin-top:auto;padding-top:clamp(1.4rem,2.4vw,1.9rem);
  border-top:var(--hair) solid var(--line);
  display:flex;align-items:center;justify-content:space-between;
  gap:1rem 1.5rem;flex-wrap:wrap
}
.carta__acts{
  display:flex;align-items:center;gap:clamp(.9rem,1.8vw,1.6rem);flex-wrap:wrap
}
/* El subrayado del tlink vive en su padding-bottom; sin esto queda 4px por
   debajo de la línea media de la pastilla y del botón. */
.carta__acts .tlink{transform:translateY(.2rem)}
/* Al partirse en dos renglones, "Reservar" deja de ser un botón suelto a la
   izquierda y pasa a barra: es la acción de la sección. */
@media (max-width:560px){
  .carta__foot{align-items:stretch}
  .carta__foot > .btn{width:100%}
}

/* ---------- Reel vertical ----------
   Una sola pieza: cabecera ancha arriba, y debajo un "escenario" donde el
   reproductor y el índice de capítulos comparten altura y filete. Los
   capítulos no son adorno — cada fila PREVISUALIZA el reel al enfocarla y
   SALTA a ese minuto al pulsarla; el capítulo en curso queda marcado. Una
   lista muerta al lado de un vídeo estrecho era lo que hacía que esta
   sección se leyera como relleno.                                        */
.reel__head{margin-bottom:clamp(2rem,4vw,3.25rem)}
.reel__kick{
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.24em;text-transform:uppercase;
  color:var(--rose);display:flex;align-items:center;gap:.75rem
}
.reel__kick::before{content:"";width:clamp(28px,4vw,56px);height:var(--hair);background:var(--rose)}
.reel__head .shead__aside{display:grid;justify-items:start}

/* El vídeo mide lo que mide (9:16); el índice se queda con TODO el resto.
   Así no queda aire muerto entre las dos columnas.                        */
.reel__stage{
  display:grid;grid-template-columns:auto minmax(0,1fr);
  gap:clamp(1.5rem,3.5vw,3rem);align-items:stretch
}
.reel__idx{display:flex;flex-direction:column;min-width:0}

.reel__lbl{
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.24em;text-transform:uppercase;
  color:var(--muted);display:flex;align-items:center;gap:.75rem;
  padding-bottom:.85rem
}
.reel__lbl::after{content:"";flex:1;height:var(--hair);background:var(--line)}

/* Las tres filas se reparten el alto del reproductor: el bloque lee como un
   objeto único y no como una lista suelta que sobra por abajo.            */
.reel__chapters{
  flex:1;display:grid;grid-template-rows:repeat(3,minmax(96px,1fr));
  border-top:var(--hair) solid var(--line)
}
.reel__row{position:relative;border-bottom:var(--hair) solid var(--line-soft)}
/* velo de arena que se abre desde la izquierda */
.reel__row::before{
  content:"";position:absolute;inset:0;z-index:0;background:var(--sand);opacity:.34;
  transform:scaleX(0);transform-origin:left;
  transition:transform .9s var(--e-silk)
}
/* el filete rosa se dibuja sobre el gris */
.reel__row::after{
  content:"";position:absolute;left:0;right:0;bottom:calc(var(--hair) * -1);
  height:var(--hair);background:var(--rose);
  transform:scaleX(0);transform-origin:left;
  transition:transform .8s var(--e-out)
}
.reel__row:hover::before,
.reel__row:focus-within::before,
.reel__row.is-on::before{transform:scaleX(1)}
.reel__row:hover::after,
.reel__row:focus-within::after,
.reel__row.is-on::after{transform:scaleX(1)}

.reel__ch{
  position:relative;z-index:1;width:100%;height:100%;cursor:pointer;text-align:left;
  display:grid;grid-template-columns:auto clamp(84px,8.5vw,122px) minmax(0,1fr) auto auto;
  align-items:center;gap:clamp(.9rem,1.8vw,1.6rem);
  padding:clamp(.85rem,1.6vw,1.25rem) clamp(.75rem,1.4vw,1.25rem);
  background:transparent;border:0;color:inherit;font:inherit
}
.reel__ch:focus-visible{outline:2px solid var(--rose);outline-offset:-4px}

.reel__t{
  align-self:start;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.12em;color:var(--rose);
  font-variant-numeric:tabular-nums;
  transition:color .45s var(--e-out)
}
.reel__row:hover .reel__t,
.reel__row.is-on .reel__t{color:var(--navy)}

/* La miniatura ya no se esconde: es la que da masa a la fila. Sólo se
   acerca un punto al pasar el puntero.                                    */
.reel__thumb{
  aspect-ratio:4/5;border-radius:var(--radius-media);overflow:hidden;background:var(--sand);
  pointer-events:none
}
.reel__thumb img{
  width:100%;height:100%;object-fit:cover;display:block;
  scale:1;transition:scale 1.1s var(--e-silk)
}
.reel__row:hover .reel__thumb img,
.reel__row:focus-within .reel__thumb img,
.reel__row.is-on .reel__thumb img{scale:1.07}

.reel__txt{display:grid;gap:.35rem;min-width:0}
.reel__c{
  font-size:clamp(1.0625rem,1.75vw,1.625rem);line-height:1.2;letter-spacing:-.015em;
  font-weight:700;color:var(--ink);
  transition:translate .7s var(--e-silk)
}
.reel__sub{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted)
}
.reel__row:hover .reel__c,
.reel__row:focus-within .reel__c{translate:.3rem 0}

.reel__time{
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.14em;color:var(--muted);
  font-variant-numeric:tabular-nums;
  transition:color .45s var(--e-out)
}
.reel__row:hover .reel__time,
.reel__row.is-on .reel__time{color:var(--navy)}

.reel__go{
  width:clamp(38px,3.4vw,46px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;
  border:var(--hair) solid var(--line);color:var(--navy);background:var(--white);
  transition:background-color .45s var(--e-out),color .45s,border-color .45s,transform .55s var(--e-out)
}
.reel__go svg{width:14px;height:14px;margin-left:2px}
.reel__row:hover .reel__go,
.reel__row:focus-within .reel__go,
.reel__row.is-on .reel__go{background:var(--navy);border-color:transparent;color:var(--cream);transform:scale(1.06)}

/* El reel es 9:16: se muestra en arco, del alto del índice. */
.vplay.vplay--arch{
  /* manda el ancho, no el alto: asi el reproductor pesa lo mismo que el
     indice y ninguna de las dos columnas queda estrangulada */
  aspect-ratio:var(--vp-ar, 9/16);width:clamp(300px,26vw,420px);height:auto;max-width:100%;
  justify-self:start;
  border-radius:999px 999px var(--radius-lg) var(--radius-lg)
}
/* Fotograma del capítulo sobre el que está el puntero. Vive bajo el velo y
   bajo el botón, así el reproductor no pierde su jerarquía.               */
.reel__peek{
  position:absolute;inset:0;z-index:0;opacity:0;pointer-events:none;
  transition:opacity .55s var(--e-out)
}
.reel__peek img{
  width:100%;height:100%;object-fit:cover;display:block;
  scale:1.08;transition:scale 1.2s var(--e-out)
}
.vplay.is-peek .reel__peek{opacity:1}
.vplay.is-peek .reel__peek img{scale:1}
.vplay.is-playing .reel__peek{opacity:0}

@media (prefers-reduced-motion:reduce){
  .reel__thumb img,.reel__peek img{scale:1;transition:none}
  .reel__c{transition:none}
  .reel__row::before,.reel__row::after{transition:none}
}

/* ---------- Gift cards ---------- */
.gc__grid{display:grid;grid-template-columns:1fr .9fr;gap:clamp(2.5rem,6vw,6rem);align-items:center}
.gc__lbl{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)
}
.gc__amts{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:1rem}
.gcamt{
  font-family:var(--serif);font-size:1.5rem;line-height:1;letter-spacing:-.02em;color:var(--navy);
  padding:.75rem 1.15rem;border:var(--hair) solid var(--line);border-radius:999px;background:transparent;
  font-variant-numeric:tabular-nums;
  transition:background-color .45s var(--e-out),color .35s var(--e-out),border-color .35s var(--e-out)
}
.gcamt i{font-family:var(--sans);font-style:normal;font-size:.5em;font-weight:800;letter-spacing:.06em;opacity:.55;margin-right:.25em}
.gcamt:hover{border-color:var(--navy)}
.gcamt.is-on{background:var(--navy);border-color:var(--navy);color:var(--cream)}
.gcamt.is-on i{opacity:.7}
.gcamt:focus-visible{outline:2px solid var(--rose);outline-offset:3px}

.gc__perks{margin-top:clamp(1.75rem,3vw,2.5rem);border-top:var(--hair) solid var(--line)}
.gc__perks li{
  padding:.8rem 0 .8rem 1.9rem;border-bottom:var(--hair) solid var(--line-soft);
  font-size:.9375rem;color:var(--muted);position:relative
}
.gc__perks li::before{
  content:"";position:absolute;left:.25rem;top:1.35rem;width:9px;height:9px;
  border-radius:50%;border:1px solid var(--rose)
}
.gc__cta{margin-top:clamp(1.75rem,3vw,2.5rem);display:flex;align-items:center;gap:1.75rem;flex-wrap:wrap}

.gc__stage{display:grid;place-items:center}
/* Objeto tarjeta: el navy vive aquí, no en el fondo de la sección.
   Lenguaje de la casa aplicado a un objeto: filete interior en vez de sombra,
   cifra fantasma en contorno (el mismo recurso que la cinta), y una troquelada
   real —puntos punzados, no un `dashed` de navegador—. Nada de skeuomorfismo
   de tarjeta bancaria: esto es un ticket de imprenta, no una Visa.         */
.gcard{
  width:100%;max-width:430px;aspect-ratio:1.586/1;
  background:var(--navy);color:var(--cream);border-radius:var(--radius-lg);
  padding:clamp(1.35rem,2.6vw,2rem);
  display:grid;grid-template-rows:auto 1fr auto auto;gap:.5rem;
  position:relative;overflow:hidden;isolation:isolate
}
/* luz de marca en la esquina + trama diagonal finísima: da materia al navy
   sin ensuciarlo. A 3% no se ve como textura, se ve como papel.           */
.gcard::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 90% at 88% 8%,rgba(192,140,134,.45),transparent 60%),
    repeating-linear-gradient(58deg,rgba(247,244,239,.05) 0 1px,transparent 1px 7px)
}
/* filete interior: el borde grabado que tiene cualquier vale impreso */
.gcard::before{
  content:"";position:absolute;z-index:2;pointer-events:none;
  inset:clamp(.55rem,1.1vw,.8rem);
  border:var(--hair) solid rgba(247,244,239,.18);
  border-radius:calc(var(--radius-lg) - clamp(.55rem,1.1vw,.8rem))
}
.gcard > *{position:relative;z-index:1}

.gcard__top{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.gcard__logo{width:clamp(84px,9vw,108px);height:auto}
.gcard__kind{
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.24em;text-transform:uppercase;opacity:.62
}

/* La cifra: serif enorme, alineada abajo, con su fantasma en contorno detrás.
   El fantasma es lo que hace que la tarjeta se lea como pieza gráfica y no
   como un rectángulo con un número encima.                                */
.gcard__amt{
  align-self:end;font-family:var(--serif);line-height:.9;letter-spacing:-.03em;
  font-size:clamp(3rem,6vw,4.5rem);display:flex;align-items:baseline;gap:.25rem;
  font-variant-numeric:tabular-nums
}
.gcard__amt i{font-family:var(--sans);font-style:normal;font-size:.28em;font-weight:800;letter-spacing:.08em;opacity:.6}
.gcard__ghost{
  position:absolute;z-index:0;right:-.08em;bottom:-.16em;pointer-events:none;
  font-family:var(--serif);font-style:italic;font-size:clamp(7rem,15vw,11rem);
  line-height:.72;letter-spacing:-.05em;font-variant-numeric:tabular-nums;
  color:transparent;-webkit-text-stroke:1px rgba(247,244,239,.14)
}

/* Troquelada de verdad: puntos punzados, no un borde discontinuo. */
.gcard__perf{
  height:var(--hair);
  background:repeating-linear-gradient(90deg,rgba(247,244,239,.42) 0 2px,transparent 2px 8px)
}

.gcard__foot{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;font-weight:700;opacity:.62
}
.gcard__id{letter-spacing:.2em;opacity:.9}

/* Reflejo especular al pasar por encima: un solo barrido, sin bucle. */
.gcard__gloss{
  position:absolute;inset:-45%;z-index:3;pointer-events:none;opacity:0;
  background:linear-gradient(102deg,
    transparent 30%,
    rgba(247,244,239,.045) 41%,
    rgba(247,244,239,.13) 50%,
    rgba(247,244,239,.045) 59%,
    transparent 70%);
  filter:blur(7px);
  transform:translateX(-52%)
}
/* La opacidad viaja dentro del keyframe. Antes se fijaba en :hover y la banda
   se quedaba aparcada sobre la tarjeta al acabar el barrido: ese resto estático
   era lo que se sentía tosco. Ahora entra, cruza y se apaga. */
.gc__stage:hover .gcard__gloss{animation:gcgloss 1.5s var(--e-soft) forwards}
@keyframes gcgloss{
  0%  {opacity:0;transform:translateX(-52%)}
  20% {opacity:1}
  72% {opacity:1}
  100%{opacity:0;transform:translateX(52%)}
}

/* Latido corto al cambiar de monto: confirma la elección sin mover el layout. */
.gcard.is-bump{animation:gcbump .55s var(--e-out)}
@keyframes gcbump{0%{transform:scale(1)}38%{transform:scale(1.022)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){
  .gcard.is-bump{animation:none}
  .gc__stage:hover .gcard__gloss{opacity:0;animation:none}
}

/* ---------- Cards / packages ---------- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1.25rem,2.5vw,2rem)}
.card{
  position:relative;display:flex;flex-direction:column;background:var(--paper);
  border:var(--hair) solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  /* La sombra en reposo va DECLARADA a cero, no omitida: sin un valor de
     partida el navegador no tiene desde dónde interpolar y la sombra
     aparecería de golpe en el primer frame en vez de crecer.            */
  box-shadow:0 0 0 0 rgba(11,15,36,0), 0 0 0 0 rgba(11,15,36,0)
}
/* El `.card.card` NO es un tic: es la especificidad mínima para empatar con
   `.js [data-stagger] > *` (línea 471), que declara `transition` completa
   para la entrada escalonada. Al ser una sola propiedad, esa regla pisaba
   la de la tarjeta entera — por eso `box-shadow` no transicionaba y el
   `transform` del hover salía con la curva de la ENTRADA. Aquí van los
   cuatro canales juntos: los dos de la entrada y los dos del hover.
   Esta lista es además la de SALIDA (la que corre al retirar el cursor) y
   dura más que la de entrada: el objeto se posa, no cae. Entrada y salida
   con el mismo tiempo es justo lo que hace que un hover lea a interruptor
   en vez de a gesto. */
.card.card{
  transition:opacity .75s var(--e-out),
             transform .8s var(--e-out),
             box-shadow .8s var(--e-out),
             border-color .65s var(--e-out)
}
/* Todo el hover vive tras `hover:hover`: en táctil el `:hover` se queda
   pegado tras el toque y la tarjeta se quedaba levantada hasta tocar otra. */
@media (hover:hover) and (pointer:fine){
  .card{will-change:transform}
  .card.card:hover{
    transform:translateY(-6px);
    /* Dos capas, no una: la corta es el contacto con el papel y la larga la
       difusa del aire. Una sola sombra lee a pegatina; dos leen a objeto
       realmente separado de la página. Ambas en negativo de spread, así el
       borde de la sombra nunca asoma por los lados del filete.          */
    box-shadow:0 4px 10px -8px rgba(11,15,36,.20),
               0 26px 50px -30px rgba(11,15,36,.30);
    /* El filete se oscurece; no salta a navy pleno. De rgba(.14) a #273569
       había tanto salto de contraste que el borde parpadeaba al entrar.  */
    border-color:color-mix(in oklab, var(--navy), transparent 62%);
    transition:transform .55s var(--e-out),
               box-shadow .55s var(--e-out),
               border-color .4s var(--e-out)
  }
  /* La tarjeta entera es zona de clic, así que tiene que hundirse al
     apretarla: si no, el -6px se queda colgado mientras el dedo ya empuja. */
  .card.card--go:active{transform:translateY(-2px);transition-duration:.12s}
}
.card__media{
  aspect-ratio:4/3;overflow:hidden;position:relative;
  margin:var(--media-pad) var(--media-pad) 0;border-radius:var(--radius-media)
}
/* Deriva lenta, no zoom. 1.07 en 1s era un empujón: se veía el reencuadre.
   1.035 en 1.4s no se ve moverse, sólo se nota que la imagen está viva.  */
.card__media img{width:100%;height:100%;object-fit:cover}
/* Otra vez especificidad, y otra vez por el mismo motivo: micro.css declara
   `transition:scale …` sobre `.js .mi-media > img` para su zoom de entrada,
   y `transition` es UNA propiedad — esa declaración borraba el canal de
   `transform`, así que el zoom del hover se aplicaba de golpe, en un frame.
   Eso era el salto que se veía. Aquí van los dos canales: el `scale` de la
   entrada (mismos valores que micro.css, para no cambiarle el gesto) y el
   `transform` del hover.                                                 */
.card.card .card__media img{
  transition:scale 1.6s var(--mi-e-hero, var(--e-hero)) var(--mi-d,0s),
             transform 1.4s var(--e-out)
}
@media (hover:hover) and (pointer:fine){
  .card.card:hover .card__media img{transform:scale(1.035)}
}
@media (prefers-reduced-motion:reduce){
  .card.card,.card.card .card__media img{transition:border-color .3s linear}
  .card.card:hover{transform:none;box-shadow:none}
  .card.card:hover .card__media img{transform:none}
}
.card__body{padding:clamp(1.4rem,2.4vw,2rem);display:flex;flex-direction:column;gap:1rem;flex:1}
.card__price{
  font-family:var(--serif);font-size:clamp(1.8rem,3vw,2.6rem);line-height:1;color:var(--navy);letter-spacing:-.02em
}
.card__price small{font-family:var(--sans);font-size:.7rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);display:block;margin-bottom:.4rem}
.card__list{display:grid;gap:.55rem;font-size:.9rem;color:var(--muted)}
.card__list li{display:flex;gap:.6rem;align-items:flex-start;line-height:1.45}
.card__list li::before{
  content:"";width:5px;height:5px;border-radius:50%;background:var(--rose);
  flex:none;margin-top:.55em
}
/* Toda la tarjeta es zona de clic. El enlace de verdad sigue siendo el botón
   —conserva foco, teclado y su etiqueta—; esta capa sólo estira el área al
   bloque entero, así que clic medio y "abrir en pestaña nueva" funcionan igual.
   Va oculta a lectores de pantalla para no anunciar el mismo destino dos veces. */
.card--go{cursor:pointer}
.card__hit{position:absolute;inset:0;z-index:1;border-radius:inherit}
.card__hit:focus{outline:none}
.card__foot{margin-top:auto;padding-top:.5rem;position:relative;z-index:2}
.card__notes{font-size:.75rem;color:var(--muted);opacity:.8;line-height:1.5;border-top:var(--hair) solid var(--line-soft);padding-top:.9rem}
.card__ribbon{
  position:absolute;top:calc(var(--media-pad) + .75rem);left:calc(var(--media-pad) + .75rem);
  z-index:2;background:var(--navy);color:var(--cream);
  padding:.4rem .85rem;border-radius:999px;font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;
  /* decorativa: el clic debe atravesarla hasta la capa de enlace */
  pointer-events:none
}

/* ---------- Gift cards ---------- */
/* Tarjeta física: proporción real de una tarjeta (85,6 × 54 mm) y cara crema,
   así funciona igual sobre la sección navy del home que sobre el fondo claro
   de gift-cards.html — antes las navy desaparecían contra la sección navy.  */
.gifts{display:grid;grid-template-columns:repeat(5,1fr);gap:clamp(.75rem,1.4vw,1.15rem)}
.gift{
  position:relative;aspect-ratio:1.586/1;border-radius:var(--radius-lg);overflow:hidden;
  background:var(--paper);color:var(--ink);
  border:var(--hair) solid var(--line);
  /* sin sombra: la tarjeta se separa con su propio borde */
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(.9rem,1.5vw,1.3rem);isolation:isolate;
  transition:transform .55s var(--e-out),
             background-color .45s var(--e-out),color .45s var(--e-out),border-color .45s
}
/* trama de marca, muy tenue, para que la cara no quede plana */
.gift::after{
  content:"";position:absolute;inset:0;z-index:-1;opacity:.07;
  background:url("../assets/img/pattern-azul.png") center/cover;
  transition:opacity .45s var(--e-out)
}
/* muesca troquelada en la esquina: detalle que la hace leer como tarjeta */
.gift::before{
  content:"";position:absolute;top:-18%;right:-12%;width:46%;aspect-ratio:1;
  border-radius:50%;border:1px solid currentColor;opacity:.14;pointer-events:none
}
.gift__top{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.gift__lbl{
  font-size:var(--fs-micro);letter-spacing:.22em;text-transform:uppercase;
  font-weight:800;opacity:.55
}
.gift__tag{
  font-size:.625rem;letter-spacing:.14em;text-transform:uppercase;font-weight:800;
  padding:.25rem .5rem;border-radius:999px;background:var(--rose);color:var(--cream);
  white-space:nowrap
}
.gift__amt{
  font-family:var(--serif);font-size:clamp(1.9rem,3.4vw,3rem);line-height:.95;
  letter-spacing:-.02em;display:flex;align-items:baseline;gap:.22em
}
.gift__amt i{font-family:var(--sans);font-style:normal;font-size:.36em;font-weight:800;letter-spacing:.06em;opacity:.55}
.gift__go{
  display:inline-flex;align-items:center;gap:.45rem;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.16em;text-transform:uppercase
}
.gift__go svg{width:15px;height:15px;transition:transform .45s var(--e-out)}
.gift:hover{
  background:var(--navy);color:var(--cream);border-color:var(--navy);
  transform:translateY(-8px)
}
.gift:hover::after{opacity:.16}
.gift:hover .gift__go svg{transform:translateX(4px)}
.gift:focus-visible{outline:2px solid var(--rose);outline-offset:3px}
/* la más regalada nace ya en navy */
.gift--feat{background:var(--navy);color:var(--cream);border-color:var(--navy)}
.gift--feat::after{opacity:.16}
.gift--feat .gift__lbl{opacity:.6}
.gift--feat:hover{background:var(--rose);border-color:var(--rose)}
.gift--feat:hover .gift__tag{background:var(--navy)}
/* sobre fondo navy la cara clara necesita un borde propio */

/* ---------- Índice de canje (gift cards) ----------
   "¿En qué se puede usar?" era diez titulares sueltos sin filete, sin precio
   y sin señal de que fueran enlaces: media pantalla en blanco que no
   respondía a la pregunta. Aquí las diez categorías son un índice de canje —
   número, nombre, cuántos servicios y desde cuánto — en dos columnas, que es
   lo que alguien con una tarjeta en la mano quiere leer: dónde la gasto y
   cuánto me alcanza. Un filete arriba y uno por fila: la misma retícula de
   tarifas que ya usa la carta de inicio, no un componente nuevo. */
.usos{
  list-style:none;margin-top:clamp(1.5rem,3vw,2.25rem);
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:clamp(2rem,4vw,4rem);
  border-top:var(--hair) solid var(--line)
}
.uso{border-bottom:var(--hair) solid var(--line);min-width:0}
.uso__a{
  display:grid;align-items:center;gap:0 clamp(.85rem,1.6vw,1.35rem);
  grid-template-columns:auto minmax(0,1fr) auto auto auto;
  padding:clamp(.95rem,1.8vw,1.3rem) .3rem;
  transition:padding-left .45s var(--e-out),background-color .45s var(--e-out)
}
.uso__a:hover{padding-left:1rem;background:var(--sand)}
.uso__a:focus-visible{outline:2px solid var(--navy);outline-offset:-2px}
.uso__n{
  font-family:var(--serif);font-size:1.05rem;line-height:1;
  color:var(--sand-deep);font-variant-numeric:tabular-nums
}
.uso__nm{
  font-size:1.0625rem;font-weight:600;letter-spacing:-.01em;color:var(--navy);
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap
}
.uso__ct{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap
}
/* El "desde" va contra un filete: es el dato que compara una fila con otra. */
.uso__fr{
  font-size:.875rem;font-weight:700;color:var(--navy);white-space:nowrap;
  font-variant-numeric:tabular-nums;
  padding-left:clamp(.85rem,1.6vw,1.35rem);
  border-left:var(--hair) solid var(--line)
}
/* Reserva su hueco desde el principio: si apareciera al pasar el ratón
   empujaría toda la fila. */
.uso__go{
  display:inline-flex;color:var(--navy);opacity:0;transform:translate(-6px,6px);
  transition:opacity .4s var(--e-out),transform .4s var(--e-out)
}
.uso__go svg{width:16px;height:16px}
.uso__a:hover .uso__go{opacity:1;transform:none}
@media (max-width:860px){
  .usos{grid-template-columns:1fr}
}
@media (max-width:560px){
  /* Dos renglones: nombre arriba, recuento debajo, y el precio alineado al
     canto derecho cruzando ambos. */
  .uso__a{grid-template-columns:auto minmax(0,1fr) auto;gap:.15rem .9rem}
  .uso__n{grid-row:1/3;align-self:center}
  .uso__nm{grid-column:2;grid-row:1;white-space:normal}
  .uso__ct{grid-column:2;grid-row:2;font-size:.6875rem}
  .uso__fr{grid-column:3;grid-row:1/3;align-self:center;border-left:0;padding-left:0}
  .uso__go{display:none}
}

/* ---------- Stats ---------- */
/* Tira de datos, no "cuatro columnas con una rayita".
   El filete superior era una línea muerta repetida cuatro veces. Aquí hay
   UN filete continuo que se DIBUJA de izquierda a derecha al entrar, y
   separadores verticales centrados en el canal entre columnas. */
.stats{
  position:relative;display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(1rem,3vw,2.5rem);padding-top:clamp(1.5rem,2.6vw,2.25rem)
}
.stats::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,
    transparent,rgba(247,244,239,.42) 12%,rgba(247,244,239,.42) 88%,transparent);
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.3s var(--e-hero)
}
.stats.is-in::before{transform:scaleX(1)}

.stat{position:relative}
/* separador en el canal, no pegado al texto: nace corto y crece */
.stat + .stat::before{
  content:"";position:absolute;left:calc(clamp(1rem,3vw,2.5rem) / -2);top:.15em;bottom:.9rem;
  width:1px;background:rgba(247,244,239,.16);
  transform:scaleY(0);transform-origin:top;
  transition:transform .9s var(--e-hero) .35s
}
.stats.is-in .stat + .stat::before{transform:scaleY(1)}

.stat__n{
  font-family:var(--serif);font-size:clamp(2.4rem,5.5vw,4.5rem);line-height:1;letter-spacing:-.03em;
  /* Cifras de ancho fijo: el contador sube de 0 a 129 y con cifras
     proporcionales el bloque entero temblaba en cada frame. */
  font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;
  transition:color .5s var(--e-out)
}
/* el ∞ no es una cifra: pide su propio tamaño para pesar lo mismo */
.stat__n:not(:has(span)):not([data-count]){font-size:clamp(2.9rem,6.4vw,5.2rem);line-height:.86}
/* max-width sin margin-inline:auto dejaba la caja pegada a la izquierda de
   su celda: el texto iba centrado dentro de una caja descentrada, y las
   cuatro etiquetas no cuadraban entre sí. */
.stat__l{
  font-size:var(--fs-micro);letter-spacing:.15em;text-transform:uppercase;
  color:rgba(247,244,239,.58);margin:.7rem auto 0;max-width:20ch;line-height:1.55;
  transition:color .5s var(--e-out)
}
/* micro-recompensa al pasar: la cifra vira a arena y la etiqueta despierta */
.stat:hover .stat__n{color:var(--sand)}
.stat:hover .stat__l{color:rgba(247,244,239,.9)}

html.no-motion .stats::before,
html.no-motion .stat + .stat::before,
html.no-motion .band__rule::before,
html.no-motion .band__rule::after,
html.no-motion .band__rule i{transform:none !important}

/* ---------- Gallery ---------- */
.gal{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(.6rem,1.2vw,1rem)}
.gal__i{position:relative;overflow:hidden;border-radius:var(--radius-media);cursor:pointer;background:var(--white);box-shadow:inset 0 0 0 var(--hair) var(--line-soft)}
.gal__i img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--e-out),filter .6s}
.gal__i:hover img{transform:scale(1.06)}
/* Velo de hover. Antes era un bloque plano navy al 34 %: apagaba la foto de
   golpe y se leía como una capa pegada encima, no como luz. Ahora es viñeta
   suave + caída al pie — el centro de la imagen casi no se toca y el contraste
   que necesita el disco de zoom se sostiene en el borde. */
.gal__i::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(39,53,105,.03) 0%,rgba(39,53,105,.08) 46%,rgba(11,15,36,.26) 100%),
    radial-gradient(112% 82% at 50% 44%,rgba(39,53,105,0) 44%,rgba(39,53,105,.14) 100%);
  opacity:0;transition:opacity .7s var(--e-soft)
}
.gal__i:hover::after{opacity:1}
/* Afordancia de zoom: un disco hueso con el icono en navy. Antes era un trazo
   claro suelto sobre la foto, que se perdía en cuanto la imagen era clara. */
.gal__i .gal__zoom{
  position:absolute;top:50%;left:50%;z-index:2;
  width:clamp(46px,4.4vw,58px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;
  background:var(--cream);color:var(--navy);
  opacity:0;transform:translate(-50%,-50%) scale(.7) rotate(-24deg);
  transition:opacity .4s var(--e-out),transform .6s var(--e-out)
}
.gal__i:hover .gal__zoom{opacity:1;transform:translate(-50%,-50%) scale(1) rotate(0)}
.gal__zoom svg{width:22px;height:22px}
.gal__i:focus-visible{outline:2px solid var(--navy);outline-offset:3px}

/* Bento del teaser: filas y columnas explícitas.
   Antes cada figura llevaba aspect-ratio pero el grid las estiraba a la altura
   de su fila, así que las parejas quedaban descuadradas y con huecos.        */
.gal--bento{
  grid-template-columns:repeat(12,1fr);
  grid-auto-rows:clamp(52px,5.4vw,92px)
}
/* Rompe el wrap: el bento se lee mejor de borde a borde. */
.gal--bleed{
  /* `scrollbar-gutter:stable` en el html deja la calle de la barra FUERA del
     viewport de layout, así que aquí `100vw` ya mide sólo lo que se ve y la
     sangría cae clavada. Sin ese soporte (Safari < 17) sobra el ancho de la
     barra, pero el `overflow-x:clip` del html lo recorta sin generar scroll. */
  width:100vw;margin-inline:calc(50% - 50vw);
  padding-inline:clamp(.5rem,1.1vw,1rem);
  gap:clamp(.4rem,.7vw,.7rem)
}
.gal--bento .gal__i{aspect-ratio:auto;height:100%}
.gal--bento .gal__i:nth-child(1){grid-column:1/6;  grid-row:1/10}
.gal--bento .gal__i:nth-child(2){grid-column:6/13; grid-row:1/6}
.gal--bento .gal__i:nth-child(3){grid-column:6/13; grid-row:6/10}
.gal--bento .gal__i:nth-child(4){grid-column:1/5;  grid-row:10/15}
.gal--bento .gal__i:nth-child(5){grid-column:5/9;  grid-row:10/15}
.gal--bento .gal__i:nth-child(6){grid-column:9/13; grid-row:10/15}
.gal--bento .gal__i:nth-child(7){grid-column:1/13; grid-row:15/20}

/* Galería completa: mismo remedio, en ciclos de 6 con bandas de igual altura,
   así ninguna pieza queda con hueco debajo.                                  */
.gal--rows{
  grid-template-columns:repeat(12,1fr);
  grid-auto-rows:clamp(46px,4.8vw,78px)
}
.gal--rows .gal__i{aspect-ratio:auto}
.gal--rows .gal__i:nth-child(6n+1){grid-column:span 5; grid-row:span 8}
.gal--rows .gal__i:nth-child(6n+2){grid-column:span 7; grid-row:span 8}
.gal--rows .gal__i:nth-child(6n+3){grid-column:span 4; grid-row:span 6}
.gal--rows .gal__i:nth-child(6n+4){grid-column:span 4; grid-row:span 6}
.gal--rows .gal__i:nth-child(6n+5){grid-column:span 4; grid-row:span 6}
.gal--rows .gal__i:nth-child(6n+6){grid-column:span 12;grid-row:span 7}
/* la última nunca deja media fila coja */
.gal--rows .gal__i:last-child{grid-column:1/-1;grid-row:span 6}

/* Galería de "nosotros": mismo remedio en pequeño. Cinco piezas con aspect
   ratios distintos en un grid de 12 dejaban un hueco bajo la primera (4/3 es
   más baja que 3/4 al mismo alto de fila). Con bandas de alto fijo las dos
   de arriba comparten fila exacta y las tres de abajo caen alineadas.      */
.gal--about{grid-auto-rows:clamp(44px,4.4vw,74px)}
.gal--about .gal__i{aspect-ratio:auto}
.gal--about .gal__i:nth-child(1){grid-column:span 7;grid-row:span 8}
.gal--about .gal__i:nth-child(2){grid-column:span 5;grid-row:span 8}
.gal--about .gal__i:nth-child(n+3){grid-column:span 4;grid-row:span 6}

/* La última pieza no abre el lightbox: lleva a la galería completa */
.gal__i--more{display:block}
.gal__i--more::after{background:linear-gradient(180deg,rgba(11,15,36,.15),rgba(11,15,36,.72));opacity:1}
.gal__more{
  position:absolute;inset:auto 0 0 0;z-index:2;color:var(--cream);
  display:flex;align-items:center;justify-content:center;gap:.7rem;
  padding:clamp(1.25rem,3vw,2rem);
  font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;font-weight:800
}
.gal__more b{font-weight:800}
.gal__more svg{width:16px;height:16px;transition:transform .5s var(--e-out)}
.gal__i--more:hover .gal__more svg{transform:translate(3px,-3px)}
.sp-4{grid-column:span 4}.sp-3{grid-column:span 3}.sp-6{grid-column:span 6}
.sp-8{grid-column:span 8}.sp-5{grid-column:span 5}.sp-7{grid-column:span 7}
.ar-1{aspect-ratio:1/1}.ar-43{aspect-ratio:4/3}.ar-34{aspect-ratio:3/4}
.ar-169{aspect-ratio:16/9}.ar-32{aspect-ratio:3/2}.ar-23{aspect-ratio:2/3}
/* ---------- Lightbox ----------------------------------------------------
   Tres cosas que estaban mal y una que no existía.

   1 · TAMAÑO HOMOLOGADO. Antes cada foto abría a su aire (`max-width:100%`
       + `max-height:86svh`): una 3:4 salía enorme y una 16:9 raquítica, y al
       pasar de una a otra la caja daba saltos. No se leía como una galería,
       se leía como un descuido. Ahora TODAS caben en el mismo cuadrado de
       lado S. La consecuencia es exactamente lo que se pedía: todas las
       verticales abren con el MISMO ALTO y todas las horizontales con el
       MISMO ANCHO. Y sin recortar un píxel, porque el marco toma la
       proporción real del archivo (la mide initLightbox y la escribe aquí).

   2 · SITIO PARA EL CROMO. El lado del cuadrado descuenta las dos calles
       laterales donde viven las flechas y el pie donde vive el contador, así
       que ni la X ni las flechas se montan nunca sobre la foto.

   3 · RADIO DE VERDAD: 24 px arriba del todo, no los 2 px de --radius, que
       es un radio de botón y en una foto a 900 px no se ve.

   4 · El marco VUELA desde la miniatura y vuelve a ella al cerrar. Va en
       `transform` (compositor, sin relayout) y la capa de dentro lleva la
       escala inversa, así la foto no se deforma ni un fotograma: lo único
       que cambia durante el vuelo es el recorte, igual que en la miniatura.
*/
.lb{
  /* Calles laterales: las flechas caben aquí y no invaden la foto. */
  --lb-side: clamp(76px, 8vw, 148px);
  /* Aire arriba y abajo del cuadrado. */
  --lb-pad:  clamp(20px, 3.5vw, 44px);
  /* Franja del contador, para que tampoco pise. */
  --lb-foot: 72px;
  --lb-r:    clamp(16px, 1.8vw, 24px);
  position:fixed;inset:0;z-index:9500;
  display:grid;place-items:center;
  visibility:hidden
}
.lb.is-open{visibility:visible}
/* El velo es su propia capa: así se puede fundir con un tiempo distinto al
   del vuelo del marco. Fundidos a la vez, el fondo llegaba a negro antes de
   que la foto hubiera salido de la miniatura y se veía el salto. */
.lb__bg{
  position:absolute;inset:0;opacity:0;
  background:rgba(11,15,36,.94);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)
}
/* JS le da ancho y alto en píxeles con la proporción del archivo. */
.lb__frame{
  position:relative;z-index:1;overflow:hidden;
  border-radius:var(--lb-r);background:var(--ink);
  transform-origin:50% 50%;will-change:transform;
  box-shadow:0 40px 120px -30px rgba(0,0,0,.7)
}
/* Capa de escala inversa. Existe sólo para que el marco pueda ir escalado
   sin estirar la fotografía. */
/* Sonda de medida. `getComputedStyle(...).getPropertyValue("--lb-side")`
   devuelve el TEXTO de la propiedad, no su valor resuelto: sobre un
   `clamp()` eso es la cadena "clamp(76px, 8vw, 148px)" y parseFloat da NaN.
   Las tres medidas se cuelgan aqui de propiedades normales — ancho, alto y
   relleno — que el navegador si resuelve a pixeles antes de devolverlas. */
.lb__probe{
  position:absolute;left:-9999px;top:0;visibility:hidden;pointer-events:none;
  box-sizing:content-box;
  width:var(--lb-side);height:var(--lb-pad);padding-top:var(--lb-foot)
}
.lb__cs{position:absolute;inset:0;transform-origin:50% 50%}
/* `cover` siempre, no `contain`: en reposo el marco YA tiene la proporción
   del archivo, así que cover enseña la foto entera. Durante el vuelo, cover
   es justo lo que reproduce el recorte de la miniatura. */
.lb__img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;will-change:transform,opacity
}

/* ---------- cromo ---------- */
/* El transform se compone de dos variables en vez de escribirse entero: así
   la entrada (--ty) y el hover (--sc) no se pisan. Con `transform` a secas,
   la regla de hover borraba el desplazamiento de entrada y el botón pegaba
   un brinco al pasar el ratón. */
.lb__x,.lb__p,.lb__n{
  position:absolute;z-index:3;
  width:clamp(46px,4.2vw,58px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;color:var(--cream);
  background:rgba(247,244,239,.10);
  border:1px solid rgba(247,244,239,.14);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transform:translateY(var(--ty,10px)) scale(var(--sc,1));
  transition:opacity .5s var(--e-out),transform .55s var(--e-out),
             background-color .3s var(--e-out),border-color .3s
}
.lb__x svg,.lb__p svg,.lb__n svg{width:22px;height:22px}
.lb.is-ready .lb__x,.lb.is-ready .lb__p,.lb.is-ready .lb__n{opacity:1;--ty:0px}
/* Escalonado corto: el cromo entra detrás de la foto, nunca con ella. */
.lb.is-ready .lb__x{transition-delay:.14s}
.lb.is-ready .lb__p{transition-delay:.20s}
.lb.is-ready .lb__n{transition-delay:.20s}
@media (hover:hover) and (pointer:fine){
  .lb__x:hover,.lb__p:hover,.lb__n:hover{
    --sc:1.09;background:rgba(247,244,239,.2);border-color:rgba(247,244,239,.3)
  }
  .lb__x:active,.lb__p:active,.lb__n:active{--sc:.96;transition-duration:.12s}
}
.lb__x:focus-visible,.lb__p:focus-visible,.lb__n:focus-visible{
  outline:2px solid var(--cream);outline-offset:3px
}
.lb__x{top:clamp(18px,2.6vw,36px);right:clamp(18px,2.6vw,36px)}
/* Centradas con `margin-block:auto` y no con `translateY(-50%)`: el translate
   ocupaba el transform que ahora necesitan la entrada y el hover. */
.lb__p,.lb__n{top:0;bottom:0;margin-block:auto}
.lb__p{left:clamp(16px,2.4vw,40px)}
.lb__n{right:clamp(16px,2.4vw,40px)}
.lb__c{
  position:absolute;z-index:3;left:0;right:0;bottom:clamp(18px,2.6vw,34px);
  text-align:center;pointer-events:none;
  color:rgba(247,244,239,.7);font-size:var(--fs-micro);letter-spacing:.2em;
  font-variant-numeric:tabular-nums;
  opacity:0;transform:translateY(var(--ty,10px));
  transition:opacity .5s var(--e-out),transform .55s var(--e-out)
}
.lb.is-ready .lb__c{opacity:1;--ty:0px;transition-delay:.24s}
.lb__c b{color:var(--cream);font-weight:700}

/* Sin movimiento: el vuelo lo desactiva el JS y aquí se apagan las entradas
   escalonadas. Sigue habiendo fundido, que no marea a nadie. */
@media (prefers-reduced-motion:reduce){
  .lb__x,.lb__p,.lb__n,.lb__c{transform:none;transition:opacity .3s linear}
  .lb.is-ready .lb__x,.lb.is-ready .lb__p,
  .lb.is-ready .lb__n,.lb.is-ready .lb__c{transition-delay:0s}
}

/* ---------- Testimonial / video band ---------- */
.band{position:relative;overflow:hidden;color:var(--cream);isolation:isolate}
.band__media{position:absolute;inset:-10% 0;z-index:-6;transform-origin:50% 46%;will-change:transform}
.band__media video,.band__media img{width:100%;height:100%;object-fit:cover}

/* Velo en TRES capas en vez de una losa plana.
   Antes era un `linear-gradient(.72 → .78)`: tapaba la foto entera y la
   banda leía como un rectángulo azul con un fantasma detrás. Ahora:
   1) viñeta radial — oscurece esquinas y deja respirar el centro,
   2) degradado vertical — sólo donde se apoya el texto,
   3) tinte de marca en `soft-light` — el navy entra en la LUZ de la foto,
      no la pinta por encima, así la imagen conserva su materia.
   Resultado: la misma legibilidad con la mitad de opacidad plana.      */
.band__scrim{
  position:absolute;inset:0;z-index:-3;
  /* El foco del velo es una VARIABLE, no un punto fijo: el motor de scroll
     lo baja mientras la banda cruza la pantalla, asi el charco de luz sigue
     al lector en vez de quedarse clavado en el centro del rectangulo. */
  --sx:50%;--sy:44%;
  background:
    radial-gradient(105% 72% at var(--sx) var(--sy),rgba(11,15,36,.20) 0%,rgba(11,15,36,.42) 58%,rgba(11,15,36,.64) 100%),
    linear-gradient(180deg,rgba(11,15,36,.54) 0%,rgba(11,15,36,.10) 36%,rgba(11,15,36,.14) 64%,rgba(11,15,36,.58) 100%)
}
.band__scrim::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(150deg,rgba(39,53,105,.55),rgba(192,140,134,.22));
  mix-blend-mode:soft-light
}
/* Grano. Una superficie oscura tan grande con degradados largos BANDEA en
   pantallas de 8 bits: se ven los escalones. El grano los rompe y de paso
   le da piel de impresión. Turbulencia SVG en línea — ni un byte de red. */
.band::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
  mix-blend-mode:overlay
}


/* ---------- Banda: planos de profundidad (parallax) ----------
   La banda deja de ser "foto + velo + texto" y pasa a ser una escena de SEIS
   planos, cada uno a su velocidad. De atras (lejos, se mueve poco) a delante
   (cerca, se mueve mucho):

     -6  .band__media   la foto. Hace de camara: dolly lento + zoom que afloja.
     -5  .band__dust    polvo luminoso, tres capas a tres velocidades.
     -4  .band__glow    una brasa rosé que sube y cruza por detras del velo.
     -3  .band__scrim   el velo, con su foco desplazandose.
     -2  .band__beam    un haz de luz sesgado que barre la escena.
     -1  .band::after   el grano, quieto: es la "pelicula", no la escena.

   Todo lo decorativo nace en `opacity:0` y lo enciende el motor de scroll.
   Sin JS, sin GSAP o con `prefers-reduced-motion` la banda queda EXACTAMENTE
   como estaba: una foto, un velo y una cita. Ni una mancha parada.        */

.band__dust,.band__glow,.band__beam{
  position:absolute;pointer-events:none;opacity:0;
  will-change:transform,opacity;backface-visibility:hidden
}

/* Polvo. El desenfoque va HORNEADO en las paradas del degradado en vez de
   `filter:blur()`: el compositor se limita a mover una capa ya pintada y el
   scroll no paga un repintado por frame. Tres <b> = tres profundidades. */
.band__dust{inset:-16% -8%;z-index:-5}
.band__dust b{position:absolute;inset:0;display:block;will-change:transform}

/* lejos — muchos puntos pequeños, casi polvo en suspension */
.band__dust b:nth-child(1){
  background:
    radial-gradient(circle at 12% 22%,rgba(247,244,239,.42),transparent 1.6%),
    radial-gradient(circle at 27% 68%,rgba(228,201,196,.38),transparent 1.4%),
    radial-gradient(circle at 41% 14%,rgba(247,244,239,.30),transparent 1.2%),
    radial-gradient(circle at 55% 82%,rgba(247,244,239,.34),transparent 1.5%),
    radial-gradient(circle at 68% 34%,rgba(228,201,196,.40),transparent 1.3%),
    radial-gradient(circle at 79% 74%,rgba(247,244,239,.28),transparent 1.1%),
    radial-gradient(circle at 88% 26%,rgba(228,201,196,.34),transparent 1.6%),
    radial-gradient(circle at 33% 44%,rgba(247,244,239,.26),transparent 1.2%),
    radial-gradient(circle at 62% 56%,rgba(228,201,196,.24),transparent 1.4%)
}
/* medio — bokeh reconocible, ya con forma de circulo desenfocado */
.band__dust b:nth-child(2){
  background:
    radial-gradient(circle at 18% 78%,rgba(228,201,196,.20),transparent 3.6%),
    radial-gradient(circle at 36% 30%,rgba(247,244,239,.17),transparent 3.1%),
    radial-gradient(circle at 58% 66%,rgba(228,201,196,.19),transparent 4.2%),
    radial-gradient(circle at 74% 18%,rgba(247,244,239,.15),transparent 3.4%),
    radial-gradient(circle at 86% 58%,rgba(228,201,196,.16),transparent 3.8%),
    radial-gradient(circle at 8% 44%,rgba(247,244,239,.13),transparent 3%)
}
/* cerca — manchas grandes y tenues, las que dan la sensacion de lente */
.band__dust b:nth-child(3){
  background:
    radial-gradient(circle at 24% 36%,rgba(228,201,196,.11),transparent 8%),
    radial-gradient(circle at 64% 74%,rgba(247,244,239,.09),transparent 9.5%),
    radial-gradient(circle at 84% 30%,rgba(228,201,196,.10),transparent 7%),
    radial-gradient(circle at 44% 88%,rgba(247,244,239,.07),transparent 6.5%)
}

/* Brasa. `screen` sobre el navy = la luz SUMA, no repinta: la foto sigue
   viendose debajo. Es lo que hace que parezca luz y no una pegatina rosa.
   Se centra con el PROPIO degradado dentro de una caja desbordada, no con
   `translate(-50%,-50%)`: GSAP absorbe cualquier centrado por transform y
   luego el tween de scroll se lo lleva por delante. Caja quieta, luz dentro. */
.band__glow{
  inset:-34% -18%;z-index:-4;
  background:radial-gradient(44% 42% at 50% 50%,
    rgba(192,140,134,.40) 0%,rgba(192,140,134,.14) 44%,transparent 72%);
  mix-blend-mode:screen
}

/* Haz. `soft-light` entra en la luz de la foto en vez de tumbarse encima,
   igual que el tinte del velo: aclara donde ya hay claro y no ensucia. */
.band__beam{
  inset:-40% -25%;z-index:-2;
  background:linear-gradient(108deg,
    transparent 30%,rgba(247,244,239,.16) 44%,rgba(228,201,196,.24) 50%,
    rgba(247,244,239,.12) 57%,transparent 70%);
  mix-blend-mode:soft-light
}

/* La comilla ornamental tambien viaja: `translate` es una propiedad aparte
   del `transform`, asi que el centrado de arriba no se toca.             */
.band__in{--qy:0px}
.band__in{position:relative;padding-block:var(--sec);text-align:center}
/* Comilla de apertura como ornamento tipográfico, no como carácter del
   titular: vive en el fondo, no la lee un lector de pantalla y no empuja
   la maquetación. Es lo que convierte "un h2 centrado" en una cita.    */
.band__in::before{
  content:"\201C";position:absolute;left:50%;top:clamp(2.6rem,7.5vw,6.5rem);
  transform:translateX(-50%);translate:0 var(--qy,0px);pointer-events:none;
  font-family:var(--serif);font-size:clamp(7rem,15vw,13rem);line-height:.62;
  color:var(--cream);opacity:.13
}
.band__q{max-width:20ch;margin-inline:auto;line-height:.95;position:relative}
/* La frase en inglés es más larga que la española y a 20ch se partía en tres.
   Sólo se ensancha ahí: el corte del español está calibrado a su medida. */
html[lang="en"] .band__q{max-width:25ch}
/* El giro de la frase en itálica arena: el mismo recurso que el titular
   del hero, para que la voz de la marca sea una sola. */
.band__q em{font-style:italic;color:var(--sand)}
/* Filete ornamental entre la cita y los datos: crece desde el centro hacia
   los dos lados. Sin texto — no inventa copy, sólo marca el respiro entre
   la voz de la marca y los números. */
.band__rule{
  margin-top:clamp(1.4rem,3vw,2.4rem);
  display:flex;align-items:center;justify-content:center;gap:.8rem
}
.band__rule::before,.band__rule::after{
  content:"";height:1px;width:clamp(34px,6vw,86px);background:var(--cream);opacity:.34;
  transform:scaleX(0);transition:transform 1.1s var(--e-hero) .45s
}
.band__rule::before{transform-origin:right}
.band__rule::after{transform-origin:left}
.band__rule i{
  width:5px;height:5px;border-radius:50%;background:var(--rose);flex:none;
  transform:scale(0);transition:transform .7s var(--e-hero) .3s
}
.band__rule.is-in::before,.band__rule.is-in::after{transform:scaleX(1)}
.band__rule.is-in i{transform:scale(1)}

/* Video player pill */
/* `--vp-ar` la escribe initVideo() en cuanto el navegador conoce las medidas
   reales del archivo (`loadedmetadata`). Así la caja NUNCA discute con el
   vídeo: sea vertical, cuadrado o apaisado, encaja al píxel y no hay ni
   recorte ni bandas. El valor de reserva es sólo para el primer fotograma,
   antes de que lleguen los metadatos. */
.vplay{
  position:relative;border-radius:var(--radius-lg);overflow:hidden;
  aspect-ratio:var(--vp-ar, 16/10);background:var(--ink)
}
/* `contain` y no `cover`: los tres vídeos del sitio están grabados en vertical
   (1080×1920) y con `cover` una caja apaisada enseña una franja del 35 % del
   fotograma — las caras salen cortadas por arriba y por abajo. Con `contain`
   el fotograma entero se ve siempre, y si sobra caja se ve el fondo, que es
   --ink. Los reproductores que ya tienen la proporción del archivo (--arch,
   --tall) no notan la diferencia: ahí `contain` y `cover` dan lo mismo. */
.vplay video{width:100%;height:100%;object-fit:contain;display:block}
/* El vídeo de testimonios es el mismo formato que el reel. Manda el ancho,
   como en el arco, y el alto lo pone el archivo: cero recorte. */
.vplay.vplay--tall{
  aspect-ratio:var(--vp-ar, 9/16);width:clamp(280px,24vw,380px);height:auto;max-width:100%;
  justify-self:center
}
/* velo para que el botón tenga contraste sobre cualquier póster */
.vplay__scrim{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,15,36,.18),rgba(11,15,36,.55));
  transition:opacity .45s var(--e-out)
}
.vplay.is-playing .vplay__scrim,
.vplay.is-started .vplay__scrim{opacity:0}
.vplay__btn{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;
  color:var(--cream);cursor:pointer;
  transition:opacity .4s var(--e-out)
}
/* `is-started`, no sólo `is-playing`: el overlay ocupa `inset:0`, o sea también
   la barra de controles nativa del vídeo. Atado sólo a `is-playing`, en cuanto
   pausabas volvía a taparlo todo y el volumen, la barra de tiempo y el botón de
   pantalla completa dejaban de responder — los clics se los comía el overlay.
   `is-started` dura desde el primer play hasta que el vídeo termina. */
.vplay.is-playing .vplay__btn,
.vplay.is-started .vplay__btn{opacity:0;pointer-events:none}
/* El anillo que late no tiene sentido con el vídeo empezado, y una animación
   infinita detrás de un overlay invisible sigue costando repintados. */
.vplay.is-started .vplay__circle::after{animation:none}
.vplay__circle{
  position:relative;
  width:clamp(72px,8vw,102px);aspect-ratio:1;border-radius:50%;display:grid;place-items:center;
  background:var(--white);color:var(--navy);
  /* sin sombra: el círculo ya contrasta contra el velo del vídeo */
  transition:transform .5s var(--e-out),background-color .4s,color .4s
}
/* anillo que respira: señala que es pulsable sin ensuciar el frame */
.vplay__circle::after{
  content:"";position:absolute;inset:-14px;border-radius:50%;
  border:1px solid rgba(247,244,239,.45);
  animation:vpulse 2.8s var(--e-io) infinite
}
@keyframes vpulse{
  0%{transform:scale(.92);opacity:.9}
  70%{transform:scale(1.12);opacity:0}
  100%{transform:scale(1.12);opacity:0}
}
.vplay__btn:hover .vplay__circle{transform:scale(1.08);background:var(--rose-soft)}
.vplay__btn:focus-visible{outline:2px solid var(--cream);outline-offset:-8px}
.vplay__circle svg{width:24px;height:24px;margin-left:4px}
.vplay__meta{
  display:flex;align-items:center;gap:.75rem;
  font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;font-weight:800
}
.vplay__meta i{font-style:normal;opacity:.7}
.vplay__meta i::before{content:"";display:inline-block;width:14px;height:1px;background:currentColor;vertical-align:middle;margin-right:.75rem;opacity:.5}
@media (prefers-reduced-motion:reduce){.vplay__circle::after{animation:none;opacity:.45}}

/* ---------- Locations ---------- */
.locs{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.25rem,3vw,2rem)}
/* los dos locales + la tarjeta de horario, los tres en la misma fila */
.locs--3{grid-template-columns:repeat(3,1fr);align-items:stretch}
.locs--3 > *{min-width:0}
.loc{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  border:var(--hair) solid var(--line);border-radius:var(--radius-lg);background:var(--paper);
  transition:border-color .5s var(--e-out),transform .55s var(--e-out)
}
.loc:hover{border-color:var(--navy);transform:translateY(-6px)}
.loc:focus-visible{outline:2px solid var(--navy);outline-offset:3px}
/* La foto se come el alto sobrante de la fila: la tarjeta ya no "respira"
   con aire muerto, el texto queda abajo y la imagen manda.                */
/* En contacto la foto sirve para RECONOCER el local, no para lucirlo: con
   la altura de la home la ficha se comía media pantalla y empujaba la
   dirección —que es el dato— fuera del campo de visión.
   Hay que fijar la ALTURA, no el min-height: con `flex:1` la caja crece a
   la proporción natural de la imagen y el mínimo sólo era un suelo. */
.locs--compact .loc__media{flex:none;min-height:0;height:clamp(150px,13vw,210px)}
.loc__media{
  position:relative;display:block;flex:1;min-height:clamp(190px,17vw,300px);
  overflow:hidden;
  margin:var(--media-pad) var(--media-pad) 0;
  border-radius:var(--radius-media);background:var(--white)
}
/* `scale` (propiedad individual) para el reveal y `transform` para el hover:
   así los dos se componen y ninguno pisa al otro.                          */
.loc__media img{
  width:100%;height:100%;object-fit:cover;
  transition:transform 1.1s var(--e-out),scale 1.4s var(--e-out)
}
.loc:hover .loc__media img{transform:scale(1.04)}

.loc__body{
  position:relative;flex:none;display:flex;flex-direction:column;gap:.3rem;
  padding:1rem clamp(1.05rem,1.5vw,1.3rem) clamp(1.05rem,1.5vw,1.3rem)
}
/* Índice + filete + chip: una línea de cabecera editorial. El número ya no
   flota sobre la foto con una sombra que lo ensuciaba.                     */
.loc__top{display:flex;align-items:center;gap:.7rem;margin-bottom:.35rem}
.loc__x{
  flex:none;font-family:var(--serif);font-size:1.0625rem;line-height:1;
  color:var(--rose);letter-spacing:.01em;font-variant-numeric:tabular-nums
}
.loc__rule{flex:1;height:var(--hair);background:var(--line);min-width:.75rem}
.loc__badge{
  flex:none;display:inline-flex;align-items:center;gap:.35rem;
  padding:.3rem .6rem .3rem .45rem;border-radius:999px;
  background:var(--white);border:var(--hair) solid var(--line);color:var(--navy);
  font-size:.625rem;font-weight:800;letter-spacing:.16em;text-transform:uppercase
}
.loc__badge svg{width:13px;height:13px}
.loc__n{
  font-family:var(--serif);font-size:clamp(1.3rem,1.9vw,1.75rem);
  line-height:1.05;letter-spacing:-.02em
}
.loc__a{color:var(--muted);font-size:.875rem;line-height:1.45}
.loc__near{font-size:.75rem;color:var(--muted);opacity:.8;margin-top:.2rem}
.loc__go{
  margin-top:.7rem;padding-top:.7rem;border-top:var(--hair) solid var(--line-soft);
  display:inline-flex;align-items:center;gap:.5rem;color:var(--navy);
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.16em;text-transform:uppercase
}
.loc__go svg{width:15px;height:15px;transition:transform .5s var(--e-out)}
.loc:hover .loc__go svg{transform:translateX(4px)}

/* ---------- Entrada de la fila (scroll) ----------------------------------
   Una sola idea, no tres a la vez: cada tarjeta se descubre bajo una
   cortina que sube, y la foto llega desde un 1.12 de escala y se asienta.
   El escalonado entre tarjetas lo estampa initReveals sobre [data-stagger];
   dentro de la tarjeta del horario, las filas entran una a una después.
   Todo con `scale`/`clip-path`, propiedades que van al compositor.       */
.js .locs--3 > *{
  opacity:0;
  transform:translateY(38px);
  clip-path:inset(16% 0 0 0 round var(--radius-lg));
  transition:opacity .75s var(--e-out),
             transform 1.05s var(--e-out),
             clip-path 1.05s var(--e-out),
             border-color .5s var(--e-out)
}
.js .locs--3.is-in > *{
  opacity:1;transform:none;
  clip-path:inset(0 0 0 0 round var(--radius-lg))
}
/* la foto usa `scale` y el hover usa `transform`: se componen, no se pisan */
.js .locs--3 .loc__media img{scale:1.12}
.js .locs--3.is-in .loc__media img{scale:1}
/* el filete de la cabecera se dibuja al final, como una firma */
.js .locs--3 .loc__rule{transform:scaleX(0);transform-origin:left;transition:transform 1s var(--e-out) .5s}
.js .locs--3.is-in .loc__rule{transform:scaleX(1)}

/* filas del horario: entran de una en una, ya con la tarjeta colocada */
.js .hlist[data-stagger] > .hrow{
  opacity:0;transform:translateY(10px);
  transition:opacity .5s var(--e-out),transform .55s var(--e-out)
}
.js .hlist[data-stagger].is-in > .hrow{opacity:1;transform:none}
/* el filete rosé de HOY se estira cuando su fila ya está puesta */
.js .hlist[data-stagger] > .hrow.is-today::before{scale:1 0;transition:scale .5s var(--e-out) .5s}
.js .hlist[data-stagger].is-in > .hrow.is-today::before{scale:1 1}

/* red de seguridad: si el motor de scroll no corre, nada queda escondido */
html.no-motion .locs--3 > *{clip-path:none !important}
html.no-motion .locs--3 .loc__media img{scale:1 !important}
html.no-motion .locs--3 .loc__rule,
html.no-motion .hlist > .hrow.is-today::before{transform:none !important;scale:1 !important}
@media (prefers-reduced-motion:reduce){
  .js .locs--3 > *{clip-path:none !important}
  .js .locs--3 .loc__media img{scale:1 !important}
  .js .locs--3 .loc__rule{transform:none !important}
}

/* ---------- Contact form ---------- */
.form{display:grid;gap:1.5rem}
.field{position:relative;display:grid;gap:.5rem}
.field label{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;font-weight:700;color:var(--muted)}
.field input,.field textarea,.field select{
  width:100%;background:transparent;border:0;border-bottom:var(--hair) solid var(--line);
  padding:.85rem 0;font-size:1rem;border-radius:0;
  transition:border-color .4s var(--e-out)
}
.field select{cursor:pointer}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--navy)}
.field textarea{resize:vertical;min-height:120px}
.form__row{display:grid;grid-template-columns:1fr 1fr;gap:1.5rem}
.form__note{font-size:.75rem;color:var(--muted)}

/* ---------- Map ---------- */
.map{border-radius:var(--radius-lg);overflow:hidden;aspect-ratio:16/9;background:var(--white);border:var(--hair) solid var(--line)}
.map iframe{width:100%;height:100%;border:0;filter:grayscale(1) contrast(1.05);transition:filter .7s var(--e-out)}
.map:hover iframe{filter:grayscale(0)}

/* Mapa: una PLACA, no un widget incrustado.
   Antes eran dos píldoras sueltas flotando encima de una losa gris de 24/9:
   leía como un embed de Google, no como parte del sitio, y no decía nada que
   las tres fichas de arriba no dijeran ya. Ahora el mapa va montado dentro de
   un marco con el mismo `--media-pad` que el resto de medios (curvas
   concéntricas), el selector es una cápsula igual que la del nav, y abajo va
   la dirección real del local con su enlace a Maps: el mapa por fin informa. */
.mapbox{display:grid;gap:.75rem}
.mapbox .map{aspect-ratio:4/3;border-radius:var(--radius-lg)}

.mapbox--wide{
  position:relative;gap:0;
  padding:var(--media-pad);
  background:var(--paper);
  border:var(--hair) solid var(--line);
  border-radius:var(--radius-lg);
  overflow:hidden
}
.mapbox--wide .map{
  /* `width:100%` NO sobra. Con `aspect-ratio` y ancho automático, en cuanto
     el `max-height` recorta el alto el navegador reduce el ANCHO para
     conservar la razón: en pantallas anchas el mapa se quedaba en 1073 px
     dentro de una placa de 1416 y sobraban 343 px de blanco a la derecha.
     Fijando el ancho, la razón sólo manda en el alto y el tope lo recorta. */
  width:100%;
  aspect-ratio:21/9;max-height:clamp(320px,32vw,460px);
  border-radius:var(--radius-media);border:0
}
.mapbox--wide iframe{filter:grayscale(1) contrast(1.04)}
.mapbox--wide:hover iframe{filter:grayscale(.15) contrast(1.02)}

/* Selector: misma cápsula flotante que la barra de navegación. */
.mapbox--wide .mapbox__tabs{
  position:absolute;z-index:2;
  top:calc(var(--media-pad) + clamp(.6rem,1.2vw,1rem));
  left:calc(var(--media-pad) + clamp(.6rem,1.2vw,1rem));
  display:inline-flex;flex-wrap:nowrap;gap:.2rem;padding:.3rem;
  background:rgba(255,255,255,.82);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:var(--hair) solid var(--line-soft);
  border-radius:999px
}
.mapbox--wide .mtab{flex:0 0 auto;min-width:0;padding:.6rem 1.05rem}

.mapbox__tabs{display:flex;gap:.4rem;flex-wrap:wrap}
.mtab{
  flex:1 1 auto;padding:.7rem 1rem;border-radius:999px;cursor:pointer;
  border:var(--hair) solid var(--line);background:transparent;color:var(--muted);
  font-family:var(--sans);font-size:var(--fs-micro);font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;white-space:nowrap;
  transition:background-color .4s var(--e-out),color .4s,border-color .4s
}
.mtab:hover{color:var(--navy);border-color:var(--navy)}
.mtab.is-on{background:var(--navy);border-color:var(--navy);color:var(--cream)}
/* dentro de la cápsula el borde sobra: la pastilla activa ya separa */
.mapbox--wide .mtab{border-color:transparent}
.mapbox--wide .mtab:hover{border-color:transparent;background:var(--line-soft);color:var(--navy)}
.mapbox--wide .mtab.is-on{border-color:transparent;background:var(--navy);color:var(--cream)}
.mtab:focus-visible{outline:2px solid var(--rose);outline-offset:2px}

/* Ficha de dirección del local activo, anclada abajo a la izquierda. */
.mapbox__addr{
  position:absolute;z-index:2;
  left:calc(var(--media-pad) + clamp(.6rem,1.2vw,1rem));
  bottom:calc(var(--media-pad) + clamp(.6rem,1.2vw,1rem));
  right:calc(var(--media-pad) + clamp(.6rem,1.2vw,1rem));
  display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  padding:clamp(.85rem,1.6vw,1.15rem) clamp(1rem,1.9vw,1.35rem);
  background:rgba(255,255,255,.86);
  -webkit-backdrop-filter:blur(16px) saturate(1.5);
  backdrop-filter:blur(16px) saturate(1.5);
  border:var(--hair) solid var(--line-soft);
  border-radius:var(--radius-media);
  max-width:max-content
}
.mapbox__addr b{
  display:block;font-family:var(--serif);font-weight:400;
  font-size:clamp(1.15rem,1.9vw,1.6rem);line-height:1.05;letter-spacing:-.02em;color:var(--navy)
}
.mapbox__addr span{display:block;margin-top:.3rem;font-size:.875rem;color:var(--muted)}
.mapbox__addr .tlink{white-space:nowrap}
/* el contenido cambia de local: entra con un desplazamiento corto */
.mapbox__addr.is-swap{animation:maddr .5s var(--e-out)}
@keyframes maddr{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.mapbox__addr.is-swap{animation:none}}

/* ---------- Horario ---------- */
/* Tercera tarjeta de la fila: misma piel que las fichas de local */
.hcard{
  display:flex;flex-direction:column;
  border:var(--hair) solid var(--line);border-radius:var(--radius-lg);background:var(--paper);
  padding:clamp(1.35rem,2.4vw,2rem);
  transition:border-color .5s var(--e-out),transform .55s var(--e-out)
}
.hcard:hover{border-color:var(--navy)}
/* la cabecera va centrada: con el título a la izquierda y el resto del
   contenido justificado, la tarjeta se veía descolgada                     */
.hcard__head{display:grid;gap:.7rem;justify-items:center;text-align:center}
.hcard__head .h3{font-size:clamp(1.45rem,1.9vw,1.85rem)}
.hcard__cta{margin-top:auto;padding-top:clamp(1rem,2vw,1.4rem);display:grid;gap:.55rem}
.hcard__cta .btn{width:100%;padding-block:.9rem}
.hlist{display:grid;gap:0;margin-top:clamp(.9rem,1.6vw,1.25rem)}
.hrow{
  position:relative;
  display:flex;align-items:baseline;justify-content:space-between;gap:1.25rem;
  padding:.62rem 0;
  border-bottom:var(--hair) solid var(--line-soft);font-size:.9rem
}
.hrow:last-child{border-bottom:0}
.hrow__d{font-weight:500;display:inline-flex;align-items:baseline;gap:.5rem}
.hrow__t{color:var(--muted);font-variant-numeric:tabular-nums}

/* HOY: ni bloque gris ni píldora. Un filete rosé real a la izquierda, tinta
   plena y la palabra en versalitas rosé. Cero cajas dentro de cajas.       */
.hrow.is-today{color:var(--ink);font-weight:700}
.hrow.is-today::before{
  content:"";position:absolute;left:calc(-1 * clamp(.55rem,1vw,.8rem));
  top:50%;translate:0 -50%;
  width:2px;height:1.15em;border-radius:1px;background:var(--rose)
}
.hrow.is-today .hrow__d{font-weight:700}
.hrow.is-today .hrow__t{color:var(--ink);font-weight:600}
.hrow__d em{
  font-style:normal;font-size:.5625rem;letter-spacing:.2em;text-transform:uppercase;
  font-weight:800;color:var(--rose)
}

/* Abierto / cerrado — sin relleno ni borde: sólo el punto y el texto. El
   punto emite un anillo que respira, así se lee como un dato en vivo.      */
.opin{
  display:inline-flex;align-items:center;gap:.6rem;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)
}
.opin i{
  position:relative;width:7px;height:7px;border-radius:50%;
  background:currentColor;flex:none
}
.opin.is-open{color:#1F8C4F}
.opin.is-open i::after{
  content:"";position:absolute;inset:0;border-radius:50%;
  border:1px solid currentColor;
  animation:opulse 2.8s var(--e-out) infinite
}
@keyframes opulse{
  0%  {scale:1;   opacity:.7}
  70% {scale:2.6; opacity:0}
  100%{scale:2.6; opacity:0}
}
@media (prefers-reduced-motion:reduce){.opin.is-open i::after{animation:none;opacity:.35;scale:1.8}}

/* ---------- Footer ---------- */
.foot{background:var(--navy);color:var(--cream);position:relative;overflow:hidden;isolation:isolate}
.foot::before{
  content:"";position:absolute;inset:0;z-index:-1;opacity:.13;
  background:url("../assets/img/pattern-azul.png") center/cover
}
/* Halo lento. Iba a .85 con un radial de arena al 20%: eso levantaba el navy
   de la esquina superior y el pie dejaba de ser el azul de marca para
   convertirse en un azul lavado. Ahora sólo insinúa profundidad — el campo
   tiene que leerse como #273569 y nada más. */
.foot__glow{
  position:absolute;inset:-30% -10% auto;height:120%;z-index:-1;pointer-events:none;
  background:
    radial-gradient(48% 46% at 18% 22%, rgba(192,140,134,.16), transparent 70%),
    radial-gradient(42% 40% at 82% 6%,  rgba(51,68,127,.28),   transparent 68%);
  filter:blur(22px);opacity:.6;
  animation:foot-drift 26s var(--e-soft) infinite alternate
}
@keyframes foot-drift{
  from{transform:translate3d(-3%,0,0) scale(1)}
  to  {transform:translate3d(3%,2%,0) scale(1.12)}
}
@media (prefers-reduced-motion:reduce){.foot__glow{animation:none}}

.foot__top{padding-block:clamp(3.5rem,8vw,7rem) clamp(2rem,4vw,3.5rem)}
.foot__head{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);
  gap:clamp(2.5rem,6vw,6rem);align-items:start
}

/* ---- bloque de cierre ---- */
.foot__lead{display:grid;gap:clamp(1.4rem,2.6vw,2.1rem);justify-items:start}
.foot__status{
  display:inline-flex;align-items:center;gap:.7rem;
  font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;font-weight:700
}
.foot__dot{
  width:7px;height:7px;border-radius:50%;flex:none;
  background:#8A94B5;position:relative
}
.foot__status.is-open .foot__dot{background:#4ADE80}
.foot__status.is-open .foot__dot::after{
  content:"";position:absolute;inset:-5px;border-radius:50%;
  border:1px solid #4ADE80;opacity:0;
  animation:foot-ping 2.4s var(--e-out) infinite
}
@keyframes foot-ping{
  0%{opacity:.8;transform:scale(.55)}
  70%,100%{opacity:0;transform:scale(1.25)}
}
@media (prefers-reduced-motion:reduce){.foot__status.is-open .foot__dot::after{animation:none}}
.foot__clock{
  font-variant-numeric:tabular-nums;letter-spacing:.14em;
  color:rgba(247,244,239,.55);font-weight:600
}
.foot__cta{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.6rem,6.4vw,5.5rem);line-height:.92;letter-spacing:-.035em
}
.foot__cta em{font-style:italic;color:var(--sand)}
.foot__act{display:flex;flex-wrap:wrap;align-items:center;gap:clamp(1rem,2.5vw,2rem)}
.foot__mail{
  position:relative;font-size:1.0625rem;padding-bottom:.25rem;
  transition:color .4s var(--e-out)
}
.foot__mail::after{
  content:"";position:absolute;left:0;bottom:0;height:1px;width:100%;
  background:currentColor;transform-origin:right;transform:scaleX(1);
  transition:transform .5s var(--e-out)
}
.foot__mail:hover{color:var(--sand)}
.foot__mail:hover::after{transform:scaleX(0);transform-origin:left}

/* ---- columnas ---- */
.foot__cols{
  display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1fr) minmax(0,1.25fr);
  gap:clamp(1.5rem,3.2vw,3rem)
}
.foot h5{
  font-size:var(--fs-micro);letter-spacing:.22em;text-transform:uppercase;
  opacity:.45;margin-bottom:1.2rem;font-weight:700
}
.foot h5.is-second{margin-top:2rem}
.foot__nav{display:grid;gap:.15rem;font-size:.9375rem}
.foot__nav a{
  position:relative;display:flex;align-items:baseline;gap:.65rem;
  padding-block:.3rem;
  transition:color .35s var(--e-out)
}
.foot__nav i{
  font-style:normal;font-size:.5625rem;font-weight:700;letter-spacing:.12em;
  color:rgba(247,244,239,.32);flex:none;
  transition:color .35s var(--e-out),transform .5s var(--e-out)
}
.foot__nav b{
  font-weight:inherit;position:relative;display:inline-block;
  transition:transform .5s var(--e-out)
}
.foot__nav b::after{
  content:"";position:absolute;left:0;bottom:-2px;height:1px;width:100%;
  background:var(--sand);transform:scaleX(0);transform-origin:left;
  transition:transform .5s var(--e-out)
}
/* Objetivo tactil. Con raton bastan los 34 px que mide el renglon; un
   pulgar no apunta, aplasta, y la referencia son 44. Solo se toca el
   relleno y solo en puntero grueso: en escritorio el pie no se mueve un
   pixel. Mismo motivo en el correo del pie, que medía 31. */
@media (pointer:coarse){
  .foot__nav a{padding-block:.62rem}
  .foot__mail{padding-block:.4rem}
}
.foot__nav a:hover,.foot__nav a:focus-visible{color:var(--sand);outline:none}
.foot__nav a:hover i,.foot__nav a:focus-visible i{color:var(--sand);transform:translateX(2px)}
.foot__nav a:hover b,.foot__nav a:focus-visible b{transform:translateX(6px)}
.foot__nav a:hover b::after,.foot__nav a:focus-visible b::after{transform:scaleX(1)}

/* ---- locales + horario ---- */
.foot__locs{display:grid;gap:1rem;margin-bottom:1.4rem}
.foot__loc{
  display:grid;gap:.2rem;font-size:.9375rem;
  padding-left:.9rem;border-left:1px solid rgba(247,244,239,.2);
  transition:border-color .4s var(--e-out),padding-left .45s var(--e-out)
}
.foot__loc strong{font-weight:700}
.foot__loc span{color:rgba(247,244,239,.6);font-size:.875rem}
.foot__loc:hover{border-color:var(--sand);padding-left:1.2rem}
.foot__tel{
  display:inline-block;font-size:1.0625rem;font-variant-numeric:tabular-nums;
  transition:color .35s var(--e-out)
}
.foot__tel:hover{color:var(--sand)}
.foot__hrs{list-style:none;display:grid;gap:.45rem;font-size:.875rem}
.foot__hrs li{
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;
  color:rgba(247,244,239,.62)
}
.foot__hrs li span{white-space:nowrap}
.foot__hrs li span:last-child{color:var(--cream)}

/* ---- firma: el logotipo real, a sangre, escribiendose al entrar ---- */
.foot__mark{padding-inline:var(--gut);margin-top:clamp(2.5rem,6vw,5rem)}
.foot__markin{position:relative}
.foot__logo{
  display:block;width:100%;aspect-ratio:300/105;
  color:var(--cream);background:currentColor;opacity:.92;
  -webkit-mask:url("../assets/img/logo.svg") center/contain no-repeat;
  mask:url("../assets/img/logo.svg") center/contain no-repeat;
  clip-path:inset(0 100% 0 0)
}
.foot__mark.is-in .foot__logo{animation:foot-write 1.7s var(--e-out) forwards}
@keyframes foot-write{to{clip-path:inset(0 0 0 0)}}
/* el trazo que va dejando la firma */
.foot__markin::after{
  content:"";position:absolute;top:4%;bottom:4%;left:0;width:2px;
  background:var(--sand);opacity:0
}
.foot__mark.is-in .foot__markin::after{animation:foot-pen 1.7s var(--e-out) forwards}
@keyframes foot-pen{
  0%{opacity:1;left:0}
  88%{opacity:1}
  100%{opacity:0;left:100%}
}
@media (prefers-reduced-motion:reduce){
  .foot__logo{clip-path:none;animation:none}
  .foot__markin::after{display:none}
}

/* ---- barra inferior ---- */
.foot__bar{
  margin-top:clamp(2rem,4vw,3rem);
  border-top:1px solid rgba(247,244,239,.16);padding-block:1.5rem;
  display:flex;flex-wrap:wrap;gap:1rem 2rem;align-items:center;justify-content:space-between;
  font-size:.75rem;color:rgba(247,244,239,.6)
}
.foot__bar a:hover{color:var(--sand)}
.foot__legal{display:flex;flex-wrap:wrap;gap:.6rem 1.6rem;align-items:center}
/* Iconos de marca reales (trazados oficiales, sólidos). Al pasar el ratón el
   botón se pinta con el color de la red y despliega su nombre.             */
.foot__socials{display:flex;gap:.5rem;flex-wrap:wrap}
.soc{
  position:relative;height:44px;padding:0 13px;border-radius:999px;
  display:inline-flex;align-items:center;gap:0;
  border:1px solid rgba(247,244,239,.22);color:var(--cream);
  overflow:hidden;
  transition:background-color .45s var(--e-out),color .35s var(--e-out),
             border-color .45s var(--e-out),transform .45s var(--e-out),
             gap .45s var(--e-out),padding .45s var(--e-out)
}
.soc svg{width:19px;height:19px;flex:none;display:block}
.soc__t{
  max-width:0;opacity:0;white-space:nowrap;
  font-size:var(--fs-micro);font-weight:800;letter-spacing:.14em;text-transform:uppercase;
  transition:max-width .5s var(--e-out),opacity .35s var(--e-out)
}
.soc:hover,.soc:focus-visible{
  background:var(--brand,var(--cream));border-color:transparent;
  color:#fff;transform:translateY(-3px);gap:.55rem;padding:0 17px;outline:none
}
.soc:hover .soc__t,.soc:focus-visible .soc__t{max-width:9rem;opacity:1}
/* TikTok y Pinterest son casi negros/rojos: mantienen texto claro; sólo el
   fondo cambia, así que no hace falta excepción de color de texto.          */
@media (hover:none){
  .soc{padding:0 13px}
  .soc__t{display:none}
}
@media (prefers-reduced-motion:reduce){
  .soc,.soc__t{transition:background-color .2s,color .2s,border-color .2s}
}

/* ---------- Floating WhatsApp ---------- */
.wa{
  position:fixed;right:clamp(1rem,2.5vw,2rem);bottom:clamp(1rem,2.5vw,2rem);z-index:700;
  width:clamp(52px,4.2vw,60px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;
  background:#25D366;color:#fff;
  transform-origin:100% 100%;will-change:transform,opacity;
  opacity:0;visibility:hidden;transform:scale(.5);
  transition:transform .55s var(--e-out),opacity .3s var(--e-soft),
             visibility 0s linear .55s
}
.wa.is-in{opacity:1;visibility:visible;transform:scale(1);transition-delay:0s}
.wa:hover{transform:scale(1.07)}
.wa:active{transform:scale(.96)}
.wa:focus-visible{outline:2px solid var(--cream);outline-offset:3px}
.wa svg{width:45%;height:45%;flex:none}
/* label solo para lectores de pantalla */
.wa span{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0
}

@media (prefers-reduced-motion:reduce){
  .wa{transition:opacity .2s linear;transform:none}
  .wa.is-in,.wa:hover,.wa:active{transform:none}
}

/* ---------- Selector de idioma (fijo, abajo a la izquierda) ----------
   Espejo del WhatsApp: misma altura, misma entrada, lado opuesto. El
   indicador es un único <i> que se desliza con --i (0 = ES, 1 = EN): un
   solo transform, sin layout ni repintado de los botones.              */
.lang{
  --i:0;
  --lang-b:clamp(40px,3.4vw,46px);
  position:fixed;left:clamp(1rem,2.5vw,2rem);bottom:clamp(1rem,2.5vw,2rem);z-index:700;
  display:flex;align-items:center;padding:4px;border-radius:999px;isolation:isolate;
  /* Fondo opaco, igual que el botón de WhatsApp: sin sombra y sin
     backdrop-filter. El blur bajo un elemento con transform se muestrea en el
     espacio local del elemento, así que durante la entrada (scale .5 → 1)
     dejaba costuras y líneas raras en el borde redondeado.                  */
  background:#141935;
  border:1px solid rgba(247,244,239,.16);
  transform-origin:0% 100%;will-change:transform,opacity;
  opacity:0;visibility:hidden;transform:scale(.5);
  transition:transform .55s var(--e-out),opacity .3s var(--e-soft),
             visibility 0s linear .55s
}
.lang.is-in{opacity:1;visibility:visible;transform:scale(1);transition-delay:0s}

.lang__b{
  position:relative;z-index:1;
  /* Ancho fijo, no min-width: las dos celdas deben medir exactamente lo mismo
     o el indicador —que se desplaza un 100% de su propio ancho— cae torcido. */
  width:var(--lang-b);height:clamp(30px,2.6vw,34px);
  padding:0;border-radius:999px;
  font-size:clamp(.6875rem,.9vw,.75rem);font-weight:700;letter-spacing:.1em;
  text-indent:.1em;
  color:rgba(247,244,239,.62);
  transition:color .35s var(--e-out);
  -webkit-tap-highlight-color:transparent
}
.lang__b.is-on{color:var(--ink)}
.lang__b:focus-visible{outline:2px solid var(--sand);outline-offset:2px}

/* El fondo claro que viaja bajo la opción activa */
.lang__ind{
  position:absolute;top:4px;bottom:4px;left:4px;z-index:0;
  width:var(--lang-b);
  border-radius:999px;background:var(--cream);
  transform:translateX(calc(var(--i) * 100%));
  transition:transform .5s var(--e-out)
}

@media (hover:hover){
  .lang__b:not(.is-on):hover{color:var(--cream)}
}
@media (prefers-reduced-motion:reduce){
  .lang{transition:opacity .2s linear;transform:none}
  .lang.is-in{transform:none}
  .lang__ind{transition:none}
}


/* ══════════════════════════════════════════════════════════════════════════
   HERO de PAQUETES — pliego editorial
   El home es foto a sangre + titular centrado encima sobre velo oscuro.
   Éste es su opuesto: dos columnas, texto a bandera izquierda sobre crema y
   la foto AL LADO, nunca debajo del texto. Así la cara se ve entera y las
   dos portadas no se confunden aunque compartan tipografía y paleta.
   ══════════════════════════════════════════════════════════════════════════ */
.pkh{
  position:relative;overflow:hidden;background:var(--cream);
  min-height:100svh;
  display:grid;grid-template-columns:minmax(0,50fr) minmax(0,50fr);
  align-items:stretch
}

/* ---------- columna de texto ---------- */
.pkh__copy{
  position:relative;z-index:2;
  display:flex;flex-direction:column;justify-content:center;
  gap:clamp(1rem,1.8vw,1.75rem);
  padding:calc(var(--nav-h) + clamp(1.75rem,4vw,3.5rem))
          clamp(1.75rem,4.5vw,4.5rem)
          clamp(4.5rem,7vw,5.5rem)
          var(--gut)
}

.pkh__title{
  font-family:var(--serif);
  /* topado para que "Para el día que" quepa en una línea a cualquier
     ancho: partido en tres, el "que" quedaba viudo */
  font-size:clamp(2.5rem,5.1vw,4.75rem);
  line-height:.92;letter-spacing:-.03em
}
.pkh__title em{font-style:italic;color:var(--rose)}

.pkh__sub{
  max-width:42ch;font-size:var(--fs-lead);line-height:1.5;color:var(--muted)
}

/* ---------- escalera de precios: es la navegación del hero ---------- */
.pkh__ladder{
  margin-top:clamp(.5rem,1.5vw,1.25rem);
  /* el tirón negativo devuelve las filas a la bandera del titular pese al
     relleno que necesitan para invertirse en hover sin quedar pegadas */
  margin-inline:calc(clamp(.6rem,1.2vw,1rem) * -1);
  display:grid;border-top:var(--hair) solid var(--line)
}
.pkh__ladder a{
  position:relative;isolation:isolate;
  display:grid;grid-template-columns:auto 1fr auto auto;align-items:baseline;
  gap:clamp(.7rem,1.6vw,1.4rem);
  padding:clamp(.7rem,1.4vw,1rem) clamp(.6rem,1.2vw,1rem);
  border-bottom:var(--hair) solid var(--line);
  color:var(--fg);
  transition:color .4s var(--e-out)
}
/* El relleno navy entra desde la izquierda: un scaleX, sin layout ni pintado */
.pkh__ladder a::before{
  content:"";position:absolute;inset:0;z-index:-1;background:var(--navy);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform .55s var(--e-out)
}
.pkh__n{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.2em;
  color:var(--muted);transition:color .4s var(--e-out)
}
.pkh__ladder b{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.3rem,2.3vw,2rem);line-height:1;letter-spacing:-.02em
}
.pkh__ladder em{
  font-style:normal;font-weight:700;
  font-size:clamp(.875rem,1.15vw,1.05rem);letter-spacing:.01em;
  color:var(--navy);transition:color .4s var(--e-out)
}
.pkh__go{
  display:grid;place-items:center;width:1.15em;height:1.15em;
  transform:translateX(-6px);opacity:0;
  transition:transform .5s var(--e-out),opacity .4s var(--e-out)
}
.pkh__go svg{width:100%;height:100%}

@media (hover:hover){
  .pkh__ladder a:hover::before{transform:scaleX(1)}
  .pkh__ladder a:hover{color:var(--cream)}
  .pkh__ladder a:hover .pkh__n{color:rgba(247,244,239,.6)}
  .pkh__ladder a:hover em{color:var(--sand)}
  .pkh__ladder a:hover .pkh__go{transform:none;opacity:1}
}
.pkh__ladder a:focus-visible{outline:2px solid var(--navy);outline-offset:-2px}
.pkh__ladder a:focus-visible::before{transform:scaleX(1)}
.pkh__ladder a:focus-visible{color:var(--cream)}
.pkh__ladder a:focus-visible .pkh__go{transform:none;opacity:1}

/* ---------- columna de foto ----------
   Sin overflow propio: el recorte lo hace .pkh__shot, así el inserto puede
   montarse sobre la costura y salirse hacia la columna de texto. */
.pkh__art{position:relative}
.pkh__shot{position:absolute;inset:0;overflow:hidden;background:var(--sand)}
.pkh__shot img{
  width:100%;height:100%;object-fit:cover;
  /* encuadre sobre la cara: en columna alta el centro geométrico la corta */
  object-position:38% 20%
}

/* micro.js estampa `mi-media mi-sheen` sobre estas dos cajas para su barrido
   de entrada, y `.js .mi-sheen` trae consigo `position:relative`. Esa sola
   línea desarmaba el pliego entero: las dos fotos volvían al flujo, la
   columna crecía hasta la SUMA de sus altos (el hero pasaba de 100svh a
   1512px) y el inserto, en vez de montarse sobre la costura, quedaba
   colgando por debajo de la foto grande sobre el crema. De ahí que se
   leyera suelto, pequeño y sin sitio: no estaba mal dimensionado, estaba
   fuera de su posición.
   Se recupera el posicionado sin quitarle a micro.js su entrada — de ahí la
   clase repetida, que es la especificidad mínima para ganarle a
   `.js .mi-sheen`, que carga después.                                    */
.pkh__art .pkh__shot.pkh__shot,
.pkh__art .pkh__inset.pkh__inset{position:absolute}

.pkh__inset{
  position:absolute;left:0;z-index:2;
  /* A ras del canto inferior del pliego. Flotando a media altura sobre el
     crema no tenía de dónde agarrarse — era eso, y no el tamaño, lo que lo
     hacía leer como una miniatura suelta. Cortado por el borde de la
     sección comparte una línea REAL con la foto grande y con el final del
     hero, y pasa a ser una segunda lámina del mismo pliego.
     El filete crema se quita abajo (más abajo, tras el atajo `border`):
     contra el canto de la sección se vería como una franja olvidada, no
     como marco.                                                         */
  bottom:0;
  /* De 208px de tope a 340px: a 15vw quedaba en miniatura contra una
     columna de media pantalla y leía a cromo pegado, no a segunda foto
     del pliego.                                                         */
  width:clamp(150px,20vw,340px);aspect-ratio:3/4;
  /* `translate`, NO `transform`: el inserto es .r-fade, y la regla de
     entrada `.js .r-fade.is-in{transform:none}` borraba el desplazamiento
     — el inserto nunca llegaba a montarse sobre la costura, se quedaba
     pegado al canto de la columna. Con la propiedad aparte, entrada y
     composición dejan de pelearse por el mismo canal.
     El desborde es una MEDIDA FIJA, no un porcentaje de su propio ancho: a
     -42 % el inserto grande se comía el extremo derecho de la escalera —
     justo donde van los precios. Una medida corta siempre cabe dentro del
     padding derecho de la columna de texto, así que cruza la costura a
     cualquier ancho sin llegar nunca a pisar un enlace.                 */
  translate:calc(-1 * clamp(14px,2vw,40px)) 0;
  overflow:hidden;border-radius:var(--radius);
  /* El marco crema se mantiene proporcional al nuevo tamaño; es lo que lo
     separa de la foto de debajo sin tener que oscurecerla.              */
  border:clamp(6px,.62vw,11px) solid var(--cream);
  border-bottom:0;
  /* Sombra más baja y más abierta: a este tamaño la anterior lo levantaba
     tanto que volvía a leerse como pegatina. Y sin desplazamiento vertical,
     porque la lámina ya no está levantada sobre nada: apoya en el canto. */
  box-shadow:0 0 64px -30px rgba(11,15,36,.42),
             0 0 14px -8px rgba(11,15,36,.18)
}
.pkh__inset img{width:100%;height:100%;object-fit:cover;object-position:62% 18%}

/* ══════════════════ tablet y móvil ══════════════════
   El pliego se dobla: la foto pasa a ser una banda superior y el texto queda
   debajo. Sigue ocupando exactamente una pantalla. */
@media (max-width:1024px){
  .pkh{
    grid-template-columns:1fr;
    /* la banda crece con la pantalla: en tablets altas una franja fija dejaba
       un hueco muerto bajo la escalera */
    grid-template-rows:clamp(240px,42svh,520px) 1fr
  }
  .pkh__art{order:-1}
  .pkh__copy{
    justify-content:center;
    padding:clamp(1.5rem,5vw,2.5rem) var(--gut) clamp(2rem,6vw,3rem)
  }
  .pkh__title{max-width:none;font-size:clamp(2.4rem,8.5vw,4.25rem)}
  .pkh__sub{max-width:52ch}
  /* el inserto se montaba sobre la costura; sin dos columnas ya no hay costura */
  .pkh__inset{display:none}
  /* en banda apaisada la cara sube y la barra le pisa la frente: se baja el encuadre */
  .pkh__shot img{object-position:41% 9%}
}

/* Pantallas bajas: el sub es lo primero que sobra antes que romper el 100svh */
@media (max-width:1024px) and (max-height:680px){
  .pkh__sub{display:none}
}

@media (max-width:520px){
  .pkh{grid-template-rows:clamp(200px,32svh,300px) 1fr}
  .pkh__ladder b{font-size:clamp(1.15rem,6vw,1.5rem)}
  .pkh__ladder a{gap:.6rem;padding-block:.7rem}
}

@media (prefers-reduced-motion:reduce){
  .pkh__ladder a::before,.pkh__go{transition:none}
}

/* ---------- Progress bar ---------- */
.prog{position:fixed;top:0;left:0;height:2px;width:100%;z-index:850;transform-origin:0 50%;transform:scaleX(0);background:var(--rose)}

/* ==========================================================================
   PAGE HERO — un sistema, siete tratamientos
   Cada página interior tiene su propia composición: partida, a sangre,
   objeto, silenciosa, apilada, tira y regla. Comparten tres piezas y nada
   más — capa de medio, velo que funde con la sección de abajo, y bloque de
   texto — para que ninguna se parezca a la anterior sin duplicar CSS.

   `--bleed` es el color de la sección que viene DESPUÉS. El velo termina
   exactamente en ese color, así el hero no "acaba": se disuelve.
   ========================================================================== */
.ph{
  --bleed:var(--bg);
  position:relative;isolation:isolate;overflow:hidden;
  padding-top:calc(var(--nav-h) + clamp(2.5rem,7vw,5.5rem));
  padding-bottom:clamp(3rem,7vw,5.5rem)
}
.ph--dark{color:var(--cream);background:var(--ink)}
.ph__in{position:relative;z-index:3}

.ph__media{position:absolute;inset:-6% 0;z-index:0;overflow:hidden;will-change:transform}
.ph__media img,.ph__media video{width:100%;height:100%;object-fit:cover;display:block}

.ph__veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(11,15,36,.72) 0%,rgba(11,15,36,.28) 34%,rgba(11,15,36,.55) 72%,var(--bleed) 100%),
    radial-gradient(120% 70% at 50% 46%,rgba(11,15,36,.34) 0%,rgba(11,15,36,0) 72%)
}

.ph__title{
  font-family:var(--serif);font-size:var(--fs-h1);line-height:.92;
  letter-spacing:-.03em;max-width:14ch
}
/* La cursiva en arena solo contrasta sobre fondo oscuro; sobre crema hay que
   bajarla dos pasos o la palabra se pierde. */
.ph__title em{font-style:italic}
.ph--dark .ph__title,
.ph--dark .ph__title em{color:var(--white)}
.ph__sub{max-width:48ch;margin-top:2rem;font-size:var(--fs-lead);line-height:1.5;opacity:.84}
.ph__cta{margin-top:2.25rem;display:flex;gap:.75rem;flex-wrap:wrap}

/* Cifras del hero. Los contadores ya existen (data-count): aquí solo viven. */
.ph__stats{display:flex;gap:clamp(1.75rem,4vw,3.5rem);margin-top:clamp(2.25rem,5vw,3.5rem);flex-wrap:wrap}
.ph__stats li{display:flex;flex-direction:column;gap:.15rem}
.ph__stats b{font-family:var(--serif);font-size:clamp(1.85rem,3.4vw,2.9rem);line-height:1;font-weight:400;letter-spacing:-.02em}
.ph__stats span{font-size:var(--fs-micro);letter-spacing:.18em;text-transform:uppercase;opacity:.62}

/* ── A · PARTIDA (servicios) ──────────────────────────────────────────────
   Texto a la izquierda, panel de vídeo a la derecha que se sale del margen
   y baja por debajo del hero para coserlo con la lista de precios.        */
/* Hero claro. Antes era un bloque navy a sangre con patrón azul encima: el
   vídeo quedaba encerrado en un rectángulo de color y la página arrancaba
   oscura para volverse blanca dos secciones después. Ahora la superficie es
   la misma que el resto del sitio y el único color fuerte es el propio vídeo,
   que es lo que se quiere mirar. */
.ph--split{--bleed:var(--bg);background:var(--bg);color:var(--fg);padding-bottom:clamp(5.5rem,11vw,8rem)}
/* Lavado tibio bajísimo, sólo para que el blanco del hero no sea el mismo
   plano muerto que el de la carta que viene debajo. No es un color: es papel. */
.ph--split::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:linear-gradient(168deg,
    rgba(220,214,208,.30) 0%,
    rgba(220,214,208,.10) 38%,
    rgba(255,255,255,0) 72%)
}
/* El fundido sale por debajo del contenido (z-index 1 < .ph__grid 3) pero el
   texto crema sobre el tramo claro perdía contraste: la rampa se queda corta
   y el bloque respira por encima gracias al padding inferior. */
.ph--split::after{
  content:"";position:absolute;left:0;right:0;bottom:0;z-index:1;pointer-events:none;
  /* altura fija, no porcentual: en móvil el hero se estira y un 22% subía
     hasta las cifras */
  height:clamp(90px,16%,240px);
  background:linear-gradient(180deg,transparent,var(--bleed) 92%)
}
/* Jerarquía del hero claro. Sobre navy bastaba con opacidad para calmar el
   texto secundario; sobre blanco la opacidad lo LAVA — parece deshabilitado.
   Aquí cada nivel es un color propio: ink el titular, navy la cursiva y las
   cifras, muted el apoyo. */
/* El rosa de marca a 11 px sobre blanco se queda en ~2.7:1 y el ojo lo lee
   como texto apagado, no como acento. Se hunde un tercio hacia ink: sigue
   siendo rosa, ya se lee. */
.ph--split .ph__title em{color:var(--navy)}
.ph--split .ph__sub{opacity:1;color:var(--muted)}
.ph--split .ph__stats b{color:var(--navy)}
.ph--split .ph__stats span{opacity:1;color:var(--muted)}
.ph__grid{
  position:relative;z-index:3;display:grid;grid-template-columns:1.05fr .95fr;
  gap:clamp(2rem,5vw,4.5rem);align-items:center
}
.ph__panel{
  position:relative;margin:0;aspect-ratio:4/5;border-radius:var(--radius-lg);overflow:hidden;
  /* se sale por la derecha: rompe la caja y quita el aire de plantilla */
  margin-right:calc(var(--gut) * -1);background:var(--ink-soft)
}
.ph__panel video,.ph__panel img{width:100%;height:100%;object-fit:cover;display:block}
.ph__panel::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(200deg,rgba(11,15,36,0) 45%,rgba(11,15,36,.5))
}
.ph__panel-cap{
  position:absolute;left:1.1rem;bottom:1.1rem;z-index:2;
  font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;color:var(--cream);opacity:.85
}

/* ── B · A SANGRE (paquetes) ──────────────────────────────────────────────
   Foto a pantalla completa, texto centrado, y una barandilla de precios
   flotando abajo que ya adelanta lo que viene.                            */
.ph--full{--bleed:var(--bg);min-height:86svh;display:flex;flex-direction:column;justify-content:center}
.ph--full .ph__in{text-align:center;display:flex;flex-direction:column;align-items:center}
.ph--full .ph__title{max-width:16ch;font-size:clamp(2.9rem,8.5vw,7.5rem)}
.ph--full .ph__sub{margin-inline:auto}
.ph__rail{
  position:relative;z-index:3;display:flex;gap:.6rem;justify-content:center;flex-wrap:wrap;
  margin-top:clamp(2.5rem,6vw,4rem)
}
.ph__rail a{
  display:flex;align-items:baseline;gap:.7rem;padding:.85rem 1.35rem;border-radius:999px;
  border:1px solid rgba(247,244,239,.28);color:var(--cream);
  background:rgba(11,15,36,.28);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  transition:background-color .45s var(--e-out),border-color .45s var(--e-out),transform .45s var(--e-out)
}
.ph__rail a:hover{background:var(--white);color:var(--navy);border-color:transparent;transform:translateY(-3px)}
.ph__rail b{font-weight:700;font-size:.8125rem;letter-spacing:.06em;text-transform:uppercase}
.ph__rail em{font-style:normal;font-family:var(--serif);font-size:1.15rem}

/* ── C · OBJETO (gift cards) ──────────────────────────────────────────────
   Sin foto de fondo: la foto ES la tarjeta, un objeto en 3D que sigue al
   cursor. El fondo es luz de marca, no un rectángulo azul.                */
.ph--object{
  --bleed:var(--bg);background:var(--paper);color:var(--fg);
  padding-bottom:clamp(3.5rem,8vw,6.5rem)
}
.ph--object::before{
  content:"";position:absolute;z-index:0;pointer-events:none;
  inset:-30% -10% auto -10%;height:120%;
  background:
    radial-gradient(48% 46% at 22% 34%,rgba(192,140,134,.28),transparent 70%),
    radial-gradient(52% 50% at 82% 24%,rgba(39,53,105,.20),transparent 72%)
}
.ph--object .ph__grid{grid-template-columns:1fr .92fr;align-items:center}

.tiltcard{
  position:relative;z-index:3;perspective:1200px;
  display:flex;align-items:center;justify-content:center;padding-block:1rem
}
.tiltcard__card{
  position:relative;width:min(100%,430px);aspect-ratio:1.586/1;border-radius:18px;overflow:hidden;
  transform:rotate(-7deg);transform-style:preserve-3d;
  /* sin sombra en ningún sitio salvo la cápsula del nav */
  transition:transform .8s var(--e-out)
}
.tiltcard__card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.tiltcard__card::after{
  content:"";position:absolute;inset:0;background:linear-gradient(145deg,rgba(11,15,36,.82),rgba(39,53,105,.62))
}
.tiltcard__face{
  position:absolute;inset:0;z-index:2;padding:clamp(1.1rem,2.4vw,1.7rem);
  display:flex;flex-direction:column;justify-content:space-between;color:var(--cream)
}
.tiltcard__brand{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.tiltcard__brand img{position:static;width:auto;height:26px;object-fit:contain;filter:brightness(0) invert(1)}
.tiltcard__lbl{font-size:var(--fs-micro);letter-spacing:.24em;text-transform:uppercase;opacity:.75}
.tiltcard__amt{font-family:var(--serif);font-size:clamp(2.4rem,5vw,3.6rem);line-height:1;letter-spacing:-.03em}
.tiltcard__amt i{font-style:normal;font-size:.42em;opacity:.7;margin-right:.25em;vertical-align:.55em}
.tiltcard__foot{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;font-size:.72rem;opacity:.72}
/* brillo que barre la tarjeta cuando el puntero la cruza */
.tiltcard__shine{
  position:absolute;inset:-40%;z-index:3;pointer-events:none;opacity:0;
  background:linear-gradient(102deg,
    transparent 30%,
    rgba(255,255,255,.055) 41%,
    rgba(255,255,255,.16) 50%,
    rgba(255,255,255,.055) 59%,
    transparent 70%);
  filter:blur(8px);
  transform:translateX(-50%)
}
.tiltcard:hover .tiltcard__shine{animation:gshine 1.5s var(--e-soft) forwards}
@keyframes gshine{
  0%  {opacity:0;transform:translateX(-50%)}
  20% {opacity:1}
  72% {opacity:1}
  100%{opacity:0;transform:translateX(50%)}
}
@media (prefers-reduced-motion:reduce){
  .tiltcard:hover .tiltcard__shine{animation:none;opacity:0}
}

/* ══════════════════════════════════════════════════════════════════════════
   CONTACTO — todo lo que hace falta para escribir, en la PRIMERA pantalla.

   La versión anterior pedía 5 pantallas de scroll para dar un número de
   teléfono: titular a 8.5rem, cuatro filas de 90 px con serif enorme y
   miniatura al hover, un mapa embebido que renderizaba en blanco y una
   tabla de siete días para un horario que en realidad son DOS.
   Contactar no se diseña como un artículo: se diseña como un botón.

   Ahora: cabecera compacta + dos canales rápidos (WhatsApp y agenda) +
   dos lentos (teléfono y correo) en una fila fina. Cero scroll para lo
   que el 95 % de la gente viene a hacer.
   ══════════════════════════════════════════════════════════════════════ */
.ctc{
  padding-top:calc(var(--nav-h) + clamp(1.5rem,4vw,3rem));
  padding-bottom:clamp(2rem,4.5vw,3.5rem)
}
/* Titular y estado en vivo comparten fila: saber si están abiertos AHORA
   es la mitad de la pregunta, y antes vivía tres bloques más abajo. */
.ctc__head{
  display:grid;grid-template-columns:1.1fr .9fr;
  gap:clamp(1rem,3vw,3rem);align-items:end
}
.ctc__title{
  font-family:var(--serif);font-size:clamp(2.9rem,7.5vw,6rem);
  line-height:.88;letter-spacing:-.035em
}
.ctc__title em{font-style:italic;color:var(--rose)}
.ctc__sub{color:var(--muted);max-width:38ch;font-size:var(--fs-lead);line-height:1.45}
.ctc__now{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem .9rem;margin-top:1rem}
.ctc__hrs{font-size:var(--fs-small);color:var(--muted);font-variant-numeric:tabular-nums}

/* ---- Canales ---- */
.chan{
  display:grid;grid-template-columns:repeat(2,1fr);
  gap:clamp(.7rem,1.3vw,1rem);margin-top:clamp(1.75rem,3.5vw,2.75rem)
}
.chan__b{
  position:relative;display:flex;flex-direction:column;gap:.5rem;
  padding:clamp(1.25rem,2.3vw,1.9rem);
  min-height:clamp(148px,16vw,196px);
  border:var(--hair) solid var(--line);border-radius:var(--radius-lg);background:var(--white);
  transition:border-color .45s var(--e-out),transform .5s var(--e-out),background-color .45s var(--e-out)
}
.chan__b:hover{border-color:var(--navy);transform:translateY(-4px)}
.chan__b:focus-visible{outline:2px solid var(--rose);outline-offset:3px}
.chan__ico{width:28px;height:28px;color:var(--navy);margin-bottom:.35rem}
.chan__ico svg{width:100%;height:100%;display:block}
.chan__t{
  font-family:var(--serif);font-size:clamp(1.4rem,2.5vw,2.05rem);
  line-height:1.05;letter-spacing:-.02em
}
.chan__d{color:var(--muted);font-size:.9375rem;line-height:1.45}
.chan__v{
  margin-top:auto;padding-top:.9rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;font-weight:800
}
.chan__v svg{width:18px;height:18px;flex:none;transition:transform .45s var(--e-out)}
.chan__b:hover .chan__v svg{transform:translateX(5px)}

/* WhatsApp va en navy: es el canal que de verdad responde en minutos, así
   que es el único que pesa. Una jerarquía real, no cuatro filas iguales. */
.chan__b--wa{background:var(--navy);border-color:var(--navy);color:var(--cream)}
.chan__b--wa .chan__ico{color:#25D366}
.chan__b--wa .chan__d{color:rgba(247,244,239,.72)}
.chan__b--wa:hover{background:var(--ink-soft);border-color:var(--ink-soft)}

/* Los canales lentos no merecen otra tarjeta grande: una fila fina basta. */
.chan__mini{grid-column:1/-1;display:grid;grid-template-columns:1fr 1fr;gap:clamp(.7rem,1.3vw,1rem)}
.mini{
  display:flex;align-items:center;gap:.85rem;
  padding:.95rem clamp(1rem,1.7vw,1.35rem);min-height:66px;
  border:var(--hair) solid var(--line);border-radius:var(--radius-lg);background:var(--white);
  transition:border-color .45s var(--e-out),transform .45s var(--e-out)
}
.mini:hover{border-color:var(--navy);transform:translateY(-3px)}
.mini:focus-visible{outline:2px solid var(--rose);outline-offset:3px}
.mini__ico{width:19px;height:19px;flex:none;color:var(--navy)}
.mini__ico svg{width:100%;height:100%;display:block}
.mini__b{min-width:0}
.mini__t{
  display:block;font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  font-weight:800;color:var(--muted)
}
.mini__v{display:block;font-size:.9375rem;font-weight:600;margin-top:.15rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mini__go{margin-left:auto;flex:none;width:17px;height:17px;color:var(--muted);
  transition:transform .45s var(--e-out),color .45s var(--e-out)}
.mini:hover .mini__go{transform:translateX(4px);color:var(--navy)}

/* ---- Horario resumido: son DOS tramos, no siete filas ---- */
.hsum{
  display:flex;flex-wrap:wrap;align-items:center;gap:.5rem clamp(1.25rem,3vw,2.5rem);
  padding-top:clamp(1.1rem,2.2vw,1.6rem);margin-top:clamp(1.75rem,3.5vw,2.75rem);
  border-top:var(--hair) solid var(--line);
  font-size:var(--fs-small);color:var(--muted)
}
.hsum__i{display:inline-flex;align-items:baseline;gap:.6rem}
.hsum__d{
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  font-weight:800;color:var(--fg)
}
.hsum__t{font-variant-numeric:tabular-nums}

@media (max-width:900px){
  /* En móvil el pulgar manda: una columna, WhatsApp primero y a lo ancho.
     Cada línea que se ahorra arriba es una que acerca el botón al fold. */
  .ctc{padding-top:calc(var(--nav-h) + 1.25rem)}
  .ctc__head{grid-template-columns:1fr;align-items:start;gap:.9rem}
  .ctc__sub{font-size:var(--fs-body);max-width:none}
  .ctc__now{margin-top:.85rem;gap:.5rem .75rem}
  .chan{grid-template-columns:1fr;margin-top:1.5rem;gap:.65rem}
  .chan__b{min-height:0;padding:1.15rem 1.2rem;gap:.4rem}
  .chan__v{padding-top:.75rem}
  .chan__mini{grid-template-columns:1fr;gap:.65rem}
  .mini{min-height:60px;padding:.8rem 1.1rem}
  .hsum{margin-top:1.5rem;gap:.35rem 1.25rem}
}

/* ── E · APILADA (nosotros) ───────────────────────────────────────────────
   El titular arriba y una banda ancha que se estrecha y redondea conforme
   bajas: el hero se convierte en la primera figura del artículo.          */
.ph--stack{--bleed:var(--bg);background:var(--bg);padding-bottom:0}
.ph--stack .ph__title{max-width:13ch}
.ph__wide{
  position:relative;margin-top:clamp(2.5rem,6vw,4rem);
  height:clamp(320px,58vh,620px);overflow:hidden;
  border-radius:0;will-change:border-radius,width
}
.ph__wide img{width:100%;height:100%;object-fit:cover;display:block}
.ph__wide figcaption{
  position:absolute;left:clamp(1rem,3vw,2rem);bottom:clamp(1rem,3vw,2rem);z-index:2;
  color:var(--cream);font-size:var(--fs-micro);letter-spacing:.2em;text-transform:uppercase;
  padding:.55rem 1rem;border-radius:999px;background:rgba(11,15,36,.42);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)
}
/* ── F · MURO (galería) ───────────────────────────────────────────────────
   Aquí no hay degradado. El anterior iba de navy a crema atravesando un gris
   sucio justo encima de las fotos: una franja embarrada, y encima el mismo
   recurso que ya usan las otras cabeceras.

   Este es otro objeto: un muro de fotos que sube y baja en columnas a
   distintas velocidades, un velo PLANO (sin rampa: sin rampa no hay franja),
   y el titular dentro de unas marcas de recorte de fotógrafo. El borde
   inferior es un CORTE LIMPIO, no un desvanecido — el muro es la portada del
   catálogo y las portadas terminan, no se disuelven.                        */
.ph--wall{
  background:var(--ink);color:var(--cream);
  min-height:clamp(520px,74svh,760px);
  display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(5rem,11vw,8rem)
}
/* El muro desborda por arriba y por abajo para que la deriva de las columnas
   nunca enseñe el final de una columna. */
.wall{
  position:absolute;inset:-12% -2%;z-index:0;
  display:grid;grid-template-columns:repeat(6,1fr);gap:clamp(6px,.7vw,10px)
}
.wall__col{display:grid;gap:clamp(6px,.7vw,10px);align-content:start;will-change:transform}
.wall__col img{
  width:100%;aspect-ratio:3/4;object-fit:cover;display:block;
  border-radius:var(--radius-media);
  /* Bajar saturación y subir contraste: el muro es textura de fondo, no una
     galería que compita con el titular. */
  filter:saturate(.82) contrast(1.02)
}
/* Columnas impares suben, pares bajan. La lista va DUPLICADA en el DOM, así
   que el -50% cae exactamente en la costura y el bucle no salta. */
.wall__col{animation:wallUp var(--sp,52s) linear infinite}
.wall__col:nth-child(even){animation-name:wallDown}
@keyframes wallUp{from{transform:translateY(0)}to{transform:translateY(-50%)}}
@keyframes wallDown{from{transform:translateY(-50%)}to{transform:translateY(0)}}

/* Velo. El toque de viñeta es radial, nunca vertical: un degradado vertical
   sobre este muro deja franja.
   Antes iba al revés — más oscuro fuera que dentro — y con un plano de .42
   debajo el borde llegaba al 91% de negro: el muro no se veía, sólo se
   intuía. Ahora el peso está DENTRO, bajo el titular (66%), y se abre hacia
   los cantos (44%), que es donde las fotos tienen que leerse. */
.wall__veil{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(52% 46% at 50% 44%,rgba(11,15,36,.66) 0%,rgba(11,15,36,.26) 100%),
    rgba(11,15,36,.20)
}

/* Marcas de recorte: cuatro escuadras, ninguna caja. Es el gesto de una
   página de galería — encuadrar — y no un rectángulo decorativo. */
.wall__frame{
  position:relative;z-index:3;max-width:min(860px,100%);margin-inline:auto;
  padding:clamp(2.25rem,5vw,3.75rem) clamp(1.5rem,4vw,3.25rem);
  text-align:center;display:flex;flex-direction:column;align-items:center
}
.wall__k{position:absolute;width:clamp(18px,2.2vw,30px);height:clamp(18px,2.2vw,30px);pointer-events:none}
.wall__k::before,.wall__k::after{content:"";position:absolute;background:rgba(247,244,239,.72)}
.wall__k::before{left:0;top:0;width:100%;height:1px}
.wall__k::after{left:0;top:0;width:1px;height:100%}
.wall__k--tl{left:0;top:0}
.wall__k--tr{right:0;top:0;transform:scaleX(-1)}
.wall__k--bl{left:0;bottom:0;transform:scaleY(-1)}
.wall__k--br{right:0;bottom:0;transform:scale(-1)}

.ph--wall .ph__title{max-width:15ch;margin-top:1.1rem}
.ph--wall .ph__sub{margin-inline:auto;max-width:46ch}
.ph--wall .ph__cta{justify-content:center}
/* Contador: el dato es el argumento de la página, pero flotando suelto sobre
   el mosaico caía encima de una foto y se perdía — y a 4.25rem competía con
   el propio titular. Aquí es una placa: cápsula con desenfoque propia, cifra
   a la izquierda, rótulo detrás de un filete. Se lee sobre cualquier foto que
   pase por debajo y ya no depende de lo oscuro que esté el velo. */
.wall__count{
  margin-top:clamp(1.6rem,3.2vw,2.35rem);
  display:inline-flex;align-items:center;gap:clamp(.8rem,1.6vw,1.15rem);
  padding:.55rem 1.25rem .55rem 1.35rem;border-radius:999px;
  border:var(--hair) solid rgba(247,244,239,.3);
  background:rgba(11,15,36,.38);
  -webkit-backdrop-filter:blur(10px) saturate(1.3);
  backdrop-filter:blur(10px) saturate(1.3)
}
.wall__count b{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.85rem,3.6vw,2.6rem);line-height:1;letter-spacing:-.03em;
  color:var(--white);font-variant-numeric:tabular-nums
}
.wall__count span{
  font-family:var(--sans);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.2em;text-transform:uppercase;line-height:1.4;text-align:left;
  color:rgba(247,244,239,.8);
  padding-left:clamp(.8rem,1.6vw,1.15rem);
  border-left:var(--hair) solid rgba(247,244,239,.26)
}

@media (prefers-reduced-motion:reduce){
  .wall__col{animation:none}
}
@media (max-width:1024px){
  .wall{grid-template-columns:repeat(4,1fr)}
  .wall__col:nth-child(n+5){display:none}
}
@media (max-width:600px){
  .wall{grid-template-columns:repeat(3,1fr);inset:-16% -6%}
  .wall__col:nth-child(n+4){display:none}
  .ph--wall{min-height:clamp(460px,72svh,620px)}
  .wall__frame{padding-inline:clamp(1.1rem,5vw,2rem)}
  .wall__k{width:16px;height:16px}
}

/* ── G · REGLA (garantía) ─────────────────────────────────────────────────
   Página legal: aquí una foto sería ruido. Tipografía, una cifra enorme y
   dos filetes. Distinta por sustracción.                                   */
.ph--rule{--bleed:var(--bg);background:var(--bg);border-bottom:var(--hair) solid var(--line)}
.ph--rule .ph__in{
  display:grid;grid-template-columns:auto 1fr;gap:clamp(1.5rem,5vw,4rem);align-items:end
}
.ph__mark{
  font-family:var(--serif);font-size:clamp(5rem,16vw,13rem);line-height:.78;
  color:var(--sand-deep);letter-spacing:-.04em;user-select:none
}
.ph--rule .ph__title{margin-top:0;max-width:16ch}
.ph--rule .ph__sub{opacity:1;color:var(--muted)}

/* ==========================================================================
   SERVICIOS — carril de categorías (sustituye a la barra de chips)
   La barra sticky quedaba justo debajo de la cápsula del nav: dos barras
   flotantes con un hueco entre medias. El índice pasa a ser un carril
   vertical al lado de los precios: no compite con el nav, y de paso indica
   por dónde vas.
   ========================================================================== */
.srvpage{
  display:grid;grid-template-columns:minmax(190px,232px) 1fr;
  gap:clamp(2rem,5vw,4.5rem);align-items:start;
  padding-block:clamp(3rem,7vw,5.5rem)
}
/* min-width:auto es el valor por defecto de un item de grid: sin esto el
   scroller de categorías (10 píldoras en fila) no puede encoger, estira su
   columna y con ella toda la página — scroll horizontal en móvil. */
.srvpage > *,.pcat__body > *,.ph__grid > *{min-width:0}
.srvrail{position:sticky;top:calc(var(--nav-h) + 1.5rem);align-self:start}
.srvrail__t{
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--muted);padding-bottom:.9rem;border-bottom:var(--hair) solid var(--line)
}
.srvrail__list{position:relative;margin-top:.4rem}
/* filete que se desliza hasta la categoría en pantalla */
.srvrail__bar{
  position:absolute;left:0;top:0;width:2px;height:0;background:var(--rose);border-radius:2px;
  transition:transform .5s var(--e-out),height .5s var(--e-out);z-index:1
}
.srvrail__i{
  position:relative;display:grid;grid-template-columns:2rem 1fr;gap:.5rem;align-items:baseline;
  padding:.62rem 0 .62rem .9rem;font-size:.875rem;color:var(--muted);
  border-left:var(--hair) solid var(--line);
  transition:color .4s var(--e-out),padding-left .4s var(--e-out)
}
.srvrail__i:hover{color:var(--navy);padding-left:1.2rem}
.srvrail__i.is-active{color:var(--navy);font-weight:600}
.srvrail__i span{font-size:var(--fs-micro);font-weight:700;letter-spacing:.12em;color:var(--sand-deep)}
.srvrail__i.is-active span{color:var(--rose)}
/* versión móvil: scroller normal, NO sticky */
.srvtabs{display:none}

/* Categoría de precios ---------------------------------------------------- */
.pcat{padding-bottom:clamp(3rem,7vw,5rem);scroll-margin-top:calc(var(--nav-h) + 2rem)}
.pcat + .pcat{padding-top:clamp(2.5rem,6vw,4rem);border-top:var(--hair) solid var(--line)}
.pcat__head{
  display:grid;grid-template-columns:1fr auto;gap:1.5rem;align-items:end;margin-bottom:clamp(1.5rem,3vw,2.25rem)
}
.pcat__n{font-family:var(--serif);font-size:var(--fs-h3);line-height:1.02;letter-spacing:-.02em}
.pcat__tag{color:var(--muted);font-size:.9375rem;max-width:52ch;margin-top:.6rem}
.pcat__count{
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  white-space:nowrap
}
.pcat__body{display:grid;grid-template-columns:1fr minmax(230px,.42fr);gap:clamp(1.5rem,4vw,3rem);align-items:start}
.pcat__img{
  position:relative;aspect-ratio:3/4;border-radius:var(--radius-lg);overflow:hidden;
  position:sticky;top:calc(var(--nav-h) + 1.5rem)
}
.pcat__img img{width:100%;height:100%;object-fit:cover;transform:scale(1.08);will-change:transform}
.pcat__img figcaption{
  position:absolute;left:.85rem;right:.85rem;bottom:.85rem;z-index:2;color:var(--cream);
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase
}
.pcat__img::after{
  content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 52%,rgba(11,15,36,.62))
}

/* Lista de precios: mismo lenguaje que el acordeón del home — nombre, guía
   punteada, "desde" + importe. Dos columnas cuando caben.                  */
.plist{columns:2;column-gap:clamp(1.5rem,3.5vw,3rem)}
.plist--one{columns:1}
.prow{
  display:flex;align-items:baseline;gap:.75rem;break-inside:avoid;
  padding:.7rem 0;border-bottom:1px dashed var(--line-soft);position:relative;
  transition:padding-left .45s var(--e-out)
}
.prow:hover{padding-left:.6rem}
.prow::before{
  content:"";position:absolute;left:0;top:.35rem;bottom:.35rem;width:2px;background:var(--rose);
  transform:scaleY(0);transform-origin:bottom;transition:transform .45s var(--e-out)
}
.prow:hover::before{transform:scaleY(1);transform-origin:top}
.prow em{transition:color .35s var(--e-out)}
.prow:hover em{color:var(--rose)}
.prow b{font-weight:500;font-size:.9375rem;max-width:74%}
.prow i{flex:1;height:1px;background:transparent}
.prow em{font-style:normal;font-weight:700;color:var(--navy);white-space:nowrap;font-variant-numeric:tabular-nums}
.prow em small{font-weight:600;color:var(--muted);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;margin-right:.4rem}


/* ---------- Misc ---------- */
.hr{height:1px;background:var(--line);border:0;margin:0}
.badge{
  display:inline-flex;align-items:center;gap:.5rem;padding:.45rem .9rem;border-radius:999px;
  border:var(--hair) solid var(--line);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.14em;text-transform:uppercase
}
.badge--fill{background:var(--white);border-color:var(--line);color:var(--navy)}
.center{text-align:center}
.mt-s{margin-top:1rem}.mt-m{margin-top:2rem}.mt-l{margin-top:3rem}
.bg-navy{background:var(--navy);color:var(--cream)}
/* .bg-paper ya no cambia de tono — todo el sitio es blanco. Lo que separa
   la sección de la anterior es un filete, no un gris. */
.bg-paper{background:var(--bg);border-block:var(--hair) solid var(--line-soft)}
.bg-sand{background:var(--bg)}
.hide{display:none !important}

/* ---------- Responsive ---------- */
@media (max-width:1180px){
  .foot__head{grid-template-columns:1fr;gap:clamp(2.5rem,6vw,4rem)}
  .gifts{grid-template-columns:repeat(3,1fr)}
  /* La foto pasa a una columna de las cinco: por debajo de 1180 dos columnas
     de foto dejaban la ficha demasiado estrecha para dos filas de precios. */
  .carta__media{grid-column:span 2;aspect-ratio:1/1}
  .reel__stage{gap:clamp(1.25rem,2.5vw,2rem)}
  .vplay.vplay--arch{width:clamp(280px,25vw,340px)}
  .reel__ch{grid-template-columns:auto clamp(70px,7vw,96px) minmax(0,1fr) auto auto}
}
@media (max-width:1024px){
  :root{--nav-h:72px}
  /* Tres columnas no caben: la apaisada pasa a lo ancho y debajo quedan la
     ficha y la vertical, que es donde el desfase sigue leyéndose. */
  .dip{
    grid-template-columns:1fr 1fr;
    column-gap:clamp(1rem,3vw,2rem);row-gap:clamp(1.5rem,4vw,2.5rem)
  }
  .dip__plate--wide{grid-column:1/-1;align-self:auto}
  .dip__plate--wide .dip__frame{aspect-ratio:16/10}
  .dip__plate--tall{grid-column:2;margin-bottom:0}
  .dip__plate--tall .dip__frame{aspect-ratio:4/5}
  /* Al lado de una foto de 490px, tres renglones pegados abajo dejaban un
     hueco de media columna. Repartidos, la ficha mide lo mismo que la foto
     y las dos piezas de la fila empiezan y terminan juntas. */
  .ledger{
    grid-column:1;padding-bottom:0;align-self:stretch;
    display:flex;flex-direction:column;justify-content:space-between
  }
  .pour__txt strong{font-size:1rem}
  .pour__txt span{font-size:.5625rem;letter-spacing:.12em}
  .nav__links{display:none}
  .burger{display:grid}
  .menu__grid{grid-template-columns:1fr;align-items:start;gap:2.5rem}
  .srv__grid{grid-template-columns:1fr}
  .srv__sticky{display:none}
  .srv__mobimg{display:block;aspect-ratio:16/10;border-radius:var(--radius);overflow:hidden;margin-bottom:1.25rem}
  .srv__mobimg img{width:100%;height:100%;object-fit:cover}
  /* Page heroes: el carril lateral y los paneles a sangre no caben */
  .ph__grid{grid-template-columns:1fr}
  .ph__panel{margin-right:0;aspect-ratio:16/10;order:-1;margin-bottom:2rem}
  .ph--object .ph__grid{grid-template-columns:1fr}
  .tiltcard__card{transform:rotate(-4deg)}
  .act__peek{display:none}
  .ph--rule .ph__in{grid-template-columns:1fr;align-items:start;gap:1rem}
  .ph__mark{font-size:clamp(4rem,18vw,7rem)}
  /* El índice de servicios deja de ser carril y pasa a scroller NO sticky:
     dos barras flotantes (nav + índice) era justo lo que había que quitar. */
  .srvpage{grid-template-columns:1fr;gap:0}
  .srvrail{display:none}
  .srvtabs{
    display:flex;gap:.5rem;overflow-x:auto;scrollbar-width:none;
    /* El swipe se queda dentro del carril: sin esto, al llegar al final el
       gesto se encadena al documento y arrastra la página entera.          */
    overscroll-behavior-x:contain;
    padding-block:1rem;margin-bottom:1.5rem;border-bottom:var(--hair) solid var(--line)
  }
  .srvtabs::-webkit-scrollbar{display:none}
  .srvtabs a{
    flex:none;padding:.55rem 1.1rem;border-radius:999px;border:var(--hair) solid var(--line);
    font-size:.75rem;font-weight:700;letter-spacing:.04em;white-space:nowrap;
    transition:background-color .35s var(--e-out),color .35s,border-color .35s
  }
  .srvtabs a.is-active{background:var(--navy);color:var(--cream);border-color:transparent}
  /* Foto a lo ancho y ficha debajo: en una columna estrecha el retrato se
     comía la pantalla antes de llegar al primer precio. La rejilla de cinco
     sigue en pie — solo cambia cuántas columnas ocupa cada pieza. */
  /* `relative`, no `static`: aquí se apaga el sticky, pero si la caja deja de
     estar posicionada las fotos (`.carta__fig`, absolutas con inset:0 y
     scale 1.07) se cuelgan del ancestro posicionado de más arriba, se van a
     ancho de pantalla y se salen 26 px por la derecha — el `overflow:hidden`
     de esta caja no las recorta porque su bloque contenedor ya no es ésta.  */
  .carta__media{grid-column:1/-1;position:relative;aspect-ratio:21/9}
  .carta__panel{grid-column:1/-1}
  .carta__nm{font-size:.8125rem}
  .carta__fr{display:none}
  .pcat__body{grid-template-columns:1fr}
  /* `relative` por lo mismo que .carta__media: apagar el sticky sin dejar de
     ser bloque contenedor, o el pie absoluto se cuelga de otro ancestro.    */
  .pcat__img{position:relative;aspect-ratio:16/9;order:-1;margin-bottom:1.5rem}
  .plist{columns:1}
  .split,.split--wide,.intro__head,.gc__grid{grid-template-columns:1fr}
  /* Apilado: el reproductor a lo ancho y el indice debajo, sin estrangular
     ninguna de las dos piezas. */
  .reel__stage{grid-template-columns:1fr;gap:clamp(1.75rem,4vw,2.5rem)}
  .vplay.vplay--arch{width:min(340px,72vw);justify-self:center}
  .reel__chapters{grid-template-rows:repeat(3,auto)}
  .reel__head .shead__aside{justify-items:start}
  /* Tres columnas: cifra, texto y el disco de la flecha al mismo alto que el
     titular. La foto baja a fila propia a lo ancho. */
  .man__row{grid-template-columns:auto minmax(0,1fr) auto;row-gap:1.25rem}
  .man__go{grid-column:3;grid-row:1;align-self:start;margin-top:.15rem}
  .man__img{grid-column:1/-1;grid-row:2;width:100%;aspect-ratio:16/9}
  .vplay--arch{max-height:min(70svh,620px)}
  .gc__stage{justify-items:start}
  .shead--split{grid-template-columns:1fr}
  /* En tablet los pilares se leen mejor apilados: tres columnas de 40ch en
     720px dejan una palabra por línea. El filete gira a horizontal para que
     la sección siga leyéndose como lista y no como tres bloques sueltos.  */
  .pillars{grid-template-columns:1fr;gap:0}
  .pillar{padding-left:0;padding-block:clamp(1.5rem,4vw,2.25rem)}
  .pillar + .pillar::before{
    left:0;right:0;top:0;bottom:auto;width:auto;height:var(--hair);
    transform:scaleX(0);transform-origin:left
  }
  .pillars.is-in .pillar + .pillar::before{transform:scaleX(1)}
  .cards{grid-template-columns:1fr}
  .stats{grid-template-columns:repeat(2,1fr)}
  .locs{grid-template-columns:1fr}
  /* en tablet la fila de tres pasa a dos: los locales arriba, el horario a
     todo el ancho debajo, para que ninguna tarjeta quede estrangulada     */
  .locs--3{grid-template-columns:repeat(2,1fr)}
  .locs--3 .hcard{grid-column:1/-1}
  .hcard__cta{display:flex;flex-wrap:wrap}
  .hcard__cta .btn{width:auto}
  .mapbox--wide .map{aspect-ratio:16/9}
  /* .g2/.g3 no tenían salto responsive: en móvil desbordaban el viewport */
  .g2{grid-template-columns:1fr}
  .g3{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:760px){
  /* Diez son 5 × 2 o 2 × 5, nunca otra cosa sin dejar una fila coja. En móvil
     toca 2 × 5: cinco columnas darían pastillas de 60px. Cae el número para
     que el nombre entre en un renglón. */
  .carta__index{grid-template-columns:repeat(2,minmax(0,1fr));gap:.45rem}
  .carta__i{padding:.55rem .85rem;gap:0}
  .carta__n{display:none}
  .carta__nm{font-size:.78125rem}

  /* El chip cuelga media pastilla por debajo de la foto: el hueco de la
     fila tiene que ser mayor que ese vuelo o se come la ficha. */
  .dip{row-gap:clamp(2rem,7vw,2.75rem)}
  .ledger__item{padding-block:.8rem}
  /* Móvil: la cápsula del mapa y la ficha de dirección dejan de flotar.
     Encima de un mapa de 4/3 taparían justo lo que hay que ver.        */
  .mapbox--wide{display:grid;gap:var(--media-pad)}
  .mapbox--wide .mapbox__tabs{position:static;width:100%;justify-content:stretch}
  .mapbox--wide .mtab{flex:1 1 0}
  .mapbox--wide .map{aspect-ratio:4/3;max-height:none}
  .mapbox__addr{position:static;max-width:none;border-radius:var(--radius-media)}
  /* La miniatura del capítulo no cabe al lado del título en pantalla corta */
  /* En pantalla corta la fila se compacta: sin boton circular y con la
     miniatura mas pequena, pero SIN esconderla: es lo que da masa. */
  .reel__ch{grid-template-columns:auto clamp(56px,15vw,74px) minmax(0,1fr);gap:.85rem;padding-inline:0}
  .reel__go,.reel__time{display:none}
  .ph--full{min-height:78svh}
  .ph__stats{gap:1.5rem 2rem}
  .act{grid-template-columns:1.9rem 1fr auto;gap:.9rem}
  .act__go{width:40px;height:40px}
  .ph__wide{height:clamp(260px,46vh,420px)}
  .pcat__head{grid-template-columns:1fr}
  .vplay.vplay--arch{width:min(300px,78vw)}
  .gcard{max-width:none}
  .g3{grid-template-columns:1fr}
  .locs--3{grid-template-columns:1fr}
  .mapbox--wide .map{aspect-ratio:4/3}
  .gifts{grid-template-columns:repeat(2,1fr)}
  .srv__prices{grid-template-columns:1fr}
  .carta__prices{columns:1}
  .form__row{grid-template-columns:1fr}
  .foot__cols{grid-template-columns:1fr;gap:2.25rem}
  .foot__status{flex-wrap:wrap;gap:.35rem .7rem}
  .foot__mark{margin-top:2.5rem}
  .foot__bar{justify-content:flex-start}

  .hero{min-height:92svh}
  .gal{grid-template-columns:repeat(6,1fr)}
  .sp-8,.sp-7,.sp-6,.sp-5,.sp-4{grid-column:span 6}
  .sp-3{grid-column:span 3}
  /* el bento se reordena a 6 columnas: sigue siendo asimétrico, sin huecos */
  .gal--bento{grid-template-columns:repeat(6,1fr);grid-auto-rows:clamp(38px,9vw,60px)}
  .gal--bento .gal__i:nth-child(1){grid-column:1/4;  grid-row:1/8}
  .gal--bento .gal__i:nth-child(2){grid-column:4/7;  grid-row:1/8}
  .gal--bento .gal__i:nth-child(3){grid-column:1/7;  grid-row:8/13}
  .gal--bento .gal__i:nth-child(4){grid-column:1/3;  grid-row:13/17}
  .gal--bento .gal__i:nth-child(5){grid-column:3/5;  grid-row:13/17}
  .gal--bento .gal__i:nth-child(6){grid-column:5/7;  grid-row:13/17}
  .gal--bento .gal__i:nth-child(7){grid-column:1/7;  grid-row:17/22}
  .gal--rows{grid-template-columns:repeat(6,1fr);grid-auto-rows:clamp(38px,9vw,60px)}
  .gal--rows .gal__i:nth-child(6n+1){grid-column:span 3;grid-row:span 7}
  .gal--rows .gal__i:nth-child(6n+2){grid-column:span 3;grid-row:span 7}
  .gal--rows .gal__i:nth-child(6n+3){grid-column:span 6;grid-row:span 5}
  .gal--rows .gal__i:nth-child(6n+4){grid-column:span 3;grid-row:span 5}
  .gal--rows .gal__i:nth-child(6n+5){grid-column:span 3;grid-row:span 5}
  .gal--rows .gal__i:nth-child(6n+6){grid-column:span 6;grid-row:span 6}
  /* en 6 columnas los tramos de 7 no caben: la pareja de arriba pasa a mitades
     y las tres de abajo a dos por fila, con la última a todo el ancho */
  .gal--about .gal__i:nth-child(1),
  .gal--about .gal__i:nth-child(2){grid-column:span 3;grid-row:span 7}
  .gal--about .gal__i:nth-child(n+3){grid-column:span 3;grid-row:span 5}
  .gal--about .gal__i:nth-child(5){grid-column:span 6;grid-row:span 6}
  .hrow{padding-inline:.6rem}
  .mtab{flex:1 1 100%}
  /* En un móvil las calles laterales del escritorio (76 px por lado) dejaban
     la foto en 223 px de ancho: más cromo que fotografía. Aquí las flechas
     bajan a una fila de controles con el contador en medio, y el cuadrado se
     queda con todo el ancho de la pantalla. */
  .lb{--lb-side:clamp(14px,4vw,24px);--lb-foot:112px}
  .lb__p,.lb__n{
    width:46px;top:auto;bottom:clamp(18px,5vw,26px);margin-block:0
  }
  .lb__p{left:50%;margin-left:-76px}
  .lb__n{right:50%;margin-right:-76px}
  .lb__c{bottom:calc(clamp(18px,5vw,26px) + 15px)}
  .menu__list a{font-size:clamp(1.75rem,9vw,3rem)}
}
@media (max-width:460px){
  .gifts{grid-template-columns:1fr}
  .stats{grid-template-columns:1fr}
  /* A 400px la pastilla entera mide más que la foto de la que cuelga: deja
     de ser una sola línea y se apoya en la esquina izquierda. */
  .pour{white-space:normal;padding-right:.9rem}
  .dip__pour{right:auto;left:clamp(.7rem,3vw,1rem);max-width:calc(100% - 1.4rem)}
  /* La ficha y la vertical a media columna dejan renglones de dos palabras:
     una sola columna y la foto cierra la composición. */
  .dip{grid-template-columns:1fr;row-gap:2.5rem}
  .dip__plate--tall{grid-column:1}
  .dip__plate--tall .dip__frame{aspect-ratio:5/6}
  /* En una sola columna la ficha ya no acompaña a ninguna foto: vuelve a
     ser una lista compacta. */
  .ledger{grid-column:1;display:block}
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  .r-fade{opacity:1 !important;transform:none !important}
  [data-split] .w{transform:none !important}
  .r-clip{clip-path:none !important}
  .figure img,.pcat__img img{transform:none !important}
  .hero__media,.band__media{position:absolute;inset:0}
}

/* ---------- Print ---------- */
@media print{
  .nav,.menu,.wa,.loader,.prog,.hero__pager{display:none !important}
  body{background:#fff}
}
