/* =========================================================================
   Rickpoint — portal
   Portado del Home v4. Un solo mundo visual: fondo tinta, texto arena, oro
   como único acento. La fotografía entra en tarjetas, nunca de fondo.
   ========================================================================= */

:root {
  --ink:      #0D131E;   /* fondo. El manual pide #111827; el teaser lo oscureció */
  --navy:     #111827;   /* el marino del manual, como superficie secundaria */
  --ink-soft: #141C2A;
  --cream:    #EDE6D6;
  --cream-2:  rgba(237, 230, 214, .68);
  /* .62 y .56 son el piso para cumplir AA (4.5:1) sobre el fondo tinta:
     con .50 y .45 las etiquetas de 10px se quedaban en 4.48 y 3.86. */
  --cream-3:  rgba(237, 230, 214, .62);
  --cream-4:  rgba(237, 230, 214, .56);
  --gold:     #C9A15A;
  --rule:     rgba(237, 230, 214, .18);
  --rule-2:   rgba(237, 230, 214, .14);

  --display: 'Jost', ui-sans-serif, system-ui, sans-serif;
  --body:    'Mulish', ui-sans-serif, system-ui, sans-serif;
  --ease:    cubic-bezier(.16, 1, .3, 1);

  /* Contenedor y margen únicos para todas las plantillas.
     1680 dejaba el texto flotando: con una medida de lectura de 60ch, media
     pantalla quedaba vacía a la derecha y el ojo no encontraba ningún eje.
     1440 con margen de 64 es el contenedor de la revisión de retícula. */
  --pad:   64px;
  --shell: 1440px;

  /* Área de protección del logotipo ---------------------------------------
     El manual pide «conservar un área de protección alrededor del logotipo
     para que respire visualmente». Hasta ahora no existía en ninguna parte:
     la cabecera lo separaba con un gap genérico y el pie no lo separaba de
     nada.

     El módulo no se inventa, se mide en el propio dibujo: es el grosor del
     trazo del símbolo, que en el maestro (920×648) es de 43px y coincide al
     píxel con el ancho de la torre dorada —la única pieza sólida de la marca
     y la que le da el nombre—. Se elige ése y no la torre entera porque es la
     medida que sobrevive a las dos piezas: en el monograma la torre aparece
     recortada por el encuadre, pero el trazo es el mismo dibujo. Como
     fracción de cada pieza:
         monograma (300×277, trazo 27.5) → 1/10 del alto
         logotipo  (920×648, trazo 43)   → 1/21 del ancho

     El área son dos módulos. El criterio es que el aire de fuera nunca puede
     ser menor que el de dentro, o el logotipo deja de leerse como una unidad:
     la mayor separación interna del maestro es la del símbolo con «RICK
     POINT», 61px = 1.42 módulos. Dos lo cubre y deja número redondo.

     Es un mínimo, no una medida fija: donde el ritmo de la página ya da más
     aire manda el mayor, de ahí los max() de las reglas de abajo. */
  --logo-alto:   46px;                          /* monograma: cabecera y pie */
  --logo-modulo: calc(var(--logo-alto) / 10);
  --aire-logo:   calc(var(--logo-modulo) * 2);

  /* El logotipo completo del hero se gobierna por ancho, no por alto, así que
     su módulo se saca de la otra fracción del maestro. */
  --logo-hero:        clamp(220px, 30vw, 460px);
  --logo-hero-modulo: calc(var(--logo-hero) / 21);
  --aire-logo-hero:   calc(var(--logo-hero-modulo) * 2);

  /* Alto de la cabecera: el monograma, su área de protección arriba y abajo
     —que nunca baja de los 16px del ritmo— y 1px de filo. Da los mismos 79px
     de siempre, pero ahora sale de la regla en vez de estar copiada a mano:
     si el logo cambia de alto, la cabecera lo sigue. */
  --header-pad: max(16px, var(--aire-logo));
  --header-h:   calc(var(--logo-alto) + var(--header-pad) * 2 + 1px);

  /* Retícula. Doce columnas y un solo gutter para toda la página: antes cada
     sección declaraba su propio auto-fit y su propio gap, y a 1920px convivían
     ocho gutters distintos (36, 40, 44, 48, 56, 80, 90 y 100), varios de ellos
     fraccionarios por venir de vw. Nada se alineaba con nada.

     Dos bandas sobre el mismo módulo: la ancha (12 col) para el cine, el
     buscador y el catálogo; la editorial (10 col) para lo que se lee. La editorial se calcula
     —no se fija— para que la columna mida exactamente igual en las dos:
     10·col + 9·g, con col = (W − 11·g)/12, se reduce a 83.333% − g/6. */
  --gutter: 24px;
  --banda-texto: calc(83.333% - var(--gutter) / 6);

  /* Ritmo vertical. Base de 8: todo lo demás es múltiplo, así que dos bloques
     distintos separados «a ojo» dejan de existir. */
  --ritmo:         8px;
  --ritmo-bloque:  32px;   /* dentro de un bloque */
  --ritmo-bloque2: 48px;   /* entre partes de una sección */
  --ritmo-seccion: 120px;  /* entre secciones */

  /* Medidas de línea. La regla es que ningún texto corrido llega a 12
     columnas: un párrafo a 1440px son 200 caracteres y nadie lee eso. */
  --medida-titulo: 22ch;
  --medida-texto:  58ch;
  --medida-corta:  40ch;
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--cream);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

/* <picture> es sólo un envoltorio de selección de formato: que no interfiera
   en el flex/grid del contenedor. */
picture { display: contents; }

a { color: var(--cream); text-decoration: none; transition: color .4s; }
a:hover, a:focus-visible { color: var(--gold); }

input, select, textarea, button { font-family: inherit; }
:focus-visible { outline: 1px solid var(--gold); outline-offset: 4px; }

.shell { max-width: var(--shell); margin-inline: auto; padding-inline: var(--pad); }

/* ---- Cajas de la retícula -----------------------------------------------
   Tres formas de repartir las doce columnas, y ninguna más. Antes cada sección
   inventaba su propio ancho —68ch aquí, 83% allá, 12 columnas más abajo— y por
   eso la página zigzagueaba: no había ningún eje que se repitiera.

   · Caja A (12 col) — full-bleed: cine, imagen ancha, franja. Tres por página
     como máximo, o deja de ser excepción.
   · Caja B (2 + 10) — etiqueta de sección a la izquierda, contenido a la
     derecha. Es la caja por defecto: la etiqueta en la columna 1 y el
     contenido arrancando en la 3 son el eje vertical de todo el portal.
   · Caja C (5 + 1 + 6) — dos piezas pareadas con una calle vacía en medio:
     texto/imagen, ficha/galería, datos/formulario.

   Las tres se apoyan en la misma rejilla de 12, así que un elemento puede
   cambiar de caja sin salirse del módulo.                                   */

.rp-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
}

/* Caja B — la de por defecto. */
.caja-b > .caja__rotulo    { grid-column: 1 / span 2; }
.caja-b > .caja__contenido { grid-column: 3 / span 10; }

/* Caja C — la calle vacía es la columna 6; nada la cruza. */
.caja-c > .caja__izq { grid-column: 1 / span 5; }
.caja-c > .caja__der { grid-column: 7 / span 6; }

/* El rótulo se alinea con la primera línea del contenido, no con el borde de
   la caja: si no, queda flotando medio renglón por encima. */
.caja__rotulo { padding-top: 4px; }

/* Ritmo entre secciones. Se aplica al contenedor de la página para que dos
   secciones seguidas no dependan de que cada una recuerde su propio margen. */
.ritmo > * + * { margin-top: var(--ritmo-seccion); }


/* ---- Área de protección: quién la lleva ---------------------------------
   Los tres sitios donde hoy se pinta el logotipo declaran aquí su aire, en un
   solo bloque, para que sea una regla del sistema y no un ajuste por sección.
   Cada uno la aplica con la herramienta que le corresponde:

   · la banda de marca centra un logotipo suelto sobre el fondo, así que
     reserva el área como relleno propio: nada puede entrar en ella y, si la
     columna se queda corta, encoge el logotipo antes que el aire;
   · la cabecera y el pie meten el monograma en una retícula compartida, y ahí
     el área se cobra sobre las separaciones (gap, padding, margen del texto
     que va debajo). Si se cobrara como relleno, el monograma se despegaría
     unos píxeles del borde de la retícula y dejaría de alinear con la banda de
     marca y con el pie, que es peor incumplimiento que el que se está arreglando.

   Aquí queda el único caso que es sólo área de protección; los otros dos se
   cobran sobre reglas que ya existen y se marcan en su sección con la misma
   variable. Un logotipo nuevo hereda la regla usando --aire-logo (o
   --aire-logo-hero si se dimensiona por ancho), nunca un número suelto. */
