/* Rooms / WebGL slider section.
   Class names are namespaced `rooms-*` — the source pack used .slider,
   .frame and .cursor, all of which would have collided with the page above. */
:root {
  --rm-bg: #17120f;
  --rm-ink: #f4efe8;
  --rm-accent: #c79a5b;
}

/* Sits above the previous section and overlaps it slightly, so it reads as a
   new panel riding up over the page. The negative margin keeps this purely a
   layout offset — a transform here would re-root the fixed canvas below. */
.rooms {
  /* Single source of truth for the main image's box. It was repeated three
     times (media, info, and now the secondary rail) and all three must stay
     pixel-identical or the secondaries drift off the photo. */
  --rm-main-w: clamp(240px, 30vw, 420px);

  /* ── Composición horizontal: foto + panel ──────────────────────────
     El panel colgaba de la foto con `left: 105%` mientras la foto se
     centraba en el viewport, así que el conjunto quedaba descentrado hacia
     la derecha y el panel se salía: medido a 1023px de ancho, su borde
     derecho caía en 1040px — fuera de pantalla — y encima chocaba con la
     flecha de siguiente.

     Ahora lo que se centra es la COMPOSICIÓN. --rm-shift desplaza foto,
     marcos secundarios y panel media anchura de panel hacia la izquierda,
     de modo que el bloque entero queda centrado y el panel siempre cabe. */
  --rm-panel-w: clamp(240px, 26vw, 360px);
  --rm-panel-gap: clamp(20px, 3vw, 48px);
  --rm-comp-w: calc(var(--rm-main-w) + var(--rm-panel-gap) + var(--rm-panel-w));
  --rm-shift: calc((var(--rm-panel-w) + var(--rm-panel-gap)) / 2);

  /* Hueco de las flechas, derivado del espacio que la composición deja
     libre en vez de un 8vw fijo. Con el valor fijo, a 700px el hueco (56px)
     más la flecha (52px) invadían la foto. El término del medio se queda con
     lo que sobra a cada lado menos el ancho de la flecha y un respiro. */
  --rm-gutter: max(0.25rem, min(5vw, calc((100vw - var(--rm-comp-w)) / 2 - 60px)));

  /* Secondary images, sized as fractions of the main image rather than in
     fixed px. The brief's absolute widths (210 / 320) do not fit: at the main
     image's capped 420x560 box the two stacked frames plus the 15% top offset
     come to 604px against 560px available, so they would collide instead of
     leaving the required 40-56px gap. These fractions keep the gap at ~41px
     and hold it at every viewport width. */
  --rm-sec-a-w: calc(var(--rm-main-w) * 0.40);
  --rm-sec-b-w: calc(var(--rm-main-w) * 0.64);
  /* 17%, not 15%. The outline room name runs across the top of this same
     column and grows to 72px at the widest breakpoint, which left only 12px
     of air above the frame. Trimming the upper frame from 0.42 to 0.40 pays
     for the extra offset, so the clearance roughly doubles without eating
     into the gap between the two frames. */
  --rm-sec-a-top: 17%;
  --rm-sec-overlap: 28px;

  /* Cut-out frame */
  --rm-frame-pad: 11px;
  --rm-frame-r: 24px;
  --rm-img-r: 16px;
  --rm-notch-r: 40px;

  position: relative;
  z-index: 5;
  width: 100%;
  min-height: 100svh;
  margin-top: -7svh;
  border-radius: 34px 34px 0 0;
  box-shadow: 0 -34px 90px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  color: var(--rm-ink);
  font-family: var(--ov-font-display);
  isolation: isolate;
}

/* Opaque backdrop; its colour is tweened per slide. */
.rooms-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--rm-bg);
}

