/* ==========================================================================
   ARENZA · oportunidades: catálogo (/oportunidades/) y fichas (/oportunidades/<slug>/) · prefijo opo-
   Catálogo (05-11, documento de Iker): cabecera, tres filtros nativos, cuadrícula uniforme (todas las fotos con la
   misma caja), estado vacío con salida y cierre hacia Asesoría privada. Las tarjetas y los filtros los genera
   site/gen/propiedades.py desde site/data/propiedades.json.
   Ficha: momento firma = la placa de la calle clavada en el borde de la foto + el mosaico con «Fig.»; plano con la
   ubicación APROXIMADA (círculo sobre la zona, mapa.js data-area).
   Animadores: GSAP mueve SOLO li.opo-i, .opo-empty, .opo-after y .ftr (FLIP al filtrar); CSS mueve SOLO la opacidad
   de las <img> de .opo-ph (fundido al estar enteras) y la escala del hover. Nunca los dos a la vez.
   ========================================================================== */

/* ---------- 0 · comunes ---------------------------------------------------- */
/* puerta de fuentes: el héroe espera a Cormorant y Switzer (la pone el <head>; tope 1,6 s) */
@media (prefers-reduced-motion: no-preference) {
  html.js:not(.opo-f) .opo-page :is(.opo-ih, .opo-fh, .opo-sel) .enter { animation: none; opacity: 0; }
  /* también oculto: con la máscara a 108 % asoman la tilde de «ó» y el punto de la «i» mientras llegan las fuentes */
  html.js:not(.opo-f) .opo-page :is(.opo-ih, .opo-fh) .enter-lines > span > span { animation: none; transform: translateY(135%); visibility: hidden; }
  /* el titular sube desde el 135 % (no el 108 % del núcleo): con el interlineado del display, las astas y las tildes
     de Cormorant asomaban por la máscara durante el retardo («T . . 1 . .» en la red lenta) */
  .opo-page .opo-ih .enter-lines > span > span { animation-name: opo-rise; }
}
@keyframes opo-rise { from { transform: translateY(135%); } }

/* hueco de foto: color medio de la propia foto mientras llega; la imagen solo se enseña entera */
.opo-ph { position: relative; display: block; overflow: hidden; background-color: var(--ph, var(--paper-2)); }
.opo-ph img { display: block; width: 100%; height: 100%; object-fit: cover; }
html.js .opo-ph:not(.is-ld) img { opacity: 0; }
/* las tarjetas del índice y la de «Siguiente» ya no se revelan con clip-path (asomaban vacías): su foto se pide
   2,5 pantallas antes (data-early, y opo.js a 1.600 px) y, cuando asoman, ya está pintada */
@media (prefers-reduced-motion: no-preference) { .opo-ph img { transition: opacity .7s var(--ease-out); } }
[data-vt-arrived] img { transform: none !important; }
/* la foto que llega por View Transition: el núcleo la pone a opacidad 1; hasta que está entera no se pinta
   (su caja es transparente y debajo sigue la foto de origen) */
html.js [data-vt-arrived].opo-ph:not(.is-ld) img { visibility: hidden; }

.opo-page .count-paren { font-size: .26em; vertical-align: 1.9em; }

/* ---------- 1 · catálogo: cabecera ---------------------------------------- */
.opo-ih { padding-top: calc(var(--hdr-h) + clamp(24px, 4vw, 72px)); padding-bottom: clamp(28px, 3.4vw, 56px); }
/* el núcleo pone `.phero--paper .phero__in { padding: 0 }` y se come el margen lateral de .wrap */
.opo-ih .phero__in { row-gap: 18px; padding-inline: var(--margin); }
.opo-ih__k { margin-top: clamp(0px, 1vw, 12px); }
.opo-ih__t { font-size: clamp(2.875rem, 6.6vw, 7rem); line-height: .94; }
.opo-ih__txt { display: grid; gap: 14px; align-content: end; }
.opo-ih__lead { max-width: 28ch; }
.opo-ih__sub { max-width: 40ch; font-size: var(--fs-sm); line-height: 1.6; }
@media (min-width: 900px) {
  .opo-ih .phero__in { align-items: end; }
  .opo-ih__txt { padding-bottom: .55em; }
}
/* en el teléfono «Inicio / Oportunidades seleccionadas» repite la marca de sección (el BreadcrumbList sigue) */
@media (max-width: 599px) {
  .opo-ih .crumbs { display: none; }
  .opo-ih .phero__in { row-gap: 14px; }
  .opo-ih__txt { margin-top: 6px; }
}

/* ---------- 2 · catálogo: filtros ------------------------------------------
   Tres <select> nativos (rueda en iOS, lista en escritorio, teclado de serie) en una barra a filetes; debajo, el
   contador, «Quitar filtros» (reserva su sitio: visibility) y la moneda. Ninguna caja cambia de tamaño al filtrar. */