.marca__logo { padding: var(--aire-logo-hero); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* El núcleo de WordPress envuelve the_posts_pagination() en un <h2> con esta
   clase («Paginación de entradas»), pensado para quien usa lector de
   pantalla y no para la vista. Sin esta regla salía como un segundo H2
   enorme, visible, debajo de cada catálogo —y debajo del blog, que usa la
   misma función—. Misma técnica que .visually-hidden, con el nombre que
   trae el núcleo de fábrica. */
.screen-reader-text {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.oro { color: var(--gold); }
.num { font-family: var(--display); font-size: 11px; letter-spacing: .2em; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 200;
  letter-spacing: -.03em;
  line-height: 1;
  margin: 0;
  text-wrap: balance;
}
h2 { font-size: clamp(30px, 4.6vw, 68px); }

p { margin: 0 0 1.1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

.eyebrow {
  display: block;
  font-size: 10px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--cream-3);
  margin-bottom: clamp(14px, 1.8vh, 22px);
}

/* ---- Animaciones de entrada --------------------------------------------
   Los estados ocultos sólo aplican con JS, para que la página siga legible
   si el script no corre. */

.js [data-in] {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 1.3s var(--ease), transform 1.3s var(--ease);
}
.js [data-in="1"] { opacity: 1; transform: none; }

/* El .24em de relleno inferior es para los descendentes: la máscara recorta con
   overflow:hidden y con line-height .94 la «g» de «tu lugar?» se cortaba por
   abajo. El margen negativo devuelve exactamente lo que suma el relleno, así
   que el espaciado entre líneas queda igual que antes — sólo cambia dónde
   recorta la caja. */
[data-mask] { display: block; overflow: hidden; padding-bottom: .24em; margin-bottom: -.18em; }
.js [data-mask] > span { display: block; transform: translateY(106%); transition: transform 1.4s var(--ease); }
.js [data-mask="1"] > span { transform: none; }

.js [data-hair] { transform: scaleX(0); transform-origin: left; transition: transform 1.6s var(--ease); }
.js [data-hair="1"] { transform: scaleX(1); }

@keyframes rpDrift  { 0%, 100% { transform: translate3d(0,0,0); } 50% { transform: translate3d(0,-12px,0); } }

/* ---- Deriva del aura -----------------------------------------------------
   Los degradados no se mueven: se mueven las cajas que los contienen.

   Es la única forma de que esto salga gratis. Animar la posición de un
   `radial-gradient` obliga a redibujarlo entero en cada fotograma; animar
   `transform` sobre una capa que el compositor ya tiene guardada es mover una
   textura, y eso ni siquiera pasa por el hilo principal.

   Tres recorridos distintos, deliberadamente primos entre sí en duración:
   ninguno vuelve al mismo sitio a la vez que otro, así que el conjunto no
   repite en varios minutos y no se le ve el bucle. */
@keyframes rpAuraA {
  0%   { transform: translate3d(0, 0, 0)       scale(1); }
  50%  { transform: translate3d(6%, 4%, 0)     scale(1.18); }
  100% { transform: translate3d(0, 0, 0)       scale(1); }
}
@keyframes rpAuraB {
  0%   { transform: translate3d(0, 0, 0)       scale(1.1); }
  50%  { transform: translate3d(-7%, -5%, 0)   scale(1); }
  100% { transform: translate3d(0, 0, 0)       scale(1.1); }
}
@keyframes rpAuraC {
  0%   { transform: translate3d(0, 0, 0)       scale(1); }
  33%  { transform: translate3d(-5%, 6%, 0)    scale(1.14); }
  66%  { transform: translate3d(4%, -4%, 0)    scale(1.06); }
  100% { transform: translate3d(0, 0, 0)       scale(1); }
}
@keyframes rpTicker { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---- Entrada del cine, sin JS y sin opacity ----------------------------
   Estas tres animaciones no tocan opacity a propósito: con `both` el elemento
   ya está pintado durante el retardo, sólo desplazado. Así el primer
   fotograma cuenta para LCP y la métrica deja de esperar a app.js. */

@keyframes rpEntra { from { transform: translateY(16px); } to { transform: none; } }
@keyframes rpSube  { from { transform: translateY(106%); } to { transform: none; } }
@keyframes rpTraza { from { transform: scaleX(0); }        to { transform: scaleX(1); } }

.cine .entra { animation: rpEntra .85s var(--ease) both; animation-delay: var(--d, 0s); }
.cine .traza { transform-origin: left; animation: rpTraza 1.2s var(--ease) both; animation-delay: var(--d, 0s); }

.cine .mask { display: block; overflow: hidden; padding-bottom: .24em; margin-bottom: -.18em; }
.cine .mask > span { display: block; animation: rpSube .8s var(--ease) both; animation-delay: var(--d, 0s); }

@media (prefers-reduced-motion: reduce) {
  .cine .entra, .cine .traza, .cine .mask > span { animation: none; }
}


/* ---- Aura: el ambiente del sitio ----------------------------------------

   Una capa de degradados que deriva despacio por detrás de TODO el sitio. No
   es de una sección: se pinta una sola vez en la cabecera y vale para la
   portada, el catálogo, la ficha, las landings y las páginas interiores.

   Va `fixed`, así que no se desplaza con la página: el contenido pasa por
   delante de una luz que se queda. Es lo que hace que un sitio de fondo plano
   deje de parecer un PDF sin dejar de ser sobrio.

   Tres decisiones:

   · `z-index: -1`. El fondo tinta del `body` se propaga al lienzo del
     documento, no lo pinta el body, así que una capa en -1 queda POR ENCIMA
     del tinta y por debajo de todo el contenido. Con 0 taparía el fondo de
     cualquier sección que no esté posicionada, que son casi todas.
   · `inset: -12%`. La caja es mayor que la ventana porque la deriva la
     desplaza hasta un 7%: si midiera justo, el borde del degradado entraría
     en pantalla por el lado contrario.
   · Sin `filter: blur()`. Un desenfoque a pantalla completa es la operación
     más cara que hay y aquí no hace falta: los degradados radiales ya llegan
     a cero suavemente, y a estas opacidades —del 8 al 16%— no hay bandeado
     que disimular.

   Lo que se mueve son las tres cajas, nunca los degradados. Ver la nota de
   rpAuraA sobre por qué. */

.aura {
  position: fixed;
  inset: -12%;
  z-index: -1;
  pointer-events: none;
  /* El oro de la casa, arriba a la derecha: es el mismo sitio del que sale el
     resplandor del hero, así que al bajar la página la luz parece la misma. */
  background: radial-gradient(42% 38% at 76% 16%,
    rgba(201, 161, 90, .10) 0%, rgba(201, 161, 90, 0) 68%);
  animation: rpAuraA 46s ease-in-out infinite;
}

.aura::before,
.aura::after { content: ""; position: absolute; inset: 0; }

/* El azul es el que da profundidad: sobre tinta plana, un tinte apenas más
   claro y más frío basta para que el fondo deje de leerse como una superficie
   y empiece a leerse como un espacio. */
.aura::before {
  background: radial-gradient(48% 44% at 18% 72%,
    rgba(38, 64, 110, .16) 0%, rgba(38, 64, 110, 0) 70%);
  animation: rpAuraB 61s ease-in-out infinite;
}

/* Y un bronce apagado que cruza por el medio y ata los otros dos: sin él, el
   oro y el azul se quedan en dos esquinas sin nada en medio. */
.aura::after {
  background: radial-gradient(52% 40% at 58% 46%,
    rgba(120, 96, 72, .09) 0%, rgba(120, 96, 72, 0) 72%);
  animation: rpAuraC 73s ease-in-out infinite;
}

/* ---- Cabecera ------------------------------------------------------------ */

/* Pegajosa en todo el sitio. En la portada arranca transparente sobre el cine
   y gana fondo al desplazar; fuera de la portada nace sólida. */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: rgba(13, 19, 30, .9);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--rule-2);
  transition: background .45s, border-color .45s, backdrop-filter .45s;
}
.site-header--overlay {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.site-header--overlay.site-header--fijo {
  background: rgba(13, 19, 30, .9);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--rule-2);
}

/* El gap ya no es un número suelto: es el ritmo de la cabecera con el área de
   protección del monograma por debajo, para que ningún ancho de ventana pueda
   acercarle la navegación más de lo que el manual permite. El padding vertical
   es el mismo que compone --header-h, así que el filete inferior tampoco entra
   en el área. */
.site-header__inner {
  display: flex; align-items: center;
  gap: max(var(--aire-logo), clamp(18px, 3vw, 32px));
  padding-block: var(--header-pad);
}
.brand img { height: var(--logo-alto); width: auto; }

.nav {
  display: flex; gap: clamp(16px, 2.2vw, 36px); margin-left: auto;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
}
.nav a { color: rgba(237, 230, 214, .86); }

.header-cta {
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  border-bottom: 1px solid rgba(237, 230, 214, .4); padding-bottom: 3px;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .nav { display: none; }
  .header-cta { margin-left: auto; }
}

/* ---- Cine: el hero de vídeo ---------------------------------------------

   Mide una pantalla entera y se mete DEBAJO de la cabecera, que es donde el
   vídeo tiene que llegar para que se lea como fondo y no como un recuadro con
   una barra encima.

   La cabecera es `sticky`, o sea que reserva su alto en el flujo. Se le
   devuelve ese alto con un margen negativo y se le vuelve a dar como relleno:
   el lienzo sube hasta el borde de la ventana y el contenido sigue cayendo por
   debajo de la barra. Pasarla a `fixed` habría resuelto lo mismo obligando a
   compensar el hueco en las otras nueve plantillas, que no tienen hero.

   `isolation: isolate` acota el z-index negativo del lienzo a esta sección: sin
   él, un `z-index: -1` se va por detrás del fondo del body y el vídeo
   desaparece. */

.cine {
  position: relative;
  z-index: 0;                 /* la cabecera va en 60 y tiene que seguir ganando */
  isolation: isolate;
  margin-top: calc(var(--header-h) * -1);
  padding-top: var(--header-h);
  padding-bottom: clamp(20px, 3vh, 36px);
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  align-items: center;
  overflow: hidden;
  background: var(--ink);     /* lo que se ve mientras no hay ni plancha ni clip */
}

/* ---- El lienzo ----
   Los cuatro clips y la plancha ocupan exactamente el mismo hueco, apilados.
   `max-width: none` y `height: 100%` pisan la regla global de img/svg/video,
   que los devolvería a su tamaño intrínseco. */

.cine__lienzo { position: absolute; inset: 0; z-index: -1; }

.cine__plancha,
.cine__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; max-width: none;
  object-fit: cover; object-position: center;
}

/* El relevo es un fundido cruzado. El clip que sale NO se pausa hasta que
   termina de irse: pararlo en seco deja su último fotograma congelado a la
   vista durante todo el fundido, que es justo lo que se quiere evitar. */
.cine__video { opacity: 0; transition: opacity 1.1s var(--ease); }
.cine__video--activo { opacity: 1; }

/* La plancha —primer fotograma del clip 1— se retira sólo cuando el vídeo ya
   está pintando de verdad. Si app.js no llega, se queda: el hero es entonces
   una portada quieta, no un rectángulo vacío. */
.cine__plancha { opacity: 1; transition: opacity 1.1s var(--ease); }
.cine--rodando .cine__plancha { opacity: 0; }

/* ---- El velo ----
   Es lo que sostiene el texto, no un efecto. Dos de los cuatro clips son
   interiores blancos a plena luz: sobre ellos el crema de la casa se queda en
   1.1:1 y el titular sencillamente no se lee.

   El degradado carga arriba (donde flota la cabecera), mantiene cuerpo en el
   centro (donde está el H1 y el buscador) y vuelve a cerrar abajo (contra el
   rótulo y los controles). El .58 del centro no es a ojo: sobre el interior
   más claro de los cuatro deja el fondo en ~#656569, y ahí el crema al 88%
   —el que usa .cine__lede— da 4.6:1, por encima del 4.5 que pide AA.

   La viñeta radial es la que evita que el texto centrado quede sobre las
   esquinas, que es donde los clips tienen más luz. */
.cine__velo {
  position: absolute; inset: 0;
  background:
    linear-gradient(to bottom,
      rgba(13, 19, 30, .88) 0%,
      rgba(13, 19, 30, .58) 22%,
      rgba(13, 19, 30, .58) 52%,
      rgba(13, 19, 30, .80) 84%,
      rgba(13, 19, 30, .96) 100%),
    radial-gradient(120% 90% at 50% 45%,
      rgba(13, 19, 30, 0) 0%,
      rgba(13, 19, 30, .5) 100%);
}

/* El resplandor dorado del teaser sobrevive aquí: es lo que impide que el hero
   se vuelva un vídeo de stock con texto encima y siga siendo esta casa.
   `screen` para que sume luz sobre el clip en vez de manchar el velo. */