.rooms-grain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  opacity: 0.05;
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* The WebGL canvas, injected into .rooms-media by rooms.js and sized to it.

   It was a viewport-sized fixed canvas that chased the frame's live position
   every frame. That is only smooth where scrolling and rendering share a
   thread; Safari and every phone scroll on the compositor, so the photograph
   trailed the page and shook — and a full-screen layer sitting over the
   document dragged on the scrolling of neighbouring sections too. As a plain
   absolutely-positioned child it scrolls with its own parent, for free. */
.rooms-gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  opacity: 0;
  pointer-events: none;
}

.rooms-corner {
  position: absolute;
  width: 14px;
  height: 14px;
  z-index: 4;
  pointer-events: none;
}
.rooms-corner::before,
.rooms-corner::after {
  content: "";
  position: absolute;
  background: rgba(244, 239, 232, 0.3);
}
.rooms-corner::before { width: 1px; height: 14px; left: 50%; top: 0; transform: translateX(-50%); }
.rooms-corner::after { width: 14px; height: 1px; top: 50%; left: 0; transform: translateY(-50%); }
.rooms-corner-tl { top: 32px; left: 32px; }
.rooms-corner-br { bottom: 32px; right: 32px; }

/* ── Section heading ─────────────────────────────────────────────────── */
.rooms-head {
  position: relative;
  z-index: 4;
  text-align: center;
  padding: clamp(3rem, 7vh, 5.5rem) 1.5rem 0;
}

/* Tipografía en .sec-eyebrow (style.css). Aquí solo el ritmo vertical. */
.rooms-eyebrow {
  margin: 0 0 0.9rem;
}

/* Escala y énfasis en .sec-title (style.css). */
.rooms-heading {
  margin: 0;
}
/* El énfasis lo define .sec-title em: itálica serif, sin color. El dorado
   de esta sección pasó al numeral del índice, para que el acento aparezca
   una sola vez y en el mismo sitio que en las otras cuatro. */

/* ── Slider stage ────────────────────────────────────────────────────── */
.rooms-stage {
  position: relative;
  z-index: 3;
  width: 100%;
  height: clamp(560px, 74svh, 760px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.rooms-media {
  position: absolute;
  left: 50%;
  top: 50%;
  /* -50% centra la caja; --rm-shift corre el conjunto para dejarle sitio al
     panel a la derecha. Los tres bloques centrados llevan el mismo desfase o
     dejan de estar alineados entre sí. */
  transform: translate(calc(-50% - var(--rm-shift)), -50%);
  width: var(--rm-main-w);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  z-index: 1;
  user-select: none;
  cursor: pointer;
}

/* The photograph used wherever the shader is not running (see rooms.js).
   Hidden while the canvas paints, because the canvas is viewport-fixed and
   sits behind the stage in the stacking order — showing both would put this
   one on top of it. */
.rooms-flat {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--rm-img-r);
}
.rooms--gl .rooms-flat { display: none; }

.rooms-info {
  position: absolute;
  left: 50%;
  top: 50%;
  /* -50% centra la caja; --rm-shift corre el conjunto para dejarle sitio al
     panel a la derecha. Los tres bloques centrados llevan el mismo desfase o
     dejan de estar alineados entre sí. */
  transform: translate(calc(-50% - var(--rm-shift)), -50%);
  width: var(--rm-main-w);
  aspect-ratio: 3 / 4;
  z-index: 2;
  pointer-events: none;
}

/* All four slides occupy the same box. They used to sit in normal flow, and
   because .rooms-index and .rooms-panel are absolute but .rooms-title is not,
   each article contributed exactly one title's height to the stack — so the
   room name drifted 64px further down on every slide (ESTUDIOS at y0,
   DEPARTAMENTOS at y191) and the lower ones ran straight into the secondary
   frame. inset:0 of .rooms-info gives .rooms-panel the identical containing
   block it had before, so the right-hand column does not move. */
.rooms-slide {
  position: absolute;
  inset: 0;
  /* The articles now overlap the whole photo, so an `auto` here would let the
     topmost one swallow the main image's click-to-advance. Only the live
     panel needs to be interactive — that is where the Reservar button is. */
  pointer-events: none;
}
.rooms-slide.is-current .rooms-panel {
  pointer-events: auto;
}
.rooms-slide:not(.is-current) .rooms-index,
.rooms-slide:not(.is-current) .rooms-title,
.rooms-slide:not(.is-current) .rooms-panel {
  opacity: 0;
  pointer-events: none;
}

.rooms-index {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-58%, -22%);
  font-size: clamp(5rem, 11vw, 12rem);
  font-weight: 700;
  line-height: 0.8;
  overflow: hidden;
  pointer-events: none;
  color: rgba(244, 239, 232, 0.12);
}