.opo-sel { position: relative; padding-bottom: clamp(48px, 6vw, 104px); }
.opo-fil { margin-bottom: clamp(28px, 3.6vw, 56px); }
.opo-fil__bar { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-top: 1px solid var(--ink); border-bottom: 1px solid var(--line); }
.opo-f { position: relative; display: grid; align-content: center; gap: 2px; min-width: 0; min-height: 76px; padding: 12px 14px 8px 0; cursor: pointer; }
.opo-f + .opo-f { padding-left: 16px; border-left: 1px solid var(--line); }
.opo-f--zona { grid-column: 1 / -1; border-bottom: 1px solid var(--line); }
.opo-f--zona + .opo-f { padding-left: 0; border-left: 0; }
.opo-f__l { font: 500 var(--fs-micro)/1.3 var(--sans); letter-spacing: .18em; text-transform: uppercase; color: var(--mute-2); }
/* filtro activo: un punto dorado junto a su nombre */
.opo-f__l::after { content: ""; display: inline-block; width: 5px; height: 5px; margin: 0 0 .15em .7em; border-radius: 50%; background: var(--gold); vertical-align: middle; opacity: 0; }
.opo-f.is-on .opo-f__l::after { opacity: 1; }
.opo-f__s {
  width: 100%; min-height: 44px; margin: 0; padding: 2px 26px 2px 0; border: 0; border-radius: 0; cursor: pointer;
  font: 400 clamp(1.25rem, 1.6vw, 1.5rem)/1.2 var(--serif); font-variant-numeric: lining-nums; color: var(--ink);
  text-overflow: ellipsis; -webkit-appearance: none; appearance: none;
  background: linear-gradient(45deg, transparent 50%, var(--gold-ink) 50% calc(50% + 1px), transparent calc(50% + 1px)) calc(100% - 9px) 52% / 6px 6px no-repeat,
              linear-gradient(-45deg, transparent 50%, var(--gold-ink) 50% calc(50% + 1px), transparent calc(50% + 1px)) calc(100% - 3px) 52% / 6px 6px no-repeat;
}
.opo-f__s:focus { outline: none; }
.opo-f:has(.opo-f__s:focus-visible) { outline: 2px solid var(--gold-ink); outline-offset: -2px; }
@media (hover: hover) and (pointer: fine) { .opo-f__s { transition: color .3s; } .opo-f:hover .opo-f__s { color: var(--gold-ink); } }
.opo-fil__st { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 20px; padding-top: 6px; }
.opo-fil__n { min-height: 44px; padding-block: 10px 8px; font: 300 1.375rem/1.2 var(--serif); font-variant-numeric: lining-nums tabular-nums; color: var(--ink); }
.opo-fil__reset {
  min-height: 44px; padding: 0; font: 500 11px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase; color: var(--gold-ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; visibility: hidden;
}
.is-filtered .opo-fil__reset { visibility: visible; }
.opo-fil__cur { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 10px; border-top: 1px solid var(--line-soft); }
.opo-fil__cur .micro { color: var(--mute-2); }
.opo-fil__cur .cur { margin-right: -8px; }
.opo-fil__note { margin-top: 4px; }
@media (min-width: 900px) {
  .opo-fil__bar { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .opo-f--zona { grid-column: auto; border-bottom: 0; }
  .opo-f--zona + .opo-f { padding-left: 24px; border-left: 1px solid var(--line); }
  .opo-f + .opo-f { padding-left: 24px; }
  .opo-f { min-height: 88px; padding-top: 16px; }
  .opo-fil__st { grid-template-columns: auto auto minmax(0, 1fr); column-gap: 28px; padding-top: 10px; }
  .opo-fil__cur { grid-column: 3; justify-content: flex-end; border-top: 0; }
  .opo-fil__note { text-align: right; }
}

/* ---------- 3 · catálogo: tarjetas -----------------------------------------
   Todas con la MISMA caja (Iker 04-11): 4:3 desde 700 px (dos columnas) y 4:5 en una columna, que es la caja de la
   cabecera de la ficha en el teléfono (la foto viaja sin cambiar de recorte). Encuadre por foto: --pos (4:3) y
   --pos-m (4:5), que vienen de propiedades.json. Cuadrícula uniforme: con 6 o con 40, el mismo ritmo. */
.opo-grid { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: clamp(48px, 12vw, 64px); }
@media (min-width: 700px) { .opo-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(20px, 3.2vw, 56px); row-gap: clamp(56px, 6vw, 96px); } }
.opo-card { position: relative; min-width: 0; }
.opo-card__a { display: block; color: inherit; }
.opo-card__media { margin: 0; width: 100%; aspect-ratio: 4 / 5; max-height: 58svh; }
.opo-card__media img { object-position: var(--pos-m, 50% 50%); transition-property: opacity, transform; }
@media (min-width: 700px) {
  .opo-card__media { aspect-ratio: 4 / 3; max-height: none; }
  .opo-card__media img { object-position: var(--pos, 50% 50%); }
}
.opo-card__no { display: none; }
.opo-fh__no .no, .opo-nx .no { display: none; }
.opo-card__st { position: absolute; right: 0; top: 0; z-index: 1; padding: 9px 11px 8px; background: var(--ink); color: var(--paper); font: 500 10.5px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase; }
.opo-card__meta { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 8px; margin-top: 18px; }
.opo-card__zone { color: var(--mute); }
.opo-card__name { font: 300 clamp(2rem, 2.9vw, 2.875rem)/1 var(--serif); letter-spacing: -.012em; font-variant-numeric: lining-nums; }
.opo-card__price { font: 400 clamp(1.375rem, 1.7vw, 1.75rem)/1.1 var(--serif); font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
.opo-card__facts { font-size: 14.5px; letter-spacing: .01em; color: var(--ink); }
.opo-card__sum { margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line); font-size: 15px; line-height: 1.6; color: var(--mute); text-wrap: pretty; }
@media (min-width: 1100px) {
  /* nombre y precio en la misma línea; debajo, las cifras */
  .opo-card__meta { grid-template-columns: minmax(0, 1fr) auto; column-gap: 24px; align-items: baseline; }
  .opo-card__zone, .opo-card__facts, .opo-card__sum { grid-column: 1 / -1; }
  .opo-card__price { text-align: right; }
}
/* hover: la foto crece dentro de su caja (la caja del enlace no se mueve: norma 16) */
@media (hover: hover) and (pointer: fine) {
  .opo-card__a:hover .opo-card__media img { transform: scale(1.035); }
  .opo-card__name { transition: color .4s; }
  .opo-card__a:hover .opo-card__name { color: var(--gold-ink); }
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) { .opo-card__media img { transition-duration: .7s, 1.2s; transition-timing-function: var(--ease-out); } }

/* ---------- 3b · estado vacío: salida doble (quitar filtros o búsqueda privada) */
.opo-empty { display: grid; row-gap: 18px; padding-top: clamp(28px, 3.4vw, 48px); border-top: 1px solid var(--ink); }
.opo-empty[hidden] { display: none; }
.opo-empty__h, .opo-empty__b { display: grid; gap: 16px; justify-items: start; align-content: start; }
.opo-empty__t { max-width: 19ch; text-wrap: balance; }
.opo-empty__p { max-width: 46ch; }
.opo-empty__btns { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 32px; margin-top: 8px; }
@media (min-width: 900px) {
  .opo-empty { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); }
  .opo-empty__h { grid-column: 1 / 7; }
  .opo-empty__b { grid-column: 7 / 13; padding-top: 30px; }
}
@media (max-width: 599px) { .opo-empty__btns { display: grid; width: 100%; } .opo-empty__btns .btn { width: 100%; } }

