/* ==========================================================================
   ELENA HAIRLOVER — Web pública
   Reunido el 2026-09-21 a partir de: componentes-comunes.css, botones-premium.css
   ========================================================================== */

/* ─── COMPONENTES COMUNES ──────────────────────────────── */
.section-label {
  display: block;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.25em;
  color: var(--color-gold-text);
  text-align: center;
  margin-bottom: 12px;
}

.section-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2rem, 4vw, 3rem);
  text-align: center;
  color: var(--color-gold-text);
  margin-bottom: 8px;
}

.section-title.light {
  color: var(--color-gold-text);
}

.section-divider {
  width: 80px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-gold-warm), transparent);
  margin: 20px auto 0;
}


/* ─── BOTONES PREMIUM ──────────────────────────────────── */
.btn {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  padding: 16px 36px;
  border-radius: 0px;
  /* Bordes rectos para máxima elegancia */
  cursor: pointer;
  transition: var(--transition-luxury);
  position: relative;
  z-index: 1;
}

.btn--primary {
  background: var(--color-gold-warm);
  color: var(--color-dark-main);
  border: 1px solid var(--color-gold-warm);
}

.btn--primary:hover {
  background: transparent;
  color: var(--color-gold-text);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
}

.btn--secondary {
  background: transparent;
  color: var(--color-text-light);
  border: 1px solid var(--color-linea-fuerte);
}

.btn--secondary:hover {
  background: var(--color-text-light);
  color: var(--color-dark-main);
  border-color: var(--color-text-light);
}

.btn--gold-outline {
  background: transparent;
  color: var(--color-gold-text);
  border: 1px solid var(--color-gold-warm);
}

.btn--gold-outline:hover {
  background: var(--color-gold-warm);
  color: var(--color-dark-main);
}

/* La duración y el precio van dentro de `.service-item__meta`, una caja de
   verdad que pone css/carta.css (2026-10-01). */

/* ─── HERO (CARRUSEL FULL-BLEED) ───────────────────────── */

/* PORTADA: el escrito entre la cabecera y la foto (2026-09-25)
   ───────────────────────────────────────────────────────────
   Lo pidió el propietario: el nombre y la frase salen de encima de la foto y
   pasan a una franja propia, entre la cabecera y la foto, para que la foto se
   vea limpia. Los dos botones sí se quedan sobre la foto.

   La franja y la foto van dentro de `.portada`, que mide una pantalla: la
   franja ocupa lo que necesite el escrito y la foto se queda con el resto
   (`flex: 1`). Así no hay que adivinar cuánto mide el escrito, que cambia con
   el idioma y con el ancho. El hueco de arriba es para la cabecera, que flota
   (`position: fixed`) y no empuja a nadie.

   ⚠️ Esto es SOLO de Elegance by Stoica. En Elena el escrito sigue encima de
   la foto (el propietario lo pidió solo aquí). */
.portada {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding-top: 90px;   /* alto de la cabecera en reposo */
}

.portada__escrito {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 30px 24px 28px;
}

.portada__escrito .hero__title { margin-bottom: 16px; }
.portada__escrito .hero__subtitle { margin-bottom: 0; }

/* Las sombras negras del texto eran para leerlo encima de la foto. Aquí, sobre
   el fondo de la página, solo lo ensucian. */
.portada__escrito .hero__title-sub,
.portada__escrito .hero__subtitle { text-shadow: none; }

/* La foto: lo que queda de pantalla, y nunca menos de esto (móvil tumbado) */
.portada .hero {
  flex: 1;
  min-height: 320px;
}

/* Sin ninguna foto elegida en el panel: fuera la franja de la foto, y la
   portada se queda solo con el nombre y la frase (2026-10-01, lo eligió el
   propietario en vez de dejar el hueco del color del tema). La clase la pone
   initHeroCarousel() en js/main.js. */
.portada--sin-foto { min-height: 0; }
.portada--sin-foto .hero { display: none; }

/* En Lino, el oro de marca (y el «oro claro», casi blanco) no se leen sobre el
   beige: el escrito de la franja usa el oro de texto. Dentro de la foto no
   hace falta, porque el hero se queda oscuro en los dos temas. */
html[data-tema="lino"] .portada__escrito .hero__title-sub {
  color: var(--color-gold-text);
  border-color: var(--color-gold-text);
}

@media (max-width: 768px) {
  .portada { padding-top: 76px; }              /* la cabecera mide menos */
  .portada__escrito { padding: 22px 20px 20px; }
  .portada__escrito .hero__title { margin-bottom: 12px; }
}

/* En el móvil, los botones flotantes caen encima del escrito de la portada,
   así que este deja libre la franja derecha, igual que hacen la carta y sus
   pestañas. Son 104 px porque el botón «Reservar» es una píldora, no un
   círculo (2026-09-25). Solo se libra el modo «abajo», que los manda a la
   esquina de abajo y nunca llega al escrito. En el ordenador tampoco hace
   falta: el escrito no llega nunca hasta el borde. Con «barra abajo»
   (horizontal, 2026-10-01) tampoco: los botones van en la barra. */
@media (max-width: 767px) {
  html:not([data-botones="abajo"]):not([data-botones="horizontal"]) .portada__escrito { padding-right: 116px; }
}

/* ─── GALERÍA Y DECLARACIÓN DE MARCA [MIGRADO A TAILWIND] ─── */
.galeria {
  padding: var(--space-section) 0;
  /* Negro, como el resto de la página (tema oscuro fijo). Antes usaba el
     fondo claro --color-light-bg, un resto del modo claro. */
  background-color: var(--color-dark-main, var(--color-dark-main));
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.9);
  padding: 32px;
  cursor: zoom-out;
}

.lightbox.is-open {
  display: flex;
}

.lightbox__img {
  max-width: 92vw;
  max-height: 88vh;
  object-fit: contain;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
  cursor: default;
}

.lightbox__close {
  position: absolute;
  top: 18px;
  right: 24px;
  width: 48px;
  height: 48px;
  border: 1px solid var(--color-gold);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  color: var(--color-gold-light);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  transition: var(--transition-fast);
}

.lightbox__close:hover {
  background: var(--color-gold);
  color: var(--color-dark);
}

/* ── Pasar de una foto a otra sin salir del visor ── */
.lightbox__figura {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border: 1px solid var(--color-gold);
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.4);
  color: var(--color-gold-light);
  font-size: 1.9rem;
  line-height: 1;
  padding-bottom: 4px;
  cursor: pointer;
  transition: var(--transition-fast);
}

.lightbox__nav:hover {
  background: var(--color-gold);
  color: var(--color-dark);
}

.lightbox__nav--prev { left: 24px; }
.lightbox__nav--next { right: 24px; }

.lightbox__contador {
  position: absolute;
  top: 30px;
  left: 28px;
  color: var(--color-gold-light);
  font-size: 0.85rem;
  letter-spacing: 0.12em;
}

/* La categoría de la pareja que se está mirando, al lado del contador: con
   las pestañas, las flechas se mueven dentro de esa categoría y conviene
   decirlo (2026-09-25). */