.rooms-title {
  /* --rm-title-fit is set per-title by rooms.js, only on names that overflow
     this box at the shared size (everything SUPERIOR-length and under stays
     untouched at 1). It has to live inside font-size rather than a transform:
     scale() on the element — overflow:hidden clips against the box as laid
     out, before any transform runs, so scaling down post-layout only shrinks
     the already-cropped result instead of the source text. Shrinking the
     font itself is what keeps the clip from happening in the first place.
     -webkit-text-stroke is scaled along with it so a smaller word keeps the
     same relative line weight instead of reading heavier than the rest. */
  font-size: calc(clamp(2.25rem, 5.4vw, 5.5rem) * var(--rm-title-fit, 1));
  font-weight: 700;
  line-height: 0.82;
  letter-spacing: -0.02em;
  overflow: hidden;
  white-space: nowrap;
  /* Box width comes from the parent (.rooms-title has no width of its own),
     so this percentage is unaffected by the font-size change above and keeps
     landing at the same pixel offset every other title uses. */
  transform: translateX(-34%);
  color: transparent;
  -webkit-text-stroke: calc(1.5px * var(--rm-title-fit, 1)) var(--rm-ink);
  margin: 0;
  pointer-events: none;
}

.rooms-title .char,
.rooms-index .char {
  /* La transición de "01"/"02"/"03" mueve cada carácter con yPercent, y una
     traslación en porcentaje se resuelve contra la caja del propio elemento —
     algo que una caja inline no tiene definido de forma fiable, así que el
     desplazamiento se resolvía en 0px pase lo que pase. El número no se
     deslizaba: aparecía de golpe en el instante en que su slide se marca
     is-current, que es justo el salto que se ve mal al cambiar de
     habitación. inline-block le da a cada carácter una caja real. */
  display: inline-block;
}

/* Copy + specs block, offset to the right of the image like the original */
.rooms-panel {
  position: absolute;
  bottom: 0;
  /* Separación explícita en lugar del 105%, que ataba el hueco al ancho de la
     foto: al encoger la foto el hueco encogía con ella justo cuando más falta
     hacía. */
  left: calc(100% + var(--rm-panel-gap));
  width: var(--rm-panel-w);
}

.rooms-desc {
  font-size: 0.95rem;
  line-height: 1.5;
  color: rgba(244, 239, 232, 0.75);
  margin: 0 0 1.4rem;
}
.rooms-desc .line { overflow: hidden; }

/* ── Spec pills with icons ───────────────────────────────────────────── */
.rooms-specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.6rem;
  margin-bottom: 1.5rem;
}

.rooms-spec {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid rgba(244, 239, 232, 0.16);
  border-radius: 10px;
  background: rgba(244, 239, 232, 0.03);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: border-color 0.35s ease, background-color 0.35s ease;
}
.rooms-spec:hover {
  border-color: rgba(199, 154, 91, 0.55);
  background: rgba(199, 154, 91, 0.08);
}
.rooms-spec svg {
  width: 16px;
  height: 16px;
  flex: none;
  stroke: var(--rm-accent);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rooms-spec b {
  font-weight: 600;
  color: var(--rm-ink);
}
.rooms-spec span {
  color: rgba(244, 239, 232, 0.55);
}

.rooms-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-top: 1px solid rgba(244, 239, 232, 0.14);
  padding-top: 1rem;
}