/* ---------- 4 · ficha: cabecera ------------------------------------------
   La foto de borde a borde y desde arriba, con la cabecera clara encima (header: dark), como la portada (revisión
   29-10: «eso de que no ocupe todo el ancho me parece muy feo»). Escritorio: lámina 2,4:1, con topes de 420 px y de la
   pantalla menos 170 px (así la placa, el precio y la consulta entran en el primer pantallazo). Móvil: 4:5, la misma
   caja que las tarjetas del índice y la de «Siguiente» (la foto viaja sin cambiar de recorte). La placa de la calle,
   clavada en el borde inferior de la foto; migas y cifras, en la banda de papel. Nada se anima aquí salvo las
   entradas CSS del núcleo (.enter). */
.opo-fh { position: relative; }
.opo-fh__media {
  --fh-in: max(var(--margin), calc((100% - var(--maxw)) / 2 + var(--margin)));   /* el borde de la rejilla */
  position: relative; margin: 0; width: 100%; aspect-ratio: 4 / 5; max-height: 64svh;
}
.opo-fh__media img { object-position: var(--pos-m, 50% 50%); }
/* velo solo arriba, bajo la cabecera clara: tinta normal semitransparente (sin mezcla); viaja con la foto */
.opo-fh__media::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; z-index: 1; height: min(240px, 50%); pointer-events: none;
  background: linear-gradient(180deg, rgb(8 24 39 / .56) 0%, rgb(8 24 39 / .36) 32%, rgb(8 24 39 / .13) 66%, rgb(8 24 39 / 0) 100%);
}
.opo-fh__a { display: block; width: 100%; height: 100%; }
/* «09 Ver las fotografías»: pestaña de papel; en móvil arriba a la derecha (abajo chocaría con la placa) */
.opo-fh__count {
  position: absolute; right: var(--fh-in); top: calc(var(--hdr-h) + 10px); z-index: 2;
  display: inline-flex; align-items: baseline; gap: 10px; min-height: 44px; padding: 12px 16px 11px;
  background: var(--paper); color: var(--ink);
  font: 500 10.5px/1 var(--sans); letter-spacing: .16em; text-transform: uppercase;
}
.opo-fh__n { font: 300 1.25rem/.8 var(--serif); letter-spacing: 0; color: var(--gold-ink); font-variant-numeric: lining-nums tabular-nums; }
@media (hover: hover) { .opo-fh__count { transition: background-color .35s, color .35s; } .opo-fh__count:hover { background: var(--ink); color: var(--paper); } .opo-fh__count:hover .opo-fh__n { color: var(--gold-light); } }
.opo-fh__band { position: relative; z-index: 3; display: grid; row-gap: 18px; padding-bottom: clamp(28px, 5vw, 64px); }
.opo-fh__id { display: grid; row-gap: 10px; justify-items: start; min-width: 0; }
/* la placa, clavada en el borde inferior de la foto */
.opo-placa {
  justify-self: start; margin: calc(-1 * clamp(40px, 4.2vw, 62px)) 0 0 clamp(12px, 2.4vw, 40px);
  min-width: 0; max-width: calc(100% - 24px); padding: clamp(16px, 1.6vw, 24px) clamp(22px, 2.6vw, 42px) clamp(14px, 1.4vw, 20px);
  box-shadow: var(--shadow);
}
.opo-placa .placa__name { font-size: clamp(2rem, 3.6vw, 3.5rem); text-wrap: balance; font-variant-numeric: lining-nums; }
/* migas (en la banda de papel: sobre la foto no tendrían contraste AA en los techos blancos) */
.opo-fh__crumbs { display: flex; align-items: center; max-width: 100%; min-width: 0; }
.opo-fh__crumbs ol { flex-wrap: nowrap; overflow: hidden; min-width: 0; max-width: 100%; }
.opo-fh__crumbs li { white-space: nowrap; flex: 0 0 auto; }
/* la casa actual se recorta con puntos suspensivos si no cabe (ES: «Oportunidades seleccionadas» es largo en 390 px) */
.opo-fh__crumbs li:last-child { display: block; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; line-height: 44px; }
@media (max-width: 429px) { .opo-fh__crumbs ol { letter-spacing: .1em; gap: 6px 9px; } .opo-fh__crumbs li + li::before { margin-right: 9px; } }
.opo-fh__meta { display: grid; gap: 10px; justify-items: start; }
.opo-fh__no { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.opo-fh__of { color: var(--mute-2); }
.opo-fh__st { font: italic 300 1.125rem/1.2 var(--serif); color: var(--mute); }
.opo-fh__price { font: 300 clamp(2.5rem, 3.5vw, 3.875rem)/1 var(--serif); letter-spacing: -.015em; font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; }
.opo-fh__cur .cur { margin-left: -8px; }
.opo-fh__kv { --kv-cols: 2; margin-top: 6px; }
.opo-fh__kv > div { padding-right: 12px; }
.opo-fh__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 28px; margin-top: 6px; }
@media (max-width: 599px) { .opo-fh__cta .btn { width: 100%; } }
@media (min-width: 900px) {
  .opo-fh__media { aspect-ratio: 2.4; min-height: 420px; max-height: min(calc(100svh - 170px), 980px); }
  .opo-fh__media img { object-position: var(--pos, 50% 50%); }
  .opo-fh__media::after { height: min(220px, 40%); }
  .opo-fh__count { top: auto; bottom: 0; }
  .opo-fh__band { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: 0; align-items: end; padding-bottom: clamp(36px, 4vw, 64px); }
  /* placa arriba (clavada en la foto) y migas abajo, a la altura de la moneda */
  .opo-fh__id { grid-column: 1 / 7; grid-row: 1; align-self: stretch; align-content: space-between; }
  .opo-fh__meta { grid-column: 7 / 13; grid-row: 1; justify-items: end; text-align: right; gap: 8px; padding-top: 22px; }
  .opo-fh__no { justify-content: flex-end; }
  .opo-fh__cur .cur { margin: 0 -8px 0 0; }
  .opo-fh__kv { --kv-cols: 4; grid-column: 1 / 8; grid-row: 2; margin-top: 22px; }
  .opo-fh__cta { grid-column: 8 / 13; grid-row: 2; justify-content: flex-end; margin: 0; padding-bottom: 14px; }
  /* la nota de moneda vive DENTRO del bloque del precio: sin grid-column (creaba 12 columnas implícitas y desbordaba) */
  .opo-fh__note { text-align: right; max-width: 36ch; }
}