.cine__brillo {
  position: absolute; inset: 0;
  background: radial-gradient(58% 52% at 76% 20%,
    rgba(201, 161, 90, .18) 0%, rgba(201, 161, 90, 0) 70%);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* ---- El cuerpo ----
   Centrado, a diferencia del hero anterior: sin el logotipo ocupando media
   retícula ya no hay dos columnas que equilibrar, y sobre vídeo el eje central
   es el único sitio donde el velo es igual de fiable a izquierda y derecha. */

.cine__cuerpo {
  position: relative;
  width: 100%; max-width: var(--shell);
  margin-inline: auto; padding-inline: var(--pad);
  text-align: center;
}

/* La sombra es de apoyo, no de estilo: cubre el caso de que un fotograma
   concreto salga más claro que la media sobre la que se calculó el velo. Muy
   difusa y sin desplazamiento para que no se lea como sombra. */
.cine__cuerpo :is(h1, p, .kicker__texto) { text-shadow: 0 2px 24px rgba(13, 19, 30, .55); }

.kicker { display: flex; align-items: center; gap: 16px; margin-bottom: clamp(16px, 2.2vh, 28px); }
.kicker__linea { flex: 0 0 auto; width: clamp(28px, 4vw, 64px); height: 1px; background: var(--gold); }
.kicker__texto { font-size: 11px; letter-spacing: .34em; text-transform: uppercase; color: var(--gold); }

/* Centrado, el rótulo lleva filete a los dos lados. */
.kicker--centro { justify-content: center; }
/* La línea de la derecha se traza hacia fuera, no hacia dentro: las dos salen
   del texto a la vez y el conjunto abre en simetría. */
.cine .traza.kicker__linea--der { transform-origin: right; }

.cine__titulo {
  font-size: clamp(42px, 7.2vw, 104px);
  line-height: .92;
  letter-spacing: -.038em;
  margin-top: clamp(14px, 2vh, 24px);
}

.cine__lede {
  margin: clamp(18px, 2.6vh, 30px) auto 0;
  max-width: 46ch;
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.7;
  /* Más claro que --cream-2 a propósito: sobre tinta plana .68 cumple de
     sobra, pero sobre el velo del vídeo se queda corto. */
  color: rgba(237, 230, 214, .88);
}

/* El buscador vuelve a alinear a la izquierda —son etiquetas de formulario, no
   un eslogan— y se apoya en un panel propio: sobre vídeo, cuatro selectores
   sueltos con sólo su filete inferior pierden el borde y dejan de leerse como
   un bloque. Sin radio, como todo en la casa. */
.cine .buscador {
  margin-top: clamp(26px, 4vh, 52px);
  text-align: left;
  padding: clamp(16px, 2.2vh, 24px) clamp(16px, 2vw, 26px);
  background: rgba(13, 19, 30, .46);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
  backdrop-filter: blur(16px) saturate(120%);
  border: 1px solid rgba(237, 230, 214, .16);
}

/* ---- El pie: rótulo y controles ---- */

.cine__pie {
  position: relative;
  width: 100%; max-width: var(--shell);
  margin-inline: auto; padding-inline: var(--pad);
  padding-top: clamp(16px, 2.4vh, 28px);
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}

.cine__rotulo {
  margin: 0;
  font-family: var(--display); font-weight: 300;
  font-size: 11px; letter-spacing: .28em; text-transform: uppercase;
  color: var(--cream-3);
  transition: opacity .45s var(--ease);
}
/* Se apaga durante el relevo y vuelve con el texto ya cambiado: sin esto el
   rótulo salta de un clip al siguiente antes de que la imagen lo haya hecho. */
.cine__rotulo[data-mudando] { opacity: 0; }

/* Sin vídeo no hay nada que mandar: con movimiento reducido o ahorro de datos
   app.js retira los controles en vez de dejar botones que no hacen nada. */
.cine--quieto .cine__mando { display: none; }

.cine__mando { display: flex; align-items: center; gap: clamp(16px, 2vw, 28px); }
.cine__barras { display: flex; gap: 8px; }

/* La caja mide 44px de alto útil aunque la línea sea de 1px: es un control y
   tiene que poder tocarse en un teléfono. */
.cine__barra {
  position: relative;
  width: clamp(26px, 4.6vw, 52px); height: 44px;
  padding: 0; border: 0; background: none; cursor: pointer;
}
.cine__barra::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: 1px; background: rgba(237, 230, 214, .3);
}
/* El avance lo escribe app.js con el tiempo real del vídeo. Si la red se
   atasca, el indicador se atasca con ella en vez de seguir corriendo solo. */
.cine__barra-avance {
  position: absolute; left: 0; top: 50%;
  width: 0; height: 1px; background: var(--gold);
  transition: width .3s linear;
}
.cine__barra:hover::before,
.cine__barra:focus-visible::before { background: rgba(237, 230, 214, .55); }

/* Pausa. No es un extra: un vídeo que arranca solo y dura más de cinco
   segundos tiene que poder pararse (WCAG 2.2.2). El icono se dibuja con
   bordes —dos barras o un triángulo— para no meter un SVG por 11px. */
.cine__pausa {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 0;
  border: 0; background: none; cursor: pointer;
  font-family: var(--display); font-weight: 300;
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--cream-3);
  transition: color .4s;
}
.cine__pausa:hover, .cine__pausa:focus-visible { color: var(--gold); }

.cine__pausa-icono {
  width: 9px; height: 11px;
  border-left: 3px solid currentColor;
  border-right: 3px solid currentColor;
}
.cine__pausa[aria-pressed="true"] .cine__pausa-icono {
  width: 0; height: 0;
  border-left: 10px solid currentColor;
  border-right: 0;
  border-top: 5.5px solid transparent;
  border-bottom: 5.5px solid transparent;
}

/* ---- Marca: lo que antes era el hero entero -----------------------------

   Se queda con lo que sólo sabe decir la marca —el logotipo grande sobre tinta
   con el resplandor dorado, dónde se opera y a qué hora— y suelta lo que se
   llevó el cine: el titular y el buscador. Ya no mide una pantalla; es una
   banda. Ése es todo el «simplificar».

   Como el logotipo dejó de competir por el mismo pliegue que el H1 y el botón
   de buscar, aquí puede ir a su tamaño sin apretar nada. */

.marca { position: relative; padding-block: clamp(56px, 9vh, 110px); overflow: hidden; }

.marca__glow {
  position: absolute; top: -55%; right: -14%;
  width: min(820px, 88vw); aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(201, 161, 90, .15) 0%, rgba(201, 161, 90, 0) 68%);
  pointer-events: none;
}

.marca__inner {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: center;
}

.marca__logo { grid-column: 1 / span 5; display: flex; justify-content: center; }
.marca__logo img {
  width: min(100%, var(--logo-hero));
  animation: rpDrift 12s ease-in-out infinite;
}

.marca__copia { grid-column: 7 / span 6; max-width: 640px; }

.sector { display: flex; align-items: center; gap: clamp(14px, 2vw, 28px); margin-top: clamp(18px, 2.6vh, 32px); }
.sector__texto {
  font-size: clamp(10px, 1vw, 13px); letter-spacing: .42em; text-transform: uppercase;
  color: rgba(237, 230, 214, .7); white-space: nowrap;
}
.sector__linea { flex: 1 1 60px; height: 1px; background: rgba(237, 230, 214, .28); }

.marca__frase {
  margin: 0;
  font-family: var(--display); font-weight: 200;
  font-size: clamp(21px, 2.2vw, 32px);
  line-height: 1.32; letter-spacing: -.022em;
  max-width: 30ch;
}

/* ---- Buscador ------------------------------------------------------------ */

.buscador {
  position: relative;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: end;
  border-top: 1px solid var(--rule);
  padding-top: clamp(18px, 2.6vh, 28px);
}
/* El ancho de cada filtro sale de lo que tiene que caber dentro: «Todas las
   zonas» necesita más sitio que «Venta». Eso es lo que auto-fit no sabe hacer.

   `position: relative` porque el campo pasa a llevar su propio filete inferior
   en ::after, como los del formulario: sin una línea que cierre la caja, un
   selector de 44px sin borde se lee como texto suelto y no como un control. */
/* Seis filtros en dos filas de tres cuartos de ancho: operación, tipo, zona y
   presupuesto arriba; recámaras y baños abajo, con la fila de acción a su lado. */
.buscador__campo { position: relative; display: flex; flex-direction: column; gap: 7px; grid-column: span 3; }
.buscador__label { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--cream-4); }

/* La zona activa tiene que ser la caja, no el renglón: a 18px de Jost el
   selector medía 24px de alto y sólo respondía sobre las letras. Los 44px van
   en `min-height` y no en `height` para que un sistema con la tipografía
   ampliada pueda crecer por encima, nunca por debajo. */
.buscador select, .catalogo-orden select {
  appearance: none; border: 0; border-radius: 0; background: transparent;
  min-height: 44px; width: 100%;
  padding: 0 26px 0 0; cursor: pointer;
  font-family: var(--display); font-size: 18px; font-weight: 300; color: var(--cream);
  background-image: linear-gradient(45deg, transparent 50%, var(--gold) 50%),
                    linear-gradient(135deg, var(--gold) 50%, transparent 50%);
  background-position: right 7px center, right 2px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.buscador select option, .catalogo-orden select option { background: var(--ink); color: var(--cream); }

/* La palabra clave: renglón propio, con la misma voz que los selectores. */
.buscador .buscador__campo--texto { grid-column: 1 / -1; }
.buscador input[type="search"] {
  appearance: none; border: 0; border-radius: 0; background: transparent;
  min-height: 44px; width: 100%; padding: 0;
  font-family: var(--display); font-size: 18px; font-weight: 300; color: var(--cream);
}
.buscador input[type="search"]::placeholder { color: var(--cream-4); }
.buscador input[type="search"]:focus { outline: none; }

/* La fila de acción cierra la retícula del buscador. Se permite el salto de
   renglón para que «Limpiar» baje en vez de estrechar al botón cuando las dos
   columnas se quedan cortas. */
.buscador__acciones {
  grid-column: 7 / -1;
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px 20px;
}

/* El buscador de la PORTADA sólo lleva 4 filtros (recámaras y baños viven en el
   catálogo) y tiene que caber en UNA fila que cierre el cine justo en «Buscar».
   El del catálogo lleva 6 y usa el reparto por defecto de arriba (dos filas).
   Sólo a partir de 1200px: por debajo, ambos apilan a dos por renglón y estas
   reglas no deben pisar ese apilado. */
@media (min-width: 1200px) {
  .cine .buscador__campo:nth-of-type(1),
  .cine .buscador__campo:nth-of-type(2) { grid-column: span 2; }
  .cine .buscador__campo:nth-of-type(3),
  .cine .buscador__campo:nth-of-type(4) { grid-column: span 3; }
  .cine .buscador__acciones { grid-column: 11 / span 2; }
}

/* EL primario del sitio. Es el único CTA sólido de arriba del pliegue porque
   buscar es lo que mueve el catálogo: todo lo demás de la portada —«Ver la
   selección», «Ver catálogo completo», «Quiero comercializar»— navega, y esto
   filtra. Reutiliza .btn-oro (el mismo sólido de «Enviar») en lugar de abrir
   un segundo botón: en toda la casa hay una sola forma de decir «pulsa aquí».
   Aquí sólo se corrige lo que cambia por vivir en dos columnas: relleno
   lateral elástico y sin partir la etiqueta en dos renglones. Se escribe con
   las dos clases porque .btn-oro se declara más abajo en el archivo y su
   `padding` en atajo pisaría al `padding-inline` de aquí. */
.buscador__enviar.btn-oro {
  flex: 1 1 auto;
  padding-inline: clamp(16px, 1.8vw, 30px);
  white-space: nowrap;
}

.buscador__limpiar {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--cream-4);
}

.filtros-resumen { padding-top: 20px; font-size: 13px; color: var(--cream-3); }

/* ---- Ticker -------------------------------------------------------------- */

.ticker { border-top: 1px solid var(--rule-2); border-bottom: 1px solid var(--rule-2); overflow: hidden; }
.ticker__pista { display: flex; width: max-content; animation: rpTicker 44s linear infinite; }
.ticker__set {
  display: flex; gap: clamp(24px, 4vw, 56px); padding: 14px clamp(12px, 2vw, 28px);
  font-family: var(--display); font-size: 12px; letter-spacing: .26em; text-transform: uppercase;
  color: rgba(237, 230, 214, .42); white-space: nowrap;
}

/* ---- Selección y tarjetas ------------------------------------------------ */

.seleccion { padding-block: clamp(72px, 11vh, 150px); }
.seleccion__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 28px; flex-wrap: wrap; }
/* El margen se recorta en los 15px que el .link-btn ganó de relleno superior
   al crecer a 44px: el enlace se queda donde estaba, la caja no. */
.seleccion__pie { margin-top: clamp(25px, 5vh, 57px); }

.pills { display: flex; gap: 10px; flex-wrap: wrap; }
/* 12px de relleno y no 11: con 11 la píldora medía 43px y se quedaba a un
   pixel del mínimo táctil. Aquí la caja ya era el objetivo, sólo faltaba alto. */
.pill {
  display: inline-flex; align-items: center;
  min-height: 44px;
  border: 1px solid rgba(237, 230, 214, .28);
  padding: 12px 20px;
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(237, 230, 214, .85);
  transition: background .35s, color .35s, border-color .35s;
}
.pill:hover, .pill:focus-visible { border-color: var(--gold); color: var(--gold); }
.pill--activa { background: var(--gold); border-color: var(--gold); color: var(--navy); }
.pill--activa:hover { color: var(--navy); }