.rooms-price small {
  display: block;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(244, 239, 232, 0.45);
  margin-bottom: 0.25rem;
}
.rooms-price strong {
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.rooms-price i {
  font-style: normal;
  font-size: 0.8rem;
  color: rgba(244, 239, 232, 0.5);
}

.rooms-cta {
  font-family: inherit;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--rm-bg);
  background: var(--rm-ink);
  border: none;
  border-radius: 999px;
  padding: 0.85em 1.6em;
  cursor: pointer;
  transition: transform 0.3s ease, background-color 0.3s ease;
}
.rooms-cta:hover {
  transform: scale(1.03);
  background: var(--rm-accent);
}

/* ── Secondary images (desktop only) ─────────────────────────────────── */
/* The rail is an invisible box laid exactly over the main image, so the two
   frames can be placed in percentages of the photo's own geometry and track
   it at any width. Built by rooms.js only above 1100px — below that the two
   images are never inserted into the DOM, so their bytes are never fetched.

   z-index 3 puts it above .rooms-info (2), which carries the outline number
   and the outline room name, satisfying "outline behind everything"; the
   arrows sit at 5 and stay clickable. pointer-events:none keeps the whole
   rail out of the way of the main image's click-to-advance. */
.rooms-aside {
  position: absolute;
  left: 50%;
  top: 50%;
  /* -50% centra la caja; --rm-shift corre el conjunto para dejarle sitio al
     panel a la derecha. Los tres bloques centrados llevan el mismo desfase o
     dejan de estar alineados entre sí. */
  transform: translate(calc(-50% - var(--rm-shift)), -50%);
  width: var(--rm-main-w);
  aspect-ratio: 3 / 4;
  z-index: 3;
  pointer-events: none;
}

.rooms-sec {
  position: absolute;
  /* Right edge parked `--rm-sec-overlap` in from the main image's left edge,
     so each frame bites into the photo by exactly that much. */
  right: calc(100% - var(--rm-sec-overlap));
  margin: 0;
  padding: var(--rm-frame-pad);
  border-radius: var(--rm-frame-r);
  /* Opaque, and matched to the section background, which rooms.js re-tweens
     per slide. That opacity is the point: it is what opens a visible gap
     between the frame and the main photo underneath. */
  background: var(--rm-bg);
  /* Concave corner. A radial-gradient mask with a transparent core punches a
     quarter-circle out of the corner facing the main image. Chosen over the
     box-shadow-spread trick because a mask removes real pixels instead of
     painting a matching-coloured disc on top — so it cannot leave a halo or a
     1px seam, and it does not care what is behind the section. The half-pixel
     feather on the first stop is what keeps the arc from aliasing. */
  -webkit-mask-image: var(--rm-notch);
  mask-image: var(--rm-notch);
}

.rooms-sec img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: var(--rm-img-r);
}

/* Upper: small portrait, notch on its bottom-right. */
.rooms-sec-a {
  top: var(--rm-sec-a-top);
  width: var(--rm-sec-a-w);
  --rm-notch: radial-gradient(
    circle at 100% 100%,
    transparent 0 calc(var(--rm-notch-r) - 0.5px),
    #000 var(--rm-notch-r)
  );
}
.rooms-sec-a img { aspect-ratio: 3 / 4; }

/* Lower: medium landscape, bottom flush with the main image, notch on its
   top-right. */
.rooms-sec-b {
  bottom: 0;
  width: var(--rm-sec-b-w);
  --rm-notch: radial-gradient(
    circle at 100% 0,
    transparent 0 calc(var(--rm-notch-r) - 0.5px),
    #000 var(--rm-notch-r)
  );
}
.rooms-sec-b img { aspect-ratio: 4 / 3; }