/* ---------- 5 · ficha: la vivienda ----------------------------------------- */
.opo-desc { padding-top: calc(var(--section) * .55); padding-bottom: calc(var(--section) * .6); }
.opo-desc .grid { row-gap: 26px; }
.opo-desc__lead { font: 300 clamp(1.625rem, 2.6vw, 2.5rem)/1.22 var(--serif); letter-spacing: -.008em; max-width: 30ch; margin-top: clamp(4px, 1vw, 16px); }
.opo-desc__body { font-size: 1.0625rem; line-height: 1.72; color: var(--ink); max-width: 64ch; }
.opo-desc__body p + p { margin-top: 1em; }
/* capitular: tres líneas, en Cormorant, a la izquierda del primer párrafo */
.opo-desc__body p:first-child::first-letter {
  float: left; margin: .08em .12em -.1em -.02em;
  font: 300 5.1em/.78 var(--serif); color: var(--gold-ink); font-variant-numeric: lining-nums;
}
.opo-rasgos { display: grid; gap: 14px; align-content: start; }
.opo-rasgos ul { border-top: 1px solid var(--ink); }
.opo-rasgos li { display: grid; grid-template-columns: 18px minmax(0, 1fr); align-items: baseline; padding-block: 14px 13px; border-bottom: 1px solid var(--line); font: 400 1.25rem/1.3 var(--serif); }
.opo-rasgos li::before { content: ""; width: 10px; height: 1px; background: var(--gold); transform: translateY(-.32em); }
/* la foto grande de la casa (sale del mosaico): lámina a todo el ancho entre la entradilla y el texto, 16:9 y como
   mucho 85svh; en móvil, 4:5 como la cabecera. Sin revelado propio: se pide 1.600 px antes (opo.js) y funde al estar
   entera (.opo-ph), como el mosaico */
.opo-desc__fig { margin: clamp(4px, 1vw, 14px) 0 clamp(2px, .6vw, 10px); }
.opo-desc__fig__a { aspect-ratio: 4 / 5; max-height: 72svh; width: 100%; }
.opo-desc__fig__a img { object-position: var(--pos-m, 50% 50%); }
.opo-desc__fig figcaption { margin-top: 11px; }
@media (hover: hover) and (pointer: fine) {
  .opo-desc__fig__a img, .opo-tools__fig__a img { transition: opacity .7s var(--ease-out), transform 1.2s var(--ease-out); }
  .opo-desc__fig__a:hover img, .opo-tools__fig__a:hover img { transform: scale(1.02); }
}
@media (min-width: 900px) {
  .opo-desc__fig__a { aspect-ratio: 16 / 9; max-height: 85svh; }
  .opo-desc__fig__a img { object-position: var(--pos, 50% 50%); }
  .opo-desc__fig { grid-row: 3; }
  .opo-desc__body { columns: 2; column-gap: clamp(28px, 3.4vw, 56px); max-width: none; }
  /* un solo párrafo (Villanueva, Génova): va junto a la entradilla, a la derecha, sin capitular (no llena 3 líneas) */
  .opo-desc:has(.opo-desc__body--1) .opo-desc__lead { grid-column: 1 / 8; grid-row: 2; }
  .opo-desc .opo-desc__body--1 { grid-column: 8 / 13; grid-row: 2; align-self: end; columns: auto; max-width: 44ch; padding-bottom: .4em; }
  .opo-desc__body--1 p:first-child::first-letter { float: none; margin: 0; font: inherit; color: inherit; }
  .opo-desc:has(.opo-desc__body--1) .opo-rasgos { grid-column: 8 / 13; width: min(100%, 44ch); margin-top: clamp(16px, 2vw, 32px); }
  .opo-desc__body p { break-inside: avoid-column; }
  .opo-rasgos { grid-row: 4; }
  .opo-desc__body { grid-row: 4; }
  /* un solo párrafo (Villanueva): entradilla y párrafo en la fila 2, rasgos debajo del párrafo y la foto al final */
  .opo-desc:has(.opo-desc__body--1) .opo-rasgos { grid-row: 3; }
  .opo-desc:has(.opo-desc__body--1) .opo-desc__fig { grid-row: 4; margin-top: clamp(8px, 1.6vw, 24px); }
}