/* Secundarios de la casa. La caja llega a 44px por arriba y por abajo del
   renglón, y el filete se queda a
   10px del texto en vez de a media altura. */
.link-btn {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 15px 0 10px;
  font-size: 11px; letter-spacing: .26em; text-transform: uppercase;
  border-bottom: 1px solid rgba(237, 230, 214, .35);
}

.grid-props {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* El hueco entre filas ya no puede ser el gutter. Cada tarjeta derrama su
     luz unos 50px por arriba y por abajo, y con 24px de separación la luz de
     la fila de abajo entraba en el precio de la de arriba: dos colores
     distintos mezclándose sobre el texto. Con este aire cada tarjeta se queda
     con la suya, y de paso la retícula respira, que a 24px iba apretada. */
  column-gap: var(--gutter);
  row-gap: clamp(48px, 6vh, 84px);
  margin-top: clamp(36px, 5vh, 68px);
}

/* span 4 fijo: tres por fila en todo el escritorio. Con auto-fit saltaba a
   cuatro columnas a partir de 1508px y las seis destacadas quedaban 4+2. */
.card {
  grid-column: span 4;
  display: flex; flex-direction: column;
  /* Los dos hacen falta para la luz y van aquí, no en el carrusel: la tarjeta
     es la misma en el catálogo y en las taxonomías, y sin `relative` el
     resplandor se colgaría del primer ancestro posicionado que encontrase
     —que no es la tarjeta— y aparecería en otro sitio de la página. */
  position: relative;
  isolation: isolate;
}
.card__media {
  position: relative; display: block;
  /* 3:2 y no 4:3: las fotos entran a 16:9 y el marco cuadrado se comía un
     cuarto del encuadre por arriba y por abajo. */
  width: 100%; aspect-ratio: 3 / 2;
  overflow: hidden; background: var(--ink-soft);
}
.card__enlace { display: block; width: 100%; height: 100%; }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.4s var(--ease); }
.card__media:hover img { transform: scale(1.05); }

/* Abre el visor sin salir del listado. Va fuera del enlace de la tarjeta. */
.card__zoom {
  position: absolute; right: 12px; bottom: 12px;
  display: flex; align-items: center; gap: 7px;
  background: rgba(13, 19, 30, .78); border: 1px solid var(--rule);
  color: var(--cream); padding: 8px 12px; cursor: zoom-in;
  font-family: var(--body); font-size: 12px; line-height: 1;
  opacity: 0; transform: translateY(6px);
  transition: opacity .3s, transform .3s, border-color .3s, color .3s;
}
.card__zoom-n { font-variant-numeric: tabular-nums; letter-spacing: .06em; }
.card:hover .card__zoom,
.card__zoom:focus-visible { opacity: 1; transform: none; }
.card__zoom:hover { border-color: var(--gold); color: var(--gold); }

/* En táctil no hay hover: el botón se queda visible. */
@media (hover: none) {
  .card__zoom { opacity: 1; transform: none; }
}

.card__marca {
  position: absolute; top: 14px; left: 14px;
  background: rgba(13, 19, 30, .82); color: var(--cream);
  font-size: 10px; letter-spacing: .22em; text-transform: uppercase;
  padding: 7px 12px;
}
.card__marca--alerta { background: var(--gold); color: var(--navy); }
/* Vendida o rentada: se queda a la vista como logro, no como oferta. La foto
   pierde color y el precio se apaga para que nadie la confunda con inventario. */
.card__marca--cerrada { background: var(--cream); color: var(--navy); }
.card--cerrada .card__media img { filter: grayscale(.7); }
.card--cerrada .card__precio { color: var(--cream-3); }

.card__fila { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 18px; }
.card__zona { font-size: 10px; letter-spacing: .24em; text-transform: uppercase; color: var(--cream-3); }

.card__titulo {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(19px, 1.7vw, 24px); line-height: 1.25; letter-spacing: -.015em;
  margin: 10px 0 0;
}

/* Dos líneas y no más: con una descripción larga la tarjeta crecería y la
   fila de precios dejaría de alinear con sus vecinas. */
.card__extracto {
  margin: 10px 0 16px;
  font-size: 14px; line-height: 1.55; color: var(--cream-2);
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}

.card__pie {
  margin-top: auto; padding-top: 14px;
  border-top: 1px solid var(--rule);
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
}
/* Aquí vivía «.card__fila + .card__titulo + .card__pie { margin-top: 14px }».
   Ganaba por especificidad al margin-top:auto de arriba y dejaba el precio
   flotando a media tarjeta: en una fila con un título de una línea y otro de
   dos, los filetes quedaban desalineados 32px. El padding-top ya da el aire. */
.card__precio { font-family: var(--display); font-size: clamp(17px, 1.5vw, 22px); font-weight: 300; color: var(--gold); }
.card__meta { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: rgba(237, 230, 214, .55); text-align: right; }

.empty { border: 1px solid var(--rule); padding: clamp(30px, 5vw, 64px); color: var(--cream-2); max-width: 62ch; }

/* ---- La luz -------------------------------------------------------------

   El resplandor que una fotografía derrama sobre lo que tiene alrededor.

   Los dos tonos los pone el HTML —--luz y --luz-2, sacados de la propia foto
   en rp_luz()—; esta regla decide cómo iluminan. Así el mismo componente vale
   para una tarjeta del carrusel, para la ficha de la propiedad y para el
   bloque de Nosotros, y añadirlo a un sitio nuevo es una línea.

   El contenedor tiene que traer `position: relative` y `isolation: isolate`.
   Lo segundo no es opcional: con z-index -1 y sin contexto de apilamiento
   propio, la luz se va por detrás del fondo del documento y no se ve nada.

   Los valores por defecto son el oro de la casa: una tarjeta sin foto, o el
   tema funcionando sin el plugin, siguen iluminando: con el color de la marca
   en vez de con el de una fotografía que no existe. */

.luz {
  position: absolute;
  /* El sangrado lateral es corto a propósito: con -22px las luces de tres
     tarjetas se tocaban y la fila entera se leía como una niebla de color en
     vez de como tres focos. Cada tarjeta tiene que quedarse con la suya. */
  inset: -48px -12px -34px;
  z-index: -1;
  pointer-events: none;

  /* Dónde van los focos lo decide qué se ve, no qué queda bonito en el
     inspector: la fotografía es opaca y ocupa los dos tercios de arriba, así
     que un foco centrado en la tarjeta queda tapado entero y la luz parece
     apagada. Los dos van al borde —uno arriba, derramándose por encima de la
     foto; otro abajo, sobre el bloque de texto— que es por donde de verdad
     sale la luz de una imagen. */
  background:
    radial-gradient(54% 36% at 30%  3%, rgb(var(--luz,   201 161 90) / .8), transparent 72%),
    radial-gradient(58% 40% at 74% 92%, rgb(var(--luz-2, 138 107 52) / .7), transparent 74%);

  /* El desenfoque no es para difuminar —los degradados ya llegan a cero antes
     del borde—, es contra el bandeado: una transición tan larga y tan tenue en
     8 bits se ve a escalones en pantallas buenas. */
  filter: blur(32px);
  /* Esto es luz ambiente, no un foco: tiene que notarse que la tarjeta está
     iluminada por su foto sin que el color llegue a leerse como una capa de
     color puesta encima. En cuanto se pasa de ~.4 deja de parecer luz. */
  opacity: .38;
  transition: opacity .7s var(--ease);
}

/* Cualquier caja que quiera luz y no pueda llevarla dentro —porque recorta—
   se envuelve en esto. Es todo lo que hace falta para llevar el recurso a un
   sitio nuevo: el marco, un <span class="luz"> y las dos variables. */
.luz-marco { position: relative; isolation: isolate; }

/* Para bloques grandes —la foto de la ficha a 21:9, el retrato de Nosotros—.
   La misma luz con los valores de una pieza que mide el triple: se derrama
   más lejos, se difumina más y pesa menos, porque sobre una superficie grande
   la misma opacidad se lee como un filtro de color encima de la página. */
.luz--amplia {
  inset: -72px -44px -60px;
  filter: blur(54px);
  opacity: .26;
}

/* La luz responde al puntero: la tarjeta que se está mirando se enciende. Es
   el único uso de color de la retícula, así que conviene que signifique algo. */
.card:hover > .luz,
.card:focus-within > .luz { opacity: .62; }

/* Y el bloque de texto se apoya en un lavado del mismo color, de arriba a
   abajo. Es lo que hace que la tarjeta parezca iluminada por su propia foto y
   no un rectángulo con un halo detrás. */
.card { background: linear-gradient(to bottom, transparent 0 56%, rgb(var(--luz, 201 161 90) / .055) 100%); }

/* Y el mismo color remata la fotografía con un filo de un píxel. Es lo que
   ata el resplandor a la imagen: sin él, la luz parece estar detrás de la
   tarjeta en vez de salir de la foto. */
.card__media { box-shadow: inset 0 0 0 1px rgb(var(--luz, 201 161 90) / .11); }
.card:hover .card__media { box-shadow: inset 0 0 0 1px rgb(var(--luz, 201 161 90) / .3); }
.card__media { transition: box-shadow .5s var(--ease); }

/* El filete que separa el precio también se tiñe: es el borde interno de la
   tarjeta y en gris neutro cortaba en seco un bloque que ya venía coloreado. */
.card__pie { border-top-color: rgb(var(--luz, 201 161 90) / .2); }

@media (prefers-reduced-motion: reduce) {
  .luz { transition: none; }
}

/* ---- Carrusel de la selección -------------------------------------------

   Una fila que se desplaza, hecha con `overflow-x` y `scroll-snap`. Sin
   librería y sin JavaScript obligatorio: el navegador ya sabe desplazar con
   el dedo, con la rueda y con el teclado, y el ajuste por tarjeta lo da el
   CSS. app.js sólo añade las flechas y el riel de avance, que es comodidad.

   `overflow-x: auto` obliga al eje vertical a recortar también —«visible» se
   convierte en «auto» en cuanto el otro eje no lo es—, así que la luz que se
   derrama por arriba y por abajo quedaría cortada. El relleno vertical le hace
   sitio y el margen negativo devuelve la sección a su ritmo. */

/* El sangrado lateral existe para que la luz de la primera y la última
   tarjeta no se corten contra el borde del contenedor con scroll. Nunca pasa
   del relleno de la sección, así que en el teléfono no empuja nada fuera de
   la pantalla. */
.carrusel { position: relative; margin-top: clamp(36px, 5vh, 68px); --sangria: min(40px, var(--pad)); }

.carrusel__pista {
  display: flex;
  gap: var(--gutter);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* El relleno va por fuera de la caja de contenido, así que las tarjetas
     siguen midiendo lo mismo y la primera sigue alineada con «Selección»: el
     margen negativo devuelve exactamente lo que añade el relleno.
     Los 96px de arriba y abajo no son un número redondo: son los 48 que la luz
     se sale de la tarjeta más los 32 que le añade el desenfoque, con holgura.
     Con menos, el recorte del contenedor con scroll corta el resplandor en una
     línea horizontal perfectamente recta que se ve desde la otra punta. */
  padding: 96px var(--sangria);
  margin: -96px calc(var(--sangria) * -1);
  scroll-padding-inline: var(--sangria);

  /* La barra del sistema partiría la fila por abajo y aquí ya hay un riel que
     dice lo mismo mejor. El scroll sigue existiendo: sólo se esconde su
     dibujo. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.carrusel__pista::-webkit-scrollbar { display: none; }

/* La pista es enfocable —es lo que hace que se pueda recorrer con el teclado—
   y el anillo tiene que verse sin que el relleno negativo lo esconda. */
.carrusel__pista:focus-visible { outline-offset: -4px; }

/* Tres por vista en escritorio. El `grid-column` de la retícula se anula: la
   misma tarjeta sirve en el catálogo (retícula de 12) y aquí (fila flexible). */
.carrusel .card {
  grid-column: auto;
  flex: 0 0 calc((100% - var(--gutter) * 2) / 3);
  scroll-snap-align: start;
}

/* ---- Mando: riel de avance y flechas ---- */

.carrusel__mando {
  display: flex; align-items: center; gap: clamp(20px, 3vw, 40px);
  margin-top: clamp(22px, 3vh, 34px);
}
.carrusel__mando[hidden] { display: none; }

.carrusel__riel { position: relative; flex: 1 1 auto; height: 1px; background: var(--rule-2); }
.carrusel__pulgar {
  position: absolute; left: 0; top: 0; height: 1px;
  width: 0; background: var(--gold);
  transition: width .25s var(--ease), transform .25s var(--ease);
}

.carrusel__flechas { display: flex; gap: 8px; }

/* 44px de caja aunque la flecha mida 14: es un control. */
.carrusel__flecha {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--rule);
  color: var(--cream); font-size: 15px; line-height: 1;
  transition: border-color .35s, color .35s, opacity .35s;
}
.carrusel__flecha:hover:not(:disabled),
.carrusel__flecha:focus-visible { border-color: var(--gold); color: var(--gold); }