@media (min-width: 1440px) {
  .rooms { --rm-frame-r: 28px; --rm-notch-r: 44px; }
}

/* Belt and braces: JS is what actually keeps the rail out of the DOM below
   this width, but if it ever runs before a resize settles, nothing shows. */
@media not all and (any-hover: hover) and (any-pointer: fine) and (min-width: 640px) {
  .rooms-aside { display: none; }
}

/* Los marcos secundarios muerden el borde izquierdo de la foto, así que
   reclaman a su izquierda 0.64 del ancho principal menos los 28px de mordida
   —unos 126px con la foto en su mínimo—. Al centrar la composición completa
   (foto + panel) el bloque se corre a la izquierda, y por debajo de este
   ancho ese aire ya no existe: los marcos se salían por el borde. Son un
   adorno; lo que la sección no puede perder es la foto y el panel. */
@media (max-width: 820px) {
  .rooms-aside { display: none; }
}

/* ── Navigation ──────────────────────────────────────────────────────── */
.rooms-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 52px;
  height: 22px;
  z-index: 5;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
}
.rooms-nav svg {
  display: block;
  width: 100%;
  height: 100%;
  transition: transform 250ms ease;
  transform: translateX(var(--tr-x, 0px));
}
.rooms-nav svg path { fill: var(--rm-ink); }
.rooms-nav-prev { left: var(--rm-gutter); }
.rooms-nav-prev:hover svg { --tr-x: -10px; }
.rooms-nav-next { right: var(--rm-gutter); }
.rooms-nav-next:hover svg { --tr-x: 10px; }

/* ── Tabs + progress ─────────────────────────────────────────────────── */
.rooms-tabs {
  position: relative;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 1.5rem;
}

.rooms-tab {
  font-family: inherit;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(244, 239, 232, 0.45);
  background: none;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 0.6em 1.1em;
  cursor: pointer;
  transition: color 0.3s ease, border-color 0.3s ease;
}
.rooms-tab:hover { color: var(--rm-ink); }
.rooms-tab.is-active {
  color: var(--rm-ink);
  border-color: rgba(244, 239, 232, 0.3);
}

.rooms-progress {
  position: relative;
  z-index: 4;
  width: min(420px, 60vw);
  height: 1px;
  margin: 1.75rem auto 0;
  background: rgba(244, 239, 232, 0.15);
}
.rooms-progress i {
  display: block;
  height: 100%;
  /* Starting value only — rooms.js overwrites it with 100/roomCount%. */
  width: 33.3333%;
  background: var(--rm-accent);
  transform-origin: left;
  transition: transform 0.6s cubic-bezier(0.65, 0, 0.35, 1);
}

.rooms-counter {
  position: relative;
  z-index: 4;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: rgba(244, 239, 232, 0.45);
  padding: 1rem 0 clamp(2.5rem, 6vh, 4.5rem);
}
.rooms-counter b { color: var(--rm-ink); font-weight: 600; }

/* ── Responsive ──────────────────────────────────────────────────────── */
/* ── Phones and tablets: one column, no shader ───────────────────────── */
/* The previous version kept the desktop's absolute placement and reserved
   room for it with 26rem of padding under the stage, while .rooms-info was
   centred inside that padded box. The result was the photograph at the top,
   the room name floating over it, and then a screen-and-a-half of nothing
   before the description — the gap was the reserved padding, not spacing.
   Here everything is in normal flow and the column is only as tall as what
   is in it. */