/* ---------- 6 · ficha: fotografías ----------------------------------------- */
.opo-gal-sec { padding-top: calc(var(--section) * .5); }
.opo-gal-sec__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: clamp(26px, 4vw, 64px); padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.opo-gal-sec__count { font: 300 1.375rem/1 var(--serif); color: var(--mute); font-variant-numeric: lining-nums tabular-nums; }
/* revisión 29-10: ninguna foto por debajo de 6/12 en escritorio. Filas de dos a 6/12 con la MISMA caja (la media de
   sus proporciones: misma altura, sin escalones) y láminas sueltas a todo el ancho (o a 8/12 si la foto es cuadrada
   o vertical). En móvil, todas a todo el ancho con su proporción (las verticales, 4:5 como mucho). La foto entera se
   ve en el visor. */
.opo-mos { display: grid; row-gap: clamp(32px, 4.4vw, 72px); }
.opo-mos__row { row-gap: 32px; align-items: start; }
.opo-fig { margin: 0; }
/* width: 100% explícito: con aspect-ratio y ancho automático, Chrome pasa el tope de alto al ancho y la lámina se
   estrecha (una 3:2 a todo el ancho salía a 8,5/12); así el tope recorta la foto (cover) y la caja llena su columna */
.opo-fig__a { width: 100%; aspect-ratio: var(--ar-m, var(--ar, 3 / 2)); max-height: 80svh; }
.opo-fig figcaption { margin-top: 11px; }
@media (hover: hover) and (pointer: fine) {
  .opo-fig__a img { transition: opacity .7s var(--ease-out), transform 1.2s var(--ease-out); }
  .opo-fig__a:hover img { transform: scale(1.025); }
}
@media (min-width: 900px) {
  .opo-mos__row { row-gap: 0; }
  .opo-fig__a { aspect-ratio: var(--ar, 3 / 2); max-height: 85svh; }
}
/* Génova (una sola foto, ya en la cabecera): en «01 La vivienda», el dibujo de Almagro a 7/12 y, a su lado, la
   petición de la información completa. Mientras el dibujo no llega (el build deja .dib--pendiente y se oculta), el
   bloque ocupa su sitio a la izquierda */
.opo-solo__head { display: grid; gap: 18px; justify-items: start; align-content: end; }
.opo-solo__head .text-2 { max-width: 44ch; }
.opo-solo__t { max-width: 13ch; }
.opo-solo__dib { width: 100%; margin: clamp(8px, 2vw, 24px) 0 0; }
@media (min-width: 900px) {
  .opo-desc--solo .opo-solo__dib, .opo-desc--solo .opo-solo__head { grid-row: 3; }
  .opo-desc--solo .opo-solo__head { align-self: end; padding-bottom: 8px; }
  .opo-desc--solo:has(.opo-solo__dib > .dib--pendiente) .opo-solo__head { grid-column: 1 / 9; margin-top: clamp(16px, 2vw, 32px); }
}

/* ---------- 7 · ficha: ubicación ------------------------------------------- */
/* 29-10: entre el mapa y el titular de 04, y entre 04 y 05, ≤ ~240 px (antes ~280) */
.opo-ubi { padding-top: calc(var(--section) * .45); padding-bottom: calc(var(--section) * .7); }
.opo-ubi .grid { row-gap: 24px; align-items: end; }
.opo-ubi__map [data-mapa] { aspect-ratio: 4 / 5; overflow: hidden; }
@media (min-width: 600px) { .opo-ubi__map [data-mapa] { aspect-ratio: 4 / 3; } }
.opo-ubi__txt { display: grid; gap: 12px; justify-items: start; }
.opo-ubi__calle { font: 300 var(--fs-3)/1.12 var(--serif); }
.opo-ubi__k { margin-bottom: 2px; }
.opo-ubi__txt .text-2 { max-width: 36ch; font-size: 15px; }
html.no-js .opo-ubi__map, html.js-failed:not(.js-core) .opo-ubi__map { display: none; }
/* el plano de la ficha entra en ~1 s (mismo orden que mapa.css, tiempos comprimidos) */
@media (prefers-reduced-motion: no-preference) {
  .opo-page .mapa.is-in .m-parks, .opo-page .mapa.is-in .m-water { transition: opacity .6s ease .15s; }
  .opo-page .mapa.is-in .m-roads-r, .opo-page .mapa.is-in .m-roads-t { transition: opacity .6s ease .05s; }
  .opo-page .mapa.is-in .m-roads-a { transition: opacity .5s ease 0s; }
  .opo-page .mapa.is-in .m-roads-p { transition: opacity .5s ease .05s; }
  .opo-page .mapa.is-in .m-streets { transition: opacity .5s ease .3s; }
  .opo-page .mapa.is-in .mapa__b { transition: opacity .5s ease calc(.3s + var(--d, 0s)); }
  .opo-page .mapa.is-in .mapa__legend, .opo-page .mapa.is-in .mapa__attr { transition: opacity .5s ease .45s; }
  .opo-page .mapa.is-in .m-area-f { transition: opacity .6s ease .2s; }
  .opo-page .mapa.is-in .m-area-r, .opo-page .mapa.is-in .mapa__area-tag { transition: opacity .5s ease .35s; }
}
@media (min-width: 900px) { .opo-ubi__txt { padding-bottom: 8px; } }