/* En el extremo la flecha se apaga en vez de desaparecer: si se fuera, la otra
   saltaría de sitio en cada extremo de la fila. */
.carrusel__flecha:disabled { opacity: .3; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .carrusel__pista { scroll-behavior: auto; }
  .carrusel__pulgar { transition: none; }
}

@media (max-width: 1199px) {
  /* Dos por vista, y la segunda entera: a tres, la tarjeta bajaba de 300px y
     el título de dos líneas se comía la mitad. */
  .carrusel .card { flex-basis: calc((100% - var(--gutter)) / 2); }
}

@media (max-width: 899px) {
  /* Una por vista y un pico de la siguiente. El pico no es estética: es lo
     único que dice que la fila sigue, y sin él la mitad de la gente no
     descubre que hay seis. */
  .carrusel .card { flex-basis: 82%; }
  .carrusel__pista { padding-block: 80px; margin-block: -80px; }
}


/* ---- Nosotros ------------------------------------------------------------ */

/* Translúcido, no opaco. En sólido, esta sección era el único rectángulo del
   sitio donde el aura desaparecía de golpe, y se notaba precisamente por eso:
   la banda de color se cortaba en línea recta arriba y abajo. */
.nosotros { background: rgba(17, 24, 39, .82); }
.nosotros__grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
  padding-block: clamp(72px, 11vh, 150px);
}
/* Sin imagen el texto ocupa el ancho completo; con ella, 1–6 y 8–12. */
.nosotros__grid > * { grid-column: 1 / -1; }
.nosotros__media { grid-column: 1 / span 6; position: relative; }
.nosotros__foto  { position: relative; overflow: hidden; }
.nosotros__media + * { grid-column: 8 / span 5; }
/* Era 3/4. A 1920px eso mostraba un JPG de 1200x675 a 742x989: recortaba el
   58% del encuadre y estiraba el alto un 47%. En 3:2 no hay ampliación. */
.nosotros__media img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
/* Sin velo, el pie caía sobre la zona clara de la foto y desaparecía. */
.nosotros__foto::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 45%;
  background: linear-gradient(to top, rgba(13, 19, 30, .78), rgba(13, 19, 30, 0));
  pointer-events: none;
}
.nosotros__pie {
  position: absolute; z-index: 1; bottom: 18px; left: 18px;
  font-size: 10px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--cream);
}
.nosotros__titulo { font-size: clamp(32px, 4.6vw, 72px); line-height: .98; letter-spacing: -.035em; }
.nosotros__texto {
  font-size: 17px; line-height: 1.85; color: rgba(237, 230, 214, .68);
  margin: clamp(26px, 3.6vh, 44px) 0 0;   /* la pista de 5 columnas ya da 63ch */
}
/* Misión y visión */
.mv {
  /* Vive dentro de .caja__contenido, que ya es la celda de 10 columnas de la
     caja B: aquí sólo hacen falta las dos pistas. */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--ritmo-bloque2) var(--gutter);
}
.mv__bloque { border-top: 1px solid rgba(237, 230, 214, .22); padding-top: 16px; }
.mv__bloque p { max-width: var(--medida-texto); }
.mv__label {
  display: block; margin-bottom: 12px;
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--gold);
}
.mv__bloque p { font-size: 15px; line-height: 1.75; color: rgba(237, 230, 214, .62); margin: 0; }

/* Valores: banda propia bajo el bloque de Nosotros */
.nosotros__valores { padding-bottom: clamp(72px, 11vh, 150px); }
.valores {
  /* Cuatro pistas dentro de la celda de 10 columnas de la caja B. Con siete
     valores la última fila queda a tres: es un final abierto, no un hueco. */
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--ritmo-bloque) var(--gutter);
}
.valor { border-top: 1px solid rgba(237, 230, 214, .22); padding-top: 16px; }
.valor h3, .valor h2 {
  font-family: var(--display); font-weight: 300; font-size: 20px;
  letter-spacing: -.01em; margin: 0 0 10px;
}
.valor p { font-size: 15px; line-height: 1.7; color: rgba(237, 230, 214, .6); margin: 0; }

/* ---- Honorarios ---------------------------------------------------------- */

.honorarios { padding-block: clamp(72px, 11vh, 150px); border-top: 1px solid var(--rule-2); }
.honorarios__grid {
  display: grid;
  max-width: var(--banda-texto);
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
}
.honorarios__grid > :first-child { grid-column: 1 / span 4; }
.honorarios__grid > :last-child  { grid-column: 6 / span 5; }
.honorarios__titulo { font-size: clamp(30px, 5vw, 74px); line-height: 1.04; letter-spacing: -.035em; }
.honorarios__frase {
  margin-top: clamp(22px, 3vh, 34px); max-width: 34ch;
  font-size: 17px; line-height: 1.8; color: rgba(237, 230, 214, .64);
}

.honorarios__prosa { max-width: 46ch; font-size: 16px; line-height: 1.8; color: rgba(237, 230, 214, .64); }
.honorarios__lista {
  list-style: none; margin: clamp(22px, 3vh, 32px) 0 clamp(24px, 3vh, 34px); padding: 0;
}
.honorarios__lista li {
  position: relative; padding: 14px 0 14px 26px;
  border-top: 1px solid var(--rule);
  font-size: 14px; line-height: 1.6; color: rgba(237, 230, 214, .72);
}
.honorarios__lista li::before {
  content: "\2192"; position: absolute; left: 0; top: 14px; color: var(--gold);
}

/* ---- Servicios ----------------------------------------------------------- */

.servicios { padding-block: clamp(72px, 11vh, 150px); }
.servicios__head { margin-bottom: clamp(32px, 4.5vh, 60px); }
.servicios__pie { margin-top: clamp(28px, 5vh, 56px); }
/* ---- Páginas interiores -------------------------------------------------
   Nosotros, Servicios y Contacto sobre la misma retícula. Todo lo de aquí es
   acomodo: color y tipografía siguen siendo los del sistema.               */

.interior { padding-bottom: clamp(64px, 9vh, 120px); }

/* Caja C del intro: la imagen sostiene la altura de la columna de texto. Un
   4:5 vertical y no una panorámica — con una apaisada el texto sobra por
   abajo y vuelve el hueco que se quería quitar. */
/* La imagen se estira a la altura de la columna de texto en vez de imponer su
   propio alto. Con un 4:5 fijo sobre cinco columnas medía 660px contra los
   420px del texto, y volvía el hueco que la caja C venía a quitar. Con
   `object-fit: cover` no se deforma: se recorta. */
.interior__intro { align-items: stretch; }
.interior__media { position: relative; display: flex; flex-direction: column; }
.interior__media img {
  width: 100%; flex: 1 1 auto;
  min-height: 380px;
  object-fit: cover;
  border: 1px solid var(--rule-2);
}
.interior__pie {
  display: block; margin-top: 12px;
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--cream-4);
}

/* Prosa: medida de 58 caracteres y ritmo de 24 entre párrafos. Nunca a 12
   columnas — un párrafo a todo el contenedor son 200 caracteres por línea. */
.prosa {
  display: flex; flex-direction: column; gap: var(--gutter);
  max-width: var(--medida-texto);
}
.prosa p { margin: 0; font-size: 16px; line-height: 1.8; color: var(--cream-2); }
/* El primer párrafo un punto mayor: da jerarquía dentro del cuerpo sin
   necesidad de meter otro título. */
.prosa__entrada {
  margin: 0; max-width: var(--medida-texto);
  font-size: clamp(17px, 1.5vw, 19px); line-height: 1.7; color: var(--cream);
}

/* Cifras al pie de la columna de texto: cierran el bloque. */
.cifras {
  display: grid;
  /* minmax(0, 1fr) y no 1fr a secas: el mínimo implícito de una pista `1fr` es
     su min-content, y «ACOMPAÑAMIENTO» —una sola palabra, en versales y con
     .18em de espaciado— mide 130px. Tres pistas así no caben en los 350px de un
     teléfono, la rejilla crecía, arrastraba al contenedor, y como el body lleva
     `overflow-x: hidden` la página entera aparecía recortada por la derecha.
     El texto cortado estaba tres bloques más arriba que la causa. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter);
  border-top: 1px solid var(--rule); padding-top: 20px; margin-top: 8px;
}
.cifra__n {
  display: block;
  font-family: var(--display); font-weight: 300; font-size: clamp(26px, 2.4vw, 34px);
  line-height: 1;
}
.cifra__et {
  display: block; margin-top: 6px;
  font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--cream-4);
  /* Cinturón además del tirante: si mañana entra una etiqueta más larga, parte
     en vez de volver a empujar el contenedor. */
  overflow-wrap: anywhere;
}

/* Servicios como tabla: la cuadrícula de 1px hace visible la retícula y el
   bloque se lee como una tabla, no como seis tarjetas sueltas. */
.tabla-serv {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--rule-2);
}
.serv { background: var(--ink); padding: 28px 24px 32px; }
.serv__n {
  display: block; margin-bottom: 20px;
  font-size: 11px; letter-spacing: .22em;
}
/* Dos líneas de título en toda la fila: sin esto, las descripciones arrancaban
   a alturas distintas y la tabla se veía descuadrada. */
.serv__titulo {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(19px, 1.8vw, 22px); line-height: 1.25; letter-spacing: -.01em;
  margin: 0 0 12px; min-height: 2.5em;
}
.serv__texto {
  margin: 0; max-width: var(--medida-corta);
  font-size: 15px; line-height: 1.65; color: var(--cream-3);
}

@media (max-width: 899px) {
  .tabla-serv { grid-template-columns: 1fr; }
  /* Apilada, «estirarse a la altura del texto» no quiere decir nada: vuelve a
     tener su propia proporción. */
  .interior__media img { flex: none; aspect-ratio: 4 / 3; min-height: 0; }
  .serv__titulo { min-height: 0; }
  .cifras { gap: 12px; }
}


.servicio {
  border-top: 1px solid var(--rule);
  padding: clamp(20px, 2.6vh, 34px) 0;
  /* El filete se detiene donde termina el texto: antes cruzaba los 1584px
     completos y seguía 270px más allá del último carácter. */
  max-width: var(--banda-texto);
  display: grid;
  grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: baseline;
  transition: border-color .4s;
}
.servicio:hover { border-top-color: var(--gold); }
.servicio__titulo { grid-column: 1 / span 4; display: flex; gap: 18px; align-items: baseline; }
.servicio__titulo h3 { font-weight: 300; font-size: clamp(22px, 2.4vw, 34px); letter-spacing: -.02em; }
.servicio p { grid-column: 6 / span 5; font-size: 16px; line-height: 1.8; color: rgba(237, 230, 214, .62); margin: 0; }
.servicio__cierre { max-width: var(--banda-texto); border-top: 1px solid var(--rule); }