.lightbox__categoria {
  position: absolute;
  top: 30px;
  left: 92px;
  padding: 2px 10px;
  border: 1px solid rgba(201, 168, 76, 0.55);
  border-radius: 2px;
  color: var(--color-gold-light);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.lightbox__categoria[hidden] { display: none; }
@media (max-width: 768px) {
  .lightbox__categoria { top: 26px; left: 76px; font-size: 0.6rem; }
}

/* .btn pone display y le ganaría al atributo hidden */
.lightbox__nav[hidden],
.lightbox__insta[hidden],
.galeria__mas-btn[hidden] {
  display: none;
}

.lightbox__insta {
  cursor: pointer;
}

@media (max-width: 768px) {
  /* En el móvil las flechas bajan al pie para no tapar la foto */
  .lightbox__nav {
    top: auto;
    bottom: 22px;
    transform: none;
  }
  .lightbox__nav--prev { left: calc(50% - 64px); }
  .lightbox__nav--next { right: calc(50% - 64px); }
  .lightbox__img { max-height: 72vh; }
  .lightbox__cmp { max-height: 62vh; }
}

/* ── «Ver más trabajos en Instagram», debajo de la galería ── */
.galeria__mas {
  margin-top: 40px;
  text-align: center;
}

.galeria__mas-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.galeria__mas-cuenta {
  margin-top: 10px;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
}

/* ─── ENTRADA SUAVE AL HACER SCROLL ──────────────────────
   Justo encima de esta regla había un `*/` suelto, sin su `/*` de
   apertura. Al tropezar con él, el navegador descartaba la regla que
   venía detrás: esta. Los 28 elementos con class="fade-in-up" se
   quedaban entonces con el `opacity: 0` que ponía animations.css y NO
   SE VEÍAN: la carta de precios entera, la galería, el bloque de
   contacto y los horarios. Comprobado en la web publicada el
   2026-09-21, donde 27 de esos 28 elementos estaban invisibles.

   Ahora la entrada la hace el propio CSS, sin depender de ningún
   JavaScript. En un navegador que no entienda `animation-timeline`,
   la animación no tiene duración, así que se queda al instante en su
   estado final (visible): nunca puede esconder nada. */
.fade-in-up {
  animation: fade-in-up linear both;
  animation-timeline: view();
  animation-range: entry 0% entry 50%;
}

@keyframes fade-in-up {
  from {
    opacity: 0;
    transform: translateY(30px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── Web en un solo idioma (panel → botón DUO / MONO) ──────────
   js/i18n-loader.js pone html[data-idiomas="mono"]: fuera los selectores
   ES/EN, en el ordenador y en el menú del móvil. */
html[data-idiomas="mono"] .lang-switch__btn,
html[data-idiomas="mono"] [role="group"]:has(> .lang-switch__btn),
html[data-idiomas="mono"] .idiomas-caja {
  display: none !important;
}

/* La carta de precios, del ancho de las pestañas y centrada, con sitio a la
   derecha para los botones flotantes (📞 💬 📍 Instagram), que están arriba a
   la derecha y tapaban los «Reservar cita». En el móvil no cambia. */
@media (min-width: 768px) {
  #public-services-list,
  #public-services-tabs {
    width: calc(100% - 160px);   /* deja 80 px libres a cada lado */
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
  }
  /* Las pestañas (2026-10-07), del mismo ancho que la carta de debajo
     (css/carta.css la deja en 980 px): si no, la fila llegaba hasta los
     botones flotantes y la última pestaña se metía debajo de ellos */
  #public-services-tabs { max-width: 980px; }
}

/* En la tableta (hasta 1279 px) la píldora «Reservar» sí llega a las fichas:
   mide 121 px y los 80 px libres no bastan. La carta se recuesta a la
   izquierda y deja 150 px por la derecha, como ya hace en el móvil. Desde
   1280 px no hace falta: ahí sobra sitio de sobra. */
@media (min-width: 768px) and (max-width: 1279px) {
  #public-services-list,
  #public-services-tabs {
    width: calc(100% - 150px);
    margin-left: 0;
    margin-right: auto;
  }
}

/* ── Carta de precios compacta en el móvil (2026-09-21) ────────────────
   Como en el ordenador, pero en dos líneas:
       Nombre del servicio (toda la línea)
       1 h              55 €   [RESERVAR CITA]
   La carta deja libre a la derecha la franja de los botones redondos
   fijos (📞 💬 📍 Instagram), que en el móvil miden 44 px: así no tapan
   nunca el precio ni el botón. Se usa #public-services-list para ganar a
   las reglas antiguas de «ficha en columna» (con !important) de
   index.html y web-responsivo.css. */
@media (max-width: 767px) {
  /* Botones redondos: 44 px, y su centro sigue justo bajo el menú ≡
     (32 px de margen de la cabecera + 22 px): right = 32 px */
  .floating-actions { right: 32px; gap: 12px; }
  .floating-actions .floating-actions__btn { width: 44px; height: 44px; }
  .floating-actions .floating-actions__btn svg { width: 20px; height: 20px; }

  /* La carta empieza a 16 px del borde y acaba 2 px antes de los BOTONES
     REDONDOS (2026-09-25, lo eligió el propietario en Stoica y las dos webs
     llevan los mismos retoques). Antes se apartaba también de la píldora
     «Reservar», que sobresale muchísimo hacia la izquierda, y la carta se
     quedaba en 223 de los 375 px de un móvil: los nombres se partían en dos y
     tres líneas. Ahora la píldora PASA POR ENCIMA de la carta a propósito
     —dicho por el propietario: así señala el servicio que la clienta está
     mirando— y solo se respeta la columna de botones redondos.
     46 px = 44 del botón redondo + 2 de aire.
     Con «barra abajo» (horizontal, 2026-10-01) no hace falta: la carta pasa
     por debajo de la barra y usa todo el ancho. */
  html:not([data-botones="horizontal"]) #public-services-list,
  html:not([data-botones="horizontal"]) #public-services-tabs,
  html:not([data-botones="horizontal"]) #transformaciones-tabs {
    margin-left: -8px;
    width: calc(100% - 46px);
  }
  #public-services-list { gap: 8px; }
}

/* La ficha compacta hasta 1023 px (2026-09-24) se quitó el 2026-10-01: la
   carta en tarjetas de css/carta.css vale para todos los anchos. */

/* ── Botones flotantes: arriba, centro o abajo (lo elige el panel) ──
   Ajustes → Datos del salón → «Botones de contacto flotantes». js/main.js
   pone <html data-botones="abajo|centro"> y aquí se bajan a la esquina
   inferior o a media pantalla («centro», 2026-09-24).
   En horizontal no cambian (en el móvil, siguen centrados bajo el ≡). */
html[data-botones="abajo"] .floating-actions {
  top: auto;
  bottom: 28px;
}
@media (max-width: 767px) {
  html[data-botones="abajo"] .floating-actions { bottom: 20px; }
}
/* «Acompaña al desplazamiento» (2026-09-25): la columna baja despacio según
   se recorre la página, de debajo de la cabecera hasta el pie. El sitio lo
   calcula js/main.js (`seguirElDesplazamiento`) y lo deja en --flotantes-y;
   si ese JS no llega a correr, se queda donde el modo «arriba». */
html[data-botones="scroll"] .floating-actions {
  top: var(--flotantes-y, 110px);
  bottom: auto;
  transform: none;
}

@media (max-width: 767px) {
  html[data-botones="scroll"] .floating-actions { top: var(--flotantes-y, 100px); }
}

html[data-botones="centro"] .floating-actions {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
}

/* ── Móvil: pestañas en rejilla y precio que no choca con el botón ──
   Pestañas: 2 columnas iguales; la última, si queda sola, a todo el ancho.
   Ficha:  Nombre del servicio (toda la línea)
           Desde 25 €            [RESERVAR CITA]
           45 min                (el botón ocupa las dos líneas) */
@media (max-width: 767px) {
  #public-services-tabs,
  #transformaciones-tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  #public-services-tabs .tab-btn,
  #transformaciones-tabs .tab-btn {
    width: 100%;
    min-height: 40px;
    padding: 8px 6px;
    letter-spacing: 0.06em;
    line-height: 1.25;
    white-space: normal;   /* si un nombre no cabe (catalán, rumano), pasa a 2 líneas */
  }
  #public-services-tabs .tab-btn:last-child:nth-child(odd),
  #transformaciones-tabs .tab-btn:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}


/* ── Con la agenda externa, la carta no lleva botón (2026-09-24) ───────
   Lo eligió el propietario: si las reservas se hacen en otra página
   (Timely, Fresha…), la carta de precios es solo informativa y los
   «Reservar cita» de cada servicio sobran — se reserva con el botón de la
   cabecera y con el de la sección de reservas, que sí llevan allí.
   El atributo lo pone el reescritor de enlaces del final de index.html
   (<html data-agenda="externa">), que ya sabe qué agenda está activa. */
/* «ACCESO CLIENTES» solo con la agenda PROPIA (2026-09-25, lo pidió el
   propietario). Las cuentas de clientas son para reservar en esta web y ver
   o anular sus citas; con la agenda externa no hay nada que hacer dentro y el
   botón solo confundía. Se esconde en la cabecera y en el menú del móvil.
   Va al revés que el botón de abajo: escondido mientras la página no sabe qué
   agenda hay (sin data-agenda), para que no asome y desaparezca al cargar. */
html:not([data-agenda="propia"]) #auth-nav-btn,
html:not([data-agenda="propia"]) #auth-mobile-btn { display: none; }
/* Quinto botón flotante, 📅 Reservar: solo con la agenda externa (2026-09-24).
   Escondido por defecto: mientras la página no sabe qué agenda hay, no sale. */
.floating-actions .floating-actions__btn--reservar { display: none; }
html[data-agenda="externa"] .floating-actions .floating-actions__btn--reservar { display: flex; }
/* Que destaque (2026-09-24): solo la píldora dorada con «Reservar» / «Book»,
   sin icono (lo pidió el propietario), y un latido dorado alrededor.
   El <a> sigue ocupando en la columna lo mismo que un botón redondo, así la
   columna no cambia de ancho y los otros cuatro no se mueven; él se vuelve
   invisible y la píldora (el <span>) sale hacia la izquierda desde su borde
   derecho. El latido es una sombra que se abre en ::after del <span>: la
   sombra de los botones lleva !important (css/web-responsivo.css) y una
   animación no puede ganarle. */
.floating-actions .floating-actions__btn--reservar {
  position: relative;
  background: transparent !important;
  box-shadow: none !important;
  border: none !important;
}
/* EL COLOR DEL BOTÓN RESERVAR (2026-09-25, lo eligió el propietario en el
   panel: Ajustes → Datos del salón → «Color del botón Reservar»).
   Cada color son tres fichas —relleno, letra y anillo que late— y cada uno
   tiene su versión para el tema oscuro y para el claro, igual que la cabecera
   (--cab-*) y el pie (--pie-*). El oro es el de siempre y vale en los dos.
   `--res-anillo` va en números sueltos porque el anillo le pone su propia
   transparencia. */
html {
  /* Hasta dónde se desvanece el botón en cada latido. Sale del deslizador
     «Cuánto se desvanece» del panel (Ajustes → Datos del salón): 0 → no se
     desvanece nada; 30 (el de serie) → baja a 0,73; 100 → baja a 0,10.

     ⚠ 30 NO es un número redondo: es el límite MEDIDO. Por encima, la palabra
     «Reservar» baja de 4,5:1 de contraste sobre la foto oscura de la portada en
     el momento más transparente (con 65 se quedó en 2,3:1). Se deja abierto
     hasta 100 a propósito, pero de fábrica va donde el texto se lee siempre. */
  --latido-suelo: calc(1 - 0.9 * var(--transp-i, 0.3));
  --res-relleno: linear-gradient(135deg, #E6C875 0%, #C9A84C 50%, #997A2A 100%);
  --res-relleno-hover: linear-gradient(135deg, #F2D89B 0%, #D8BA6A 50%, #A98A38 100%);
  --res-letra: #111111;
  --res-anillo: 201, 168, 76;
}
html[data-reservar="bronce"] {
  --res-relleno: linear-gradient(135deg, #C6B78F 0%, #AB9868 50%, #918362 100%);
  --res-relleno-hover: linear-gradient(135deg, #D6C9A6 0%, #BCA97C 50%, #A29374 100%);
  --res-letra: #17150F;
  --res-anillo: 160, 140, 94;
}
html[data-reservar="terracota"] {
  --res-relleno: linear-gradient(135deg, #DCAD92 0%, #C09479 50%, #A27B63 100%);
  --res-relleno-hover: linear-gradient(135deg, #E8BFA6 0%, #CFA78D 50%, #B48D75 100%);
  --res-letra: #1E1209;
  --res-anillo: 184, 126, 92;
}
html[data-reservar="oliva"] {
  --res-relleno: linear-gradient(135deg, #C3CBAF 0%, #A8B38F 50%, #86926C 100%);
  --res-relleno-hover: linear-gradient(135deg, #D2D9C2 0%, #B8C2A2 50%, #97A37C 100%);
  --res-letra: #161A10;
  --res-anillo: 168, 179, 143;
}
/* En el tema claro, el bronce y la terracota se oscurecen: sobre el beige, las
   versiones claras se perdían. La letra pasa a ser clara.
   Los degradados son cortos a propósito: medido con la regla del contraste,
   las esquinas del botón tienen que leerse igual que el centro (4,5:1 mínimo),
   y un degradado largo dejaba la esquina oscura por debajo. */
html[data-tema="lino"][data-reservar="bronce"] {
  --res-relleno: linear-gradient(135deg, #796B48 0%, #675A3D 50%, #514632 100%);
  --res-relleno-hover: linear-gradient(135deg, #8A7A53 0%, #776948 50%, #5F533C 100%);
  --res-letra: #F7F4EC;
  --res-anillo: 111, 96, 64;
}
html[data-tema="lino"][data-reservar="terracota"] {
  --res-relleno: linear-gradient(135deg, #8A634C 0%, #74523E 50%, #5E4231 100%);
  --res-relleno-hover: linear-gradient(135deg, #9B7159 0%, #855F49 50%, #6E4E3B 100%);
  --res-letra: #FBF3EE;
  --res-anillo: 160, 106, 76;
}

.floating-actions__texto {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 22px;
  border-radius: 999px;
  background: var(--res-relleno);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45), inset 0 1px 1px rgba(255, 255, 255, 0.6);
  color: var(--res-letra);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}
/* El latido del botón flotante: su propia animación, porque usa el color
   elegido y la FUERZA que se ajusta en el panel (--latido-i, de 0 a 1). La
   fuerza cambia a la vez lo grande y lo marcado del anillo. */
.floating-actions__texto::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  animation: latido-reservar 3s ease-out infinite;
}
/* EL BOTÓN SE LLENA DE COLOR Y LUEGO SE ABRE EL ANILLO (2026-09-25)
   ───────────────────────────────────────────────────
   Lo pidió el propietario en Stoica y las dos webs llevan lo mismo: el anillo
   se abría de golpe alrededor de un botón ya pintado y pasaba desapercibido.
   Ahora el botón entra medio transparente, se llena hasta el 100 % y SOLO
   ENTONCES se abre el anillo. Pasa en CADA latido, cada 3 segundos.

   El orden es: se llena (0 a 30 % del ciclo, 900 ms), PAUSA de 300 ms con el
   botón ya lleno, y a partir del 40 % se abre el anillo. La pausa la pidió el
   propietario: sin ella el anillo parecía la continuación del relleno.

   Las dos cosas van en animaciones del MISMO tiempo (3 s) para que no se
   puedan separar: dos duraciones distintas acaban desfasadas.

   Se anima la opacidad del propio botón, no una capa aparte: así no hay que
   pelear con los `!important` que le pintan el degradado ni mover sus sombras. */
@keyframes entrada-reservar {
  0%   { opacity: var(--latido-suelo, 0.73); }
  30%  { opacity: 1; }
  100% { opacity: 1; }
}
@keyframes latido-reservar {
  0%, 40% { box-shadow: 0 0 0 0 rgba(var(--res-anillo), calc(0.7 * var(--latido-i, 0.7))); }
  85%     { box-shadow: 0 0 0 calc(16px * var(--latido-i, 0.7)) rgba(var(--res-anillo), 0); }
  100%    { box-shadow: 0 0 0 calc(16px * var(--latido-i, 0.7)) rgba(var(--res-anillo), 0); }
}
.floating-actions__texto,
.boton-latido {
  animation: entrada-reservar 3s ease-out infinite;
}
/* Apagado desde el panel */
html[data-latido="no"] .floating-actions__texto::after,
html[data-latido="no"] .floating-actions__texto,
html[data-latido="no"] .boton-latido { animation: none; }

/* TODOS LOS BOTONES DE RESERVAR VAN DEL COLOR ELEGIDO (2026-09-25)
   ─────────────────────────────────────────────────────────────────
   Al principio el color era solo para el botón flotante; el propietario pidió
   que valiera para todos: el de la cabecera, los de la carta, el del visor y
   el del menú del móvil. Todos llevan `data-booking-link` (se lo pone el
   reescritor de enlaces del final de index.html) o la clase del botón de la
   carta, así que con eso basta para cogerlos.
   El `!important` es obligatorio: css/web-responsivo.css les pinta el
   degradado dorado con !important, y sin esto ganaría él. */
/* Y la letra, encima de todo: los botones de reservar llevan clases de
   Tailwind que fijan el color (`text-dark-main`, `text-[#1A1A1A]`), y en el
   tema claro css/base.css las reescribe. Esto tiene que ganarles, o en Lino
   el botón sale con la letra oscura sobre un relleno oscuro. */
html a[data-booking-link].text-dark-main,
html a[data-booking-link].text-\[\#1A1A1A\],
html a[data-booking-link].text-white,
html #public-services-list .service-item__btn.text-dark-main {
  color: var(--res-letra) !important;
}

/* El `html` de delante no es decorativo: css/web-responsivo.css pinta estos
   mismos botones de dorado con !important y, a igual peso, gana el que se
   carga después. Con `html` delante, este pesa un poco más y manda. */
html .header a[data-booking-link],
html .cabecera a[data-booking-link],
html a[data-booking-link],
html #public-services-list .service-item__btn,
html .lightbox__reservar {
  background: var(--res-relleno) !important;
  background-image: var(--res-relleno) !important;
  color: var(--res-letra) !important;
  border-color: transparent !important;
}
/* El latido de los botones de reservar que no son el flotante */
.boton-latido::after {
  animation: latido-reservar 3s ease-out infinite;
}
html[data-latido="no"] .boton-latido::after { animation: none; }

/* El mismo latido en los dos «Reservar» principales: el de la cabecera y el
   grande de la portada (lo pidió el propietario, 2026-09-24). */
.boton-latido { position: relative; }
.boton-latido::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .boton-latido::after { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  .floating-actions__texto::after { animation: none; }
}

html[data-agenda="externa"] #public-services-list .service-item__btn {
  display: none !important;
}

/* ═══════════════════════════════════════════════════════════════
   GALERÍA — cuatro estilos, elegidos en el panel (2026-09-24)
   ═══════════════════════════════════════════════════════════════
   La rejilla lleva data-estilo="cuadricula|mural|tira" (lo pone js/main.js
   con lo guardado en settings/gallery.estilo). Lo común primero; luego
   cada estilo. Sin clases de Tailwind: así no hay que regenerarlo. */
.galeria__grid { margin-top: 40px; }

.galeria__item {
  position: relative;
  overflow: hidden;
  margin: 0;
  cursor: pointer;
  background-color: var(--color-dark-card, var(--color-dark-card));
  outline: none;
}
.galeria__item:focus-visible { box-shadow: 0 0 0 2px var(--color-gold-warm); }

.galeria__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: center;
}

/* Fotos «vivas»: un paseo lentísimo de lado a lado, solo mientras están en
   pantalla (la clase is-viva la pone y quita un IntersectionObserver).

   EL MOVIMIENTO ES LATERAL (2026-09-25, lo pidió el propietario en Stoica y las
   dos webs llevan lo mismo). Antes era un zoom de 1 a 1,07, que tenía dos
   problemas: la foto «respiraba», y sobre todo rompía al observador (ver
   abajo). Ahora la foto se acerca muy despacio Y a la vez se mueve un poco.

   LA TIRA SE MUEVE EL DOBLE (3 % a cada lado en vez de 1,5 %): ahí las fotos
   son grandes y de una en una, y el movimiento se tenía que notar más. Va en
   24 s en vez de 20 para que, con el doble de recorrido, no acabe yendo al
   doble de rápido.

   ⚠ LAS CUENTAS DEL COLCHÓN, que es lo que impide que asome una franja vacía:
   al agrandar la foto un X %, le sobra X/2 por cada borde, y pasearla un P %
   gasta P·escala. Lo que queda es el colchón.
     · Base, en su momento más pequeño (1,08) y P = 1,5 % → colchón 2,4 %.
     · Tira, en su momento más pequeño (1,12) y P = 3 % → colchón 2,6 %.
   Al ser porcentajes, el colchón nunca se vuelve negativo por pequeña que sea
   la tarjeta. Hay que rehacer la cuenta si se toca cualquiera de los dos
   números. La ficha recorta igualmente (`overflow: hidden`), pero el recorte
   no inventa foto donde no la hay.

   ⚠ EL BUCLE DEL PARPADEO (arreglado el 2026-09-25): el observador vigilaba
   LA PROPIA FOTO, y la animación la movía. Al moverse cambiaba si «estaba en
   pantalla», se le quitaba la clase, volvía a su sitio, volvía a entrar… Las
   fotos PARES eran las que parpadeaban, porque `alternate-reverse` las arranca
   ya desplazadas y caen en el bucle desde el primer fotograma. Ahora el
   observador vigila la FICHA, que no se mueve nunca, y la clase va en ella. */
@keyframes galeria-viva {
  from { transform: scale(1.08) translateX(-1.5%); }
  to   { transform: scale(1.14) translateX(1.5%); }
}
@keyframes galeria-viva-tira {
  from { transform: scale(1.12) translateX(-3%); }
  to   { transform: scale(1.18) translateX(3%); }
}
.galeria__item.is-viva .galeria__img { animation: galeria-viva 20s ease-in-out infinite alternate; }
.galeria__grid[data-estilo="tira"] .galeria__item.is-viva .galeria__img {
  animation: galeria-viva-tira 24s ease-in-out infinite alternate;
}
/* Las pares empiezan por el otro lado, para que no se paseen todas a la vez. */
.galeria__item:nth-child(even).is-viva .galeria__img { animation-direction: alternate-reverse; }
@media (prefers-reduced-motion: reduce) {
  .galeria__item.is-viva .galeria__img { animation: none; }
}

/* La lupa arriba a la derecha y el texto abajo: al pasar el ratón, con el
   teclado o, en pantallas táctiles, tras el primer toque (is-tocada). */
.galeria__item::after {
  content: "⌕";
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 4;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--color-text-light);
  opacity: 0;
  transition: var(--transition-fast);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.galeria__overlay {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  margin: 0;
  padding: 36px 16px 14px;
  background: linear-gradient(to top, rgba(17, 17, 17, 0.88), rgba(17, 17, 17, 0));
  opacity: 0;
  transform: translateY(8px);
  transition: var(--transition-luxury);
  pointer-events: none;
}
.galeria__overlay-desc {
  margin: 0;
  color: var(--color-gold-light, var(--color-gold-text));
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.4;
}
.galeria__item:hover::after,
.galeria__item:focus-visible::after,
.galeria__item.is-tocada::after { opacity: 0.9; }
.galeria__item:hover .galeria__overlay,
.galeria__item:focus-visible .galeria__overlay,
.galeria__item.is-tocada .galeria__overlay { opacity: 1; transform: none; }

/* Estados: cargando, vacío y error. */
.galeria__grid--estado { display: block !important; columns: auto !important; }
.galeria__placeholder {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 160px;
  background: var(--color-superficie-suave);
  border: 1px dashed rgba(201, 168, 76, 0.25);
  padding: 40px;
  text-align: center;
}
.galeria__placeholder p {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* ── 1. CUADRÍCULA (la de serie): todas iguales, tres por fila, como un
   perfil de Instagram. Es la ordenada.
   Aquí había antes un «mosaico» tipo Pinterest (column-count, sin recortar),
   que era el de fábrica; se quitó el 2026-09-25 porque no le gustaba al
   propietario, y la cuadrícula ocupa su sitio. ── */
.galeria__grid[data-estilo="cuadricula"] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.galeria__grid[data-estilo="cuadricula"] .galeria__item { aspect-ratio: 1 / 1; }

/* ── 2. MURAL: cuadrícula con una de cada cinco al doble ── */
.galeria__grid[data-estilo="mural"] {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  grid-auto-flow: dense;
  gap: 6px;
}
.galeria__grid[data-estilo="mural"] .galeria__item { aspect-ratio: 1 / 1; }
.galeria__grid[data-estilo="mural"] .galeria__item.featured {
  grid-column: span 2;
  grid-row: span 2;
}

/* ── 3. TIRA: una fila que se desliza, con parada foto a foto ── */
.galeria__grid[data-estilo="tira"] {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.galeria__grid[data-estilo="tira"]::-webkit-scrollbar { display: none; }
.galeria__grid[data-estilo="tira"] .galeria__item {
  flex: 0 0 min(78vw, 400px);
  aspect-ratio: 4 / 5;
  scroll-snap-align: start;
}
.galeria__tira-nav {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin-top: 18px;
}
.galeria__tira-btn {
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-gold-warm);
  border-radius: 50%;
  background: transparent;
  color: var(--color-gold-text);
  font-size: 1.6rem;
  line-height: 1;
  padding-bottom: 4px;
  cursor: pointer;
  transition: var(--transition-fast);
}
.galeria__tira-btn:hover { background: var(--color-gold-warm); color: var(--color-on-gold, #111); }

@media (max-width: 1023px) {
  .galeria__grid[data-estilo="mural"] { grid-template-columns: repeat(2, 1fr); }
  .galeria__grid[data-estilo="cuadricula"] { gap: 3px; }
}

/* ═══════════════════════════════════════════════════════════════
   TRANSFORMACIONES — antes y después (2026-09-24)
   ═══════════════════════════════════════════════════════════════ */
.transformaciones {
  padding: var(--space-section) 0;
  background-color: var(--color-dark-bg, var(--color-dark-deep));
}
.transformaciones__ayuda {
  text-align: center;
  margin: 18px 0 0;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
}
.transf__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 36px;
}
.transf__item {
  position: relative;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  cursor: pointer;
  background: var(--color-dark-card, var(--color-dark-card));
  border: 1px solid rgba(201, 168, 76, 0.18);
  outline: none;
}
.transf__item:focus-visible { box-shadow: 0 0 0 2px var(--color-gold-warm); }
.transf__item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* El antes va encima, invisible; al pasar por encima (o tras el primer
   toque) se funde con el después. */
.transf__antes {
  transform-origin: center;
  opacity: 0;
  transition: opacity 0.55s ease;
}
.transf__item:hover .transf__antes,
.transf__item:focus-visible .transf__antes,
.transf__item.is-tocada .transf__antes { opacity: 1; }
.transf__etiqueta {
  position: absolute;
  left: 12px;
  top: 12px;
  z-index: 3;
  padding: 5px 10px;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-gold-light, var(--color-gold-text));
  background: rgba(17, 17, 17, 0.78);
  border: 1px solid rgba(201, 168, 76, 0.55);
  border-radius: 2px;
}
.transf__pie {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  margin: 0;
  padding: 40px 16px 14px;
  background: linear-gradient(to top, rgba(17, 17, 17, 0.9), rgba(17, 17, 17, 0));
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.transf__pie strong {
  color: var(--color-text-light);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.3;
}
.transf__pie span {
  color: var(--color-gold-text);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
/* ═══════════════════════════════════════════════════════════════
   LAS CUATRO FORMAS DE VER UNA PAREJA (2026-09-25)
   ═══════════════════════════════════════════════════════════════
   El propietario dijo que no se entendía: las fichas parecían fotos
   normales y, quien no las tocaba, no se enteraba de que se podían
   comparar. Ahora la administradora elige en el panel entre cuatro
   formas (Fotos → Transformaciones), y de serie se ven PARTIDAS: media
   foto de antes y media de después, con una línea dorada en medio.

   Todo cuelga de `data-estilo` en la rejilla, igual que la galería.
   `--corte` dice por dónde va la línea (50 % de serie). */
.transf__grid { --corte: 50%; }
.transf__item { --corte: 50%; }

/* La línea dorada que separa las dos mitades */
.transf__linea {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--corte);
  width: 2px;
  margin-left: -1px;
  z-index: 3;
  background: var(--color-gold-warm);
  box-shadow: 0 0 10px rgba(var(--color-gold-warm-rgb), 0.7);
  display: none;
  pointer-events: none;
}

/* Las dos etiquetas, una en cada mitad. La de «sola» es la de antes, que
   solo se usa en el estilo fundido. */
.transf__etiqueta--antes,
.transf__etiqueta--despues { display: none; }
.transf__etiqueta--despues { left: auto; right: 12px; }

/* ── 1. PARTIDO (el de serie) ── */
.transf__grid[data-estilo="partido"] .transf__antes,
.transf__grid[data-estilo="cortina"] .transf__antes,
.transf__grid[data-estilo="deslizador"] .transf__antes {
  opacity: 1;
  clip-path: inset(0 calc(100% - var(--corte)) 0 0);
  transition: none;
}
.transf__grid[data-estilo="partido"] .transf__linea,
.transf__grid[data-estilo="cortina"] .transf__linea,
.transf__grid[data-estilo="deslizador"] .transf__linea { display: block; }

.transf__grid[data-estilo="partido"] .transf__etiqueta--sola,
.transf__grid[data-estilo="cortina"] .transf__etiqueta--sola,
.transf__grid[data-estilo="deslizador"] .transf__etiqueta--sola { display: none; }
.transf__grid[data-estilo="partido"] .transf__etiqueta--antes,
.transf__grid[data-estilo="partido"] .transf__etiqueta--despues,
.transf__grid[data-estilo="cortina"] .transf__etiqueta--antes,
.transf__grid[data-estilo="cortina"] .transf__etiqueta--despues,
.transf__grid[data-estilo="deslizador"] .transf__etiqueta--antes,
.transf__grid[data-estilo="deslizador"] .transf__etiqueta--despues { display: block; }

/* ── 2. CORTINA: la línea va y viene sola ──
   Solo se mueve la ficha que se ve en pantalla (`is-viva`, lo pone un
   IntersectionObserver en js/main.js), para no tener siete animaciones
   corriendo a la vez. La foto y la línea llevan la MISMA animación y los
   mismos tiempos, así nunca se separan. */
/* El recorrido va casi de lado a lado, del 2 % al 98 % (2026-09-25, lo pidió el
   propietario en Stoica y las dos webs llevan los mismos retoques: con el
   12-88 % de antes se veía poco de cada foto). No llega al 0 ni al 100 para que
   la línea dorada no se coma el borde de la ficha. */
@keyframes transf-cortina-foto {
  0%, 8%    { clip-path: inset(0 98% 0 0); }
  50%       { clip-path: inset(0 2% 0 0); }
  92%, 100% { clip-path: inset(0 98% 0 0); }
}
@keyframes transf-cortina-linea {
  0%, 8%    { left: 2%; }
  50%       { left: 98%; }
  92%, 100% { left: 2%; }
}
.transf__grid[data-estilo="cortina"] .transf__item .transf__antes {
  animation: transf-cortina-foto 7s ease-in-out infinite;
}
.transf__grid[data-estilo="cortina"] .transf__item .transf__linea {
  animation: transf-cortina-linea 7s ease-in-out infinite;
}
/* Lo que está fuera de la pantalla se para. Se marca al revés a propósito:
   si el navegador no avisa (o tarda), todas se mueven, que es lo correcto;
   con la marca al derecho, un fallo las dejaría todas quietas. */
.transf__grid[data-estilo="cortina"] .transf__item.is-quieta .transf__antes,
.transf__grid[data-estilo="cortina"] .transf__item.is-quieta .transf__linea {
  animation-play-state: paused;
}
/* Al pasar el ratón se para, para poder mirar con calma */
.transf__grid[data-estilo="cortina"] .transf__item:hover .transf__antes,
.transf__grid[data-estilo="cortina"] .transf__item:hover .transf__linea {
  animation-play-state: paused;
}

/* ── 3. DESLIZADOR: el asa se arrastra en la propia ficha ──
   El corte lo mueve js/main.js con el dedo o el ratón. `touch-action: none`
   es lo que impide que la página se desplace mientras se arrastra. */
.transf__grid[data-estilo="deslizador"] .transf__item {
  touch-action: none;
  cursor: ew-resize;
}
.transf__grid[data-estilo="deslizador"] .transf__linea::after {
  content: "9 A";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: var(--gold-grad-primary);
  color: var(--color-on-gold);
  font-size: 0.8rem;
  letter-spacing: 1px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}

/* ── 4. FUNDIDO: el de antes, sin tocar nada ── */

@media (prefers-reduced-motion: reduce) {
  .transf__grid[data-estilo="cortina"] .transf__item .transf__antes,
  .transf__grid[data-estilo="cortina"] .transf__item .transf__linea {
    animation: none;
  }
}

@media (max-width: 1023px) { .transf__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .transf__grid { grid-template-columns: 1fr; } }

/* ── Pestañas de categoría: la carta y las transformaciones (2026-10-07,
   de Stoica) ──
   Hasta ese día Hairlover no tenía este aspecto: la carta no llevaba
   pestañas y las de transformaciones salían como botones del navegador.
   El [hidden] lleva !important porque en el móvil la fila es una rejilla
   con su #id (más arriba), que pesa más que esta clase. */
.servicios__tabs-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin: 8px 0 36px;
}
.servicios__tabs-nav[hidden] { display: none !important; }
.tab-btn {
  background: transparent;
  border: 1px solid var(--color-linea-suave);
  border-radius: 6px;
  color: var(--color-text-suave);
  cursor: pointer;
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  padding: 12px 22px;
  text-transform: uppercase;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.tab-btn:hover {
  background: rgba(201, 168, 76, 0.1);
  border-color: rgba(201, 168, 76, 0.4);
  color: var(--color-text-light);
}
.tab-btn.active {
  background: var(--color-gold-warm);
  border-color: var(--color-gold-warm);
  color: var(--color-dark-main, #111111);
  font-weight: 600;
}
.tab-btn:focus-visible { outline: 2px solid var(--color-gold-light); outline-offset: 2px; }

/* En el móvil, más compactas, para que la carta se vea sin bajar tanto */
@media (max-width: 767px) {
  .servicios__tabs-nav { gap: 8px; margin-bottom: 24px; }
  .tab-btn { font-size: 0.62rem; letter-spacing: 0.1em; padding: 9px 12px; }
}

/* Las pestañas de categoría, a la misma distancia que la ayuda */
.transformaciones__tabs { margin-top: 22px; }

/* Pestañas que laten (de Stoica, 2026-10-06; allí las pidió el propietario:
   quietas, las clientas no veían que había más categorías). Las NO
   elegidas, de una en una y solo las que se ven, cada 1,5 s: lo lleva
   js/main.js (latirPestanas), que pone y quita is-latiendo.
   Un aro dorado que se abre y se apaga, el borde en dorado y la pestaña un
   poco más grande. La letra no cambia de color (el contraste queda como
   estaba) y, al ser transform, las vecinas no se mueven de sitio. */
@keyframes latido-pestana {
  0%   { transform: scale(1);    border-color: var(--color-gold-warm); box-shadow: 0 0 0 0 rgba(201, 168, 76, 0.55); }
  35%  { transform: scale(1.05); background-color: rgba(201, 168, 76, 0.12); }
  100% { transform: scale(1);    box-shadow: 0 0 0 10px rgba(201, 168, 76, 0); }
}
.tab-btn.is-latiendo { animation: latido-pestana 0.9s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .tab-btn.is-latiendo { animation: none; }
}

/* ── El comparador (dentro del visor) ──
   Dos fotos superpuestas; la de antes se recorta hasta la línea --x. */
.cmp {
  position: relative;
  width: min(92vw, 1100px);
  max-height: 72vh;
  aspect-ratio: 4 / 3;   /* provisional: js/main.js pone la forma real de la foto */
  overflow: hidden;
  user-select: none;
  touch-action: none;
  background: #000;
  border: 1px solid rgba(201, 168, 76, 0.45);
  --x: 50%;
}
.cmp img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
/* La cortina recorta el envoltorio, no la foto: si la foto de antes lleva
   reajuste (movida, acercada o girada), la línea sigue recta junto al
   tirador. El fondo tapa el hueco que deja una foto alejada. */
.cmp__antes-marco {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--color-dark-card, #1a1a1a);
  clip-path: inset(0 calc(100% - var(--x)) 0 0);
  pointer-events: none;
}
.cmp__antes { transform-origin: center; }
.cmp__tirador {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--x);
  width: 2px;
  margin-left: -1px;
  background: var(--color-gold-warm, #C9A84C);
  box-shadow: 0 0 12px rgba(230, 200, 117, 0.8);
  cursor: ew-resize;
  outline: none;
}
.cmp__tirador::after {
  content: "‹ ›";
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 48px; height: 48px;
  border-radius: 50%;
  background: var(--gold-grad-primary, linear-gradient(135deg, #E6C875, #C9A84C));
  color: var(--color-on-gold, #111);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 700;
  letter-spacing: 2px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.6);
}
.cmp__tirador:focus-visible::after { box-shadow: 0 0 0 3px #fff, 0 6px 20px rgba(0, 0, 0, 0.6); }
.cmp__etiqueta {
  position: absolute;
  top: 14px;
  z-index: 2;
  padding: 5px 12px;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-gold-light, var(--color-gold-text));
  background: rgba(17, 17, 17, 0.78);
  border: 1px solid rgba(201, 168, 76, 0.55);
  border-radius: 2px;
  pointer-events: none;
}
.cmp__etiqueta--antes { left: 14px; }
.cmp__etiqueta--despues { right: 14px; }

.lightbox__pie {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
  max-width: 92vw;
}
.lightbox__pie[hidden], .lightbox__img[hidden], .lightbox__cmp[hidden], .lightbox__reservar[hidden] { display: none; }
.lightbox__img { cursor: pointer; }   /* un toque o clic pasa a la siguiente */
.lightbox__titulo { color: var(--color-text-light); font-size: 1.05rem; font-weight: 600; }
.lightbox__detalle { color: var(--color-gold-text); font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase; }
.lightbox__reservar { margin-top: 6px; }
/* Con la agenda externa, la reserva no se hace en esta web: sin botón. */
html[data-agenda="externa"] .lightbox__reservar { display: none !important; }

/* ═══════════════════════════════════════════════════════════════
   PORTADA: CÓMO PASAN LAS FOTOS (2026-09-24)
   ═══════════════════════════════════════════════════════════════
   El panel elige el estilo (data-transicion en .hero__carousel) y el tiempo
   entre fotos (--hero-intervalo). js/main.js marca la foto que se va con
   .is-saliendo y la dirección con data-direccion. «Fundido» es el de
   siempre (reglas de .hero__slide en index.html). */
.hero__carousel { --hero-intervalo: 15s; }
/* Las fotos ordenan su z-index entre ellas sin pasar por encima del velo oscuro. */
.hero__slides { isolation: isolate; }

/* Zoom suave: la foto se acerca despacio mientras está en pantalla. */
.hero__carousel[data-transicion="zoom"] .hero__slide-img {
  transform: scale(1);
  transition: transform 0s linear 1.1s;   /* vuelve a su sitio ya invisible */
}
.hero__carousel.hero--listo[data-transicion="zoom"] .hero__slide.is-active .hero__slide-img {
  transform: scale(1.12);
  transition: transform calc(var(--hero-intervalo) + 1.5s) linear;
}

/* Deslizar: la nueva entra y empuja a la anterior. */
.hero__carousel[data-transicion="deslizar"] .hero__slide {
  opacity: 1;
  transform: translateX(100%);
  transition: transform 900ms cubic-bezier(0.65, 0, 0.35, 1);
}
.hero__carousel[data-transicion="deslizar"][data-direccion="atras"] .hero__slide { transform: translateX(-100%); }
.hero__carousel[data-transicion="deslizar"] .hero__slide.is-active { transform: translateX(0); }
.hero__carousel[data-transicion="deslizar"] .hero__slide.is-saliendo { transform: translateX(-100%); }
.hero__carousel[data-transicion="deslizar"][data-direccion="atras"] .hero__slide.is-saliendo { transform: translateX(100%); }
.hero__carousel[data-transicion="deslizar"] .hero__slide:not(.is-active):not(.is-saliendo) { transition: none; }

/* Cortina dorada: una línea de oro barre la pantalla y descubre la nueva. */
.hero__carousel[data-transicion="cortina"] .hero__slide {
  opacity: 1;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1100ms cubic-bezier(0.65, 0, 0.35, 1);
}
.hero__carousel[data-transicion="cortina"][data-direccion="atras"] .hero__slide { clip-path: inset(0 0 0 100%); }
.hero__carousel[data-transicion="cortina"] .hero__slide.is-active { clip-path: inset(0 0 0 0); z-index: 3; }
.hero__carousel[data-transicion="cortina"] .hero__slide.is-saliendo { clip-path: inset(0 0 0 0); z-index: 2; transition: none; }
.hero__carousel[data-transicion="cortina"] .hero__slide:not(.is-active):not(.is-saliendo) { transition: none; }
.hero__carousel.hero--en-marcha[data-transicion="cortina"] .hero__slide.is-active::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -3px;
  width: 3px;
  z-index: 3;
  background: linear-gradient(180deg, transparent, #E6C875 18%, #C9A84C 82%, transparent);
  box-shadow: 0 0 18px 4px rgba(230, 200, 117, 0.55);
  pointer-events: none;
  animation: cortina-linea 1100ms cubic-bezier(0.65, 0, 0.35, 1) forwards;
}
.hero__carousel.hero--en-marcha[data-transicion="cortina"][data-direccion="atras"] .hero__slide.is-active::after {
  animation-name: cortina-linea-atras;
}
@keyframes cortina-linea {
  0%   { left: -3px; opacity: 1; }
  85%  { opacity: 1; }
  100% { left: calc(100% - 3px); opacity: 0; }
}
@keyframes cortina-linea-atras {
  0%   { left: 100%; opacity: 1; }
  85%  { opacity: 1; }
  100% { left: 0; opacity: 0; }
}

/* Desenfoque: la que se va se difumina; la nueva llega nítida. */
.hero__carousel[data-transicion="desenfoque"] .hero__slide {
  filter: blur(16px);
  transform: scale(1.06);   /* tapa el borde transparente que deja el desenfoque */
  transition: opacity 1200ms ease, filter 1200ms ease, transform 1200ms ease;
}
.hero__carousel[data-transicion="desenfoque"] .hero__slide.is-active { filter: blur(0); transform: scale(1); }

/* Con «reducir movimiento», solo fundido. */
@media (prefers-reduced-motion: reduce) {
  .hero__carousel[data-transicion] .hero__slide,
  .hero__carousel[data-transicion] .hero__slide-img {
    transform: none !important;
    clip-path: none !important;
    filter: none !important;
  }
  .hero__carousel[data-transicion] .hero__slide::after { display: none !important; }
}

/* El botón flotante «Reservar», IGUAL EN TODAS LAS PANTALLAS (2026-09-25, lo
   pidió el propietario al verlo en el móvil): la píldora con el texto, también
   en el móvil. Por la mañana ahí era un círculo con un calendario, porque la
   píldora se metía encima de las fichas de la carta; ahora la píldora es un
   poco más corta en el móvil y la carta le deja sitio (la franja libre de la
   derecha pasa de 52 a 104 px), así que ya no tapa nada.
   El calendario se queda en el marcado, escondido: es el respaldo por si
   algún día vuelve a hacer falta el círculo. */
.floating-actions__icono-reservar { display: none; }
@media (max-width: 767px) {
  /* El <a> sigue midiendo 44 px como los demás; la píldora sale de su borde
     derecho hacia la izquierda, así que la columna no se ensancha. */
  .floating-actions .floating-actions__texto {
    padding: 0 12px;
    font-size: 0.58rem;
    letter-spacing: 0.08em;
  }
}

/* ── PRECIOS SÍ / NO (2026-09-25) ──────────────────────────────────────────
   Con la agenda externa, el panel puede esconder los precios (Ajustes →
   Reservas online). El reescritor de enlaces del final de index.html pone
   <html data-precios="no"> SOLO si la agenda es externa y los precios están
   apagados; con la agenda propia siempre pone "si". Se esconde el precio de
   la carta y el de las fichas de las transformaciones (el visor lo quita al
   abrirse, en entradaDe()). Con `#public-services-list` delante para ganar a
   las reglas del móvil, que llevan !important. */
html[data-precios="no"] #public-services-list .service-item__price,
html[data-precios="no"] .precio-del-servicio {
  display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════
   ICONOS DE TRAZO FINO (2026-10-01)
   Cada icono de los botones flotantes, el pie y la sección de contacto
   lleva DOS dibujos: el relleno de siempre (.i-relleno) y uno de línea
   fina (.i-linea). El panel elige cuál se ve (Ajustes → Datos del salón
   → «Estilo de los iconos», salon_info.iconosEstilo → <html data-iconos>).
   El trazo usa currentColor, así que sigue solo a Noche y a Lino.
   El `fill: none` va en el grupo y no en el <svg>: así le gana al
   `fill: #111 !important` de los flotantes (css/web-responsivo.css).
   ═══════════════════════════════════════════════════════════════════ */
.i-linea { display: none; }
html[data-iconos="linea"] .i-relleno { display: none; }
html[data-iconos="linea"] .i-linea {
  display: inline;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Los de la sección de contacto llevan el oro como atributo (fill), que el
   trazo no hereda: el de texto, que en Lino se lee mejor que el de marca. */
html[data-iconos="linea"] .contacto__icono .i-linea { stroke: var(--color-gold-text); }


/* Sin testimonios, la sección y su enlace del menú se esconden (js/main.js,
   renderPublicReviews, 2026-10-01). Las clases del menú ponen su propio
   display, así que [hidden] necesita ganarles. */
#experiencia[hidden],
a[href="#experiencia"][hidden] { display: none !important; }


/* ── «Barra abajo» (horizontal, 2026-10-01, de Stoica) ─────────────────────
   Una posición más de los botones flotantes (Ajustes → Datos del salón →
   «Botones de contacto flotantes»; la de serie sigue siendo «arriba»).
   En el ordenador, como «abajo» (columna en la esquina). En el móvil, barra a
   todo el ancho pegada al borde inferior: la carta y el escrito de la portada
   recuperan el 100 % (ver más arriba) y el pie deja hueco para no quedar
   tapado. El color de los botones va aparte, justo debajo («EL COLOR DE
   LOS BOTONES REDONDOS», también de Stoica, desde el 2026-10-07). */
html[data-botones="horizontal"] .floating-actions { top: auto; bottom: 28px; transform: none; }
@media (max-width: 767px) {
  html[data-botones="horizontal"] .floating-actions {
    top: auto; right: 0; bottom: 0; left: 0;
    flex-direction: row; justify-content: space-evenly; align-items: center; gap: 0;
    padding: 8px 6px calc(8px + env(safe-area-inset-bottom));
    background: var(--color-dark-card); border-top: 1px solid var(--color-linea-suave);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.18);
  }
  html[data-botones="horizontal"] .floating-actions__btn:not(.floating-actions__btn--reservar) { width: 44px; height: 44px; }
  /* En la barra no crecen al tocarlos: se montarían sobre el vecino. */
  html[data-botones="horizontal"] .floating-actions__btn:not(.floating-actions__btn--reservar):hover { transform: none !important; }
  /* La píldora «Reservar» ocupa su sitio en la fila (en la columna sale por
     fuera del círculo). */
  html[data-botones="horizontal"] .floating-actions .floating-actions__btn--reservar { width: auto; height: 44px; flex: 0 1 auto; }
  html[data-botones="horizontal"] .floating-actions .floating-actions__texto {
    position: static; height: 44px; padding: 0 18px; font-size: 0.66rem; letter-spacing: 0.16em; border-radius: 999px;
  }
  html[data-botones="horizontal"] .footer-modern { padding-bottom: 72px; }
}

/* ── EL COLOR DE LOS BOTONES REDONDOS (2026-10-07, de Stoica) ──
   Panel → Ajustes → Datos del salón → «Color de los botones redondos»
   (salon_info.flotantesColor → <html data-flotantes>, lo ponen el <head> y
   pintarSalonInfo). Vale para los cuatro redondos (llamar, WhatsApp,
   Instagram y Maps); la píldora «Reservar» tiene su propio color.
     oro      → el de siempre y el de serie: no se toca nada, lo pinta
                css/web-responsivo.css.
     tema     → el fondo de tarjeta del tema, con el icono en oro de texto.
     reservar → el mismo relleno y la misma letra que el botón Reservar
                (las fichas --res-*, que cambian con su color y con el tema).
   Llevan !important porque css/web-responsivo.css pinta el oro con
   !important; el «html[data-flotantes]» les da más peso. */
html[data-flotantes="tema"] .floating-actions__btn:not(.floating-actions__btn--reservar) {
  background: var(--color-dark-card) !important;
  color: var(--color-gold-text) !important;
  border: 1px solid var(--color-linea-suave) !important;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25) !important;
}
html[data-flotantes="tema"] .floating-actions__btn:not(.floating-actions__btn--reservar):hover {
  background: var(--color-dark-card) !important;
  border-color: var(--color-gold-warm) !important;
}
html[data-flotantes="reservar"] .floating-actions__btn:not(.floating-actions__btn--reservar) {
  background: var(--res-relleno) !important;
  color: var(--res-letra) !important;
  border: 0 !important;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22) !important;
}
html[data-flotantes="reservar"] .floating-actions__btn:not(.floating-actions__btn--reservar):hover {
  background: var(--res-relleno-hover, var(--res-relleno)) !important;
}
/* El icono, del color de su botón (web-responsivo.css lo deja en la letra
   «sobre oro»). Con los iconos de trazo fino, el trazo ya usa currentColor. */
html[data-flotantes="tema"] .floating-actions__btn:not(.floating-actions__btn--reservar) svg,
html[data-flotantes="reservar"] .floating-actions__btn:not(.floating-actions__btn--reservar) svg {
  fill: currentColor !important;
}


/* ── En qué consiste cada servicio (2026-10-01, de Stoica) ──
   El panel escribe la explicación de cada servicio y marca cuáles se ven.
   Esos llevan una ⓘ junto al nombre (js/main.js, nombreConExplicacion) y, al
   pulsarla, la explicación se abre DENTRO de su ficha, en su propia línea al
   final, con una raya dorada a la izquierda. */
.service-item__ultima { white-space: nowrap; }   /* la ⓘ no se queda sola en otra línea */
.service-item__ver {
  position: relative;
  display: inline-flex;
  width: 18px;
  height: 18px;
  margin: 0 0 0 6px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--color-gold-text);
  vertical-align: -3px;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}
/* El dibujo mide 18 px; la zona que recoge el toque, 34 (44 con el dedo) */
.service-item__ver::before {
  content: "";
  position: absolute;
  inset: -8px;
}
@media (pointer: coarse) {
  .service-item__ver::before { inset: -13px; }
}
.service-item__ver svg { display: block; width: 100%; height: 100%; }
.service-item__ver:hover { transform: scale(1.12); }
/* Abierta, la ⓘ se rellena */
.service-item__ver[aria-expanded="true"] {
  background: var(--color-gold-text);
  color: var(--color-dark-main);
}
.service-item__ver[aria-expanded="true"] .service-item__ver-aro { stroke: var(--color-gold-text); }

/* Una línea entera de la ficha: la explicación va siempre debajo del nombre,
   la duración y el precio. */
.service-item__explicacion {
  flex: 1 1 100%;
  grid-column: 1 / -1;        /* en la ficha compacta (rejilla), a todo el ancho */
  margin: 4px 0 2px;
  padding: 2px 0 2px 14px;
  border-left: 2px solid var(--color-gold-text);
  color: var(--color-text-suave);
  font-size: 0.86rem;
  line-height: 1.6;
  text-align: left;
  white-space: pre-line;      /* respeta los saltos de línea del panel */
  overflow-wrap: break-word;
  animation: explicacion-entra 0.22s ease-out;
}
.service-item__explicacion[hidden] { display: none; }
@keyframes explicacion-entra {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
/* La ficha se reparte en líneas mientras enseña su explicación */
.service-item:has(> .service-item__explicacion:not([hidden])) { flex-wrap: wrap; }
/* En la ficha compacta, con su letra */
@media (max-width: 1023px), (pointer: coarse) and (max-height: 500px) {
  .service-item__explicacion { font-size: 0.8rem; }
}
@media (prefers-reduced-motion: reduce) {
  .service-item__explicacion { animation: none; }
  .service-item__ver { transition: none; }
  .service-item__ver:hover { transform: none; }
}

/* «Visítanos» con el mismo aire que las demás secciones (2026-10-01): no
   tenía ninguno y su título pegaba con la sección de arriba. */
.contacto { padding: var(--space-section) 0; }


/* ── Un último «Reservar Cita» encima del pie (2026-10-01) ──
   Corta: etiqueta, título y botón. Fondo hondo con una línea fina arriba. El
   color del botón es el de Reservar elegido en el panel (regla «TODOS LOS
   BOTONES DE RESERVAR», más arriba); no late. */
.reservar-final {
  padding: 64px 0;
  background: var(--color-dark-deep);
  border-top: 1px solid var(--color-linea-suave);
  text-align: center;
}
.reservar-final .section-title { margin-bottom: 28px; }
.reservar-final__btn { display: inline-block; text-decoration: none; }
.reservar-final[hidden] { display: none; }
@media (max-width: 767px) {
  .reservar-final { padding: 48px 0; }
}

/* SECCIONES APAGADAS (2026-10-07, como en Stoica desde el 2026-09-27)
   ───────────────────────────────────────────────────────────
   El panel (Ajustes → «Secciones de la web») apaga secciones. Lo aplica
   aplicarSecciones() en js/main.js. Una sección apagada, y sus enlaces del
   menú, llevan su propia marca, data-apagada, y no `hidden`: las reseñas ya
   se esconden solas con `hidden` cuando no hay ninguna, y así no se pisan, y
   al volver a encenderla se ve al momento en una pestaña ya abierta. */
[data-apagada] { display: none !important; }

/* La fila «Cerrado» del horario de contacto (2026-10-07): lleva el gris
   apagado escrito en su style="", y en Noche, sobre la tarjeta, se quedaba en
   4,4:1 en Hairlover. Un poco de la letra normal lo deja legible sin que deje de
   verse más apagada que las demás. El !important es para ganar al style="". */
.contacto__horario-row.closed { color: color-mix(in srgb, var(--color-text-muted) 75%, var(--color-text-light)) !important; }

/* ── Mapa que solo se carga al pulsarlo (2026-10-07, traído de Stoica) ──
   Hasta que la visitante pulsa, en el sitio del mapa va este botón: así
   Google no pone sus cookies antes de que ella quiera. */
.mapa-diferido__boton {
  align-items: center;
  background: var(--color-superficie-suave);
  border: 1px dashed rgba(201, 168, 76, 0.45);
  border-radius: 12px;
  color: var(--color-gold-text);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  font-family: var(--font-body);
  gap: 6px;
  justify-content: center;
  min-height: 120px;
  padding: 16px;
  transition: background 0.2s ease;
  width: 100%;
}
.mapa-diferido__boton span { font-size: 0.85rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
.mapa-diferido__boton small { color: var(--color-text-muted); font-size: 0.7rem; line-height: 1.4; }
.mapa-diferido__boton:hover { background: rgba(201, 168, 76, 0.08); }
/* En Lino el oro de marca es muy pálido y la caja del mapa casi no se veía */
html[data-tema="lino"] .mapa-diferido__boton { border-color: rgba(111, 96, 64, 0.35); }
html[data-tema="lino"] .mapa-diferido__boton:hover { background: rgba(111, 96, 64, 0.08); }
/* El aviso de las cookies va en letra pequeña: con el gris apagado se quedaba
   justo en el límite de lo legible (4,5:1) sobre el beige */
html[data-tema="lino"] .mapa-diferido__boton small { color: var(--color-text-suave); }