@media not all and (any-hover: hover) and (any-pointer: fine) and (min-width: 640px) {
  .rooms {
    /* Shared by the photograph and by the arrows, which centre on it. */
    --rm-m-w: min(320px, 74vw);
  }

  .rooms-stage {
    /* Back to normal flow. It is a centring flex row on desktop, and leaving
       it that way here made the photograph and the copy siblings in a row
       that squeezed the picture down to 45px wide. */
    display: block;
    height: auto;
    padding: 1.5rem 0 0;
  }

  .rooms-media {
    position: relative;
    left: auto;
    top: auto;
    transform: none;
    margin: 0 auto;
    width: var(--rm-m-w);
  }

  .rooms-info {
    position: relative;
    left: auto;
    top: auto;
    transform: none;
    width: min(420px, 88vw);
    aspect-ratio: auto;
    margin: 1.6rem auto 0;
    /* The slides stack in a single grid cell rather than being absolutely
       positioned, so the column takes the height of its tallest slide on its
       own. That is what removes the need for reserved padding — and it keeps
       every slide in the layout, so the cross-fade between them still has
       something to animate. */
    display: grid;
  }

  .rooms-slide {
    position: relative;
    inset: auto;
    grid-area: 1 / 1;
  }

  .rooms-index {
    position: relative;
    left: auto;
    top: auto;
    transform: none;
    font-size: clamp(2.5rem, 15vw, 3.75rem);
    line-height: 0.9;
    /* All four sides, not just the bottom. It is an <h3>, and taking it out
       of absolute positioning handed it the browser's default 1em top margin
       back — 56px of it at this size, which was most of the gap under the
       photograph. */
    margin: 0 0 0.15rem;
  }

  .rooms-title {
    transform: none;
    /* Keeps the per-title fit factor rooms.js measures; without it the long
       names would be clipped again at this size. */
    font-size: calc(clamp(1.6rem, 8.4vw, 2.4rem) * var(--rm-title-fit, 1));
    -webkit-text-stroke-width: calc(1.2px * var(--rm-title-fit, 1));
    margin-bottom: 1.1rem;
  }

  .rooms-panel {
    position: relative;
    left: auto;
    top: auto;
    bottom: auto;
    transform: none;
    width: 100%;
    text-align: left;
  }

  /* The stage used to end well below the panel because of its reserved
     padding, which kept these clear. Now that it ends where the content does,
     they need the gap themselves — without it the Reservar button and the
     first tab sit against each other. */
  .rooms-tabs { margin-top: 2.25rem; }

  /* Centred on the photograph rather than on the stage: with the stage now
     as tall as the whole column, a 50% offset would have put them down among
     the specs. */
  .rooms-nav {
    top: calc(1.5rem + var(--rm-m-w) * 0.6667);
  }
  .rooms-nav-prev { left: 3vw; }
  .rooms-nav-next { right: 3vw; }

  /* ── Escalón de tablet ─────────────────────────────────────────────
     Una tablet cae en este layout apilado y hace bien: no tiene puntero
     fino, así que la composición horizontal de escritorio no le sirve.
     Pero las medidas de aquí estaban pensadas para un teléfono y en una
     pantalla de tablet se quedaban cortas — medido a 767px: la foto
     ocupaba 320px (42% del ancho) y la columna de texto 420px (55%),
     dejando 224px y 174px de vacío a cada lado.

     Sólo crecen estas dos medidas. El resto de la sección se deriva de
     ellas: las flechas se posicionan desde --rm-m-w, y los títulos ya
     usan clamp con tope propio. Y sólo hace falta en Habitaciones: el
     resto de secciones ya ocupaban entre el 85% y el 100% a este ancho.

     Anidado dentro de la consulta de arriba, no suelto: así aplica
     únicamente cuando el layout apilado está activo, sin tener que
     reescribir la negación de REGO_MQ y arriesgarse a que las dos
     versiones se desincronicen. */
  @media (min-width: 700px) {
    .rooms { --rm-m-w: min(480px, 58vw); }
    .rooms-info { width: min(600px, 76vw); }
  }
}

@media (max-width: 640px) {
  .rooms-corner { display: none; }
  .rooms-specs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rooms-foot { flex-direction: column; align-items: flex-start; }
  .rooms-nav { width: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  .rooms-cta:hover { transform: none; }
  .rooms-progress i { transition: none; }
}