/* ---- Contacto ------------------------------------------------------------ */

.contacto { border-top: 1px solid var(--rule-2); }
.contacto .shell { padding-block: clamp(72px, 11vh, 150px); }

/* En /contacto/ la sección es el cuerpo de la página, no un cierre: sin filete
   —que ahí no separa de nada— y con los datos y el formulario en el mismo eje
   de la columna 3 que sigue el resto de las interiores. */
.contacto--pagina { border-top: 0; }
.contacto--pagina .shell { padding-top: 0; }
.contacto--pagina .contacto__datos { grid-column: 3 / span 4; }
.contacto--pagina .contacto__datos + * { grid-column: 8 / span 5; }
.contacto__titulo {
  font-size: clamp(34px, 6.4vw, 110px); line-height: .94; letter-spacing: -.04em; max-width: 20ch;
}
.contacto__grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  margin-top: clamp(40px, 6vh, 80px);
}
/* 3 columnas son 372px: la medida que antes forzaba el max-width de 34ch,
   pero ahora llenando su pista en vez de dejar el 54% en hueco. */
.contacto__datos { grid-column: 1 / span 4; display: flex; flex-direction: column; gap: 22px; }
.contacto__datos + * { grid-column: 6 / span 7; }
.contacto__hair { height: 1px; background: rgba(237, 230, 214, .25); }
.contacto__label { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--cream-4); }
.contacto__valor {
  display: block; margin-top: 8px;
  font-family: var(--display); font-weight: 300; font-size: clamp(19px, 1.7vw, 24px);
}
.contacto__valor--sm { font-size: clamp(15px, 1.4vw, 21px); word-break: break-word; }

.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gutter);
  align-content: start;
}
.chips { grid-column: 1 / -1; border: 0; padding: 0; margin: 0; display: flex; gap: 10px; flex-wrap: wrap; }
.chip { cursor: pointer; }
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip span {
  display: inline-block;
  border: 1px solid rgba(237, 230, 214, .28);
  padding: 12px 20px;
  font-size: 11px; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(237, 230, 214, .85);
  transition: all .35s;
}
.chip input:checked + span { background: var(--cream); border-color: var(--cream); color: var(--navy); }
.chip input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 3px; }

.form__campo { display: flex; flex-direction: column; gap: 9px; }
.form__campo--ancho { grid-column: 1 / -1; }
.form input, .form textarea {
  border: 0; border-bottom: 1px solid rgba(237, 230, 214, .28);
  background: transparent; color: var(--cream);
  padding: 8px 0; font-size: 16px; outline: none; resize: vertical;
  transition: border-color .35s;
}
.form input::placeholder, .form textarea::placeholder { color: var(--cream-4); }
.form input:focus, .form textarea:focus { border-bottom-color: var(--gold); }

.form__pie {
  grid-column: 1 / -1;
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; flex-wrap: wrap;
}
.form__legal { font-size: 13px; color: var(--cream-3); max-width: 32ch; line-height: 1.6; }

/* El único botón sólido del sitio, y por eso marca lo primario: «Enviar» del
   formulario, «Buscar» del buscador y la llamada de la ficha. Es inline-flex
   —no inline-block— para poder centrar la etiqueta cuando el botón se estira
   dentro de una fila, y el `min-height` deja el objetivo táctil garantizado
   aunque alguien reduzca el relleno más adelante. */
.btn-oro {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px;
  background: var(--gold); color: var(--navy); border: 0;
  padding: 17px 36px; cursor: pointer;
  font-size: 11px; letter-spacing: .22em; text-transform: uppercase;
  transition: background .35s, color .35s;
}
.btn-oro:hover, .btn-oro:focus-visible { background: var(--cream); color: var(--navy); }

.rp-trampa { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.aviso { grid-column: 1 / -1; border: 1px solid var(--rule); padding: 16px 20px; margin: 0 0 26px; font-size: 15px; }
.aviso--ok { border-color: var(--gold); color: var(--gold); }
.aviso--error { color: var(--cream-2); }

/* ---- Pie ----------------------------------------------------------------- */

.site-footer { border-top: 1px solid var(--rule-2); }
.footer-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: start;
  padding-block: clamp(40px, 6vh, 72px);
}
.footer-grid > * { grid-column: span 3; }
.footer-logo { height: var(--logo-alto); width: auto; }
/* El pie era el sitio donde el monograma no tenía ninguna protección: lo único
   que lo separaba de «(Bienes raíces)» era este margen fijo, que no sabía nada
   del logotipo. Ahora es el mayor entre el ritmo del pie y el área. Por los
   otros tres lados ya está cubierto sin tocar la retícula: el gutter, que es
   quien lo separa de la columna vecina, no baja de 16px en ningún escalón, y
   el padding del pie no baja de 40px; los dos por encima de los 9.2px del
   área. Si algún día el monograma crece, esto hay que volver a mirarlo. */
.footer-tag { font-size: 11px; letter-spacing: .24em; text-transform: uppercase; color: var(--cream-4); margin: max(16px, var(--aire-logo)) 0 0; }
.footer-col { display: flex; flex-direction: column; gap: 11px; font-size: 14px; color: rgba(237, 230, 214, .7); }
.footer-col__titulo { font-size: 11px; letter-spacing: .24em; text-transform: uppercase; color: var(--cream-4); }
.footer-legal { padding-block: 0 40px; font-size: 12px; color: rgba(237, 230, 214, .4); }

/* ---- Catálogo y ficha ---------------------------------------------------- */

.page-head { padding-block: clamp(48px, 7vh, 96px) clamp(24px, 3vh, 40px); }
/* El título se corta a 22 caracteres: a 12 columnas un h1 de dos palabras deja
   media pantalla vacía y deja de leerse como un título. */
.page-head h1 { font-size: clamp(30px, 4.6vw, 64px); max-width: var(--medida-titulo); }
.page-head__texto { margin: clamp(18px, 2.4vh, 28px) 0 0; max-width: 62ch; color: var(--cream-2); }
.page-head__prosa { margin: clamp(18px, 2.4vh, 28px) 0 0; max-width: 68ch; }
.page-head__prosa p { margin: 0 0 1em; font-size: 16px; line-height: 1.8; color: var(--cream-2); }
.page-head__prosa p:last-child { margin-bottom: 0; }
.listado-buscador { padding-bottom: clamp(28px, 4vh, 48px); }

/* El marco no dibuja nada: sostiene la luz, que el propio .prop-hero no puede
   llevar dentro porque recorta a 21:9. */
.prop-hero__marco { position: relative; isolation: isolate; }

/* Es un <button> para que abra el visor también con teclado. */
.prop-hero {
  display: block; width: 100%; padding: 0; border: 0;
  aspect-ratio: 21 / 9; overflow: hidden; background: var(--ink-soft); cursor: zoom-in;
}
.prop-hero img { width: 100%; height: 100%; object-fit: cover; }

/* La ficha se quedó fuera de la tanda que puso la retícula en la portada, y
   arrastraba tres `auto-fit` con gaps propios. Aquí entra al mismo contrato:
   doce columnas siempre, un solo gutter, y lo que cambia por ancho es cuánto
   ocupa cada elemento, nunca el número de pistas. */

.prop-head {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  align-items: end;
  padding-block: clamp(32px, 5vh, 60px) clamp(24px, 3vh, 40px);
}
/* Título y precio no pesan igual: el titular necesita sitio para respirar en
   Jost 68 y el precio es una sola cifra. Ocho y cuatro, no seis y seis. */
.prop-head > *:first-child { grid-column: span 8; }
.prop-head > *:last-child  { grid-column: span 4; }
.prop-head h1 { font-size: clamp(32px, 4.6vw, 68px); }
.prop-price { font-family: var(--display); font-weight: 200; font-size: clamp(30px, 4vw, 52px); letter-spacing: -.03em; color: var(--gold); }

.spec-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  border-top: 1px solid var(--rule);
  padding-top: clamp(20px, 2.6vh, 30px);
}
/* Seis por fila: son como mucho seis especificaciones y así caben en un
   renglón limpio, alineadas con las doce columnas de arriba. */
.spec { grid-column: span 2; }
.spec dt { font-size: 10px; letter-spacing: .26em; text-transform: uppercase; color: var(--cream-4); }
.spec dd { margin: 8px 0 0; font-family: var(--display); font-weight: 300; font-size: 21px; }

.prop-body { max-width: 68ch; padding-block: clamp(32px, 5vh, 64px); color: var(--cream-2); }
.prop-body h3 { color: var(--cream); font-size: 22px; font-weight: 300; margin: 1.6em 0 .5em; }
.prop-body ul { padding-left: 1.1em; }
.prop-body li { margin-bottom: .4em; }

.cta-row {
  display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
  border-top: 1px solid var(--rule); padding-top: clamp(22px, 3vh, 34px);
}

/* ---- Aviso de propiedad no disponible ------------------------------------ */
.prop-aviso {
  border: 1px solid var(--rule); border-left: 3px solid var(--gold);
  padding: 16px 20px; margin-bottom: clamp(20px, 3vh, 32px);
  font-size: 15px; line-height: 1.6; color: var(--cream-2);
}
.prop-aviso strong { color: var(--cream); }

/* ---- Compartir propiedad ------------------------------------------------- */
.prop-share {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding-top: 18px;
}
.prop-share__label { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--cream-4); }
.prop-share__btn {
  border: 1px solid var(--rule); padding: 8px 16px; min-height: 40px;
  display: inline-flex; align-items: center;
  font-size: 13px; color: var(--cream-2); text-decoration: none;
  transition: border-color .3s, color .3s;
}
.prop-share__btn:hover, .prop-share__btn:focus-visible { border-color: var(--gold); color: var(--gold); }
.prop-share__btn--ok { border-color: var(--verde); color: var(--verde); }

/* ---- También podría interesarte ------------------------------------------ */
.relacionadas {
  padding-block: clamp(48px, 7vh, 88px);
  border-top: 1px solid var(--rule-2);
}
.relacionadas__tit {
  font-size: clamp(22px, 3vw, 34px); letter-spacing: -.02em;
  margin-bottom: clamp(24px, 3.5vh, 40px);
}

/* ---- Blog ----------------------------------------------------------------
   Misma tarjeta que .card (catálogo): media, fila, título. .card--articulo
   cambia el precio por un resumen de dos líneas y no necesita la terna ni la
   luz, así que esas piezas simplemente no se imprimen desde la plantilla. */
.grid-blog {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: clamp(36px, 5vh, 56px);
  margin-top: clamp(28px, 4vh, 48px);
}
.card--articulo { grid-column: span 4; }
.card__resumen {
  margin-top: 6px;
  font-size: 14px; line-height: 1.6; color: var(--cream-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.blog-temas { padding-block: clamp(20px, 3vh, 32px) 0; }
.blog-credito {
  padding-top: 8px;
  font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--cream-4);
}

@media (max-width: 900px) {
  .card--articulo { grid-column: span 6; }
}
@media (max-width: 600px) {
  .card--articulo { grid-column: 1 / -1; }
}

/* ---- Ordenar catálogo ---------------------------------------------------- */
.catalogo-orden { display: flex; justify-content: flex-end; margin-bottom: clamp(18px, 2.4vh, 28px); }
.catalogo-orden__campo { display: inline-flex; flex-direction: column; gap: 6px; }

/* ---- Galería y visor a pantalla completa --------------------------------- */

.galeria {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gutter);
  padding-bottom: clamp(32px, 5vh, 56px);
}
/* Tres por fila, la misma cadencia que las tarjetas del catálogo. El gap sube
   de 12 px al gutter de la casa: la galería deja de ser un mosaico aparte y se
   alinea con todo lo demás de la página. */