/* ---------- 8 · ficha: herramientas ---------------------------------------- */
.opo-tools-sec { padding-block: calc(var(--section) * .8); }
.opo-tools-sec .grid { row-gap: 26px; align-items: start; }
/* izquierda: titular + calculadora · derecha: foto de la casa (4:3) + precio en tu moneda. En móvil, una columna */
.opo-tools-sec__main, .opo-tools-sec__side { display: grid; gap: 26px; align-content: start; min-width: 0; }
.opo-tools-sec__t { max-width: 15ch; margin-bottom: clamp(4px, 1.4vw, 22px); }
.opo-tools__fig { margin: 0; }
.opo-tools__fig__a { aspect-ratio: 4 / 3; width: 100%; }
.opo-tools__fig figcaption { margin-top: 11px; }
@media (min-width: 900px) {
  /* revisión 29-10: la foto de la casa a 6/12 (antes 5/12); la calculadora, en las otras 6 */
  .opo-tools-sec__main { grid-column: 1 / 7; grid-row: 2; }
  .opo-tools-sec__side { grid-column: 7 / 13; grid-row: 2; gap: clamp(28px, 3vw, 44px); }
  .opo-calc { max-width: 40rem; }
}
.opo-calc { display: grid; gap: 20px; }
.opo-calc__k { margin-bottom: -4px; }
.opo-calc__in { display: grid; gap: 10px; justify-items: start; padding-top: 16px; border-top: 1px solid var(--ink); }
.opo-calc__l { font: 500 var(--fs-micro)/1.3 var(--sans); letter-spacing: .18em; text-transform: uppercase; color: var(--mute); }
/* la cifra a tamaño de capítulo y el € pegado, en dorado; el campo mide lo que su cifra (--n, que escribe propiedades.py
   y actualiza opo.js; con field-sizing, el navegador) */
.opo-calc__field { display: inline-flex; align-items: baseline; gap: .25em; max-width: 100%; min-height: 44px; border-bottom: 1px solid var(--ink); font: 300 var(--fs-2)/1.1 var(--serif); font-variant-numeric: lining-nums tabular-nums; }
html[lang="en"] .opo-calc__field { gap: .04em; }
.opo-calc__field:focus-within { box-shadow: 0 1px 0 0 var(--gold-ink); }
.opo-calc__field > span { color: var(--gold-ink); }
.opo-calc__input { width: calc(var(--n, 9) * 1ch + 2px); min-width: 4ch; max-width: 100%; padding: 4px 0 6px; border: 0; border-radius: 0; background: transparent; color: var(--ink); font: inherit; font-variant-numeric: inherit; -webkit-appearance: none; appearance: none; }
@supports (field-sizing: content) { .opo-calc__input { width: auto; field-sizing: content; } }
.opo-calc__input:focus { outline: none; }
.opo-calc__hint { font-size: 13px; color: var(--mute); }
.opo-calc__dl { border-top: 1px solid var(--ink); }
.opo-calc__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 18px; align-items: baseline; padding-block: 14px; border-bottom: 1px solid var(--line); }
.opo-calc__row dt { font-size: .9375rem; line-height: 1.4; }
.opo-calc__row dt small { display: block; max-width: 40ch; font-size: .8125rem; line-height: 1.45; color: var(--mute); }
.opo-calc__row dd { font: 400 1.5rem/1.15 var(--serif); font-variant-numeric: lining-nums tabular-nums; white-space: nowrap; text-align: right; }
.opo-calc__row--extra { border-bottom-color: var(--ink); }
.opo-calc__row--extra dt { font-weight: 500; }
.opo-calc__row--extra dd { font-size: var(--fs-3); color: var(--gold-ink); }
.opo-calc__note { max-width: 62ch; font-size: 13px; line-height: 1.55; color: var(--mute); }
.opo-fx { display: grid; gap: 16px; align-content: start; }
.opo-fx__ap { color: var(--mute-2); }
.opo-fx__dl { border-top: 1px solid var(--ink); }
.opo-fx__row { display: grid; grid-template-columns: 3.4rem minmax(0, 1fr) minmax(0, 1.5fr); gap: 4px 14px; align-items: baseline; padding-block: 14px; border-bottom: 1px solid var(--line); }
.opo-fx__row dt { font: 500 11px/1 var(--sans); letter-spacing: .16em; color: var(--gold-ink); }
.opo-fx__row dd { font: 400 1.125rem/1.25 var(--serif); font-variant-numeric: lining-nums tabular-nums; text-align: right; white-space: nowrap; }
.opo-fx__row--h { padding-block: 10px; }
.opo-fx__row--h span { font: 500 10.5px/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--mute-2); text-align: right; }
.opo-fx__l { display: none; }
.opo-fx__note { font-size: 13px; line-height: 1.55; color: var(--mute); max-width: 46ch; }
@media (max-width: 599px) {
  .opo-calc__row { grid-template-columns: minmax(0, 1fr); }
  .opo-calc__row dd { text-align: left; font-size: 1.375rem; white-space: normal; }
  .opo-calc__row--extra dd { font-size: var(--fs-3); }
}
/* hasta 1279 px la columna de la moneda es estrecha: cada moneda en dos líneas (precio / total), sin desbordar */
@media (max-width: 1279px) {
  .opo-fx__row { grid-template-columns: 3.4rem minmax(0, 1fr); row-gap: 12px; }
  .opo-fx__row dd { grid-column: 2; display: grid; gap: 3px; text-align: left; white-space: normal; }
  .opo-fx__row--h { display: none; }
  .opo-fx__l { display: block; font: 500 10.5px/1.4 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--mute-2); }
}
@media (min-width: 900px) { .opo-fx { padding-top: 6px; } .opo-calc { padding-right: clamp(0px, 2vw, 32px); } }
@media (min-width: 900px) and (max-width: 1279px) { .opo-calc__row { grid-template-columns: minmax(0, 1fr); } .opo-calc__row dd { text-align: left; } }

