/* Ritual Bienestar — personalizaciones sobre el tema hummingbird.
   Este fichero se carga automáticamente el último (prioridad 1000),
   así que cualquier regla de aquí gana a las del tema padre. */

/* ascent/descent/line-gap-override pinned to Roman's own win-metrics ratio
   (931/225/200 of a 1000-unit em, per the font files' OS/2 table) on all
   three cuts: Light's own win metrics (979/250) are taller and more
   bottom-heavy than Roman's, and since none of the three set the
   USE_TYPO_METRICS flag, browsers fall back to win ascent/descent for the
   line box — Light ends up with extra space below the baseline that Roman
   doesn't have, so switching weight mid-page shifts the visible text
   upward inside its own line box. Overriding all three to the same values
   removes the mismatch outright instead of relying on browsers agreeing
   on which metric table to read. */
@font-face{font-family:"Helvetica LT Std";src:url("../fonts/HelveticaLTStd-Roman.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;ascent-override:93.1%;descent-override:22.5%;line-gap-override:20%}
@font-face{font-family:"Helvetica LT Std";src:url("../fonts/HelveticaLTStd-Bold.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;ascent-override:93.1%;descent-override:22.5%;line-gap-override:20%}
@font-face{font-family:"Helvetica LT Std";src:url("../fonts/HelveticaLTStd-Light.woff2") format("woff2");font-weight:300;font-style:normal;font-display:swap;ascent-override:93.1%;descent-override:22.5%;line-gap-override:20%}
@font-face{font-family:"Angel Face";src:url("../fonts/AngelFace.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Tindoghouse";src:url("../fonts/Tindoghouse.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Helvetica Cursiva";src:url("../fonts/HelveticaLTStd-LightObl.woff2") format("woff2");font-weight:300;font-style:italic;font-display:swap}

:root{
  --ink:#29251c;
  --ritual-cream:#f7f3ec;
  --brass:#af8a52;
  --color-error:#b00020;
  --color-success:#1e7e34;
  /* Altura real del header, medida y mantenida al día por custom.js
     (ResizeObserver). 0px es solo el valor antes de que el script corra o
     si falla del todo: ver custom.js para el porqué de cada caso. */
  --ritual-header-h:0px;
}

/* Grises de texto de Bootstrap → --ink. body ya fija color:var(--ink),
   pero los componentes de Bootstrap/hummingbird no leen el color de body:
   leen estas variables, que seguían en el #212529 (y sus versiones al
   75%/65%). Por eso quedaban en gris frío los títulos de modal
   (.modal-title), las ayudas de formulario (.form-text, requisitos de
   contraseña), .text-body-secondary/-tertiary/.text-muted, los botones
   .btn-link/.btn-basic sin color propio, dropdowns, list-groups,
   offcanvas... Se mantienen las mismas opacidades de Bootstrap (.75/.65)
   para no cambiar la jerarquía relativa que ya tenían, solo el tono.
   El :root de theme.css va fuera de @layer, así que este gana por orden
   de carga con la misma especificidad. --bs-dark y la escala --bs-gray-*
   no se tocan: son colores explícitos de utilidad, no el color de texto. */
:root{
  --bs-body-color:var(--ink);
  --bs-body-color-rgb:41,37,28;
  --bs-secondary-color:rgba(41,37,28,.75);
  --bs-secondary-color-rgb:41,37,28;
  --bs-tertiary-color:rgba(41,37,28,.65);
  --bs-tertiary-color-rgb:41,37,28;
  --bs-highlight-color:var(--ink);
}

/* hummingbird nunca define a:visited, así que cae al morado por defecto
   del navegador; heredamos el color que ya tenga el enlace en cada
   contexto en vez de fijar uno global. */
a{
  color:var(--ink);
}

/* ==== Botón píldora — clase maestra ====
   Forma/color/hover/disabled únicos para todo botón "CTA píldora" del
   sitio: añadir al carrito, finalizar compra, cupones/tarjetas regalo,
   reservas del carrito, login/registro, CTAs de home. .ritual-cta queda
   como alias — ya era la clase compartida de los CTAs de home/header/menú
   antes de esta unificación, así que sigue funcionando en su HTML tal
   cual. .btn-pill--secondary es la variante outline (antes iba por
   .btn-outline-primary/--ghost/--outline según el sitio); .btn-pill--sm es
   el tamaño compacto para botones en línea con un input o dentro de una
   fila de tabla. Se añade como clase adicional junto a las clases de
   Bootstrap/estructurales existentes — no las sustituye — para no romper
   ningún hook de JS que dependa de ellas. */
.btn-pill,
.ritual-cta{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  border:none;
  border-radius:999px;
  background:var(--ink);
  color:#fff;
  font-weight:700;
  font-size:.85rem;
  text-transform:uppercase;
  letter-spacing:.04em;
  padding:.75rem 1.75rem;
  text-decoration:none!important;
  cursor:pointer;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
  transition:transform var(--motion-hover) var(--motion-ease), box-shadow var(--motion-hover) var(--motion-ease), background-color var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease);
}
.btn-pill:hover,
.ritual-cta:hover{
  color:#fff;
  transform:translateY(-2px);
  box-shadow:0 10px 22px rgba(0,0,0,.2);
}
.btn-pill:disabled,
.btn-pill.disabled,
.ritual-cta:disabled,
.ritual-cta.disabled{
  opacity:.4;
  cursor:not-allowed;
  pointer-events:none;
  box-shadow:none;
  transform:none;
}
@media (prefers-reduced-motion: reduce){
  .btn-pill,
  .ritual-cta{transition:none}
  .btn-pill:hover,
  .ritual-cta:hover{transform:none}
}

.btn-pill--secondary{
  background:transparent;
  color:var(--ink);
  border:1px solid var(--ink);
  box-shadow:none;
}
.btn-pill--secondary:hover{
  background:var(--ink);
  color:#fff;
}

.btn-pill--sm{
  padding:.5rem 1.25rem;
  font-size:.8rem;
}

/* --brass como fondo de botón: acento de marca deliberado (DIRECCION-VISUAL.md
   #1), hoy infrautilizado frente a --ink. Texto en blanco por decisión
   explícita — nótese que sobre #af8a52 el blanco da ~3.2:1 de contraste,
   por debajo del 4.5:1 de AA para texto normal (--ink daría ~4.8:1); se
   mantiene así porque así se ha pedido, no por descuido. No hace falta
   fijar color en :hover: ya hereda el blanco de la base .btn-pill. */
.btn-pill--brass{
  background:var(--brass);
  color:#fff;
}

/* --- Wider side gutters than Bootstrap's 1.5rem default, on every
   container variant plus the mobile checkout stepper (which sets its own
   --bs-gutter-x rather than using a .container class). --- */
.checkout-steps__mobile,
.container,
.container-fluid,
.container-lg,
.container-md,
.container-sm,
.container-xl,
.container-xxl{
  --bs-gutter-x:2.5rem;
}

/* --- Carousel prev/next controls (site-wide: reviews, image slider, any
   other Bootstrap carousel): base theme's white icon chip sits at
   opacity:.35 on the button, fading it into any light/cream section
   background. Bump both the badge and the arrow to full brand-ink so it
   reads clearly wherever it lands, and raise the base opacity so it
   doesn't need a hover to become visible. --- */
.carousel-control-prev,
.carousel-control-next{
  opacity:.9;
  align-items: start;
  top: -3.5rem;
}
.carousel-control-prev:hover,
.carousel-control-next:hover,
.carousel-control-prev:focus,
.carousel-control-next:focus{
  opacity:1;
}
.carousel-control-prev-icon,
.carousel-control-next-icon{
  background-color:var(--ink);
  border-radius:50%;
}
.carousel-control-prev-icon::before,
.carousel-control-next-icon::before{
  color:#fff;
}
/* Transición entre slides: 1s en vez del .6s de Bootstrap. Dentro de
   no-preference para no pisar el transition:none de reduced-motion. El
   retardo de .carousel-fade va ligado a la duración, se ajusta a la par. */
@media (prefers-reduced-motion:no-preference){
  .carousel-item{
    transition-duration:1s;
  }
  .carousel-fade .active.carousel-item-start,
  .carousel-fade .active.carousel-item-end{
    transition-delay:1s;
  }
  /* Slider de portada: duración configurable en el módulo
     ritualbienestar_imageslider (variable inline en .ps-imageslider). */
  .ps-imageslider .carousel-item{
    transition-duration:var(--rb-slider-transition,1s);
  }
}

/* Type system: Tindoghouse for headings, Helvetica Regular (400) for
   emphasized/highlighted body copy, Helvetica Light (300) as the running
   body text default — Helvetica LT Std's own @font-face rules already map
   each weight to the right cut, so setting the base weight is enough; use
   font-weight:400 on any element that needs the "destacado" register. */
/* Color y peso por defecto de todo el sitio. Sin ellos, hummingbird deja
   el texto en el #212529 de Bootstrap (gris frío) en vez de --ink, y en
   Light, así que cualquier elemento que no declarara los suyos se desviaba
   del estándar tipográfico por omisión. Los sitios donde el Light sí es
   deliberado ya lo declaran explícitamente (cuerpo narrativo de home, cita
   del equipo, página de contacto, descripción de la ficha de producto y
   todos los controles de formulario), así que siguen en 300.
   El cambio de peso no mueve nada en vertical: las tres cortes de Helvetica
   LT Std comparten ascent/descent/line-gap-override en sus @font-face
   justo para eso. Sí ensancha un poco el texto (Roman es más ancho que
   Light), así que lo que puede variar es dónde parten las líneas. */
body{
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-weight:400;
  color:var(--ink);
  /* .category__hero below is full-bleed via 100vw + negative margins, which
     always overshoots the visible viewport by the scrollbar's width on any
     page tall enough to scroll (100vw includes the scrollbar, 50% doesn't) -
     clip that horizontal sliver here rather than adding scrollbar-width math. */
  overflow-x:hidden;
  /* Sticky footer site-wide: short-content pages used to leave raw white
     space between content and footer. Body's own direct children (header,
     main.wrapper, footer.page-footer) become a column flex; main grows to
     fill whatever's left, pinning the footer to the bottom on every page. */
  display:flex;
  flex-direction:column;
  min-height:100vh;
}
body>main.wrapper{
  flex:1 0 auto;
}
h1,h2,h3,h4,h5,h6{
  font-family:"Tindoghouse",cursive;
  font-weight:400;
}

.ritual-whatsapp-icon{
  flex:none;
}
.ritual-contact-link{
  margin-left:1rem;
}

/* --- Main nav: smaller text, single line, no wrapping, animated underline
   that grows from the link on hover/focus --- */
.ps-mainmenu__tree{
  gap:.5rem;
}
.ps-mainmenu__tree-link{
  position:relative;
  padding:1.25rem .15rem!important;
  font-size:.9rem!important;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.02em;
  white-space:nowrap;
  color:var(--ink)!important;
  transition:font-size .35s ease;
}
.ps-mainmenu__tree-link:hover,
.ps-mainmenu__tree-link:focus,
.ps-mainmenu__tree-item.current .ps-mainmenu__tree-link{
  color:var(--ink)!important;
}
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree>li .ps-mainmenu__tree-link:focus,
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree>li .ps-mainmenu__tree-dropdown-toggle:focus,
.ps-mainmenu:is(.ps-mainmenu--desktop) .submenu__left-item:focus{
  outline:none!important;
}
.ps-mainmenu__tree-link::after{
  content:"";
  position:absolute;
  left:.25rem;
  right:.25rem;
  bottom:.85rem;
  height:1px;
  background:currentColor;
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .25s ease;
}
.ps-mainmenu__tree-link:hover::after,
.ps-mainmenu__tree-link:focus::after{
  transform:scaleX(1);
}
@media (prefers-reduced-motion: reduce){
  .ps-mainmenu__tree-link::after{transition:none}
}

/* --- Submenu: dark, compact single column, hanging under its OWN trigger
   link — not a full-width band centered under the whole menu (hummingbird's
   base .submenu{left:0;right:0} spans the whole header; we size to content
   instead). Floats in like the search flyout (opacity/transform, rounded
   corners) instead of hummingbird's abrupt display:none/block swap: since
   that swap is driven by an inline style we can't transition, we force
   display:block permanently and drive visibility from the .is-open class,
   which custom.js toggles by watching the trigger button's aria-expanded
   (set on every open path — hover, click, keyboard — see custom.js). Left
   offset is also set there, since hummingbird's own JS only ever sets
   `top`, never `left`/`right`. --- */
.ritual-submenu{
  display:block!important;
  left:0;
  right:auto;
  width:max-content;
  background:#fff;
  border:1px solid rgba(41,37,28,.12);
  box-shadow:0 8px 24px rgba(41,37,28,.12);
  border-top:none;
  border-radius:16px;
  overflow:hidden;
  opacity:0;
  visibility:hidden;
  transform:translateY(-8px);
  pointer-events:none;
  transition:opacity .25s ease, transform .25s ease, visibility .25s ease;
}
.ritual-submenu.is-open{
  opacity:1;
  visibility:visible;
  transform:translateY(0);
  pointer-events:auto;
}
@media (prefers-reduced-motion: reduce){
  .ritual-submenu{transition:none}
}
.ritual-submenu .container{
  width:auto;
  max-width:none;
  margin:0;
  padding:.5rem;
}
.ritual-submenu__list{
  list-style:none;
  margin:0;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:2px;
  min-width:220px;
  max-width:280px;
}
.ritual-submenu__item .ritual-submenu__list{
  padding-left:14px;
  margin-top:2px;
}
.ritual-submenu__link{
  display:block;
  padding:.55rem .9rem;
  border-radius:6px;
  color:var(--ink);
  text-decoration:none;
  font-size:.85rem;
  font-weight:600;
  text-transform:uppercase;
  letter-spacing:.02em;
  transition:background .2s ease;
}
.ritual-submenu__link:hover{
  background:rgba(41,37,28,.1);
}
.ritual-submenu__link.is-active{
  color:var(--brass);
  background:rgba(41,37,28,.04);
}

/* --- Breadcrumb: same Bootstrap default link-blue issue as the mobile
   menu's subcategory toggle/back button above — hummingbird's
   _breadcrumb.scss only sets the divider/active-item color to
   var(--bs-body-color), leaving the links themselves on Bootstrap's
   default blue. Recolor to ink, underline on hover/focus for the
   link affordance now that color alone isn't providing it. --- */
/* Metadato del estándar de home: .8125rem, line-height 1.4, peso 400 y
   --ink al 60%. Las dos variables de Bootstrap son necesarias porque
   hummingbird las resuelve contra --bs-body-color (#212529), que es
   independiente del color que fija body — sin tocarlas, el separador y el
   ítem activo seguirían en el gris de Bootstrap. El 60% va como rgba y no
   como opacity para que el enlace pueda subir a --ink pleno en hover. */
.breadcrumb{
  --bs-breadcrumb-font-size:.8125rem;
  --bs-breadcrumb-divider-color:rgba(41,37,28,.6);
  --bs-breadcrumb-item-active-color:rgba(41,37,28,.6);
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.breadcrumb a{
  color:rgba(41,37,28,.6);
}
.breadcrumb a:hover,
.breadcrumb a:focus{
  color:var(--ink);
  text-decoration:underline;
}

/* --- Search: field always visible in the header row (no icon-toggle
   flyout anymore) — the form itself is the visible pill; only the results
   dropdown still opens/closes (driven by hummingbird's own JS via the
   .d-none on .ps-searchbar__dropdown, untouched here). --- */
.ritual-search-widget{
  position:relative;
  gap:0;
}
/* El tema base fija .ps-searchbar{min-width:19rem} (304px) pensado para el
   antiguo panel flotante — el campo visible aquí mide 220px
   (.ritual-search-inline .ps-searchbar__form), así que sin esto quedaba un
   margen invisible de ~84px entre el buscador y el siguiente icono. */
.ritual-search-inline{
  min-width:0;
}
.ritual-search-inline .ps-searchbar__form{
  display:flex;
  align-items:center;
  gap:.5rem;
  width:220px;
  padding:.4rem .75rem;
  border:1px solid rgba(41,37,28,.25);
  border-radius:10px;
  background:#fff;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.ritual-search-inline .ps-searchbar__form:focus-within{
  border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(175,138,82,.15);
}
.ritual-search-inline .ps-searchbar__magnifier{
  /* El tema base (hummingbird) posiciona este icono en position:absolute
     (pensado para superponerse sobre el padding-inline del input) — aquí
     el campo es un flex row (icono + input como hermanos, ver
     .ritual-search-inline .ps-searchbar__form), así que hay que anular esa
     posición absoluta o el icono queda flotando encima del texto. */
  position:static;
  top:auto;
  left:auto;
  transform:none;
  flex:none;
  font-size:20px;
  color:var(--ink);
  opacity:.6;
}
.ritual-search-inline .ps-searchbar__input{
  border:none;
  background:transparent;
  padding:0;
  flex:1 1 auto;
  min-width:0;
}
.ritual-search-inline .ps-searchbar__dropdown{
  border:1px solid rgba(41,37,28,.12);
  border-radius:16px;
  box-shadow:0 8px 24px rgba(41,37,28,.12);
}
/* Bootstrap's default :focus is a blue glow (.form-control:focus in
   theme.css) — the pill itself already shows focus via :focus-within
   above, so just drop Bootstrap's own ring on the (now borderless)
   input to avoid a double outline. */
.ps-searchbar__input:focus{
  box-shadow:none;
}
.ps-searchbar__clear {
  right: .75rem;
  border: none !important;
}
.ps-searchbar__clear:hover {
  color: var(--ink);
}
/* No max-height here before meant a long result list grew the flyout (and
   the whole page) instead of scrolling in place — the page's own scrollbar
   would then take over, and dragging *that* one (outside #ps_searchbar)
   tripped the document click-outside listener in custom.js and closed the
   flyout. Bounding it keeps the scroll — and every click that drives it —
   inside the flyout. */
.ps-searchbar__results {
  max-height:60vh;
  overflow-y:auto;
}
.ps-searchbar__result-image {
  display:none;
}
/* .ps-searchbar__result-link is a CSS grid item (parent .ps-searchbar__results
   is grid-template-columns:1fr) — grid items default to min-width:auto, so
   without this they'd grow to fit the name's nowrap content instead of
   shrinking to the 1fr track, pushing the price off the dropdown's clipped
   (overflow:hidden) right edge. */
.ps-searchbar__result-link {
  min-width:0;
}
.ps-searchbar__result-name {
  flex:1 1 auto;
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}
.ps-searchbar__result-price {
  flex-shrink:0;
  padding-right:1rem;
  color:var(--bs-body-color);
  font-weight:600;
  white-space:nowrap;
}
/* Theme base sets an :active link color to bs-link-hover-color (blue);
   keep result text the same color while pressed, matching hover/focus. */
.ps-searchbar__result-link:active .ps-searchbar__result-name{
  color:var(--bs-body-color);
}
.ps-searchbar__result-link:focus-visible {
  outline: 2px solid var(--ink);
}
@media (prefers-reduced-motion: reduce){
  .ritual-search-inline .ps-searchbar__form{transition:none}
}

/* ==== Menú móvil (offcanvas #mobileMenu) — acordeón ritual-mnav ====
   Sustituye al menú de paneles deslizantes de hummingbird (cada categoría
   con hijos "cambiaba de página"): ver ps_mainmenu.tpl ("GENERATE MOBILE
   MENU") y custom.js ("Menú móvil en acordeón"). Todo va prefijado con
   #mobileMenu para ganar a las reglas de hummingbird
   (.ps-mainmenu:is(.ps-mainmenu--mobile) ...) sin !important.
   Color según DIRECCION-VISUAL.md: texto y estructura en ink; brass solo
   para lo interactivo/activo (chevron, categoría actual, divisor del
   desplegable). Márgenes laterales unificados en --mnav-gutter para
   cabecera, buscador, lista y bloque inferior. */
#mobileMenu{
  --mnav-gutter:1.25rem;
  --mnav-line:rgba(41,37,28,.1);
  /* El panel entero hace scroll: con los desplegables abiertos la lista
     puede superar la altura de pantalla (hummingbird lo dejaba en
     overflow:hidden porque cada nivel era un panel aparte). */
  overflow-x:hidden;
  overflow-y:auto;
  overscroll-behavior:contain;
}
#mobileMenu > *{
  flex-shrink:0;
}

/* Cabecera: logo + cerrar, fija arriba mientras se hace scroll. */
#mobileMenu .ritual-mnav__header{
  position:sticky;
  top:0;
  z-index:2;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  padding:1rem var(--mnav-gutter);
  margin-bottom:1rem;
  background:var(--bs-body-bg, #fff);
  border-bottom:1px solid var(--mnav-line);
}
#mobileMenu .ritual-mnav__logo{
  display:block;
  line-height:0;
}
#mobileMenu .ritual-mnav__logo img{
  width:auto;
  height:auto;
  max-height:2.25rem;
  max-width:10rem;
}
#mobileMenu .ritual-mnav__close{
  flex:none;
  width:2.5rem;
  height:2.5rem;
  padding:0;
  margin:0 0 0 auto;
  border-radius:50%;
  background-color:rgba(41,37,28,.06);
  background-size:.85rem;
  opacity:1;
  transition:background-color .2s ease;
}
#mobileMenu .ritual-mnav__close:hover,
#mobileMenu .ritual-mnav__close:focus-visible{
  background-color:rgba(41,37,28,.12);
}

/* Lista */
#mobileMenu .ritual-mnav{
  height:auto;
  padding:0 var(--mnav-gutter);
}
#mobileMenu .ritual-mnav__list{
  list-style:none;
  margin:0;
  padding:0;
}
#mobileMenu .ritual-mnav__list[data-depth="0"] > .ritual-mnav__item{
  border-bottom:1px solid var(--mnav-line);
}
#mobileMenu .ritual-mnav__link{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  width:100%;
  min-height:3.25rem;
  padding:.85rem 0;
  margin:0;
  font:inherit;
  font-size:1.05rem;
  font-weight:400;
  line-height:1.3;
  text-align:left;
  color:var(--ink);
  text-decoration:none;
  background:none;
  border:0;
  border-radius:0;
  cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
#mobileMenu .ritual-mnav__link:focus-visible{
  outline:2px solid var(--brass);
  outline-offset:2px;
}
#mobileMenu .ritual-mnav__label{
  flex:1 1 auto;
  min-width:0;
}
#mobileMenu .ritual-mnav__chevron{
  flex:none;
  font-size:1.5rem;
  color:var(--brass);
  transition:transform .3s cubic-bezier(.2,.8,.2,1);
}
#mobileMenu .ritual-mnav__item.is-open > .ritual-mnav__toggle .ritual-mnav__chevron{
  transform:rotate(180deg);
}
#mobileMenu .ritual-mnav__item.is-open > .ritual-mnav__toggle{
  font-weight:700;
}
/* Categoría en la que está la clienta */
#mobileMenu .ritual-mnav__item.is-current > .ritual-mnav__link{
  color:var(--brass);
}

/* Desplegable: la altura se anima con grid-template-rows 0fr → 1fr
   (sin medir alturas en JS); visibility retrasada para que los enlaces
   plegados no reciban foco ni toques. */
#mobileMenu .ritual-mnav__panel{
  display:grid;
  grid-template-rows:0fr;
  visibility:hidden;
  transition:grid-template-rows .3s cubic-bezier(.2,.8,.2,1), visibility 0s linear .3s;
}
#mobileMenu .ritual-mnav__item.is-open > .ritual-mnav__panel{
  grid-template-rows:1fr;
  visibility:visible;
  transition:grid-template-rows .3s cubic-bezier(.2,.8,.2,1), visibility 0s;
}
#mobileMenu .ritual-mnav__panel-inner{
  min-height:0;
  overflow:hidden;
}
#mobileMenu .ritual-mnav__panel .ritual-mnav__list{
  margin:0 0 .85rem .15rem;
  padding-left:1rem;
  border-left:1px solid var(--brass);
}
#mobileMenu .ritual-mnav__panel .ritual-mnav__list .ritual-mnav__list{
  margin-bottom:.35rem;
}
#mobileMenu .ritual-mnav__panel .ritual-mnav__link{
  min-height:2.75rem;
  padding:.55rem 0;
  font-size:.95rem;
  color:rgba(41,37,28,.8);
}
#mobileMenu .ritual-mnav__panel .ritual-mnav__item.is-open > .ritual-mnav__toggle,
#mobileMenu .ritual-mnav__panel .ritual-mnav__item.is-current > .ritual-mnav__link{
  color:var(--ink);
}
#mobileMenu .ritual-mnav__panel .ritual-mnav__item.is-current > .ritual-mnav__link{
  color:var(--brass);
}
/* Primera fila del desplegable: enlace a la categoría padre */
#mobileMenu .ritual-mnav__panel .ritual-mnav__item--parent > .ritual-mnav__link{
  font-weight:700;
  color:var(--ink);
}
#mobileMenu .ritual-mnav__go{
  flex:none;
  font-size:1.1rem;
  color:var(--brass);
  transition:transform .2s ease;
}
#mobileMenu .ritual-mnav__item--parent > .ritual-mnav__link:hover .ritual-mnav__go{
  transform:translateX(3px);
}
@media (prefers-reduced-motion: reduce){
  #mobileMenu .ritual-mnav__panel,
  #mobileMenu .ritual-mnav__item.is-open > .ritual-mnav__panel,
  #mobileMenu .ritual-mnav__chevron,
  #mobileMenu .ritual-mnav__go,
  #mobileMenu .ritual-mnav__close{transition:none}
}

/* --- Capa de búsqueda (<1400px): la lupa de la cabecera
   (.ritual-search-toggle, header.tpl) la abre; custom.js mueve dentro el
   buscador (#_desktop_ps_searchbar). Panel claro a todo el ancho arriba y
   el resto de la pantalla oscurecido; clic en el fondo, en la X o Escape
   la cierran. --- */
.ritual-search-overlay{
  position:fixed;
  inset:0;
  z-index:1050;
  visibility:hidden;
  opacity:0;
  transition:opacity .25s ease, visibility 0s linear .25s;
}
.ritual-search-overlay.is-open{
  visibility:visible;
  opacity:1;
  transition:opacity .25s ease, visibility 0s;
}
.ritual-search-overlay__backdrop{
  position:absolute;
  inset:0;
  background:rgba(41,37,28,.55);
}
.ritual-search-overlay__panel{
  position:relative;
  display:flex;
  align-items:flex-start;
  gap:.5rem;
  padding:1rem;
  background:var(--ritual-cream);
  box-shadow:0 8px 26px rgba(0,0,0,.18);
  transform:translateY(-100%);
  transition:transform .25s ease;
}
.ritual-search-overlay.is-open .ritual-search-overlay__panel{
  transform:none;
}
.ritual-search-overlay__field{
  flex:1 1 auto;
  min-width:0;
}
.ritual-search-overlay__close{
  flex:none;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:44px;
  height:44px;
  padding:0;
  border:none;
  border-radius:50%;
  background:none;
  color:var(--ink);
  cursor:pointer;
  transition:background .2s ease;
}
.ritual-search-overlay__close:hover{
  background:rgba(41,37,28,.07);
}
body.ritual-search-open{
  overflow:hidden;
}
/* The moved node keeps its own header-row classes (order-2/ms-auto/
   col-auto/d-none d-xxl-flex, see ps_searchbar.tpl) — Bootstrap utilities
   are !important and layered ("utilities"), so plain overrides here would
   silently lose to them. @layer vendors reuses the first-declared layer
   name (same trick as the #_mobile_ps_customersignin rule below): per the
   cascade-layers spec, !important flips layer priority, so an
   earlier-declared layer's !important beats a later one's. */
@layer vendors{
  .ritual-search-overlay__field #_desktop_ps_searchbar{
    display:flex!important;
    order:0!important;
    margin-left:0!important;
    width:100%!important;
    flex:none!important;
  }
}
.ritual-search-overlay__field .ritual-search-inline,
.ritual-search-overlay__field .ritual-search-inline .ps-searchbar__form{
  width:100%;
}
.ritual-search-overlay__field .ritual-search-inline .ps-searchbar__form{
  min-height:44px;
}
/* 16px: por debajo, iOS hace zoom en la página al enfocar el campo. */
.ritual-search-overlay__field .ps-searchbar__input{
  font-size:16px;
}
@media (prefers-reduced-motion: reduce){
  .ritual-search-overlay,
  .ritual-search-overlay.is-open,
  .ritual-search-overlay__panel{transition:none}
}

/* --- The link list (.ps-mainmenu__mobile) inherits height:100% from
   hummingbird, sized for a layout where it's the only scrollable section —
   here it pushes .ps-mainmenu__additionnals (Contacto/CTA/selectors) off
   below the fold regardless of how short the link list actually is. Let it
   size to its own content instead. --- */
.ps-mainmenu__mobile{
  height:auto;
}
/* .ps-mainmenu__additionnals also carries Bootstrap's own .offcanvas-body
   class (flex:1 1 auto), designed to fill whatever height the link list
   above leaves free — once that link list stops hogging the whole offcanvas,
   this section stretches into all the leftover space instead, and its
   align-items:center then centers its content inside that tall box, which
   reads as a big gap above Contacto/CTA rather than a close-following
   section. Let it size to its own content and sit right after the link
   list with a small gap instead. --- */
.ps-mainmenu__additionnals{
  flex-grow:0;
  align-items:flex-start;
  margin-top:1rem;
}
#mobileMenu .ps-mainmenu__additionnals{
  overflow:visible;
  padding:1.25rem var(--mnav-gutter) 2rem;
}

/* --- Contacto + Reserva tu cita, added to the bottom of the hamburger
   menu (now the only place this CTA shows below xxl, since the desktop
   row itself is d-xxl-block only). .ritual-contact-link there has no
   color of its own, so it gets a --menu variant in plain ink instead.
   The CTA is flat (var(--ink), no gradient/animation — same treatment as
   the header row's own CTA, see .header-bottom__cta) — only the panel
   layout (full width, order) is --menu-specific. Full width so it reads
   as the menu's closing action.
   Cuenta/Contacto ya no son texto subrayado a secas: llevan icono +
   tratamiento de píldora con borde (mismo lenguaje que .btn-pill--secondary,
   sin reutilizar esa clase porque aquí necesitan quedar a ancho completo y
   con icono en vez de solo texto centrado). --- */
.ritual-contact-link--menu{
  display:flex;
  align-items:center;
  gap:.6rem;
  margin-left:0;
  width:100%;
  padding:.65rem 1rem;
  border:1px solid rgba(41,37,28,.2);
  border-radius:999px;
  color:var(--ink);
  text-decoration:none;
  transition:background .2s ease, border-color .2s ease;
  order:1;
}
.ritual-contact-link--menu:hover,
.ritual-contact-link--menu:focus{
  background:rgba(41,37,28,.06);
  border-color:var(--ink);
  color:var(--ink);
  text-decoration:none;
}
.ritual-contact-link--menu .material-icons{
  flex:none;
  font-size:20px;
  opacity:.7;
}
.ritual-cta--menu{
  display:flex;
  width:100%;
  margin-left:0;
  order:2;
}

/* --- Cart: icon only, badge always visible as a small circle, in brass
   so it reads as a state ("hay artículos en el carrito") rather than
   blending into the rest of the structural icons. --- */
.ps-shoppingcart .header-block__title{
  display:none!important;
}
.ps-shoppingcart .header-block__badge{
  position:absolute!important;
  top:-.25rem!important;
  right:-.25rem!important;
  min-width:1rem!important;
  height:1rem!important;
  font-size:.6rem!important;
  color:#fff!important;
  background:var(--brass)!important;
}
.ps-shoppingcart .header-block,
.ps-shoppingcart .header-block__icon,
.ps-shoppingcart.header-block--active .header-block,
.ps-shoppingcart.header-block--active .header-block__icon{
  color:var(--ink)!important;
}

/* --- Account: text link → icon, same 36x36 circular treatment as the
   search/cart icons so the three form one coherent group in the single
   header row. --- */
.ps-customersignin .header-block__action-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  padding:0;
  border-radius:50%;
  color:var(--ink);
  transition:background .2s ease;
}
.ps-customersignin .header-block__action-btn:hover{
  background:rgba(41,37,28,.07);
}
.ps-customersignin .header-block__icon{
  font-size:22px;
}

/* Same circular hover chip used by the account icon: a soft gray circle
   behind the icon. Overriding hummingbird's own padding (symmetric on
   mobile, wider than tall on desktop — .5rem .75rem) to a fixed 36x36 box
   so border-radius:50% renders a true circle at every breakpoint instead
   of an oval. */
.ps-shoppingcart .header-block__action-btn{
  width:36px;
  height:36px;
  padding:0;
  justify-content:center;
  border:none;
  background:none;
  border-radius:50%;
  cursor:pointer;
  transition:background .2s ease;
}
.ps-shoppingcart .header-block__action-btn:hover{
  background:rgba(41,37,28,.07);
}
.ps-shoppingcart .header-block__action-btn:not([href]):hover{
  background:none;
}

/* --- Row order: logo(0, implicit) → menu(1, vendor's own .ps-mainmenu{order:1})
   → search(2, Bootstrap order-2 class in ps_searchbar.tpl) → account(3) →
   cart(4) → CTA(5, see .header-bottom__cta). Account/cart/CTA all default
   to order:0 without this, which — since the vendor's own .ps-mainmenu
   rule already bumps the menu to order:1 — would render them ahead of the
   menu instead of after it. --- */
#_desktop_ps_customersignin{
  order:3;
  /* Unlike its row siblings (ps_mainmenu/ps_searchbar/cart), this div's
     own theme override never carries a `col-auto`-equivalent class — it
     was only ever nested inside a Bootstrap column before this redesign
     (header-top__right), never a direct flex-row child. Without an
     explicit width here it resolves its flex-basis to the row's full
     available space instead of shrinking to its ~36px icon, ballooning
     into every other row item pushed off past the right edge. */
  width:max-content;
  /* .header-bottom__row is a Bootstrap "row align-items-stretch" — every
     direct flex child (this div included) stretches to the row's full
     height by default. #_desktop_ps_shoppingcart's own markup already
     carries `d-flex align-items-center` to re-center its icon inside that
     taller box, but this div (ps_customersignin.tpl) never did, so its
     36px icon just sat flush at the top instead of centered. */
  display:flex;
  align-items:center;
  /* Below 1400px (see .header-bottom__logo's own <1399.98px centering
     block further down) the row's remaining items — hamburger, this icon,
     cart — used to rely on `justify-content:space-between` to spread
     across the row. With only 3 small items in a wide row that put THIS
     one (the middle item) almost exactly at the row's horizontal center,
     landing it right on top of the absolutely-centered logo. margin-left:
     auto instead explicitly pushes this icon (and cart right after it, via
     the row's own `gap:1rem`) into one tight cluster flush against the
     row's right edge — no middle-item drift possible, since nothing is
     left to "space between" anymore. Below 1400px the search magnifier
     (.ritual-search-toggle) takes over that auto margin, see its block. */
  margin-left:auto;
}
#_desktop_ps_shoppingcart{
  order:4;
}
/* Below 768px, hummingbird's own responsive swap (theme.js, fixed 768px
   cut) moves #_desktop_ps_customersignin's node out of this row entirely
   (into the force-hidden #_mobile_ps_customersignin, see the @layer
   vendors rule below), so cart becomes the first — and only — item of the
   right-hand cluster in that range, and needs the same margin-left:auto
   to reach the
   row's right edge on its own. Scoped to <768px only: at 768px and up,
   account is still present and already does this job, and giving cart its
   OWN auto margin too there would open a second gap between account and
   cart instead of keeping them as one tight cluster.

   BUT: swapElements (themes/hummingbird/src/js/helpers/swapElements.ts)
   does NOT move the #_desktop_ps_shoppingcart element itself below 768px —
   it copies its innerHTML into #_mobile_ps_shoppingcart (a separate div,
   see header.tpl) and empties the desktop one. So below 768px the rules
   above never actually apply to anything visible: the real flex item in
   the row at that point is #_mobile_ps_shoppingcart, a plain `d-md-none
   d-flex col-auto` div with none of this cart's order/margin — it just
   fell in wherever default flex flow put it (right after the hamburger),
   which is exactly the "cart stuck on the left, big gap on the right"
   reported. Same order/margin/centering repeated here, targeting the
   container that's actually in the DOM's flex flow at this width. */
@media (max-width: 767.98px){
  #_desktop_ps_shoppingcart{
    margin-left:auto;
  }
  #_mobile_ps_shoppingcart{
    order:4;
    display:flex;
    align-items:center;
    margin-left:auto;
  }
}
/* --- Lupa (<1400px, header.tpl): abre la capa de búsqueda. Mismo círculo
   de 36x36 que los iconos de cuenta y carrito. Va justo antes de ellos
   (order 3, y en el DOM antes que la cuenta) y es ella la que lleva ahora
   el margin-left:auto que empuja el grupo de iconos a la derecha, así que
   se le quita a la cuenta y al carrito para que no se reparta el hueco
   entre dos márgenes automáticos. --- */
.ritual-search-toggle{
  order:3;
}
.ritual-search-toggle__btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  padding:0;
  border:none;
  border-radius:50%;
  background:none;
  color:var(--ink);
  cursor:pointer;
  transition:background .2s ease;
}
.ritual-search-toggle__btn:hover{
  background:rgba(41,37,28,.07);
}
.ritual-search-toggle__btn .material-icons{
  font-size:22px;
}
@media (max-width: 1399.98px){
  .ritual-search-toggle{
    margin-left:auto;
  }
  #_desktop_ps_customersignin{
    margin-left:0;
  }
}
@media (max-width: 767.98px){
  #_desktop_ps_shoppingcart,
  #_mobile_ps_shoppingcart{
    margin-left:0;
  }
  /* Lupa + carrito a la derecha del logo centrado: con el gap de 1rem el
     grupo invadía el logo (max-width 9rem) en pantallas de 320px.
     Selector doble para ganar a .header-bottom__row{gap:1rem}, que va
     más abajo en este fichero. */
  .header-bottom .header-bottom__row{
    gap:.5rem;
  }
}
/* --- Blog en el menú de escritorio (ps_mainmenu.tpl, >=1400px): justo
   después de Contacto. Más pequeño, más fino y más espaciado que las
   categorías (.9rem/700, .85rem con la cabecera compacta) para que se lea
   como acceso secundario y no como una categoría más; el subrayado
   animado es el mismo de .ps-mainmenu__tree-link. Selector con tres
   clases para ganar a .header.is-stuck .ps-mainmenu__tree-link, que va
   más abajo en este fichero. Por debajo de 1400px va en el menú
   hamburguesa, junto a Contacto. --- */
.ps-mainmenu__tree .ps-mainmenu__tree-item--blog .ps-mainmenu__tree-link{
  font-size:.75rem!important;
  font-weight:500;
  letter-spacing:.08em;
}
/* ps_socialfollow shares displayNav2 with ps_customersignin (see
   header.tpl) — redes sociales solo en el footer, ver
   DOC-header-footer.md. */
.header-bottom .ps-socialfollow{
  display:none;
}

/* --- Sticky header: .is-stuck (plain "scrolled past 40px", toggled by
   custom.js) shrinks the single header row once the page has scrolled a
   bit — a lighter, more compact bar while browsing, instead of permanently
   reserving the full-height row's space. .header is position:sticky
   (hummingbird's own theme.css); overflow-anchor:none avoids the browser's
   scroll-anchoring feature nudging window.scrollY on its own whenever a
   layout shift happens near the top of a pinned element. --- */
.header{
  overflow-anchor:none;
}
.header.is-stuck .header-bottom{
  box-shadow:0 8px 26px rgba(0,0,0,.18);
}
.header.is-stuck .ps-mainmenu__tree-link{
  font-size:.85rem!important;
}
.header-bottom{
  transition:box-shadow .35s ease;
}
@media (prefers-reduced-motion: reduce){
  .header-bottom,
  .ps-mainmenu__tree-link{
    transition:none;
  }
}

/* --- Header row: gutter + no-wrap single row + full width (see
   header.tpl: header-bottom__container is now container-fluid, not
   container-md — see DOC-header-footer.md for why). --- */
.header-bottom__container{
  --bs-gutter-x:1rem;
}
.header-bottom__row{
  /* Bootstrap's own gx-2/gx-md-4 gutter classes (removed from header.tpl)
     add up to .75rem padding on EACH SIDE of every column at md+ — across
     ~7 items in this single dense row that's ~10.5rem of pure gutter,
     wide enough on its own to force horizontal overflow at normal desktop
     widths (1400-1440px). Zeroing --bs-gutter-x drops that column padding
     to 0, leaving a single flat 1rem gap between items instead — same
     spacing model DOC-header-footer.md specifies for this row. */
  --bs-gutter-x:0;
  gap:1rem;
  flex-wrap:nowrap;
}
.header-bottom__cta{
  /* hummingbird's own .ps-mainmenu{order:1} (vendor theme.css) puts the
     nav ahead of any plain order:0 sibling — without an explicit order
     here this CTA (default order:0, same as the logo) renders right
     after the logo and BEFORE the menu instead of at the row's right
     edge. 5 clears every other row item (logo 0, menu 1, search 2,
     account 3, cart 4 — see #_desktop_ps_customersignin/#_desktop_ps_shoppingcart). */
  order:5;
  margin-left:.5rem;
  white-space:nowrap;
  /* Same "row align-items-stretch" issue as #_desktop_ps_customersignin
     above, but worse here: this <a> IS the visible pill (not a wrapper
     around a small icon), so stretching it to the row's full height
     turned the pill itself into a tall rectangle instead of a compact
     button. Opt out of the stretch and size to its own content. */
  align-self:center;
}
/* --- Hamburger toggle: hummingbird's own theme.css hides it unconditionally
   from xl (1200px) up, assuming the desktop tree is always visible there.
   Since the tree now only shows from xxl (1400px, see ps_mainmenu.tpl),
   the toggle needs to stay visible through the 1200-1399px gap and only
   disappear at the new cut — same selector/specificity as the vendor
   rule, relying on custom.css loading after theme.css to win. --- */
@media (min-width: 1200px){
  .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__mobile-toggle{
    display:flex;
  }
}
@media (min-width: 1400px){
  .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__mobile-toggle{
    display:none;
  }
}
/* --- Mobile: center the logo over the row instead of letting it sit
   wherever flex would place it. Pulled out of flow with position:absolute
   so it centers regardless of how much the hamburger/icons weigh on each
   side. Search used to live in this row down to 768px and, at real phone
   widths, its icon cluster alone reached past the row's center no matter
   how small the logo got (see git history for that whole dead end) — since
   the search bar now leaves this row below 1400px (it lives in the search
   overlay, opened from a magnifier icon — see custom.js), the only things
   left here are the hamburger and the magnifier/account/cart icons, pushed into their own tight cluster on the right via
   margin-left:auto (see #_desktop_ps_customersignin/#_desktop_ps_shoppingcart
   above) instead of `justify-content:space-between`: with 3 small flex
   items spread across a wide row, space-between's middle item (account, at
   768px+) landed almost exactly at the row's horizontal center — right on
   top of the logo. No `justify-content` override needed here anymore; the
   row's default (flex-start) plus the icons' own auto margin is enough. --- */
@media (max-width: 1399.98px){
  .header-bottom__row{
    position:relative;
  }
  .header-bottom__logo{
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%, -50%);
    margin:0!important;
    z-index:2;
    pointer-events:none;
  }
  .header-bottom__logo a{
    pointer-events:auto;
  }
}
/* Account access now lives in the hamburger menu (Iniciar sesión/Su
   cuenta, next to Contacto) — this icon was only adding extra width
   between the search and cart icons for no remaining purpose.
   Needs @layer vendors (hummingbird's theme.css declares the master layer
   order as vendors, bs-base, ..., utilities — Bootstrap's .d-flex utility
   that's already on this element lives in that last "utilities" layer with
   display:flex!important): per the CSS cascade-layers spec, !important
   declarations reverse layer priority, so ANY layered !important beats an
   unlayered one regardless of specificity — a plain override here, even
   with !important, silently loses to .d-flex every time. Reusing the
   "vendors" name (the first-declared layer) instead of introducing a new
   one, since a layer only earns "first" priority from where it was FIRST
   declared across the whole page, not from this file's load order. */
@layer vendors{
  @media (max-width: 767.98px){
    #_mobile_ps_customersignin{
      display:none!important;
    }
  }
}
/* --- Floating WhatsApp button: hidden while the top bar (with its own
   WhatsApp link) is visible, shown once scroll hides it — synced to
   `.header.is-stuck` via custom.js. Fade + slide from the bottom edge. --- */
.ritual-whatsapp-float{
  position:fixed;
  right:1.25rem;
  bottom:1.25rem;
  z-index:1030;
  display:flex;
  align-items:center;
  justify-content:center;
  width:3.25rem;
  height:3.25rem;
  border-radius:50%;
  background:var(--ink);
  color:#fff;
  box-shadow:0 8px 20px rgba(0,0,0,.3);
  opacity:0;
  transform:translateY(1.5rem);
  pointer-events:none;
  /* bottom: sube por encima de la barra fija de la ficha de producto
     (.has-booking-sticky, más abajo). */
  transition:opacity .35s ease, transform .35s ease, background .25s ease, bottom .35s ease;
}
.ritual-whatsapp-float:hover{
  background:#000;
}
.ritual-whatsapp-float.is-visible{
  opacity:1;
  transform:translateY(0);
  pointer-events:auto;
}
@media (prefers-reduced-motion: reduce){
  .ritual-whatsapp-float{transition:none}
}

/* --- Footer: hummingbird's own .footer__main only sets background:var(--bs-dark)
   (bootstrap's generic near-black gray, not our brand ink) and .footer__before
   (displayFooterBefore: newsletter + trust badges) has no background rule at
   all, defaulting to the page's white body background — so the block above
   the dark footer showed as a mismatched white band. Both now use --ink, and
   text/links reset to pure white (the legacy site never used the gray tone
   hummingbird's scss applies to footer text). --- */
.footer__main,
.footer__before{
  background:var(--ink);
  color:#fff;
}
.footer__main .footer-block,
.footer__main .footer-block a,
.footer__before a{
  color:#fff;
}
.footer__main .footer-block a:hover,
.footer__before a:hover{
  color:#fff;
  text-decoration:underline;
}
.footer__main{
  position:relative;
}
.footer__main::before{
  content:"";
  display:block;
  height:4px;
  background:#fff;
  margin-bottom:1.5rem;
}
.footer__main-top{
  display:grid;
  grid-template-columns:1.1fr .85fr .85fr 1fr 1.4fr;
  gap:2rem;
}
.footer__main-top>[class*="col-"]{
  width:auto;
  max-width:none;
}
.footer-block__title{
  font-size:.8rem;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.06em;
  margin:0 0 1rem;
  color:#fff;
}
/* "Contacto" y "Categorías" son <p class="h3 footer-block__title">, no
   encabezados: .h3 les da el h3 de hummingbird y aquí la fuente que h1-h6
   toman de la regla general. Solo a esos dos: "La empresa" (ps_linklist)
   ya era un <p class="footer-block__title"> sin esa fuente. */
.h3.footer-block__title{
  font-family:"Tindoghouse",cursive;
}
#footer .ps-contactinfo__phone svg {
  margin-right: .5rem;
}

/* 5 columns: Marca / Categorías / La empresa / Contacto / Newsletter. Every
   hook-captured module is still a flat sibling in the DOM (ps_contactinfo,
   ps_linklist, ps_customeraccountlinks, ps_socialfollow all render via the
   same {hook h='displayFooter'} capture in footer.tpl), so — same
   technique as before this redesign — each one is placed with an explicit
   grid-column/row instead of relying on DOM order.
   Newsletter tenía antes su propia columna (col 5) compartida con Contacto
   apilada en 2 filas — eso dejaba la fila 1 llena y la fila 2 casi vacía
   (solo Contacto+Newsletter tenían algo ahí). Ahora Newsletter es una
   columna propia en la misma fila que el resto, sin fila 2 en desktop. */
.footer__main-top .ritual-footer-brand{
  grid-column:1;
  grid-row:1;
}
.footer__main-top .ritual-footer-categories{
  grid-column:2;
  grid-row:1;
}
.footer__main-top .ps-linklist{
  grid-column:3;
  grid-row:1;
}
.footer__main-top .ps-customeraccountlinks{
  grid-column:3;
  grid-row:2;
}
.footer__main-top .ps-contactinfo{
  grid-column:4;
  grid-row:1;
}
.footer__main-top .ritual-footer-newsletter{
  grid-column:5;
  grid-row:1;
}
/* ps_socialfollow is relocated into .ritual-footer-brand by custom.js (a
   shared grid row is only ever as tall as the tallest column, which left a
   gap between the tagline and the icons no matter what row we assigned) —
   once it's a normal flex child there it just needs its own spacing,
   handled below alongside the rest of the brand column's styles.
   ritualbienestar_workwithus's own footer link uses the exact same
   relocation trick (see custom.js): its <li> gets moved inside
   ps_linklist's own <ul>, so it's never a grid item here at all — no
   .ritualbienestar-workwithus-footer rule needed in this block. */

/* "La empresa" (ps_linklist) title text comes from the link block's own
   BO configuration (Diseño > Bloque de enlaces) — it was blanked out when
   this footer's mobile collapse-toggle was removed (see below) and needs
   to be set back to "La empresa" there for the <h3> to show; nothing to
   change here once it is. Style it the same as the other 3 columns'
   .footer-block__title without needing a class change on ps_linklist's
   own (vendor) template. */
.footer__main-top .ps-linklist h3{
  font-size:.8rem;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.06em;
  margin:0 0 1rem;
  color:#fff;
}
/* En el footer "Newsletter" es <p class="h2 ritual-newsletter-form__title">,
   no encabezado: el selector de clase gana a la regla de <p> de abajo, y
   la fuente y el line-height son los que tenía como h2. */
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .ritual-newsletter-form__title{
  font-family:"Tindoghouse",cursive;
  font-size:.8rem;
  font-weight:700;
  line-height:1.2;
  text-transform:uppercase;
  letter-spacing:.06em;
  margin:0 0 .35rem;
  color:#fff;
}
/* ps_emailsubscription's own template (.ritual-newsletter-form) está
   pensado para la sección clara "Tu opinión nos importa" de Home (caja
   blanca, texto/borde en --ink) — en este footer oscuro sería casi
   invisible. Igual que antes, se invierte a blanco sobre oscuro solo en
   este contexto, ahora apuntando a las clases del sistema compartido
   (.input-field__wrap/.input-field__control, .form-check-ritual__input/
   __label) en vez de a los selectores de tipo/atributo antiguos. */
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form p{
  font-size:.8rem;
  line-height:1.4;
  color:rgba(255,255,255,.6);
  margin:0 0 .85rem;
}
/* --- Rediseño (petición explícita del cliente): antes era un campo a todo
   lo ancho de la columna con el botón "¡Suscribirme!" en su propia fila
   debajo (mucha altura para lo que aporta, y aún peor ahora que la columna
   es más estrecha al ser una de 5 en vez de compartir fila con Contacto).
   Se pasa a email + botón en una sola línea, con la casilla de condiciones
   en letra pequeña debajo. El propio <form> es quien controla el orden
   (flex + order), no el HTML de ps_emailsubscription.tpl (que sigue
   poniendo el botón después del checkbox en el DOM) — así funciona igual
   si algún hook añade más contenido (displayNewsletterRegistration/
   displayGDPRConsent): todo lo que no sea el campo o el botón cae debajo,
   a todo lo ancho, sin tocar la plantilla del módulo. */
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form form{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.5rem .6rem;
  /* .ritual-newsletter-form form (regla global, para la sección centrada
     "Tu opinión nos importa" de Home) le fija max-width:24rem+margin:0
     auto — aquí, en la columna del footer, eso descentraba el bloque
     campo+botón respecto al resto de columnas (tituloo/párrafo sí ocupan
     todo el ancho, el <form> no). Se anula para que ocupe todo el ancho
     de la columna, alineado a la izquierda como el resto del footer. */
  max-width:none;
  margin:0;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form form>*{
  order:3;
  flex-basis:100%;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .input-field__wrap{
  order:1;
  /* El sistema compartido de formularios fija width:100% en .input-field__wrap
     (pensado para ir solo en su propia fila). Con flex-basis:auto eso se
     traduce en flex-basis:100% (auto usa el width), dejando al botón sin
     sitio en la misma línea y forzándolo a la de abajo. flex-basis:0
     ignora ese width heredado y reparte el espacio solo por flex-grow. */
  flex:1 1 0%;
  min-width:0;
  padding:.5rem .75rem;
  background:transparent;
  border-color:rgba(255,255,255,.4);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .input-field__wrap:hover:not(:focus-within){
  border-color:rgba(255,255,255,.6);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .input-field__wrap:focus-within{
  border-color:#fff;
  box-shadow:0 0 0 3px rgba(255,255,255,.15);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .input-field__control{
  color:#fff;
  font-size:.85rem;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .input-field__control::placeholder{
  color:rgba(255,255,255,.6);
}
/* Botón: icono real (material-icons "send", ver ps_emailsubscription.tpl)
   en vez de texto — cabe en la misma línea que el campo sin forzar el
   ancho de la columna. El texto "¡Suscribirme!" sigue en el DOM para
   lectores de pantalla, solo se oculta visualmente (misma técnica que
   .visually-hidden de Bootstrap). Acento en --brass en vez del --ink/
   blanco del resto de CTAs: es el único punto de color de la columna,
   ayuda a que el ojo encuentre el botón de "enviar". */
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .ritual-cta{
  order:2;
  flex:none;
  width:38px;
  height:38px;
  /* .ritual-newsletter-form .ritual-cta (regla global, pensada para el
     botón en su propia fila del bloque de Home) le mete margin-top:1.5rem
     — aquí el botón va al lado del campo, en la misma fila, así que ese
     margen lo empujaba hacia abajo y quedaba descuadrado con el input. */
  margin-top:0;
  padding:0;
  background:var(--brass);
  color:#fff;
  box-shadow:none;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .ritual-newsletter-form__submit-text{
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .ritual-newsletter-form__submit-icon{
  display:inline-block;
  font-size:18px;
  line-height:1;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .ritual-cta:hover{
  color:#fff;
  background:#c4a06a;
  transform:none;
  box-shadow:none;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual{
  align-items:center;
  margin-top:.6rem;
  margin-bottom:0;
  gap:.5rem;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual__input{
  width:1rem;
  height:1rem;
  margin-top:0;
  border-color:rgba(255,255,255,.6);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual__input:hover:not(:disabled):not(:checked){
  border-color:#fff;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual__input:checked{
  background:#fff;
  border-color:#fff;
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual__input:checked::after{
  border-color:var(--ink);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form .form-check-ritual__label{
  font-size:.7rem;
  line-height:1.35;
  color:rgba(255,255,255,.6);
}
.footer__main-top .ritual-footer-newsletter .ritual-newsletter-form__privacy a{
  color:rgba(255,255,255,.85);
}

/* Nota: aquí había un `.footer__main .footer-block__content.collapse{
   display:block!important}` que forzaba a mano la visibilidad del único
   bloque colapsable del footer (ps_linklist), y de paso rompía su propio
   toggle: bootstrap añadía/quitaba .show pero el contenido no podía
   ocultarse, así que el botón no hacía nada. Se ha quitado el acordeón
   entero en la plantilla hija de linkblock.tpl (sin <button> y sin clase
   .collapse), así que ya no hay nada que forzar: las listas del footer se
   ven siempre, en todos los breakpoints. Si algún día vuelve a aparecer un
   .collapse aquí, que venga con su toggle, no con otro !important. */
@media (max-width: 991.98px){
  .footer__main {
    padding-bottom: 5rem;
  }
  .footer__main-top{
    grid-template-columns:1fr 1fr;
    row-gap:3rem;
  }
  .footer__main-top .ritual-footer-brand{ grid-column:1; grid-row:1; }
  .footer__main-top .ritual-footer-categories{ grid-column:2; grid-row:1; }
  .footer__main-top .ps-linklist{ grid-column:1; grid-row:2; }
  .footer__main-top .ps-customeraccountlinks{ grid-column:1; grid-row:3; }
  .footer__main-top .ps-contactinfo{ grid-column:2; grid-row:2; }
  .footer__main-top .ritual-footer-newsletter{ grid-column:2; grid-row:3; }
}
@media (max-width: 575.98px){
  .footer__main-top{
    grid-template-columns:1fr;
  }
  .footer__main-top .ritual-footer-brand,
  .footer__main-top .ritual-footer-categories,
  .footer__main-top .ps-linklist,
  .footer__main-top .ps-customeraccountlinks,
  .footer__main-top .ps-contactinfo,
  .footer__main-top .ritual-footer-newsletter{
    grid-column:1;
    grid-row:auto;
  }
  /* En una sola columna el orden lo decide el auto-placement, o sea el
     orden del DOM, y ahí Categorías va detrás de todos los módulos del
     hook displayFooter y del bloque de marca — acababa la última del
     footer. `order` sí afecta al auto-placement de grid, así que la sube
     a la primera posición sin tener que fijar filas explícitas a los
     demás bloques (que son hooks y pueden aparecer/desaparecer). */
  .footer__main-top .ritual-footer-categories{
    order:-1;
  }
}

/* --- Social icons inside the footer: same white-outline/invert treatment
   as the top bar, reusing the exact rules from Task 3 scoped to .footer --- */
.footer .ps-socialfollow ul{
  display:flex;
  gap:.5rem;
  margin:.75rem 0 0;
  padding:0;
  list-style:none;
}
.footer .ps-socialfollow a{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:2.25rem;
  height:2.25rem;
  color:#fff;
  transition:opacity .2s ease;
}
.footer .ps-socialfollow a svg{
  width:19px;
  height:19px;
  fill:currentColor;
}
.footer .ps-socialfollow a:hover{
  opacity:.7;
  text-decoration:none;
}

/* --- Brand column: white logo, script tagline --- */
.ritual-footer-brand{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
}
.ritual-footer-brand__logo{
  height:64px;
  width:auto;
}
.ritual-footer-brand__tagline{
  display:block;
  margin-top:.75rem;
  font-family:"Angel Face",cursive;
  font-size:1.6rem;
  line-height:1.3;
  color:#fff;
}
.ritual-footer-brand .ps-socialfollow{
  margin-top:1rem;
}

/* --- Newsletter (displayFooterBefore): drop hummingbird's default
   bg-body-tertiary/btn-primary look (light gray box, blue button) so it
   reads as part of the same dark footer instead of an unbranded strip. --- */
.ritual-newsletter{
  color:#fff;
}
.ritual-newsletter .text-body-secondary{
  color:rgba(255,255,255,.75)!important;
}
.ritual-newsletter__submit{
  background:#fff;
  color:var(--ink);
  font-weight:700;
  border:none;
  transition:opacity .2s ease;
}
.ritual-newsletter__submit:hover{
  opacity:.85;
}

/* --- Trust badges (blockreassurance, displayFooterBefore): if configured
   with the module's own "light" variant, neutralize its background so it
   doesn't reintroduce a mismatched light patch; text follows the same
   white-only rule as the rest of the footer. --- */
.footer__before .blockreassurance--light{
  background:transparent;
}
.footer__before .blockreassurance,
.footer__before .reassurance__title,
.footer__before .reassurance__desc{
  color:#fff;
}

/* ==== Motion standard (home; reference for the next pages) ====
   - Scroll reveal: opacity 0 -> 1 plus a 1rem rise, 600ms, one easing for
     the whole page (soft ease-out, no bounce), once per element (custom.js
     stops observing after the first reveal). Photos only fade.
   - Stagger between siblings revealed together (cards, columns, list
     items): 120ms per step, capped at 360ms. Groups of more than four that
     appear at once spread the 360ms instead (step = 360ms / (n - 1)).
   - Hover on clickable elements: 400ms, same easing. Cards lift slightly
     (translateY), text links draw a brass underline, buttons lift 2px.
     Only transform/opacity move; colour changes (color, background-color,
     border-color, box-shadow) repaint but never reflow.
   - No parallax or other scroll-linked motion beyond the reveal.
   - prefers-reduced-motion: everything shows already visible, no
     transitions. Without JS nothing is ever hidden (see below). */
:root{
  --motion-duration:.6s;
  --motion-hover:.4s;
  --motion-ease:cubic-bezier(.33,0,.2,1);
  --motion-distance:1rem;
}

/* ==== Shared reveal-on-scroll utility ====
   Ships visible by default (nothing hidden if JS fails or doesn't load);
   custom.js adds reveal--pending to hide it, then is-visible once it
   scrolls into view. The final state is transform:none rather than
   translateY(0): a lingering transform would turn the element into the
   containing block of any position:fixed descendant (e.g. the reviews'
   "Ver más" popup, the newsletter privacy modal). */
.reveal{
  transition:opacity var(--motion-duration) var(--motion-ease), transform var(--motion-duration) var(--motion-ease);
}
.reveal.reveal--pending{
  opacity:0;
  transform:translateY(var(--motion-distance));
}
.reveal.is-visible{
  opacity:1;
  transform:none;
}
@media (prefers-reduced-motion: reduce){
  .reveal{
    transition:none;
  }
  .reveal.reveal--pending{
    opacity:1;
    transform:none;
  }
}
@media (max-width: 768px){
  .page-content--home{
    gap:0;
  }
}

/* ==== Homepage — Los más elegidos (4 servicios destacados) ====
   Right after the hero, before the reviews (_partials/home/featured.tpl).
   No images by design (there's no product photography anywhere in the
   shop), so each card gets its presence from type and air:
   - Hierarchy inside the card: name (Tindoghouse, small caps-size) →
     tagline in Angel Face as the largest, most evocative element → a
     hairline → duration + price pinned to the bottom (margin-top:auto on
     the rule, so all cards in a row align their meta regardless of how
     many lines the tagline takes).
   - Brass is a point accent only: the short segment of the hairline
     (grows to full width on hover), the price, and the arrow on hover.
   - Card surface: 1px faint ink hairline + --radius-md, semi-transparent
     white so the cream background shape shows through faintly. Hover
     turns it solid white with a brass-tinted hairline, a 4px lift and a
     barely-there shadow — all 600ms, no bounce. Hover styles only apply
     on devices that actually hover, so taps don't leave cards "stuck".
   - Weights inside the block: 400 (Tindoghouse, Angel Face, Helvetica) and
     700 (shared .ritual-section-kicker and the .btn-pill CTA) — no third.
   - Layout: 2 columns up to xxl (roomy cards, tagline breathes), 4 in a
     row from 1400px, stacked on phones.
   - The hero CTA (z-index:2, outside this section) still paints over the
     top edge; isolation:isolate keeps the shape's z-index:-1 inside here,
     and padding-top leaves room for the pill's lower half. */
/* Background shape fits whole vertically by construction, not by guessing
   the section's rendered height: the section's min-height is the shape's
   size plus 2rem each side, and its content is centered vertically, so any
   extra height needed is shared evenly above and below the cards (the 6rem
   padding stays as the minimum). When the cards already make the section
   taller than that, min-height simply has no effect. The shape is centered
   (-50%), and its path fits inside the circle inscribed in its square
   viewBox, so the -8deg tilt never pushes it past its own box vertically.
   Only the right edge clips it. */
.ritual-featured{
  --ritual-featured-shape:min(72vw, 960px);
  position:relative;
  isolation:isolate;
  overflow:hidden;
  display:flex;
  flex-direction:column;
  justify-content:center;
  min-height:calc(var(--ritual-featured-shape) + 4rem);
  padding:6rem 0;
  background:#fff;
}
.ritual-featured__shape{
  position:absolute;
  z-index:-1;
  top:50%;
  right:-20%;
  width:var(--ritual-featured-shape);
  height:auto;
  fill:var(--ritual-cream);
  transform:translateY(-50%) rotate(-8deg);
  pointer-events:none;
}
.ritual-featured__header{
  margin:0 0 3.5rem;
  text-align:center;
}
.ritual-featured__title{
  margin:0;
  font-size:2.5rem;
  color:var(--ink);
}
.ritual-featured__list{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:1.5rem;
  max-width:1120px;
  margin:0 auto;
  padding:0;
  list-style:none;
}
.ritual-featured__item{
  display:flex;
}
/* Card = versión sintetizada de .product-listing-item: mismo fondo crema
   rebajado y radio, sin borde. Orden: nombre → frase → pie de compra
   (precio + duración en una franja, y botones). El pie se va al fondo
   (margin-top:auto) solo para alinear los botones de una misma fila; la
   card no se estira más allá de su contenido, así que el hueco bajo la
   frase es solo la diferencia de líneas entre cards vecinas. */
.ritual-featured__card{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  width:100%;
  padding:2.25rem 2rem 2rem;
  border-radius:16px;
  background:#fbf8f5;
  background:color-mix(in srgb, var(--ritual-cream) 55%, #fff);
  color:var(--ink);
  transition:transform var(--motion-hover) var(--motion-ease), box-shadow var(--motion-hover) var(--motion-ease);
}
.ritual-featured__name{
  margin:0 0 .5rem;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:1.625rem;
  line-height:1.2;
}
/* Mismo tratamiento que .product-listing-item__name-link del listado. */
.ritual-featured__name-link{
  color:inherit;
  text-decoration:underline;
  text-decoration-color:transparent;
  text-decoration-thickness:1px;
  text-underline-offset:.2em;
  transition:color var(--motion-hover) var(--motion-ease), text-decoration-color var(--motion-hover) var(--motion-ease);
}
.ritual-featured__name-link:hover,
.ritual-featured__name-link:focus-visible{
  color:var(--brass);
  text-decoration-color:var(--brass);
}
.ritual-featured__name-link:focus-visible{
  outline:1px solid var(--brass);
  outline-offset:4px;
}
.ritual-featured__tagline{
  margin:0 0 1.25rem;
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:1.75rem;
  line-height:1.15;
  text-wrap:balance;
}
.ritual-featured__buy{
  width:100%;
  margin-top:auto;
  padding-top:1rem;
  border-top:1px solid rgba(41,37,28,.12);
}
.ritual-featured__facts{
  display:flex;
  align-items:flex-end;
  justify-content:space-between;
  flex-wrap:wrap;
  gap:.5rem 1rem;
  margin:0 0 1.25rem;
}
.ritual-featured__price{
  margin:0;
  line-height:1.1;
}
.ritual-featured__price-value{
  display:block;
  font-size:2rem;
  font-weight:400;
  color:var(--brass);
}
.ritual-featured__price-vat{
  display:block;
  margin-top:.2rem;
  font-size:.75rem;
  font-weight:400;
  opacity:.6;
}
.ritual-featured__duration{
  display:inline-flex;
  align-items:center;
  gap:.35rem;
  margin:0 0 .15rem;
  font-size:.75rem;
  font-weight:700;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--ink);
}
.ritual-featured__duration .material-icons{
  font-size:1rem;
  color:var(--brass);
}
.ritual-featured__actions{
  display:flex;
  flex-direction:column;
  gap:.625rem;
  width:100%;
}
.ritual-featured__form,
.ritual-featured__add,
.ritual-featured__book{
  width:100%;
}
.ritual-featured__add,
.ritual-featured__book{
  padding-left:1rem;
  padding-right:1rem;
}
/* Secundario sin sombra: la única píldora con relieve es la de reservar. */
.ritual-featured__add{
  box-shadow:none;
}
.ritual-featured__add:hover{
  box-shadow:none;
}
@media (hover: hover){
  .ritual-featured__card:hover{
    transform:translateY(-4px);
    box-shadow:0 16px 40px rgba(41,37,28,.08);
  }
  /* En promoción conserva el borde dorado al subir (ver --promo). */
  .ritual-featured__card--promo:hover{
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brass) 55%, transparent), 0 16px 40px color-mix(in srgb, var(--brass) 28%, transparent);
  }
}
.ritual-featured__footer{
  margin-top:3.5rem;
  text-align:center;
}
/* Reveal: shared .reveal utility (motion standard) per card, 120ms stagger. */
.ritual-featured__item.reveal:nth-child(4n+2){
  transition-delay:.12s;
}
.ritual-featured__item.reveal:nth-child(4n+3){
  transition-delay:.24s;
}
.ritual-featured__item.reveal:nth-child(4n+4){
  transition-delay:.36s;
}
@media (min-width: 1400px){
  .ritual-featured__list{
    grid-template-columns:repeat(4, minmax(0, 1fr));
    max-width:none;
  }
  .ritual-featured__card{
    padding:2rem 1.75rem 1.75rem;
  }
}
@media (max-width: 767.98px){
  .ritual-featured{
    padding:4rem 0;
  }
  /* Same size as before on phones; centered like desktop so the
     min-height guarantee above also holds on wide/landscape phones. */
  .ritual-featured{
    --ritual-featured-shape:160vw;
  }
  .ritual-featured__shape{
    right:-80%;
  }
  .ritual-featured__header{
    margin-bottom:2.5rem;
  }
  .ritual-featured__title{
    font-size:2rem;
  }
  .ritual-featured__name{
    font-size:1.5rem;
  }
  .ritual-featured__list{
    grid-template-columns:minmax(0, 1fr);
    gap:1rem;
  }
  .ritual-featured__card{
    padding:1.75rem 1.25rem 1.5rem;
  }
  .ritual-featured__tagline{
    margin-bottom:1.5rem;
    font-size:1.625rem;
  }
  .ritual-featured__footer{
    margin-top:2.5rem;
  }
  /* Right at the fold on phones — a rise during initial layout/font
     settling reads as a glitch. Fade only here. */
  .ritual-featured__item.reveal.reveal--pending{
    transform:none;
  }
}
@media (prefers-reduced-motion: reduce){
  .ritual-featured__card,
  .ritual-featured__name-link{
    transition:none;
  }
  .ritual-featured__card:hover{
    transform:none;
  }
}

/* ==== Homepage — shared section kicker (small uppercase label above section titles) ==== */
.ritual-section-kicker{
  margin:0 0 .5rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--ink);
  opacity:.6;
}
/* ==== Homepage — type standard (reference for every home section) ====
   Taken from the redesigned sections (featured, ¿Es para ti?, Para regalar,
   Nuestra esencia, team intro) and applied across the whole home:
   - Kicker / small label: Helvetica 700, .72rem, .12em, uppercase, ink .6
     (.ritual-section-kicker above).
   - Section title (h2): Tindoghouse 400, 2.5rem (2rem on phones), line-height
     1.2, no uppercase, --ink.
   - Item title (pillar, card name): Tindoghouse 400, 1.625rem (1.5rem on
     phones), line-height 1.2, no uppercase, --ink.
   - Body: Helvetica 400, 1.0625rem (1rem on phones), line-height 1.7, --ink,
     1rem between consecutive paragraphs.
   - Highlighted text: Helvetica 400, 1.25rem (1.125rem on phones),
     line-height 1.5, --ink.
   - Brand script (Angel Face), one highlighted phrase at a time: 400,
     clamp(2rem, 2.8vw, 2.5rem) (1.875rem on phones), line-height 1.15,
     --ink. Display-size closing line ("Aquí tienes tu refugio.") is the
     one larger exception.
   - Meta / legal text: Helvetica 400, .8125rem, line-height 1.4, ink .6.
   - Text link / CTA: Helvetica 400, .8125rem, .14em, uppercase, --ink,
     brass underline.
   Section-specific compositions keep their own sizes (featured card price
   and duration, the "Para regalar" cadence, the narrative fondo/encima
   titles). */

/* ==== Extensiones del estándar (categoría/subcategoría) ====
   Solo comentario: los valores viven en cada regla. Se anotan aquí porque
   son tipos de elemento que la home no tenía y que las páginas siguientes
   (ficha de producto, checkout) se van a encontrar igual.

   - Titular de página interior (h1 de categoría): Tindoghouse 400, 3.5rem
     (2.25rem en móvil), line-height 1.2, --ink. La home solo define dos
     pasos de titular (sección 2.5rem, elemento 1.625rem) porque no los
     necesita más; una página de categoría necesita tres, porque la
     cabecera de grupo de subcategoría se intercala entre el h1 y el nombre
     de producto. La escala queda 3.5 / 2.5 / 1.625, con los dos pasos de
     abajo tomados tal cual del estándar y solo el h1 como paso nuevo.
   - Dato (duración): Helvetica 400, .9375rem, line-height 1.4, --ink, con
     su etiqueta en el paso de antetítulo (.72rem/700/.12em/mayúsculas/ink
     al 60%). Es el par "etiqueta + valor" que la home resuelve dentro de
     la composición de su card y aquí necesita nombre propio.
   - Dato destacado (precio): Helvetica 400, 2.25rem (2rem en móvil),
     line-height 1.1, --brass, misma etiqueta de antetítulo encima. El
     precio de la home (1.125rem) es parte de una card compacta y sigue
     exento como composición propia; este es el precio como dato principal
     de un bloque.
   - Precio tachado: Helvetica 400, 1.125rem, --ink al 50%, line-through.
   - Metadato accionable: el metadato del estándar (.8125rem/1.4/ink al
     60%/400) cuando además es enlace — conserva subrayado permanente y
     pasa a --brass al hover, en vez de adoptar el enlace de texto, que a
     igual tamaño y en mayúsculas compite con el CTA que tiene al lado.
     Lo usan "¡Reserva tu cita ahora!" y los enlaces de la línea de
     contacto.

   body ya lleva color:var(--ink) y font-weight:400, y las variables de
   gris de Bootstrap apuntan a --ink (ver arriba del todo), así que un
   elemento nuevo ya no cae al #212529 ni a Light por omisión. */

/* ==== Extensiones del estándar (páginas transaccionales y de contenido) ====
   Checkout, confirmación de pedido, Mi cuenta, login/registro/contraseña,
   búsqueda, CMS, "Trabaja con nosotros", 404 y la landing de reservas.
   Como las de categoría, solo comentario: los valores viven en cada regla.

   - Titular de página interior: se aplica a h1.page-title-section, el h1
     que hummingbird pinta en todas las páginas que no tienen cabecera
     propia (antes a clamp(1.5rem, …, 2rem)). "Trabaja con nosotros" baja a
     2rem: su h1 va en una columna de 36rem y a 3.5rem se partía en tres
     líneas (a 2rem cabe en una: 556px medidos con las métricas de la
     fuente, que no tiene kerning).
   - Titular de modal (checkout, cuenta, confirmación): el paso de titular
     de elemento, 1.625rem (1.5rem en móvil). El .modal-title genérico
     sigue en 2rem para el resto del sitio.
   - Cabecera de tabla: el antetítulo tal cual (Helvetica 700, .72rem,
     .12em, mayúsculas, --ink al 60%). También los titulares funcionales
     del checkout ("Cupones y tarjetas regalo", "Datos personales", "Pago")
     y la palabra "Total".
   - Código / referencia (código de compra, referencia de pedido):
     antetítulo con cifras tabulares. Se lee como identificador, no como
     texto.
   - Estado (reservado, entregado en mano, ya no se puede modificar,
     "Quedan 2 de 5 usos" en la landing de reservas — en las filas de Mi
     cuenta "Usos restantes" es una celda más y va en dato): Helvetica 700,
     .72rem, .12em, mayúsculas,
     --ink pleno — el antetítulo sin la rebaja al 60%, porque aquí la
     etiqueta es la información. Variante de error en --color-error.
     Cuando el estado es una frase entera (p. ej. "No hemos podido
     confirmar la hora que elegiste") no va en mayúsculas: usa el mensaje
     de validación.
   - Badge ("Regalo", código de cupón aplicado): la tipografía de estado
     dentro de la píldora. Unifica los tres valores que había (.65rem/.03em,
     .7rem/.04em y .75–.8rem/.02em). Forma y colores de cada badge no
     cambian.
   - Total: la palabra "Total" en cabecera de tabla y el importe en
     Helvetica 400, 1.5rem, line-height 1.2, --brass, cifras tabulares. Es
     información de cierre: un paso por debajo del dato destacado (2.25rem,
     reservado al precio de la ficha como reclamo comercial).
   - Dato en filas y tablas (servicio, precio, fecha de cita, descuento):
     el dato del estándar (.9375rem, line-height 1.4, 400) con cifras
     tabulares en importes y fechas.
   - Etiqueta de campo (label de formulario): Helvetica 700, .72rem, .04em,
     mayúsculas, --ink pleno. Tipo propio, no antetítulo: una etiqueta de
     campo necesita contraste pleno y el tracking corto de un control. Es el
     valor que ya tenían .input-field__label y las etiquetas del core en
     login/registro/checkout/Mi cuenta; solo se formaliza.
   - Ayuda de formulario (.form-text, requisitos de contraseña, pistas como
     "Y ahorra tiempo en tu próximo pedido"): el metadato (.8125rem,
     line-height 1.4, 400, --ink al 60%).
   - Texto de casilla (label de checkbox/radio): 400 en estas páginas en vez
     del 300 de .form-check-ritual__label, que no se toca de forma global.
     Si la casilla es un consentimiento (condiciones, privacidad, ofertas),
     usa el texto legal (.8125rem/1.4/400/--ink al 60%) y su enlace, el
     metadato accionable.
   - Mensaje de validación (errores de campo del core, avisos de error de
     formulario, frases de estado de error): el metadato a opacidad plena
     en --color-error (.8125rem, line-height 1.4, 400).
   - Enlaces secundarios de formulario ("¿Has olvidado tu contraseña?",
     "Usar contraseña", "¿Ya tienes cuenta? Iniciar sesión"): metadato
     accionable. "Volver al inicio de sesión", "Ver todas", "← Elegir otra
     experiencia" y las pestañas de Mi cuenta son navegación: enlace de
     texto (.8125rem, 400, .14em, mayúsculas).
   - Contenido legal largo (páginas CMS y la política de privacidad dentro
     del modal de "Trabaja con nosotros"): cuerpo del estándar (1.0625rem/
     1.7, 1rem en móvil, 1.5rem entre párrafos, como la descripción de la
     ficha); h2 como titular de elemento (1.625rem/1.5rem) — con hasta 15
     por página, el titular de sección pesaría demasiado —; h3 como en la
     descripción de la ficha (Helvetica 700, 1.25rem/1.125rem, line-height
     1.5); negrita 700; enlaces subrayados en --ink que pierden el
     subrayado al hover, igual que en la descripción de la ficha. */

/* ==== Homepage — narrative trio (Lo que hacemos / Qué es Ritual / Ciencia) ==== */
.ritual-narrative{
  padding:4rem 0;
}
.ritual-narrative--a{
  background:#fff;
}
.ritual-narrative--b{
  background:var(--ritual-cream);
}
.ritual-narrative__row{
  display:grid;
  grid-template-columns:minmax(0, 5fr) minmax(0, 5fr);
  gap:3rem;
  align-items:center;
}
/* Title block recreates the legacy .titulo-fondo/.titulo-encima overlap:
   a large pale title (fondo) with a smaller ink title pulled up on top of
   it via negative margin (not position:relative like the legacy CSS, so
   the reserved space collapses instead of leaving a gap below). Mirrored
   to the right instead of the legacy site's left placement. */
.ritual-narrative__title-block{
  text-align:right;
}
.ritual-narrative--a .ritual-narrative__title-block{
  order:-1;
  text-align:left;
}
.ritual-narrative__title-fondo{
  margin:0;
  font-size:3.75rem;
  line-height:1.05;
  color:rgba(41,37,28,.15);
  text-transform:uppercase;
}
.ritual-narrative__title-encima{
  font-family:"Tindoghouse",cursive;
  font-size:1.35rem;
  color:var(--ink);
  text-transform:uppercase;
  letter-spacing:.02em;
}
@media (max-width: 768px){
  .ritual-narrative{
    padding:2rem 0;
  }
  .ritual-narrative__row{
    grid-template-columns:1fr;
    gap:2rem;
  }
  .ritual-narrative__title-block{
    order:-1;
    text-align:left;
  }
  .ritual-narrative__title-fondo{
    font-size:2.5rem;
  }
  .ritual-narrative__title-encima{
    font-size:1.1rem;
  }
  .ritual-narrative__body p{
    font-size:1rem;
  }
  .ritual-narrative__body .ritual-narrative__lines:last-child{
    margin-bottom:0;
  }
}
.ritual-pull-quote{
  margin:1.5rem 0;
  padding-left:1.25rem;
  border-left:2px solid var(--ink);
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:1.25rem;
  font-style:italic;
  line-height:1.5;
}
.ritual-narrative p{
  font-weight:300;
  line-height:1.7;
}
/* Reveal (motion standard): the title block and each block of the body
   reveal on their own; body blocks lag 120ms each, capped at 360ms. */
.ritual-narrative__body > .reveal:nth-child(1){
  transition-delay:.12s;
}
.ritual-narrative__body > .reveal:nth-child(2){
  transition-delay:.24s;
}
.ritual-narrative__body > .reveal:nth-child(n+3){
  transition-delay:.36s;
}
/* Body paragraphs follow the home type standard; the fondo/encima titles and
   the pull-quote keep their own treatment. */
.ritual-narrative__body p{
  color:var(--ink);
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
.ritual-narrative__lines{
  margin:1.25rem 0;
}
.ritual-narrative__lines p{
  margin:0 0 .35rem;
}
.ritual-narrative__lines p:last-child{
  margin-bottom:0;
}

/* ==== Homepage — Reseñas (ritualbienestar_sitereviews, via displayHome) ====
   Right after Los más elegidos. The module's own CSS leaves the section
   without a background and with 40px of vertical padding; here it becomes
   a cream band for the white/cream alternation of the home order
   (featured, white, above; ¿Es para ti?, white, below), with the same 4rem
   vertical rhythm as its neighbours on desktop. Phones keep the module's
   40px. custom.css loads after the module CSS, so same-specificity rules
   win without touching the module. */
.ritualbienestar-sitereviews{
  padding:4rem 0;
  background:var(--ritual-cream);
}
@media (max-width: 768px){
  .ritualbienestar-sitereviews{
    padding:40px 0;
  }
}
/* Type standard applied to the module's own text (same specificity as the
   module CSS, which loads earlier). */
.ritualbienestar-sitereviews__title{
  color:var(--ink);
}
.ritualbienestar-sitereviews__subtitle{
  color:var(--ink);
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.25rem;
  font-weight:400;
  line-height:1.5;
}
.ritualbienestar-sitereviews__name{
  color:var(--ink);
}
.ritualbienestar-sitereviews__summary{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:center;
  gap:.5rem .75rem;
  margin:0 0 2rem;
  color:var(--ink);
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
}
.ritualbienestar-sitereviews__summary-rating{
  font-size:1.75rem;
  font-weight:700;
}
.ritualbienestar-sitereviews__summary-score{
  display:inline-flex;
  align-items:center;
  gap:.5rem;
  white-space:nowrap;
}
.ritualbienestar-sitereviews__summary-stars{
  letter-spacing:.1em;
}
@media (max-width: 768px){
  /* Phones: score + stars on one line, total on its own line below. */
  .ritualbienestar-sitereviews__summary{
    flex-direction:column;
    gap:.25rem;
    margin-bottom:1.5rem;
    padding-inline:1.25rem;
    text-align:center;
    font-size:1rem;
  }
  .ritualbienestar-sitereviews__summary-rating{
    font-size:1.5rem;
  }
  .ritualbienestar-sitereviews__summary-stars{
    font-size:1rem;
    letter-spacing:.05em;
  }
}
.ritualbienestar-sitereviews__text,
.ritualbienestar-sitereviews__more-panel p:not(.ritualbienestar-sitereviews__name){
  color:var(--ink);
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
.ritualbienestar-sitereviews__local-guide,
.ritualbienestar-sitereviews__count,
.ritualbienestar-sitereviews__date{
  color:rgba(41,37,28,.6);
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
}
.ritualbienestar-sitereviews__more-toggle{
  position:relative;
  display:inline-block;
  padding-bottom:.35rem;
  color:var(--ink);
  font-size:.8125rem;
  font-weight:400;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-decoration:none;
}
/* Same hover as the home's text links: a brass underline that draws out. */
.ritualbienestar-sitereviews__more-toggle::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:var(--brass);
  transform:scaleX(.3);
  transform-origin:left center;
  transition:transform var(--motion-hover) var(--motion-ease);
}
@media (hover: hover){
  .ritualbienestar-sitereviews__more-toggle:hover::after{
    transform:scaleX(1);
  }
}
#ritualbienestar-sitereviews-carousel .carousel-control-prev,
#ritualbienestar-sitereviews-carousel .carousel-control-next{
  transition:opacity var(--motion-hover) var(--motion-ease);
}
/* Reveal (motion standard): title, subtitle 120ms later, carousel 240ms
   later and fade-only — no transform on the carousel, so its fixed "Ver
   más" popup is never trapped inside a transformed ancestor. */
.ritualbienestar-sitereviews__subtitle.reveal{
  transition-delay:.12s;
}
#ritualbienestar-sitereviews-carousel.reveal{
  transition-delay:.24s;
}
#ritualbienestar-sitereviews-carousel.reveal.reveal--pending{
  transform:none;
}
@media (prefers-reduced-motion: reduce){
  .ritualbienestar-sitereviews__more-toggle::after,
  #ritualbienestar-sitereviews-carousel .carousel-control-prev,
  #ritualbienestar-sitereviews-carousel .carousel-control-next{
    transition:none;
  }
}
@media (max-width: 768px){
  .ritualbienestar-sitereviews__title{
    font-size:2rem;
  }
  .ritualbienestar-sitereviews__subtitle{
    /* The module pads the subtitle 4rem on each side (desktop framing); on a
       375px screen that left the line in ~247px. Match the container gutter
       instead. */
    padding-inline:1.25rem;
    font-size:1.125rem;
  }
  .ritualbienestar-sitereviews__text,
  .ritualbienestar-sitereviews__more-panel p:not(.ritualbienestar-sitereviews__name){
    font-size:1rem;
  }
}

/* ==== Homepage — Este espacio es para ti si... ("¿Es para ti?") ====
   (_partials/home/for-you.tpl) Breaks the text-left/image-right pattern
   used by the rest of the home:
   - Desktop (>=992px): the photo bleeds off the LEFT edge of the viewport
     (square left corners, 16px radius on the right) and is inset top and
     bottom by the same 6rem as the text padding, so it spans exactly from
     the kicker to the CTA. Its height always follows the text column
     (object-fit:cover), so neither side is left with dead space. The text
     column's right edge lines up with the regular .container of the rest of
     the home via --for-you-edge: same max-widths as .container per
     breakpoint, plus its 1.25rem inner padding (this theme's 2.5rem
     --bs-gutter-x, see "Wider side gutters" above, halved).
   - The 6 items are equals (all reasons this space is for you), so they
     share one treatment: --ink, a size just above body copy and a short
     brass rule above each, in a 2-column grid of 3 rows (a single column at
     992-1199px, where the text column is narrow, and on phones). They gain
     presence from type, colour and air, not containers. "Aquí tienes tu
     refugio." closes in Angel Face at display size, then a quiet text CTA
     whose brass underline draws out on hover.
   - White background, for the white/cream alternation of the home order:
     reviews (cream) above, Regalar (cream) below.
   - Weights: 400 (Helvetica, Tindoghouse, Angel Face) plus 700 in the
     shared kicker only. No check icons.
   - Motion: each block reveals on its own as it enters (shared .reveal),
     600ms on a soft curve; the right-hand item of each grid row lags 120ms.
     The photo only fades. prefers-reduced-motion turns all of it off.
   - Below 992px: stacked, photo first as a full-bleed band (the -mobile
     crop is landscape, made for this) so the section opens with a visual
     pause before the text. */
.ritual-for-you{
  --for-you-container:1320px;
  --for-you-edge:max(1.25rem, calc((100vw - var(--for-you-container)) / 2 + 1.25rem));
  display:grid;
  grid-template-columns:minmax(0, 5fr) minmax(0, 7fr);
  background:#fff;
}
.ritual-for-you__media{
  position:relative;
  margin:6rem 0;
  overflow:hidden;
  border-radius:0 16px 16px 0;
}
.ritual-for-you__img{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:50% 40%;
}
.ritual-for-you__content{
  padding:6rem var(--for-you-edge) 6rem clamp(3rem, 6vw, 6.5rem);
}
.ritual-for-you__header{
  margin:0 0 2.5rem;
}
.ritual-for-you__title{
  margin:0;
  font-size:2.5rem;
  color:var(--ink);
}
.ritual-for-you__list{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:3rem;
  margin:0;
  padding:0;
  list-style:none;
}
.ritual-for-you__item{
  position:relative;
  margin:0;
  padding-top:1.25rem;
  color:var(--ink);
  font-weight:400;
  font-size:clamp(1.125rem, 1.35vw, 1.25rem);
  line-height:1.5;
}
.ritual-for-you__item::before{
  content:"";
  position:absolute;
  top:0;
  left:0;
  width:2.5rem;
  height:2px;
  background:var(--brass);
}
.ritual-for-you__closing{
  margin-top:2.75rem;
}
.ritual-for-you__refuge{
  margin:0 0 2rem;
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:clamp(3rem, 5vw, 4.5rem);
  line-height:1.05;
  color:var(--ink);
}
.ritual-for-you__cta{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:.75rem;
  padding-bottom:.6rem;
  color:var(--ink);
  font-size:.8125rem;
  font-weight:400;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-decoration:none;
}
.ritual-for-you__cta:hover,
.ritual-for-you__cta:focus-visible{
  color:var(--ink);
}
.ritual-for-you__cta:focus-visible{
  outline:1px solid var(--brass);
  outline-offset:.4rem;
}
.ritual-for-you__cta::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:var(--brass);
  transform:scaleX(.3);
  transform-origin:left center;
  transition:transform var(--motion-hover) var(--motion-ease);
}
.ritual-for-you__cta-arrow{
  flex:none;
  opacity:.6;
  transition:transform var(--motion-hover) var(--motion-ease), opacity var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease);
}
.ritual-for-you__cta:focus-visible::after{
  transform:scaleX(1);
}
.ritual-for-you__cta:focus-visible .ritual-for-you__cta-arrow{
  opacity:1;
  color:var(--brass);
}
@media (hover: hover){
  .ritual-for-you__cta:hover::after{
    transform:scaleX(1);
  }
  .ritual-for-you__cta:hover .ritual-for-you__cta-arrow{
    opacity:1;
    color:var(--brass);
    transform:translateX(4px);
  }
}
/* Reveal: shared .reveal utility (motion standard) per block; the photo only
   fades (no rise under its rounded, clipped frame). */
.ritual-for-you__media.reveal.reveal--pending{
  transform:none;
}
@media (min-width: 1200px), (min-width: 768px) and (max-width: 991.98px){
  .ritual-for-you__item.reveal:nth-child(even){
    transition-delay:.12s;
  }
}
@media (max-width: 1399.98px){
  .ritual-for-you{
    --for-you-container:1140px;
  }
}
@media (max-width: 1199.98px){
  .ritual-for-you{
    --for-you-container:960px;
  }
  .ritual-for-you__list{
    grid-template-columns:minmax(0, 1fr);
    gap:2.25rem;
  }
}
@media (max-width: 991.98px){
  .ritual-for-you{
    --for-you-container:720px;
    grid-template-columns:minmax(0, 1fr);
  }
  .ritual-for-you__media{
    margin:0;
    border-radius:0;
    aspect-ratio:16 / 9;
    max-height:32rem;
  }
  .ritual-for-you__img{
    object-position:50% 35%;
  }
  .ritual-for-you__content{
    padding:3.5rem var(--for-you-edge) 4rem;
  }
  .ritual-for-you__list{
    grid-template-columns:repeat(2, minmax(0, 1fr));
    gap:2.75rem 2.5rem;
  }
}
@media (max-width: 767.98px){
  .ritual-for-you{
    --for-you-container:540px;
  }
  .ritual-for-you__media{
    aspect-ratio:360 / 228;
  }
  .ritual-for-you__img{
    object-position:50% 50%;
  }
  .ritual-for-you__content{
    padding-top:3rem;
    padding-bottom:3.5rem;
  }
  .ritual-for-you__header{
    margin-bottom:2rem;
  }
  .ritual-for-you__title{
    font-size:2rem;
  }
  .ritual-for-you__list{
    grid-template-columns:minmax(0, 1fr);
    gap:2.25rem;
  }
  .ritual-for-you__closing{
    margin-top:2.25rem;
  }
  .ritual-for-you__refuge{
    margin-bottom:1.5rem;
    font-size:2.75rem;
  }
}
@media (max-width: 575.98px){
  .ritual-for-you{
    --for-you-container:100vw;
  }
}
@media (prefers-reduced-motion: reduce){
  .ritual-for-you__cta::after,
  .ritual-for-you__cta-arrow{
    transition:none;
  }
  .ritual-for-you__cta:hover .ritual-for-you__cta-arrow{
    transform:none;
  }
}

/* ==== Homepage — Regalar un ritual ====
   (_partials/home/gift.tpl) The home's only real conversion CTA and the way
   into gift cards. One compact block that reads as a single unit:
   - Two columns of similar height, vertically centered against each other,
     inside the regular .container. Main (7fr): kicker, title, opening quote
     and the six short chained sentences as ONE continuous cascade. Aside
     (5fr): the photo at a contained 4:3 (framed on the face and hands),
     then the closing paragraph and the single CTA, right after the copy
     has given its reasons.
   - Cascade: every line steps in 1.25rem further than the one before and
     grows a little, with a slightly larger gap where the copy's second
     group starts ("No es sólo un bono."), ending on "…o incluso a ti mism@."
     in Angel Face. Indents are padding on each line, so a wrapped line keeps
     its step. Below 768px the indents go (lines flush left), only the size
     steps remain. Lines reveal one after another (120ms apart).
   - Single CTA: brass pill (same .btn-pill--brass as the hero CTA).
   - Background stays cream: ¿Es para ti? (white) above; Nuestra esencia,
     also cream, below (see there for why).
   - Weights: 400 everywhere; 700 only in the shared kicker and the pill.
   - Below 992px: stacked in reading order, with the closing paragraph and
     CTA moved before the photo (shown uncropped) so the CTA isn't pushed
     further down.
   - Motion: 600ms reveals on a soft curve, the photo only fades;
     prefers-reduced-motion turns all of it off. */
.ritual-gift{
  padding:6rem 0;
  background:var(--ritual-cream);
}
.ritual-gift__layout{
  display:grid;
  grid-template-columns:minmax(0, 7fr) minmax(0, 5fr);
  column-gap:5rem;
  align-items:center;
}
.ritual-gift__intro{
  margin:0 0 2.5rem;
}
.ritual-gift__title{
  margin:0 0 1.25rem;
  font-size:2.5rem;
  color:var(--ink);
}
.ritual-gift__quote{
  max-width:32rem;
  margin:0;
  color:var(--ink);
  font-size:1.25rem;
  font-weight:400;
  line-height:1.5;
}
.ritual-gift__cadence{
  display:flex;
  flex-direction:column;
  gap:.85rem;
}
.ritual-gift__line{
  margin:0;
  color:var(--ink);
  font-size:1.125rem;
  font-weight:400;
  line-height:1.35;
}
.ritual-gift__line:nth-child(2){
  padding-left:1.25rem;
}
.ritual-gift__line:nth-child(3){
  margin-top:.75rem;
  padding-left:2.5rem;
  font-size:1.25rem;
}
.ritual-gift__line:nth-child(4){
  padding-left:3.75rem;
  font-size:1.375rem;
}
.ritual-gift__line:nth-child(5){
  padding-left:5rem;
  font-size:1.5rem;
}
.ritual-gift__line--peak{
  margin-top:.5rem;
  padding-left:6.25rem;
  font-family:"Angel Face",cursive;
  font-size:clamp(2rem, 2.8vw, 2.5rem);
  line-height:1.15;
  text-wrap:balance;
}
.ritual-gift__aside{
  display:flex;
  flex-direction:column;
  gap:2rem;
}
.ritual-gift__media{
  overflow:hidden;
  border-radius:16px;
}
.ritual-gift__img{
  display:block;
  width:100%;
  height:auto;
  aspect-ratio:4 / 3;
  object-fit:cover;
  object-position:72% 50%;
}
.ritual-gift__closing-text{
  margin:0 0 1.75rem;
  color:var(--ink);
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
.ritual-gift__cta{
  padding:1rem 2.5rem;
  font-size:.95rem;
}
/* Reveal: shared .reveal utility (motion standard) per block and per line;
   the six cascade lines spread the 360ms cap (72ms per step). The photo
   only fades (no rise inside its clipped frame). */
.ritual-gift__media.reveal.reveal--pending{
  transform:none;
}
.ritual-gift__line.reveal:nth-child(2){
  transition-delay:.072s;
}
.ritual-gift__line.reveal:nth-child(3){
  transition-delay:.144s;
}
.ritual-gift__line.reveal:nth-child(4){
  transition-delay:.216s;
}
.ritual-gift__line.reveal:nth-child(5){
  transition-delay:.288s;
}
.ritual-gift__line.reveal:nth-child(6){
  transition-delay:.36s;
}
@media (max-width: 991.98px){
  .ritual-gift__layout{
    grid-template-columns:minmax(0, 1fr);
    row-gap:3rem;
  }
  .ritual-gift__aside{
    gap:2.5rem;
  }
  .ritual-gift__closing{
    order:-1;
  }
  .ritual-gift__img{
    aspect-ratio:773 / 382;
    object-position:50% 50%;
  }
}
@media (max-width: 767.98px){
  .ritual-gift{
    padding:4rem 0;
  }
  .ritual-gift__layout{
    row-gap:2.5rem;
  }
  .ritual-gift__intro{
    margin-bottom:2rem;
  }
  .ritual-gift__title{
    font-size:2rem;
  }
  .ritual-gift__quote{
    font-size:1.125rem;
  }
  .ritual-gift__cadence{
    gap:.7rem;
  }
  .ritual-gift__line{
    font-size:1.0625rem;
  }
  .ritual-gift__line:nth-child(2){
    padding-left:0;
  }
  .ritual-gift__line:nth-child(3){
    margin-top:.5rem;
    padding-left:0;
    font-size:1.125rem;
  }
  .ritual-gift__line:nth-child(4){
    padding-left:0;
    font-size:1.25rem;
  }
  .ritual-gift__line:nth-child(5){
    padding-left:0;
    font-size:1.375rem;
  }
  .ritual-gift__line--peak{
    padding-left:0;
    font-size:1.875rem;
  }
  .ritual-gift__aside{
    gap:2rem;
  }
  .ritual-gift__closing-text{
    margin-bottom:1.5rem;
    font-size:1rem;
  }
  .ritual-gift__cta{
    padding:.85rem 2rem;
    font-size:.85rem;
  }
}

/* ==== Homepage — Nuestra esencia + Nuestros pilares ====
   (_partials/home/essence-pillars.tpl) Replaces the separate Pilares and
   Nuestra esencia sections: both said what the brand believes in, so they
   now read as one block with three clear levels, all original copy kept:
   1. Misión / Visión: short framing intro under the section title, two
      narrow columns at body size with small uppercase labels. Least weight.
   2. Nuestros pilares: the main element. Its own kicker + (smaller) title,
      three wide columns with brass icons, Tindoghouse titles, larger text.
   3. Valores: a compact secondary row of five, no cards: small ink icon
      (one redrawn family), name and one line, introduced by a short
      centered hairline.
   The air between levels (5rem before the pillars, 3.5rem before the
   values) does the separating, not boxes.
   - Pillars: from 992px the three columns share rows through subgrid (icon,
     title, first and second paragraph each line up across columns), so the
     block reads aligned even though "Presencia real" runs longer. The values
     divider is a short centered rule rather than a full-width line, so the
     columns' uneven last lines aren't measured against a long edge.
   - Cream background. With the home order fixed, one repeat is unavoidable
     here (Regalar, cream, above; the first narrative block, white, below).
     Cream sits next to Regalar instead of white next to the narrative
     block: on desktop the home's 2.5rem white gap still separates two cream
     sections, whereas white would fuse with the narrative block entirely.
   - Weights: 400, plus 700 in the shared kicker, labels and value names.
   - Motion: header, intro and every item reveal on their own (600ms, soft
     curve); items in a row lag slightly. Reduced motion turns it off.
   - Below 992px the pillars stack and the values wrap 3 + 2; on phones the
     values become a compact single-column list (icon beside name + line)
     instead of a cramped grid of five. */
.ritual-essence{
  padding:6rem 0;
  background:var(--ritual-cream);
}
.ritual-essence__header{
  max-width:46rem;
  margin:0 auto 2.5rem;
  text-align:center;
}
.ritual-essence__title{
  margin:0;
  font-size:2.5rem;
  color:var(--ink);
}
.ritual-essence__mv{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:3.5rem;
  max-width:52rem;
  margin:0 auto;
}
.ritual-essence__mv-label,
.ritual-essence__values-title{
  margin:0 0 .75rem;
  color:var(--ink);
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  opacity:.6;
}
.ritual-essence__mv p{
  margin:0;
  color:var(--ink);
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
.ritual-essence__mv p + p{
  margin-top:1rem;
}
.ritual-essence__pillars{
  margin-top:5rem;
}
.ritual-essence__pillars-header{
  margin:0 0 3.5rem;
  text-align:center;
}
.ritual-essence__pillars-title{
  margin:0;
  font-size:1.75rem;
  color:var(--ink);
}
.ritual-essence__pillars-grid{
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  column-gap:4rem;
  row-gap:0;
  max-width:1120px;
  margin:0 auto;
}
.ritual-essence__pillar{
  display:flex;
  flex-direction:column;
  align-items:center;
  text-align:center;
}
@supports (grid-template-rows: subgrid){
  @media (min-width: 992px){
    .ritual-essence__pillar{
      display:grid;
      grid-row:span 4;
      grid-template-rows:subgrid;
      justify-items:center;
      align-content:start;
    }
  }
}
.ritual-essence__pillar-icon{
  width:56px;
  height:56px;
  margin-bottom:1.5rem;
  color:var(--brass);
}
.ritual-essence__pillar-title{
  margin:0 0 1rem;
  font-size:1.625rem;
  color:var(--ink);
  line-height:1.2;
}
.ritual-essence__pillar p{
  max-width:22rem;
  margin:0;
  color:var(--ink);
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
.ritual-essence__pillar p + p{
  margin-top:1rem;
}
.ritual-essence__values{
  max-width:1120px;
  margin:3.5rem auto 0;
}
.ritual-essence__values::before{
  content:"";
  display:block;
  width:4rem;
  height:1px;
  margin:0 auto 2.5rem;
  background:rgba(41,37,28,.2);
}
.ritual-essence__values-title{
  margin-bottom:2rem;
  text-align:center;
}
.ritual-essence__values-list{
  display:grid;
  grid-template-columns:repeat(5, minmax(0, 1fr));
  gap:2rem;
  margin:0;
  padding:0;
  list-style:none;
}
.ritual-essence__value{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.5rem;
  text-align:center;
}
.ritual-essence__value-icon{
  width:28px;
  height:28px;
  margin-bottom:.25rem;
  color:var(--ink);
  opacity:.7;
}
.ritual-essence__value-name{
  color:var(--ink);
  font-size:.8125rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
}
.ritual-essence__value-desc{
  color:var(--ink);
  font-size:.875rem;
  font-weight:400;
  line-height:1.5;
}
/* Reveal: shared .reveal utility (motion standard) per block and per item;
   pillars lag 120ms each, the row of five values spreads the 360ms cap. */
.ritual-essence__pillar.reveal:nth-child(2){
  transition-delay:.12s;
}
.ritual-essence__pillar.reveal:nth-child(3){
  transition-delay:.24s;
}
.ritual-essence__value.reveal:nth-child(2){
  transition-delay:.09s;
}
.ritual-essence__value.reveal:nth-child(3){
  transition-delay:.18s;
}
.ritual-essence__value.reveal:nth-child(4){
  transition-delay:.27s;
}
.ritual-essence__value.reveal:nth-child(5){
  transition-delay:.36s;
}
@media (max-width: 1199.98px){
  .ritual-essence__pillars-grid{
    column-gap:2.5rem;
  }
  .ritual-essence__values-list{
    gap:1.5rem;
  }
}
@media (max-width: 991.98px){
  .ritual-essence__pillars-grid{
    grid-template-columns:minmax(0, 1fr);
    gap:3.5rem;
    max-width:34rem;
  }
  .ritual-essence__pillar.reveal:nth-child(n){
    transition-delay:0s;
  }
  .ritual-essence__values-list{
    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    gap:2.5rem 2rem;
  }
  .ritual-essence__value{
    flex:0 0 calc((100% - 4rem) / 3);
  }
}
@media (max-width: 767.98px){
  .ritual-essence{
    padding:4rem 0;
  }
  .ritual-essence__header{
    margin-bottom:2rem;
  }
  .ritual-essence__title{
    font-size:2rem;
  }
  .ritual-essence__mv p{
    font-size:1rem;
  }
  .ritual-essence__mv{
    grid-template-columns:minmax(0, 1fr);
    gap:2rem;
  }
  .ritual-essence__pillars{
    margin-top:4rem;
  }
  .ritual-essence__pillars-header{
    margin-bottom:2.5rem;
  }
  .ritual-essence__pillars-grid{
    gap:3rem;
  }
  .ritual-essence__pillar-icon{
    width:48px;
    height:48px;
    margin-bottom:1.25rem;
  }
  .ritual-essence__pillar-title{
    font-size:1.5rem;
  }
  .ritual-essence__pillar p{
    font-size:1rem;
  }
  .ritual-essence__values{
    margin-top:3rem;
  }
  .ritual-essence__values::before{
    margin-bottom:2rem;
  }
  .ritual-essence__values-title{
    margin-bottom:1.75rem;
  }
  .ritual-essence__values-list{
    display:grid;
    grid-template-columns:minmax(0, 1fr);
    gap:1.5rem;
    max-width:22rem;
    margin:0 auto;
  }
  .ritual-essence__value{
    display:grid;
    grid-template-columns:28px minmax(0, 1fr);
    column-gap:1rem;
    row-gap:.2rem;
    align-items:start;
    text-align:left;
  }
  .ritual-essence__value-icon{
    grid-row:1 / 3;
    margin:0;
  }
  .ritual-essence__value.reveal:nth-child(n){
    transition-delay:0s;
  }
}

/* ==== Homepage — Tres hermanas, un mismo propósito ==== */
.ritual-team{
  padding:4rem 0;
  background:var(--ritual-cream);
  text-align:center;
}
.ritual-team__title{
  margin:0 0 1.5rem;
  font-size:2.5rem;
  color:var(--ink);
}
/* ---- Tres hermanas — intro (between the title and the team photo) ----
   - The opening line is a centered Angel Face epigraph, with a short brass
     rule under it — the block's one brass accent. Angel Face is used only
     here, so it doesn't compete with the six quotes in the team cards.
   - Everything after the rule is plain, even running text split across two
     columns on desktop (inside the same 960px measure as before): every
     paragraph in both columns has the same size, weight, colour, line-height
     and spacing — no lead, no steps, no italics — so the two columns read as
     one continuous text.
   - Motion: epigraph, story and each paragraph reveal on their own (600ms,
     soft curve), with no staggered delays. Reduced motion turns it off.
   - Below 992px the two columns stack. */
.ritual-team__intro{
  max-width:960px;
  margin:0 auto 4rem;
  text-align:left;
}
.ritual-team__epigraph{
  max-width:44rem;
  margin:0 auto;
  padding:0;
  border:0;
  color:var(--ink);
  font-family:"Angel Face",cursive;
  font-size:clamp(2rem, 2.8vw, 2.5rem);
  font-style:normal;
  font-weight:400;
  line-height:1.15;
  text-align:center;
  text-wrap:balance;
}
.ritual-team__epigraph::after{
  content:"";
  display:block;
  width:2.5rem;
  height:1px;
  margin:2.25rem auto 0;
  background:var(--brass);
}
.ritual-team__body{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:4.5rem;
  align-items:start;
  margin-top:3.5rem;
}
.ritual-team__story p,
.ritual-team__line,
.ritual-team__closing{
  margin:0;
  padding:0;
  color:var(--ink);
  font-size:1.0625rem;
  font-style:normal;
  font-weight:400;
  line-height:1.7;
}
.ritual-team__story p + p{
  margin-top:1rem;
}
.ritual-team__cadence{
  display:flex;
  flex-direction:column;
  gap:1rem;
}
.ritual-team__closing{
  margin-top:1rem;
}
@media (max-width: 991.98px){
  .ritual-team__body{
    grid-template-columns:minmax(0, 1fr);
    gap:1rem;
  }
}
@media (max-width: 768px){
  .ritual-team__intro{
    margin-bottom:3rem;
  }
  .ritual-team__title{
    font-size:2rem;
  }
  .ritual-team__epigraph{
    font-size:1.875rem;
  }
  .ritual-team__epigraph::after{
    margin-top:1.75rem;
  }
  .ritual-team__body{
    margin-top:2.5rem;
  }
  .ritual-team__story p,
  .ritual-team__line,
  .ritual-team__closing{
    font-size:1rem;
  }
}
.ritual-team__symbolic{
  margin:0;
  overflow:hidden;
  border-radius:12px;
}
.ritual-team__symbolic img{
  display:block;
  width:100%;
  height:auto;
}
.ritual-team__grid{
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:2.5rem;
}
.ritual-team__card{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.4rem;
  margin-top:2rem;
  padding:1.5rem;
  border-radius:12px;
  background:#fff;
}
.ritual-team__photo{
  width:100%;
  height:auto;
  border-radius:16px;
  margin-bottom:.75rem;
}
.ritual-team__card h3{
  margin:0;
  font-size:1.625rem;
  color:var(--ink);
  line-height:1.2;
}
.ritual-team__role{
  margin:0;
  font-weight:700;
  font-size:.72rem;
  text-transform:uppercase;
  letter-spacing:.12em;
  opacity:.6;
  color:var(--ink);
}
.ritual-team__quote{
  margin:.25rem 0 0;
  font-family:"Angel Face",cursive;
  font-weight:300;
  font-size:1.8rem;
  color:var(--ink);
  opacity:.65;
}
@media (max-width: 768px){
  .ritual-team__grid{
    grid-template-columns:1fr;
  }
  .ritual-team__card h3{
    font-size:1.5rem;
  }
  .ritual-team__photo{
    width:60%;
    margin-left:auto;
    margin-right:auto;
  }
}
/* Reveal (motion standard): kicker and title together, the group photo only
   fades, the three cards lag 120ms each (no lag once they stack). The cards
   are not links, so they no longer lift on hover. */
.ritual-team__symbolic.reveal.reveal--pending{
  transform:none;
}
.ritual-team__card.reveal:nth-child(2){
  transition-delay:.12s;
}
.ritual-team__card.reveal:nth-child(3){
  transition-delay:.24s;
}
@media (max-width: 768px){
  .ritual-team__card.reveal:nth-child(n){
    transition-delay:0s;
  }
}

/* ==== Homepage — Image slider: stable height, no cropping ====
   The parent hummingbird theme forces a fixed 320px/240px figure height
   with object-fit:cover below lg, sized for a single reused desktop
   image — that cropped the mobile-specific image once it got its own
   asset. Switching to height:auto fixed the cropping but removed the
   only space reservation the box had (the <img> no longer carries
   width/height attributes either), so each lazy-loaded slide's image
   collapsed to 0 height until it finished loading, then snapped to
   full size — a layout jump on every carousel auto-advance.
   aspect-ratio reserves the correct box size up front (no load-timing
   dependency), matching today's real uploaded images (desktop ones are
   4000x1560, mobile ones 720x400); object-fit:contain shows the full
   image without cropping even if a future upload doesn't match exactly. */
.ps-imageslider{
  margin-bottom:2rem;
}
.ps-imageslider__figure{
  height:auto;
  aspect-ratio:4000/1560;
}
.ps-imageslider__figure img{
  object-fit:contain;
}
@media (max-width:991.98px){
  .ps-imageslider__figure{
    aspect-ratio:720/400;
  }
}

/* ==== Portadas: entrada con cortinilla (dorada o crema) ====
   Fotos de portada de la home (slider) y de la cabecera de categoría
   (.category__hero, más abajo). Una sola vez, al cargar la página, sin JS.
   Cada portada lleva su variante en el marcado (.ritual-cover--gold o
   --cream, ver index.tpl y category-header.tpl), y así se alternan entre
   páginas:
   - Dorada: una franja --brass cruza la foto de izquierda a derecha; la
     foto aparece cuando la franja la tapa entera, a mitad de recorrido.
   - Crema: una cortinilla --ritual-cream se retira hacia la derecha y la
     foto, un 6% ampliada, se asienta a su tamaño.
   En la home se anima .carousel-inner (contenedor de todas las
   diapositivas) y no cada foto, así que al pasar de diapositiva no se
   repite. El marco recorta (overflow:hidden): no mueve nada alrededor.
   La cortinilla va en un pseudo-elemento del marco: en la home
   .ps-imageslider; en categoría el <picture>. */
@keyframes ritual-cover-gold-wipe{
  0%{transform:scaleX(0);transform-origin:left center;}
  49%{transform:scaleX(1);transform-origin:left center;}
  51%{transform:scaleX(1);transform-origin:right center;}
  100%{transform:scaleX(0);transform-origin:right center;}
}
@keyframes ritual-cover-show-at-half{
  0%, 50%{opacity:0;}
  51%, 100%{opacity:1;}
}
@keyframes ritual-cover-cream-wipe{
  from{transform:scaleX(1);}
  to{transform:scaleX(0);}
}
@keyframes ritual-cover-settle{
  from{transform:scale(1.06);}
  to{transform:none;}
}
/* isolation: la cortinilla (z-index:1) se apila solo dentro de su marco,
   así que nunca pasa por encima de lo que rodea la foto: la tarjeta
   "Regala Bienestar" o el botón "Descubre nuestros rituales". */
.ps-imageslider{
  position:relative;
  overflow:hidden;
  isolation:isolate;
}
.ritual-cover .ps-imageslider::after,
.ritual-cover .category__hero-frame::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
  pointer-events:none;
  transform:scaleX(0);
}
.ritual-cover--gold .ps-imageslider::after,
.ritual-cover--gold .category__hero-frame::after{
  background:var(--brass);
  animation:ritual-cover-gold-wipe 1.4s cubic-bezier(.77,0,.18,1) forwards;
}
.ritual-cover--gold .ps-imageslider .carousel-inner,
.ritual-cover--gold .category__hero-image,
.ritual-cover--gold .category__hero-frame::before{
  animation:ritual-cover-show-at-half 1.4s linear both;
}
/* Home: duración de la entrada configurable en el módulo
   ritualbienestar_imageslider (variable inline en .ps-imageslider). La
   franja y la aparición de la foto comparten duración para que la foto
   siga apareciendo a mitad de recorrido. Categoría mantiene sus 1.4s. */
.ritual-cover--gold .ps-imageslider::after,
.ritual-cover--gold .ps-imageslider .carousel-inner{
  animation-duration:var(--rb-slider-intro,1.4s);
}
.ritual-cover--cream .ps-imageslider::after,
.ritual-cover--cream .category__hero-frame::after{
  background:var(--ritual-cream);
  transform-origin:right center;
  animation:ritual-cover-cream-wipe 1.2s cubic-bezier(.77,0,.18,1) forwards;
}
.ritual-cover--cream .ps-imageslider .carousel-inner,
.ritual-cover--cream .category__hero-image{
  animation:ritual-cover-settle 1.8s cubic-bezier(.22,.61,.36,1) .2s both;
}
/* Hover: la foto se acerca un 5% muy despacio mientras el ratón está
   encima, y vuelve al salir. Va con la propiedad `scale` y no con
   transform: la entrada crema anima transform y su fill-mode (both)
   ganaría a cualquier transform del :hover; `scale` se compone aparte.
   Solo con ratón (hover:hover); recortado en el marco de cada foto. */
.ps-imageslider__figure{
  overflow:hidden;
}
@media (hover:hover){
  .ps-imageslider__figure img,
  .category__hero-image{
    transition:scale 1.2s cubic-bezier(.22,.61,.36,1);
  }
  .ps-imageslider:hover .ps-imageslider__figure img,
  .category__hero:hover .category__hero-image{
    scale:1.05;
  }
}
@media (prefers-reduced-motion: reduce){
  .ritual-cover .ps-imageslider::after,
  .ritual-cover .category__hero-frame::after{
    display:none;
  }
  .ritual-cover .ps-imageslider .carousel-inner,
  .ritual-cover .category__hero-image,
  .ritual-cover .category__hero-frame::before{
    animation:none;
  }
  .ps-imageslider__figure img,
  .category__hero-image{
    transition:none;
  }
}

/* ==== Homepage — Hero floating CTA ("Descubre nuestros rituales") ====
   Sits astride the boundary between the hero slider and whatever section
   comes right after it (Pilares today, a future categories section later
   — see the href/id note in index.tpl), independent of that section's
   background: half the pill overlaps the slider image, half falls over
   the next section. The anchor wrapper (in index.tpl, around the hook)
   is what makes this deterministic instead of relying on margin-collapse
   between the slider and the next section: zeroing .ps-imageslider's own
   margin-bottom here means the wrapper's bottom edge is exactly the
   image's bottom edge, so bottom:0 + translate(-50%, 50%) always centers
   the button on that seam regardless of whatever spacing the section
   below defines for itself.
   position:absolute (not fixed) keeps the button anchored to this one
   slider container — it doesn't move or repeat per .carousel-item, and
   scrolls away with the page like the rest of the hero. z-index:2 is
   enough to paint over the static in-flow content on both sides (Pilares
   background, the slider image) without competing with the header
   (sticky), the WhatsApp float or the cookie banner, which all sit well
   above it and are unaffected since this button is never fixed-position. */
.ritual-hero-cta-anchor{
  position:relative;
}
.ritual-hero-cta-anchor .ps-imageslider{
  margin-bottom:0;
}
/* Idle bob: every keyframe re-states translate(-50%, 50%) so the seam
   positioning survives the animation the same way :hover has to below —
   a keyframe that only set translateY would blow away the centering the
   moment the animation started. */
@keyframes ritual-hero-cta-float{
  0%, 100%{transform:translate(-50%, 50%) translateY(0);}
  50%{transform:translate(-50%, 50%) translateY(-10px);}
}
.ritual-hero-cta{
  position:absolute;
  left:50%;
  bottom:0;
  z-index:2;
  transform:translate(-50%, 50%);
  animation:ritual-hero-cta-float 3.2s ease-in-out infinite;
  max-width:calc(100% - 2rem);
  padding:1rem 2.5rem;
  font-size:.95rem;
  text-align:center;
  white-space:normal;
  /* Layered black shadow (no brand-color tint) so the lift on hover below
     reads as depth, not a glow — deliberate contrast against the warm
     brass background instead of matching it. */
  box-shadow:0 4px 14px rgba(0,0,0,.2), 0 12px 30px rgba(0,0,0,.28);
}
/* .btn-pill:hover (specificity 0,2,0: one class + :hover) beats the base
   .ritual-hero-cta rule above (0,1,0) — without this, hovering replaced
   translate(-50%, 50%) outright with the generic translateY(-2px), so the
   button visibly jumped off-center and off the seam instead of just
   lifting. Re-declaring :hover here at the same specificity (0,2,0) wins
   on source order (this rule comes later) and recombines both transforms.
   The float animation keeps running through hover (no animation:none
   here) so the bob never freezes — while it's running it keeps winning
   over this transform line for the actual paint, so the lift itself
   doesn't show, but the rule still matters for prefers-reduced-motion
   below, where the animation really is off and this is what applies. */
.ritual-hero-cta:hover{
  transform:translate(-50%, 50%) translateY(-4px);
  box-shadow:0 10px 22px rgba(0,0,0,.25), 0 16px 36px rgba(0,0,0,.32);
}
@media (prefers-reduced-motion: reduce){
  .ritual-hero-cta{
    animation:none;
  }
  .ritual-hero-cta:hover{
    transform:translate(-50%, 50%);
  }
}
/* Below lg the slider switches to its short 720x400 crop (387px tall at
   992px, 208px at 375px), so the hero never fills the screen and the
   section below it is already visible without scrolling — the button has
   nothing left to announce, so it's hidden. Nothing collapses when it goes:
   it was absolutely positioned (it never occupied space in the flow), and
   .ritual-hero-cta-anchor keeps the slider's margin-bottom at 0, so no
   empty gap is left between the hero and the section below. */
@media (max-width: 991.98px){
  .ritual-hero-cta{
    display:none;
  }
}

/* ==== Homepage — "Tu opinión nos importa" + Newsletter (last section) ====
   Two columns like production's .bloque-newsletter: vertical divider
   between them on desktop, single column on mobile. Reuses .ritual-cta
   for both buttons instead of introducing a new button style, and the
   theme's own underline-input convention (border-bottom only, no box)
   for the email field. */
.ritual-newsletter-cta{
  padding:4rem 0;
  background:#fff;
  text-align:center;
}
.ritual-newsletter-cta__grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:3rem;
}
.ritual-newsletter-cta__col--newsletter{
  border-left:1px solid #e0e0e0;
  padding-left:3rem;
}
.ritual-newsletter-cta__grid h2{
  font-size:2.5rem;
  margin:0 0 1rem;
  color:var(--ink);
}
.ritual-newsletter-cta__grid p{
  font-weight:400;
  line-height:1.7;
  max-width:32rem;
  margin:0 auto 1.5rem;
  color:var(--ink);
  font-size:1.0625rem;
}
.ritual-newsletter-form form{
  max-width:24rem;
  margin:0 auto;
}
.ritual-newsletter-form .ritual-cta{
  margin-top:1.5rem;
}
/* El botón lleva texto + icono en el DOM (ver ps_emailsubscription.tpl):
   aquí (Home, "Tu opinión nos importa") se ve el texto y el icono queda
   oculto; el footer (más abajo, .footer__main-top .ritual-footer-newsletter)
   hace lo contrario para caber en una columna estrecha junto al campo. */
.ritual-newsletter-form__submit-icon{
  display:none;
}
/* La caja/checkbox los da el sistema compartido (.input-field__wrap /
   .form-check-ritual, ver "Formularios — sistema compartido" al final de
   este fichero) — aquí solo queda el layout propio de este bloque. */
.ritual-newsletter-form__privacy{
  margin-top:1rem;
  text-align:left;
}
.ritual-newsletter-form__privacy .form-check-ritual__label{
  font-size:.8125rem;
  color:rgba(41,37,28,.6);
}
.ritual-newsletter-form__privacy a{
  color:var(--ink);
  text-decoration:underline;
}
/* Título de la capa modal de política de privacidad — reutilizado tal
   cual (mismo .modal-title de Bootstrap) en el modal de "trabaja con
   nosotros" (ritualbienestar_workwithus). */
.modal-title{
  font-size:2rem;
}
/* Ese título es <p class="h5 modal-title ritual-privacy-modal__title"> (no
   encabezado) en los modales de newsletter, "trabaja con nosotros" y
   comentarios del blog: .h5 le da el h5 de hummingbird y aquí la fuente y
   el peso que h1-h6 toman de la regla general. */
.ritual-privacy-modal__title{
  font-family:"Tindoghouse",cursive;
  font-weight:400;
}
.ritual-newsletter-cta__grid .ritual-newsletter-form__msg{
  display:inline-block;
  font-size:.9rem;
  font-weight:700;
  margin-top:.75rem;
  padding:.4rem .9rem;
  border-radius:999px;
  color:#1e7e34;
  background:rgba(30,126,52,.1);
}
.ritual-newsletter-cta__grid .ritual-newsletter-form__msg.ritual-newsletter-form__msg--error{
  color:#b00020;
  background:rgba(176,0,32,.1);
}
.ritual-newsletter-cta .form-check-ritual__label{
  font-weight:400;
  line-height:1.4;
}
.ritual-newsletter-cta .ritual-newsletter-form__privacy a{
  text-decoration-color:var(--brass);
  text-underline-offset:.2em;
  transition:color var(--motion-hover) var(--motion-ease);
}
@media (hover: hover){
  .ritual-newsletter-cta .ritual-newsletter-form__privacy a:hover{
    color:var(--brass);
  }
}
/* Reveal (motion standard): the two columns, the second 120ms later (no lag
   once they stack). */
.ritual-newsletter-cta__col.reveal:nth-child(2){
  transition-delay:.12s;
}
@media (max-width: 768px){
  .ritual-newsletter-cta__col.reveal:nth-child(n){
    transition-delay:0s;
  }
}
@media (prefers-reduced-motion: reduce){
  .ritual-newsletter-cta .ritual-newsletter-form__privacy a{
    transition:none;
  }
}
.ritual-newsletter-cta__grid .ritual-newsletter-form__conditions{
  font-size:.8125rem;
  color:rgba(41,37,28,.6);
  margin-top:.5rem;
}

@media (max-width: 768px){
  .ritual-newsletter-cta__grid h2{
    font-size:2rem;
  }
  .ritual-newsletter-cta__grid p{
    font-size:1rem;
  }
  .ritual-newsletter-cta{
    padding:2rem 0;
  }
  .ritual-newsletter-cta__grid{
    grid-template-columns:1fr;
    gap:0;
  }
  .ritual-newsletter-cta__col--newsletter{
    border-left:none;
    padding-left:0;
    border-top:1px solid #e0e0e0;
    padding-top:2rem;
    margin-top:2rem;
  }
}

/* ==== Página de contacto — sin formulario, solo horario/datos/mapa ====
   Tres bandas a ancho completo con la alternancia blanco/crema de la home y
   su mismo ritmo vertical (4rem, 2rem en móvil): cabecera → horario (crema)
   → datos + mapa (blanco) → footer (ink). contact.tpl quita el .container
   de las columnas para que el fondo de cada banda llegue al borde; cada
   banda trae su propio .container.

   Tipografía tomada tal cual del estándar ya fijado (ver "Homepage — type
   standard" y "Extensiones del estándar"), sin pasos nuevos:
   - h1 de página interior (Tindoghouse 3.5rem / 2.25rem) + frase de marca
     en Angel Face con el tratamiento de .category__subtitulo.
   - Horario: antetítulo ("Consulta nuestro") + titular de sección
     ("Horario"). Sustituye al fondo/encima de la narrativa de home, que
     fuera de su composición a dos columnas dejaba el antetítulo casi
     ilegible y un vacío a la izquierda.
   - Horario compacto: es un dato de consulta rápida, no contenido
     protagonista. Los seis días en una fila (3×2 en pantallas medianas,
     2×3 en móvil), sin card: a este tamaño el contenedor solo añadía
     bulto, y basta el hueco entre columnas para separar los días. Cada día
     es el par "etiqueta + dato" de "Extensiones del estándar": nombre en el
     paso de antetítulo y franjas en el paso de dato (.9375rem, cifras
     tabulares), con la "y" delante de la segunda franja en ink al 60%.
   - --brass solo en el día de hoy (custom.js pone .is-today): filete corto
     sobre la columna y nombre en dorado a opacidad plena, frente al 60% de
     los demás. Es un estado, que es el uso que la dirección visual reserva
     al dorado; es el único acento de la página.
   - Datos + mapa a partes iguales (antes 5/7): el mapa dominaba la
     composición. Los datos se agrupan con etiqueta de antetítulo: principales
     (dirección; teléfono y WhatsApp en par) como texto destacado
     (1.25rem / 1.125rem) y, tras un filete de 1px, secundarios (email,
     redes) como cuerpo. Todo dato es enlace —la dirección abre Google Maps—
     con un único tratamiento: subrayado fino permanente en el texto, icono
     en ink al 60%, y ambos pasan a --brass al hover.
   - Iconos: un solo juego de trazo (1.5 sobre caja de 24, sin relleno) a
     1.25rem para todos, redes incluidas, en vez de glifos de Material Icons
     y SVG rellenos de tamaños distintos.
   - Datos y mapa estiran a la misma altura de fila: el mapa ocupa la altura
     del bloque de datos (con un mínimo de 24rem) y los grupos se reparten
     esa altura, así que ambos empiezan y acaban juntos. Mapa plano
     (--radius-md, sin sombra); al apilarse, 16:10 y 1:1 en móvil, para que
     la tarjeta de Google no caiga sobre el pin centrado.
   Movimiento: .reveal compartido; los seis días se reparten los 360ms
   de escalonado (72ms por paso) y el mapa entra 120ms tras los datos. */
.ritual-contact-header{
  margin:0;
  padding:2.5rem 0 4rem;
  background:#fff;
  text-align:center;
}
.ritual-contact-header__title{
  margin:0;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:3.5rem;
  line-height:1.2;
  color:var(--ink);
}
.ritual-contact-header__subheading{
  margin:1rem 0 0;
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:clamp(2rem, 2.8vw, 2.5rem);
  line-height:1.15;
  color:var(--ink);
}
@media (max-width:767px){
  .ritual-contact-header{
    padding:1.5rem 0 2rem;
  }
  .ritual-contact-header__title{
    font-size:2.25rem;
  }
  .ritual-contact-header__subheading{
    font-size:1.875rem;
  }
}

/* --- Horario --- */
.ritual-contact-hours{
  padding:4rem 0;
  background:var(--ritual-cream);
}
.ritual-contact-hours__heading{
  margin:0 0 2rem;
  text-align:center;
}
.ritual-contact-hours__title{
  margin:0;
  font-size:2.5rem;
  line-height:1.2;
  color:var(--ink);
}
.ritual-contact-hours__grid{
  display:grid;
  grid-template-columns:repeat(var(--ritual-contact-days, 6), minmax(0, 1fr));
  gap:1.5rem 1rem;
  max-width:1040px;
  margin:0 auto;
  padding:0;
  list-style:none;
}
/* El filete existe en todos los días (transparente) para que el de hoy no
   desplace su columna respecto a las demás. */
.ritual-contact-hours__day{
  position:relative;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.375rem;
  padding-top:.875rem;
  text-align:center;
}
.ritual-contact-hours__day::before{
  content:"";
  position:absolute;
  top:0;
  left:50%;
  width:2rem;
  height:1px;
  background:transparent;
  transform:translateX(-50%);
  transition:background-color var(--motion-hover) var(--motion-ease);
}
.ritual-contact-hours__name{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:700;
  font-size:.72rem;
  line-height:1.4;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:rgba(41,37,28,.6);
  transition:color var(--motion-hover) var(--motion-ease);
}
.ritual-contact-hours__times{
  display:flex;
  flex-direction:column;
  align-items:center;
}
.ritual-contact-hours__range{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:.9375rem;
  line-height:1.4;
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
  color:var(--ink);
}
.ritual-contact-hours__joiner{
  color:rgba(41,37,28,.6);
}
.ritual-contact-hours__day.is-today::before{
  background:var(--brass);
}
.ritual-contact-hours__day.is-today .ritual-contact-hours__name{
  color:var(--brass);
}
.ritual-contact-hours__grid > .reveal:nth-child(2){ transition-delay:.072s; }
.ritual-contact-hours__grid > .reveal:nth-child(3){ transition-delay:.144s; }
.ritual-contact-hours__grid > .reveal:nth-child(4){ transition-delay:.216s; }
.ritual-contact-hours__grid > .reveal:nth-child(5){ transition-delay:.288s; }
.ritual-contact-hours__grid > .reveal:nth-child(6){ transition-delay:.36s; }
.ritual-contact-hours__grid > .reveal:nth-child(7){ transition-delay:.432s; }
@media (max-width:991px){
  .ritual-contact-hours__grid{
    grid-template-columns:repeat(3, minmax(0, 1fr));
    max-width:36rem;
  }
}
@media (max-width:767px){
  .ritual-contact-hours{
    padding:2rem 0;
  }
  .ritual-contact-hours__heading{
    margin-bottom:1.5rem;
  }
  .ritual-contact-hours__title{
    font-size:2rem;
  }
}
@media (max-width:575px){
  .ritual-contact-hours__grid{
    grid-template-columns:repeat(2, minmax(0, 1fr));
    gap:1.25rem .75rem;
  }
}

/* --- Datos + mapa --- */
.ritual-contact-info{
  padding:4rem 0;
  background:#fff;
}
.ritual-contact-info__grid{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:4rem;
  align-items:stretch;
}
.ritual-contact-info__card{
  display:flex;
  flex-direction:column;
  justify-content:space-between;
  gap:2rem;
}
.ritual-contact-info__group{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.5rem;
  min-width:0;
}
.ritual-contact-info__group .ritual-section-kicker{
  margin:0;
}
.ritual-contact-info__pair,
.ritual-contact-info__secondary{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:1.5rem 2rem;
}
.ritual-contact-info__secondary{
  grid-template-columns:minmax(0, auto) minmax(0, auto);
  justify-content:start;
  column-gap:3rem;
  padding-top:2rem;
  border-top:1px solid rgba(41,37,28,.12);
}
.ritual-contact-info__social{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  gap:.375rem;
}
/* Enlace de dato: icono + texto. El subrayado va en el texto y no en el
   <a> flex, para que no dependa de cómo cada navegador propaga la
   decoración a los hijos de un contenedor flex. */
.ritual-contact-info__link{
  display:inline-flex;
  align-items:flex-start;
  gap:.75rem;
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:1.0625rem;
  line-height:1.5;
  color:var(--ink);
  text-decoration:none;
  overflow-wrap:anywhere;
}
.ritual-contact-info__link--lead{
  font-size:1.25rem;
}
.ritual-contact-info__text{
  text-decoration:underline;
  text-decoration-thickness:1px;
  text-decoration-color:rgba(41,37,28,.3);
  text-underline-offset:.2em;
  transition:color var(--motion-hover) var(--motion-ease), text-decoration-color var(--motion-hover) var(--motion-ease);
}
/* Icono centrado en la primera línea de texto: (1.5 × tamaño − 1.25rem) / 2,
   para que en la dirección —dos líneas— no quede entre ambas. */
.ritual-contact-info__icon{
  flex:none;
  width:1.25rem;
  height:1.25rem;
  margin-top:.171875rem;
  fill:none;
  stroke:rgba(41,37,28,.6);
  stroke-width:1.5;
  stroke-linecap:round;
  stroke-linejoin:round;
  transition:stroke var(--motion-hover) var(--motion-ease);
}
.ritual-contact-info__link--lead .ritual-contact-info__icon{
  margin-top:.3125rem;
}
.ritual-contact-info__link:hover,
.ritual-contact-info__link:focus-visible{
  color:var(--ink);
  text-decoration:none;
}
.ritual-contact-info__link:hover .ritual-contact-info__text,
.ritual-contact-info__link:focus-visible .ritual-contact-info__text{
  color:var(--brass);
  text-decoration-color:var(--brass);
}
.ritual-contact-info__link:hover .ritual-contact-info__icon,
.ritual-contact-info__link:focus-visible .ritual-contact-info__icon{
  stroke:var(--brass);
}
.ritual-contact-info__map{
  overflow:hidden;
  min-height:24rem;
  border-radius:16px;
  background:var(--ritual-cream);
}
.ritual-contact-info__map.reveal{
  transition-delay:.12s;
}
.ritual-contact-info__map iframe{
  display:block;
  width:100%;
  height:100%;
  border:0;
}
@media (max-width:991px){
  .ritual-contact-info__grid{
    grid-template-columns:1fr;
    gap:2.5rem;
  }
  .ritual-contact-info__card{
    justify-content:flex-start;
  }
  .ritual-contact-info__map{
    min-height:0;
    aspect-ratio:16 / 10;
  }
}
@media (max-width:767px){
  .ritual-contact-info{
    padding:2rem 0 3rem;
  }
  .ritual-contact-info__grid{
    gap:2rem;
  }
  .ritual-contact-info__card{
    gap:1.5rem;
  }
  .ritual-contact-info__secondary{
    padding-top:1.5rem;
  }
  .ritual-contact-info__link--lead{
    font-size:1.125rem;
  }
  .ritual-contact-info__link--lead .ritual-contact-info__icon{
    margin-top:.21875rem;
  }
  .ritual-contact-info__map{
    aspect-ratio:1 / 1;
  }
}
@media (max-width:575px){
  .ritual-contact-info__secondary{
    grid-template-columns:1fr;
    row-gap:1.5rem;
  }
}
@media (max-width:399px){
  .ritual-contact-info__pair{
    grid-template-columns:1fr;
  }
}
@media (prefers-reduced-motion: reduce){
  .ritual-contact-hours__day::before,
  .ritual-contact-hours__name,
  .ritual-contact-info__text,
  .ritual-contact-info__icon{
    transition:none;
  }
  .ritual-contact-hours__grid > .reveal,
  .ritual-contact-info__map.reveal{
    transition-delay:0s;
  }
}

/* --- "Trabaja con nosotros" candidacy form: layout + reuse of the site's
   .ritual-cta pill treatment, scoped to this page (there's no bare
   .ritual-cta base rule anywhere in this file — every section redeclares
   its own variant, so this follows the same pattern instead of inventing
   a shared utility). Ink-fill/white-text here since the button sits on
   the page's light cream background, not the dark header bar (which uses
   the inverse: white-fill/ink-text). --- */
.ritual-workwithus{
  max-width:36rem;
  margin:0 auto;
  padding-bottom:6rem;
}
/* Titular de página interior del estándar (Tindoghouse 400, line-height
   1.2, sin mayúsculas), pero a 2rem y no a 3.5rem: la columna mide 36rem
   (576px) y "¿Quieres formar parte del equipo Ritual?" mide 17.37em con las
   métricas de Tindoghouse (sin kerning), así que a 3.5rem ocupaba tres
   líneas; a 2rem son 556px y cabe en una. En móvil parte igual a
   cualquier tamaño razonable, así que no baja más. */
.ritual-workwithus__title{
  text-align:center;
  margin:0 0 2rem;
  font-size:2rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
/* --- Success/error banners: same green/red pair already established for
   the newsletter form's inline messages (.ritual-newsletter-form__msg),
   reused here as a bordered block instead of a pill since this one can
   hold a full <ul> of several error lines, not just a one-line message. --- */
.ritual-workwithus .notification{
  margin-bottom:2rem;
  padding:1rem 1.25rem;
  border-radius:8px;
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  /* Cuerpo del estándar (antes Light 300). */
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
}
@media (max-width:767px){
  .ritual-workwithus .notification{
    font-size:1rem;
  }
}
.ritual-workwithus .notification p{
  margin:0;
}
.ritual-workwithus .notification-success{
  color:var(--color-success);
  background:rgba(30,126,52,.1);
  border:1px solid rgba(30,126,52,.25);
}
.ritual-workwithus .notification-error{
  color:var(--color-error);
  background:rgba(176,0,32,.1);
  border:1px solid rgba(176,0,32,.25);
}
.ritual-workwithus .notification-error ul{
  margin:0;
  padding-left:1.25rem;
}
/* --- Inputs/textarea de Nombre/Contacto/Carta de presentación: pasan a
   .input-field (sistema compartido, ver "Formularios — sistema compartido"
   al final de este fichero) — este bloque solo mantiene lo propio del
   input de fichero, que no tiene variante en ese sistema. --- */
/* --- File input: mismo lenguaje de caja que el resto de campos para el
   control exterior, pero el botón nativo "elegir archivo" no puede
   heredarla (es un pseudo-elemento que cada navegador pinta por su
   cuenta, no puede llevar la clase .btn-pill--secondary.btn-pill--sm —
   los valores de abajo se mantienen idénticos a esa combinación a
   propósito). El padding izquierdo lo lleva el input (no el botón) para
   dar aire a la píldora antes del borde del campo. --- */
.ritual-workwithus__form input[type="file"].form-control{
  border:1px solid rgba(41,37,28,.25);
  border-radius:10px;
  background:#fff;
  padding:.55rem .75rem .55rem 1rem;
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-weight:300;
  color:var(--ink);
  box-shadow:none;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.ritual-workwithus__form input[type="file"].form-control:hover{
  border-color:rgba(41,37,28,.45);
}
.ritual-workwithus__form input[type="file"].form-control:focus{
  outline:none;
  border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(175,138,82,.15);
}
.ritual-workwithus__form input[type="file"].form-control::file-selector-button,
.ritual-workwithus__form input[type="file"].form-control::-webkit-file-upload-button{
  appearance:none;
  -webkit-appearance:none;
  margin-right:1rem;
  padding:.5rem 1.25rem;
  border:1px solid var(--ink);
  border-radius:999px;
  background:transparent;
  color:var(--ink);
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-weight:700;
  font-size:.8rem;
  text-transform:uppercase;
  letter-spacing:.04em;
  cursor:pointer;
  transition:background .2s ease, color .2s ease;
}
.ritual-workwithus__form input[type="file"].form-control:hover::file-selector-button,
.ritual-workwithus__form input[type="file"].form-control:hover::-webkit-file-upload-button{
  background:var(--ink);
  color:#fff;
}
/* Consentimiento: texto legal (400, no el 300 de
   .form-check-ritual__label) y su enlace, metadato accionable. */
.ritual-workwithus__privacy{
  margin-bottom:2rem;
  font-size:.8125rem;
}
.ritual-workwithus__privacy .form-check-ritual__label{
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.ritual-workwithus__privacy a{
  color:inherit;
  font-weight:400;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
/* El checkbox en sí ahora es .form-check-ritual (sistema compartido, ver
   "Formularios — sistema compartido" al final de este fichero) — ya no
   necesita su propio checkbox dibujado a mano. Solo queda el color del
   enlace "Política de privacidad" dentro del texto. */
.ritual-workwithus__privacy a:hover,
.ritual-workwithus__privacy a:focus-visible{
  color:var(--brass);
}
/* Forma/color/hover ya los da la clase maestra .ritual-cta — solo el
   ancho completo, propio de este botón de envío del formulario. */
.ritual-workwithus .ritual-cta{
  width:100%;
}

/* --- Hide Google's floating reCAPTCHA v3 badge (bottom-right corner,
   injected by recaptcha/api.js on any page that calls grecaptcha.execute
   — only workwithus right now). Google's own terms allow hiding it as
   long as the required "protected by reCAPTCHA" notice is shown
   somewhere else in the UI instead — that text isn't added anywhere on
   this page yet, so it still needs to go somewhere near the form. --- */
.grecaptcha-badge{
  visibility:hidden;
}

/* ==== Category page — header, hero, subcategory nav (legacy PS1.6 layout) ====
   Values matched against the original stylesheets/styles.css rules for
   .page-heading, .page-subheading and #bloque-regala-bienestar (see
   migration/backup/web/themes/default-bootstrap/category.tpl +
   stylesheets/styles.css) — centered title/subtitulo, a dark floating
   badge straddling the top edge of the hero image (not a full tint), and
   a bouncing arrow that scrolls down to the product list on click. */
.category__title{
  font-family:"Tindoghouse",cursive;
  font-size:3.5rem;
  /* line-height 1.2, el del titular de sección del estándar de home. El
     tamaño se queda en 3.5rem a propósito: es el h1 de la página y por
     encima de la cabecera de grupo (2.5rem), que ya usa el paso estándar.
     Ver nota de "escala de titulares de página interior". */
  line-height:1.2;
  color:var(--ink);
  text-align:center;
  margin:0 0 .25rem;
}
@media (max-width:767px){
  .category__title{
    font-size:2.25rem;
  }
}
/* Angel Face, la cursiva de marca, con el estándar de home para frases
   evocadoras (400, clamp(2rem, 2.8vw, 2.5rem), line-height 1.15, --ink) —
   el mismo que las cards de home. Antes
   iba en "Helvetica Cursiva", que al pedirse sin font-style:italic caía en
   la oblicua sintética del navegador en vez de en la cursiva real.
   El hueco sobre la frase sube de .5rem a 1rem: los márgenes de título y
   frase colapsan entre sí, así que manda el mayor de los dos, y con una
   tipografía de firma a 2.5rem los 8px anteriores dejaban la frase pegada
   al titular.
   Compactada para acercar el listado: fija en 2rem, el suelo del clamp()
   del estándar (antes crecía hasta 2.5rem con la ventana), y el hueco
   sobre ella baja a .75rem, que a este tamaño ya no la deja pegada. */
.category__subtitulo{
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:2rem;
  line-height:1.15;
  color:var(--ink);
  text-align:center;
  margin:.75rem 0 0;
}
/* En móvil no se muestra: con el título, la tarjeta "Regala Bienestar" y
   el hero, la cabecera ya ocupa casi toda la primera pantalla. */
@media (max-width:767px){
  .category__subtitulo{
    display:none;
  }
}
/* Full-bleed: breaks out of the theme's centered .container regardless of
   its max-width, so the hero image spans the full viewport edge to edge
   like the legacy site's, while everything else on the page (title,
   subtitulo, badge, description) stays inside the normal container. */
/* Alto: la proporción 2000/780 sin tope hacía la imagen el 39% del ancho
   de ventana (749px a 1920px), casi la mitad del camino hasta el primer
   producto. El tope a algo más de media pantalla deja que el bloque
   siguiente asome por el borde inferior; al recortarse la caja, la imagen
   la sigue llenando con object-fit:cover sin deformarse. svh (con vh
   delante para navegadores sin soporte) para que en móvil no cambie de
   alto al mostrarse u ocultarse la barra del navegador.
   La tarjeta "Regala Bienestar" no se superpone a la foto en ningún
   tamaño de pantalla: las fotos llevan caras y la tarjeta las tapaba. El
   hero es una columna con la tarjeta en el flujo, encima de la imagen, y
   la proporción y el tope de alto los lleva el <picture>. */
.category__hero{
  position:relative;
  display:flex;
  flex-direction:column;
  width:100vw;
  margin-top:2rem;
  margin-bottom:1.5rem;
  margin-left:calc(50% - 50vw);
  margin-right:calc(50% - 50vw);
}
/* Marco de recorte de la entrada con cortinilla y del hover de
   .category__hero-image (ver "Portadas: entrada con cortinilla"): recorta
   el <picture> (.category__hero-frame), que es también donde va la
   cortinilla, y fija la proporción y el tope de alto de la foto. */
.category__hero-frame{
  position:relative;
  display:block;
  width:100%;
  aspect-ratio:2000/780;
  max-height:55vh;
  max-height:55svh;
  overflow:hidden;
  isolation:isolate;
}
@media (max-width:767px){
  .category__hero{
    margin-top:1.25rem;
  }
  /* En móvil el marco no tiene proporción fija: toma la altura de la
     foto (.category__hero-image, más abajo). */
  .category__hero-frame{
    aspect-ratio:auto;
    max-height:none;
  }
}
/* La foto se ve entera, sin recortes (contain): sus versiones se generan
   a la proporción de la foto, sin relleno (override/classes/ImageManager.php),
   y el hueco que deja en el marco (a los lados en las fotos de cámara 3:2
   en escritorio) lo cubre la misma foto ampliada y difuminada (::before).
   El fondo usa la versión pequeña de la foto (category_hero_mobile,
   --rb-hero-backdrop en category-header.tpl): al
   difuminarla no se nota la resolución y pesa unos KB. inset negativo:
   blur() aclara los bordes de lo que difumina; así quedan fuera del marco.
   position:relative en la foto para que quede por encima del fondo; la
   cortinilla (::after, z-index:1) sigue encima de las dos. Si la foto ya
   tiene la proporción del marco, lo llena y el fondo no se ve. */
.category__hero-frame::before{
  content:"";
  position:absolute;
  inset:-40px;
  background:var(--rb-hero-backdrop) center/cover no-repeat;
  filter:blur(30px) brightness(.85);
}
@media (max-width:767px){
  .category__hero-frame::before{
    background-image:var(--rb-hero-backdrop-mobile, var(--rb-hero-backdrop));
  }
}
.category__hero-image{
  position:relative;
  display:block;
  width:100%;
  height:100%;
  object-fit:contain;
}
/* Móvil: la foto va a todo el ancho y entera, y el marco toma su altura,
   así que no queda hueco. aspect-ratio:auto 3/2 reserva una caja 3:2 (la
   de las fotos de cámara) mientras carga, en vez de la 2000x780 de sus
   atributos width/height, y al cargar pasa a su proporción real. Tope de
   70svh para fotos verticales: ahí vuelve el contain con el fondo
   difuminado a los lados. */
@media (max-width:767px){
  .category__hero-image{
    height:auto;
    aspect-ratio:auto 3/2;
    max-height:70vh;
    max-height:70svh;
  }
}
.category__hero-badge{
  position:relative;
  display:block;
  width:90%;
  max-width:260px;
  margin:0 auto 1.25rem;
  padding:.9rem 1.25rem .7rem;
  background:var(--ink);
  color:#fff;
  text-align:center;
  text-decoration:none;
  border-radius:1.25rem;
  box-shadow:0 10px 30px rgba(0,0,0,.7);
  cursor:pointer;
  transition:transform .25s ease, box-shadow .25s ease;
}
.category__hero-badge:hover,
.category__hero-badge:focus-visible{
  color:#fff;
  transform:translateY(-6px);
  animation-play-state:paused;
}
.category__hero-badge-title{
  display:block;
  font-family:"Tindoghouse",cursive;
  font-size:1.6rem;
  margin:0;
}
.category__hero-badge-text{
  display:block;
  font-family:"Tindoghouse",cursive;
  font-size:1.15rem;
  margin-top:.35rem;
}
.category__hero-arrow{
  display:inline-block;
  margin-top:.2rem;
  font-size:1.6rem;
  line-height:1;
  color:inherit;
  transform:rotate(90deg);
  animation:category-hero-arrow-bounce 2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){
  .category__hero-arrow{
    animation:none;
  }
}
/* Móvil: con el hero a 360/200 (~200px de alto en un teléfono), la tarjeta
   se reduce más que en escritorio para que la cabecera no ocupe toda la primera
   pantalla. */
@media (max-width:767px){
  .category__hero-badge{
    max-width:210px;
    margin-bottom:1rem;
    padding:.6rem .9rem .5rem;
    border-radius:1rem;
    box-shadow:0 8px 20px rgba(0,0,0,.6);
  }
  .category__hero-badge-title{
    font-size:1.25rem;
  }
  .category__hero-badge-text{
    font-size:.95rem;
    margin-top:.25rem;
  }
  .category__hero-arrow{
    margin-top:.1rem;
    font-size:1.3rem;
  }
}
@keyframes category-hero-arrow-bounce{
  0%, 100%{ transform:rotate(90deg) translateX(0); }
  50%{ transform:rotate(90deg) translateX(6px); }
}
/* Legacy .bloque-categoria two-column block: palabras_especiales as large
   pale words (left, matches the pale/ink-tint treatment already used for
   .ritual-narrative__title-fondo on the homepage rather than the legacy
   site's literal flat #E0E0E0) and the category description (right).
   Cierra la página, tras el listado (category-footer.tpl): más aire
   arriba que cuando seguía al hero, para despegarse de la última fila de
   productos. */
.category__special-block{
  display:grid;
  grid-template-columns:minmax(0, 1fr) minmax(0, 1fr);
  gap:2.5rem;
  max-width:1100px;
  margin:4.5rem auto 3rem;
  align-items: center;
}
/* Sin descripción (todas las categorías que no son padre) o sin palabras:
   una sola columna, centrada bajo el título como el resto de la cabecera.
   La descripción sola se limita a una medida de lectura. */
.category__special-block--single{
  grid-template-columns:minmax(0, 1fr);
  justify-items:center;
}
.category__special-block--single .category__special-words{
  align-items:center;
  text-align:center;
}
.category__special-block--single .category__description{
  max-width:38rem;
}
.category__special-words{
  display:flex;
  flex-direction:column;
  min-width:0;
}
/* Subido de .15 a .28: a .15 sobre blanco las palabras apenas se leían
   (~1.3:1). A .28 quedan legibles como fondo tipográfico sin acercarse al
   contraste del texto de la derecha, que sigue mandando en el bloque.
   3.5rem (antes 5rem): tres palabras pasan de ~256px a ~184px de alto, y
   siguen al paso del h1, así que no dejan de leerse como fondo tipográfico
   a gran escala. */
.category__special-word{
  font-family:"Tindoghouse",cursive;
  font-size:3.5rem;
  line-height:1;
  color:rgba(41,37,28,.28);
  text-transform:uppercase;
  hyphens:auto;
  margin:0 0 .5rem;
}
.category__special-word:last-child{
  margin-bottom:0;
}
/* Estándar de cuerpo de home (Helvetica 400, 1.0625rem, line-height 1.7,
   --ink, 1rem entre párrafos). El contenido migrado separa las frases con
   <br /> dentro de un mismo <p>, así que el interlineado es aquí lo que de
   verdad abre el bloque: a 1.2 se leía como un párrafo apelmazado. */
.category__description{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:1.0625rem;
  line-height:1.7;
  color:var(--ink);
  min-width:0;
  margin:0;
}
.category__description p{
  margin:0 0 1rem;
}
.category__description p:last-child{
  margin-bottom:0;
}
.category__description strong,
.category__description b{
  font-weight:700;
  color:var(--ink);
}
/* El contenido migrado usa <br /> como separador de párrafo dentro de un
   mismo <p>. Convertirlo en caja vacía con margen le da esa separación sin
   tocar el copy guardado (y sin confundirla con un salto de línea normal
   del propio párrafo, que sigue a line-height 1.7). */
.category__description br{
  display:block;
  content:"";
  margin-bottom:.6rem;
}
/* The migrated legacy rich-text content ships literal empty <p class="texto">
   placeholders (PS1.6 editor artifacts) — collapse them instead of editing
   the stored content. */
.category__description .texto:empty{
  display:none;
}
@media (max-width:767px){
  .category__special-block{
    grid-template-columns:1fr;
    gap:1rem;
    margin-top:3rem;
  }
  .category__special-word{
    font-size:2.25rem;
  }
}
/* Cabecera de grupo: en una página de categoría agrupa a todos los
   productos que vienen debajo, así que necesita leerse por encima del
   nombre de cada producto (1.75rem) y tener aire propio antes y después.
   El filete corto en --brass es el único acento de color de la cabecera
   (DIRECCION-VISUAL.md #1: el dorado señala, no decora). */
.subcategory-section{
  margin:0;
}
.subcategory-section + .subcategory-section{
  margin-top:7rem;
}
.subcategory-section__title{
  font-family:"Tindoghouse",cursive;
  font-size:2.5rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
  /* Sin text-transform ni letter-spacing: el titular de sección del
     estándar de home no los lleva (solo el antetítulo va en mayúsculas).
     Hoy no cambia nada a la vista, porque los nombres de categoría ya
     vienen en mayúsculas desde la BBDD; deja de forzarlo desde el estilo. */
  text-align:center;
  margin:0 0 3.5rem;
}
.subcategory-section__title::after{
  content:"";
  display:block;
  width:3rem;
  height:1px;
  margin:1.25rem auto 0;
  background:var(--brass);
}
@media (max-width:767px){
  .subcategory-section + .subcategory-section{
    margin-top:4.5rem;
  }
  .subcategory-section__title{
    font-size:2rem;
    margin-bottom:2.5rem;
  }
}

/* ==== Product listing item — text-only (legacy PS1.6 layout, no image) ==== */
/* Rejilla del listado: una columna en móvil y dos desde 768px. La de
   Hummingbird (themes/hummingbird/assets/css/theme.css) está pensada para
   miniaturas con foto: 2 columnas ya desde 360px y 4 desde 992px en
   layout-full-width (3 en layout-left/right-column), demasiado estrechas
   para esta card de texto. Se reescribe con los mismos selectores por
   layout-* para empatar su especificidad (este fichero carga después), y
   con .products suelto para las páginas de módulo que no la heredan.
   El hueco es el mismo que antes separaba una card de la siguiente en la
   lista apilada (1.25rem en móvil, 2rem en escritorio).
   Las celdas se estiran a la altura de la fila (align-items:stretch por
   defecto), así que el botón de cada card, que va al pie con
   margin-top:auto, queda alineado con el de su vecina. */
.products,
.layout-full-width .products,
.layout-left-column .products,
.layout-right-column .products,
.layout-both-columns .products{
  --listing-gap:1.25rem;
  display:grid;
  grid-template-columns:minmax(0, 1fr);
  gap:var(--listing-gap);
}
@media (min-width:768px){
  .products,
  .layout-full-width .products,
  .layout-left-column .products,
  .layout-right-column .products,
  .layout-both-columns .products{
    --listing-gap:2rem;
    grid-template-columns:repeat(2, minmax(0, 1fr));
  }
  /* Card que se queda sola en su fila (subcategoría con un único
     producto, o la última de un número impar): conserva el ancho de media
     rejilla y se centra, en vez de quedarse pegada a la izquierda bajo un
     título de sección centrado. En el índice plegable de "Todos nuestros
     rituales" no: allí el rótulo de cada bloque va alineado a la izquierda
     y la card lo acompaña. */
  .products > .product-listing-item:last-child:nth-child(odd){
    grid-column:1 / -1;
    justify-self:center;
    width:calc((100% - var(--listing-gap)) / 2);
  }
  .ritual-accordion__panel .products > .product-listing-item:last-child:nth-child(odd){
    grid-column:auto;
    justify-self:stretch;
    width:auto;
  }
}
.subcategory-section .products{
  margin:0 auto;
}
/* Cada producto va dentro de una card. El fondo es lo único que la define:
   sin borde y sin sombra, porque en una categoría con 17 productos seguidos
   cualquiera de los dos apila 17 marcos o 17 halos repetidos, y el ruido de
   esa repetición pesa más que la ganancia de definir el contenedor.
   El tono es --ritual-cream rebajado sobre el blanco de la página: a plena
   intensidad la repetición se hace presente, y además el precio en --brass
   se queda en 2.88:1 sobre #f7f3ec (por debajo del 3:1 de AA para texto
   grande), mientras que sobre esta mezcla llega a 3.02:1. Se declara con
   color-mix para que el token siga siendo la fuente del color, con el
   valor ya resuelto delante como alternativa para navegadores sin soporte.
   Una sola columna interna, apilada y alineada a la izquierda como las
   cards de la home (.ritual-featured__card): nombre → frase → extracto →
   datos (duración y precio) → botón. Antes eran dos columnas (3fr texto /
   2fr compra), que no caben en media rejilla: la de compra se quedaba en
   ~200px con un botón que pide 15rem.
   Flex en columna para que el botón pueda irse al pie (margin-top:auto) y,
   en una rejilla, los botones de una misma fila queden alineados aunque
   una card tenga frase de dos líneas y la vecina de una. */
.product-listing-item{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  margin:0;
  padding:2rem;
  border-radius:16px;
  background:#fbf8f5;
  background:color-mix(in srgb, var(--ritual-cream) 55%, #fff);
}
/* Fuera de una rejilla .products (p. ej. ps_categoryproducts, que pinta las
   cards en un <div> sin esa clase) siguen apiladas con este hueco. Dentro
   de la rejilla lo pone su gap: un margin-top aquí descolocaría la card de
   la derecha respecto a la de su izquierda. */
.product-listing-item + .product-listing-item{
  margin-top:2rem;
}
.products > .product-listing-item + .product-listing-item{
  margin-top:0;
}
@media (max-width:767px){
  .product-listing-item{
    padding:1.75rem 1.25rem;
  }
  .product-listing-item + .product-listing-item{
    margin-top:1.25rem;
  }
}
.product-listing-item > *{
  max-width:100%;
}
.product-listing-item > :last-child{
  margin-bottom:0;
}
/* Titular de elemento del estándar de home: Tindoghouse 400, 1.625rem
   (1.5rem en móvil), line-height 1.2, sin mayúsculas, --ink — el mismo
   bloque que .ritual-featured__name. El hueco hasta la frase es corto a
   propósito: nombre y frase se leen como un solo titular a dos voces. */
.product-listing-item__name{
  font-family:"Tindoghouse",cursive;
  font-size:1.625rem;
  line-height:1.2;
  font-weight:400;
  color:var(--ink);
  margin:0 0 .5rem;
}
@media (max-width:767px){
  .product-listing-item__name{
    font-size:1.5rem;
  }
}
/* El nombre enlaza a la ficha, como segundo camino junto a "¡Reserva tu
   cita ahora!" (al pie de la card). En reposo se lee como titular, no como enlace; al pasar
   por encima toma el --brass de los elementos interactivos de marca
   (DIRECCION-VISUAL.md #1) y el subrayado. */
.product-listing-item__name-link{
  color:inherit;
  text-decoration:underline;
  text-decoration-color:transparent;
  text-decoration-thickness:1px;
  text-underline-offset:.2em;
  transition:color var(--motion-hover) var(--motion-ease), text-decoration-color var(--motion-hover) var(--motion-ease);
}
.product-listing-item__name-link:hover,
.product-listing-item__name-link:focus-visible{
  color:var(--brass);
  text-decoration-color:var(--brass);
}
.product-listing-item__name-link:focus-visible{
  outline:1px solid var(--brass);
  outline-offset:4px;
}
@media (prefers-reduced-motion: reduce){
  .product-listing-item__name-link{transition:none}
}
/* Angel Face como acento puntual, justo bajo el nombre. 2rem es el suelo
   del clamp() del estándar de home (clamp(2rem, 2.8vw, 2.5rem)): en media
   rejilla la card es la mitad de ancha y con el clamp la frase crecía con
   la ventana, no con la card. */
.product-listing-item__tagline{
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:2rem;
  line-height:1.15;
  color:var(--ink);
  text-wrap:balance;
  margin:0 0 1rem;
}
@media (max-width:767px){
  .product-listing-item__tagline{
    font-size:1.875rem;
  }
}
/* Primer párrafo de la descripción, recortado a 3 líneas con puntos
   suspensivos. Cuerpo del estándar de home (Helvetica 400, 1.0625rem,
   line-height 1.7), sin el tratamiento de gancho de la ficha: aquí es un
   extracto, no la entrada de un texto largo. */
.product-listing-item__excerpt{
  display:-webkit-box;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:3;
  line-clamp:3;
  overflow:hidden;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
  margin:0 0 1.5rem;
}
/* "Descripción del listado de productos" propia del producto: entero, con sus párrafos. */
.product-listing-item__excerpt--full{
  display:block;
  -webkit-line-clamp:unset;
  line-clamp:none;
  overflow:visible;
}
.product-listing-item__excerpt--full p{
  margin:0 0 .75rem;
}
.product-listing-item__excerpt--full > :last-child{
  margin-bottom:0;
}
.product-listing-item__excerpt--full strong{
  font-weight:700;
}
@media (max-width:767px){
  .product-listing-item__excerpt{
    font-size:1rem;
  }
}

/* --- Datos del servicio: duración y precio en la misma franja, cada uno
   con su etiqueta en versalitas encima, alineados por abajo. Si no caben
   (móvil estrecho, precio con tachado) pasan a dos líneas. --- */
/* El body del sitio está en font-weight:300, así que todo lo que no fije
   peso propio cae a Light. El estándar de home usa 400 para cuerpo, dato y
   metadato, de ahí el font-weight:400 explícito aquí. */
.product-listing-item__facts{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-end;
  gap:.75rem 2rem;
  margin:0 0 1.5rem;
}
.product-listing-item__duration{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.9375rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
  margin:0;
}
.product-listing-item__duration-label{
  display:block;
  margin:0 0 .15rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  opacity:.6;
}
/* El precio es el dato que manda en la card: mismo papel que le da
   DIRECCION-VISUAL.md #1 al dorado (marcar lo importante, una vez por
   bloque). A 2rem entra de sobra en el 3:1 de AA para texto grande. */
.product-listing-item__price{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  color:var(--ink);
  margin:0;
  line-height:1.2;
}
.product-listing-item__price-label{
  display:block;
  margin:0 0 .15rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--ink);
  opacity:.6;
}
.product-listing-item__price-value{
  display:inline-block;
  margin:0;
  font-size:2rem;
  font-weight:400;
  line-height:1.1;
  color:var(--brass);
}
.product-listing-item__price-vat{
  display:block;
  margin-top:.25rem;
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
  opacity:.6;
}
/* --- Producto con descuento ---
   - Cards del listado y de «Los más elegidos» (--promo): la card entera
     destaca, con un lavado dorado suave en vez del crema, borde dorado
     fino y una sombra cálida.
   - En las cards y en la ficha, junto al precio, la etiqueta «Experiencia
     en promoción» (__promo-label) y el precio anterior tachado.
   La etiqueta es el .badge--gold de DIRECCION-VISUAL.md (§5, el caso de
   promoción): píldora en degradado dorado con texto blanco y el icono de
   etiqueta. El precio
   anterior: un paso por debajo del actual y con el tachado en dorado.
   Las reglas del precio anterior van bajo __promo: la misma clase
   __regular-price la usa el selector de tarjeta regalo de reservas
   («Pagas: X Y»), que no cambia. --- */
.product-listing-item--promo,
.ritual-featured__card--promo{
  position:relative;
  background:color-mix(in srgb, var(--brass) 9%, #fff);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brass) 55%, transparent), 0 10px 28px color-mix(in srgb, var(--brass) 22%, transparent);
}
.product-listing-item__promo-label,
.ritual-featured__promo-label,
.product-detail__promo-label{
  display:inline-flex;
  align-items:center;
  gap:.3rem;
  padding:.3rem .75rem .3rem .55rem;
  border-radius:999px;
  /* Dorado de marca con un degradado muy leve hacia uno algo más intenso,
     y texto en blanco cálido (no blanco puro, que sobre el dorado quedaba
     duro). Para que se lea mejor sobre un fondo claro: letra un punto
     mayor y una sombra muy suave bajo el texto. */
  background:linear-gradient(135deg, var(--brass) 0%, color-mix(in srgb, var(--brass) 88%, var(--ink)) 100%);
  box-shadow:0 2px 8px rgba(41,37,28,.10);
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.8125rem;
  font-weight:700;
  line-height:1.2;
  letter-spacing:.02em;
  color:#fffaf2;
  text-shadow:0 1px 2px rgba(41,37,28,.28);
  white-space:nowrap;
}
.product-listing-item__promo-label::before,
.ritual-featured__promo-label::before,
.product-detail__promo-label::before{
  content:"\e54e";
  font-family:"Material Icons";
  font-size:.9375rem;
  font-weight:400;
  line-height:1;
  -webkit-font-feature-settings:"liga";
  font-feature-settings:"liga";
}
.product-listing-item__promo,
.product-detail__promo,
.ritual-featured__promo{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.35rem .6rem;
  margin:0 0 .4rem;
  line-height:1.3;
  color:var(--ink);
}
/* Precio anterior fuera de la línea de promoción: el «Pagas: X Y» del
   selector de tarjeta regalo de reservas (giftcard-picker.tpl). Mismo
   estilo que tenía antes de la etiqueta de promoción. */
.product-listing-item__regular-price{
  text-decoration:line-through;
  color:var(--ink);
  opacity:.5;
  margin-left:.5rem;
  font-size:1.125rem;
  font-weight:400;
}
.product-listing-item__promo .product-listing-item__regular-price,
.product-detail__promo .product-detail__regular-price,
.ritual-featured__promo .ritual-featured__regular-price{
  margin:0;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.2;
  color:rgba(41,37,28,.75);
  opacity:1;
  text-decoration:line-through;
  text-decoration-color:var(--brass);
  text-decoration-thickness:2px;
  white-space:nowrap;
}
.product-listing-item__giftcard-form{
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  width:100%;
  margin-top:auto;
}
.product-listing-item__giftcard-field{
  display:flex;
  align-items:baseline;
  gap:.75rem;
  width:100%;
}
.product-listing-item__giftcard-label{
  font-weight:700;
}
.product-listing-item__giftcard-wrap{
  flex:1 1 auto;
  max-width:12rem;
}
.product-listing-item__giftcard-input{
  text-align:center;
}
.product-listing-item__giftcard-help{
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
  opacity:.6;
  margin:.5rem 0 1.5rem;
}
/* Las acciones van al pie de la card: el botón y "¡Reserva tu cita
   ahora!" en la misma franja, o solo el CTA suelto en la variante de canje
   (sin <form>). Si no caben juntos (media rejilla en tableta, móvil), la
   reserva baja debajo del botón. */
.product-listing-item__actions,
.product-listing-item > .product-listing-item__add{
  margin-top:auto;
}
.product-listing-item__actions{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:1rem 1.25rem;
  width:100%;
}
/* "¡Reserva tu cita ahora!" es el acceso explícito a la ficha (el nombre
   también enlaza, pero como titular no se reconocía como enlace). Va en
   píldora --brass (.btn-pill--brass, el acento de marca de
   DIRECCION-VISUAL.md #1) para que resalte junto a "Añadir al carrito".
   Etiquetas fijas, sin el nombre del producto dentro: con un min-width
   común todos los botones del listado quedan del mismo ancho aunque el
   idioma cambie la longitud del texto. */
.product-listing-item__add,
.product-listing-item__book{
  min-width:15rem;
}
@media (max-width:420px){
  .product-listing-item__form,
  .product-listing-item__add,
  .product-listing-item__book{
    width:100%;
  }
  .product-listing-item__add,
  .product-listing-item__book{
    min-width:0;
  }
}

/* --- Descripción de la ficha de producto: estándar de cuerpo de home
   (Helvetica 400, 1.0625rem, line-height 1.7, --ink). El primer párrafo es
   el gancho — mantiene la negrita que ya trae el contenido migrado, pero la
   jerarquía la marca sobre todo la escala (un paso arriba, interlineado
   algo más corto), no solo el peso.
   Hasta el rediseño de la card del listado estas reglas se compartían con
   la descripción completa que pintaba la card; la card ya solo lleva un
   extracto (.product-listing-item__excerpt, más arriba), así que quedan
   solo para la ficha. --- */
.product-detail__description-body{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:1.0625rem;
  line-height:1.7;
  color:var(--ink);
  /* El hueco hasta "Ver más" lo pone el margen superior del propio enlace:
     con margen aquí también, y sin colapso posible (el enlace es
     inline-flex), se sumaban los dos. */
  margin:0;
}
/* 1.5rem y no el 1rem literal del estándar de home: con el cuerpo a
   1.0625rem y line-height 1.7 la caja de línea mide ~29px, así que un hueco
   de 16px entre párrafos queda por debajo del propio interlineado y el
   bloque se lee corrido. 24px es lo mínimo para que el corte de párrafo se
   vea como tal. */
.product-detail__description-body p{
  margin:0 0 1.5rem;
}
/* Mismo caso que en .category__description: el contenido migrado corta
   párrafos con <br /> dentro de un mismo <p>. */
.product-detail__description-body br{
  display:block;
  content:"";
  margin-bottom:.6rem;
}
/* :first-child, no :first-of-type: parte del contenido migrado abre con un
   <h3> que ya hace de gancho, y con :first-of-type el párrafo siguiente
   recibía además el tratamiento de entrada y quedaban dos ganchos seguidos. */
/* Texto destacado del estándar de home: 1.25rem (1.125rem en móvil),
   line-height 1.5. */
.product-detail__description-body > p:first-child{
  font-size:1.25rem;
  line-height:1.5;
  margin-bottom:1.5rem;
}
/* Titular dentro del contenido migrado: hace de gancho, así que se trata
   como el párrafo de entrada (mismo tamaño y peso) y no como un titular de
   sección — a la escala de Tindoghouse una frase entera pesaría más que el
   propio nombre del producto, que es el que tiene que mandar en la card. */
.product-detail__description-body h1,
.product-detail__description-body h2,
.product-detail__description-body h3,
.product-detail__description-body h4,
.product-detail__description-body h5,
.product-detail__description-body h6{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.25rem;
  font-weight:700;
  line-height:1.5;
  color:var(--ink);
  margin:0 0 1.5rem;
}
.product-detail__description-body > :last-child{
  margin-bottom:0;
}
.product-detail__description-body strong,
.product-detail__description-body b{
  font-weight:700;
  color:var(--ink);
}
.product-detail__description-body ul,
.product-detail__description-body ol{
  margin:0 0 1rem;
  padding-left:1.25rem;
}
.product-detail__description-body li{
  margin-bottom:.35rem;
}
.product-detail__description-body li p{
  margin:0;
}
/* Restos del editor de PS1.6 en el contenido migrado. */
.product-detail__description-body p:empty{
  display:none;
}
@media (max-width:767px){
  .product-detail__description-body{
    font-size:1rem;
  }
  .product-detail__description-body > p:first-child,
  .product-detail__description-body h1,
  .product-detail__description-body h2,
  .product-detail__description-body h3,
  .product-detail__description-body h4,
  .product-detail__description-body h5,
  .product-detail__description-body h6{
    font-size:1.125rem;
  }
}

/* ==== Calendario de disponibilidad (compartido) ====
   Consulta real a Bewe (ver product-availability-calendar.tpl, custom.js y
   cart-reservation.js, que pinta el mismo marcado en el checkout). Aquí va
   el calendario tal como se ve en el checkout: tarjeta propia de 360px.
   La ficha de producto lo adapta a su columna en "Ficha de producto —
   composición", más abajo. Días disponibles y hora con tinte --brass
   suave; día/hora elegidos en --brass sólido (DIRECCION-VISUAL.md #1). */
.availability-calendar{
  max-width:360px;
  padding:1.25rem;
  border-radius:12px;
  background:var(--ritual-cream);
  box-shadow:0 14px 30px rgba(0,0,0,.08);
  margin: 0 auto;
}
@media (max-width:767px){
  .availability-calendar{
    max-width:none;
  }
}
.availability-calendar__loading{
  display:none;
  font-size:.9rem;
  text-align:center;
  padding:1.5rem 0;
}
.availability-calendar__spinner{
  display:inline-block;
  width:20px;
  height:20px;
  margin-right:.5rem;
  vertical-align:middle;
  border:3px solid rgba(41,37,28,.15);
  border-top-color:var(--ink);
  border-radius:50%;
  animation:availability-calendar-spin .8s linear infinite;
}
@keyframes availability-calendar-spin{
  to{ transform:rotate(360deg); }
}
@media (prefers-reduced-motion: reduce){
  .availability-calendar__spinner{ animation:none; }
}
.availability-calendar.is-loading .availability-calendar__loading{
  display:block;
}
.availability-calendar.is-loading .availability-calendar__header,
.availability-calendar.is-loading .availability-calendar__weekdays,
.availability-calendar.is-loading .availability-calendar__days{
  display:none;
}
.availability-calendar__header{
  display:flex;
  align-items:center;
  justify-content:space-between;
  margin-bottom:1rem;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.02em;
}
.availability-calendar__nav{
  width:2rem;
  height:2rem;
  border:none;
  border-radius:50%;
  background:transparent;
  color:var(--ink);
  font-size:1.25rem;
  line-height:1;
  cursor:pointer;
  transition:background .2s ease;
}
.availability-calendar__nav:hover:not(:disabled){
  background:rgba(41,37,28,.08);
}
.availability-calendar__nav:disabled{
  opacity:.3;
  cursor:default;
}
.availability-calendar__weekdays,
.availability-calendar__days{
  display:grid;
  grid-template-columns:repeat(7, 1fr);
  gap:.35rem;
  text-align:center;
}
.availability-calendar__weekdays{
  margin-bottom:.5rem;
  font-size:.75rem;
  font-weight:700;
  text-transform:uppercase;
  opacity:.6;
}
.availability-calendar__day{
  aspect-ratio:1;
  display:flex;
  align-items:center;
  justify-content:center;
  border:none;
  border-radius:8px;
  background:transparent;
  font-size:.85rem;
  font-weight:400;
  color:var(--ink);
  cursor:default;
}
.availability-calendar__day--blank{
  visibility:hidden;
}
.availability-calendar__day--past{
  opacity:.3;
}
.availability-calendar__day--unavailable{
  opacity:.3;
}
.availability-calendar__day--available{
  background:color-mix(in srgb, var(--brass) 12%, #fff);
  border:1px solid rgba(41,37,28,.12);
  color:var(--ink);
  cursor:pointer;
  transition:background var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease), transform var(--motion-hover) var(--motion-ease);
}
.availability-calendar__day--available:hover{
  background:color-mix(in srgb, var(--brass) 26%, #fff);
  border-color:var(--brass);
  transform:scale(1.05);
}
.availability-calendar__day--selected{
  background:var(--brass);
  border-color:var(--brass);
  color:#fff;
  font-weight:700;
}
.availability-calendar__day--selected:hover{
  background:var(--brass);
  transform:none;
}
@media (prefers-reduced-motion: reduce){
  .availability-calendar__day--available{
    transition:none;
  }
  .availability-calendar__day--available:hover{
    transform:none;
  }
}
.availability-calendar__message{
  margin-top:1rem;
  font-size:.9rem;
  text-align:center;
}
.availability-calendar__hours{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
  margin-top:1rem;
  justify-content:center;
}
.availability-calendar__hours-title{
  flex-basis:100%;
  text-align:center;
  font-size:.75rem;
  font-weight:700;
  text-transform:uppercase;
  opacity:.6;
  margin:0 0 .25rem;
}
/* Modo 'info' (checkout, horas no clicables: <span>): se deja en --ink,
   es un dato de referencia, no un estado de selección. */
.availability-calendar__hour{
  padding:.35rem .75rem;
  border-radius:999px;
  background:var(--ink);
  color:#fff;
  font-size:.85rem;
  font-weight:600;
  cursor:default;
}
/* Modo 'select' (ficha de producto): mismo tratamiento suave que los días,
   con --brass como acento de hover/selección en vez del relleno --ink
   sólido anterior. */
button.availability-calendar__hour{
  cursor:pointer;
  border:1px solid rgba(41,37,28,.15);
  background:#fff;
  color:var(--ink);
  font:inherit;
  font-weight:600;
  transition:background var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease);
}
button.availability-calendar__hour:hover:not(:disabled){
  border-color:var(--brass);
  background:color-mix(in srgb, var(--brass) 12%, #fff);
}
button.availability-calendar__hour--selected{
  background:var(--brass);
  border-color:var(--brass);
  color:#fff;
}
button.availability-calendar__hour--selected:hover{
  background:var(--brass);
}
@media (prefers-reduced-motion: reduce){
  button.availability-calendar__hour{
    transition:none;
  }
}
.availability-calendar__hour--blocked{
  opacity:.3;
  cursor:not-allowed !important;
}
/* Móvil: la tira de horas es la superficie con más chips pequeños del
   calendario (hasta ~47 en el modal de cadena, agrupadas en mañana/tarde) —
   objetivo de toque cómodo (44px de referencia habitual) en vez de la
   densidad de escritorio. */
@media (max-width:767px){
  button.availability-calendar__hour{
    padding:.5rem .9rem;
    min-height:44px;
  }
  /* Misma razón para las flechas de mes: 2rem (32px) es cómodo con ratón y
     escaso con el dedo, y son el único control para llegar a un día que no
     esté en el mes en curso. */
  .availability-calendar__nav{
    width:44px;
    height:44px;
  }
}
.js-order-group-modal-summary-text{
  font-weight:700;
}

/* ==== Ficha de producto — composición (servicios legacy PS1.6, sin imagen) ====
   Los servicios de este catálogo no tienen foto (ver .product-listing-item
   en el listado de categoría), así que la ficha no tiene galería.
   - Cabecera centrada: nombre + frase de marca.
   - Reserva en dos columnas, igual que la card del listado: a la izquierda
     "¿Cómo quieres reservar?" y el calendario; a la derecha los datos del
     servicio y, debajo, las dos vías. Con áreas de grid para que en una
     columna (<992px) los datos vayan antes que el calendario.
   - "¿En qué consiste?" en dos columnas: título | texto a ancho de lectura.
   Estándar tipográfico de home/categoría (ver "Homepage — type standard" y
   "Extensiones del estándar"): antetítulo, dato, dato destacado, titular
   de sección y de elemento, cuerpo y metadato. */
.product-detail__container{
  padding-bottom:4rem;
}
@media (max-width:767px){
  .product-detail__container{
    padding-bottom:3rem;
  }
}
.product-detail__header{
  margin:0 0 4.5rem;
}
@media (max-width:767px){
  .product-detail__header{
    margin-bottom:2.5rem;
  }
}
.product-detail__title{
  font-size:3rem;
  text-align:center;
  text-transform:uppercase;
  margin:6.5rem 0 .25rem;
}
@media (max-width:767px){
  .product-detail__title{
    font-size:2rem;
    margin-top:2rem;
  }
}
/* Frase de marca (feature "Frase"): mismo tratamiento que
   .category__subtitulo. El margen inferior
   de .25rem del título colapsa con este 1rem: el hueco real queda en 1rem,
   igual que category__subtitulo sobre category__title. */
.product-detail__tagline{
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:clamp(2rem, 2.8vw, 2.5rem);
  line-height:1.15;
  color:var(--ink);
  text-align:center;
  margin:1rem 0 0;
}
@media (max-width:767px){
  .product-detail__tagline{
    font-size:1.875rem;
  }
}

/* --- Reserva: datos + vías | calendario ---
   5fr/6fr: el calendario necesita algo más de ancho que el texto de la
   izquierda para que sus 7 columnas respiren. align-items:start, como en la
   card del listado: las dos columnas arrancan en la misma horizontal. */
.product-detail__booking{
  display:grid;
  grid-template-columns:minmax(0, 5fr) minmax(0, 6fr);
  grid-template-rows:auto 1fr;
  grid-template-areas:
    "facts calendar"
    "ways calendar";
  column-gap:clamp(3rem, 6vw, 6rem);
  align-items:start;
}
.product-detail__calendar{
  grid-area:calendar;
  min-width:0;
  /* Al llegar desde el paso 1 (custom.js), que la cabecera fija no tape
     el mes. */
  scroll-margin-top:calc(var(--ritual-header-h, 0px) + 1rem);
}
/* Ídem con el paso 2 al elegir un día (custom.js lleva la vista a sus
   horas). */
.product-detail__step{
  scroll-margin-top:calc(var(--ritual-header-h, 0px) + 1rem);
}
.product-detail__facts{
  grid-area:facts;
  min-width:0;
}
.product-detail__ways{
  grid-area:ways;
  min-width:0;
}
.product-detail__ways:focus{
  outline:none;
}
/* Una columna: datos, "Reserva tu cita", calendario y, al final, la card
   de "Cómpralo y resérvalo más tarde". Esa card vive dentro del form de
   .product-detail__ways junto a la vía 1 (las dos vías comparten form, ver
   product.tpl), así que para colocar el calendario entre ellas el
   contenedor y el form se disuelven (display:contents: el form sigue
   enviando igual) y el orden lo da `order` sobre una columna flex. El
   resto de hijos del form (inputs ocultos, bloques de hooks) van detrás. */
@media (max-width:991px){
  .product-detail__booking{
    display:flex;
    flex-direction:column;
    /* El align-items:start de las dos columnas, en una columna flex,
       encogía cada bloque a su contenido (el calendario se estrechaba). */
    align-items:stretch;
    max-width:40rem;
    margin:0 auto;
  }
  .product-detail__ways,
  .product-detail__ways > form{
    display:contents;
  }
  .product-detail__ways > form > *{
    order:5;
  }
  .product-detail__facts{
    order:1;
  }
  .product-detail__ways > form > .product-detail__way--now{
    order:2;
    margin-bottom:3rem;
  }
  .product-detail__calendar{
    order:3;
  }
  .product-detail__ways > form > .product-detail__way--later{
    order:4;
  }
}

/* Sin reserva online (sin URL de disponibilidad, o Bewe responde
   bookable:false): fuera el calendario y todo lo que habla de reservar;
   queda una sola columna con los datos y el botón de compra. */
.product-detail--no-booking .product-detail__booking{
  grid-template-columns:minmax(0, 1fr);
  grid-template-rows:none;
  grid-template-areas:
    "facts"
    "ways";
  max-width:40rem;
  margin:0 auto;
}
.product-detail--no-booking .product-detail__calendar,
.product-detail--no-booking .product-detail__way--now,
.product-detail--no-booking .product-detail__way--later .product-detail__way-title,
.product-detail--no-booking .product-detail__note{
  display:none;
}
.product-detail--no-booking .product-detail__ways{
  margin-bottom:0;
}
.product-detail--no-booking .product-detail__way--later{
  margin-top:0;
  padding:0;
  border:0;
  border-radius:0;
  background:none;
}

/* --- Calendario en la ficha ---
   Superficie de la card del listado (--ritual-cream rebajado, 16px, sin
   borde ni sombra) en vez de la tarjeta con sombra del checkout, y a todo
   el ancho de su columna. Las celdas dejan de ser cuadradas: a este ancho
   un día cuadrado mediría ~70px y el mes pasaría de 500px de alto. En
   móvil vuelven a medir lo que su columna, alto fijo de 2.5rem. */
.product-detail__calendar .availability-calendar{
  max-width:none;
  margin:0;
  padding:2.5rem;
  border-radius:16px;
  background:#fbf8f5;
  background:color-mix(in srgb, var(--ritual-cream) 55%, #fff);
  box-shadow:none;
}
@media (max-width:767px){
  .product-detail__calendar .availability-calendar{
    padding:1.75rem 1.25rem;
  }
}
/* Mientras carga, la card ya ocupa lo que ocupará el mes: sin esto la
   página salta al llegar la respuesta de Bewe. */
.product-detail__calendar .availability-calendar.is-loading{
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:26rem;
}
.product-detail__calendar .availability-calendar__loading{
  font-size:.9375rem;
  font-weight:400;
  color:var(--ink);
}
.product-detail__calendar .availability-calendar__header{
  margin-bottom:1.5rem;
}
/* Mes como titular de elemento (Tindoghouse 400, 1.625rem, sin mayúsculas). */
.product-detail__calendar .availability-calendar__month{
  font-family:"Tindoghouse",cursive;
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  text-transform:none;
  letter-spacing:0;
  color:var(--ink);
}
.product-detail__calendar .availability-calendar__nav{
  width:2.5rem;
  height:2.5rem;
  border:1px solid rgba(41,37,28,.12);
  transition:background-color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
.product-detail__calendar .availability-calendar__nav:hover:not(:disabled){
  background:#fff;
  border-color:var(--brass);
}
.product-detail__calendar .availability-calendar__weekdays{
  margin-bottom:.75rem;
  font-size:.72rem;
  letter-spacing:.12em;
  color:var(--ink);
}
.product-detail__calendar .availability-calendar__days{
  gap:.5rem;
}
.product-detail__calendar .availability-calendar__day{
  aspect-ratio:auto;
  height:clamp(2.5rem, 3.6vw, 3.25rem);
  font-size:.9375rem;
}
@media (max-width:767px){
  .product-detail__calendar .availability-calendar__days{
    gap:.35rem;
  }
  .product-detail__calendar .availability-calendar__day{
    height:2.5rem;
  }
}
/* Los mensajes (sin horas / error) cierran la card separados del mes por
   un filete, y entran con el fundido lento del sitio. Las horas ya no van
   aquí: se pintan en el paso "Selecciona una hora" de la vía 1
   (.product-detail__step-hours, más abajo). */
.product-detail__calendar .availability-calendar__message{
  margin-top:2rem;
  padding-top:1.75rem;
  border-top:1px solid rgba(41,37,28,.1);
  font-size:.9375rem;
  font-weight:400;
  line-height:1.5;
  color:var(--ink);
  animation:product-detail-fade-in var(--motion-duration) var(--motion-ease);
}
@keyframes product-detail-fade-in{
  from{ opacity:0; }
  to{ opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  .product-detail__calendar .availability-calendar__message{
    animation:none;
  }
}

/* --- Calendario fuera de la ficha: tipografía ---
   La landing de reservas (/reservas) y los modales de reserva del
   checkout, la confirmación y Mi cuenta pintan el calendario compartido
   de arriba, cuya tipografía base quedó de antes del estándar (mes en
   mayúsculas/700, días a .85rem, horas en 600). Aquí toman la misma
   tipografía que el calendario de la ficha (mes como titular de elemento,
   días de la semana y "Selecciona una hora" en antetítulo, días, horas y
   mensajes en dato), sin su composición de columna ancha. */
.rb-booking-landing .availability-calendar__month,
#cart-reservation-modal .availability-calendar__month,
#cart-group-reservation-modal .availability-calendar__month,
#order-group-reservation-modal .availability-calendar__month{
  font-family:"Tindoghouse",cursive;
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  text-transform:none;
  letter-spacing:0;
  color:var(--ink);
}
.rb-booking-landing .availability-calendar__weekdays,
.rb-booking-landing .availability-calendar__hours-title,
#cart-reservation-modal .availability-calendar__weekdays,
#cart-reservation-modal .availability-calendar__hours-title,
#cart-group-reservation-modal .availability-calendar__weekdays,
#cart-group-reservation-modal .availability-calendar__hours-title,
#order-group-reservation-modal .availability-calendar__weekdays,
#order-group-reservation-modal .availability-calendar__hours-title{
  font-size:.72rem;
  line-height:1.4;
  letter-spacing:.12em;
  color:var(--ink);
}
.rb-booking-landing .availability-calendar__day,
.rb-booking-landing .availability-calendar__hour,
.rb-booking-landing .availability-calendar__loading,
.rb-booking-landing .availability-calendar__message,
#cart-reservation-modal .availability-calendar__day,
#cart-reservation-modal .availability-calendar__hour,
#cart-reservation-modal .availability-calendar__loading,
#cart-reservation-modal .availability-calendar__message,
#cart-group-reservation-modal .availability-calendar__day,
#cart-group-reservation-modal .availability-calendar__hour,
#cart-group-reservation-modal .availability-calendar__loading,
#cart-group-reservation-modal .availability-calendar__message,
#order-group-reservation-modal .availability-calendar__day,
#order-group-reservation-modal .availability-calendar__hour,
#order-group-reservation-modal .availability-calendar__loading,
#order-group-reservation-modal .availability-calendar__message{
  font-size:.9375rem;
  font-weight:400;
  line-height:1.4;
}
.rb-booking-landing .availability-calendar__day--selected,
.rb-booking-landing .availability-calendar__hour--selected,
#cart-reservation-modal .availability-calendar__day--selected,
#cart-reservation-modal .availability-calendar__hour--selected,
#cart-group-reservation-modal .availability-calendar__day--selected,
#cart-group-reservation-modal .availability-calendar__hour--selected,
#order-group-reservation-modal .availability-calendar__day--selected,
#order-group-reservation-modal .availability-calendar__hour--selected{
  font-weight:700;
}
.rb-booking-landing .availability-calendar__message,
#cart-reservation-modal .availability-calendar__message,
#cart-group-reservation-modal .availability-calendar__message,
#order-group-reservation-modal .availability-calendar__message{
  line-height:1.5;
  color:var(--ink);
}

/* --- Datos del servicio: duración y precio en una fila, con la pareja
   etiqueta + valor del listado (antetítulo encima, precio como dato
   destacado en --brass). Un filete los separa de las vías. --- */
.product-detail__facts{
  display:flex;
  flex-wrap:wrap;
  align-items:flex-start;
  column-gap:3.5rem;
  row-gap:1.5rem;
  margin:0 0 2rem;
  padding-bottom:2rem;
  border-bottom:1px solid rgba(41,37,28,.12);
}
.product-detail__fact-label{
  display:block;
  margin:0 0 .35rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  line-height:1.4;
  text-transform:uppercase;
  color:var(--ink);
  opacity:.6;
}
/* 1.125rem y no el 1.25rem de texto destacado: las duraciones llegan
   hasta "60 min + ritual de bienvenida y cierre" y a 1.25rem empujaban el
   precio a una segunda fila. */
.product-detail__duration{
  margin:0;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.5;
  color:var(--ink);
}
.product-detail__price{
  margin:0;
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
.product-detail__price-value{
  display:inline-block;
  font-size:2.25rem;
  font-weight:400;
  line-height:1.1;
  color:var(--brass);
}
.product-detail__price-vat{
  display:block;
  margin-top:.25rem;
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
  opacity:.6;
}
@media (max-width:767px){
  .product-detail__facts{
    column-gap:2.5rem;
    padding-bottom:2rem;
  }
  .product-detail__duration{
    font-size:1rem;
  }
  .product-detail__price-value{
    font-size:2rem;
  }
}

/* --- Las dos vías ---
   No son dos cajas: la vía 1 es la que se completa con el calendario y
   lleva el peso (titular de elemento, pasos, botón sólido); la vía 2 queda
   debajo tras un filete, un paso de tamaño por debajo y con el botón en
   su variante outline. Se leen como alternativa, no como gemelas. */
.product-detail__way-title{
  margin:0 0 .5rem;
  font-size:1.625rem;
  line-height:1.2;
  font-weight:400;
  color:var(--ink);
}
.product-detail__way-text{
  margin:0;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1rem;
  font-weight:400;
  line-height:1.6;
  color:var(--ink);
}
@media (max-width:767px){
  .product-detail__way-title{
    font-size:1.5rem;
  }
}

/* Pasos de la vía 1: siempre dicen lo elegido o lo que falta. Pendiente
   atenuado; paso hecho con el número relleno en --brass y el valor
   destacado. El paso actual es el que tiene que llevarse la vista: va en
   un panel teñido de --brass, con el número relleno y el texto en negrita,
   y al activarse (clase --attention, la pone custom.js) late un par de
   veces. Con solo el cambio de color del número se dudaba de cuál era el
   siguiente paso tras elegir día. */
.product-detail__steps{
  display:grid;
  gap:.5rem;
  margin:1.75rem 0 2rem;
  padding:0;
  list-style:none;
}
.product-detail__step{
  display:grid;
  grid-template-columns:2.25rem minmax(0, 1fr);
  align-items:center;
  column-gap:1rem;
  padding:.75rem 1rem;
  border:1px solid transparent;
  border-radius:12px;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
  opacity:.5;
  transition:opacity var(--motion-hover) var(--motion-ease), background-color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
.product-detail__step--current,
.product-detail__step--done{
  opacity:1;
}
.product-detail__step--current{
  background:color-mix(in srgb, var(--brass) 10%, #fff);
  border-color:color-mix(in srgb, var(--brass) 45%, #fff);
}
.product-detail__step--current .product-detail__step-text{
  font-size:1.125rem;
  font-weight:700;
}
.product-detail__step-mark{
  display:flex;
  align-items:center;
  justify-content:center;
  width:2.25rem;
  height:2.25rem;
  border:1px solid rgba(41,37,28,.25);
  border-radius:50%;
  font-size:.8125rem;
  font-weight:700;
  transition:background-color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease);
}
.product-detail__step--current .product-detail__step-mark,
.product-detail__step--done .product-detail__step-mark{
  background:var(--brass);
  border-color:var(--brass);
  color:#fff;
}
.product-detail__step--done .product-detail__step-text{
  font-size:1.25rem;
}
.product-detail__step--attention{
  animation:product-detail-step-attention 1.1s var(--motion-ease) 2;
}
.product-detail__step--attention .product-detail__step-mark{
  animation:product-detail-step-mark-pulse 1.1s var(--motion-ease) 2;
}
@keyframes product-detail-step-attention{
  0%, 100%{ background-color:color-mix(in srgb, var(--brass) 10%, #fff); }
  40%{ background-color:color-mix(in srgb, var(--brass) 28%, #fff); }
}
@keyframes product-detail-step-mark-pulse{
  0%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--brass) 55%, transparent); }
  100%{ box-shadow:0 0 0 .75rem transparent; }
}
/* Horas del día elegido, dentro del paso 2 y alineadas con su texto
   (segunda columna), en vez de al pie del calendario. El antetítulo
   "Selecciona una hora" que BeweCalendar pone encima de las horas sobra
   aquí: el propio paso ya lo dice justo encima. */
.product-detail__step-hours{
  grid-column:2;
  justify-content:flex-start;
  gap:.5rem;
  margin-top:.875rem;
  animation:product-detail-fade-in var(--motion-duration) var(--motion-ease);
}
.product-detail__step-hours .availability-calendar__hours-title{
  display:none;
}
.product-detail__step-hours button.availability-calendar__hour{
  padding:.5rem 1rem;
  font-size:.9375rem;
  font-weight:400;
}
.product-detail__step-hours button.availability-calendar__hour--selected{
  font-weight:700;
}
@media (max-width:767px){
  .product-detail__step{
    column-gap:.75rem;
    padding:.75rem;
  }
  /* En móvil las horas usan todo el ancho del paso: bajo el texto dejaban
     una columna estrecha y con 44px por chip cabían muy pocas por fila. */
  .product-detail__step-hours{
    grid-column:1 / -1;
  }
}
@media (prefers-reduced-motion: reduce){
  .product-detail__step,
  .product-detail__step-mark{
    transition:none;
  }
  .product-detail__step--attention,
  .product-detail__step--attention .product-detail__step-mark,
  .product-detail__step-hours{
    animation:none;
  }
}

.product-detail__way-actions{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:1rem 1.75rem;
}
.product-detail__confirm{
  min-width:15rem;
}
/* Deshabilitado (falta día u hora). Sin opacidad: el .disabled de
   .btn-pill (--ink al 40%) y cualquier --ink rebajado sobre blanco dan un
   gris neutro, porque --ink es casi negro sin apenas tono. Se construye
   con los tonos cálidos de la marca: fondo --ritual-cream, filete interior
   de 1px en --brass rebajado (inset, para no cambiar el tamaño respecto al
   botón activo, que no lleva borde) y texto en --brass. Plano, sin sombra
   ni elevación al hover y con cursor not-allowed, frente al botón activo
   sólido en --ink: se lee como el mismo botón aún no disponible. La guarda
   de custom.js sigue bloqueando el clic aunque aquí se reactiven los
   pointer-events (necesarios para que se vea el cursor). */
.product-detail__confirm.disabled,
.product-detail__confirm.disabled:hover{
  opacity:1;
  pointer-events:auto;
  cursor:not-allowed;
  background:var(--ritual-cream);
  color:var(--brass);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--brass) 45%, #fff);
  transform:none;
}
/* "Quitar": enlace subrayado en --brass y negrita, --ink al hover. Más
   presente que el metadato accionable del estándar (--ink atenuado), que
   aquí pasaba desapercibido junto al día elegido. Va dentro del paso 1, bajo el día elegido y alineado
   con su texto (segunda columna de la rejilla del paso). */
.product-detail__clear{
  grid-column:2;
  justify-self:start;
  margin-top:.375rem;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.9375rem;
  font-weight:700;
  line-height:1.4;
  color:var(--brass);
  text-decoration:underline;
  text-underline-offset:3px;
  transition:color var(--motion-hover) var(--motion-ease);
}
.product-detail__clear:hover,
.product-detail__clear:focus-visible{
  color:var(--ink);
}
@media (prefers-reduced-motion: reduce){
  .product-detail__clear{transition:none}
}

/* Barra fija inferior con la reserva elegida y una copia del botón de la
   vía 1 (custom.js la muestra con día y hora elegidos mientras el botón
   real no se ve). Franja a todo el ancho en --ritual-cream con filete
   superior en --brass: el mismo tono de la card del calendario, así que se
   lee como la reserva que se acaba de hacer ahí. Contenido centrado: día y
   hora (icono en --brass + dato en negrita, separados por un filete
   vertical) y el botón sólido. Entra y sale deslizando desde el borde
   inferior; oculta se queda fuera de pantalla y con visibility:hidden, así
   que no se puede tabular hasta ella. */
.product-detail__sticky-confirm{
  position:fixed;
  left:0;
  right:0;
  bottom:0;
  z-index:1030;
  padding:1rem 0;
  padding-bottom:calc(1rem + env(safe-area-inset-bottom, 0px));
  background:var(--ritual-cream);
  border-top:2px solid var(--brass);
  box-shadow:0 -10px 30px rgba(41,37,28,.12);
  transform:translateY(100%);
  visibility:hidden;
  transition:transform var(--motion-duration) var(--motion-ease), visibility 0s linear var(--motion-duration);
}
.product-detail__sticky-confirm--visible{
  transform:none;
  visibility:visible;
  transition:transform var(--motion-duration) var(--motion-ease), visibility 0s;
}
.product-detail__sticky-confirm-inner{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:2.5rem;
}
.product-detail__sticky-confirm-summary{
  display:flex;
  align-items:center;
  margin:0;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
  font-weight:700;
  line-height:1.3;
  color:var(--ink);
}
.product-detail__sticky-confirm-item{
  display:inline-flex;
  align-items:center;
  gap:.5rem;
}
.product-detail__sticky-confirm-item + .product-detail__sticky-confirm-item{
  margin-left:1.25rem;
  padding-left:1.25rem;
  border-left:1px solid color-mix(in srgb, var(--brass) 45%, transparent);
}
.product-detail__sticky-confirm-item .material-icons{
  font-size:1.375rem;
  color:var(--brass);
}
.product-detail__sticky-confirm-button{
  min-width:18rem;
  height:3.25rem;
}
@media (max-width:767px){
  .product-detail__sticky-confirm{
    padding-top:.75rem;
    padding-bottom:calc(.75rem + env(safe-area-inset-bottom, 0px));
  }
  .product-detail__sticky-confirm-inner{
    flex-direction:column;
    align-items:stretch;
    gap:.625rem;
  }
  .product-detail__sticky-confirm-summary{
    justify-content:center;
    font-size:1rem;
  }
  .product-detail__sticky-confirm-item .material-icons{
    font-size:1.25rem;
  }
  .product-detail__sticky-confirm-button{
    width:100%;
    min-width:0;
    padding-inline:1rem;
  }
}
@media (prefers-reduced-motion: reduce){
  .product-detail__sticky-confirm,
  .product-detail__sticky-confirm--visible{
    transition:none;
  }
}
/* Con la barra a la vista: el botón de WhatsApp sube por encima de ella y
   la página gana al final su alto, para que no tape el pie. */
body.has-booking-sticky{
  padding-bottom:var(--booking-sticky-h, 0px);
}
body.has-booking-sticky .ritual-whatsapp-float{
  bottom:calc(var(--booking-sticky-h, 0px) + 1.25rem);
}
/* Barra fija "Pagar" de todo el sitio (.ritual-site-cart-bar, footer.tpl):
   mismo hueco al pie y misma subida del botón de WhatsApp. En la ficha cede
   el sitio a la barra de reserva mientras esta se ve: las dos ocupan el
   mismo borde inferior. */
body.has-cart-bar:not(.has-booking-sticky){
  padding-bottom:var(--cart-bar-h, 0px);
}
body.has-cart-bar:not(.has-booking-sticky) .ritual-whatsapp-float{
  bottom:calc(var(--cart-bar-h, 0px) + 1.25rem);
}
body.has-booking-sticky .ritual-site-cart-bar.ritual-cart-sticky--visible{
  transform:translateY(100%);
  visibility:hidden;
  transition:transform var(--motion-duration) var(--motion-ease), visibility 0s linear var(--motion-duration);
}

/* --- Aviso de reserva encadenada (§6.1 de RESERVAS-MULTIPLES.md) ---
   Aparece dentro de la vía 1 solo cuando el carrito ya tiene otro servicio
   reservable. Es una oferta, no un paso: se lee como una nota al margen de
   la vía, no como una tercera vía. De ahí el filete en --brass a la
   izquierda y el lavado del mismo tono al 6% (el mismo recurso que
   .rb-chain__order dentro del modal, para que el cliente reconozca que
   habla de lo mismo) en vez de una caja con borde propio. */
.product-detail__chain{
  display:block;
  margin-top:2.5rem;
  padding:1.75rem 1.75rem 1.875rem;
  border-left:2px solid var(--brass);
  background:color-mix(in srgb, var(--brass) 10%, transparent);
  animation:product-detail-chain-in var(--motion-duration) var(--motion-ease) both;
}
/* Rótulo: antetítulo del estándar en --brass. Le da nombre a la oferta
   antes de explicarla — sin él, el bloque empezaba directamente por un
   "Ya tienes X en el carrito" que se leía como un aviso más. */
.product-detail__chain-kicker{
  margin:0 0 .5rem;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.72rem;
  font-weight:700;
  line-height:1.4;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--brass);
}
.product-detail__chain-text{
  margin:0 0 1.25rem;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.6;
  color:var(--ink);
}
/* Fue enlace, luego botón outline y ahora sólido --brass (§14 del encargo:
   el outline no bastaba). Es la acción de más valor de la ficha; el sólido
   --ink sigue siendo el de comprar, así que el acento los distingue en vez
   de enfrentarlos. */
.product-detail__chain-action{
  margin-top:.25rem;
}
/* Aviso de reserva conjunta al entrar en la ficha (§15 del encargo): el
   mismo texto que el bloque de la vía 1, en el paso de "texto destacado"
   porque aquí es lo único que hay que leer. */
.rb-chain-invite__text{
  margin:0 0 .75rem;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.6;
  color:var(--ink);
}
.rb-chain-invite__note{
  margin:0;
  font-size:.9375rem;
  font-weight:400;
  line-height:1.6;
  color:rgba(41,37,28,.75);
}
@keyframes product-detail-chain-in{
  from{opacity:0;transform:translateY(calc(var(--motion-distance) / 2))}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion: reduce){
  .product-detail__chain{animation:none}
}

/* Vía 2 como card propia, para que comprar sin reserva se lea como otro
   proceso y no como la continuación de la vía 1. Distinta de la del
   calendario a propósito: aquella es superficie crema rellena y sin borde;
   esta es blanca con filete fino, más ligera, porque es la alternativa y no
   el camino principal. Mismo radio (16px) para que sigan siendo familia. */
.product-detail__way--later{
  margin-top:2.5rem;
  padding:2rem;
  border:1px solid rgba(41,37,28,.14);
  border-radius:16px;
  background:#fff;
}
.product-detail__way--later .product-detail__way-title{
  font-size:1.25rem;
}
.product-detail__way--later .product-detail__way-text{
  font-size:.9375rem;
  opacity:.75;
}
@media (max-width:420px){
  .product-detail__confirm{
    min-width:0;
    width:100%;
  }
  /* El sólido de la reserva conjunta creció en la pasada visual (§14): en
     420px "Reservar en la misma cita" no cabe en una línea dentro de un
     padding de píldora, así que ocupa el ancho como el resto de CTAs de
     esta columna. El bloque también afloja el padding lateral. */
  .product-detail__chain{
    padding:1.5rem 1.25rem;
  }
  .product-detail__chain-action{
    width:100%;
  }
}

/* Botón "Añadir al carrito" (product-add-to-cart.tpl override en tema
   hijo, clase .btn-pill): forma/color/hover ya los da la clase maestra.
   Aquí va en la variante outline (.btn-pill--secondary, replicada porque
   la clase no está en la plantilla), para quedar por debajo del botón
   sólido de la vía 1. Hummingbird fuerza width:100% en .page-product
   .product__add-to-cart-button — se anula para que mida lo que su
   contenido — y se oculta el icono (texto puro, como el resto de CTAs). */
.product-detail__way--later .product__add-to-cart-container{
  margin-top:1.5rem;
}
.product-detail__way--later .product__add-to-cart-button{
  width:auto;
  background:transparent;
  color:var(--ink);
  border:1px solid var(--ink);
  box-shadow:none;
}
.product-detail__way--later .product__add-to-cart-button:hover{
  background:var(--ink);
  color:#fff;
}
.product-detail__way--later .product__add-to-cart-button .material-icons{
  display:none;
}
/* Selector de cantidad de la vía 2 (RESERVAS-MULTIPLES.md §7.2 punto 1:
   "el selector de cantidad se muestra junto al botón de añadir al
   carrito"). Estuvo oculto con display:none desde ce00d28e, cuando el
   original no lo mostraba y una compra sólo podía acabar en una cita; con
   la cantidad múltiple implementada (N unidades = N líneas = N pedidos = N
   códigos de reserva, D10) ya hay a dónde llevar la segunda unidad, así que
   se muestra.

   No hace falta tocar la plantilla: .product__actions-qty-add ya es un flex
   con gap de 1rem en el tema padre y el stepper ya es hermano del botón.
   Aquí sólo se le da la forma del sitio — píldora en contorno, misma altura
   y mismo borde que .btn-pill--secondary, que es la variante del botón que
   tiene al lado. */
.product-detail__ways .quantity-button__group{
  width:auto;
  border:1px solid var(--ink);
  border-radius:999px;
  overflow:hidden;
}
.product-detail__ways .quantity-button__group .btn{
  border:none;
  border-radius:0;
  background:transparent;
  color:var(--ink);
  padding:.5rem .75rem;
  box-shadow:none;
}
.product-detail__ways .quantity-button__group .btn:hover{
  opacity:1;
  background:rgba(41,37,28,.08);
}
.product-detail__ways .quantity-button__group .btn .material-icons{
  font-size:1.125rem;
}
.product-detail__ways .quantity-button__group .form-control{
  width:2.75rem;
  max-width:2.75rem;
  border:none;
  border-radius:0;
  background:transparent;
  color:var(--ink);
  text-align:center;
  font-weight:700;
  font-size:.95rem;
  padding:.5rem 0;
  box-shadow:none;
}
.product-detail__ways .quantity-button__group .form-control:focus{
  box-shadow:none;
  background:rgba(41,37,28,.06);
}
/* El input llega con type="text" del include del tema padre, así que no
   pinta las flechas nativas; esto cubre el caso de que algún día venga como
   number y no se solapen con los botones del stepper. */
.product-detail__ways .quantity-button__group .form-control::-webkit-outer-spin-button,
.product-detail__ways .quantity-button__group .form-control::-webkit-inner-spin-button{
  -webkit-appearance:none;
  margin:0;
}
/* Selector y botón siempre en la misma línea. El tema padre deja la fila
   con flex-wrap y, por debajo de 576px, pone .product__quantity a
   width:100%, que mandaba el botón a la línea de abajo. */
.product-detail__way--later .product__actions-qty-add{
  flex-wrap:nowrap;
  margin-block-end:0;
}
.product-detail__way--later .product__quantity{
  width:auto;
  flex-shrink:0;
}
.product-detail__way--later .product__add-to-cart{
  min-width:0;
}
/* Misma altura para selector y botón: con sus paddings y tamaños de letra
   propios, el stepper quedaba unos píxeles más bajo que la píldora. Se fija
   una altura común (algo más alta que la natural de .btn-pill) y el grupo
   estira sus tres piezas a ella; flex-wrap:nowrap porque .input-group del
   tema padre envuelve. */
.product-detail__way--later .quantity-button__group,
.product-detail__way--later .product__add-to-cart-button{
  box-sizing:border-box;
  height:3.25rem;
}
.product-detail__way--later .quantity-button__group{
  flex-wrap:nowrap;
  align-items:stretch;
}
.product-detail__way--later .quantity-button__group .btn{
  display:flex;
  align-items:center;
  padding-top:0;
  padding-bottom:0;
}
.product-detail__way--later .quantity-button__group .form-control{
  height:auto;
  padding-top:0;
  padding-bottom:0;
}
@media (max-width:767px){
  .product-detail__way--later{
    padding:1.5rem 1.25rem;
  }
}
@media (max-width:420px){
  .product-detail__ways .product__actions-qty-add{
    gap:.75rem;
  }
  /* En la línea que queda tras el selector, el botón ocupa el resto y
     afloja el padding lateral de la píldora para que "Añadir al carrito"
     quepa sin partirse. */
  .product-detail__way--later .product__add-to-cart-button{
    width:100%;
    padding-inline:1rem;
  }
}

/* --- "¿En qué consiste?": el bloque entero (filete, título y texto) va
   centrado en la página con un ancho de lectura de 38rem — unos 70-75
   caracteres por línea al 1.0625rem del cuerpo. El sobrante se reparte
   por igual a los dos lados en vez de acumularse en uno. Título encima
   del texto y alineado con él. Una sola columna: con descripciones cortas
   (~320 caracteres) o largas (~2900) el bloque solo cambia de alto. El
   cuerpo usa el estándar de .product-detail__description-body (más
   arriba). --- */
.product-detail__description{
  max-width:38rem;
  margin:3.5rem auto 0;
  padding-top:3rem;
  border-top:1px solid rgba(41,37,28,.12);
}
.product-detail__description-title{
  margin:0 0 1.5rem;
  font-size:2.5rem;
  line-height:1.2;
  font-weight:400;
  color:var(--ink);
}
@media (max-width:991px){
  .product-detail__description{
    margin-top:3rem;
    padding-top:2.5rem;
  }
}
@media (max-width:767px){
  .product-detail__description{
    margin-top:2.5rem;
    padding-top:2rem;
  }
  .product-detail__description-title{
    font-size:2rem;
    margin-bottom:1.25rem;
  }
}
/* el contenido viene de WYSIWYG y algunos enlaces traen un span interno
   con color inline; !important es necesario para pisarlo, ya que un
   estilo inline gana a cualquier selector externo sin él. */
.product-detail__description a,
.product-detail__description a *{
  color:var(--ink)!important;
}
.product-detail__description a{
  text-decoration:underline;
}
.product-detail__description a:hover{
  text-decoration:none;
}

/* ==== Ficha de producto — tarjeta regalo de importe libre ====
   Mismo tratamiento visual que .product-listing-item__giftcard-form /
   __add en el listado de categoría, con el prefijo .product-detail__ de
   esta ficha. */
.product-detail__giftcard-form{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.5rem;
}
.product-detail__giftcard-input{
  width:6rem;
  padding:.4rem .6rem;
  border:1px solid rgba(41,37,28,.3);
}
/* ==== Listado de categoría — ocultar barra superior de resultados ====
   #js-product-list-top sigue en el DOM: theme.js lo usa como target AJAX
   (listTop) al filtrar/paginar. Solo se oculta visualmente, no se borra. */
#js-product-list-top{
  display:none;
}

/* --- Login / Register / Password recovery: card treatment on top of the
   existing .login / .register-form / .password-reset wrappers. Scoped by
   body id (#authentication, #registration, #password — set from
   AuthController/RegistrationController/PasswordController's php_self) as
   well as by class, because .page-header and .btn-primary etc. below are
   shared components reused sitewide — the id keeps this from leaking into
   checkout, product, or other account pages. --- */
/* #authentication .login, #registration .register-form.form-card y
   #password .password-reset.form-card ("¿Has olvidado tu contraseña?")
   ahora usan la card compartida .form-card (ver "Formularios — sistema
   compartido" al final de este fichero) en vez de su propio fondo/sombra —
   solo se mantiene el ritmo vertical de página. password-infos.tpl /
   password-new.tpl siguen con la card antigua hasta convertirlas. */
#authentication .login,
#registration .register-form.form-card,
#password .password-reset.form-card{
  margin-bottom: 4rem;
}
#registration .register-form:not(.form-card),
#password .password-reset:not(.form-card){
  background:var(--ritual-cream);
  border-radius:20px;
  padding:2.5rem clamp(1.5rem,5vw,3.5rem);
  box-shadow:0 10px 40px rgba(41,37,28,.08);
  margin-bottom: 4rem;
}
@media (max-width:575.98px){
  #registration .register-form:not(.form-card),
  #password .password-reset:not(.form-card){
    padding:2rem 1.25rem;
    border-radius:16px;
  }
}
#authentication .page-header,
#registration .page-header,
#password .page-header{
  text-align:center;
  margin-bottom:2rem;
}
#authentication .login hr,
#registration .register-form hr,
#password .password-reset hr{
  border:none;
  border-top:1px solid rgba(41,37,28,.15);
  margin:2rem 0;
}
#authentication .login__register-prompt,
#checkout-login-form .login__register-prompt{
  text-align:center;
}
/* "¿No tienes cuenta?" es h2.h4: con la clase de Bootstrap quedaba a
   1.125rem. Titular de elemento del estándar. */
#authentication .login__register-prompt h2,
#checkout-login-form .login__register-prompt h2{
  margin-bottom:1rem;
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
@media (max-width:767px){
  #authentication .login__register-prompt h2,
  #checkout-login-form .login__register-prompt h2{
    font-size:1.5rem;
  }
}
/* checkout has no leading <hr> before this prompt (unlike /iniciar-sesion),
   so it needs its own top spacing to not sit flush under the social
   buttons / password form above it. */
#checkout-login-form .login__register-prompt{
  margin-top:2.5rem;
}
#authentication .login__form-wrapper,
#authentication .ritual-login__social,
#checkout-login-form .login__form-wrapper,
#checkout-login-form .ritual-login__social{
  margin-bottom:1.5rem;
}
#authentication .ritual-login__password-toggle,
#checkout-login-form .ritual-login__password-toggle{
  text-align:center;
  margin-bottom:1.5rem;
}
/* Dentro de .ritual-login__meta-row (ver más abajo) el toggle ya no va
   solo en su propia línea centrada — comparte fila con "¿Has olvidado la
   contraseña?", así que se le quita el margen/centrado de la regla de
   arriba (necesita más especificidad vía el mismo id para ganarle). */
#authentication .ritual-login__meta-row .ritual-login__password-toggle,
#checkout-login-form .ritual-login__meta-row .ritual-login__password-toggle{
  margin-bottom:0;
  text-align:left;
}
#authentication .ritual-login__divider,
#checkout-login-form .ritual-login__divider{
  text-align:center;
  text-transform:uppercase;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  color:rgba(41,37,28,.6);
  margin:0 0 1.5rem;
}
/* "¿Has olvidado la contraseña?" y "¿Prefieres iniciar sesión sin
   contraseña?" comparten fila, a la misma altura, en vez de ir cada uno
   en su propia línea: olvido de contraseña a la izquierda, toggle a la
   derecha. Vive en login-form.tpl (compartido por login y checkout), así
   que esta única regla cubre ambos sitios. Lleva un margen propio además
   del que ya da el campo de contraseña (.form-card .mb-3, 2rem) para que
   quede claramente separada de la caja de texto, no pegada a ella.
   flex-wrap:wrap es la red de seguridad para que, si no caben en una
   línea (móvil, o la card en su ancho normal — ver ampliación de card
   más abajo), pasen a apilarse en columna en vez de recortarse. */
.ritual-login__meta-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap:.5rem 1rem;
  margin:.5rem 0 1.5rem;
  font-size:.8125rem;
}
.ritual-login__meta-row .ritual-login__forgot{
  margin:0;
}
.ritual-login__forgot{
  text-align:right;
  font-size:.8125rem;
}
/* Los dos textos de .ritual-login__meta-row no caben en una línea con el
   ancho normal de .form-card (32rem) — se amplía solo en los paneles de
   acceso (login/checkout), que son los que llevan esta fila; el resto de
   cards (Mi cuenta, checkout-invitado, registro, contraseña) se quedan en
   32rem. Por debajo de ese ancho (pantallas donde ni siquiera caben
   36rem) flex-wrap ya se encarga de apilarlos en columna. */
#authentication .login.form-card,
#checkout-login-form .form-card{
  max-width:36rem;
}

/* --- Inputs: underline-only (password-infos.tpl/password-new.tpl still
   pending conversion — ver nota en la sección de Login/Register/Password
   recovery más abajo). --- */
/* Etiqueta de campo del estándar (ver "Extensiones del estándar (páginas
   transaccionales y de contenido)"). Antes esta regla también alcanzaba
   a .form-check-label, así que los consentimientos del core (ofertas,
   privacidad) salían como frases enteras en mayúsculas a .72rem: ahora
   tienen su propia regla de texto de casilla, justo debajo. */
#authentication .login .form-label,
#registration .register-form .form-label,
#password .password-reset .form-label,
#checkout-login-form .form-label,
#checkout-guest-form .form-label,
.rb-account-datos .form-label,
#order-confirmation .order-confirmation__account-transformation .form-label{
  font-size:.72rem;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.04em;
  color:var(--ink);
}
/* Texto de casilla del core (_partials/form-fields.tpl): son
   consentimientos (ofertas de socios, privacidad, condiciones), así que
   van en texto legal y su enlace en metadato accionable. Las casillas en
   línea (radios de tratamiento, si se activan) son una elección, no un
   texto legal: dato. */
#authentication .login .form-check-label,
#registration .register-form .form-check-label,
#checkout-login-form .form-check-label,
#checkout-guest-form .form-check-label,
.rb-account-datos .form-check-label{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  text-transform:none;
  letter-spacing:0;
  color:rgba(41,37,28,.6);
}
#authentication .login .form-check-label em,
#registration .register-form .form-check-label em,
#checkout-login-form .form-check-label em,
#checkout-guest-form .form-check-label em,
.rb-account-datos .form-check-label em{
  font-size:inherit;
}
#authentication .login .form-check-label a,
#registration .register-form .form-check-label a,
#checkout-login-form .form-check-label a,
#checkout-guest-form .form-check-label a,
.rb-account-datos .form-check-label a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
#authentication .login .form-check-label a:hover,
#registration .register-form .form-check-label a:hover,
#checkout-login-form .form-check-label a:hover,
#checkout-guest-form .form-check-label a:hover,
.rb-account-datos .form-check-label a:hover{
  color:var(--brass);
}
#registration .register-form .form-check-inline .form-check-label,
#checkout-guest-form .form-check-inline .form-check-label,
.rb-account-datos .form-check-inline .form-check-label{
  font-size:.9375rem;
  color:var(--ink);
}
/* Ayuda de formulario ("Opcional", requisitos de contraseña): metadato. */
#registration .register-form .form-text,
#registration .register-form .password-requirements__length,
#registration .register-form .password-requirements__score,
#checkout-guest-form .form-text,
#checkout-guest-form .password-requirements__length,
#checkout-guest-form .password-requirements__score,
.rb-account-datos .form-text,
.rb-account-datos .password-requirements__length,
.rb-account-datos .password-requirements__score,
#password .password-reset .form-text,
#password .password-reset .password-requirements__length,
#password .password-reset .password-requirements__score{
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
/* Mensaje de validación: errores de campo del core (form-errors.tpl,
   .help-block .alert-danger) y el aviso de error de las páginas de
   contraseña. La caja de la alerta no se toca; solo el texto. */
.form-card .help-block .alert-danger,
#password .password-reset .alert-danger{
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:var(--color-error);
}
#authentication .login .form-label,
#registration .register-form .form-label,
#password .password-reset .form-label,
#checkout-login-form .form-label,
#checkout-guest-form .form-label,
.rb-account-datos .form-label{
  display:block;
  margin-bottom:.5rem;
}
#password .password-reset .form-control{
  border:none;
  border-bottom:2px solid var(--ink);
  border-radius:0;
  background:transparent;
  padding:.5rem 0;
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-weight:300;
  color:var(--ink);
  box-shadow:none;
}
#password .password-reset .form-control:focus{
  outline:none;
  box-shadow:none;
  border-bottom-color:var(--ink);
}
/* Campos renderizados por el core dentro de #registration (Nombre/
   Apellidos/Email/Teléfono) no tienen un <span> propio que envolver en
   .input-field__wrap (vienen de _partials/form-fields.tpl, fuera de
   alcance) — misma solución que en checkout/Mi cuenta: caja apuntando
   directo al .form-control, combinador directo para no alcanzar el input
   de contraseña (anidado en .input-group.password-field). */
#registration .register-form .mb-3 > .form-control,
#registration .register-form .mb-3 > .form-select{
  display:block;
  width:100%;
  border:1px solid rgba(41,37,28,.25);
  border-radius:10px;
  background:#fff;
  padding:.55rem .75rem;
  font-weight:300;
  font-size:1rem;
  color:var(--ink);
  box-shadow:none;
  transition:border-color .2s ease, box-shadow .2s ease;
}
#registration .register-form .mb-3 > .form-control:hover:not(:focus),
#registration .register-form .mb-3 > .form-select:hover:not(:focus){
  border-color:rgba(41,37,28,.45);
}
#registration .register-form .mb-3 > .form-control:focus,
#registration .register-form .mb-3 > .form-select:focus{
  outline:none;
  border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(175,138,82,.15);
}
/* Checkbox "Recibir ofertas de nuestros socios": renderizado por el core
   (form-fields.tpl, fuera de alcance), no se le puede cambiar la clase a
   .form-check-ritual__input sin un override de plantilla. accent-color no
   sirve aquí (bootstrap pinta :checked con background-color:#0b69f6 fijo,
   como en el paso de pago y en Mi cuenta — mismo motivo por el que esos
   necesitan su propio override) — se corrige igual, sobrescribiendo el
   color de fondo/borde directamente en :checked. */
#registration .register-form .form-check-input:checked,
.rb-account-datos .form-check-input:checked{
  background-color:var(--brass);
  border-color:var(--brass);
}
#registration .register-form .form-check-input:focus,
.rb-account-datos .form-check-input:focus{
  border-color:var(--brass);
  box-shadow:0 0 0 .25rem rgba(175,138,82,.25);
}
/* --- Password field: input-group wraps the text input + a show/hide
   icon button. Move the underline to the group itself so the two
   children can sit flush together instead of each drawing its own
   border. --- */
#password .password-reset .input-group.password-field{
  border-bottom:2px solid var(--ink);
}
#authentication .login .input-group.password-field .form-control,
#password .password-reset .input-group.password-field .form-control,
#checkout-login-form .input-group.password-field .form-control,
#checkout-guest-form .input-group.password-field .form-control,
.rb-account-datos .input-group.password-field .form-control{
  border-bottom:none;
}
#password .password-reset .input-group.password-field .btn{
  background:transparent;
  border:none;
  color:var(--ink);
  box-shadow:none;
  padding:.5rem .25rem;
}
#checkout-personal-information-step{margin-bottom:2rem;}
#checkout-personal-information-step .step__account{display: none;}
/* --- Botón "Guardar": mismo lenguaje que el resto de CTAs de la cuenta
   (.btn-pill), el core solo le da .btn.btn-primary.form-control-submit. --- */
.rb-account-datos .form-control-submit{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  border:none;
  border-radius:999px;
  background:var(--ink);
  color:#fff;
  font-weight:700;
  font-size:.85rem;
  text-transform:uppercase;
  letter-spacing:.04em;
  padding:.75rem 1.75rem;
  margin-top:1rem;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
}

/* --- Forma/color/hover de estos botones (Sign in / Email me a login link /
   Create account / Google / Facebook) ya los da la clase maestra .btn-pill
   (+ --secondary en los outline), añadida en sus templates. Solo queda el
   layout propio de esta página. --- */
#password .password-reset .buttons-wrapper{
  justify-content:center;
}
#authentication .login .ritual-google-icon,
#checkout-login-form .ritual-google-icon,
#authentication .login .ritual-facebook-icon,
#checkout-login-form .ritual-facebook-icon{
  flex:none;
}
/* --- Text-only links: "Forgot your password?" and the password-toggle
   button — no button chrome, just an ink underline. #authentication .login,
   the checkout auth panels and password-email.tpl (ya en .form-card) lo
   obtienen genéricamente de .form-card .btn-link/.btn-basic (ver
   "Formularios — sistema compartido" al final de este fichero) — esta
   regla sigue haciendo falta para password-infos.tpl/password-new.tpl,
   que aún no llevan .form-card. --- */
/* "Volver al inicio de sesión" (#back-to-login, único .btn-basic de las
   tres páginas de contraseña): es navegación, así que toma el enlace de
   texto del estándar (.8125rem, 400, .14em, mayúsculas, filete --brass
   que arranca a scaleX(.3) y se completa al hover), el mismo de
   .ritual-for-you__cta. Gana a .form-card .btn-basic por el id. */
#password .password-reset .btn-basic{
  position:relative;
  display:inline-flex;
  align-items:center;
  padding:0 0 .6rem;
  border:none;
  border-radius:0;
  background:transparent;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-decoration:none;
  color:var(--ink);
}
#password .password-reset .btn-basic:hover,
#password .password-reset .btn-basic:focus-visible{
  color:var(--ink);
  background:transparent;
}
#password .password-reset .btn-basic::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:var(--brass);
  transform:scaleX(.3);
  transform-origin:left center;
  transition:transform var(--motion-hover) var(--motion-ease);
}
#password .password-reset .btn-basic:hover::after,
#password .password-reset .btn-basic:focus-visible::after{
  transform:scaleX(1);
}
@media (prefers-reduced-motion: reduce){
  #password .password-reset .btn-basic::after{transition:none}
}
/* "¿Ya tienes cuenta? Iniciar sesión": metadato y su enlace, metadato
   accionable (el enlace del checkout es un .btn-link dentro de .form-card
   y lo cubre la regla de .form-card .btn-link). */
#registration .register-form__login-prompt,
#checkout-guest-form .register-form__login-prompt{
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
#registration .register-form__login-prompt a{
  color:rgba(41,37,28,.6);
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
#registration .register-form__login-prompt a:hover,
#registration .register-form__login-prompt a:focus-visible{
  color:var(--brass);
}
/* Intro de "¿Has olvidado tu contraseña?": cuerpo. "Dirección de correo
   electrónico: x" en la nueva contraseña: dato. */
#password .send-renew-password-link{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
#password .renew-password > .mb-3:first-child{
  font-size:.9375rem;
  font-weight:400;
  line-height:1.4;
  color:var(--ink);
}
@media (max-width:767px){
  #password .send-renew-password-link{
    font-size:1rem;
  }
}

/* magiclogin-form.tpl ya no usa .form-group (pasó a .input-field, con su
   propio margin-bottom, ver sistema compartido) — nada que fijar aquí.
   Buttons siguen necesitando centrado explícito: el inline-flex del pill
   solo centra su propio label/icono, no el pill dentro de la card. */
/* Checkout's login/register panes shouldn't stretch across the whole step
   column — .form-card ya fija max-width:32rem y margin:0 auto (ver sistema
   compartido), así que .ritual-checkout-auth__panel no necesita su propio
   ancho aquí. */
#authentication .ritual-login__social,
#checkout-login-form .ritual-login__social{
  text-align:center;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:.75rem;
}
/* hummingbird's .buttons-wrapper is itself a flex container, so text-align
   doesn't reach the button — needs justify-content/align-items instead.
   Scoped to #magiclogin-form specifically (not every .buttons-wrapper under
   .login__form-wrapper): the password form's own buttons-wrapper carries
   --split, which must keep its space-between layout for the forgot-
   password link + submit button pair. #magiclogin-form's id alone is
   enough scope (unique per page) — no ancestor prefix, so this also
   reaches checkout's copy of the form, which has no #authentication
   ancestor. */
#magiclogin-form .buttons-wrapper{
  justify-content:center;
  align-items:center;
}

/* --- Checkout redesign: single-page layout matching the old production
   site — product table full-width, then coupon + steps + image below. --- */
.ritual-checkout-grid__content{padding-right:2rem}
@media (max-width:767px){
  .ritual-checkout-grid__content{
    padding-right:calc(var(--bs-gutter-x)*.5);
    padding-bottom:4rem;
  }
}
.ritual-checkout-image{width:100%;height:100%;min-height:480px;border-radius:4px;overflow:hidden}
.ritual-checkout-image img{width:100%;height:100%;object-fit:cover;display:block}

/* --- Dos modos de /pedido (checkout.tpl, checkout-flow.js) ---
   Resumen (por defecto): titular, tabla con sus reservas y, al lado, la
   tarjeta de resumen; el proceso de PrestaShop no se ve. Pago
   (html.ritual-payflow, o la clase en la rejilla cuando la pone el
   servidor): solo la cabecera de pasos y el paso actual, en una columna
   centrada. --- */
.ritual-checkout-grid__content{display:none}
.ritual-payflow .ritual-checkout-grid__table-wrap,
.ritual-payflow .ritual-checkout-grid__aside{display:none}
.ritual-payflow .ritual-checkout-grid__content{display:block;max-width:44rem;margin:0 auto;padding-right:calc(var(--bs-gutter-x)*.5)}

/* Resumen: titular de página y tabla pegada a él. */
.ritual-cart-head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:.5rem 1.5rem;margin-top:2rem}
.ritual-cart-title{margin:0;font-size:2.5rem;font-weight:400;line-height:1.2;color:var(--ink)}
.ritual-cart-head__continue{display:inline-flex;align-items:center;gap:.3rem;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;color:var(--ink);opacity:.7;text-decoration:none;transition:opacity var(--motion-hover) var(--motion-ease)}
.ritual-cart-head__continue .material-icons{font-size:1rem}
.ritual-cart-head__continue:hover,
.ritual-cart-head__continue:focus-visible{opacity:1;color:var(--brass)}
@media (max-width:767px){
  .ritual-cart-head{margin-top:1.25rem}
  .ritual-cart-title{font-size:2rem}
}

/* --- Listado del carrito como tarjetas (cart-table.tpl) ---
   El marcado sigue siendo la tabla —de sus filas y atributos dependen las
   reservas, quitar productos y los modales—; lo que cambia es cómo se pinta,
   en todos los anchos: cada línea es una tarjeta blanca con filete fino.
   Arriba, nombre (y sus datos de regalo), precio y papelera; debajo, tras
   un filete, su cita, el botón para reservarla o la nota de regalo. Sin
   cabecera de columnas: la tarjeta ya dice qué es cada cosa. Las citas
   conjuntas y las unidades de un mismo servicio son bloques unidos (su
   cabecera + sus líneas, sin hueco entre ellas); la cita conjunta, con el
   filete --brass a la izquierda y un velo del mismo tono. El total vive en
   la tarjeta de resumen: de la fila del total solo queda "Reserva
   conjunta", cuando la hay. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed{display:block;width:100%;margin:1.5rem 0 3rem}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed thead{display:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tbody,
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tfoot{display:block;width:100%}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;grid-template-areas:"product price actions" "booking booking booking";align-items:start;column-gap:1.25rem;margin:0 0 .75rem;padding:1.25rem 1.5rem;border:1px solid rgba(41,37,28,.12);border-radius:16px;background:#fff}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td{display:block;padding:0;border:0;background:none;min-width:0;text-align:left}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__product{grid-area:product;padding:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__price{grid-area:price;text-align:right;white-space:nowrap}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__actions{grid-area:actions;padding:0;margin:0;text-align:right}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__booking{grid-area:booking;display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;margin:1rem 0 0;padding:1rem 0 0;border-top:1px solid rgba(41,37,28,.08)}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__booking:empty{display:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__product-name{font-size:1.25rem;line-height:1.3}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__price-value{font-family:"Helvetica LT Std",sans-serif;font-size:1.0625rem;font-weight:700}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__remove{padding:.15rem;opacity:.5}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__remove-label{display:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__remove .material-icons{font-size:1.25rem}
/* Cita: fecha y hora en píldora --brass suave, "Quitar la cita" al lado. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__reservation{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;margin:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__reservation-value{display:inline-flex;align-items:center;gap:.35rem;padding:.25rem .75rem;border-radius:999px;background:color-mix(in srgb, var(--brass) 12%, #fff);font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__reservation-value::before{content:"\E878";font-family:"Material Icons";font-size:1rem;font-weight:400;line-height:1}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__reservation a{margin-top:0}
/* Sin cita: "Reservar" como píldora de contorno --brass. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__booking .js-cart-row-reserve{display:inline-flex;align-items:center;gap:.35rem;padding:.4rem 1rem;border:1px solid var(--brass);border-radius:999px;color:var(--brass);font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;text-decoration:none;transition:background-color var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease)}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__booking .js-cart-row-reserve::before{content:"\E878";font-family:"Material Icons";font-size:1rem;font-weight:400;line-height:1}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__booking .js-cart-row-reserve:hover,
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__booking .js-cart-row-reserve:focus-visible{background:var(--brass);color:#fff;opacity:1}

/* Unidades de un mismo servicio: bloque unido (su cabecera + sus líneas,
   sin hueco entre ellas). */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--group-header{display:block;margin-bottom:0;padding:1.1rem 1.5rem .5rem;border-bottom:0;border-radius:16px 16px 0 0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--group-header td{padding:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--unit{margin-bottom:0;border-top:0;border-bottom:0;border-radius:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--unit + tr.ritual-checkout-table__row--unit{box-shadow:inset 0 1px 0 rgba(41,37,28,.1)}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--unit-last{margin-bottom:.75rem;border-bottom:1px solid rgba(41,37,28,.12);border-radius:0 0 16px 16px}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--unit td.ritual-checkout-table__product{padding-left:0}

/* Cita conjunta, como línea de tiempo: la cabecera ("Cita del …", sin
   tarjeta) y, colgando de ella, cada servicio en su propia tarjeta —con su
   hora dentro, así no hay duda de qué hora es de qué servicio—, unidas por
   un filete --brass vertical con un punto a la altura de cada una. La
   fecha ya la dice la cabecera: en cada servicio, solo la hora. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-header{display:block;margin:0;padding:.75rem 0 .75rem;border:0;border-radius:0;background:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-header td{padding:0;border:0;background:none}
/* El título de la cita, con peso de titular de bloque (no de antetítulo):
   es lo que agrupa a los servicios de debajo. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__chain-title{display:flex;align-items:center;gap:.5rem;font-size:1rem;letter-spacing:.08em}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__chain-title::before{content:"\E878";font-family:"Material Icons";font-size:1.375rem;font-weight:400;letter-spacing:0;line-height:1;text-transform:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header){position:relative;margin-left:1.5rem}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header)::before{content:"";position:absolute;top:-.75rem;bottom:-.75rem;left:calc(-1.5rem + 5px);width:2px;background:color-mix(in srgb, var(--brass) 45%, #fff)}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-last::before{bottom:50%!important}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header)::after{content:"";position:absolute;top:50%;left:calc(-1.5rem + 1px);width:10px;height:10px;margin-top:-5px;border-radius:50%;background:var(--brass)}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-header + tr.ritual-checkout-table__row--chain::before{top:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-last{margin-bottom:1.25rem}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain .ritual-checkout-table__reservation-date{display:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain .ritual-checkout-table__reservation-value::before{content:"\E8B5"}

/* Fila del total: solo "Reserva conjunta" (y su ayuda), si la hay. */
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total{display:flex;align-items:center;padding:.5rem 0 0;border:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total td{display:block;padding:0;border:0}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total td.ritual-checkout-table__product,
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total td.ritual-checkout-table__price{display:none}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total td.ritual-checkout-table__booking{display:flex;align-items:center;gap:.6rem;margin:0;text-align:left}
.ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__total td.ritual-checkout-table__booking:empty{display:none}

@media (max-width:767px){
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row{column-gap:.75rem;padding:1rem 1.1rem}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--group-header{padding:1rem 1.1rem .4rem}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header){margin-left:1.1rem}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header)::before{left:calc(-1.1rem + 3px)}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain:not(.ritual-checkout-table__row--chain-header)::after{left:calc(-1.1rem - 1px)}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__product-name{font-size:1.0625rem}
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__booking{margin-top:.75rem;padding-top:.75rem}
}
@media (prefers-reduced-motion: reduce){
  .ritual-cart-head__continue,
  .ritual-checkout-grid__table-wrap .ritual-checkout-table--fixed .ritual-checkout-table__booking .js-cart-row-reserve{transition:none}
}

/* Barra fija del resumen (móvil/tablet, checkout-flow.js): total y "Pagar
   ahora" mientras la tarjeta de resumen no se ve. La misma barra sale en el
   resto del sitio mientras haya algo en el carrito (.ritual-site-cart-bar,
   _partials/footer.tpl y custom.js). Misma factura que la
   barra de reserva de la ficha (.product-detail__sticky-confirm): crema,
   filete --brass arriba, entra y sale deslizando desde el borde. En
   escritorio no existe: allí la tarjeta de resumen ya es fija. */
.ritual-cart-sticky{display:none}
@media (max-width:991px){
  .ritual-cart-sticky{display:block;position:fixed;left:0;right:0;bottom:0;z-index:1030;padding:.75rem 0;padding-bottom:calc(.75rem + env(safe-area-inset-bottom, 0px));background:var(--ritual-cream);border-top:2px solid var(--brass);box-shadow:0 -10px 30px rgba(41,37,28,.12);transform:translateY(100%);visibility:hidden;transition:transform var(--motion-duration) var(--motion-ease), visibility 0s linear var(--motion-duration)}
  .ritual-cart-sticky--visible{transform:none;visibility:visible;transition:transform var(--motion-duration) var(--motion-ease), visibility 0s}
  .ritual-payflow .ritual-cart-sticky{display:none}
}
.ritual-cart-sticky__inner{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.ritual-cart-sticky__total{display:flex;flex-direction:column;margin:0;font-family:"Helvetica LT Std",sans-serif;font-size:.68rem;font-weight:700;line-height:1.3;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6)}
.ritual-cart-sticky__total strong{font-size:1.5rem;font-weight:400;line-height:1.1;letter-spacing:0;text-transform:none;color:var(--brass);font-variant-numeric:tabular-nums}
.ritual-cart-sticky__pay{flex:0 1 14rem;height:3.25rem;text-decoration:none}
@media (prefers-reduced-motion: reduce){
  .ritual-cart-sticky,
  .ritual-cart-sticky--visible{transition:none}
}

/* Tarjeta de resumen: la imagen de ambiente arriba (antes ocupaba sola la
   columna lateral), el total como dato destacado en --brass, los cupones
   como desplegables discretos y "Pagar ahora" a todo el ancho. Fija al
   hacer scroll en escritorio, para que el pago esté siempre a mano. */
.ritual-cart-summary{overflow:hidden;border-radius:16px;background:color-mix(in srgb, var(--ritual-cream) 70%, #fff)}
@media (min-width:992px){
  .ritual-checkout-grid__aside{padding-top:2rem}
  .ritual-cart-summary{position:sticky;top:calc(var(--ritual-header-h, 0px) + 1.5rem)}
}
@media (max-width:991px){
  .ritual-checkout-grid__aside{margin-bottom:4rem}
}
.ritual-cart-summary .ritual-checkout-image{height:auto;min-height:0;aspect-ratio:4 / 3;border-radius:0}
.ritual-cart-summary__body{padding:1.5rem}
.ritual-cart-summary__kicker{margin:0 0 1rem;font-family:"Helvetica LT Std",sans-serif;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6)}
.ritual-cart-summary__total{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;margin:0;font-family:"Helvetica LT Std",sans-serif;font-size:1rem;color:var(--ink)}
.ritual-cart-summary__total strong{font-size:1.75rem;font-weight:400;line-height:1.2;color:var(--brass);font-variant-numeric:tabular-nums}
.ritual-cart-summary__tax{margin:.2rem 0 0;text-align:right;font-family:"Helvetica LT Std",sans-serif;font-size:.75rem;color:rgba(41,37,28,.6)}
.ritual-cart-summary .ritual-cart-voucher{margin:1.25rem 0 0;padding-top:1rem;border-top:1px solid rgba(41,37,28,.12)}
.ritual-cart-summary .ritual-cart-voucher .cart-summary__line{background:#fff}
.ritual-cart-summary__pay{width:100%;height:3.25rem;margin-top:1.5rem;text-decoration:none}
.ritual-cart-summary .ritual-cart-voucher__column > form{background:#fff}
@media (min-width:768px){
  .ritual-cart-summary .ritual-cart-voucher__columns{grid-template-columns:minmax(0, 1fr);gap:.25rem}
}
.ritual-payflow .step__title{display:none}
/* Un paso a la vez. !important frente a .collapse/.show del core, que
   decide a su manera cuál de sus dos pasos se ve. */
.ritual-payflow #checkout-personal-information-step,
.ritual-payflow #checkout-payment-step{display:none!important}
html.ritual-payflow[data-pay-current="1"] #checkout-personal-information-step,
html.ritual-payflow[data-pay-current="2"] #checkout-payment-step,
html.ritual-payflow[data-pay-current="3"] #checkout-payment-step{display:block!important}
.ritual-pay-panel{display:none}
html[data-pay-current="2"] .ritual-pay-panel[data-pay-panel="2"],
html[data-pay-current="3"] .ritual-pay-panel[data-pay-panel="3"]{display:block}
/* Red por si checkout-flow.js no llega a correr (sin data-pay-current): se
   ve el paso actual del core entero, con todos sus paneles, en vez de una
   página vacía. */
html:not([data-pay-current]) #checkout-personal-information-step.js-current-step,
html:not([data-pay-current]) #checkout-payment-step.js-current-step{display:block!important}
html:not([data-pay-current]) .ritual-pay-panel{display:block}
/* En el paso 1 con la sesión iniciada se ve con qué cuenta se paga. */
.ritual-payflow #checkout-personal-information-step .step__account{display:block}

/* Cabecera: volver al carrito, los pasos y el titular del actual. */
.ritual-payflow-head{margin:1.5rem 0 2rem}
.ritual-payflow-head__back{display:inline-flex;align-items:center;gap:.3rem;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;color:var(--ink);opacity:.7;text-decoration:none;transition:opacity var(--motion-hover) var(--motion-ease)}
.ritual-payflow-head__back .material-icons{font-size:1rem}
.ritual-payflow-head__back:hover,
.ritual-payflow-head__back:focus-visible{opacity:1;color:var(--brass)}
.ritual-payflow-steps{display:flex;margin:1.25rem 0 2.25rem;padding:1.25rem .5rem 1rem;list-style:none;border-radius:16px;background:color-mix(in srgb, var(--ritual-cream) 70%, #fff)}
.ritual-payflow-steps__item{position:relative;flex:1 1 0;min-width:0}
/* Filete entre pasos, a la altura del centro de los círculos. */
.ritual-payflow-steps__item + .ritual-payflow-steps__item::before{content:"";position:absolute;top:1rem;right:calc(50% + 1.25rem);left:calc(-50% + 1.25rem);height:1px;background:rgba(41,37,28,.18)}
.ritual-payflow-steps__item.is-done + .ritual-payflow-steps__item::before,
.ritual-payflow-steps__item.is-done + .ritual-payflow-steps__item.is-current::before{background:var(--brass)}
.ritual-payflow-steps__button{display:flex;flex-direction:column;align-items:center;gap:.5rem;width:100%;padding:0;border:0;background:none;color:var(--ink);font-family:"Helvetica LT Std",sans-serif;cursor:pointer}
.ritual-payflow-steps__button:disabled{cursor:default}
.ritual-payflow-steps__mark{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:1px solid rgba(41,37,28,.25);border-radius:50%;background:#fff;font-size:.8125rem;font-weight:700;transition:background-color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease), color var(--motion-hover) var(--motion-ease)}
.ritual-payflow-steps__label{font-size:.8125rem;line-height:1.3;text-align:center;opacity:.55}
.ritual-payflow-steps__item.is-done .ritual-payflow-steps__mark{background:var(--brass);border-color:var(--brass);color:#fff}
.ritual-payflow-steps__item.is-current .ritual-payflow-steps__mark{background:var(--ink);border-color:var(--ink);color:#fff;box-shadow:0 0 0 .3rem color-mix(in srgb, var(--brass) 22%, transparent)}
.ritual-payflow-steps__item.is-current .ritual-payflow-steps__label,
.ritual-payflow-steps__item.is-done .ritual-payflow-steps__label{opacity:1}
.ritual-payflow-steps__item.is-current .ritual-payflow-steps__label{font-weight:700}
.ritual-payflow-steps__item.is-skipped{opacity:.35}
/* Bloqueado (aún no alcanzable): todos igual de apagados. */
.ritual-payflow-steps__item.is-locked .ritual-payflow-steps__mark{border-style:dashed;color:rgba(41,37,28,.4)}
.ritual-payflow-steps__item.is-locked .ritual-payflow-steps__label{opacity:.4}
.ritual-payflow-steps__button:not(:disabled):hover .ritual-payflow-steps__label{color:var(--brass)}
.ritual-payflow-head__title{margin:0;font-size:2rem;font-weight:400;line-height:1.2;color:var(--ink)}
@media (max-width:767px){
  .ritual-payflow-steps__label{font-size:.6875rem}
  .ritual-payflow-head__title{font-size:1.625rem}
}
@media (prefers-reduced-motion: reduce){
  .ritual-payflow-head__back,
  .ritual-payflow-steps__mark{transition:none}
}

/* Paso 1 · Cuenta, sin sesión (steps/personal-information.tpl): la
   pregunta con dos respuestas grandes y, según cuál, entrar o crear la
   cuenta. Cada vista va en su tarjeta, la misma superficie que el resto de
   pasos: crema rebajado, 16px, sin borde ni sombra (la card del calendario
   de la ficha), no la card crema con filete dorado de /iniciar-sesion.
   Lo que va dentro (respuestas, campos) en blanco. Los formularios, a una medida de
   lectura (32rem); Google primero, a todo ese ancho, porque es la opción
   más usada. */
.ritual-account__view{display:none;max-width:32rem;margin:0 auto;padding:2.5rem;border-radius:16px;background:color-mix(in srgb, var(--ritual-cream) 55%, #fff)}
@media (max-width:575px){
  .ritual-account__view{padding:1.75rem 1.25rem}
}
.ritual-account[data-account-view="question"] [data-account-panel="question"],
.ritual-account[data-account-view="login"] [data-account-panel="login"],
.ritual-account[data-account-view="register"] [data-account-panel="register"]{display:block;animation:ritual-account-in var(--motion-duration) var(--motion-ease)}
.ritual-account[data-account-view="question"] [data-account-panel="question"]{max-width:38rem;text-align:center}
@keyframes ritual-account-in{
  from{opacity:0;transform:translateY(.5rem)}
  to{opacity:1;transform:none}
}
.ritual-account__question{margin:.5rem 0 1.5rem;font-size:1.5rem;line-height:1.3;color:var(--ink)}
.ritual-account__choices{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
.ritual-account__choice{display:flex;flex-direction:column;align-items:flex-start;gap:1rem;padding:1.5rem;border:1px solid transparent;border-radius:12px;background:#fff;color:var(--ink);text-align:left;cursor:pointer;transition:border-color var(--motion-hover) var(--motion-ease), background-color var(--motion-hover) var(--motion-ease), transform var(--motion-hover) var(--motion-ease)}
.ritual-account__choice:hover,
.ritual-account__choice:focus-visible{border-color:var(--brass);background:#fff;transform:translateY(-2px)}
.ritual-account__choice-icon{color:var(--brass)}
.ritual-account__choice-title{font-family:"Helvetica LT Std",sans-serif;font-size:1.0625rem;font-weight:700;line-height:1.3}
@media (max-width:575px){
  .ritual-account__choices{grid-template-columns:1fr}
  .ritual-account__choice{flex-direction:row;align-items:center;padding:1.1rem 1.25rem}
}

.ritual-account__back{display:inline-flex;align-items:center;gap:.3rem;margin:0 0 1rem;padding:0;border:0;background:none;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;color:var(--ink);opacity:.7;cursor:pointer}
.ritual-account__back .material-icons{font-size:1rem}
.ritual-account__back[hidden],
.ritual-account__quick-methods[hidden]{display:none}
.ritual-account__back:hover,
.ritual-account__back:focus-visible{opacity:1;color:var(--brass)}
.ritual-account__heading{margin:0 0 1.75rem;font-size:1.75rem;line-height:1.25;color:var(--ink)}

/* Google y Facebook apilados a todo el ancho, con la misma separación que
   el botón de cambio de modo de debajo (.ritual-account__quick). */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__social{display:flex;flex-direction:column;gap:.75rem}
/* Botón de cambio de modo (contraseña / enlace mágico), bajo Google y con
   su mismo formato: píldora de contorno a todo el ancho, blanca sobre el
   crema, con icono. */
.ritual-account__quick{margin-top:.75rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;width:100%;min-height:3.25rem;padding-inline:1rem;background:#fff;line-height:1.2;white-space:normal}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle .material-icons{font-size:1.25rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle[hidden]{display:none}
/* "Elegir otro método" (modo enlace mágico): mismo botón, con aire hasta el
   formulario que lleva debajo. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle--back{margin-bottom:1.5rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle:hover,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-account__mode-toggle:focus-visible{background:var(--ink);color:#fff}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__social .btn{width:100%;height:3.25rem;background:#fff}
/* Blanco solo en reposo: sobre el crema. Al hover, el de .btn-pill--secondary
   (--ink con texto blanco); sin esto el fondo seguía blanco y el texto,
   blanco, desaparecía. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__social .btn:hover,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__social .btn:focus-visible{background:var(--ink);color:#fff}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__divider{display:flex;align-items:center;gap:1rem;margin:1.5rem 0;font-size:.72rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__divider::before,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .ritual-login__divider::after{content:"";flex:1;height:1px;background:rgba(41,37,28,.15)}

.ritual-account__forgot{margin:-.5rem 0 1.5rem;text-align:right;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem}
.ritual-account__forgot a{color:var(--ink);opacity:.7;text-decoration:underline;text-underline-offset:2px}
.ritual-account__forgot a:hover{opacity:1;color:var(--brass)}
.ritual-account__submit,
.ritual-account #magiclogin-form .btn-pill,
.ritual-account #customer-form .form-control-submit{width:100%;height:3.25rem}
.ritual-account #customer-form .buttons-wrapper,
.ritual-account #magiclogin-form .buttons-wrapper{display:block}
.ritual-account__link{padding:0;border:0;background:none;font-family:"Helvetica LT Std",sans-serif;font-size:.875rem;color:var(--ink);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.ritual-account__link:hover,
.ritual-account__link:focus-visible{color:var(--brass)}
.ritual-account__switch{display:flex;flex-wrap:wrap;justify-content:center;gap:.4rem;margin:2rem 0 0;padding-top:1.5rem;border-top:1px solid rgba(41,37,28,.12);font-family:"Helvetica LT Std",sans-serif;font-size:.875rem;color:rgba(41,37,28,.7)}
.ritual-account__switch .ritual-account__link{font-weight:700;color:var(--ink)}
/* Campos: los de _partials/form-fields.tpl (core) y los del enlace mágico
   (magiclogin-form.tpl, .input-field__*), con un solo aspecto. Etiqueta
   pequeña en mayúsculas encima, campo blanco de 3rem con filete fino y
   foco en --brass, "Opcional" y ayudas en metadato. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field{margin-bottom:1.25rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-label,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__label{display:block;margin:0 0 .4rem;font-family:"Helvetica LT Std",sans-serif;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.1em;text-transform:uppercase;color:rgba(41,37,28,.75)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-label.required::after,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__label.required::after{content:none}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3 > .form-control,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3 > .form-select,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .js-parent-focus .form-select,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__wrap,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field{display:block;width:100%;height:3rem;padding:0 1rem;border:1px solid rgba(41,37,28,.2);border-radius:12px;background:#fff;font-family:"Helvetica LT Std",sans-serif;font-size:1rem;font-weight:400;color:var(--ink);box-shadow:none;transition:border-color var(--motion-hover) var(--motion-ease), box-shadow var(--motion-hover) var(--motion-ease)}
/* Enlace mágico: la caja es la del contenedor (.input-field__wrap, sistema
   de formularios); el campo va dentro sin borde propio, o salían dos. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__wrap{display:flex;align-items:center;padding:0 1rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__control{height:100%;padding:0;border:0;background:transparent;box-shadow:none;font-family:"Helvetica LT Std",sans-serif;font-size:1rem;font-weight:400}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3 > .form-control:hover:not(:focus),
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__wrap:hover:not(:focus-within),
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field:hover:not(:focus-within){border-color:rgba(41,37,28,.4)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3 > .form-control:focus,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .mb-3 > .form-select:focus,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .input-field__wrap:focus-within,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field:focus-within{outline:none;border-color:var(--brass);box-shadow:0 0 0 3px color-mix(in srgb, var(--brass) 18%, transparent)}
/* Contraseña: el botón de mostrarla va dentro del campo, sin su azul. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field{display:flex;align-items:stretch;padding:0;overflow:hidden}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .form-control{flex:1;min-width:0;height:auto;padding:0 1rem;border:0;border-radius:0;background:transparent;box-shadow:none}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .form-control:focus{box-shadow:none}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .btn{display:flex;align-items:center;padding:0 1rem;border:0;border-radius:0;background:transparent;color:rgba(41,37,28,.6);box-shadow:none}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .btn:hover,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .btn:focus-visible{color:var(--brass);background:transparent}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .password-field .btn .material-icons{font-size:1.25rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .js-parent-focus{display:flex;gap:.5rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-text{margin-top:.35rem;font-family:"Helvetica LT Std",sans-serif;font-size:.75rem;color:rgba(41,37,28,.55)}
/* Casillas (newsletter, privacidad): texto legal, y la casilla de la casa. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check{display:flex;align-items:flex-start;gap:.6rem;padding-left:0}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check-input{flex:none;float:none;width:1.125rem;height:1.125rem;margin:.15rem 0 0;border:1px solid rgba(41,37,28,.45);border-radius:4px;box-shadow:none}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check-input:checked{background-color:var(--brass);border-color:var(--brass)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check-input:focus{box-shadow:0 0 0 3px color-mix(in srgb, var(--brass) 18%, transparent);border-color:var(--brass)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check-label{font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;font-weight:400;line-height:1.5;color:rgba(41,37,28,.8)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .form-check-label a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}
/* Errores: filete del campo y mensaje en --color-error. */
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .has-error .form-control,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .has-error .password-field{border-color:var(--color-error)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .help-block,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .invalid-feedback{font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;color:var(--color-error)}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account .alert-danger{border:0;border-radius:12px;background:color-mix(in srgb, var(--color-error) 8%, #fff);color:var(--color-error);font-size:.875rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account #customer-form section{margin-bottom:1.5rem}
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account #customer-form .buttons-wrapper,
:is(#checkout-personal-information-step, #authentication, #registration) .ritual-account #magiclogin-form .buttons-wrapper{margin-top:.5rem}
@media (prefers-reduced-motion: reduce){
  .ritual-account .mb-3 > .form-control,
  .ritual-account .input-field__control,
  .ritual-account .password-field{transition:none}
  .ritual-account__view{animation:none!important}
  .ritual-account__choice{transition:none}
}

/* Contenedor del resto del proceso: el paso 1 con la sesión ya iniciada
   (cuenta, teléfono si falta, "Continuar") y los paneles 2 y 3. La
   superficie de la card del calendario de la ficha (crema rebajado, 16px,
   sin borde ni sombra), a 38rem, el ancho de la pregunta del paso 1. Las
   acciones cierran la tarjeta tras un filete. */
.ritual-payflow #checkout-personal-information-step .step__content:has(> .step__account),
.ritual-pay-panel{max-width:38rem;margin:0 auto;padding:2.5rem;border-radius:16px;background:color-mix(in srgb, var(--ritual-cream) 55%, #fff)}
@media (max-width:575px){
  .ritual-payflow #checkout-personal-information-step .step__content:has(> .step__account),
  .ritual-pay-panel{padding:1.75rem 1.25rem}
}
.ritual-payflow #checkout-personal-information-step .step__account p{margin:0 0 .35rem;font-family:"Helvetica LT Std",sans-serif;font-size:1rem;color:var(--ink)}
.ritual-payflow #checkout-personal-information-step .step__account a{color:var(--ink);font-weight:700;text-decoration:underline;text-underline-offset:3px}
.ritual-payflow #checkout-personal-information-step .step__account a.text-danger{font-weight:400;color:rgba(41,37,28,.7)!important}
.ritual-payflow #checkout-personal-information-step .step__account a:hover{color:var(--brass)!important}
/* Dentro de la tarjeta, el formulario del teléfono deja su propia caja. */
.ritual-payflow #checkout-phone-form{margin-top:1.5rem;padding:1.5rem 0 0;border:0;border-top:1px solid rgba(41,37,28,.12);border-radius:0;background:none}
.ritual-payflow #checkout-continue-form .buttons-wrapper{margin-top:1.5rem!important;padding-top:1.5rem;border-top:1px solid rgba(41,37,28,.12)}
.ritual-payflow #checkout-continue-form .btn-pill,
.ritual-payflow #checkout-phone-form .btn-pill{display:inline-flex;align-items:center;gap:.4rem;min-width:12rem;height:3.25rem;justify-content:center}

/* Paso 2 · Método de pago: cada método es una opción grande y blanca sobre
   el crema del panel, con el radio de la casa; la elegida, con filete
   --brass. */
.ritual-pay-panel .payment-options__list{gap:.75rem}
.ritual-pay-panel .payment-option{padding:1.1rem 1.25rem;border-radius:12px;border-color:rgba(41,37,28,.12);background:#fff;transition:border-color var(--motion-hover) var(--motion-ease), background-color var(--motion-hover) var(--motion-ease)}
.ritual-pay-panel .payment-option:has(.form-check-ritual__input:checked){background:#fff;box-shadow:0 0 0 1px var(--brass)}
.ritual-pay-panel .payment-option__label{gap:.75rem;font-size:1rem;cursor:pointer}
.ritual-pay-panel .payment-option__label img{max-height:1.75rem;width:auto}
/* Opciones de ps_checkout: su CSS (payments.css) fuerza el label a inline con
   line-height 2.5; vuelve a ser flex como el resto, para que su imagen
   (PayPal y Google Pay desde la plantilla, el resto desde checkout-flow.js)
   quede a la izquierda del texto igual que la de Redsys. Mismo alto que las de Redsys
   (16px, el natural de sus PNG). */
.ritual-pay-panel .ps_checkout-payment-option .payment-option__label{display:flex!important;line-height:1.2}
.ritual-pay-panel .payment-option:has(input[data-module-name^="ps_checkout-"]) .payment-option__label > img{flex:none;height:16px;width:auto}
/* Si la imagen ya viene en la plantilla (PayPal, Google Pay), la marca que
   pinta el SDK sobra. Se oculta en vez de quitarla: el SDK la sigue
   buscando para pintar dentro. !important frente a su display en línea. */
.ritual-pay-panel .payment-option:has(.payment-option__label > img) .ps_checkout-mark{display:none!important}
.ritual-pay-panel .payment-option__additional-information{margin-top:.75rem;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;line-height:1.5;color:rgba(41,37,28,.7)}
.ritual-pay-panel .payment-options__free,
.ritual-pay-panel .payment-options__updated{margin:0 0 1rem;font-size:1rem}

/* Paso 3 · Resumen (condiciones y pagar, tras la lista y el total). El aviso del core ("elige
   un método y acepta las condiciones") como nota suave, no caja roja. */
.ritual-pay-panel #conditions-to-approve{margin:0!important}
.ritual-pay-panel #conditions-to-approve .form-check-ritual{align-items:flex-start;gap:.6rem}
.ritual-pay-panel .js-alert-payment-conditions{margin:1.25rem 0 0!important;padding:.75rem 1rem;border:0;border-radius:12px;background:#fff;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;line-height:1.5;color:rgba(41,37,28,.8)}
.ritual-pay-panel .js-alert-payment-conditions .alert-link{color:var(--ink);text-decoration:underline;text-underline-offset:2px}
.ritual-pay-panel .ritual-pay-summary__total + #conditions-to-approve{margin-top:1.5rem!important}
.ritual-pay-panel #payment-confirmation .btn-pill{display:inline-flex;align-items:center;justify-content:center;gap:.4rem}

/* Paso 3 · Resumen: filas blancas sobre el crema del panel, con icono en
   círculo (--brass relleno si la cita ya está reservada, contorno si es un
   servicio sin cita o un regalo), nombre, etiqueta de cita/regalo y precio
   en --brass. Total al pie, destacado. */
.ritual-pay-summary{display:flex;flex-direction:column;gap:.6rem;margin:0;padding:0;list-style:none}
.ritual-pay-summary__line{display:flex;align-items:center;gap:1rem;padding:1rem 1.25rem;border-radius:12px;background:#fff}
.ritual-pay-summary__icon{display:flex;flex:none;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border:1px solid color-mix(in srgb, var(--brass) 45%, #fff);border-radius:50%;color:var(--brass)}
.ritual-pay-summary__icon .material-icons{font-size:1.25rem}
.ritual-pay-summary__line--booked .ritual-pay-summary__icon{border-color:var(--brass);background:var(--brass);color:#fff}
.ritual-pay-summary__main{display:flex;flex:1;flex-direction:column;align-items:flex-start;gap:.35rem;min-width:0}
.ritual-pay-summary__name{font-size:1.125rem;line-height:1.3;color:var(--ink);overflow-wrap:anywhere}
.ritual-pay-summary__chip{display:inline-block;padding:.15rem .6rem;border-radius:999px;background:color-mix(in srgb, var(--brass) 12%, #fff);font-family:"Helvetica LT Std",sans-serif;font-size:.75rem;font-weight:700;line-height:1.5;color:var(--brass);font-variant-numeric:tabular-nums}
.ritual-pay-summary__chip--gift{background:none;border:1px solid var(--ink);color:var(--ink);letter-spacing:.1em;text-transform:uppercase;font-size:.68rem}
.ritual-pay-summary__price{flex:none;font-family:"Helvetica LT Std",sans-serif;font-size:1.0625rem;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
/* Cita conjunta: un bloque blanco con filete --brass a la izquierda (el
   recurso con que la tabla del carrito marca la cita encadenada), su
   título con la fecha; dentro, sus servicios como filas sin
   fondo propio, separadas por filetes, y con la hora entre ellos. */
.ritual-pay-summary__group{padding:1.1rem 1.25rem .35rem;border-left:2px solid var(--brass);border-radius:12px;background:#fff}
.ritual-pay-summary__group-title{display:flex;align-items:center;gap:.5rem;margin:0;font-family:"Helvetica LT Std",sans-serif;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:var(--brass)}
.ritual-pay-summary__group-title .material-icons{font-size:1.125rem}
.ritual-pay-summary__group-list{margin:.35rem 0 0;padding:0;list-style:none}
.ritual-pay-summary__group-list .ritual-pay-summary__line{padding:.85rem 0;border-radius:0;background:none}
.ritual-pay-summary__group-list .ritual-pay-summary__line + .ritual-pay-summary__line{border-top:1px solid rgba(41,37,28,.1)}
/* El icono sobra en cada eslabón: el bloque ya dice que es una cita. */
.ritual-pay-summary__group-list .ritual-pay-summary__icon{display:none}
@media (max-width:575px){
  .ritual-pay-summary__group{padding:1rem 1rem .25rem}
}
.ritual-pay-summary__line--voucher{background:none;border:1px dashed color-mix(in srgb, var(--brass) 45%, #fff)}
.ritual-pay-summary__line--voucher .ritual-pay-summary__name{font-size:.9375rem}
.ritual-pay-summary__line--voucher .ritual-pay-summary__price{color:var(--brass)}
@media (max-width:575px){
  .ritual-pay-summary__line{gap:.75rem;padding:.85rem 1rem}
  .ritual-pay-summary__icon{width:2.125rem;height:2.125rem}
  .ritual-pay-summary__name{font-size:1rem}
}
.ritual-pay-summary__total{display:grid;grid-template-columns:1fr auto;align-items:baseline;column-gap:1rem;margin:1.75rem 0 0;padding:1.25rem 0 0;border-top:1px solid rgba(41,37,28,.15);font-family:"Helvetica LT Std",sans-serif;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6)}
.ritual-pay-summary__total strong{font-family:inherit;font-size:2rem;font-weight:400;line-height:1.1;letter-spacing:0;text-transform:none;color:var(--brass);font-variant-numeric:tabular-nums}
.ritual-pay-summary__tax{grid-column:2;justify-self:end;margin-top:.2rem;font-size:.72rem;font-weight:400;letter-spacing:0;text-transform:none;color:rgba(41,37,28,.55)}

/* Acciones de cada panel: "Atrás" a la izquierda, avanzar a la derecha. */
/* flex-direction/nowrap explícitos: el del último paso lleva además
   .buttons-wrapper del tema padre, que en móvil apila en columna y dejaba
   "Atrás" y el botón de pagar escalonados. */
.ritual-pay-panel__actions{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:flex-end;align-items:center;gap:.75rem;margin-top:2rem;padding-top:1.5rem;border-top:1px solid rgba(41,37,28,.12)}
.ritual-pay-panel__actions [data-pay-back]{margin-right:auto}
.ritual-pay-panel__actions > .btn-pill,
.ritual-pay-panel__actions #payment-confirmation .btn-pill{min-width:12rem;height:3.25rem}
/* Móvil: "Atrás" se queda en lo que mide su texto y la acción principal
   (Continuar / Realizar pedido) ocupa el resto. A partes iguales, el pedido
   quedaba estrujado junto a un "Atrás" igual de grande. */
@media (max-width:575px){
  .ritual-pay-panel__actions{gap:.5rem}
  .ritual-pay-panel__actions > [data-pay-back]{flex:0 0 auto;min-width:0;padding-inline:1.25rem}
  .ritual-pay-panel__actions > [data-pay-next],
  .ritual-pay-panel__actions #payment-confirmation{flex:1 1 auto;min-width:0}
  .ritual-pay-panel__actions #payment-confirmation .btn-pill{width:100%;min-width:0;padding-inline:1rem;white-space:nowrap}
}
/* Botón de ps_checkout (PayPal…) en el sitio de "Realizar pedido": mismo
   ancho mínimo; en móvil, el resto de la fila junto a "Atrás". El mt-1 que
   trae su plantilla lo descolgaba de la fila. */
.ritual-pay-panel__actions .js-payment-binary{flex:0 1 16rem;min-width:12rem;margin-top:0!important}
/* Google Pay: su botón (de Google, en modo "fill") ocupa todo su contenedor;
   con el mismo alto que "Realizar pedido" y recortado en píldora. El de
   PayPal se ajusta desde checkout-flow.js (va en un iframe). */
.ritual-pay-panel__actions .ps_checkout-button[data-funding-source="google_pay"]{height:3.25rem;border-radius:999px;overflow:hidden}
@media (max-width:575px){
  .ritual-pay-panel__actions .js-payment-binary{flex:1 1 auto;min-width:0}
}

.ritual-checkout-table{width:100%;border-collapse:collapse;margin-top:3rem;margin-bottom:6rem}
/* Anchos fijos vía <colgroup>, SOLO en la tabla del carrito
   (.ritual-checkout-table--fixed, cart-table.tpl): sin ellos, PRODUCTO
   absorbía todo el ancho sobrante (única columna sin ancho propio) y
   empujaba PRECIO/RESERVA/ACCIONES tan a la derecha que el hueco entre el
   nombre y el precio se leía como dos islas. No se aplica a la tabla base
   .ritual-checkout-table porque la comparte order-confirmation-summary-table.tpl,
   con 4 columnas distintas (código/servicio/precio/reserva) y sin colgroup
   propio — table-layout:fixed ahí tomaría los anchos literales de esa
   cabecera (p.ej. el `width:1%` de la referencia, pensado para layout
   automático) y rompería esa tabla. */
.ritual-checkout-table--fixed{table-layout:fixed}
.ritual-checkout-table__col-product{width:44%}
.ritual-checkout-table__col-price{width:14%}
.ritual-checkout-table__col-booking{width:30%}
.ritual-checkout-table__col-actions{width:12%}
/* Tipografía de las tablas del checkout y la confirmación: estándar de
   "Extensiones del estándar (páginas transaccionales y de contenido)" —
   cabecera de tabla en antetítulo, filas en dato, personalización del
   regalo en metadato, badge unificado y total en su propio paso. */
.ritual-checkout-table thead th{text-align:left;text-transform:uppercase;letter-spacing:.12em;font-size:.72rem;font-weight:700;line-height:1.4;color:rgba(41,37,28,.6);border-bottom:2px solid var(--ink);padding-bottom:.75rem}
.ritual-checkout-table th.ritual-checkout-table__price,
.ritual-checkout-table td.ritual-checkout-table__price{text-align:right;white-space:nowrap}
/* Aire y jerarquía (pasada visual de fases 3-6): la tabla se leía vacía —
   tres columnas de texto del mismo tamaño y del mismo peso, con filas muy
   juntas. Se resuelve donde se puede resolver en un spa: con espacio y con
   escala, no añadiendo bordes ni sombras. Las filas respiran (1.5rem por
   arriba y por abajo en vez de .9), el nombre del servicio y el importe
   suben al paso de "texto destacado" del estándar (1.125rem) y todo lo
   demás se queda donde estaba, que es lo que crea la jerarquía. */
.ritual-checkout-table__row td{padding:1.5rem 0;border-bottom:1px solid rgba(41,37,28,.15)}
.ritual-checkout-table__product-name{display:inline;font-size:1.125rem;font-weight:400;line-height:1.4;color:var(--ink)}
.ritual-checkout-table__row .ritual-checkout-table__product{font-size:1.125rem;font-weight:400;line-height:1.4;color:var(--ink)}
.ritual-checkout-table__row .ritual-checkout-table__price{font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink);font-variant-numeric:tabular-nums}
.ritual-checkout-table__price-value{display:inline-block;font-size:1.125rem;line-height:1.4;font-variant-numeric:tabular-nums}
.ritual-checkout-table__gift-badge{display:inline-block;font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:.1rem .6rem;margin-left:.5rem;vertical-align:middle;padding-top:4px}
/* La insignia "va encadenada con otra" (.rb-chain-badge) se retira en la
   pasada visual de fases 3-6: se repetía en cada línea del grupo diciendo
   siempre lo mismo, y no servía para lo que hacía falta, que era saber QUÉ
   líneas van juntas. Lo sustituye el bloque con cabecera de fecha y filete
   lateral --brass (.ritual-checkout-table__row--chain aquí abajo, y su
   equivalente .rb-cart-flyout__item--chain en el desplegable). */
.ritual-checkout-table__coupon-code{display:inline-block;font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:var(--ink);border:1px solid var(--ink);border-radius:999px;padding:.1rem .6rem;margin-left:.5rem;vertical-align:middle}
.ritual-checkout-table__customizations{margin-top:.4rem;font-size:.8125rem;font-weight:400;line-height:1.4;color:rgba(41,37,28,.6)}
.ritual-checkout-table__custom-field{margin-bottom:.15rem}
.ritual-checkout-table__custom-label{font-weight:700}
.ritual-checkout-table__custom-value{margin-left:.25rem}
/* Eliminar el artículo del carrito. Antes era una papelera muda al 60% de
   opacidad, y en la misma fila había un "Quitar" (que sólo quitaba la cita):
   las dos se leían como la misma acción, o ninguna de las dos se leía. Ahora
   la papelera lleva su palabra al lado, va a plena opacidad y su hover es el
   rojo de error del estándar — es la única acción destructiva de la fila. */
.ritual-checkout-table__remove{display:inline-flex;align-items:center;gap:.3rem;color:var(--ink);opacity:.75;text-decoration:none;transition:color var(--motion-hover) var(--motion-ease), opacity var(--motion-hover) var(--motion-ease)}
.ritual-checkout-table__remove .material-icons{font-size:1.125rem}
.ritual-checkout-table__remove-label{font-size:.8125rem;font-weight:400;line-height:1.4;text-decoration:underline;text-underline-offset:2px}
.ritual-checkout-table__remove:hover,
.ritual-checkout-table__remove:focus-visible{opacity:1;color:var(--color-error)}
@media (prefers-reduced-motion: reduce){
  .ritual-checkout-table__remove{transition:none}
}
.ritual-checkout-table th.ritual-checkout-table__booking,
.ritual-checkout-table__row .ritual-checkout-table__booking{padding-left:2rem;text-align:right}
/* Columna propia de "Eliminar" (antes vivía dentro de PRECIO, pegada al
   importe, sin cabecera propia — se leía como parte del precio). Angosta y
   discreta a propósito: es la única acción destructiva de la fila y no
   compite con el precio ni con la reserva. */
/* padding-right: las filas van a padding horizontal 0 y "Eliminar" quedaba
   pegado al borde derecho de la tabla. */
.ritual-checkout-table th.ritual-checkout-table__actions,
.ritual-checkout-table td.ritual-checkout-table__actions{text-align:right;padding-left:1rem;padding-right:1rem}
/* Botón "Reservar" por línea: un pill outline repetido en cada fila sin
   cita forma un muro en el margen derecho. Mismo peso visual que "Quitar la
   cita" de abajo —metadato accionable en --brass, negrita para que siga
   leyéndose como una llamada a la acción— en vez de una caja con borde. */
.ritual-checkout-table__booking .js-cart-row-reserve{
  display:inline;
  padding:0;
  border:none;
  border-radius:0;
  background:none;
  box-shadow:none;
  color:var(--brass);
  font-size:.9375rem;
  font-weight:700;
  text-transform:none;
  letter-spacing:normal;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:opacity var(--motion-hover) var(--motion-ease);
}
.ritual-checkout-table__booking .js-cart-row-reserve:hover,
.ritual-checkout-table__booking .js-cart-row-reserve:focus-visible{
  transform:none;
  box-shadow:none;
  color:var(--brass);
  opacity:.7;
}
@media (prefers-reduced-motion: reduce){
  .ritual-checkout-table__booking .js-cart-row-reserve{transition:none}
}
.ritual-checkout-table__reservation{margin:0;font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink);font-variant-numeric:tabular-nums}
/* La cita ya elegida es un estado confirmado, y el acento de marca es
   justo para eso (DIRECCION-VISUAL.md #1). Va en su propia línea para que
   "Quitar la cita" no compita con el dato. */
.ritual-checkout-table__reservation-value{display:block;font-weight:700;color:var(--brass);font-variant-numeric:tabular-nums}
/* "Quitar la cita": metadato accionable, igual que el "Quitar" de la ficha.
   Deliberadamente por debajo de "Eliminar" en peso visual — no borra nada
   del carrito, sólo libera la hora. */
.ritual-checkout-table__reservation a{display:inline-block;margin-top:.35rem;color:rgba(41,37,28,.6);font-size:.8125rem;font-weight:400;text-decoration:underline;text-underline-offset:2px;transition:color var(--motion-hover) var(--motion-ease)}
.ritual-checkout-table__reservation a:hover,
.ritual-checkout-table__reservation a:focus-visible{color:var(--brass)}
@media (prefers-reduced-motion: reduce){
  .ritual-checkout-table__reservation a{transition:none}
}

/* --- Cita encadenada: bloque con cabecera de fecha y filete lateral ---
   "Conjunta 1" no identificaba nada; la fecha sí. La cabecera dice de qué
   cita se trata una sola vez, y el filete --brass (el mismo recurso de
   .rb-chain__order en el modal de cadena, para que se reconozca como lo
   mismo) marca hasta dónde llega el bloque. Las líneas sueltas no lo
   llevan, y ahí está toda la distinción: con filete = van juntas; sin
   filete = servicio independiente. Sin bordes nuevos ni sombras: un filete
   de 2px y un lavado del mismo tono al 5%.
   El borde va en la PRIMERA celda y no en el <tr>: con border-collapse los
   bordes de fila no se pintan. */
.ritual-checkout-table__row--chain td{background:color-mix(in srgb, var(--brass) 5%, transparent);border-bottom:none}
.ritual-checkout-table__row--chain td.ritual-checkout-table__product{border-left:2px solid var(--brass);padding-left:1.25rem}
.ritual-checkout-table__row--chain td.ritual-checkout-table__booking{padding-right:1.25rem}
.ritual-checkout-table__row--chain-last td{border-bottom:1px solid rgba(41,37,28,.15)}
.ritual-checkout-table__row--chain-header td{padding-top:1.5rem;padding-bottom:.5rem}
/* Título de la cita: mismo antetítulo del estándar que el resto de
   rótulos de la tabla, en --brass porque nombra la agrupación de marca. */
.ritual-checkout-table__chain-title{display:block;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:var(--brass)}
.ritual-checkout-table__chain-note{display:block;margin-top:.3rem;font-size:.8125rem;font-weight:400;line-height:1.5;color:rgba(41,37,28,.6)}
/* Cantidad múltiple (RESERVAS-MULTIPLES.md §7.3): cabecera de grupo (nombre
   + "N unidades" + "x de N reservadas") sin filete propio — el filete de
   cada fila de unidad ya marca la separación — y las filas de unidad con un
   nombre más ligero ("Unidad n") que el resto de la tabla, porque el nombre
   real ya se dijo una vez en la cabecera. */
.ritual-checkout-table__row--group-header td{padding-bottom:.35rem;border-bottom:none}
.ritual-checkout-table__multi-badge{display:inline-block;margin-left:.5rem;font-size:.8125rem;font-weight:400;color:rgba(41,37,28,.6)}
.ritual-checkout-table__multi-progress{display:block;margin-top:.15rem;font-size:.8125rem;font-weight:400;color:rgba(41,37,28,.6)}
.ritual-checkout-table__row--unit td{padding-top:.5rem;padding-bottom:.5rem}
/* Sangría suave para que cada unidad se lea anidada bajo su cabecera de
   grupo (--row--group-header), no como una fila más al mismo nivel. */
.ritual-checkout-table__row--unit .ritual-checkout-table__product{padding-left:1rem}
.ritual-checkout-table__product-name--unit{font-size:.8125rem;font-weight:400;color:rgba(41,37,28,.6)}
/* Cierre del bloque de unidades propias (§7): un filete algo más marcado en
   la última unidad, para que lo que venga detrás —el mismo servicio comprado
   como regalo, por ejemplo— no se lea como una unidad más del grupo. La
   cabecera dice "N unidades" y sólo cuenta las propias; este filete es donde
   se ve que el grupo termina. */
.ritual-checkout-table__row--unit-last td{border-bottom:1px solid rgba(41,37,28,.28)}
/* Fila de regalo de un servicio reservable: no es una unidad del grupo, es
   otra compra con otro destinatario. Se saca de la sangría de las unidades
   (nombre completo, no "Unidad n") y se separa con aire por arriba. */
.ritual-checkout-table__row--gift td{padding-top:1rem}
/* Por qué la casilla de reserva de un regalo no trae botón. Tono de
   metadato, igual que el resto de la columna. */
.ritual-checkout-table__gift-reservation{margin:0;font-size:.8125rem;line-height:1.5;color:rgba(41,37,28,.6);max-width:20rem}
/* Separación clara del cuerpo: mismo filete --ink de 2px que ya usa la
   cabecera de la tabla (thead), para que TOTAL se lea como su propio bloque
   y no como una fila más pegada a la última línea. */
.ritual-checkout-table__total td{padding-top:1.75rem;border-top:2px solid var(--ink);border-bottom:none}
/* Total: "Total" en cabecera de tabla, importe a 1.5rem en --brass. */
.ritual-checkout-table__total .ritual-checkout-table__product{font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6)}
.ritual-checkout-table__total .ritual-checkout-table__price{font-size:1.5rem;font-weight:400;line-height:1.2;color:var(--brass);font-variant-numeric:tabular-nums}
.ritual-checkout-table__total .ritual-checkout-table__booking{padding-left:2rem;text-align:right}

.ritual-checkout-table.ritual-order-confirmation-table{margin-bottom:0}
/* Referencia de pedido: código/referencia (antetítulo, cifras tabulares). */
.ritual-checkout-table__row .ritual-order-confirmation-table__reference{width:1%;white-space:nowrap;padding-right:1.5rem;font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:rgba(41,37,28,.6);font-variant-numeric:tabular-nums}
.ritual-order-confirmation-table th.ritual-order-confirmation-table__booking,
.ritual-checkout-table__row .ritual-order-confirmation-table__booking,
.ritual-checkout-table__total .ritual-order-confirmation-table__booking{width:30%;text-align:right;padding-left:2rem}
.ritual-order-confirmation-table__booking-date,
.ritual-order-confirmation-table__booking-warning{display:block;margin-bottom:.4rem}
/* "Reservado: fecha hora": estado. "No hemos podido confirmar la hora que
   elegiste" es una frase: mensaje de validación. */
.ritual-order-confirmation-table__booking-date{font-size:.72rem;font-weight:700;line-height:1.4;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);font-variant-numeric:tabular-nums}
.ritual-order-confirmation-table__booking-warning{font-size:.8125rem;font-weight:400;line-height:1.4;color:var(--color-error)}
/* Pack: fila con su nombre y su precio, y debajo sus servicios (sin precio,
   el repartido no corresponde a nada) colgando de un filete --brass. */
.ritual-order-confirmation-table tr.ritual-checkout-table__row--pack td{padding-bottom:.5rem;border-bottom:0}
.ritual-order-confirmation-table tr.ritual-checkout-table__row--pack-item td.ritual-checkout-table__product{padding-left:1.25rem;box-shadow:inset 2px 0 0 var(--brass)}

/* --- Mobile: la columna Reserva (fecha/aviso + CTA) no cabe junto a
   Servicio/Precio sin scroll lateral. En vez de 4 (o 3) columnas
   apretadas, cada <tr> pasa a flex-wrap y la celda de reserva se fuerza
   a una línea propia de 100% de ancho debajo del resto — mismo patrón
   para cart-table.tpl y order-confirmation-summary-table.tpl, que
   comparten las clases base .ritual-checkout-table*. --- */
@media (max-width:767px){
  /* Sacar la tabla del algoritmo de layout de <table> (auto table layout):
     con las filas en flex pero la tabla/tbody aún como table/table-row-group,
     el ancho de columnas se sigue calculando por contenido intrínseco (un
     email largo, un código de reserva, el texto del botón) y puede exceder
     el viewport → scroll lateral en toda la página, no solo en la tabla. */
  .ritual-checkout-table{display:block; width:100%;}
  .ritual-checkout-table thead{display:none}
  .ritual-checkout-table tbody,
  .ritual-checkout-table tfoot{display:block; width:100%;}
  .ritual-checkout-table tr.ritual-checkout-table__row,
  .ritual-checkout-table tr.ritual-checkout-table__total{
    display:flex;
    flex-wrap:wrap;
    align-items:baseline;
    width:100%;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td,
  .ritual-checkout-table tr.ritual-checkout-table__total td{
    display:block;
    padding:0;
    border-bottom:none;
    min-width:0;
    max-width:100%;
  }
  .ritual-checkout-table__product-name,
  .ritual-checkout-table__custom-value,
  .ritual-checkout-table__coupon-code,
  .ritual-order-confirmation-table__reference{
    overflow-wrap:anywhere;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-order-confirmation-table__reference{
    order:0;
    width:100%;
    padding:0 0 .3rem;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-order-confirmation-table__reference:empty{
    padding:0;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-checkout-table__product,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-checkout-table__product{
    order:1;
    flex:1 1 auto;
    padding-right:.75rem;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-checkout-table__price,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-checkout-table__price{
    order:2;
    flex:0 0 auto;
    text-align:right;
    white-space:nowrap;
  }
  /* "Eliminar" tiene su propia celda (ya no vive dentro de PRECIO): baja a
     su propia línea, alineada a la derecha bajo el precio, igual que antes
     se apilaba dentro de la celda de precio — sólo que ahora es su propia
     columna con su propia cabecera. */
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-checkout-table__actions,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-checkout-table__actions{
    order:2;
    flex:0 0 100%;
    text-align:right;
    margin-top:.4rem;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-checkout-table__booking,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-checkout-table__booking,
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-order-confirmation-table__booking,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-order-confirmation-table__booking{
    order:3;
    width:100%;
    flex:0 0 100%;
    text-align:left;
    padding:.9rem 0 0;
    margin-top:1rem;
    border-top:1px dashed rgba(41,37,28,.15);
  }
  /* En móvil la celda del pie pasa a 100% y alineada a la IZQUIERDA, así
     que el botón y su tooltip quedan pegados al borde izquierdo. El bubble
     se ancla por la derecha (right:0, cart-reservation.css) porque en
     escritorio la celda va alineada a la derecha; manteniéndolo así aquí se
     saldría de la pantalla por la izquierda. Sólo para ESTE tooltip: los de
     confirmación de pedido y mi cuenta no cambian de alineación. */
  .ritual-checkout-table__chain-tip .rb-info-tip__bubble{right:auto;left:0}
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-checkout-table__booking:empty,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-checkout-table__booking:empty,
  .ritual-checkout-table tr.ritual-checkout-table__row td.ritual-order-confirmation-table__booking:empty,
  .ritual-checkout-table tr.ritual-checkout-table__total td.ritual-order-confirmation-table__booking:empty{
    border-top:none;
    margin-top:0;
    padding:0;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row{
    padding:1.25rem 0;
    border-bottom:1px solid rgba(41,37,28,.15);
  }
  .ritual-order-confirmation-table tr.ritual-checkout-table__row--pack{
    padding-bottom:.25rem;
    border-bottom:0;
  }
  .ritual-order-confirmation-table tr.ritual-checkout-table__row--pack-item td.ritual-checkout-table__product{
    padding-left:1.25rem;
  }
  /* El filete del total va en la <tr>, no en cada celda. Con la fila en
     flex y align-items:baseline, la celda del importe (1.5rem/1.2) y la de
     la etiqueta (.72rem/1.4) no arrancan a la misma altura: la del importe
     queda ~10px más arriba, así que sus border-top se dibujaban a dos
     alturas distintas y el importe aparecía por encima del filete largo de
     la etiqueta. En la <tr> el filete es uno solo y cruza la fila entera,
     como en escritorio, sea cual sea el ancho o el tamaño del importe. */
  .ritual-checkout-table tr.ritual-checkout-table__total{
    padding-top:1rem;
    border-top:2px solid var(--ink);
  }
  .ritual-checkout-table tr.ritual-checkout-table__total td{
    border-top:none;
  }
  /* Con las filas en flex, el <tr> SÍ admite borde: el filete de la cita
     pasa ahí, que es donde cubre la fila entera (y no sólo la celda del
     servicio, como en la tabla de escritorio). */
  .ritual-checkout-table tr.ritual-checkout-table__row--chain{
    border-left:2px solid var(--brass);
    border-bottom:none;
    padding-left:.85rem;
    background:color-mix(in srgb, var(--brass) 5%, transparent);
  }
  .ritual-checkout-table tr.ritual-checkout-table__row--chain-last{
    border-bottom:1px solid rgba(41,37,28,.15);
  }
  .ritual-checkout-table tr.ritual-checkout-table__row--chain td{
    background:none;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row--chain td.ritual-checkout-table__product{
    border-left:none;
    padding-left:0;
  }
  .ritual-checkout-table tr.ritual-checkout-table__row--chain-header{
    padding-bottom:.35rem;
  }
  /* El separador punteado de la celda de reserva sobra dentro de una cita:
     el bloque ya está delimitado por su filete. */
  .ritual-checkout-table tr.ritual-checkout-table__row--chain td.ritual-checkout-table__booking{
    margin-top:.5rem;
    padding-top:.5rem;
    padding-right:0;
    border-top:none;
  }

  /* Carrito (cart-table.tpl, --fixed) más compacto: cada línea eran cuatro
     alturas —nombre y precio, "Eliminar" solo en la suya, un separador
     punteado y la reserva— y el listado se llenaba de aire. Ahora son dos:
     nombre y precio arriba; la reserva y, al extremo, la papelera (sin el
     texto: el enlace ya lleva aria-label) debajo, sin separador. Menos
     margen alrededor de la tabla. La confirmación de pedido, que comparte
     estas clases, no cambia. */
  .ritual-checkout-table--fixed{
    margin-top:1.5rem;
    margin-bottom:2.5rem;
  }
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row{
    padding-top:1rem;
    padding-bottom:1rem;
  }
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__booking{
    order:3;
    flex:1 1 0;
    width:auto;
    margin-top:.6rem;
    padding:0;
    border-top:none;
  }
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row td.ritual-checkout-table__actions{
    order:4;
    flex:0 0 auto;
    align-self:center;
    margin-top:.6rem;
    margin-left:auto;
    padding:0 0 0 1rem;
  }
  .ritual-checkout-table--fixed .ritual-checkout-table__remove-label{
    display:none;
  }
  .ritual-checkout-table--fixed .ritual-checkout-table__remove .material-icons{
    font-size:1.25rem;
  }
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row--unit{
    padding-top:.6rem;
    padding-bottom:.6rem;
  }
  /* Las cabeceras de cita y de grupo de unidades siguen pegadas a sus
     líneas. */
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row--chain-header,
  .ritual-checkout-table--fixed tr.ritual-checkout-table__row--group-header{
    padding-bottom:.35rem;
    border-bottom:none;
  }
}

/* "Necesitamos tu teléfono…": texto destacado (la jerarquía la da la
   escala, no la negrita). */
.ritual-checkout-auth__question{margin-bottom:.5rem;font-size:1.25rem;font-weight:400;line-height:1.5;color:var(--ink)}
@media (max-width:767px){
  .ritual-checkout-auth__question{font-size:1.125rem}
}

/* --- Phone gate (checkout-phone-form): logged-in customers without a phone
   on file (Google/Facebook sign-up, migrated PS1.6 accounts) hit this before
   they can pay — see CheckoutPersonalInformationStep::handleRequest(). Same
   contained-callout language as .ritual-cart-voucher__column (cream card,
   ink border, 12px radius) so a required action reads as its own block
   instead of a bare label+input floating in the step column. --- */
#checkout-phone-form{
  padding:1.5rem 1.75rem;
  background:var(--ritual-cream);
  border:1px solid var(--ink);
  border-radius:12px;
}
#checkout-phone-form .input-field{
  margin-bottom:0;
}
/* This step's own "Continuar" button (#checkout-continue-form, shown once
   the phone is on file) is left as core's plain .btn-primary blue — a
   pre-existing gap in the checkout steps, out of scope here. But sat inside
   the new cream/ink card, that blue reads as a clash no prior page had, so
   this one button gets the sitewide .btn-pill treatment (ink pill, same
   language as Sign in / Create account / Guardar in "Mis datos"). */
#checkout-phone-form .btn-primary{
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  border:none;
  border-radius:999px;
  background:var(--ink);
  color:#fff;
  font-weight:700;
  font-size:.85rem;
  text-transform:uppercase;
  letter-spacing:.04em;
  padding:.75rem 1.75rem;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
}
#checkout-phone-form .btn-primary:hover,
#checkout-phone-form .btn-primary:focus{
  background:#000;
  color:#fff;
}
@media (max-width:575.98px){
  #checkout-phone-form{
    max-width:none;
    padding:1.25rem;
  }
}

#checkout-payment-step .form-control{border:none;border-bottom:1px solid var(--ink);border-radius:0;background:transparent;padding-left:0}
/* Campos renderizados por el core dentro de #checkout-guest-form (Nombre/
   Apellidos/Email/Teléfono) no tienen un <span> propio que envolver en
   .input-field__wrap (vienen de _partials/form-fields.tpl, fuera de
   alcance) — se les da la misma caja apuntando directamente al
   .form-control, usando el combinador directo para no alcanzar el input
   de contraseña (anidado dentro de .input-group.password-field, no hijo
   directo de .mb-3). */
#checkout-personal-information-step .mb-3 > .form-control,
#checkout-personal-information-step .mb-3 > .form-select{
  display:block;
  width:100%;
  border:1px solid rgba(41,37,28,.25);
  border-radius:10px;
  background:#fff;
  padding:.55rem .75rem;
  font-weight:300;
  font-size:1rem;
  color:var(--ink);
  box-shadow:none;
  transition:border-color .2s ease, box-shadow .2s ease;
}
#checkout-personal-information-step .mb-3 > .form-control:hover:not(:focus),
#checkout-personal-information-step .mb-3 > .form-select:hover:not(:focus){
  border-color:rgba(41,37,28,.45);
}
#checkout-personal-information-step .mb-3 > .form-control:focus,
#checkout-personal-information-step .mb-3 > .form-select:focus{
  outline:none;
  border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(175,138,82,.15);
}
/* --- Tarjeta regalo y cupón: dos desplegables discretos, cerrados por
   defecto, separados de la tabla por un filete. --- */
.ritual-cart-voucher{margin-bottom:4rem;padding-top:1.25rem;border-top:1px solid rgba(41,37,28,.15)}
/* Misma barra que separa el título de "PAGO"/"Datos personales" de su
   contenido (#checkout-payment-step .step__title hr) — reutilizada aquí y
   en el bloque "Reserva tu cita" para que los tres títulos de sección del
   checkout compartan el mismo lenguaje visual. */
.ritual-checkout-hr{margin:1rem 0;border:0;border-top:1px solid rgba(41,37,28,.15)}
/* Cada desplegable cerrado es solo una línea de texto pequeño atenuado con
   su icono y un chevron fino, sin caja: se lee como una opción al margen,
   no como una sección. Abierto, el formulario aparece debajo sin fondo
   propio. align-items:start para que abrir uno no estire el otro. */
.ritual-cart-voucher__columns{display:grid;grid-template-columns:1fr 1fr;gap:.5rem 2rem;align-items:start}
.ritual-cart-voucher__title{display:inline-flex;align-items:center;gap:.4rem;margin:0;padding:.25rem 0;font-family:"Helvetica LT Std",sans-serif;font-size:.8125rem;font-weight:400;line-height:1.4;color:var(--ink);opacity:.6;cursor:pointer;list-style:none;transition:opacity var(--motion-hover) var(--motion-ease)}
.ritual-cart-voucher__title::-webkit-details-marker{display:none}
.ritual-cart-voucher__title .material-icons{font-size:1rem}
.ritual-cart-voucher__title::after{content:"";width:.35rem;height:.35rem;margin-left:.15rem;border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:translateY(-25%) rotate(45deg);transition:transform var(--motion-hover) var(--motion-ease)}
.ritual-cart-voucher__column[open] > .ritual-cart-voucher__title::after{transform:translateY(25%) rotate(-135deg)}
.ritual-cart-voucher__title:hover{opacity:1}
/* Abierto se tiene que notar: el título pasa a --brass en negrita, con
   subrayado, y el formulario va en un panel crema. */
.ritual-cart-voucher__column[open] > .ritual-cart-voucher__title{opacity:1;font-weight:700;color:var(--brass)}
/* El subrayado va en el texto y no en el <summary>: puesto ahí alcanzaba
   también al icono. */
.ritual-cart-voucher__column[open] > .ritual-cart-voucher__title > span{text-decoration:underline;text-underline-offset:4px}
.ritual-cart-voucher__column > form{margin-top:.5rem;padding:.75rem;background:var(--ritual-cream);border-radius:12px;animation:ritual-cart-voucher-in var(--motion-duration) var(--motion-ease)}
@keyframes ritual-cart-voucher-in{
  from{opacity:0;transform:translateY(-.25rem)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion: reduce){
  .ritual-cart-voucher__title,
  .ritual-cart-voucher__title::after{transition:none}
  .ritual-cart-voucher__column > form{animation:none}
}
.ritual-cart-voucher__label-short{display:none}
/* Móvil: los dos en una sola línea repartida (space-evenly), con texto
   corto. El formulario del abierto (solo uno a la vez, ver el
   script de cart-voucher.tpl) se saca de su columna y ocupa todo el ancho
   bajo la línea; la fila reserva su alto con :has() para no tapar lo que
   viene debajo. */
@media (max-width:767px){
  .ritual-cart-voucher__columns{
    position:relative;
    display:flex;
    justify-content:space-evenly;
    gap:0;
  }
  .ritual-cart-voucher__columns:has(.ritual-cart-voucher__column[open]){
    padding-bottom:5.5rem;
  }
  .ritual-cart-voucher__label-long{display:none}
  .ritual-cart-voucher__label-short{display:inline}
  .ritual-cart-voucher__column > form{
    position:absolute;
    left:0;
    right:0;
    top:2.25rem;
    margin-top:0;
  }
}
.ritual-cart-voucher__input-group{display:flex;gap:.5rem}
.ritual-cart-voucher__input-group .input-field__wrap{flex:1}
.ritual-cart-voucher__input-group .input-field__control{font-size:.85rem}
.ritual-cart-voucher__input-group .btn-pill{white-space:nowrap}
.ritual-cart-voucher .cart-voucher__list{list-style:none;padding:0;margin:0 0 1rem}
.ritual-cart-voucher .cart-summary__line{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.6rem .9rem;background:var(--ritual-cream);border:1px solid var(--ink);border-radius:8px;margin-bottom:.5rem;font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink)}
.ritual-cart-voucher .cart-summary__label{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.ritual-cart-voucher .cart-summary__label i{font-size:1rem}
.ritual-cart-voucher .cart-voucher__type{font-weight:700;text-transform:uppercase;font-size:.75rem;letter-spacing:.03em}
.ritual-cart-voucher .cart-voucher__code{font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;padding:.1rem .5rem;border:1px solid var(--ink);border-radius:999px}
.ritual-cart-voucher .cart-summary__value{display:flex;align-items:center;gap:.75rem;font-weight:400;font-variant-numeric:tabular-nums}
.ritual-cart-voucher .cart-voucher__remove{display:inline-flex;color:var(--ink);opacity:.6;text-decoration:none}
.ritual-cart-voucher .cart-voucher__remove:hover{opacity:1}
.ritual-cart-voucher .cart-voucher__highlight{margin-top:1rem}
@media (max-width:767px){
  .ritual-cart-voucher__columns{
    grid-template-columns:1fr;
  }
}

.payment-options__list{padding:0;list-style:none;display:flex;flex-direction:column;gap:12px}
.payment-option{border:1px solid rgba(41,37,28,.2);border-radius:10px;padding:12px 16px;transition:border-color .15s ease, background .15s ease}
.payment-option:has(.form-check-ritual__input:checked){border-color:var(--brass);background:rgba(175,138,82,.06)}
.payment-option:has(.form-check-ritual__input:hover):not(:has(.form-check-ritual__input:checked)){border-color:rgba(41,37,28,.4)}
/* Opción de pago: dato (el estado elegido ya lo marca el borde --brass). */
.payment-option__label{display:flex;align-items:center;gap:.5rem;width:100%;font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink)}
.payment-options__free,
.payment-options__updated{font-size:1.0625rem;font-weight:400;line-height:1.7;color:var(--ink)}

/* --- Step title: the base theme renders the current step's title as an
   h1.page-title-section, which inherits the site's cursive display font at
   hero size (h1,h2,h3{font-family:Tindoghouse} above) — oversized and
   out of place for a functional "Pago" label. Bring it back to the same
   plain, uppercase micro-header style already used for the checkout table
   headers. --- */
/* Antetítulo del estándar, como "Cupones y tarjetas regalo" y las
   cabeceras de la tabla. El paso no actual se pinta como
   p.page-title-section: mismo tratamiento. */
#checkout-personal-information-step .step__title .page-title-section,
#checkout-payment-step .step__title .page-title-section{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:.72rem;
  font-weight:700;
  line-height:1.4;
  text-transform:uppercase;
  letter-spacing:.12em;
  color:rgba(41,37,28,.6);
  margin-bottom:0;
}
#checkout-personal-information-step .step__title hr,
#checkout-payment-step .step__title hr{
  border-color:rgba(41,37,28,.15);
}

/* --- Terms link: same issue as .breadcrumb a / .ritual-workwithus__privacy
   a above — color alone doesn't read against body copy of the same ink
   tone, needs the underline for the link affordance. --- */
/* Condiciones: texto legal (y 400 en vez del 300 de
   .form-check-ritual__label); su enlace, metadato accionable. */
#checkout-payment-step .js-terms{
  cursor:pointer;
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
#checkout-payment-step .js-terms a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
#checkout-payment-step .js-terms a:hover,
#checkout-payment-step .js-terms a:focus-visible{
  color:var(--brass);
}
/* "Crear una cuenta (opcional)" del checkout de invitado: texto de casilla
   en 400; su pista ("Y ahorra tiempo…", .text-body-tertiary), ayuda de
   formulario. La utilidad fija el color con !important dentro de @layer
   (y un !important en capa gana a uno fuera de ella), así que el 60% se
   ajusta desde la variable que lee. */
#checkout-guest-form .js-password-form__check .form-check-ritual__label{
  font-weight:400;
  color:var(--ink);
}
#checkout-guest-form .js-password-form__check small{
  font-size:.8125rem;
  line-height:1.4;
}
#checkout-guest-form .js-password-form__check .text-body-tertiary{
  --bs-tertiary-color:rgba(41,37,28,.6);
}

#checkout-payment-step .form-check-ritual { margin-bottom: 0; }

.ritual-checkout-empty{
  text-align:center;
  padding:5rem 1rem;
}
.ritual-checkout-empty p{
  font-size:1.25rem;
  font-weight:400;
  line-height:1.5;
  color:var(--ink);
  margin-bottom:1.5rem;
}
@media (max-width:767px){
  .ritual-checkout-empty p{
    font-size:1.125rem;
  }
}
.order-confirmation__actions{margin-top:6rem}

/* Tu cuenta — barra de tabs y dashboard (docs/superpowers/specs/2026-08-26-my-account-redesign-design.md) */
.rb-account-tabs{display:flex;gap:.5rem;border-bottom:1px solid rgba(41,37,28,.15);margin-bottom:2rem;flex-wrap:wrap}
/* Pestañas: navegación, así que enlace de texto del estándar (.8125rem,
   400, .14em, mayúsculas). La pestaña activa la sigue marcando su barra. */
.rb-account-tabs__link{padding:.75rem 1.25rem;color:var(--ink);text-decoration:none;font-weight:400;font-size:.8125rem;line-height:1.4;text-transform:uppercase;letter-spacing:.14em;border-bottom:3px solid transparent}
.rb-account-tabs__link--active{border-bottom-color:var(--ink)}
.rb-account-resumen{display:grid;gap:2rem}
.rb-account-resumen__row{display:grid;gap:2rem;grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.rb-account-resumen__block{background:var(--ritual-cream);border-radius:12px;padding:1.5rem}
/* Titulares de bloque (Pendientes de reservar, Próximas citas, Últimas
   compras, Mis citas): titular de elemento. Antes el h2 de Bootstrap a
   1.5rem. */
.rb-account-resumen__block h2,
.rb-account-reservas__block h2{font-size:1.625rem;font-weight:400;line-height:1.2;color:var(--ink);margin-bottom:1rem}
@media (max-width:767px){
  .rb-account-resumen__block h2,
  .rb-account-reservas__block h2{font-size:1.5rem}
}
.rb-account-resumen__block--full{width:100%}
.rb-account-resumen__list{list-style:none;padding:0;margin:0 0 1rem}
.rb-account-resumen__list li{display:flex;justify-content:space-between;align-items:center;gap:1rem;padding:.5rem 0;border-bottom:1px solid rgba(41,37,28,.1);font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink);font-variant-numeric:tabular-nums}
.rb-account-resumen__list li span{flex:1}
.rb-account-resumen__item-main{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.rb-account-resumen__item-meta{display:flex;flex-direction:column;align-items:flex-end;gap:.15rem;font-size:.85rem;white-space:nowrap}
.rb-account-resumen__code{font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:rgba(41,37,28,.6);font-variant-numeric:tabular-nums}
.rb-account-resumen__empty-inline{margin:0 0 .5rem;font-size:1.0625rem;font-weight:400;line-height:1.7;color:var(--ink)}
.rb-account-resumen__invite{margin:1rem 0 .75rem;font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:rgba(41,37,28,.6)}
.rb-account-resumen__categories{display:flex;flex-wrap:wrap;gap:.5rem}
/* --- "Últimas compras": cada campo en su propia columna (código/servicio/
   precio/fecha) en vez de las 2 líneas apiladas de los otros bloques. --- */
.rb-account-resumen__list--columns li{display:grid;grid-template-columns:5rem 1fr auto auto;gap:1rem;align-items:center;padding:.75rem 0}
.rb-account-resumen__col-code{font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:rgba(41,37,28,.6);font-variant-numeric:tabular-nums}
.rb-account-resumen__col-price{white-space:nowrap;font-weight:400}
/* Fecha de compra: dato secundario de la fila, metadato. */
.rb-account-resumen__col-date{white-space:nowrap;font-size:.8125rem;line-height:1.4;color:rgba(41,37,28,.6)}
.rb-account-resumen__block--full .rb-account-resumen__list{margin-bottom:1.5rem}
/* --- Móvil: el grid de 4 columnas de "Últimas compras" no cabe en el
   ancho disponible. El código pasa a su propia línea encima del servicio
   (mismo patrón que .rb-account-resumen__item-main en "Pendientes de
   reservar"), precio/fecha se envuelven debajo en vez de exigir 4 columnas
   fijas en horizontal. --- */
@media (max-width:767px){
  .rb-account-resumen__list--columns li{display:flex;flex-wrap:wrap;column-gap:1rem;row-gap:.15rem}
  .rb-account-resumen__col-code{flex:0 0 100%;order:0}
  .rb-account-resumen__col-service{flex:1 1 auto;order:1}
  .rb-account-resumen__col-price{order:2}
  .rb-account-resumen__col-date{order:3}
}
.rb-account-compras__table-wrap{overflow-x:auto;background:var(--ritual-cream);border-radius:12px;padding:1.5rem}
.rb-account-compras__table{width:100%;border-collapse:collapse;font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink);font-variant-numeric:tabular-nums}
.rb-account-compras__table th,.rb-account-compras__table td{padding:.75rem 1rem;text-align:left;border-bottom:1px solid rgba(41,37,28,.12);vertical-align:top}
.rb-account-compras__table td{white-space:nowrap}
.rb-account-compras__table th{font-weight:700;text-transform:uppercase;font-size:.72rem;letter-spacing:.12em;color:rgba(41,37,28,.6)}
/* Destinatario del regalo: metadato. El mensaje, con la cursiva de apoyo
   de la marca (Helvetica Cursiva) en vez de la oblicua sintética de
   Helvetica LT Std, que no tiene corte itálico. Estado del envío: estado. */
.rb-account-compras__gift{display:flex;flex-direction:column;gap:.2rem;font-size:.8125rem;line-height:1.4;white-space:normal;max-width:16rem;color:rgba(41,37,28,.6)}
.rb-account-compras__gift-message{font-family:"Helvetica Cursiva","Helvetica LT Std",sans-serif;font-style:italic;font-weight:300}
.rb-account-compras__gift-status{font-weight:700;text-transform:uppercase;font-size:.72rem;letter-spacing:.12em;color:var(--ink)}
.rb-account-compras__pdf{display:inline-flex;color:var(--ink)}
.rb-account-compras__pdf .material-icons{font-size:1.4rem}
/* Tag "Regalo" compartido en Pendientes de reservar (resumen/reservas) y
   Últimas compras (resumen) — la tabla completa de account-compras.tpl ya
   tiene su propia columna "Regalo" y no lo necesita. */
.rb-tag-regalo{display:inline-block;padding:.15rem .55rem;border-radius:999px;background:var(--ink);color:#fff;font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;white-space:nowrap;vertical-align:middle}
.rb-account-reservas{display:grid;gap:2rem}
.rb-account-reservas__block{background:var(--ritual-cream);border-radius:12px;padding:1.5rem}
.rb-account-reservas__list{list-style:none;padding:0;margin:0}
.rb-account-reservas__item{display:flex;justify-content:space-between;align-items:center;gap:1rem;padding:.75rem 0;border-bottom:1px solid rgba(41,37,28,.1);font-size:.9375rem;font-weight:400;line-height:1.4;color:var(--ink);font-variant-numeric:tabular-nums}
/* Combinador directo: el código de "Pendientes de reservar" anida su
   propio span dentro de .rb-account-reservas__item-main y no debe heredar
   este flex:1 (solo el contenedor -main debe crecer, igual que en
   .rb-account-resumen__item-main). */
.rb-account-reservas__item > span{flex:1}
.rb-account-reservas__item-main{display:flex;flex-direction:column;gap:.15rem;min-width:0;flex:1}
.rb-account-reservas__code{font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:rgba(41,37,28,.6);font-variant-numeric:tabular-nums}
/* "Ya no se puede modificar": estado. */
.rb-account-reservas__closed{font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:var(--ink)}
.rb-account-reservas__empty{margin:0;font-size:1.0625rem;font-weight:400;line-height:1.7;color:var(--ink)}
.rb-account-reservas__group-btn-row{display:flex;align-items:center;justify-content:flex-end;gap:.5rem;margin-top:1.5rem}
.rb-account{display:block}
.rb-account__content{margin-top:1rem;margin-bottom:4rem}
.rb-account-datos{max-width:32rem;margin:0 auto}
/* Igual que en el checkout (ver #checkout-personal-information-step
   arriba): los campos de customer-form.tpl los renderiza el core sin
   .input-field__wrap propio — se les da la caja apuntando al .form-control
   directo, excluyendo el input de contraseña anidado con el combinador
   directo. */
.rb-account-datos .mb-3 > .form-control,
.rb-account-datos .mb-3 > .form-select{
  display:block;
  width:100%;
  border:1px solid rgba(41,37,28,.25);
  border-radius:10px;
  background:#fff;
  padding:.55rem .75rem;
  font-weight:300;
  font-size:1rem;
  color:var(--ink);
  box-shadow:none;
  transition:border-color .2s ease, box-shadow .2s ease;
}
.rb-account-datos .mb-3 > .form-control:hover:not(:focus),
.rb-account-datos .mb-3 > .form-select:hover:not(:focus){
  border-color:rgba(41,37,28,.45);
}
.rb-account-datos .mb-3 > .form-control:focus,
.rb-account-datos .mb-3 > .form-select:focus{
  outline:none;
  border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(175,138,82,.15);
}

/* --- Página 404 (y sus variantes 410/producto-no-disponible/categoría-no-
   disponible): hummingbird la deja con el "404" en fuente/negro por defecto
   de Bootstrap y el botón en .btn-primary azul — ninguno de los dos existe
   en la paleta de la marca. errors/404.tpl y errors/410.tpl son la
   plantilla real de PageNotFoundController (body #pagenotfound), pero
   ProductController y CategoryController reutilizan esas mismas plantillas
   cuando el producto/categoría existe pero no está disponible (no
   "not found" object, así que el body conserva su propio id: #product o
   #category) — de ahí que la 404 de un producto se viera sin estilo pese a
   arreglar solo #pagenotfound. Se envuelve en la misma tarjeta crema con
   sombra suave que usan login/cuenta (#authentication .login,
   .rb-account-resumen__block, etc.), el número grande pasa a Tindoghouse
   (ya es la fuente de h1-h6 en todo el sitio) y el CTA reutiliza el
   lenguaje visual de .btn-pill sin poder añadirle la clase porque sale del
   núcleo vía errors/not-found.tpl con .btn.btn-primary fijo. Los estilos de
   texto/botón (.page-content--not-found) se dejan sin acotar por id porque
   ese bloque también aparece embebido dentro del listado de categoría
   ("no hay productos en esta categoría"), que hereda texto y botón y
   añade su propio panel más abajo (#category #products). --- */
#pagenotfound .container--limited-md,
[id^="module-smartblog-"] .container--limited-md,
#product .container--limited-md,
#category .container--limited-md{
  background:var(--ritual-cream);
  border-radius:20px;
  box-shadow:0 10px 40px rgba(41,37,28,.08);
  padding:3.5rem clamp(1.5rem,5vw,4rem) 3rem;
  margin:3rem auto 4rem;
}
#pagenotfound .page-header .display-1,
[id^="module-smartblog-"] .page-header .display-1,
#product .page-header .display-1,
#category .page-header .display-1{
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  color:var(--ink);
  font-size:clamp(5rem,18vw,9rem);
  line-height:1;
  margin-bottom:.5rem;
  /* errors/404.tpl le pone .fw-bold, que es font-weight:700!important
     dentro de @layer y gana a cualquier font-weight de este fichero.
     Tindoghouse solo tiene corte 400, así que el navegador la engordaba
     de forma sintética: se impide la síntesis en vez de pelear el peso. */
  font-synthesis:none;
}
/* Título ("Página no encontrada", h1.h2 a 1.5rem de Bootstrap): el "404"
   hace de cabecera, así que el titular va en el paso de sección. */
.page-content--not-found h1{
  color:var(--ink);
  margin-bottom:1rem;
  font-size:2.5rem;
  font-weight:400;
  line-height:1.2;
}
@media (max-width:767px){
  .page-content--not-found h1{
    font-size:2rem;
  }
}
.page-content--not-found p{
  color:var(--ink);
  opacity:.75;
  margin-bottom:2rem;
}
.page-content--not-found p a{
  color:var(--ink);
}
/* Texto de la 404 (y sus variantes, que van en .container--limited-md) y
   de la búsqueda sin resultados: cuerpo a opacidad plena, enlace
   "contáctanos" subrayado. No se toca la regla base de arriba porque
   .page-content--not-found también pinta el estado "categoría sin
   productos" de la página de categoría, ya validada. */
#pagenotfound .page-content--not-found p,
[id^="module-smartblog-"] .page-content--not-found p,
.container--limited-md .page-content--not-found p,
#search .page-content--not-found p{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  opacity:1;
}
#pagenotfound .page-content--not-found p a,
[id^="module-smartblog-"] .page-content--not-found p a,
.container--limited-md .page-content--not-found p a,
#search .page-content--not-found p a{
  text-decoration:underline;
  text-underline-offset:2px;
}
#pagenotfound .page-content--not-found p a:hover,
[id^="module-smartblog-"] .page-content--not-found p a:hover,
.container--limited-md .page-content--not-found p a:hover,
#search .page-content--not-found p a:hover{
  text-decoration:none;
}
@media (max-width:767px){
  #pagenotfound .page-content--not-found p,
  .container--limited-md .page-content--not-found p,
  #search .page-content--not-found p{
    font-size:1rem;
  }
}
.page-content--not-found .btn.btn-primary{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.5rem;
  border:none;
  border-radius:999px;
  background:var(--ink);
  color:#fff;
  font-weight:700;
  font-size:.85rem;
  text-transform:uppercase;
  letter-spacing:.04em;
  padding:.75rem 1.75rem;
  text-decoration:none!important;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
  transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease;
}
.page-content--not-found .btn.btn-primary:hover{
  color:#fff;
  transform:translateY(-2px);
  box-shadow:0 10px 22px rgba(0,0,0,.2);
}
@media (prefers-reduced-motion: reduce){
  .page-content--not-found .btn.btn-primary{transition:none}
  .page-content--not-found .btn.btn-primary:hover{transform:none}
}
@media (max-width:575.98px){
  #pagenotfound .container--limited-md,
  #product .container--limited-md,
  #category .container--limited-md{
    padding:2.5rem 1.25rem 2rem;
    border-radius:16px;
    margin:1.5rem auto 3rem;
  }
}
/* En esta variante (producto/categoría no disponible), el error real
   (Product/CategoryController rellenando $this->errors[]) se pinta en
   #notifications, que va suelto justo debajo de la cabecera — sin el
   padding-top del .wrapper que hummingbird solo le da a #pagenotfound
   (ver _page-not-found.scss). Se separa el aviso en sí en vez de tocar
   #notifications .container en general para no mover los avisos de otras
   páginas (carrito, login, checkout) que ya tienen su propio espaciado. */
#pagenotfound #notifications .alert,
[id^="module-smartblog-"] #notifications .alert,
#product #notifications .alert,
#category #notifications .alert{
  margin-top:2rem;
}
/* --- Categoría sin servicios: product-list.tpl de hummingbird pinta
   errors/not-found.tpl dentro de #products con un p.h3 como título (no es
   un h3 real, así que no hereda Tindoghouse y salía en Helvetica de
   Bootstrap), el texto y el botón "Volver a Página Principal", todo
   alineado a la izquierda y sin contenedor. Se acota a #category #products
   para no tocar la 404 ni la búsqueda sin resultados (#search), que usan
   el mismo bloque con sus propias reglas de arriba. Panel crema plano
   (--ritual-cream, radio --radius-md, sin sombra: es un aviso, no una
   card), filete --brass de divisor encima del título, titular Tindoghouse
   en el paso h2 (--text-xl) y cuerpo en --text-md. --- */
#category #products .page-content--not-found{
  max-width:40rem;
  margin:3rem auto 4rem;
  padding:3.5rem clamp(1.5rem,5vw,3rem) 3rem;
  background:var(--ritual-cream);
  border-radius:16px;
  text-align:center;
}
#category #products .page-content--not-found::before{
  content:"";
  display:block;
  width:3rem;
  height:1px;
  margin:0 auto 1.5rem;
  background:var(--brass);
}
#category #products .page-content--not-found p.h3{
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:2rem;
  line-height:1.2;
  color:var(--ink);
  opacity:1;
  margin:0 0 1rem;
  font-synthesis:none;
}
#category #products .page-content--not-found p:not(.h3){
  max-width:30rem;
  margin:0 auto 2rem;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
  opacity:.75;
}
#category #products .page-content--not-found .btn.btn-primary .material-icons{
  font-size:1.125rem;
  line-height:1;
}
@media (max-width:575.98px){
  #category #products .page-content--not-found{
    margin:2rem auto 3rem;
    padding:2.5rem 1.25rem 2rem;
  }
  #category #products .page-content--not-found p.h3{
    font-size:1.5rem;
  }
  #category #products .page-content--not-found p:not(.h3){
    font-size:1rem;
  }
}
/* "Ver todas": enlace de texto del estándar (mismo filete --brass que
   .ritual-for-you__cta). */
.rb-account-resumen__more{position:relative;display:inline-block;margin-top:.5rem;padding-bottom:.6rem;font-weight:400;font-size:.8125rem;line-height:1.4;text-transform:uppercase;letter-spacing:.14em;color:var(--ink);text-decoration:none}
.rb-account-resumen__more:hover,
.rb-account-resumen__more:focus-visible{color:var(--ink)}
.rb-account-resumen__more::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--brass);transform:scaleX(.3);transform-origin:left center;transition:transform var(--motion-hover) var(--motion-ease)}
.rb-account-resumen__more:hover::after,
.rb-account-resumen__more:focus-visible::after{transform:scaleX(1)}
@media (prefers-reduced-motion: reduce){
  .rb-account-resumen__more::after{transition:none}
}
.rb-account-resumen__empty{margin:0;text-align:center}
.rb-account-compras__empty{margin:0;text-align:center;font-size:1.0625rem;font-weight:400;line-height:1.7;color:var(--ink)}
.rb-account-compras__invite{margin:1rem 0 .75rem;font-size:.72rem;font-weight:700;line-height:1.4;text-transform:uppercase;letter-spacing:.12em;color:rgba(41,37,28,.6);text-align:center}
.rb-account-compras__categories{display:flex;flex-wrap:wrap;justify-content:center;gap:.5rem}
.rb-group-reservation__warning{font-size:.85rem;color:rgba(41,37,28,.6)}
.product-pack__name{color:var(--ink)}

/* Red de seguridad: el aviso y el panel de configuración nacen ocultos
   aunque falte el CSS que genera el módulo (lgcookieslaw_*.css, propio de
   cada instalación y fuera de git). Sin él, el formulario salía suelto en
   el pie. El módulo los abre poniendo el display en línea (y fancybox), que
   gana a esta regla. */
[id^="lgcookieslaw_banner_"],
[id^="lgcookieslaw_modal_"]{display:none}

/* ==== Aviso de cookies (lgcookieslaw) ====
   El módulo trae de fábrica botones cuadrados en Noto Sans y verde/gris
   genérico, y el panel de admin del módulo (que genera
   lgcookieslaw_1_1.css con !important) solo llegó a recolorear
   accept-button (blanco/ink) y reject-button (ink/blanco) del banner y
   del modal — cancel-button y partial-accept-button quedaron en el
   gris/verde de fábrica, la insignia "Technical"/fecha de consentimiento
   quedó en blanco-sobre-blanco (invisible) y el slider sigue con el
   fondo verde bajo una sombra blanca que el admin sí cambió. Se homologa
   forma/tipografía/hover al mismo lenguaje que .btn-pill y el modal de
   giftflow (border-radius 999px en botones, 16px en el modal, Helvetica
   LT Std, hover ink-fill) sin tocar los colores que ya eligió el admin
   para accept/reject. */
.lgcookieslaw-modal{
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  border-radius:16px;
  overflow:hidden;
}
.tooltipster-base{
  font-family:"Helvetica LT Std",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
}
.lgcookieslaw-modal-header{
  border-top-color:var(--brass) !important;
}
.lgcookieslaw-button-container .lgcookieslaw-reject-button,
.lgcookieslaw-button-container .lgcookieslaw-accept-button,
.lgcookieslaw-modal-footer .lgcookieslaw-button{
  border-radius:999px;
  font-weight:700;
  letter-spacing:.04em;
  box-shadow:0 4px 12px rgba(0,0,0,.15);
  transition:transform .25s cubic-bezier(.2,.8,.2,1), box-shadow .25s ease;
}
.lgcookieslaw-button-container .lgcookieslaw-reject-button:hover,
.lgcookieslaw-button-container .lgcookieslaw-accept-button:hover,
.lgcookieslaw-modal-footer .lgcookieslaw-button:hover{
  transform:translateY(-2px);
  box-shadow:0 10px 22px rgba(0,0,0,.2);
}
.lgcookieslaw-modal-footer .lgcookieslaw-button{
  text-transform:uppercase;
  font-size:.8rem;
  padding:.5rem 1.25rem;
}
.lgcookieslaw-modal .lgcookieslaw-cancel-button,
.lgcookieslaw-modal .lgcookieslaw-partial-accept-button{
  background:transparent;
  color:var(--ink);
  border:1px solid var(--ink);
  box-shadow:none;
}
.lgcookieslaw-modal .lgcookieslaw-cancel-button:hover,
.lgcookieslaw-modal .lgcookieslaw-partial-accept-button:hover{
  background:var(--ink);
  color:#fff;
}
.lgcookieslaw-slider.lgcookieslaw-slider-checked{
  background-color:var(--brass) !important;
}
.lgcookieslaw-modal .lgcookieslaw-badge{
  background-color:var(--brass) !important;
  color:#fff !important;
  border-color:var(--brass) !important;
}
@media (prefers-reduced-motion: reduce){
  .lgcookieslaw-button-container .lgcookieslaw-reject-button,
  .lgcookieslaw-button-container .lgcookieslaw-accept-button,
  .lgcookieslaw-modal-footer .lgcookieslaw-button{transition:none}
  .lgcookieslaw-button-container .lgcookieslaw-reject-button:hover,
  .lgcookieslaw-button-container .lgcookieslaw-accept-button:hover,
  .lgcookieslaw-modal-footer .lgcookieslaw-button:hover{transform:none}
}
/* Modal "Preferencias de cookies": mismo lenguaje que los modales del
   sitio. Cabecera con el titular en --ink (sin mayúsculas ni el verde y la
   sombra de fábrica), finalidades como filas separadas por filete en vez de
   cajas grises, el desplegable "Descripción y cookies" como enlace discreto
   con su flecha, la tabla de cookies en metadato y el pie sin sombra. */
.lgcookieslaw-modal .lgcookieslaw-modal-header{padding:1.5rem 1.75rem 1.25rem;border-top-width:3px;border-bottom:1px solid rgba(41,37,28,.12);box-shadow:none}
.lgcookieslaw-modal .lgcookieslaw-modal-header .lgcookieslaw-modal-header-title{font-size:1.5rem;font-weight:400;line-height:1.25;text-transform:none;letter-spacing:0;color:var(--ink)}
.lgcookieslaw-modal .lgcookieslaw-modal-body{padding:.5rem 1.75rem}
.lgcookieslaw-modal .lgcookieslaw-section{align-items:center;justify-content:space-between;margin:0;padding:1.25rem 0;border:0;border-bottom:1px solid rgba(41,37,28,.1);border-radius:0;background:none;box-shadow:none;-webkit-box-shadow:none}
.lgcookieslaw-modal .lgcookieslaw-section:last-child{border-bottom:0}
.lgcookieslaw-modal .lgcookieslaw-section-name{display:flex;align-items:center;gap:.5rem;padding:0;font-size:1.0625rem;font-weight:700;color:var(--ink)}
.lgcookieslaw-modal .lgcookieslaw-badge{padding:.15rem .6rem;border-radius:999px;font-size:.68rem;letter-spacing:.08em;text-transform:uppercase}
.lgcookieslaw-modal .lgcookieslaw-section-purpose{margin-top:.5rem}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-button{display:inline-flex;align-items:center;gap:.4rem;margin:0;padding:.25rem 0;border:0;background:none;color:rgba(41,37,28,.7);text-decoration:none}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-button .lgcookieslaw-section-purpose-button-title{font-size:.8125rem;text-decoration:underline;text-underline-offset:2px}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-button:hover,
.lgcookieslaw-modal .lgcookieslaw-section-purpose-button:focus-visible{background:none;color:var(--brass)}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-button::after{position:static;width:.75rem;height:.75rem;background-size:contain!important;opacity:.7}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-description{padding:.75rem 0 0;font-size:.875rem;line-height:1.6;color:rgba(41,37,28,.85)}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-cookies{margin-top:.75rem;padding:.75rem 1rem;border-radius:12px;background:color-mix(in srgb, var(--ritual-cream) 70%, #fff)}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-cookies-table{margin:0;font-size:.75rem}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-cookies-table > thead > tr > th{padding:.35rem .5rem;border-bottom:1px solid rgba(41,37,28,.15);font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:rgba(41,37,28,.6);background:none}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-cookies-table tbody > tr > td{padding:.4rem .5rem;border-top:1px solid rgba(41,37,28,.08);color:var(--ink);background:none;overflow-wrap:anywhere}
.lgcookieslaw-modal .lgcookieslaw-section-purpose-content-cookies-table a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}
.lgcookieslaw-modal .lgcookieslaw-modal-footer{gap:.75rem;padding:1.25rem 1.75rem;border-top:1px solid rgba(41,37,28,.12);box-shadow:none}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-modal-footer-right{gap:.5rem}
/* Fancybox (con el que el módulo abre el modal) lo envuelve en su propia
   caja: 15px de relleno en línea, fondo gris y sombra. Fuera: la caja es el
   propio modal, con su radio y la sombra de modal del sistema. */
.lgcookieslaw-fancybox .fancybox-skin{padding:0!important;border-radius:16px;background:transparent;box-shadow:0 16px 48px rgba(41,37,28,.18)}
.lgcookieslaw-fancybox .fancybox-outer,
.lgcookieslaw-fancybox .fancybox-inner{border-radius:16px}
/* Botones del pie con jerarquía propia. Los colores del admin del módulo
   (lgcookieslaw_*.css, con !important) están pensados para el aviso, que es
   oscuro: dentro del modal, blanco, "Aceptar todo" quedaba como un botón
   blanco sin borde sobre blanco, que no se leía como botón. Aquí: "Aceptar todo" sólido --ink, "Aceptar selección" y
   "Rechazar todo" en contorno, "Cancelar" como enlace. De ahí el
   !important y la especificidad (pie + botón), por encima de los del admin. */
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-button{height:2.75rem;padding:0 1.25rem!important;border:1px solid var(--ink)!important;font-family:"Helvetica LT Std",sans-serif}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-accept-button{background:var(--ink)!important;color:#fff!important}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-partial-accept-button,
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-reject-button{background:#fff!important;color:var(--ink)!important;box-shadow:none}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-accept-button:hover{background:#000!important}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-partial-accept-button:hover,
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-reject-button:hover{background:var(--ink)!important;color:#fff!important}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-cancel-button{height:auto;padding:0!important;border:0!important;background:none!important;box-shadow:none;color:rgba(41,37,28,.7)!important;text-transform:none;letter-spacing:0;font-weight:400;font-size:.875rem;text-decoration:underline;text-underline-offset:3px}
.lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-cancel-button:hover{transform:none;box-shadow:none;background:none!important;color:var(--brass)!important}
/* Etiqueta "Técnica" y fecha del consentimiento: dorado suave con texto
   --brass, más ligero que el dorado sólido de la regla general de arriba. */
.lgcookieslaw-modal .lgcookieslaw-section .lgcookieslaw-badge,
.lgcookieslaw-modal .lgcookieslaw-modal-header .lgcookieslaw-badge{background:color-mix(in srgb, var(--brass) 14%, #fff)!important;border:0!important;color:var(--brass)!important}
@media (max-width:575px){
  .lgcookieslaw-modal .lgcookieslaw-modal-header,
  .lgcookieslaw-modal .lgcookieslaw-modal-footer{padding-left:1.25rem;padding-right:1.25rem}
  .lgcookieslaw-modal .lgcookieslaw-modal-body{padding:.25rem 1.25rem}
  .lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-modal-footer-left,
  .lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-modal-footer-right{width:100%;flex-wrap:wrap}
  .lgcookieslaw-modal .lgcookieslaw-modal-footer .lgcookieslaw-button{flex:1 1 auto}
}
/* En móvil se quita el botón flotante de cookies. El JS del módulo
   (showFixedButton) le pone display:flex en línea, de ahí el !important. */
@media (max-width: 767.98px){
  #lgcookieslaw_fixed_button{display:none !important}
}

/* ============================================================
   Formularios — sistema compartido de controles
   Sustituye a los estilos ad-hoc de input/checkbox/radio dispersos
   por el sitio (subrayado, píldora, azul de Bootstrap sin rebrandear...)
   por un único sistema: caja de 10px, foco/marcado en dorado (--brass).
   ============================================================ */

/* ---- Input / Select / Textarea — .input-field ---- */
.input-field { display: block; margin-bottom: 1.5rem; }

.input-field__label {
  display: block;
  margin-bottom: 4px;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink);
}
.input-field__label.required::after { content: ' *'; color: var(--color-error); }

.input-field__wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 1px solid rgba(41, 37, 28, .25);
  border-radius: 10px;
  background: #fff;
  padding: .55rem .75rem;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.input-field__wrap:hover:not(:focus-within) { border-color: rgba(41, 37, 28, .45); }
.input-field__wrap:focus-within {
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(175, 138, 82, .15);
}
.input-field__wrap:has(.input-field__control:disabled) {
  background: rgba(41, 37, 28, .03);
  border-color: rgba(41, 37, 28, .12);
}

.input-field__icon { flex: none; font-size: 20px; color: var(--ink); opacity: .6; }

.input-field__control {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  border: none;
  background: transparent;
  padding: 0;
  font-weight: 300;
  font-size: 1rem;
  color: var(--ink);
  box-shadow: none;
}
.input-field__control:focus { outline: none; }
.input-field__control::placeholder { color: rgba(41, 37, 28, .4); }
.input-field__control:disabled { color: rgba(41, 37, 28, .35); cursor: not-allowed; }

.input-field__wrap--multiline { align-items: flex-start; }
.input-field__wrap--multiline .input-field__control { resize: vertical; min-height: 5rem; }

/* Select: se quita la flecha nativa del navegador y se dibuja una propia */
select.input-field__control {
  appearance: none;
  padding-right: 1.25rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2329251c' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right center;
  background-size: .65rem;
  cursor: pointer;
}

.input-field.has-error .input-field__wrap { border-color: var(--color-error); }
.input-field.has-success .input-field__wrap { border-color: var(--color-success); }
.input-field__message { display: block; margin-top: .35rem; font-size: .8125rem; font-weight: 400; line-height: 1.4; }
.input-field.has-error .input-field__message { color: var(--color-error); }
.input-field.has-success .input-field__message { color: var(--color-success); }

.input-field--sm .input-field__wrap { padding: .4rem .5rem; }
.input-field--sm .input-field__control { font-size: .9rem; }

/* Password: el propio input-group.password-field ya envuelve input+botón
   de mostrar/ocultar (core, _partials/form-fields.tpl) — se le da la caja
   a ese contenedor. */
.input-group.password-field {
  display: flex;
  align-items: center;
  border: 1px solid rgba(41, 37, 28, .25);
  border-radius: 10px;
  background: #fff;
  padding: 0 .75rem;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.input-group.password-field:focus-within {
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(175, 138, 82, .15);
}
.input-group.password-field .form-control {
  border: none;
  background: transparent;
  padding: .55rem 0;
  box-shadow: none;
}
.input-group.password-field .btn {
  border: none;
  background: transparent;
  color: var(--ink);
  opacity: .7;
  border-radius: 50%;
  padding: .35rem;
  transition: background .15s ease, opacity .15s ease;
}
.input-group.password-field .btn:hover { opacity: 1; background: rgba(41, 37, 28, .08); }

/* ---- Checkbox / Radio — .form-check-ritual (sustituye a .form-check-input
   de Bootstrap sin rebrandear, azul por defecto) ---- */
.form-check-ritual {
  display: flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
  margin-bottom: 16px;
}
.form-check-ritual:last-child { margin-bottom: 0; }

.form-check-ritual__input {
  appearance: none;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  margin: .15rem 0 0;
  border: 1.5px solid var(--ink);
  border-radius: 6px;
  background: transparent;
  position: relative;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
}
.form-check-ritual__input[type="radio"] { border-radius: 50%; }
.form-check-ritual__input:hover:not(:disabled):not(:checked) { border-color: var(--brass); }
.form-check-ritual__input:checked { background: var(--brass); border-color: var(--brass); }
.form-check-ritual__input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 5px; top: 1px;
  width: 5px; height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.form-check-ritual__input[type="radio"]:checked::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: #fff;
}
.form-check-ritual__input:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.form-check-ritual__input:disabled { border-color: rgba(41, 37, 28, .25); cursor: not-allowed; }
.form-check-ritual__input:disabled:checked { background: rgba(41, 37, 28, .25); border-color: rgba(41, 37, 28, .25); }
.form-check-ritual.has-error .form-check-ritual__input { border-color: var(--color-error); }
.form-check-ritual__label { font-weight: 300; color: var(--ink); line-height: 1.2; }

/* ---- Card de formulario — .form-card (Login, Checkout datos/pago, Mi cuenta) ---- */
.form-card {
  max-width: 32rem;
  margin: 0 auto;
  /* La página/sección detrás (Login, checkout, Mi cuenta) es blanca sin
     fondo propio — la card necesita su propio tono para no perderse
     contra ella. Mismo crema que ya usan las cards de Registro/Recuperar
     contraseña (fuera de este sistema, pero mismo lenguaje de "card sobre
     página blanca" ya validado en el sitio). */
  background: var(--ritual-cream);
  border-radius: 16px;
  border-top: 3px solid var(--brass);
  box-shadow: 0 2px 8px rgba(41, 37, 28, .08);
  padding: 2rem 1.5rem;
}
.form-card .form-group,
.form-card .mb-3 { margin-bottom: 2rem; }
.form-card .buttons-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 12px;
}
.form-card .buttons-wrapper--split { justify-content: space-between; }
.form-card .buttons-wrapper--end { justify-content: flex-end; }

/* Enlaces secundarios de las cards ("¿Has olvidado tu contraseña?",
   "Usar contraseña", "¿Prefieres iniciar sesión sin contraseña?", "Iniciar
   sesión" del checkout): metadato accionable del estándar (.8125rem,
   line-height 1.4, 400, --ink al 60%, subrayado permanente, --brass al
   hover). Antes heredaban el 1rem de .btn y pasaban a #000 al hover. */
.form-card .btn-link,
.form-card .btn-basic{
  color: rgba(41, 37, 28, .6);
  font-size: .8125rem;
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 2px;
  font-weight: 400;
  padding: 0;
  border: none;
  background: transparent;
  transition: color var(--motion-hover) var(--motion-ease);
}
.form-card .btn-link:hover,
.form-card .btn-basic:hover,
.form-card .btn-link:focus-visible,
.form-card .btn-basic:focus-visible{ color: var(--brass); }

/* ==== Estándar tipográfico — páginas transaccionales y de contenido ====
   Reglas que no tenían dónde vivir en las secciones propias de cada página
   (ver "Extensiones del estándar (páginas transaccionales y de
   contenido)" para los tipos). Solo tipografía: tamaños, pesos,
   interlineados, color de texto y el ritmo entre párrafos/titulares. */

/* --- Titular de página interior en las páginas sin cabecera propia ---
   hummingbird pinta aquí h1.page-title-section a clamp(1.5rem, …, 2rem)
   (CMS, búsqueda, login/registro/contraseña, Mi cuenta, confirmación de
   pedido, alta de newsletter). Ninguna de las páginas ya validadas usa esta
   clase: tienen su propio h1. El paso de checkout (también
   .page-title-section) lo sobrescribe su propia regla por id. */
h1.page-title-section{
  font-family:"Tindoghouse",cursive;
  font-size:3.5rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
@media (max-width:767px){
  h1.page-title-section{
    font-size:2.25rem;
  }
}

/* --- Confirmación de pedido ---
   El h1 y el texto del email van dentro de .alert-success y heredaban su
   verde (#0a3420): pasan a --ink y a cuerpo. La caja no se toca. */
#order-confirmation .alert-success .page-title-section{
  color:var(--ink);
}
#order-confirmation .alert-success p{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
/* "Detalles de la compra" (h2.h2, 1.5rem de Bootstrap): titular de sección. */
.order-confirmation__details h2{
  font-size:2.5rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
/* Texto que añade el módulo de pago en displayOrderConfirmation (p sueltos
   bajo #center-column): cuerpo. */
#order-confirmation #center-column > p{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
/* Aviso de conducta tras el resumen de la compra, antes de los botones:
   mismo recurso de nota destacada que .product-detail__chain (filete
   --brass a la izquierda y lavado del mismo tono) con el texto en el paso
   de "texto destacado". */
.order-confirmation__notice{
  margin:0;
  padding:1.25rem 1.5rem;
  border-left:2px solid var(--brass);
  background:color-mix(in srgb, var(--brass) 10%, transparent);
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.125rem;
  font-weight:400;
  line-height:1.6;
  color:var(--ink);
}
/* Los botones traen 6rem de margin-top (.order-confirmation__actions),
   pensados para separarlos de la tabla; tras el aviso sobran. */
.order-confirmation__notice + .order-confirmation__actions{
  margin-top:2rem;
}
/* "Crea tu cuenta" para invitados (plantilla de hummingbird): titular de
   elemento y cuerpo. */
.order-confirmation__account-transformation h3{
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
.order-confirmation__account-transformation .rich-text{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
@media (max-width:767px){
  .order-confirmation__details h2{
    font-size:2rem;
  }
  .order-confirmation__account-transformation h3{
    font-size:1.5rem;
  }
  .order-confirmation__notice{
    padding:1rem 1.25rem;
    font-size:1rem;
  }
  #order-confirmation .alert-success p,
  #order-confirmation #center-column > p,
  .order-confirmation__account-transformation .rich-text{
    font-size:1rem;
  }
}

/* --- Modales de checkout, cuenta y confirmación ---
   Título en el paso de titular de elemento (el .modal-title genérico se
   queda en 2rem para el resto del sitio) y texto en cuerpo.
   La lista incluye TODOS los modales de esta familia: el gestor de citas,
   el aviso de hora ocupada, la cantidad múltiple y el aviso de la ficha se
   quedaban fuera y heredaban el titular genérico de 2rem, que en un diálogo
   estrecho se leía como de otro sitio. */
#cart-reservation-modal .modal-title,
#cart-group-reservation-modal .modal-title,
#cart-group-confirm-modal .modal-title,
#cart-group-manager-modal .modal-title,
#cart-remove-confirm-modal .modal-title,
#cart-payment-gate-modal .modal-title,
#cart-chain-occupied-modal .modal-title,
#multi-quantity-modal .modal-title,
#product-chain-invite-modal .modal-title,
#order-group-reservation-modal .modal-title,
#order-group-confirm-modal .modal-title,
#logout-confirm-modal .modal-title{
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
/* Cuerpo del modal: paso de texto cómodo para los párrafos SIN clase propia
   (una pregunta, un aviso: leerlos es todo lo que hay que hacer con ellos).
   El `:not([class*="rb-"])` es el arreglo de raíz de la revisión de
   usabilidad: esta regla, al no excluir nada, igualaba a 1.0625rem/1.7
   TODOS los párrafos de estos modales —entradilla, instrucción, nota de
   aviso, texto de estado vacío—, que es exactamente por lo que se leían
   como un muro de texto sin jerarquía: las clases que sí definen esa
   jerarquía (.rb-chain__lead, .rb-chain__prompt, .rb-chain__rewrite-note,
   .rb-chain__empty-*, .rb-multi-quantity__intro…) perdían siempre por
   especificidad. Ahora cada una manda en lo suyo. */
#cart-reservation-modal .modal-body p:not([class*="rb-"]),
#cart-group-reservation-modal .modal-body p:not([class*="rb-"]),
#cart-group-confirm-modal .modal-body p:not([class*="rb-"]),
#cart-group-manager-modal .modal-body p:not([class*="rb-"]),
#cart-remove-confirm-modal .modal-body p:not([class*="rb-"]),
#cart-payment-gate-modal .modal-body p:not([class*="rb-"]),
#cart-chain-occupied-modal .modal-body p:not([class*="rb-"]),
#multi-quantity-modal .modal-body p:not([class*="rb-"]),
#product-chain-invite-modal .modal-body p:not([class*="rb-"]),
#order-group-reservation-modal .modal-body p:not([class*="rb-"]),
#order-group-confirm-modal .modal-body p:not([class*="rb-"]),
#logout-confirm-modal .modal-body p:not([class*="rb-"]){
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
/* Error al guardar la reserva: mensaje de validación. */
#cart-reservation-modal .modal-body p.js-cart-reservation-modal-error,
#cart-group-reservation-modal .modal-body p.js-cart-group-modal-error,
#cart-group-manager-modal .modal-body p.js-cart-group-manager-error,
#order-group-reservation-modal .modal-body p.js-order-group-modal-error{
  font-size:.8125rem;
  line-height:1.4;
  color:var(--color-error);
}
@media (max-width:767px){
  #cart-reservation-modal .modal-title,
  #cart-group-reservation-modal .modal-title,
  #cart-group-confirm-modal .modal-title,
  #cart-group-manager-modal .modal-title,
  #cart-remove-confirm-modal .modal-title,
  #cart-payment-gate-modal .modal-title,
  #cart-chain-occupied-modal .modal-title,
  #multi-quantity-modal .modal-title,
  #product-chain-invite-modal .modal-title,
  #order-group-reservation-modal .modal-title,
  #order-group-confirm-modal .modal-title,
  #logout-confirm-modal .modal-title{
    font-size:1.5rem;
  }
  #cart-reservation-modal .modal-body p:not([class*="rb-"]),
  #cart-group-reservation-modal .modal-body p:not([class*="rb-"]),
  #cart-group-confirm-modal .modal-body p:not([class*="rb-"]),
  #cart-group-manager-modal .modal-body p:not([class*="rb-"]),
  #cart-remove-confirm-modal .modal-body p:not([class*="rb-"]),
  #cart-payment-gate-modal .modal-body p:not([class*="rb-"]),
  #cart-chain-occupied-modal .modal-body p:not([class*="rb-"]),
  #multi-quantity-modal .modal-body p:not([class*="rb-"]),
  #product-chain-invite-modal .modal-body p:not([class*="rb-"]),
  #order-group-reservation-modal .modal-body p:not([class*="rb-"]),
  #order-group-confirm-modal .modal-body p:not([class*="rb-"]){
    font-size:1rem;
  }
}

/* --- Mi cuenta: textos de estado vacío en cuerpo, 1rem en móvil --- */
@media (max-width:767px){
  .rb-account-resumen__empty-inline,
  .rb-account-reservas__empty,
  .rb-account-compras__empty{
    font-size:1rem;
  }
}

/* --- Contenido legal largo: páginas CMS y la política de privacidad que
   "Trabaja con nosotros" y el formulario de comentarios del blog abren en
   un modal ---
   El contenido viene del editor del BO: h2, h3, p, strong, ul/ol, a, img
   y <br>, sin estilos inline. Mismo tratamiento que la descripción de la
   ficha (.product-detail__description-body), salvo los h2, que aquí son
   los apartados del documento y van en titular de elemento. Las páginas
   CMS no llevan h2/h3 sino <p class="ritual-legal-title"> y
   <p class="ritual-legal-subtitle">, con el mismo aspecto pero sin ser
   encabezados. Los <p> vacíos que trae el contenido no se ocultan: son
   parte de la composición pendiente de revisar. */
/* Fuera de esos tres contextos (modal de newsletter, que custom.js cuelga
   de <body>; modal de condiciones del checkout, que inyecta CMS 4) no hay
   reglas propias: el aspecto es el de un h2/h3 suelto (el de hummingbird
   con la fuente y el peso de la regla general de h1-h6). */
.ritual-legal-title,
.ritual-legal-subtitle{
  margin-top:0;
  margin-bottom:1rem;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  line-height:1.2;
  color:var(--bs-heading-color);
}
.ritual-legal-title{
  font-size:calc(var(--bs-body-font-size)*1.5);
}
.ritual-legal-subtitle{
  font-size:calc(var(--bs-body-font-size)*1.25);
}
.page-content--cms,
#workwithus-privacy-modal .modal-body,
#blog-privacy-modal .modal-body{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
.page-content--cms p,
#workwithus-privacy-modal .modal-body p,
#blog-privacy-modal .modal-body p{
  margin:0 0 1.5rem;
}
.page-content--cms h2,
.page-content--cms .ritual-legal-title,
#workwithus-privacy-modal .modal-body h2,
#workwithus-privacy-modal .modal-body .ritual-legal-title,
#blog-privacy-modal .modal-body h2,
#blog-privacy-modal .modal-body .ritual-legal-title{
  margin:3rem 0 1rem;
  font-family:"Tindoghouse",cursive;
  font-size:1.625rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
.page-content--cms h3,
.page-content--cms .ritual-legal-subtitle,
#workwithus-privacy-modal .modal-body h3,
#workwithus-privacy-modal .modal-body .ritual-legal-subtitle,
#blog-privacy-modal .modal-body h3,
#blog-privacy-modal .modal-body .ritual-legal-subtitle{
  margin:2rem 0 .75rem;
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1.25rem;
  font-weight:700;
  line-height:1.5;
  color:var(--ink);
}
.page-content--cms > :first-child,
#workwithus-privacy-modal .modal-body > :first-child,
#blog-privacy-modal .modal-body > :first-child{
  margin-top:0;
}
.page-content--cms strong,
.page-content--cms b,
#workwithus-privacy-modal .modal-body strong,
#blog-privacy-modal .modal-body strong,
#workwithus-privacy-modal .modal-body b,
#blog-privacy-modal .modal-body b{
  font-weight:700;
  color:var(--ink);
}
.page-content--cms ul,
.page-content--cms ol,
#workwithus-privacy-modal .modal-body ul,
#blog-privacy-modal .modal-body ul,
#workwithus-privacy-modal .modal-body ol,
#blog-privacy-modal .modal-body ol{
  margin:0 0 1.5rem;
  padding-left:1.25rem;
}
.page-content--cms li,
#workwithus-privacy-modal .modal-body li,
#blog-privacy-modal .modal-body li{
  margin-bottom:.35rem;
}
.page-content--cms a,
#workwithus-privacy-modal .modal-body a,
#blog-privacy-modal .modal-body a{
  color:var(--ink);
  text-decoration:underline;
  text-underline-offset:2px;
}
.page-content--cms a:hover,
#workwithus-privacy-modal .modal-body a:hover,
#blog-privacy-modal .modal-body a:hover{
  text-decoration:none;
}
@media (max-width:767px){
  .page-content--cms,
  #workwithus-privacy-modal .modal-body,
  #blog-privacy-modal .modal-body{
    font-size:1rem;
  }
  .page-content--cms h2,
  .page-content--cms .ritual-legal-title,
  #workwithus-privacy-modal .modal-body h2,
  #workwithus-privacy-modal .modal-body .ritual-legal-title,
  #blog-privacy-modal .modal-body h2,
  #blog-privacy-modal .modal-body .ritual-legal-title{
    margin-top:2.5rem;
    font-size:1.5rem;
  }
  .page-content--cms h3,
  .page-content--cms .ritual-legal-subtitle,
  #workwithus-privacy-modal .modal-body h3,
  #workwithus-privacy-modal .modal-body .ritual-legal-subtitle,
  #blog-privacy-modal .modal-body h3,
  #blog-privacy-modal .modal-body .ritual-legal-subtitle{
    font-size:1.125rem;
  }
}

/* --- Páginas sencillas del core/módulos sobre page.tpl (alta de
   newsletter, borrado de cookies): su texto suelto en cuerpo. --- */
/* Su h1 es un <h1> suelto (no .page-title-section): titular de página. */
#module-ps_emailsubscription-subscription .page-content h1{
  font-size:3.5rem;
  font-weight:400;
  line-height:1.2;
  color:var(--ink);
}
#module-ps_emailsubscription-subscription .page-content p,
#module-ps_emailsubscription-verification .page-content,
#module-lgcookieslaw-disallow .disallow-controller-content p{
  font-size:1.0625rem;
  font-weight:400;
  line-height:1.7;
  color:var(--ink);
}
@media (max-width:767px){
  #module-ps_emailsubscription-subscription .page-content h1{
    font-size:2.25rem;
  }
  #module-ps_emailsubscription-subscription .page-content p,
  #module-ps_emailsubscription-verification .page-content,
  #module-lgcookieslaw-disallow .disallow-controller-content p{
    font-size:1rem;
  }
}

/* ==== Categoría raíz ("Inicio") — índice plegable de todo el catálogo ====
   Solo se aplica a esa página: el marcado que lleva estas clases lo pinta
   catalog/_partials/category-root-header.tpl y
   catalog/_partials/category-root-accordions.tpl, que únicamente se incluyen
   cuando la categoría es PS_HOME_CATEGORY. Las páginas de categoría y
   subcategoría normales no comparten ninguna de estas clases.

   Tipografía tomada tal cual del estándar ya fijado más arriba:
   h1 de página interior (3.5rem / 2.25rem en móvil), cabecera de grupo
   (2.5rem / 2rem), antetítulo (.72rem/700/.12em/mayúsculas/ink 60%),
   metadato (.8125rem/1.4/ink 60%), cuerpo (1.0625rem/1.7) y la cursiva de
   marca en Angel Face. No se introduce ningún paso nuevo. */
.category-root__header{
  text-align:center;
  max-width:46rem;
  margin:0 auto 4.5rem;
}
.category-root__title{
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:3.5rem;
  line-height:1.2;
  color:var(--ink);
  margin:0;
}
.category-root__tagline{
  font-family:"Angel Face",cursive;
  font-weight:400;
  font-size:clamp(2rem, 2.8vw, 2.5rem);
  line-height:1.15;
  color:var(--ink);
  margin:1rem 0 0;
}
.category-root__intro{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:1.0625rem;
  line-height:1.7;
  color:var(--ink);
  margin:1.5rem auto 0;
  max-width:40rem;
}
@media (max-width:767px){
  .category-root__header{
    margin-bottom:3rem;
  }
  .category-root__title{
    font-size:2.25rem;
  }
  .category-root__tagline{
    font-size:1.875rem;
  }
  .category-root__intro{
    font-size:1rem;
    margin-top:1.25rem;
  }
}

/* El acordeón no es una card: es una lista. Su único contorno es un filete
   de 1px al 12% — suficiente para separar filas y para que se lea como algo
   pulsable, sin apilar cuatro marcos ni cuatro sombras en una página cuyo
   contenido real son las cards que hay dentro. El acento --brass aparece
   solo en el chevron (hover/abierto), que es el único elemento de estado. */
.category-root{
  margin:0 0 2rem;
}
.ritual-accordion{
  border-bottom:1px solid rgba(41,37,28,.12);
}
.ritual-accordion:first-of-type{
  border-top:1px solid rgba(41,37,28,.12);
}
/* display:flex en el <summary> quita de paso el triángulo nativo en Firefox;
   los otros dos selectores cubren Chrome/Safari antiguos. La semántica de
   "botón de revelado" y el estado abierto/cerrado siguen siendo los nativos
   de details/summary, no se sustituyen por roles ARIA a mano. */
.ritual-accordion__summary{
  display:flex;
  align-items:baseline;
  gap:1.25rem;
  padding:1.75rem 1.25rem;
  cursor:pointer;
  list-style:none;
  transition:background-color var(--motion-hover) var(--motion-ease);
}
.ritual-accordion__summary::-webkit-details-marker{
  display:none;
}
.ritual-accordion__summary::marker{
  content:"";
}
.ritual-accordion__summary:hover{
  background:#fdfbf9;
  background:color-mix(in srgb, var(--ritual-cream) 40%, #fff);
}
.ritual-accordion__summary:focus-visible{
  outline:1px solid var(--brass);
  outline-offset:-.25rem;
}
/* Sticky solo mientras el acordeón está abierto (selector [open], no una
   clase aparte: no hace falta JS para activarlo/desactivarlo). El límite
   de "hasta dónde se queda pegada" lo da gratis el propio <details>: es el
   contenedor de posicionamiento de este <summary>, así que en cuanto el
   final del panel (fin de esa categoría) pasa de largo, la cabecera se
   suelta sola y sube con el resto — nunca llega a montarse sobre la
   categoría siguiente. Por el mismo motivo, si hay más de un acordeón
   abierto a la vez nunca puede haber dos cabeceras ancladas a la vez: la
   de un acordeón se suelta en el instante exacto en que el siguiente
   <details> empieza a entrar en pantalla, no antes.
   Fondo sólido (mismo var que .header) porque, al quedar fija, el listado
   de servicios pasa por debajo. El borde es el único acabado: nada de
   sombra. */
.ritual-accordion[open] > .ritual-accordion__summary{
  position:sticky;
  top:var(--ritual-header-h, 0px);
  z-index:5;
  background-color:var(--bs-body-bg, #fff);
  border-bottom:1px solid rgba(41,37,28,.12);
}
/* Cabecera de grupo del estándar: el mismo paso que
   .subcategory-section__title, porque cumple exactamente el mismo papel
   (agrupar a los productos que vienen debajo). */
.ritual-accordion__name{
  flex:1 1 auto;
  min-width:0;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:2.5rem;
  line-height:1.2;
  color:var(--ink);
  margin:0;
}
.ritual-accordion__meta{
  flex:0 0 auto;
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:400;
  font-size:.8125rem;
  line-height:1.4;
  color:var(--ink);
  opacity:.6;
}
/* Chevron dibujado con dos bordes en vez de con un icono: a este tamaño una
   punta de flecha es todo lo que se ve, y así hereda color y grosor sin
   depender de ningún sprite. Gira 180º al abrir. */
.ritual-accordion__chevron{
  flex:0 0 auto;
  align-self:center;
  width:.5rem;
  height:.5rem;
  border-right:1px solid var(--ink);
  border-bottom:1px solid var(--ink);
  transform:translateY(-25%) rotate(45deg);
  transition:transform var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
.ritual-accordion__summary:hover .ritual-accordion__chevron,
.ritual-accordion__summary:focus-visible .ritual-accordion__chevron{
  border-color:var(--brass);
}
.ritual-accordion[open] > .ritual-accordion__summary .ritual-accordion__chevron{
  border-color:var(--brass);
  transform:translateY(25%) rotate(225deg);
}
@media (max-width:767px){
  .ritual-accordion__summary{
    flex-wrap:wrap;
    align-items:center;
    gap:.5rem 1rem;
    padding:1.25rem .75rem;
  }
  .ritual-accordion__name{
    flex:1 1 100%;
    order:1;
    font-size:2rem;
  }
  .ritual-accordion__meta{
    order:2;
  }
  .ritual-accordion__chevron{
    order:3;
    margin-left:auto;
  }
}
/* La altura la anima custom.js (WAAPI) sobre este contenedor; sin JS,
   details/summary abre y cierra igual, solo que de golpe. overflow lo pone y
   lo quita el propio script para no dejar recortado nada mientras está
   cerrado por CSS. */
.ritual-accordion__panel-inner{
  padding:.5rem 1.25rem 3.5rem;
}
@media (max-width:767px){
  .ritual-accordion__panel-inner{
    padding:.5rem .75rem 2.5rem;
  }
}
/* Las cards del listado traen .reveal, que custom.js oculta hasta que el
   elemento entra en pantalla al hacer scroll. Dentro de un acordeón eso no
   aplica: el contenido no aparece por scroll, lo abre el usuario, y la
   propia apertura ya es la animación. Se neutraliza solo aquí dentro, sin
   tocar la regla compartida .reveal, que el resto del sitio sigue usando. */
.ritual-accordion__panel .reveal{
  transition:none;
}
.ritual-accordion__panel .reveal.reveal--pending{
  opacity:1;
  transform:none;
}
.ritual-accordion__panel .products{
  margin:0;
}
/* Subcategorías dentro del panel: no son un segundo acordeón ni una segunda
   cabecera de grupo, son el rótulo que separa un bloque de servicios del
   siguiente. Por eso van en el paso de antetítulo del estándar y no en un
   tamaño de titular: a 1.875rem competirían con el nombre de cada servicio
   (1.625rem), que es lo que el usuario ha venido a leer. */
.category-root__section + .category-root__section{
  margin-top:3.5rem;
}
.ritual-accordion__panel .products + .category-root__section{
  margin-top:3.5rem;
}
.category-root__section-title{
  font-family:"Helvetica LT Std",sans-serif;
  font-weight:700;
  font-size:.72rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  color:var(--ink);
  opacity:.6;
  margin:0 0 1.25rem;
}
@media (max-width:767px){
  .category-root__section + .category-root__section,
  .ritual-accordion__panel .products + .category-root__section{
    margin-top:2.5rem;
  }
}

/* Bloque "métodos de pago" que el SDK de ps_checkout añade en la ficha de
   producto y en el carrito (PS_CHECKOUT_DISPLAY_LOGO_PRODUCT/_CART). */
#ps_checkout-payment-method-logo-block-container{display:none!important}

/* ==== Blog (módulos smartblog y smartbloghomelatestnews) ====
   Plantillas: themes/ritualbienestar/modules/smartblog/views/templates/
   front/ (overrides de las del módulo) y el bloque de la home en
   modules/smartbloghomelatestnews/. El módulo ya no carga CSS propio en el
   front (antes fw.css + smartblogstyle.css con Poppins/PT Serif de Google
   Fonts en todas las páginas): todo el estilo del blog vive aquí.
   - Tipografía: el estándar de la home y de las páginas de contenido.
     Titular de página (h1.page-title-section, 3.5rem), titular de
     elemento en las tarjetas (Tindoghouse 1.625rem), antetítulo para
     categoría/etiquetas de la barra lateral, metadato para fecha/autor,
     cuerpo de contenido largo (.page-content--cms) en la entrada.
   - Color: --brass solo como acento — estado activo (categoría actual,
     página actual), hover de enlaces de marca y filetes. Estructura y
     texto en --ink.
   - Tarjeta: mismo fondo crema rebajado y radio de 16px que las de "Los
     más elegidos"; al pasar el ratón sube 4px con --shadow-md.
   - La 404 de entradas/categorías inexistentes reutiliza la tarjeta de la
     404 del sitio (selectores [id^="module-smartblog-"] en esa sección). */

/* --- Listado: rejilla + barra lateral (encima en móvil) --- */
.blog-layout{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:2rem;
  margin:1rem 0 4rem;
}
.blog-layout__main{
  min-width:0;
}
.blog-layout > .blog-sidebar{
  order:-1;
}
@media (min-width:992px){
  .blog-layout{
    grid-template-columns:minmax(0,1fr) 16rem;
    gap:3.5rem;
  }
  .blog-layout > .blog-sidebar{
    order:0;
  }
}

.blog-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(17rem, 1fr));
  gap:2rem 1.5rem;
}

.blog-empty{
  margin:0;
  padding:2.5rem 1.5rem;
  border-radius:16px;
  background:var(--ritual-cream);
  text-align:center;
  font-size:1.0625rem;
  line-height:1.7;
  color:var(--ink);
}

.blog-search-summary{
  margin:0 0 1.5rem;
  font-size:.8125rem;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}

/* --- Cabecera de categoría: imagen y descripción bajo el h1 --- */
.blog-intro{
  margin:0 0 2.5rem;
  text-align:center;
}
.blog-intro__image{
  display:block;
  width:100%;
  aspect-ratio:16 / 9;
  object-fit:cover;
  border-radius:16px;
}
/* Solo texto (categoría sin imagen): columna de lectura de 46rem
   centrada; a todo el ancho las líneas serían demasiado largas. */
.blog-intro__text{
  max-width:46rem;
  margin:0 auto;
  font-size:1.0625rem;
  line-height:1.7;
  color:var(--ink);
}
.blog-intro__text > :last-child{
  margin-bottom:0;
}
/* Con imagen: imagen y descripción al 50%, centradas en vertical; en
   móvil, una debajo de otra. */
.blog-intro--image{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:1.5rem;
  align-items:center;
}
@media (min-width:768px){
  .blog-intro--image{
    grid-template-columns:repeat(2, minmax(0,1fr));
    gap:3rem;
    text-align:left;
  }
  .blog-intro--image .blog-intro__text{
    max-width:none;
    margin:0;
  }
}

/* --- Tarjeta de entrada --- */
.blog-card{
  position:relative;
  display:flex;
  flex-direction:column;
  overflow:hidden;
  border-radius:16px;
  background:#fbf8f5;
  background:color-mix(in srgb, var(--ritual-cream) 55%, #fff);
  color:var(--ink);
  transition:transform var(--motion-hover) var(--motion-ease), box-shadow var(--motion-hover) var(--motion-ease);
}
.blog-card__media{
  aspect-ratio:3 / 2;
  overflow:hidden;
  background:var(--ritual-cream);
}
.blog-card__image{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
  transition:transform var(--motion-duration) var(--motion-ease);
}
.blog-card__body{
  display:flex;
  flex:1 1 auto;
  flex-direction:column;
  align-items:flex-start;
  padding:1.5rem 1.5rem 1.25rem;
}
.blog-card--text .blog-card__body{
  padding-top:2rem;
}
.blog-card__kicker{
  margin:0 0 .5rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-card__title{
  margin:0 0 .75rem;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:1.625rem;
  line-height:1.2;
  color:var(--ink);
  text-wrap:balance;
}
/* Enlace estirado: toda la tarjeta es clicable, pero el único enlace
   accesible es el título. */
.blog-card__link{
  color:inherit;
  text-decoration:underline;
  text-decoration-color:transparent;
  text-decoration-thickness:1px;
  text-underline-offset:.2em;
  transition:color var(--motion-hover) var(--motion-ease), text-decoration-color var(--motion-hover) var(--motion-ease);
}
.blog-card__link::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:1;
}
.blog-card__link:focus-visible{
  outline:none;
}
.blog-card:has(.blog-card__link:focus-visible){
  outline:1px solid var(--brass);
  outline-offset:4px;
}
.blog-card__excerpt{
  margin:0 0 1.25rem;
  font-size:1rem;
  line-height:1.6;
  color:var(--ink);
}
.blog-card__meta{
  display:flex;
  flex-wrap:wrap;
  gap:0 .5rem;
  width:100%;
  margin:auto 0 0;
  padding-top:1rem;
  border-top:1px solid rgba(41,37,28,.12);
  font-size:.8125rem;
  line-height:1.4;
  color:rgba(41,37,28,.6);
  font-variant-numeric:tabular-nums;
}
@media (hover:hover){
  .blog-card:hover{
    transform:translateY(-4px);
    box-shadow:0 8px 24px rgba(41,37,28,.12);
  }
  .blog-card:hover .blog-card__image{
    transform:scale(1.03);
  }
  .blog-card:hover .blog-card__link{
    color:var(--brass);
    text-decoration-color:var(--brass);
  }
}
@media (prefers-reduced-motion:reduce){
  .blog-card,
  .blog-card__image{
    transition:none;
  }
  .blog-card:hover,
  .blog-card:hover .blog-card__image{
    transform:none;
  }
}
@media (max-width:767px){
  .blog-card__title{
    font-size:1.5rem;
  }
}

/* --- Barra lateral: buscador + categorías --- */
.blog-sidebar__block + .blog-sidebar__block{
  margin-top:2.5rem;
}
.blog-sidebar__title{
  display:block;
  margin:0 0 .75rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-search__field{
  padding-right:.35rem;
}
.blog-search__field .input-field__control::-webkit-search-cancel-button{
  -webkit-appearance:none;
}
.blog-search__submit{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  flex:none;
  width:2rem;
  height:2rem;
  padding:0;
  border:0;
  border-radius:50%;
  background:transparent;
  color:var(--ink);
  cursor:pointer;
  transition:color var(--motion-hover) var(--motion-ease), background-color var(--motion-hover) var(--motion-ease);
}
.blog-search__submit .material-icons{
  font-size:20px;
}
.blog-search__submit:hover,
.blog-search__submit:focus-visible{
  color:var(--brass);
  background:rgba(175,138,82,.1);
}

.blog-categories{
  margin:0;
  padding:0;
  list-style:none;
}
.blog-categories__link{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:1rem;
  padding:.65rem 0;
  border-bottom:1px solid rgba(41,37,28,.12);
  color:var(--ink);
  font-size:1rem;
  line-height:1.4;
  text-decoration:none;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-categories li:first-child .blog-categories__link{
  border-top:1px solid rgba(41,37,28,.12);
}
.blog-categories__count{
  font-size:.8125rem;
  color:rgba(41,37,28,.6);
  font-variant-numeric:tabular-nums;
}
.blog-categories__link:hover,
.blog-categories__link:focus-visible,
.blog-categories__link.is-active,
.blog-categories__link.is-active .blog-categories__count{
  color:var(--brass);
}

/* Móvil/tablet: la barra va encima del listado y las categorías pasan a
   píldoras que saltan de línea. Antes iban en una sola fila con scroll
   propio, pero el ancho de la fila empujaba a .blog-sidebar (rejilla con
   columna automática) y provocaba scroll lateral de toda la página; de ahí
   también el minmax(0,1fr) y el min-width:0. */
@media (max-width:991px){
  .blog-sidebar{
    display:grid;
    grid-template-columns:minmax(0,1fr);
    gap:1.5rem;
    min-width:0;
  }
  .blog-sidebar__block + .blog-sidebar__block{
    margin-top:0;
  }
  .blog-categories{
    display:flex;
    flex-wrap:wrap;
    justify-content:center;
    gap:.5rem;
  }
  .blog-categories li{
    max-width:100%;
  }
  .blog-categories__link,
  .blog-categories li:first-child .blog-categories__link{
    gap:.4rem;
    max-width:100%;
    padding:.45rem 1rem;
    border:1px solid rgba(41,37,28,.25);
    border-radius:999px;
    font-size:.9375rem;
  }
  .blog-categories__link.is-active{
    border-color:var(--brass);
  }
}

/* --- Paginación --- */
.blog-pagination{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:center;
  gap:1rem 1.5rem;
  margin:3.5rem 0 0;
}
.blog-pagination__list{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
  margin:0;
  padding:0;
  list-style:none;
}
.blog-pagination__page{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:2.5rem;
  height:2.5rem;
  border:1px solid rgba(41,37,28,.2);
  border-radius:50%;
  color:var(--ink);
  font-size:.9375rem;
  text-decoration:none;
  font-variant-numeric:tabular-nums;
  transition:color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
a.blog-pagination__page:hover,
a.blog-pagination__page:focus-visible{
  border-color:var(--brass);
  color:var(--brass);
}
.blog-pagination__page.is-current{
  border-color:var(--brass);
  background:var(--brass);
  color:#fff;
  font-weight:700;
}
.blog-pagination__step{
  display:inline-flex;
  align-items:center;
  gap:.25rem;
  color:var(--ink);
  font-size:.8125rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-decoration:none;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-pagination__step .material-icons{
  font-size:20px;
}
.blog-pagination__step:hover,
.blog-pagination__step:focus-visible{
  color:var(--brass);
}

/* --- Ficha de entrada ---
   Columna de lectura de 46rem; la foto destacada ocupa algo más (64rem). */
.blog-post{
  max-width:64rem;
  margin:1rem auto 0;
}
.blog-post__header,
.blog-post__content,
.blog-post__tags,
.blog-post-nav,
.blog-comments{
  max-width:46rem;
  margin-left:auto;
  margin-right:auto;
}
.blog-post__header{
  margin-bottom:2.5rem;
  text-align:center;
}
.blog-post__kicker{
  margin:0 0 .75rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
}
.blog-post__kicker a{
  color:rgba(41,37,28,.6);
  text-decoration:none;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-post__kicker a:hover,
.blog-post__kicker a:focus-visible{
  color:var(--brass);
}
h1.page-title-section.blog-post__title{
  margin:0 0 1rem;
  text-wrap:balance;
}
.blog-post__meta{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:0 .5rem;
  margin:0;
  font-size:.8125rem;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-post__meta a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-post__meta a:hover{
  color:var(--brass);
}
.blog-post__cover{
  margin:0 0 3rem;
}
.blog-post__cover img{
  display:block;
  width:100%;
  height:auto;
  aspect-ratio:16 / 9;
  object-fit:cover;
  border-radius:16px;
}
/* Cuerpo: tipografía de .page-content--cms (contenido largo). Aquí solo
   lo que el editor de entradas añade y una página CMS no suele llevar. */
.blog-post__content img{
  max-width:100%;
  height:auto;
  border-radius:16px;
}
.blog-post__content blockquote{
  margin:2.5rem 0;
  padding:0 0 0 1.5rem;
  border-left:2px solid var(--brass);
  font-size:1.25rem;
  line-height:1.5;
}
.blog-post__content blockquote > :last-child{
  margin-bottom:0;
}

/* Etiquetas: badge neutro (fondo crema, filete ink) de DIRECCION-VISUAL.md #5. */
.blog-post__tags{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
  margin-top:2.5rem;
  margin-bottom:0;
  padding:0;
  list-style:none;
}
.blog-tag{
  display:inline-block;
  padding:.4rem .9rem;
  border:1px solid rgba(41,37,28,.25);
  border-radius:999px;
  background:var(--ritual-cream);
  color:var(--ink);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  text-decoration:none;
  transition:color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
.blog-tag:hover,
.blog-tag:focus-visible{
  border-color:var(--brass);
  color:var(--brass);
}

/* Anterior / siguiente */
.blog-post-nav{
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:1.5rem;
  margin-top:4rem;
  padding:2rem 0;
  border-top:1px solid rgba(41,37,28,.12);
  border-bottom:1px solid rgba(41,37,28,.12);
}
.blog-post-nav__link{
  display:flex;
  flex-direction:column;
  gap:.5rem;
  color:var(--ink);
  text-decoration:none;
}
.blog-post-nav__link--next{
  grid-column:2;
  align-items:flex-end;
  text-align:right;
}
.blog-post-nav__label{
  display:inline-flex;
  align-items:center;
  gap:.25rem;
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-post-nav__label .material-icons{
  font-size:18px;
}
.blog-post-nav__title{
  font-family:"Tindoghouse",cursive;
  font-size:1.5rem;
  line-height:1.2;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-post-nav__link:hover .blog-post-nav__title,
.blog-post-nav__link:focus-visible .blog-post-nav__title{
  color:var(--brass);
}
@media (max-width:575px){
  .blog-post-nav{
    grid-template-columns:minmax(0,1fr);
  }
  .blog-post-nav__link--next{
    grid-column:1;
  }
}

/* --- Comentarios --- */
.blog-comments{
  margin-top:4rem;
  margin-bottom:4rem;
}
/* Anclas (#comments, #respond, #comment-N): que no queden tapadas por la
   cabecera fija (--ritual-header-h la mantiene custom.js). */
.blog-comments,
.blog-comment-form,
.blog-comment{
  scroll-margin-top:calc(var(--ritual-header-h) + 1.5rem);
}
.blog-comments__title{
  margin:0 0 1.5rem;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:1.625rem;
  line-height:1.2;
  color:var(--ink);
}
.blog-comments__count{
  font-family:"Helvetica LT Std",sans-serif;
  font-size:1rem;
  color:rgba(41,37,28,.6);
}
.blog-comments__empty{
  margin:0;
  font-size:1rem;
  line-height:1.7;
  color:rgba(41,37,28,.75);
}
.blog-comments__list,
.blog-comment__replies{
  margin:0;
  padding:0;
  list-style:none;
}
.blog-comment{
  display:grid;
  grid-template-columns:2.75rem minmax(0,1fr);
  gap:1rem;
  padding:1.5rem 0;
  border-bottom:1px solid rgba(41,37,28,.12);
}
.blog-comments__list > .blog-comment:first-child{
  border-top:1px solid rgba(41,37,28,.12);
}
.blog-comment__avatar{
  display:flex;
  align-items:center;
  justify-content:center;
  width:2.75rem;
  height:2.75rem;
  border-radius:50%;
  background:var(--ritual-cream);
  font-family:"Tindoghouse",cursive;
  font-size:1.25rem;
  line-height:1;
  color:var(--ink);
}
.blog-comment__header{
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:0 .75rem;
  margin:0 0 .35rem;
}
.blog-comment__author{
  font-weight:700;
  font-size:1rem;
}
.blog-comment__date{
  font-size:.8125rem;
  line-height:1.4;
  color:rgba(41,37,28,.6);
  font-variant-numeric:tabular-nums;
}
.blog-comment__text{
  margin:0 0 .75rem;
  font-size:1rem;
  line-height:1.7;
  color:var(--ink);
  overflow-wrap:anywhere;
}
.blog-comment__reply{
  display:inline-flex;
  align-items:center;
  gap:.25rem;
  padding:0;
  border:0;
  background:none;
  color:rgba(41,37,28,.7);
  font-size:.72rem;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  line-height:1.4;
  cursor:pointer;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-comment__reply .material-icons{
  font-size:16px;
}
.blog-comment__reply:hover,
.blog-comment__reply:focus-visible{
  color:var(--brass);
}
/* Respuestas: un nivel, colgadas con un filete --brass suave. */
.blog-comment__replies{
  margin-top:1rem;
  padding-left:1.25rem;
  border-left:1px solid rgba(175,138,82,.45);
}
.blog-comment--reply{
  grid-template-columns:2.25rem minmax(0,1fr);
  gap:.75rem;
  padding:.75rem 0;
  border-bottom:0;
}
.blog-comment--reply .blog-comment__avatar{
  width:2.25rem;
  height:2.25rem;
  font-size:1rem;
}

/* Formulario: card de formulario (.form-card) y controles .input-field del
   sistema compartido; aquí solo el ancho y lo propio del blog. */
.form-card.blog-comment-form{
  max-width:none;
  margin-top:2.5rem;
  padding:2rem 1.5rem;
}
@media (min-width:768px){
  .form-card.blog-comment-form{
    padding:2.5rem;
  }
}
.blog-comment-form__title{
  margin:0 0 .5rem;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:1.625rem;
  line-height:1.2;
  color:var(--ink);
}
.blog-comment-form__intro,
.blog-comment-form__as{
  margin:0 0 1.5rem;
  font-size:.8125rem;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-comment-form__as strong{
  color:var(--ink);
}
.blog-comment-form__notice,
.blog-comment-form__error{
  margin:0 0 1.5rem;
  padding:.75rem 1rem;
  border-left:3px solid var(--color-success);
  border-radius:10px;
  background:#fff;
  font-size:.9375rem;
  line-height:1.5;
  color:var(--ink);
}
.blog-comment-form__error{
  border-left-color:var(--color-error);
  color:var(--color-error);
}
.blog-comment-form__replying{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.25rem .75rem;
  margin:0 0 1.5rem;
  padding:.6rem .9rem;
  border:1px dashed rgba(175,138,82,.6);
  border-radius:10px;
  background:#fff;
  font-size:.9375rem;
}
/* Casilla de privacidad: texto legal del estándar (.8125rem, ink al 60%)
   y su enlace como metadato accionable, igual que en la newsletter. */
.blog-comment-form__privacy{
  margin:0 0 1.5rem;
}
.blog-comment-form__privacy .form-check-ritual{
  align-items:flex-start;
  margin-bottom:0;
}
.blog-comment-form__privacy .form-check-ritual__label{
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  color:rgba(41,37,28,.6);
}
.blog-comment-form__privacy a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
  transition:color var(--motion-hover) var(--motion-ease);
}
.blog-comment-form__privacy a:hover,
.blog-comment-form__privacy a:focus-visible{
  color:var(--brass);
}
.blog-comment-form__privacy.has-error .input-field__message{
  color:var(--color-error);
}
/* display:flex pisaría el atributo hidden del marcado. */
.blog-comment-form__replying[hidden]{
  display:none;
}
.blog-comment-form__cancel{
  padding:0;
  border:0;
  background:none;
  color:rgba(41,37,28,.6);
  font-size:.8125rem;
  text-decoration:underline;
  text-underline-offset:2px;
  cursor:pointer;
}
.blog-comment-form__cancel:hover,
.blog-comment-form__cancel:focus-visible{
  color:var(--brass);
}
@media (min-width:768px){
  .blog-comment-form__row{
    display:grid;
    grid-template-columns:repeat(2, minmax(0,1fr));
    gap:0 1.25rem;
  }
}
.blog-comment-form__captcha-row{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:.75rem;
}
.blog-comment-form__captcha-image{
  display:block;
  border:1px solid rgba(41,37,28,.12);
  border-radius:10px;
}
.blog-comment-form__captcha-refresh{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:2.5rem;
  height:2.5rem;
  padding:0;
  border:1px solid rgba(41,37,28,.2);
  border-radius:50%;
  background:#fff;
  color:var(--ink);
  cursor:pointer;
  transition:color var(--motion-hover) var(--motion-ease), border-color var(--motion-hover) var(--motion-ease);
}
.blog-comment-form__captcha-refresh .material-icons{
  font-size:20px;
}
.blog-comment-form__captcha-refresh:hover,
.blog-comment-form__captcha-refresh:focus-visible{
  border-color:var(--brass);
  color:var(--brass);
}
.blog-comment-form__captcha-row .input-field__wrap{
  flex:1 1 8rem;
  width:auto;
}
.blog-comment-form__actions{
  display:flex;
  justify-content:flex-end;
  margin-top:.5rem;
}
@media (max-width:575px){
  .blog-comment-form__actions .btn-pill{
    width:100%;
  }
}

/* --- Home: últimas entradas (smartbloghomelatestnews vía displayHome) ---
   Misma composición que el resto de secciones de la home: antetítulo +
   titular de sección centrados, 4rem de ritmo vertical (40px en móvil),
   enlace de texto con filete --brass al final. Fondo blanco. */
.ritual-blog-latest{
  padding:4rem 0;
  background:#fff;
}
.ritual-blog-latest__header{
  margin:0 0 3rem;
  text-align:center;
}
.ritual-blog-latest__title{
  margin:0;
  font-family:"Tindoghouse",cursive;
  font-weight:400;
  font-size:2.5rem;
  line-height:1.2;
  color:var(--ink);
}
.ritual-blog-latest__grid{
  grid-template-columns:minmax(0,1fr);
  max-width:1120px;
  margin:0 auto;
  transition-delay:.12s;
}
@media (min-width:768px){
  .ritual-blog-latest__grid{
    grid-template-columns:repeat(2, minmax(0,1fr));
  }
}
@media (min-width:992px){
  .ritual-blog-latest__grid{
    grid-template-columns:repeat(3, minmax(0,1fr));
  }
}
.ritual-blog-latest__more{
  margin:2.5rem 0 0;
  text-align:center;
  transition-delay:.24s;
}
.ritual-blog-latest__link{
  position:relative;
  display:inline-block;
  padding-bottom:.6rem;
  color:var(--ink);
  font-size:.8125rem;
  font-weight:400;
  line-height:1.4;
  letter-spacing:.14em;
  text-transform:uppercase;
  text-decoration:none;
}
.ritual-blog-latest__link:hover,
.ritual-blog-latest__link:focus-visible{
  color:var(--ink);
}
.ritual-blog-latest__link::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:1px;
  background:var(--brass);
  transform:scaleX(.3);
  transform-origin:left center;
  transition:transform var(--motion-hover) var(--motion-ease);
}
.ritual-blog-latest__link:hover::after,
.ritual-blog-latest__link:focus-visible::after{
  transform:scaleX(1);
}
@media (prefers-reduced-motion:reduce){
  .ritual-blog-latest__link::after{
    transition:none;
  }
}
@media (max-width:768px){
  .ritual-blog-latest{
    padding:40px 0;
  }
  .ritual-blog-latest__title{
    font-size:2rem;
  }
}