.galeria__item { grid-column: span 4; }

/* Escalones: los mismos 1199 y 899 del resto del sistema. Nunca se reduce el
   número de pistas, sólo lo que ocupa cada elemento. */
@media (max-width: 1199px) {
  .spec          { grid-column: span 3; }   /* cuatro por fila */
  .galeria__item { grid-column: span 6; }   /* dos por fila */
}

@media (max-width: 899px) {
  .prop-head > *:first-child,
  .prop-head > *:last-child { grid-column: span 12; }
  .spec { grid-column: span 4; }            /* tres por fila */
}

@media (max-width: 599px) {
  /* «Estacionamientos» a 10 px con .26em de tracking no cabe en un tercio de
     un teléfono: en el móvil la ficha baja a dos por fila. */
  .spec          { grid-column: span 6; }
  .galeria__item { grid-column: span 12; }
}
.galeria__item {
  position: relative; display: block; padding: 0; border: 0; background: var(--ink-soft);
  aspect-ratio: 3 / 2; overflow: hidden; cursor: zoom-in;
}
.galeria__item img,
.galeria__item video { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.galeria__item:hover img,
.galeria__item:hover video { transform: scale(1.04); }
.galeria__lupa {
  position: absolute; right: 10px; bottom: 10px;
  width: 32px; height: 32px; display: grid; place-items: center;
  background: rgba(13, 19, 30, .74); color: var(--cream);
  font-size: 14px; line-height: 1;
  opacity: 0; transition: opacity .3s;
}
.galeria__item:hover .galeria__lupa, .galeria__item:focus-visible .galeria__lupa { opacity: 1; }

/* A diferencia de la lupa, el ícono de video no depende de :hover: es lo que
   distingue una miniatura de video de una foto antes de tocarla, no sólo un
   efecto al pasar el mouse. */
.galeria__play {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(13, 19, 30, .28);
}
.galeria__play::after {
  content: '\25B6';
  width: 52px; height: 52px; border-radius: 50%;
  background: rgba(13, 19, 30, .74);
  display: grid; place-items: center;
  padding-left: 4px; /* el triángulo no es visualmente simétrico: sin esto se ve descentrado a la izquierda */
  color: var(--cream); font-size: 16px;
  box-shadow: 0 0 0 1px var(--rule);
}
.galeria__item--video:hover .galeria__play::after { background: var(--gold); color: var(--ink); }

.visor {
  position: fixed; inset: 0; z-index: 200;
  /* dvh y no vh: en el móvil la barra de direcciones se cuenta en vh y el pie
     del visor quedaba debajo de ella. */
  height: 100dvh;
  background: #080C13;              /* opaco: a 97% se transparentaba la cabecera */
  display: none;
  /* minmax(0,1fr) y no 1fr: si no, la fila crece con la foto y se desborda. */
  grid-template-rows: auto minmax(0, 1fr) auto;
}
.visor[open], .visor.abierto { display: grid; }

.visor__barra {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 16px var(--pad);
  font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--cream-3);
}
.visor__cerrar {
  background: transparent; border: 1px solid var(--rule); color: var(--cream);
  width: 44px; height: 44px; font-size: 18px; line-height: 1; cursor: pointer;
  transition: border-color .3s, color .3s;
}
.visor__cerrar:hover { border-color: var(--gold); color: var(--gold); }

/* La foto va posicionada, no centrada por rejilla.
   Antes esto era `display:grid; place-items:center` con la imagen acotada por
   `max-height:100%`, y ese porcentaje no acotaba nada: se resuelve contra una
   pista `1fr`, que es flexible, y el navegador no puede resolverlo sin
   dependencia circular — así que lo trata como `none`. Las fotos horizontales
   se salvaban porque el `max-width` ya las limitaba; las verticales se pintaban
   al triple del alto del marco y sólo se veía una porción.
   Con la imagen absoluta contra el marco, la caja es definida por construcción
   y `object-fit: contain` la encaja entera sin recortar nunca. */
.visor__marco {
  position: relative; min-height: 0; overflow: hidden;
}
.visor__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  margin: 0;
  z-index: 1;
}

.visor__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  /* Por encima de la imagen: sin esto, como en el marco el orden es
     prev → img → next y la imagen es `position:absolute; inset:0`, la flecha
     «anterior» se pintaba DEBAJO de la foto y desaparecía. La «siguiente», que
     va después en el DOM, se salvaba de casualidad. */
  z-index: 2;
  background: rgba(13, 19, 30, .7); border: 1px solid var(--rule); color: var(--cream);
  width: 52px; height: 52px; font-size: 20px; line-height: 1; cursor: pointer;
  transition: border-color .3s, color .3s;
}
.visor__nav:hover { border-color: var(--gold); color: var(--gold); }
.visor__nav--prev { left: max(10px, calc(var(--pad) / 2)); }
.visor__nav--next { right: max(10px, calc(var(--pad) / 2)); }

.visor__pie { padding: 14px var(--pad) 24px; font-size: 13px; color: var(--cream-3); text-align: center; }

body.visor-abierto { overflow: hidden; }

/* ---- Paginación ---------------------------------------------------------- */

.pagination { padding-block: clamp(30px, 4vh, 50px); font-size: 12px; letter-spacing: .18em; text-transform: uppercase; }
.pagination .page-numbers { padding: 8px 12px; color: var(--cream-3); }
.pagination .current { color: var(--gold); border-bottom: 1px solid var(--gold); }

/* ---- Filetes que se dibujan ----------------------------------------------
   «Point» viene del tenis, y de ahí sale el criterio: las líneas no son
   adorno, son trayectorias. Ninguna aparece de golpe — todas se trazan al
   entrar en pantalla, como el bote de la pelota marcando la cancha. Por eso
   se incluyen también las de los enlaces, los campos del formulario y los
   filos del ticker, que antes estaban excluidos.

   Un `border` no se puede animar así, de modo que estas reglas lo sustituyen
   por una línea en ::before/::after que escala en X. Se apoya en el mismo
   data-in que ya lleva cada bloque: sin JS extra. */

.servicio,
.servicio__cierre,
.valor,
.mv__bloque,
.cifra,
.spec-grid,
.buscador,
.card__pie,
.contacto,
.site-footer { position: relative; border-top-color: transparent !important; }

.servicio::before,
.servicio__cierre::before,
.valor::before,
.mv__bloque::before,
.cifra::before,
.spec-grid::before,
.buscador::before,
.card__pie::before,
.contacto::before,
.site-footer::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--rule);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform 1.6s var(--ease), background-color .4s;
  pointer-events: none;
}

/* Con JS arrancan sin trazar… */
.js .servicio::before,
.js .servicio__cierre::before,
.js .valor::before,
.js .mv__bloque::before,
.js .cifra::before,
.js .spec-grid::before,
.js .buscador::before,
.js .card__pie::before,
.js .contacto::before,
.js .site-footer::before { transform: scaleX(0); }

/* …y se trazan cuando el bloque —o su contenedor— entra en pantalla. */
.js [data-in="1"].servicio::before,
.js [data-in="1"].servicio__cierre::before,
.js [data-in="1"].valor::before,
.js [data-in="1"].spec-grid::before,
.js [data-in="1"].buscador::before,
.js [data-in="1"].contacto::before,
.js [data-in="1"] .mv__bloque::before,
.js [data-in="1"] .cifra::before,
.js [data-in="1"] .card__pie::before { transform: scaleX(1); }

.js [data-in="1"].site-footer::before { transform: scaleX(1); }

.servicio:hover::before { background: var(--gold); }

@media (prefers-reduced-motion: reduce) {
  .js .servicio::before,
  .js .servicio__cierre::before,
  .js .valor::before,
  .js .mv__bloque::before,
  .js .cifra::before,
  .js .spec-grid::before,
  .js .buscador::before,
  .js .card__pie::before,
  .js .contacto::before,
  .js .site-footer::before { transform: scaleX(1); transition: none; }
}

/* --- Las que faltaban ------------------------------------------------------
   Filos del ticker, tope de honorarios, tope de la fila de acción en la ficha,
   subrayado de cada campo del formulario y del buscador, y de los enlaces de
   acción. «Buscar» ya no está en la lista: pasó a botón sólido y un filete
   dorado sobre fondo dorado no se ve. */

.ticker,
.honorarios,
.cta-row,
.form__campo,
.link-btn { position: relative; border-color: transparent !important; }

.ticker::before, .ticker::after,
.honorarios::before,
.cta-row::before,
.form__campo::after,
.buscador__campo::after,
.link-btn::after {
  content: "";
  position: absolute; left: 0; right: 0; height: 1px;
  background: var(--rule);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform 1.6s var(--ease), background-color .35s;
  pointer-events: none;
}

.ticker::before, .honorarios::before, .cta-row::before { top: 0; }
.ticker::after, .form__campo::after, .buscador__campo::after,
.link-btn::after { bottom: 0; }

.link-btn::after { background: rgba(237, 230, 214, .35); }
.form__campo::after,
.buscador__campo::after { background: rgba(237, 230, 214, .28); }

.js .ticker::before, .js .ticker::after,
.js .honorarios::before,
.js .cta-row::before,
.js .form__campo::after,
.js .buscador__campo::after,
.js .link-btn::after { transform: scaleX(0); }

.js [data-in="1"].ticker::before,
.js [data-in="1"].ticker::after,
.js [data-in="1"].honorarios::before,
.js [data-in="1"].cta-row::before,
.js [data-in="1"] .form__campo::after,
.js [data-in="1"] .buscador__campo::after,
.js [data-in="1"] .link-btn::after { transform: scaleX(1); }

/* El filo inferior del ticker se traza al revés: la pelota vuelve. */
.ticker::after { transform-origin: right; }

/* El campo enfocado enciende su línea, como el punto que se juega. Vale igual
   para los del buscador: ahí el foco del selector es lo único que dice cuál de
   los cuatro filtros está abierto. */
.form__campo:focus-within::after,
.buscador__campo:focus-within::after { background: var(--gold); }
.form input, .form textarea { border-bottom: 0; }

/* El hover ya no puede tocar el borde (va en transparente): va en la línea. */
.link-btn:hover::after,
.link-btn:focus-visible::after { background: var(--gold); }
.buscador__campo:hover::after { background: rgba(237, 230, 214, .5); }

/* El peloteo: cada servicio se traza desde el lado contrario al anterior. */
.servicio--der::before { transform-origin: right; }

@media (prefers-reduced-motion: reduce) {
  .js .ticker::before, .js .ticker::after,
  .js .honorarios::before,
  .js .cta-row::before,
  .js .form__campo::after,
  .js .buscador__campo::after,
  .js .link-btn::after { transform: scaleX(1); transition: none; }
}

/* Las anclas no deben quedar bajo la cabecera pegajosa. */
[id] { scroll-margin-top: calc(var(--header-h) + 12px); }

/* ---- Movimiento reducido -------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .js [data-in],
  .js [data-mask] > span,
  .js [data-hair] { opacity: 1; transform: none; transition: none; }
  .marca__logo img { animation: none; }
  .ticker__pista { animation: none; width: 100%; }

  /* El aura se queda: es profundidad, no movimiento. Lo que se va es la
     deriva. */
  .aura, .aura::before, .aura::after { animation: none; }

  /* El cine no se reproduce: app.js ni siquiera le pone origen a los clips y
     lo que se ve es la plancha, el primer fotograma del clip 1. Los fundidos
     se quedan sin transición por si el relevo se dispara a mano desde los
     controles del pie. */
  .cine__video, .cine__plancha, .cine__rotulo { transition: none; }
  .cine__barra-avance { transition: none; }
  .card__media:hover img,
  .galeria__item:hover img { transform: none; }
}