/* ---------- 9 · ficha: contacto -------------------------------------------- */
.opo-con { padding-top: calc(var(--section) * .8); padding-bottom: calc(var(--section) * .75); }
.opo-con .grid { row-gap: 30px; align-items: start; }
.opo-con__head { display: grid; gap: 14px; }
.opo-con__t { max-width: 17ch; }
.opo-con__p { max-width: 50ch; }
.opo-form { row-gap: 26px; }
.opo-vc { gap: 12px; }
.opo-vc__opt { color: var(--mute-2); }
.opo-vc__p { font-size: 14px; line-height: 1.5; color: var(--mute); }
.opo-vc__tz { display: block; margin-top: 2px; color: var(--ink); }
.opo-vc__slots { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (min-width: 700px) { .opo-vc__slots { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.opo-slot {
  display: grid; gap: 5px; justify-items: start; align-content: start; min-height: 84px; padding: 12px 14px 11px;
  border: 1px solid var(--line); border-radius: 1px; text-align: left; background: transparent; color: var(--ink);
  transition: border-color .3s, background-color .3s, color .3s;
}
.opo-slot:disabled { cursor: default; }
.is-same .opo-slot { min-height: 70px; }
.is-same .opo-slot__m { display: none; }
.opo-slot__d { font: 500 10.5px/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--mute); transition: color .3s; }
.opo-slot__t { font: 300 1.625rem/1 var(--serif); font-variant-numeric: lining-nums tabular-nums; }
.opo-slot__m { font-size: 12px; line-height: 1.3; color: var(--mute-2); transition: color .3s; }
@media (hover: hover) { .opo-slot:not(:disabled):hover { border-color: var(--ink); } }
.opo-slot[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.opo-slot[aria-pressed="true"] .opo-slot__d { color: var(--gold-light); }
.opo-slot[aria-pressed="true"] .opo-slot__m { color: var(--cream-72); }
.opo-vc__sel { min-height: 1.4em; font: italic 300 1.0625rem/1.4 var(--serif); color: var(--mute); }
.opo-vc__sel b { font-style: normal; font-weight: 400; color: var(--ink); }
.opo-con__aside { display: grid; gap: clamp(20px, 2.4vw, 32px); justify-items: start; align-content: start; }
/* las llaves (dibujo, 1:1): junto a «¿Quieres verla?» en escritorio; en móvil, a todo el ancho entre el formulario y el
   contacto directo */
.opo-con__dib { width: min(100%, 26rem); }
.opo-con__direct { display: grid; gap: 16px; justify-items: start; }
.opo-con__aside .text-2 { max-width: 34ch; }
@media (max-width: 899px) { .opo-con__dib { width: 100%; margin-top: 8px; } }
.opo-con__big { font: 300 var(--fs-3)/1.2 var(--serif); font-variant-numeric: lining-nums tabular-nums; }
.opo-con__line { font-size: 15px; color: var(--mute); }
.opo-con__line time { color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
@media (min-width: 900px) {
  .opo-con__head { margin-bottom: 8px; }
  .opo-con__head { grid-row: 2; }
  .opo-form { grid-row: 3; }
  .opo-con__aside { grid-row: 2 / span 2; }
  .opo-con__direct { padding-left: clamp(0px, 2vw, 32px); border-left: 1px solid var(--line); }
}

/* ---------- 10 · ficha: anterior / siguiente -------------------------------
   La foto de la siguiente, sin revelado (data-early: ya está pintada al asomar) y con la proporción de la cabecera de
   SU ficha: en escritorio, 6/10 de ella en ancho y en alto (60cqw del ancho de la página × los mismos topes × .6),
   así que la foto que viaja solo escala, sin cambiar de recorte; en móvil, 4:5 como la cabecera. */
.opo-nx { padding-block: calc(var(--section) * .6); border-top: 1px solid var(--line); container-type: inline-size; }
.opo-nx .grid { row-gap: 40px; align-items: end; }
.opo-nx__a { display: grid; gap: 18px; }
.opo-nx__media { margin: 0; aspect-ratio: 4 / 5; max-height: 58svh; width: 100%; }
.opo-nx__media img { object-position: var(--pos-m, 50% 50%); }
.opo-nx__meta { display: grid; gap: 10px; }
.opo-nx__name { font: 300 var(--fs-2)/1 var(--serif); letter-spacing: -.012em; transition: color .4s; }
.opo-nx__facts { font-size: 15px; color: var(--mute); }
.opo-nx__side { display: grid; gap: 22px; align-content: end; justify-items: start; }
.opo-nx__prev { display: grid; gap: 8px; }
.opo-nx__pn { font: 300 1.5rem/1.15 var(--serif); transition: color .4s; }
.opo-nx__pn .no { margin-right: .5em; vertical-align: .3em; }
@media (hover: hover) and (pointer: fine) {
  .opo-nx__media img { transition: opacity .7s var(--ease-out), transform 1.2s var(--ease-out); }
  .opo-nx__a:hover .opo-nx__media img { transform: scale(1.03); }
  .opo-nx__a:hover .opo-nx__name, .opo-nx__prev:hover .opo-nx__pn { color: var(--ink-2); }
}
@media (min-width: 900px) {
  .opo-nx__a, .opo-nx__side { grid-row: 1; }
  .opo-nx__a { width: 60cqw; justify-self: end; }
  .opo-nx__media { aspect-ratio: 2.4; min-height: 252px; max-height: calc(min(100svh - 170px, 980px) * .6); }
  .opo-nx__media img { object-position: var(--pos, 50% 50%); }
  .opo-nx__meta { grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 24px; }
  .opo-nx__meta .micro { grid-column: 1 / -1; }
  .opo-nx__facts { text-align: right; }
}

/* ---------- 11 · detalles ------------------------------------------------- */
/* titulares sin viudas («pública.» sola, «o» colgando) */
.opo-solo__t, .opo-con__t, .opo-tools-sec__t { text-wrap: balance; }
.opo-solo__t { max-width: 16ch; }
/* la luz de ventana no termina en una línea recta al borde de la sección (máscara quieta: no repinta) */
.opo-ih .gobo { -webkit-mask-image: linear-gradient(#000 0 52%, transparent 86%); mask-image: linear-gradient(#000 0 52%, transparent 86%); }

/* dibujo aún sin entregar (el build deja un <svg class="dib--pendiente"> vacío): no se reserva su hueco, que en el
   cierre serían ~730 px de papel vacío; al llegar el SVG y volver a montar, aparece con su proporción fija */
.opo-page .dib:has(> .dib--pendiente) { display: none; }

/* ---------- 11b · índice: cierre con la calle dibujada ---------------------
   La pregunta y la consulta en una sola fila; debajo, «calle-perspectiva» a sangre, de borde a borde de la pantalla
   (Pedro 29-10: lo que no ocupa todo el ancho «me parece muy feo»), como el Madrid del cierre de la portada. El trazado
   lo hace el núcleo ([data-draw]); aquí solo la caja con su proporción fija. En escritorio, 16:9 con tope de 78svh
   (si la pantalla es baja se recorta lo mismo arriba y abajo); en móvil, recortada al centro en 4:3 (el SVG mide
   4/3 ÷ 16/9 = 133,3 % del ancho de la caja). Transformación quieta: no se anima nada de la caja. */
.opo-after { padding-top: calc(var(--section) * .7); padding-bottom: clamp(12px, 2vw, 32px); }
.opo-after .cta-end__t { margin-top: clamp(20px, 2.4vw, 36px); }
.opo-after__p { max-width: 40ch; }
.opo-after__dib { position: relative; width: 100%; aspect-ratio: 1920 / 1080; max-height: 78svh; overflow: hidden; margin-top: clamp(40px, 5vw, 80px); }
.opo-after__dib .dib__svg { position: absolute; left: 0; top: 50%; width: 100%; height: auto; transform: translateY(-50%); }
@media (min-width: 900px) {
  .opo-after .cta-end__t { grid-row: 2; }
  .opo-after .cta-end__aside { grid-row: 2; align-self: end; margin-top: 0; padding-bottom: .4em; }
}
@media (max-width: 899px) {
  .opo-after .cta-end__aside { margin-top: clamp(24px, 6vw, 40px); }
  .opo-after__dib { aspect-ratio: 4 / 3; max-height: none; }
  .opo-after__dib .dib__svg { left: -16.667%; top: 0; width: 133.333%; max-width: none; transform: none; }
}
/* sin dibujo (aún no entregado), el cierre no termina pegado al pie */
.opo-after:has(> .opo-after__dib > .dib--pendiente) { padding-bottom: calc(var(--section) * .6); }

/* ---------- 12 · transiciones entre páginas ---------------------------------
   Estas reglas solo valen cuando la página que LLEGA es de oportunidades (los pseudoelementos de la transición
   toman los estilos del documento nuevo). Propuesta para el núcleo: las de root, para todo el sitio. */
@media (prefers-reduced-motion: no-preference) {
  /* root (fundido en serie, papel entre medias): lo pone el núcleo para todo el sitio (site.css §23) */
  /* la foto que viaja: origen y destino tienen la misma proporción y el mismo encuadre (si no, opo-fotos.js no la deja
     viajar), así que la nueva tapa a la vieja desde el primer fotograma: nunca dos recortes superpuestos */
  ::view-transition-new(vt-foto) { animation: none; }
  /* destino aún sin decodificar (caja transparente: debajo sigue la de origen, con el mismo recorte): fundido corto */
  html:active-view-transition-type(foto-tarde)::view-transition-new(vt-foto) { animation: vt-fade .2s var(--ease-out) both; }
  /* sin gemela (volver al catálogo, foto fuera de pantalla, otra proporción): la vieja se va con la página, en serie */
  ::view-transition-old(vt-foto):only-child { animation: vt-out .22s var(--ease-out) both; }
  ::view-transition-new(vt-foto):only-child { animation: vt-fade .35s var(--ease-out) both; }
  /* la placa de la calle (el h1) va POR ENCIMA de la foto que llega: entra en su sitio desde el primer fotograma */
  html.has-vt.vt-run .opo-placa { view-transition-name: opo-placa; }
  ::view-transition-group(opo-placa) { z-index: 60; animation: none; }
  ::view-transition-new(opo-placa) { animation: none; }
  ::view-transition-old(opo-placa) { animation: vt-out .22s var(--ease-out) both; }
}