/* ---- Retícula: escalones -------------------------------------------------
   Las doce columnas no desaparecen nunca; lo único que cambia es cuánto ocupa
   cada elemento. Así el módulo sigue siendo el mismo en todos los anchos. */

@media (max-width: 1199px) {
  /* Tablet: 8 columnas de contenido sobre el mismo módulo de 12. */
  :root { --gutter: 20px; --pad: 40px; }

  .card  { grid-column: span 6; }
  .valores { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-grid > * { grid-column: span 6; }
  .buscador__campo { grid-column: span 6; }
  .buscador__acciones { grid-column: 1 / -1; }
  /* La fila de acción pasa a ocupar las doce columnas: si el botón siguiera
     estirándose, «Buscar» sería una banda de un metro. Vuelve a medir lo que
     mide su etiqueta, con un mínimo que lo mantenga por encima de los 44px de
     ancho útil. */
  .buscador__enviar { flex: 0 0 auto; min-width: 180px; }
}

@media (max-width: 899px) {
  :root { --gutter: 16px; --pad: 20px; }

  .marca__logo, .marca__copia,
  .nosotros__media, .nosotros__media + *,
  .honorarios__grid > :first-child, .honorarios__grid > :last-child,
  .contacto__datos, .contacto__datos + *,
  .servicio__titulo, .servicio p { grid-column: 1 / -1; }

  .honorarios__grid, .contacto__grid,
  .servicio, .servicio__cierre { max-width: none; }

  .form { grid-template-columns: minmax(0, 1fr); }

  /* En este escalón el logotipo deja de compartir fila con el texto y ocupa
     las doce columnas: por los lados ya no tiene vecino —sólo el relleno de la
     banda— y arriba y abajo el vecino es la fila de al lado. Así que el área se
     cobra sobre el gap de la retícula, como en la cabecera, y no otra vez como
     relleno. El relleno lateral se queda: no mueve nada, porque ahí sobra
     sitio, y mantiene la regla escrita. */
  .marca__inner { row-gap: max(var(--gutter), var(--aire-logo-hero)); }
  .marca__logo  { padding-block: 0; }
  .marca__copia { max-width: none; }
  .marca__frase { max-width: none; }

  /* El cine centrado en el teléfono: el pie pasa a dos renglones y el rótulo
     encabeza, porque los controles tienen que quedar al alcance del pulgar. */
  .cine__pie { flex-direction: column; align-items: stretch; gap: 14px; }
  .cine__mando { justify-content: space-between; }
  .cine__rotulo { text-align: center; }
}

@media (max-width: 599px) {
  .card  { grid-column: 1 / -1; }
  .valores { grid-template-columns: 1fr; }
  .footer-grid > * { grid-column: 1 / -1; }

  /* En el teléfono el botón cierra el bloque a lo ancho, como cualquier envío
     de formulario. Los filtros se quedan a dos por renglón: el cine mide una
     pantalla exacta y cuatro renglones de 44px empujarían «Buscar» por debajo
     del pliegue, que es justo lo que se está arreglando.
     No compite con la barra fija de abajo: aquélla es persistente y su acción
     es WhatsApp; ésta se va con el scroll y lo que hace es filtrar. */
  .buscador__enviar { flex: 1 1 100%; min-width: 0; }
}

/* ---- Migas de pan --------------------------------------------------------
   Sólo presentación: el BreadcrumbList lo sigue imprimiendo el plugin en la
   cabecera. Aquí la ruta se lee como una etiqueta más del sistema —Jost fino,
   versalitas y tracking ancho, igual que .eyebrow y .num—, no como un menú:
   es contexto, no navegación principal, y no debe competir con el H1 que
   viene justo debajo. */

.migas { position: relative; padding-block: clamp(18px, 2.6vh, 30px); }

.migas__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;              /* rutas largas bajan de renglón, no desbordan */
  align-items: baseline;
  gap: 4px 10px;
  font-family: var(--display);
  font-weight: 300;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cream-3);        /* el piso que cumple AA sobre el fondo tinta */
}

.migas__item { display: flex; align-items: baseline; gap: 10px; }

/* El separador es decorativo —va aria-hidden en el marcado— así que puede
   permitirse el oro apagado sin deber contraste de texto. */
.migas__sep { color: rgba(201, 161, 90, .7); }

/* El enlace baja del crema pleno al --cream-3 para no pesar más que el título;
   el hover recupera el oro, como cualquier otro enlace del sitio. */
.migas__enlace { color: var(--cream-3); }
.migas__enlace:hover,
.migas__enlace:focus-visible { color: var(--gold); }

/* La página actual no es enlace: se distingue subiendo a --cream-2. El título
   de una ficha puede ser larguísimo en versalitas, así que se corta con
   puntos suspensivos en vez de arrastrar la ruta tres renglones. */
.migas__texto { color: var(--cream-3); }
.migas__texto--actual {
  color: var(--cream-2);
  max-width: 44ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El filete sigue el criterio de la casa: no es un border —no se puede
   animar— sino una línea en un pseudo que escala en X con el mismo data-in
   del bloque, sin JS extra. Va abajo, cerrando la ruta contra el H1, por eso
   ::after: en este archivo ::before es siempre filete superior. */
.migas::after {
  content: "";
  position: absolute;
  left: var(--pad); right: var(--pad); bottom: 0; height: 1px;
  background: var(--rule-2);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform 1.6s var(--ease);
  pointer-events: none;
}

.js .migas::after { transform: scaleX(0); }
.js [data-in="1"].migas::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .js .migas::after { transform: scaleX(1); transition: none; }
}

@media (max-width: 599px) {
  /* En móvil el tracking ancho es lo primero que hace desbordar la ruta. */
  .migas__lista { font-size: 10px; letter-spacing: .14em; gap: 4px 7px; }
  .migas__item { gap: 7px; }
  .migas__texto--actual { max-width: 22ch; }
}

/* ---- Barra inferior en móvil ---------------------------------------------
   Sustituye a `.nav`, que desaparece por debajo de 900 px. Barra fija y no
   hamburguesa: el sitio es de una sola página —las cuatro anclas caben a la
   vista— y WhatsApp es el canal real del negocio, así que meterlo tras un
   botón sería esconder la conversión.

   Por encima de 900 px no existe: `display: none` la saca también del orden
   de tabulación y del árbol de accesibilidad, no sólo de la vista. */

:root {
  /* Alto real de la barra, sin el margen del iPhone: 54 px de objetivo táctil
     más 1 px de filo, redondeado a 56. Sirve para reservar el hueco del final
     de la página; si cambia el alto, se cambia aquí y en ningún otro sitio. */
  --barra-h: 56px;
}

.barra-movil { display: none; }

@media (max-width: 900px) {

  .barra-movil {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    /* 60, el mismo plano que la cabecera y muy por debajo del 200 del visor:
       cuando la foto se abre a pantalla completa la barra queda debajo. */
    z-index: 60;
    display: grid;
    /* Por columnas automáticas y no `repeat(5, 1fr)`: si algún día entra o
       sale un enlace, la barra se reparte sola. */
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    background: rgba(13, 19, 30, .94);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--rule-2);
    /* El margen de gestos del iPhone se suma como relleno, no se descuenta
       del alto: los objetivos táctiles no se comen ese espacio. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  .barra-movil__enlace {
    display: grid;
    place-items: center;
    align-content: center;
    gap: 5px;
    /* 54 px de alto por un quinto del ancho (64 px en un iPhone SE de 320)
       superan los 44 px mínimos en toda la caja, no sólo en el texto. */
    min-height: 54px;
    padding: 6px 4px;
    color: var(--cream-2);
    text-align: center;
    transition: color .35s var(--ease);
  }

  .barra-movil__enlace svg { width: 21px; height: 21px; display: block; }

  .barra-movil__texto {
    font-family: var(--display);
    /* Cinco etiquetas tienen que caber a 320 px: la más larga
       —«Propiedades»— es la que manda el tamaño. */
    font-size: clamp(8px, 2.5vw, 10px);
    letter-spacing: .12em;
    text-transform: uppercase;
    line-height: 1;
  }

  /* La sección que se está leyendo. La marca la pone app.js con
     aria-current="location", no con una clase: así el estado lo anuncia
     también el lector de pantalla y no vive sólo en el color. */
  .barra-movil__enlace[aria-current] { color: var(--gold); }

  /* WhatsApp va siempre en oro: es el único enlace que sale del sitio y el
     que de verdad cierra la operación. */
  .barra-movil__enlace--wa { color: var(--gold); }

  .barra-movil__enlace:hover,
  .barra-movil__enlace:focus-visible { color: var(--gold); }

  /* El anillo global lleva `outline-offset: 4px` y aquí se saldría de la
     barra por arriba: se mete hacia dentro. */
  .barra-movil__enlace:focus-visible { outline-offset: -4px; }

  /* Hueco al final del documento para que la barra no tape el pie ni el
     renglón legal. Va en `body` y no en `.site-footer` para que valga
     también en el 404 y en las fichas de propiedad. */
  body {
    padding-bottom: calc(var(--barra-h) + env(safe-area-inset-bottom, 0px));
  }

  /* El cine mide una pantalla exacta y termina en el buscador: sin esto la
     barra se comería la fila de «Buscar». El margen negativo que lo mete bajo
     la cabecera sigue puesto, así que aquí sólo se descuenta la barra. */
  .cine {
    min-height: calc(100svh - var(--barra-h));
  }

  /* El visor abre a pantalla completa y bloquea el scroll del cuerpo: la
     barra ahí no navega nada y su fondo translúcido se vería sobre la foto
     en los navegadores sin `backdrop-filter`. Se retira del todo. */
  body.visor-abierto .barra-movil { display: none; }
}

/* Lo único que se mueve es el color del enlace; con movimiento reducido, ni
   eso. */
@media (max-width: 900px) and (prefers-reduced-motion: reduce) {
  .barra-movil__enlace { transition: none; }
}

/* Terna de la tarjeta: el hueco debe leerse como hueco, no como dato. */
.card__dato--vacio { opacity: .55; }
.card__meta-sep    { opacity: .55; margin-inline: .12em; }
.card__meta        { font-variant-numeric: tabular-nums; }

/* ---- Retícula en móvil ---------------------------------------------------
   Va al final del archivo a propósito. Estas reglas tienen la misma
   especificidad que las de los componentes que corrigen (`.mv`, `.rp-12`), y
   una media query no añade peso: si estuvieran arriba, junto a la definición
   de las cajas, cualquier `.mv { grid-template-columns: … }` declarado más
   abajo las pisaría. Pasó: Misión y Visión se quedaban a dos columnas en el
   teléfono, forzaban el ancho del contenedor, y como el body lleva
   `overflow-x: hidden` el resultado no era una barra de scroll sino la página
   entera recortada por la derecha.                                          */

@media (max-width: 899px) {
  /* Una sola columna. Y de verdad una: dejar las doce pistas con `1 / -1`
     encima parece equivalente, pero once gaps de 16px son 176px reservados de
     los 350 útiles de un teléfono. La retícula de 12 es de escritorio. */
  .rp-12 { grid-template-columns: 1fr; }

  .caja-b > .caja__rotulo,
  .caja-b > .caja__contenido,
  .caja-c > .caja__izq,
  .caja-c > .caja__der { grid-column: auto; }

  .caja__rotulo { padding-top: 0; }
  .ritmo > * + * { margin-top: clamp(56px, 12vw, 88px); }

  /* Misión y visión se apilan: a dos pistas cada una quedaba a 20 caracteres. */
  .mv { grid-template-columns: 1fr; }

  .cifras { gap: 12px; }
  .cifra__et { font-size: 9px; letter-spacing: .1em; }

  /* Contacto vuelve al ancho: su eje de la columna 3 es de escritorio. */
  .contacto--pagina .contacto__datos,
  .contacto--pagina .contacto__datos + * { grid-column: 1 / -1; }
}
