/* =====================================================================
   EL CORTIJO · rancho hípico y cabañas — Tlajomulco
   Motor inmersivo calcado de la arquitectura de persepolis.getty.edu:
   escenas con la cámara atada al scroll (con pausas), bloques editoriales
   por rango de avance, hotspots de comparación, índice de capítulos.
   La piel es del rancho: tierra, pasto seco, madera y cerros — jamás la
   paleta del Getty (la identidad no se copia, el esqueleto sí).
   ===================================================================== */

:root{
  /* ═══ LOS 11 COLORES DEL MANUAL (§2.1) — no hay ningún otro ═══════════
     Este sitio se construyó ANTES de que existiera el manual, con otra
     paleta y otras tipografías. Aquí se re-viste: los nombres viejos que
     usa el resto de la hoja quedan como ALIAS que apuntan a estos once.
     Regla dura: --arena es el ÚNICO acento y no pasa de 3 elementos por
     pantalla; el negro puro está prohibido (§7.5). */
  --noche:        #221D18;   /* el suelo oscuro de todo el recorrido */
  --cal:          #F3EEE4;   /* el papel */
  --tinta-papel:  #2A241D;   /* texto sobre papel */
  --arena:        #C9995C;   /* ACENTO ÚNICO */
  --madera:       #6E5138;
  --piedra:       #A29A8E;
  --potrero:      #3F6B37;
  --ambar-m:      #8A5E24;
  --gris-vendido: #6F675C;
  --lago:         #5C7683;
  --lago-claro:   #7FA3B3;

  /* ═══ Alias del sitio → los once de arriba ══════════════════════════ */
  --tinta:      var(--noche);   /* era #0c0a07: negro de facto, prohibido */
  --tinta-2:    #2A241D;
  --tinta-3:    #332B23;
  --hueso:      var(--cal);
  /* ⚠️ el peor caso NO es el fotograma negro, es el CLARO: sobre la arena
     beige del capítulo 2 y sobre el lago a mediodía, un blanco al 62% se
     borra. Y el velo no puede subir de .35 (doctrina). La legibilidad la
     dan entonces la opacidad del texto y su propia sombra. */
  --tenue:      rgba(243,238,228,.84);
  --apenas:     rgba(243,238,228,.56);
  --linea:      rgba(243,238,228,.18);
  --ambar:      var(--arena);
  --ambar-alto: #DCB07A;      /* arena aclarada para hover, misma familia */
  --tierra:     var(--madera);
  --pasto:      var(--potrero);

  /* ═══ LAS TRES FAMILIAS DEL MANUAL (§3.1) — una cuarta está prohibida
     (§7.10). --titular se usaba sin estar definido: caía a Arial. ═══ */
  --display: "Fraunces", Georgia, "Times New Roman", serif;  /* 550 · 600 */
  --serif:   var(--display);
  --titular: var(--display);
  --sans:    "Archivo", system-ui, -apple-system, sans-serif; /* 400 · 500 */
  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace; /* 400 */

  /* ═══ Escala fluida del manual (§3.2): lineal entre 640 y 1920, piso en
     el valor de 375 px, techo en el de compu. Sin saltos por breakpoint. */
  --t-placa:  clamp(2.5rem, calc(2.5rem + 32*var(--escala)*(100vw - 640px)/1280), 4.5rem);
  --t-ancla:  clamp(1rem, calc(1rem +  4*var(--escala)*(100vw - 640px)/1280), 1.25rem);
  --t-edit:   clamp(1.25rem, calc(1.25rem +  8*var(--escala)*(100vw - 640px)/1280), 1.75rem);
  --t-dato:   clamp(2.125rem, calc(2.125rem + 22*var(--escala)*(100vw - 640px)/1280), 3.5rem);
  --t-ficha:  clamp(1.375rem, calc(1.375rem +  6*var(--escala)*(100vw - 640px)/1280), 1.75rem);
  /* paso derivado: el titular de una parada editorial vive entre la placa
     de capítulo (72/40) y el propio bloque editorial (28/20). */
  --t-sub:    clamp(1.75rem, calc(1.75rem + 16*var(--escala)*(100vw - 640px)/1280), 2.75rem);
  --t-cuerpo: clamp(.9375rem, calc(.9375rem +  1*var(--escala)*(100vw - 640px)/1280), 1rem);
  /* ⚠️ 11 px ERA EL LÍMITE DE LO LEGIBLE, y este token pinta justo lo que más
     se lee de reojo: «Capítulos», el número de capítulo, la placa y los
     rótulos. Sube a 12-13 px. No es capricho de diseño: quien prende «texto
     más grande» lo prende POR estos rótulos, y partir de 11 dejaba el piso
     demasiado abajo aun con el interruptor puesto. */
  --t-tecn:   clamp(.75rem, calc(.75rem +  1*var(--escala)*(100vw - 640px)/1280), .8125rem);

  /* ═══ Espaciado base 8 (§3.3) ═══════════════════════════════════════ */
  --esp-1:8px; --esp-2:16px; --esp-3:24px; --esp-4:40px; --esp-5:64px; --esp-6:104px;

  --paso: cubic-bezier(.22,.61,.36,1);
  --safe: env(safe-area-inset-bottom, 0px);
}

*,*::before,*::after{ box-sizing:border-box; }

html{ background:var(--tinta); }
html.bloqueado{ overflow:hidden; }

body{
  margin:0;
  background:var(--tinta);
  color:var(--hueso);
  /* cuerpo y UI = Archivo (§3.1). Fraunces queda reservada a placa,
     titular, bloque editorial y cifra grande — no al cuerpo corrido. */
  font-family:var(--sans);
  font-size:var(--t-cuerpo);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ max-width:100%; display:block; }
a{ color:inherit; }

/* Accesibilidad — los cuatro interruptores del menú
   ────────────────────────────────────────────────────────────────────────
   ⚠️ LEY DE ESTE ARCHIVO, nacida de un defecto real (16-ago-2026): dos de
   los tres interruptores RESPONDÍAN y no HACÍAN NADA. Medido: la base subía
   de 16 a 18.88 px y el alto total de la página no se movía ni un píxel
   (60,633 prendido y apagado), porque cada letra estaba clavada en px. Y el
   alto contraste solo levantaba 3 de 14 textos, porque los demás se pintaban
   con color-mix() a mano, esquivando los tokens que este bloque redefine.

   Por eso ahora hay DOS palancas y todo el sitio tiene que pasar por ellas:
   · tamaño de letra → SIEMPRE en rem (nunca px), y todo término en vw se
     multiplica por var(--escala), porque la base no arrastra al vw.
   · color de letra apagada → SIEMPRE
     color-mix(in srgb, var(--hueso) calc(N% + var(--alza)), transparent)
     o uno de los tokens --tenue/--apenas. Un color-mix sin var(--alza) es
     una letra que el alto contraste NO va a poder rescatar.
   Un interruptor que le promete algo al cliente y no cumple es peor que no
   tener el interruptor: quien lo prende concluye que el roto es él.
   ──────────────────────────────────────────────────────────────────────── */
:root{ --escala:1; --alza:0%; }
html.sin-movimiento *{ animation-duration:.001s !important; transition-duration:.001s !important; }
html.texto-grande{ font-size:118%; --escala:1.18; }
html.alto-contraste{
  --alza:22%;
  --tenue:rgba(243,238,228,.94); --apenas:rgba(243,238,228,.78); --linea:rgba(243,238,228,.42);
}
/* El único texto del sitio que traía su color a mano, fuera de token y fuera
   de mezcla. Se rescata aquí en vez de reescribir la regla de allá abajo. */
html.alto-contraste .credito-mundo{ color:var(--hueso); }
/* el velo NO pasa de .35 ni en alto contraste (regla escrita del proyecto):
   la legibilidad la sube la opacidad del texto, no una capa negra encima. */
html.alto-contraste .velo{ background:rgba(34,29,24,.35) !important; }

/* ⚠️ EL AGUJERO QUE NO ESTÁ EN NUESTRA HOJA (17-ago-2026).
   Los controles de formulario NO heredan el tamaño de letra: el navegador les
   pone el suyo, `font: 400 13.3333px Arial`, clavado en PÍXELES. Ese número no
   vive en ningún archivo nuestro, así que buscar `px` en esta hoja da cero y
   uno concluye —falsamente— que ya todo escala. Medido: 46 controles del sitio
   se quedaban en 13.3333 px con «texto más grande» puesto.
   Aquí se traduce ESE MISMO valor a rem: 13.3333/16 = .8333333rem. Con el
   interruptor apagado mide exactamente igual que antes (13.3333 px, comprobado
   elemento por elemento); prendido, ya crece con todo lo demás.
   Es un PISO, no una decisión de diseño: cualquier regla con clase le gana, y
   por eso ningún botón ya estilado se mueve. Su única función es que un control
   al que se le olvide el tamaño caiga dentro del sistema escalable en vez de
   fuera.
   ⛔ AQUÍ NO VA `font-family:inherit`, aunque pica ponerlo. Se probó y medió:
   arreglaba de paso que 80 textos caigan a Arial —una cuarta familia, que el
   §3.1 prohíbe— pero eso CAMBIA la tipografía del sitio con el interruptor
   apagado, que es justo lo que este trabajo tiene prohibido tocar. El Arial
   queda anotado como defecto propio, con dueño, en `_BITACORA-ESCALA-TEXTO.md`.
   Ningún control que pinte texto propio depende de esto: los 7 que existen ya
   declaran su familia (comprobado uno por uno). */
button,input,select,textarea,optgroup{
  font-size:.8333333rem;
}

::selection{ background:var(--arena); color:var(--noche); }

/* Foco visible en TODO lo que se puede tabular (§4.3): 2 px + separación. */
a:focus-visible,button:focus-visible,input:focus-visible,
label:focus-within,[tabindex]:focus-visible{
  outline:2px solid var(--arena); outline-offset:2px; border-radius:4px;
}

/* ─────────────────────────────────────────────────────────────
   0. TIPOGRAFÍA BASE
   ───────────────────────────────────────────────────────────── */
.titulo{
  font-family:var(--display);
  font-weight:600;
  line-height:1.05;
  letter-spacing:0;      /* §3.1: letter-spacing 0 en TODO menos la mono */
  margin:0;
}
/* La etiqueta técnica del manual (§3.2): Plex Mono 400, mayúsculas, y el
   ÚNICO letter-spacing distinto de 0 en toda la hoja (.08em). Antes iba en
   sans a .22em, que es tracking inventado. */
.rotulo{
  font-family:var(--mono);
  font-size:var(--t-tecn);
  font-weight:400;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--arena);
  margin:0;
}
.rotulo.apagado{ color:var(--piedra); }
.parrafo{
  margin:0; color:var(--tenue); max-width:46ch;
  font-family:var(--sans); font-weight:400;
  font-size:var(--t-cuerpo); line-height:1.5; letter-spacing:0;
}
/* El bloque editorial de parada (§3.2): Fraunces 550, 28/20. */
.caja .parrafo{
  font-family:var(--display); font-weight:550;
  font-size:var(--t-edit); line-height:1.35;
  max-width:22ch;
}
/* Dato numérico protagonista (§3.2): cifra en Fraunces, unidad en Plex Mono
   12 px arriba a la derecha. El tamaño hace el peso, no un tercer grosor. */
.uni{
  font-family:var(--mono); font-weight:400;
  font-size:var(--t-tecn); letter-spacing:.08em; text-transform:uppercase;
  vertical-align:super; margin-left:.34em; color:var(--piedra);
}
em{ font-style:italic; }

/* ─────────────────────────────────────────────────────────────
   1. PORTADA — la entrada (calco del preloader del Getty)
   ───────────────────────────────────────────────────────────── */
.portada{
  position:fixed; inset:0; z-index:100;
  display:grid; place-items:center;
  background:var(--tinta);
  text-align:center;
  padding:24px;
  transition:opacity 1.1s var(--paso), visibility 1.1s;
}
/* la marca se ancla ABAJO, sobre el pasto —la zona oscura de la foto—
   para no pelearse con el cielo. La foto queda a brillo pleno. */
.portada.marcada{ place-items:end center; padding-bottom:clamp(34px,9vh,92px); }
.portada.fuera{ opacity:0; visibility:hidden; pointer-events:none; }

.portada .fondo{
  position:absolute; inset:0;
  background-size:cover; background-position:center 72%;
  opacity:0; transform:scale(1.12);
  transition:opacity 2.4s var(--paso), transform 9s linear;
  /* §4.8: sin filtro de color sobre la foto — la materia va a brillo pleno */
}
.portada.viva .fondo{ opacity:1; transform:scale(1); }
/* gradiente LOCAL detrás del texto — nunca una capa negra encima de la foto.
   Tope duro .35; la legibilidad la termina de dar la sombra del propio texto. */
.portada .velo{
  position:absolute; inset:0;
  background:radial-gradient(ellipse 60% 34% at 50% 46%, rgba(34,29,24,.35) 0%, rgba(34,29,24,.16) 62%, rgba(34,29,24,0) 100%);
  transition:background .9s var(--paso);
}
.portada.marcada .velo{
  background:linear-gradient(to top, rgba(34,29,24,.35) 0%, rgba(34,29,24,.26) 26%, rgba(34,29,24,0) 62%);
}

.portada .centro{ position:relative; z-index:2; max-width:760px; }
.portada .centro *{ text-shadow:0 1px 3px rgba(34,29,24,.72), 0 6px 34px rgba(34,29,24,.82); }
.portada .entrar{ text-shadow:none; }
.sonido-aviso{ text-shadow:0 1px 3px rgba(34,29,24,.95), 0 0 18px rgba(34,29,24,.9); font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;}

.saltar{
  position:absolute; z-index:4;
  top:clamp(14px,3vh,30px); right:clamp(14px,3vw,32px);
  min-height:44px; padding:0 18px;
  font-family:var(--sans); font-size:1rem; letter-spacing:0;
  color:var(--hueso); background:rgba(34,29,24,.42); border:1px solid var(--linea);
  border-radius:8px; backdrop-filter:blur(10px); cursor:pointer;
  transition:background .3s var(--paso), color .3s var(--paso); font-weight:500;}
.saltar:hover,.saltar:focus-visible{ background:var(--hueso); color:var(--tinta); }
.portada.marcada .saltar{ opacity:0; pointer-events:none; }

/* ⚠️ Vivía arriba, a todo lo ancho: en teléfono el botón SALTAR INTRO
   —que va arriba a la derecha— se le encimaba y lo partía a media palabra.
   Se baja al pie, centrado, donde no compite con nada, y sube de --apenas
   a --tenue porque sobre cielo claro el gris tenue desaparecía. */
.sonido-aviso{
  position:absolute; bottom:clamp(16px,3.5vh,34px); left:0; right:0;
  z-index:3;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em; text-transform:uppercase;
  color:var(--tenue);
  opacity:0; transition:opacity 1s var(--paso) .4s;
}
.portada.viva .sonido-aviso{ opacity:1; }

.intro-linea{
  font-family:var(--serif);
  font-size:clamp(1.1875rem,calc(2.3vw*var(--escala)),1.875rem);
  line-height:1.45;
  color:var(--hueso);
  margin:0 auto;
  max-width:22ch;
  opacity:0; transform:translateY(14px);
  transition:opacity .9s var(--paso), transform .9s var(--paso);
  position:absolute; left:50%; top:50%;
  translate:-50% -50%;
  width:min(90vw,700px);
}
.intro-linea.dentro{ opacity:1; transform:translateY(0); }
.intro-linea.presenta{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas);
}

.marca{
  opacity:0; transform:translateY(18px);
  transition:opacity 1.3s var(--paso), transform 1.3s var(--paso);
}
.marca.dentro{ opacity:1; transform:translateY(0); }
.marca h1{
  font-family:var(--display); font-weight:600;
  font-size:clamp(3.25rem,calc(11.5vw*var(--escala)),8.75rem);
  line-height:1.05; letter-spacing:0; margin:0;
}
.marca .sufijo{
  font-family:var(--sans); font-size:var(--t-ancla);
  letter-spacing:0;
  color:var(--ambar); margin-top:18px;
}
.marca .sitio{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas); margin-top:8px;
}

.entrar{
  margin-top:clamp(30px,5vh,52px);
  display:inline-flex; align-items:center; justify-content:center;
  min-height:52px; padding:0 40px;
  background:rgba(34,29,24,.44); backdrop-filter:blur(10px);
  color:var(--hueso);
  border:1px solid rgba(243,238,228,.5); border-radius:8px;   /* §5.2: 8 px, no píldora */
  font-family:var(--sans); font-size:1rem; font-weight:500;
  letter-spacing:0;
  cursor:pointer;
  transition:background .5s var(--paso), border-color .5s var(--paso), color .5s var(--paso);
}
.entrar:hover,.entrar:focus-visible{ background:var(--hueso); color:var(--tinta); border-color:var(--hueso); }
.entrar-pie{
  margin-top:16px; font-family:var(--mono); font-size:var(--t-tecn);
  letter-spacing:.08em; text-transform:uppercase; color:var(--apenas);
}

/* ─────────────────────────────────────────────────────────────
   2. BARRA SUPERIOR + ÍNDICE DE CAPÍTULOS
   ───────────────────────────────────────────────────────────── */
.barra{
  position:fixed; top:0; left:0; right:0; z-index:80;
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; padding:16px clamp(14px,3vw,32px);
  pointer-events:none;
  opacity:0; transform:translateY(-10px);
  transition:opacity .8s var(--paso), transform .8s var(--paso);
}
body.dentro .barra{ opacity:1; transform:translateY(0); }
.barra > *{ pointer-events:auto; }
.barra::before{
  content:''; position:absolute; inset:0; z-index:-1;
  background:linear-gradient(to bottom, rgba(34,29,24,.62), rgba(34,29,24,0));
  transition:background .35s var(--paso);
}
/* sobre el cierre (fondo sólido) la barra deja de ser un degradado:
   si no, el texto se transparenta a través de ella y se encima. */
body.fin .barra::before{
  background:var(--tinta);
  box-shadow:0 1px 0 var(--linea);
}

/* El área tocable llega a 44px sin mover un pixel del diseño: el alto mínimo
   crece y el margen negativo devuelve exactamente lo que creció, así la barra
   no se empuja. Medía 143×30 y en teléfono el pulgar se le iba. */
.marca-min{
  font-family:var(--display); font-size:1.0625rem; font-weight:500;
  letter-spacing:0; text-decoration:none; line-height:1;
  display:inline-flex; flex-direction:column; justify-content:center;
  min-height:44px; margin-block:-7px;
}
.marca-min span{
  display:block; font-family:var(--mono); font-size:var(--t-tecn);
  letter-spacing:.08em; text-transform:uppercase; color:var(--apenas); margin-top:4px;
}

.barra-der{ display:flex; align-items:center; gap:8px; }

.btn-icono{
  min-width:44px; min-height:44px;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:0 15px;
  background:rgba(34,29,24,.5); backdrop-filter:blur(10px);
  border:1px solid var(--linea); border-radius:100px;
  color:var(--hueso); cursor:pointer;
  font-family:var(--mono); font-size:var(--t-tecn); font-weight:400;
  letter-spacing:.08em; text-transform:uppercase;
  transition:background .35s var(--paso), border-color .35s var(--paso);
}
.btn-icono:hover{ background:rgba(40,32,22,.75); border-color:var(--apenas); }
.btn-icono svg{ width:14px; height:14px; flex:none; }

/* medidor de avance del recorrido completo */
.medidor{
  position:fixed; top:0; left:0; right:0; height:2px; z-index:90;
  background:rgba(243,238,228,.09);
  opacity:0; transition:opacity .6s;
}
body.dentro .medidor{ opacity:1; }
.medidor i{
  display:block; height:100%; width:100%;
  background:linear-gradient(90deg,var(--tierra),var(--ambar));
  transform:scaleX(0); transform-origin:0 50%;
}

/* ─────────────────────────────────────────────────────────────
   3. EL MENÚ (índice + mapa + accesibilidad)
   ───────────────────────────────────────────────────────────── */
.menu{
  position:fixed; inset:0; z-index:95;
  background:rgba(34,29,24,.94); backdrop-filter:blur(18px);
  opacity:0; visibility:hidden;
  transition:opacity .6s var(--paso), visibility .6s;
  overflow-y:auto; overscroll-behavior:contain;
  padding:80px clamp(18px,5vw,64px) calc(48px + var(--safe));
}
.menu.abierto{ opacity:1; visibility:visible; }
.menu-cerrar{ position:absolute; top:16px; right:clamp(14px,3vw,32px); }

.menu-tit{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas);
  padding-bottom:12px; border-bottom:1px solid var(--linea); margin:0 0 6px;
}
.menu-cols{
  display:grid; gap:clamp(30px,5vw,64px);
  grid-template-columns:1fr; max-width:1180px; margin:0 auto;
}
@media (min-width:900px){ .menu-cols{ grid-template-columns:1.4fr .9fr; } }

.indice{ list-style:none; margin:0; padding:0; }
.indice li{ border-bottom:1px solid var(--linea); }
.indice button{
  width:100%; min-height:56px;
  display:flex; align-items:baseline; gap:16px;
  padding:16px 4px; background:none; border:0; cursor:pointer;
  color:var(--tenue); text-align:left;
  transition:color .35s var(--paso), padding-left .35s var(--paso);
}
.indice button:hover{ color:var(--hueso); padding-left:10px; }
.indice .num{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  color:var(--apenas); flex:none; width:22px;
}
.indice .nom{ font-family:var(--display); font-size:clamp(1.5rem,calc(3.2vw*var(--escala)),2.375rem); line-height:1.1; }
.indice .dato{
  margin-left:auto; font-family:var(--mono); font-size:var(--t-tecn);
  letter-spacing:.08em; text-transform:uppercase; color:var(--apenas); flex:none;
}
.indice li.visitado button{ color:var(--hueso); }
.indice li.actual button{ color:var(--ambar); }
.indice li.actual .num, .indice li.actual .dato{ color:var(--ambar); }

.leyenda{
  display:flex; flex-wrap:wrap; gap:16px; margin-top:20px;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas);
}
.leyenda span{ display:inline-flex; align-items:center; gap:7px; }
.leyenda i{ width:7px; height:7px; border-radius:50%; background:var(--apenas); }
.leyenda .l-act i{ background:var(--ambar); }
.leyenda .l-vis i{ background:var(--hueso); }

.opciones{ display:flex; flex-direction:column; gap:2px; }
.opciones label{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  min-height:48px; padding:6px 2px;
  border-bottom:1px solid var(--linea);
  /* 11.5 → 12 px: el panel de accesibilidad era de los textos más chicos de
     la página. Un menú que ofrece «texto más grande» escrito en el tamaño más
     chico se contradice a sí mismo. */
  font-family:var(--sans); font-size:.75rem; letter-spacing:0;
  color:var(--tenue); cursor:pointer;
}
.opciones input{ position:absolute; opacity:0; pointer-events:none; }
.palanca{
  width:42px; height:24px; border-radius:100px; flex:none;
  border:1px solid var(--linea); background:rgba(243,238,228,.06);
  position:relative; transition:background .3s var(--paso), border-color .3s;
}
.palanca::after{
  content:''; position:absolute; top:3px; left:3px;
  width:16px; height:16px; border-radius:50%; background:var(--apenas);
  transition:transform .3s var(--paso), background .3s;
}
input:checked + .palanca{ background:rgba(201,151,63,.28); border-color:var(--ambar); }
input:checked + .palanca::after{ transform:translateX(18px); background:var(--ambar); }

/* ─────────────────────────────────────────────────────────────
   4. LA ESCENA — el corazón: escenario pegado + bloques por rango
   ───────────────────────────────────────────────────────────── */
.recorrido{ position:relative; z-index:1; background:transparent; }

.cap{ position:relative; background:transparent; }

.pegado{
  position:sticky; top:0;
  height:100vh; height:100svh;
  overflow:hidden;
}

/* EL MUNDO: un solo lienzo 3D detrás de todo el recorrido. No se repinta
   por capítulo ni se reproduce nada — el scroll mueve la cámara. */
.mundo{
  position:fixed; inset:0;
  width:100%; height:100%;
  display:block;
  z-index:0;
  background:#c9d8e6;
  /* §4.8: el mundo 3D se ve tal cual; nada de saturar ni contrastar */
}
html.bloqueado .mundo{ filter:blur(6px); }   /* solo desenfoque de foco */
.sin-js{ position:fixed; inset:auto 0 0 0; z-index:99; margin:0; padding:18px; text-align:center; background:var(--tinta); color:#fff; }

/* las secuencias de cuadros quedaron derogadas por el mundo 3D */
.lienzo, .poster{ display:none; }

/* gradiente local detrás del texto. Tope duro .35 y SOLO en los bordes
   donde cae el copy — nunca una capa negra sobre toda la imagen. */
.velo{
  position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(to top,    rgba(34,29,24,.35) 0%,  rgba(34,29,24,0) 42%),
    linear-gradient(to bottom, rgba(34,29,24,.28) 0%,  rgba(34,29,24,0) 30%);
}
.grano{
  position:absolute; inset:0; pointer-events:none; opacity:.055;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode:overlay;
}

/* ── los bloques ─────────────────────────────────────────────── */
.bloque{
  position:absolute; inset:0;
  display:flex; align-items:flex-end;
  padding:clamp(22px,4vw,64px);
  padding-bottom:calc(clamp(46px,9vh,110px) + var(--safe));
  opacity:0; visibility:hidden;
  transition:opacity .75s var(--paso), visibility .75s, transform .75s var(--paso);
  transform:translateY(22px);
  pointer-events:none;
}
.bloque.dentro{ opacity:1; visibility:visible; transform:translateY(0); pointer-events:auto; }
.bloque .caja{ max-width:min(560px,92vw); position:relative; }
/* la sombra propia del texto es lo que lo salva sobre fondo claro sin
   oscurecer un solo pixel de la escena alrededor. */
.bloque .caja > *{ text-shadow:0 1px 2px rgba(34,29,24,.62), 0 10px 34px rgba(34,29,24,.72); }
/* velo LOCAL detrás del texto — no una capa negra encima de la escena.
   El recorrido pasa por paredes color crema y por el lago a mediodía: ahí
   el texto blanco se perdía. Esto es una sombra suave que solo existe
   donde hay letras, se desvanece antes de llegar al borde y NUNCA pasa
   de .35 de opacidad (tope de la doctrina). */
.bloque .caja::before{
  content:''; position:absolute; z-index:0;
  inset:clamp(-46px,-6vw,-26px) clamp(-56px,-7vw,-30px);
  background:radial-gradient(ellipse at 32% 60%,
    rgba(10,8,5,.35) 0%, rgba(10,8,5,.35) 40%,
    rgba(10,8,5,.22) 62%, rgba(10,8,5,.08) 78%, rgba(10,8,5,0) 90%);
  filter:blur(16px); pointer-events:none;
}
.bloque.centro .caja::before{ background:radial-gradient(ellipse at 50% 50%,
    rgba(10,8,5,.35) 0%, rgba(10,8,5,.35) 42%,
    rgba(10,8,5,.21) 64%, rgba(10,8,5,.07) 80%, rgba(10,8,5,0) 91%); }
.bloque .caja > *{ position:relative; z-index:1; }
/* la sombra de texto hace el resto del trabajo sin oscurecer nada.
   El peor caso no es el cuadro oscuro: es el CLARO —la ladera de pasto seco
   a media tarde en el capítulo 2—, y ahí lo que salva al texto blanco es el
   filo oscuro pegado a la letra, no el velo. */
/* ⚠️ ESTAS REGLAS LE GANAN A LA GENÉRICA `.bloque .caja > *` de más abajo:
   dos clases + un elemento pesan más que dos clases + `*`. Por eso reforzar
   la genérica NO servía de nada y el título del interior seguía saliendo
   blanco sobre pared blanca — la sombra fuerte se escribía ahí abajo y esta
   regla, más específica, la pisaba con la débil. La sombra fuerte tiene que
   vivir AQUÍ. */
.bloque .caja h2, .bloque .caja h3,
.bloque .caja .parrafo, .bloque .caja .cap-num{
  text-shadow:0 1px 2px rgba(34,29,24,.92), 0 0 10px rgba(34,29,24,.85),
              0 2px 12px rgba(34,29,24,.8), 0 12px 40px rgba(34,29,24,.7);
}
/* el rótulo dorado es el más frágil de todos: chico, fino y sin blanco */
.bloque .caja .cap-num, .bloque .caja .rotulo{
  text-shadow:0 1px 2px rgba(34,29,24,.95), 0 0 12px rgba(34,29,24,.9),
              0 2px 14px rgba(34,29,24,.8);
}

/* ── VARIANTES DE POSICIÓN (§4.1) ───────────────────────────────────────
   El texto NO va centrado sobre la escena: se ancla a un costado y a una
   altura, para dejar libre lo que se está mirando (los caballos, la ladera,
   el lago). `.centro` se retiró del HTML de los seis arranques de capítulo;
   la regla se queda por si el motor la vuelve a poner en algún estado.
   En teléfono todo esto colapsa a una sola columna abajo (§8). */
.bloque.centro{ align-items:center; justify-content:center; text-align:center; }
.bloque.centro .caja{ max-width:min(680px,92vw); }
.bloque.derecha{ justify-content:flex-end; }
.bloque.media { align-items:center; }
.bloque.alta  { align-items:flex-start; padding-top:clamp(88px,13vh,136px); }
/* el velo local sigue al texto: si el bloque se fue a la derecha, la mancha
   suave también — si no, quedaba iluminando el lado vacío. */
.bloque.derecha .caja::before{ background:radial-gradient(ellipse at 68% 60%,
    rgba(34,29,24,.35) 0%, rgba(34,29,24,.35) 40%,
    rgba(34,29,24,.22) 62%, rgba(34,29,24,.08) 78%, rgba(34,29,24,0) 90%); }

/* ── EL FILETE (§4.5) — la firma visual del proyecto ────────────────────
   Anatomía de la placa: CAP. 0X (mono) → título (Fraunces) → línea de
   anclaje (Archivo) → filete de 1 px × 48 px en --arena. No existía en
   ninguna parte del sitio; es lo que hace que una placa se lea como de
   ESTE proyecto y no de cualquier recorrido inmersivo. */
.b-intro .caja::after,
.b-edit  .caja::after{
  content:''; display:block; position:relative; z-index:1;
  width:48px; height:1px; background:var(--arena);
  margin-top:var(--esp-3);
}
.bloque.derecha .caja::after{ margin-left:auto; }
.bloque.centro  .caja::after{ margin-inline:auto; }

/* — apertura de capítulo (placa, §3.2: Fraunces 600, 72/40) — */
.b-intro .cap-num{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--arena); margin:0 0 var(--esp-2);
}
.b-intro h2{
  font-family:var(--display); font-weight:600;
  font-size:var(--t-placa); line-height:1.05; letter-spacing:0;
  margin:0 0 var(--esp-2);
}
/* línea de anclaje: Archivo 400, 20/16 — NO es el bloque editorial */
.b-intro .parrafo{
  font-family:var(--sans); font-weight:400;
  font-size:var(--t-ancla); line-height:1.45; margin-inline:0;
  max-width:34ch;
}

/* — bloque editorial de parada — */
.b-edit h3{
  font-family:var(--display); font-weight:600;
  font-size:var(--t-sub); line-height:1.1; letter-spacing:0;
  margin:0 0 var(--esp-2);
}
.b-edit .parrafo + .parrafo{ margin-top:var(--esp-2); }

/* — la ficha técnica (calco de las "Inscription" del Getty) — */
.ficha{
  /* §5.1: la ficha es PAPEL sobre la escena, no un vidrio oscuro. El dato
     duro del levantamiento se lee en tinta sobre cal — así se distingue de
     la narración, que sí vive dentro del video. */
  background:var(--cal); color:var(--tinta-papel);
  border:1px solid rgba(42,36,29,.10); border-left:2px solid var(--arena);
  border-radius:8px;
  box-shadow:0 1px 4px rgba(42,36,29,.12), 0 18px 48px rgba(34,29,24,.30);
  padding:var(--esp-3);
  max-width:min(480px,92vw);
}
@media (min-width:761px){ .ficha{ padding:var(--esp-4); } }
/* sobre papel el texto NO lleva la sombra que necesita sobre video */
.ficha, .ficha *{ text-shadow:none !important; }
.ficha .rotulo{ margin-bottom:var(--esp-2); color:var(--madera); }
.ficha dl{ margin:0; display:grid; grid-template-columns:1fr auto; gap:9px 18px; }
.ficha dt{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--madera);
}
.ficha dd{
  margin:0; font-family:var(--sans); font-size:var(--t-cuerpo); font-weight:500;
  letter-spacing:0; text-align:right; color:var(--tinta-papel);
}
.ficha .fuente{
  margin:var(--esp-3) 0 0; padding-top:13px; border-top:1px solid rgba(42,36,29,.14);
  font-family:var(--mono); font-size:var(--t-tecn); line-height:1.6;
  letter-spacing:.08em; color:var(--madera);
}

/* — hotspot: el punto pulsante — */
.punto{
  position:absolute; z-index:5;
  width:44px; height:44px; margin:-22px 0 0 -22px;
  display:grid; place-items:center;
  background:none; border:0; cursor:pointer; padding:0;
  opacity:0; visibility:hidden;
  transition:opacity .6s var(--paso), visibility .6s;
}
.punto.dentro{ opacity:1; visibility:visible; }
.punto::before{
  content:''; position:absolute; width:13px; height:13px; border-radius:50%;
  background:var(--ambar); box-shadow:0 0 0 1px rgba(34,29,24,.5);
}
.punto::after{
  content:''; position:absolute; width:13px; height:13px; border-radius:50%;
  border:1px solid var(--ambar);
  animation:latido 2.6s var(--paso) infinite;
}
@keyframes latido{
  0%{ transform:scale(1); opacity:.9; }
  70%{ transform:scale(3.4); opacity:0; }
  100%{ transform:scale(3.4); opacity:0; }
}
.punto .etiq{
  position:absolute; left:30px; top:50%; translate:0 -50%;
  white-space:nowrap;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--hueso);
  background:rgba(34,29,24,.72); backdrop-filter:blur(8px);
  border:1px solid var(--linea); border-radius:100px;
  padding:7px 13px;
  opacity:0; transform:translateX(-6px);
  transition:opacity .35s var(--paso), transform .35s var(--paso);
}
.punto:hover .etiq,.punto:focus-visible .etiq{ opacity:1; transform:translateX(0); }
/* El punto del capítulo 3 está al 60 % del ancho: su etiqueta abría hacia la
   derecha y a 375 px se salía de la pantalla. data-lado="izq" la voltea. */
.punto[data-lado="izq"] .etiq{ left:auto; right:30px; transform:translateX(6px); }
/* ⚠️ ESTA PASTILLA CRECE Y SE SALE DE LA PANTALLA (medido a 375 px, 17-ago).
   Con «texto más grande» la etiqueta pasaba de 248 a 288 px de ancho: se iba
   42 px fuera del borde derecho, cortada, y la de la izquierda se salía por el
   otro lado (-17 px). La culpa es del `nowrap`, que le prohíbe plegarse.
   Se le permite plegarse SOLO con el interruptor puesto, y no por timidez: el
   `.etiq` está posicionado dentro del `.punto`, que mide 44 px, así que en
   cuanto se le quita el `nowrap` el navegador la encoge al ancho de su palabra
   más larga —126 px, dos renglones— aunque haya sitio de sobra. Aplicarlo
   siempre le cambiaba la forma a las etiquetas con el interruptor APAGADO, que
   es justo lo que este trabajo tiene prohibido tocar.
   `width:max-content` la devuelve a un renglón cuando cabe (en compu sigue
   siendo una sola línea) y el tope la pliega solo cuando el teléfono no da:
   300 px pasa el ancho que necesita a 118% (288), y `100vw - 160px` es el
   sitio que de verdad queda a los lados de un punto a 375 y a 360 px. */
html.texto-grande .punto .etiq{
  white-space:normal;
  width:max-content;
  max-width:min(300px, calc(100vw - 160px));
}
.punto[data-lado="izq"]:hover .etiq,
.punto[data-lado="izq"]:focus-visible .etiq{ transform:translateX(0); }

/* — comparador HOY / PROYECTO (el "past & present" del Getty) — */
.comparador{
  position:absolute; inset:0; z-index:6;
  opacity:0; visibility:hidden;
  transition:opacity .8s var(--paso), visibility .8s;
}
.comparador.abierto{ opacity:1; visibility:visible; }
.comparador .capa{ position:absolute; inset:0; overflow:hidden; }
.comparador .capa img{ width:100%; height:100%; object-fit:cover; }
.comparador .capa.frente{ clip-path:inset(0 0 0 var(--corte,50%)); }
.comparador .tirador{
  position:absolute; top:0; bottom:0; left:var(--corte,50%);
  width:2px; background:var(--hueso); z-index:2; cursor:ew-resize;
  touch-action:none;
}
.comparador .tirador::before{
  content:''; position:absolute; left:50%; top:50%; translate:-50% -50%;
  width:52px; height:52px; border-radius:50%;
  background:rgba(34,29,24,.6); backdrop-filter:blur(8px);
  border:1px solid var(--hueso);
}
.comparador .tirador::after{
  content:'‹ ›'; position:absolute; left:50%; top:50%; translate:-50% -50%;
  font-family:var(--sans); font-size:.9375rem; letter-spacing:0; color:var(--hueso);
}
.comparador .sello{
  position:absolute; top:clamp(66px,10vh,96px); z-index:3;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--hueso);
  background:rgba(34,29,24,.66); backdrop-filter:blur(8px);
  border:1px solid var(--linea); border-radius:100px; padding:7px 14px;
}
.comparador .sello.izq{ left:clamp(16px,4vw,44px); }
.comparador .sello.der{ right:clamp(16px,4vw,44px); border-color:var(--ambar); color:var(--ambar-alto); }
.comparador .cerrar{ position:absolute; bottom:calc(24px + var(--safe)); left:50%; translate:-50% 0; z-index:3; }

/* — RANURAS DE IMAGEN: el enchufe de las imágenes que llegan aparte —
   Una ranura reusa el comparador tal cual (capas, arrastre, cerrar). Lo único
   propio es esto:

   1) LA RANURA VACÍA NO SE VE. Nace con el atributo `hidden` en el panel Y en
      su botón, y `[hidden]{display:none!important}` (más abajo en este mismo
      archivo) lo hace de verdad — sin esa regla, `.btn-icono` y `.btn-ranura`
      traen display:flex y se lo comerían, que es exactamente el defecto que ya
      pasó una vez con el botón de sonido. Si el archivo no existe, js/sitio.js
      además BORRA los dos del documento: no hay marco, ni hueco, ni texto de
      «imagen por venir». Un marco vacío repetido es una promesa rota.
   2) EL FONDO OSCURO DEBAJO DE LA CAPA. Sin él, el instante entre que el panel
      se abre y el JPEG termina de pintarse era un destello del mundo 3D a
      través del hueco. Con --tinta debajo, el panel abre en negro y la imagen
      aparece encima.
   3) EL RÓTULO HONESTO. Si la imagen vive en img/por-venir/ es un render de
      algo que no está construido, y el sello lo dice — centrado, no en un
      costado, porque no describe un lado del comparador sino la imagen entera.
      Si vive en img/ya-existe/ es una foto real y no lleva sello ninguno.
      Nunca al revés: la carpeta es la que manda, no el gusto de nadie. */
.comparador.ranura .capa{ background:var(--tinta); }
.comparador.ranura .sello.honesto{
  left:50%; right:auto; translate:-50% 0;
  max-width:calc(100vw - 32px);
  text-align:center; text-wrap:balance;
  border-color:var(--ambar); color:var(--ambar-alto);
}

/* — LA RANURA EN MOVIMIENTO —
   Cuando la parada tiene video, el panel es el mismo: mismo fondo, mismo
   sello, mismo botón de cerrar. Solo cambian tres cosas.

   1) EL VIDEO SE ENCUADRA COMO LA FOTO. `object-fit:cover` sobre la capa
      entera: en un teléfono vertical un 16:9 metido a la fuerza dejaría dos
      franjas negras arriba y abajo, y el panel se leería como un reproductor,
      no como una ventana al lugar.
   2) EL PÓSTER SOSTIENE EL HUECO. El primer fotograma va como `poster`, así
      que el panel abre CON imagen mientras el video baja. Sin esto el visitante
      del teléfono ve negro los primeros dos segundos y cierra.
   3) EL BOTÓN DE SONIDO ARRIBA A LA DERECHA, lejos del de cerrar (que va
      abajo al centro) y lejos del sello. Se mide contra el dedo, no contra sí
      mismo: 44 px de alto y separado de sus vecinos.
   Y no hay tirador: comparar dos videos arrastrando no se entiende con el
   dedo. Aquí lo que hay que ver es la escena. */
.comparador .capa-video{ background:var(--tinta); }
.comparador .capa-video video{
  width:100%; height:100%; object-fit:cover; display:block;
  background:var(--tinta);
}
.comparador .son{
  position:absolute; z-index:3;
  top:clamp(66px,10vh,96px); right:clamp(16px,4vw,44px);
  min-height:44px; padding:0 16px;
}
/* Con el sello centrado y el botón a la derecha, las dos cajas se tocaban:
   medido a 360 px, 9 px de ancho por 6 de alto de letra sobre letra. El
   número suelto de antes (66 + 52) solo tapaba el caso de 375 px y se ataba a
   un corte de 520: arriba de ese ancho el sello se vuelve una sola línea más
   larga y los dos se vuelven a encontrar. Así que el sello ya no se coloca con
   una cifra: se cuelga del botón —su mismo arranque, más los 44 px del botón,
   más 10 de aire— y por eso no hay ancho ni alto de pantalla en el que puedan
   volver a tocarse, ni cuando el clamp del botón crece a 96 px. */
.comparador.con-video .sello.honesto{ top:calc(clamp(66px,10vh,96px) + 54px); }
/* Quien pide menos movimiento no recibe un video que arranca solo: eso se
   decide en js/sitio.js (`menosMovimiento`), que le pone los controles nativos
   y no le llama a play. Aquí solo se le da sitio al barrote de controles para
   que no le tape el botón de cerrar. */
.comparador .capa-video video[controls]{ padding-bottom:0; }

/* el botón de la ranura dentro de una tarjeta de modelo: la tarjeta es papel
   claro (.ficha-mod), así que aquí no sirve el .btn-icono oscuro de la barra.
   44 px de alto, del ancho de la tarjeta, para que se toque con el pulgar. */
.btn-ranura{
  margin-top:14px; width:100%; min-height:44px;
  display:inline-flex; align-items:center; justify-content:center;
  padding:0 14px;
  background:transparent; border:1px solid rgba(42,36,29,.2); border-radius:100px;
  color:var(--tierra); cursor:pointer;
  font-family:var(--mono); font-size:var(--t-tecn); font-weight:400;
  letter-spacing:.08em; text-transform:uppercase;
  transition:background .35s var(--paso), border-color .35s var(--paso);
}
.btn-ranura:hover{ background:rgba(42,36,29,.06); border-color:var(--tierra); }

/* — el aviso de "toca para ver" — */
.pista{
  position:absolute; left:50%; translate:-50% 0;
  bottom:calc(22px + var(--safe)); z-index:7;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas);
  display:flex; align-items:center; gap:10px;
  opacity:0; transition:opacity .7s var(--paso);
  pointer-events:none;
}
.pista.dentro{ opacity:1; }
.pista .flechita{
  width:1px; height:22px;
  background:linear-gradient(to bottom,var(--apenas),transparent);
  animation:cae 2.2s var(--paso) infinite;
}
@keyframes cae{ 0%{ opacity:0; transform:translateY(-8px);} 40%{opacity:1;} 100%{ opacity:0; transform:translateY(8px);} }

/* — la placa de "capítulo actual" abajo a la izquierda — */
.placa{
  position:fixed; left:clamp(14px,3vw,32px); bottom:calc(18px + var(--safe));
  z-index:70; pointer-events:none;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--tenue);
  opacity:0; transform:translateY(8px);
  transition:opacity .7s var(--paso), transform .7s var(--paso);
}
body.dentro .placa{ opacity:1; transform:translateY(0); }
/* en el cierre ya no hay capítulo que rotular: la placa se quedaba encendida
   sobre el pie de página, anunciando un capítulo que dejó de estar en pantalla */
body.fin .placa{ opacity:0; transform:translateY(8px); }
.placa b{ color:var(--hueso); font-weight:500; }

/* — EL CRÉDITO DE LA ORTOFOTO —
   El terreno se levanta sobre teselas de Esri World Imagery: el crédito es
   obligatorio mientras ese lienzo esté a la vista, así que vive en el chrome
   FIJO del sitio y no dentro de un capítulo —el mundo 3D se ve durante todo
   el recorrido, no en una escena—. Va abajo a la DERECHA: la izquierda es de
   la placa del capítulo y el medidor de avance vive arriba, en 2 px de alto.
   Sobre el cierre se apaga: ahí el fondo es sólido, ya no hay ortofoto que
   acreditar y taparía el pie de página; el crédito queda escrito de planta en
   la lista de "quién hace qué". */
.credito-mundo{
  position:fixed; z-index:71; margin:0; pointer-events:none;
  right:clamp(14px,3vw,32px); bottom:calc(18px + var(--safe));
  /* estaba en 10 px, el texto más chico del sitio. Subió a 11 y ahora a 12:
     11 px seguía siendo el suelo de toda la página, y en un teléfono al sol
     —que es donde se ve este sitio— una letra de 11 con 78 % de opacidad
     sobre video no se lee, se adivina. 12 px es el piso del sitio. */
  font-family:var(--mono); font-size:.75rem; letter-spacing:.08em; line-height:1.4;
  color:rgba(243,238,228,.78);
  /* el peor caso es el fotograma CLARO —la arena y el lago a mediodía—: lo
     que salva al texto es su propio filo oscuro, nunca una capa sobre la
     escena (tope de la doctrina). */
  text-shadow:0 1px 2px rgba(34,29,24,.95), 0 0 8px rgba(34,29,24,.9), 0 0 18px rgba(34,29,24,.8);
  opacity:0; transform:translateY(8px);
  transition:opacity .7s var(--paso), transform .7s var(--paso);
}
body.dentro .credito-mundo{ opacity:1; transform:translateY(0); }
body.fin .credito-mundo{ opacity:0; transform:translateY(8px); }

/* LA LEYENDA DE LO PROYECTADO — vive DENTRO de la vista del recorrido, no en
   un panel de al lado. Mismo tratamiento que el crédito de Esri: filo oscuro
   propio contra el fotograma claro, nunca una capa encima de la escena. Va
   anclada a la izquierda porque el crédito ya ocupa la derecha; con esos dos
   anclajes opuestos no se pisan a ningún ancho. Se enciende y se apaga con la
   misma condición que el crédito, así que nunca aparece sobre el cierre. */
.leyenda-mundo{
  position:fixed; z-index:71; margin:0; pointer-events:none;
  /* ⚠️ SE ENCIMABA CON EL CRÉDITO. Anclada solo a la izquierda, a 375 px la
     leyenda llegaba a x=232 y el crédito de Esri arrancaba en x=100: se
     pisaban. Anclarlos a esquinas opuestas NO basta cuando el crédito envuelve
     a dos renglones. Ahora la leyenda sube 52 px sobre la línea del crédito,
     que es más que sus dos renglones, así que viven en filas distintas a
     cualquier ancho y ya no dependen de cuánto mida el otro. */
  left:clamp(14px,3vw,32px); bottom:calc(18px + var(--safe) + 52px);
  max-width:min(52vw,320px);
  display:flex; flex-direction:column; gap:.28em;
  /* 11 → 12 px: esta leyenda no es adorno, es la que dice cuántas cabañas
     están de pie y cuántas están proyectadas. Un dato que decide la lectura
     del mapa no se publica en el tamaño más chico de la página. */
  font-family:var(--mono); font-size:.75rem; letter-spacing:.06em; line-height:1.35;
  color:rgba(243,238,228,.82);
  text-shadow:0 1px 2px rgba(34,29,24,.95), 0 0 8px rgba(34,29,24,.9), 0 0 18px rgba(34,29,24,.8);
  opacity:0; transform:translateY(8px);
  transition:opacity .7s var(--paso), transform .7s var(--paso);
}
.leyenda-mundo .ll-linea{ display:flex; align-items:center; gap:.5em; }
.leyenda-mundo .ll-marca{
  /* el cuadrito ES la leyenda: si no se distingue relleno de contorno, el
     renglón no explica nada. A .5625rem de teléfono, .85em daban 5 px y los
     dos se veían igual. Mínimo en px para que el teléfono no lo achique. */
  flex:0 0 auto; width:1em; height:1em; min-width:9px; min-height:9px; border-radius:2px;
  box-shadow:0 1px 2px rgba(34,29,24,.95);
}
/* el contorno blanco es LA MISMA señal que se dibuja sobre cada volumen
   proyectado en el 3D: aquí se repite en chiquito para que se pueda emparejar
   de un vistazo, sin leer. */
.leyenda-mundo .ll-proy{ border:1.5px solid rgba(243,238,228,.92); background:transparent; }
.leyenda-mundo .ll-hecha{ border:1.5px solid rgba(243,238,228,.92); background:rgba(243,238,228,.92); }
.leyenda-mundo .ll-cuenta{ opacity:.72; padding-left:1.35em; }
body.dentro .leyenda-mundo{ opacity:1; transform:translateY(0); }
body.fin .leyenda-mundo{ opacity:0; transform:translateY(8px); }
/* en teléfono el crédito de Esri baja a dos o tres renglones: la leyenda se
   queda en su esquina y se acorta, nunca se encima. */
@media (max-width:520px){
  /* solo se acota el ancho: el tamaño NO baja aquí, o la leyenda
     caería debajo del piso de 11 px que acabamos de fijar. */
  .leyenda-mundo{ max-width:58vw; }
}
/* ⚠️⚠️ FOTOGRAFIADO A 375 × 812: LA LEYENDA SE ENCIMABA CON EL TEXTO DEL
   CAPÍTULO, letra sobre letra, y ninguno de los dos se podía leer. Se veía
   en el capítulo 4 (encima de la tarjeta "La de pilotes") y en el 5 (encima
   de "Para qué sirve un lago").
   El pleito anterior de esta leyenda fue contra el crédito de Esri y se
   resolvió subiéndola 52 px sobre él. Correcto entonces, y ahí estaba el
   precio que no se anotó: en la compu el texto del capítulo vive en una
   columna a un lado y abajo-izquierda queda libre, pero en teléfono TODO
   se apila en una sola columna y el pie de pantalla es justo donde caen la
   tarjeta y el párrafo. O sea que abajo-izquierda dejó de ser una esquina
   vacía: en teléfono es la zona más ocupada de la pantalla.
   Se ancla arriba, debajo del rótulo "El Cortijo", que en teléfono es cielo
   en las cinco paradas fotografiadas. Se conserva la leyenda entera —los
   dos renglones y la cuenta—: es lo que explica el contorno blanco de las
   cabañas proyectadas, y una leyenda que no se lee ya no explica nada. */
@media (max-width:620px){
  .leyenda-mundo{
    top:calc(var(--safe) + 58px); bottom:auto;
    max-width:min(72vw,300px);
  }
  /* al angostarse, el segundo renglón se parte en dos líneas y el cuadrito
     centrado quedaba flotando en medio del hueco, sin tocar ninguna de las
     dos: el cuadrito se alinea con la PRIMERA línea, que es la que nombra. */
  .leyenda-mundo .ll-linea{ align-items:flex-start; }
  .leyenda-mundo .ll-marca{ margin-top:.18em; }
}
/* ⚠️⚠️⚠️ Y EN LA COMPU CHOCA IGUAL — el comentario de arriba afirmó que
   "abajo-izquierda queda libre en la compu" SIN MEDIRLO, y es falso.
   Medido con la caja de cada letra, no de ojo, en 51 paradas del recorrido
   (de 0.00 a 1.00, cada 0.02):
     · 1280 × 800 → choca en 15 de 51 paradas, hasta 6912 px² de letra
       sobre letra (b-intro/parrafo, b-edit/parrafo, .fuente).
     · 1440 × 900 → choca igual, con la leyenda en 32,779 307×51.
   Es estructural, no un caso raro: `.leyenda-mundo` se ancla abajo a la
   izquierda y `.bloque` también (align-items:flex-end + padding-inline
   chico), así que los dos pelean por la MISMA esquina a cualquier ancho de
   compu. La leyenda no se puede mover: arriba no está medido, la derecha es
   del crédito de Esri y los bloques `.derecha` bajan hasta ahí, y encogerla
   la vuelve ilegible —y una leyenda que no se lee no explica nada—.
   Se mueve el texto del capítulo: sube lo justo para dejar libre la franja
   de la leyenda (52 px de separación + sus 51 px de alto = 121 px desde el
   piso; el texto se detiene 133 px arriba del piso).
   PRECIO ANOTADO, que es justo lo que faltó la vez pasada: en la compu el
   texto del capítulo queda ~40 px más alto, o sea menos pegado al borde
   inferior. En ventanas de compu bajitas (≤ 620 px de alto) eso come aire
   real. No se toca el teléfono: ahí la leyenda ya vive arriba (media query
   de 620 px) y esta franja no existe.
   ⚠️ LA REGLA NO VIVE AQUÍ: la sección 8 (teléfono) reescribe el
   padding-bottom de `.bloque` hasta 760 px de ancho —no 620—, así que
   puesta aquí quedaba pisada justo en la franja 621–760. Vive al FINAL
   del archivo, después de la sección 8. */
html.alto-contraste .leyenda-mundo{ color:var(--hueso); }

/* ⚠️ CONTRASTE DE LA ROTULACIÓN FLOTANTE — el peor caso NO es el cielo negro,
   es el fotograma CLARO: arena beige, pared iluminada, cielo de mediodía.
   Ahí el hueso sobre hueso desaparecía (se midió: encabezado, placa de
   capítulo, "CAPÍTULO CINCO" y el párrafo del interior, todos ilegibles).
   Se resuelve con SOMBRA sobre la letra, no oscureciendo la imagen: la
   doctrina prohíbe la capa negra encima del mundo. */
/* y el gris `--tenue` de la placa no aguantó la arena beige del capítulo 1:
   gris claro sobre beige claro es el mismo valor, y ninguna sombra salva un
   texto que no contrasta con su fondo. Sube a hueso, que sí es más claro que
   todo lo que hay abajo, y la sombra hace el filo. */
.marca-min, .placa, .medidor{
  color:var(--hueso);
  text-shadow:0 1px 2px rgba(34,29,24,.95), 0 0 8px rgba(34,29,24,.9),
              0 0 18px rgba(34,29,24,.8);
}
.bloque .caja > *{
  text-shadow:0 1px 2px rgba(34,29,24,.9), 0 2px 10px rgba(34,29,24,.8), 0 12px 40px rgba(34,29,24,.7);
}

/* ─────────────────────────────────────────────────────────────
   5. LOS SELECTORES — elegir lote y elegir cabaña
   Reemplazan la foto del plano y el catálogo de modelos: aquí se
   elige contra el mundo 3D, que es lo que el visitante está viendo.
   ───────────────────────────────────────────────────────────── */
/* ⚠️ EL PANEL SE CORTABA EN PANTALLAS BAJAS (~900 px de alto). El alto del
   panel lo fijaban sus PARTES (lista 392 px + encabezado + ficha) sin que
   nadie mirara cuánta pantalla había: en una laptop de 900 px el último
   renglón —y con la ficha abierta, la ficha entera— quedaba fuera del
   viewport, sin manera de alcanzarlo: el panel es absolute dentro de
   .pegado, que recorta con overflow:hidden. No hay scroll que lo rescate.
   Ahora el TECHO del panel es el viewport (menos la barra de arriba y su
   propio despegue de abajo), el encabezado y la ficha no encogen nunca, y
   lo que sobra lo absorbe la LISTA, que ya es scrolleable por dentro.
   Nada queda inalcanzable: lo que no cabe, se desliza. */
.selector{
  position:absolute; z-index:8;
  left:clamp(16px,4vw,52px);
  bottom:calc(clamp(28px,6vh,64px) + var(--safe));
  width:min(392px,calc(100vw - 32px));
  max-height:min(58vh, calc(100vh - 132px - var(--safe)));
  max-height:min(58svh, calc(100svh - 132px - var(--safe)));
  display:flex; flex-direction:column; gap:12px;
  opacity:0; visibility:hidden; transform:translateY(16px);
  transition:opacity .6s var(--paso), visibility .6s, transform .6s var(--paso);
  pointer-events:none;
}
.selector.dentro{ opacity:1; visibility:visible; transform:none; pointer-events:auto; }
.selector.cabs{ left:auto; right:clamp(16px,4vw,52px); width:min(420px,calc(100vw - 32px)); }

/* el encabezado ("Elige cuál recorrer") queda FIJO: no encoge ni se desliza,
   pase lo que pase con el alto de la pantalla. Lo mismo la ficha del lote. */
.sel-cab, .sel-ficha{ flex:0 0 auto; }
.sel-cab{
  padding:14px 18px 12px;
  background:color-mix(in srgb, var(--noche) 82%, transparent);
  backdrop-filter:blur(14px);
  border:1px solid var(--linea);
  border-bottom:0; border-radius:8px 8px 0 0;
}
.sel-cab .rotulo{ margin:0; }
.sel-pista{
  margin:5px 0 0; font-size:.76rem; letter-spacing:0;
  color:color-mix(in srgb, var(--hueso) calc(58% + var(--alza)), transparent);
}

.sel-lista{
  list-style:none; margin:0; padding:0;
  /* la lista es la parte elástica del panel: se lleva todo el alto que sobre
     y nunca menos de dos renglones. `min-height:0` es lo que le da permiso de
     encoger dentro del flex (sin él, un flex item no baja de su contenido:
     17 renglones × 85 px, y el panel volvía a desbordar la pantalla). */
  flex:1 1 auto; min-height:0;
  max-height:min(46vh,392px); overflow-y:auto; overscroll-behavior:contain;
  background:color-mix(in srgb, var(--noche) 82%, transparent);
  backdrop-filter:blur(14px);
  border:1px solid var(--linea);
  scrollbar-width:thin; scrollbar-color:var(--linea) transparent;
}
/* la señal de que la lista sigue: el borde de abajo se difumina mientras
   quede algo por debajo (js le pone .hay-mas), y se apaga al llegar al final */
.sel-lista.hay-mas{
  /* 34 px de difuminado no alcanzaban: un renglón mide 85, así que el
     siguiente lote se cortaba a la mitad NÍTIDO y se leía como bug, no como
     "hay más". El velo cubre ahora un renglón entero y llega a cero. */
  -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 78px), rgba(0,0,0,.55) calc(100% - 26px), rgba(0,0,0,0) 100%);
          mask-image:linear-gradient(to bottom, #000 calc(100% - 78px), rgba(0,0,0,.55) calc(100% - 26px), rgba(0,0,0,0) 100%);
}
.sel-lista::-webkit-scrollbar{ width:4px; }
.sel-lista::-webkit-scrollbar-thumb{ background:var(--linea); }
.sel-lista li + li{ border-top:1px solid color-mix(in srgb, var(--linea) 60%, transparent); }
.sel-lista button{
  display:grid; grid-template-columns:44px 1fr; gap:2px 12px; align-items:baseline;
  width:100%; min-height:52px; padding:11px 16px;
  background:none; border:0; text-align:left; color:inherit; cursor:pointer;
  transition:background .25s var(--paso);
}
.sel-lista button:hover,
.sel-lista button:focus-visible{ background:color-mix(in srgb, var(--hueso) calc(8% + var(--alza)), transparent); }
.sel-lista button.elegido{ background:color-mix(in srgb, var(--ambar) 15%, transparent); }
.sel-n{
  grid-row:1 / span 2;
  font-family:var(--titular); font-weight:600; font-size:var(--t-ficha); line-height:1;
  color:color-mix(in srgb, var(--hueso) calc(42% + var(--alza)), transparent);
  font-variant-numeric:tabular-nums;
}
.sel-lista button.elegido .sel-n{ color:var(--ambar); }
.sel-t{ font-size:var(--t-cuerpo); line-height:1.3; }
.sel-d{
  /* sin uppercase: convertía "m²" en "M²", que no es una unidad. */
  font-size:var(--t-tecn); letter-spacing:.08em;
  color:color-mix(in srgb, var(--hueso) calc(52% + var(--alza)), transparent);
  font-variant-numeric:tabular-nums; font-family:var(--mono);}

.sel-ficha{
  padding:var(--esp-3);
  background:color-mix(in srgb, var(--noche) 82%, transparent);
  backdrop-filter:blur(14px);
  border:1px solid var(--linea); border-radius:0 0 8px 8px;
}
.sel-ficha[hidden]{ display:none; }
.sel-num{
  margin:0 0 2px; font-size:var(--t-tecn); letter-spacing:.08em; text-transform:uppercase;
  color:var(--ambar); font-family:var(--mono);}
.sel-ficha h4{ margin:0 0 10px; font-family:var(--sans); font-size:var(--t-ficha); font-weight:500; line-height:1.15; }
.sel-ficha dl{ margin:0; display:grid; grid-template-columns:auto 1fr; gap:5px 16px; font-size:var(--t-cuerpo); }
.sel-ficha dt{ color:color-mix(in srgb, var(--hueso) calc(55% + var(--alza)), transparent); }
.sel-ficha dd{ margin:0; text-align:right; font-variant-numeric:tabular-nums; }

/* ─────────────────────────────────────────────────────────────
   6. EL RIEL DE LOS BUNGALOWS — solo las medidas de las plantas
   Tres tarjetas grandes en una pista que corre en horizontal movida
   por el scroll del capítulo. Dos piezas y una sola entrada:
     · la CAJA (.fichas.riel-caja) recorta y no se mueve;
     · la PISTA (.riel-pista, #rielBungalows) se desliza en X.
   La entrada es la variable --riel-t (0→1) que escribe el JS del
   scroll; --riel-sobra la mide el JS al cargar y al redimensionar.
   Nadie escribe style.transform sobre la pista: lo hace este CSS.
   ───────────────────────────────────────────────────────────── */
.fichas{
  position:absolute; inset:auto 0 0;
  padding:0 clamp(20px,5vw,72px) calc(clamp(34px,7vh,80px) + var(--safe));
  /* recorta la pista: por aquí no se escapa un pixel a la página */
  overflow:hidden;
  opacity:0; visibility:hidden; transform:translateY(20px);
  transition:opacity .7s var(--paso), visibility .7s, transform .7s var(--paso);
}
.fichas.dentro{ opacity:1; visibility:visible; transform:none; }
/* el recorte va también con el nombre, para que la clase signifique algo si
   el riel se reusa fuera de este capítulo */
.riel-caja{ overflow:hidden; }

.riel-pista{
  display:flex; align-items:flex-end;
  gap:clamp(12px,1.6vw,22px);
  /* max-content: la pista mide exactamente lo que suman sus tarjetas, que es
     lo que el JS lee como scrollWidth para calcular cuánto tiene que correr */
  width:max-content;
  will-change:transform;
  transform:translate3d(calc(var(--riel-t,0) * var(--riel-sobra,0px) * -1),0,0);
}

.ficha-mod{
  flex:0 0 auto; width:clamp(272px,40vw,600px);
  padding:var(--esp-3);
  /* §5.1: las tarjetas de modelo son papel, con sombra de papel */
  background:var(--cal); color:var(--tinta-papel);
  border:1px solid rgba(42,36,29,.10); border-radius:8px;
  box-shadow:0 1px 4px rgba(42,36,29,.12), 0 18px 48px rgba(34,29,24,.30);
}
.ficha-mod, .ficha-mod *{ text-shadow:none !important; }
/* §5.1 pide tres alturas DISTINTAS: el modelo dos ya es más alto por su
   cuarto renglón; al tercero se le da su propio respiro abajo. */
.ficha-mod:nth-child(3){ padding-bottom:calc(var(--esp-3) + 18px); }
.ficha-mod .rotulo.apagado{ color:var(--madera); }
.ficha-mod h4{ margin:3px 0 4px; font-family:var(--sans); font-size:var(--t-ficha); font-weight:500; line-height:1.15; }
.ficha-mod .medida{
  margin:0 0 var(--esp-2); letter-spacing:0;
  font-family:var(--display); font-weight:600;
  font-size:var(--t-ficha); line-height:1;
  color:var(--tinta-papel); font-variant-numeric:tabular-nums;
}
.ficha-mod ul{ list-style:none; margin:0; padding:0; }
.ficha-mod li{
  font-size:var(--t-cuerpo); line-height:1.5;
  color:color-mix(in srgb, var(--tinta-papel) 88%, transparent);
  padding-left:14px; position:relative;
}
.ficha-mod li::before{
  content:''; position:absolute; left:0; top:.62em;
  width:5px; height:1px; background:var(--madera); opacity:.8;
}

/* ─────────────────────────────────────────────────────────────
   7. CIERRE
   ───────────────────────────────────────────────────────────── */
.cierre{
  position:relative; z-index:10;
  background:var(--tinta);
  padding:clamp(70px,13vh,150px) clamp(20px,5vw,72px) calc(48px + var(--safe));
  border-top:1px solid var(--linea);
}
.cierre-cols{
  max-width:1140px; margin:0 auto;
  display:grid; gap:clamp(34px,5vw,72px);
  grid-template-columns:1fr;
}
@media (min-width:880px){ .cierre-cols{ grid-template-columns:1.25fr .95fr; } }
.cierre h2{
  font-family:var(--display); font-weight:600;
  font-size:var(--t-placa); line-height:1.05; margin:14px 0 22px;
}
.cierre .parrafo{ max-width:52ch; }
.cierre .parrafo + .parrafo{ margin-top:14px; }

.reparto{ list-style:none; margin:0; padding:0; }
.reparto li{
  display:flex; gap:16px; align-items:baseline;
  padding:15px 0; border-bottom:1px solid var(--linea);
}
.reparto .quien{
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--ambar); flex:none; width:114px;
}
.reparto .que{ font-family:var(--serif); font-size:.9375rem; color:var(--tenue); }

.acciones{ display:flex; flex-wrap:wrap; gap:12px; margin-top:34px; }
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:52px; padding:0 30px;
  border-radius:8px; text-decoration:none; cursor:pointer;   /* §5.2 */
  font-family:var(--sans); font-size:1rem; font-weight:500;
  letter-spacing:0;
  border:1px solid var(--linea); background:transparent; color:var(--hueso);
  transition:background .4s var(--paso), color .4s var(--paso), border-color .4s var(--paso);
}
.btn:hover{ background:rgba(243,238,228,.09); border-color:var(--apenas); }
.btn.lleno{ background:var(--ambar); border-color:var(--ambar); color:var(--tinta); }
.btn.lleno:hover{ background:var(--ambar-alto); border-color:var(--ambar-alto); }

.pie{
  max-width:1140px; margin:clamp(50px,8vh,90px) auto 0;
  padding-top:26px; border-top:1px solid var(--linea);
  display:flex; flex-wrap:wrap; gap:14px 26px; justify-content:space-between;
  font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;
  text-transform:uppercase; color:var(--apenas);
}

/* ─────────────────────────────────────────────────────────────
   8. TELÉFONO — el recorrido se maneja con el pulgar
   ───────────────────────────────────────────────────────────── */
@media (max-width:760px){
  .bloque{ align-items:flex-end; padding:20px; padding-bottom:calc(76px + var(--safe)); }
  .bloque .caja{ max-width:100%; }
  .bloque.derecha{ justify-content:flex-start; }
  .bloque.centro{ align-items:center; }

  .b-intro h2{ font-size:clamp(2.25rem,calc(11.5vw*var(--escala)),3.625rem); }
  .b-edit h3{ font-size:clamp(1.625rem,calc(8vw*var(--escala)),2.5rem); }
  .parrafo{ font-size:.96875rem; max-width:100%; }

  /* ⚠️⚠️ EN TELÉFONO ESTA FICHA TAPABA LA PANTALLA. Medido en vivo, no
     estimado: a la fracción 0.24 el panel «El predio, en números» medía
     671 px de una pantalla de 812 — el 78%. El recorrido es el producto;
     un panel que ocupa cuatro quintas partes del teléfono no es una ficha,
     es una interrupción. Se repartía así: la lista 319 px, las dos notas de
     fuente 268 px, el resto relleno.
     ⛔ NO se borra ni se acorta NINGÚN dato: los dos renglones de fuente son
     la procedencia del levantamiento (lámina, escala, fecha, perito) y el
     que reconoce las 11.85 ha sin desglosar. Un dato de fuente no se
     desaparece para ganar espacio. Lo que se cambia es cómo está puesto.
       · LA LISTA volvía a una sola columna en teléfono, o sea DOCE renglones
         donde había seis. Vuelve a rótulo-y-cifra en el mismo renglón: son
         seis. Se le quita el espaciado de letra al rótulo porque ese 8% de
         más era justo lo que empujaba «Lotes del levantamiento» a dos
         líneas en 375 px.
       · LAS NOTAS son el bocado siguiente. Se quedan enteras, más compactas:
         el interlineado de 1.6 es de párrafo de lectura y estas son dos
         líneas de pie de plano.
     💰 Precio anotado: en 320 px de ancho (iPhone SE viejo) los rótulos más
     largos sí van a partirse en dos líneas. Se prefiere eso a doce
     renglones en todos los teléfonos. */
  .ficha{ max-width:100%; padding:16px; }
  .ficha .rotulo{ margin-bottom:10px; }
  .ficha dl{ grid-template-columns:1fr auto; gap:7px 12px; }
  .ficha dt{ margin-top:0; font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.01em; }
  .ficha dd{ text-align:right; letter-spacing:0; }
  .ficha .fuente{
    margin-top:12px; padding-top:10px;
    /* el .94 encogía la fuente a 11.28 px en teléfono. Esta línea es la
       PROCEDENCIA —el levantamiento, la lámina, la escala—: es la que sostiene
       que las cifras no son inventadas. El dato que prueba la honestidad no se
       publica en el tamaño más chico de la página. Piso del sitio: 12 px. */
    font-size:var(--t-tecn); line-height:1.42; letter-spacing:.015em;
  }
  /* la segunda nota es continuación de la primera: no necesita su propia
     línea de corte ni volver a separarse del bloque */
  .ficha .fuente + .fuente{ margin-top:7px; padding-top:0; border-top:0; }

  .comparador .sello{ top:64px; font-size:var(--t-tecn); padding:6px 11px; font-family:var(--mono); letter-spacing:.08em;}
  .comparador .tirador::before{ width:44px; height:44px; }

  /* el cierre arranca por debajo de la barra fija, no pegado a ella */
  .cierre{ padding-top:calc(64px + clamp(40px,8vh,80px)); }

  .marca .sufijo{ letter-spacing:0; font-family:var(--sans); font-size:var(--t-ancla);}
  .indice .nom{ font-size:1.625rem; }
  .indice .dato{ display:none; font-family:var(--mono); font-size:var(--t-tecn); letter-spacing:.08em;}
  .placa{ font-size:var(--t-tecn); letter-spacing:.08em; font-family:var(--mono);}
  /* en 375 px no caben el crédito y la placa en el mismo renglón: el crédito
     baja al filo de abajo, en una línea propia y alineado a la derecha —por
     debajo de la placa (18 px), de la pista (22) y del botón de cerrar el
     comparador (24), sin tocar ninguno—. Cabe entero en una línea hasta en
     320 px de ancho. */
  /* La ortofoto está HORNEADA en dos JPEG dentro del repo: no se le pide en
     vivo a Esri, así que la atribución no es cortesía sino condición de la
     licencia y tiene que verse. A 10 px (el tamaño del manual §4.1) la línea
     completa mide ~460 px y en 375 se partía en dos, tapando la placa del
     capítulo y saliéndose por abajo. Se conserva íntegra la atribución
     obligatoria —© Esri, Maxar, Earthstar Geographics— y solo se recorta lo
     descriptivo. Nunca se esconde en un title. */
  .credito-mundo{
    /* left:auto (no 10px): con la caja de borde a borde, el fondo propio de
       abajo se pintaría como una franja negra de lado a lado con el texto en
       una punta. Sin left, la caja mide lo que mide la letra y el respaldo es
       una etiqueta, no una barra. El texto ya venía alineado a la derecha:
       en pantalla no se mueve un píxel. */
    left:auto; right:clamp(14px,3vw,32px); max-width:calc(100vw - 28px); bottom:calc(3px + var(--safe));
    text-align:right; font-size:.75rem; letter-spacing:.08em; font-family:var(--mono);}
  .credito-mundo .c-larga{ display:none; }

  /* ═══ EL RESPALDO DE LA ROTULACIÓN FIJA — solo teléfono ════════════════
     EL DEFECTO (medido, ronda 11): en el capítulo 4 la placa y el crédito de
     Esri se escribían ENCIMA de la tarjeta blanca del bungalow, texto
     rgb(243,238,228) sobre fondo rgb(243,238,228) = 1.00:1. El mismo color
     exacto: no es poco contraste, es texto invisible. Y con el crédito no es
     estética — es la licencia de la ortofoto de Esri, que exige que se lea.

     POR QUÉ NO SE ARREGLA MOVIÉNDOLOS, probado con la caja medida a 375 px:
       · el piso de las tarjetas del riel está a 54 px del borde inferior
         (.fichas, padding-bottom de este mismo bloque) y NO se mueve: la
         tarjeta es sticky, mide 205 px de alto y ocupa de 553 a 758;
       · la barra de contacto ocupa de 0 a 64 px, y cuando está a la vista
         sube la placa y el crédito por encima de ella (css/venta.css §5,
         obligación de licencia: el botón no puede taparlos);
       · o sea: la banda libre entre el techo de la barra (64) y el piso de
         la tarjeta (54) NO EXISTE — es negativa. No hay dónde ponerlos.
     Por eso el fallo es solo de teléfono: en compu las tarjetas despegan a
     63 px y la placa vive a 18, sin barra que la empuje.

     LA SALIDA, y por qué es esta: el anillo del §4.4 fabrica contraste contra
     un fondo MÁS OSCURO que la letra; contra una tarjeta de papel del MISMO
     color no hay halo que sirva. Y subir el velo está prohibido (tope .35).
     Queda la tercera vía del manual, que además es su regla escrita para
     cualquier superficie de UI: «un panel vive en ≥.92 o no vive» (§5.1) y
     «todo lo que flota encima del recorrido es --noche al 92 %» (§2.2).
     El rótulo deja de depender de lo que haya detrás —mundo, tarjeta de
     papel, panel o el botón de contacto— porque se trae su propio piso.
     Etiqueta de museo, que es justo lo que el §4.1 pide para el crédito.
     MEDIDO EN PÍXELES, no calculado, poniendo a propósito una superficie del
     color del papel justo detrás de los rótulos (el peor fondo que el sitio
     puede ofrecer) y fotografiando el mismo recorte con la tinta apagada:
       · placa    1.00:1 → 11.66:1   · crédito Esri  1.00:1 → 7.77:1
     idéntico a 375 y a 360, con la barra de contacto encendida. Sobre el
     mundo oscuro sube a ~13-14:1. La norma es 4.5:1.
     Sobre panel opaco NO va anillo (§4.4, tercera fila): ensucia y ya no hace
     falta. Cuesta cero bytes: ni una imagen, ni un difuminado, ni un nodo.
     El margen derecho del crédito se igualó al izquierdo de la placa
     (clamp 14/3vw/32) porque con 10 px el crédito sobresalía cuatro píxeles
     más que la placa y los dos chips se leían chuecos, no como una pareja. */
  .placa, .credito-mundo{
    background:rgba(34,29,24,.92);      /* --noche al 92 % */
    border-radius:4px;
    text-shadow:none;
  }
  .placa{ padding:4px 9px; }
  .credito-mundo{ padding:3px 8px; }
  .barra{ padding:12px 14px; }
  .btn-icono{ padding:0 13px; font-size:var(--t-tecn); font-family:var(--mono); letter-spacing:.08em;}
}

@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.001s !important; transition-duration:.001s !important; }
}

/* ⚠️ todo esto vivía DENTRO del bloque de arriba: las reglas de teléfono
   —selectores, fichas de modelo, listas— solo se aplicaban a quien tuviera
   apagadas las animaciones del sistema. En un iPhone normal no existían, y
   por eso los tres modelos salían en tres columnas de 100 px con el texto
   partido y cortado abajo. Vuelven a donde van: al ancho de teléfono. */
@media (max-width:760px){
  /* los selectores: pulgar, no ratón */
  .selector{
    left:8px; right:8px; width:auto;
    /* la placa del capítulo vive abajo a la izquierda: si el selector
       arranca a 16 px, la ficha del lote termina debajo de ella y el
       último renglón se pierde. */
    bottom:calc(46px + var(--safe));
    gap:0;
    /* mismo techo que en compu, con las medidas del teléfono: la barra de
       arriba mide ~68 px y el panel despega a 46 del piso. Lo que no cabe se
       desliza dentro de la lista; nada queda fuera de la pantalla. */
    max-height:calc(100vh - 118px - var(--safe));
    max-height:calc(100svh - 118px - var(--safe));
  }
  .selector.cabs{ left:8px; right:8px; width:auto; }
  .sel-cab{ padding:11px 14px 9px; }
  .sel-pista{ font-size:var(--t-cuerpo); letter-spacing:0; }
  /* ⚠️ En teléfono el velo de "hay más" cubría 78 px —un renglón entero— y en
     una lista de solo cuatro renglones visibles eso se leía como si el cuarto
     lote estuviera roto y el quinto hubiera desaparecido, no como "sigue
     hacia abajo". Con la lista un poco más alta y el velo reducido a media
     línea, el renglón cortado se ve por lo que es: una lista que se desliza. */
  .sel-lista{ max-height:min(34vh,244px); }
  .sel-lista.hay-mas{
    -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 30px), rgba(0,0,0,.72) calc(100% - 12px), rgba(0,0,0,.35) 100%);
            mask-image:linear-gradient(to bottom, #000 calc(100% - 30px), rgba(0,0,0,.72) calc(100% - 12px), rgba(0,0,0,.35) 100%);
  }
  .sel-lista button{ min-height:56px; padding:12px 14px; grid-template-columns:40px 1fr; }
  .sel-t{ font-size:var(--t-cuerpo); }
  .sel-ficha{ padding:var(--esp-3) 16px; border-top:0; }
  .sel-ficha dl{ font-size:var(--t-cuerpo); gap:4px 12px; }

  /* ⚠️ EN TELÉFONO SE PERDÍAN DOS DE LOS TRES MODELOS cuando esto era un
     carrusel que había que deslizar con el dedo: el modelo dos y el tres
     quedaban fuera de pantalla y nada avisaba del gesto —el comprador en
     celular creía que solo existe "La chica"—. Por eso se apilaron.
     Con el RIEL el problema ya no existe: no hay gesto que descubrir, los
     mueve el mismo scroll con el que se recorre todo el sitio, y los tres
     pasan por delante sí o sí antes de salir del capítulo. Una tarjeta a la
     vez, ancha y legible, en vez de tres apretadas contra el bungalow que
     el capítulo está enseñando. */
  /* El piso de las tarjetas lo dicta el CROMO FIJO, no un número redondo.
     Con el respaldo puesto, los rótulos ya se leen sobre la tarjeta — pero
     mirando la pantalla de verdad apareció lo que ningún contraste iba a
     delatar: los dos chips se sientan ENCIMA de las medidas del bungalow y
     tapan renglones de la ficha. Legible sobre dato tapado sigue siendo un
     defecto, y el dato es del cliente.
     Medido a 375 con la barra apagada: la placa ocupa de 18 a 43 px del
     borde inferior. 43 + 6 px de aire = 49; con los 20 px que la tarjeta
     desborda su caja, el padding tiene que ser 69. */
  .fichas{
    padding:0 20px calc(69px + var(--safe));
  }
  .riel-pista{ gap:12px; }
  /* una tarjeta a la vez; el resto asoma apenas para que se lea que hay más */
  .ficha-mod{ width:min(82vw,320px); }
  /* Cuando las tres estaban apiladas había que exprimirlas: tapaban de media
     pantalla para abajo y el bungalow del que habla el capítulo quedaba
     detrás de la del medio. En el riel solo hay UNA tarjeta al frente, así
     que el texto puede volver a respirar sin robarle cuadro a la escena.
     El rótulo sigue en la misma línea de la medida, y desde el 18-ago-2026
     ya no repite el nombre: dice qué mide la cifra ("Bajo techo cerrado"),
     porque el titular pasó a ser el nombre del plano ("Modelo 1", "Modelo
     2", "Modelo 3") y el rótulo estaba diciendo lo mismo dos veces. */
  .ficha-mod{ padding:var(--esp-3) 18px; }
  /* nada baja de 15 px en teléfono (§3.2): antes .62/.78 rem = 10 y 12.5 px */
  .ficha-mod .rotulo.apagado{ display:block; margin:0 0 6px; }
  .ficha-mod h4{ margin:0 0 4px; }
  .ficha-mod .medida{ margin-bottom:var(--esp-2); }
  .ficha-mod ul{ margin:0; }
  .ficha-mod li{ line-height:1.45; padding-left:11px; }
}

/* `hidden` es HTML, no una sugerencia: .btn-icono trae display:flex y se lo
   comía, así que el botón de sonido salía visible sin pista que reproducir. */
[hidden]{ display:none !important; }

/* la unidad, dentro de una tarjeta de papel, va en madera: --piedra sobre
   --cal no llega al contraste que pide el manual. */
.ficha-mod .uni, .ficha .uni{ color:var(--madera); }

/* ─────────────────────────────────────────────────────────────
   9. MOVIMIENTO REDUCIDO (§4.3)
   El manual pide algo muy concreto: el mundo SALTA de parada en parada
   (eso lo hace el JS) y el texto entra por opacidad, SIN desplazarse.
   Antes solo se acortaban las duraciones: el texto seguía viajando, nada
   más que de golpe, que es exactamente lo que marea.
   ───────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
}
html.sin-movimiento .bloque,
html.sin-movimiento .bloque.dentro,
html.sin-movimiento .ficha,
html.sin-movimiento .fichas,
html.sin-movimiento .selector,
html.sin-movimiento .marca,
html.sin-movimiento .intro-linea,
html.sin-movimiento .portada .fondo{ transform:none !important; }
html.sin-movimiento .punto::after{ animation:none !important; }
html.sin-movimiento .riel-pista{ will-change:auto; }

/* ── el bloque de contacto del cierre (vive `hidden` hasta que exista el
   dato real: ver el comentario en index.html). Se deja vestido para que el
   día que se encienda no haya que diseñar nada. ── */
.contacto{ margin-top:var(--esp-5); padding-top:var(--esp-4); border-top:1px solid var(--linea); }
.contacto .rotulo{ margin-bottom:var(--esp-2); }
.contacto .acciones{ margin-top:var(--esp-3); }

/* ─────────────────────────────────────────────────────────────
   9. LA FRANJA DE LA LEYENDA (compu y tableta) — va al FINAL a propósito
   ─────────────────────────────────────────────────────────────
   ⚠️⚠️ LA LEYENDA CHOCABA CON EL TEXTO DEL CAPÍTULO EN LA COMPU, letra
   sobre letra. El comentario de la leyenda (sección de chrome fijo) afirmó
   que "en la compu abajo-izquierda queda libre" SIN MEDIRLO. Es falso.
   Medido con la caja de cada letra —no de ojo— en 51 paradas del recorrido
   (0.00 → 1.00, paso 0.02):
     · 1280 × 800 → choca en 15 de 51 paradas, hasta 6912 px² de letra sobre
       letra (b-intro/parrafo, b-edit/parrafo, .fuente).
     · 1440 × 900 → choca igual; la leyenda mide 307 × 51 en 32,779.
   Es estructural: `.leyenda-mundo` se ancla abajo-izquierda y `.bloque`
   también (align-items:flex-end con padding chico), así que los dos pelean
   por la MISMA esquina a cualquier ancho de compu. Los bloques `.derecha`
   no chocan a 1280, pero a ~700 px de ancho su caja llega hasta la
   izquierda: por eso la regla es para TODOS los bloques, no solo los de la
   izquierda.
   La leyenda no se mueve: arriba no está medido, la derecha es del crédito
   de Esri, y encogerla la vuelve ilegible (una leyenda que no se lee ya no
   explica nada). Sube el texto del capítulo lo justo: la leyenda ocupa
   52 px de separación + 51 px de alto = 121 px desde el piso, y el texto se
   detiene ~133 px arriba del piso.
   💰 PRECIO ANOTADO —lo que faltó la vez pasada—: en compu y tableta el
   texto del capítulo queda ~40 px más alto, menos pegado al borde inferior;
   en ventanas de compu bajitas eso come aire real. El teléfono no se toca:
   ahí la leyenda ya vive arriba y esta franja no existe.
   📍 POR QUÉ AL FINAL DEL ARCHIVO: la sección 8 (teléfono) reescribe el
   padding-bottom de `.bloque` hasta 760 px de ancho —no 620—; puesta antes,
   esta regla quedaba pisada justo en la franja 621–760. */
@media (min-width:621px){
  .bloque{ padding-bottom:calc(clamp(46px,9vh,110px) + var(--safe) + 40px); }
}

/* ⚠️⚠️ TELÉFONO: MEJORA MEDIDA, **NO** CERRADO. Se escribe así de claro
   porque el defecto nació justo de dar por cerrado lo que no se midió.

   LO QUE SE MIDIÓ, letra contra letra, 51 paradas por ancho:
     · 375 × 812 → antes 7 choques (peor 5,130 px²) · ahora 6 (peor 4,104)
     · 360 × 800 → antes 6 choques (peor ~4,700)   · ahora 6 (peor 3,913)
   Bajó el área en todos, pero NO llega a cero. No está resuelto.

   POR QUÉ NO HAY DÓNDE PONERLA — medido, no supuesto, a 375 y a 360:
     · arriba: la barra fija ocupa de y 0 a y 68 de borde a borde. Dentro de
       ella la marca vive en x 14-91 y una etiqueta en x 274-347; queda un
       hueco de x 91 a x 274 (183 px) por 68 de alto, pero es DENTRO de la
       barra (z-index 80) y la leyenda va en 71: meterla ahí ya no es mover
       la leyenda, es rediseñar la barra.
     · abajo: el texto del capítulo, anclado abajo, baja hasta y 758 y la
       placa arranca en y 756. Tampoco cabe.
     · a los lados: el texto del capítulo mide 312 px de los 375. No sobra
       columna.
     · en medio: los bloques que chocan llegan a y 96-120 (los rótulos) y uno
       de ellos hasta y 67. La franja de la leyenda (58-109) está tomada.
   O sea: en teléfono la leyenda y el texto NO caben los dos a la vez. La
   única salida real es TEMPORAL —que la leyenda se apague mientras hay un
   panel de texto encendido—, y eso no se puede escribir solo aquí: la clase
   `dentro` se queda pegada en bloques que ya se fueron 40,000 px arriba, así
   que un `:has(.bloque.dentro)` apagaría la leyenda casi todo el recorrido.
   Necesita una clase de "panel visible AHORA", y esa vive en el JS del sitio.
   👉 QUEDA APUNTADO PARA QUIEN LLEVE EL JS. No se toca desde aquí.

   PRIMER INTENTO, Y POR QUÉ SE DESCARTÓ —para que nadie lo repita—: anclar
   el texto ARRIBA (align-items:flex-start) con 132 px de despeje. Bajó los
   choques de 7 a 1... y ese uno era el PEOR de todos, 12,087 px² en la
   parada 0.38, más del doble que cualquiera de los siete originales, más un
   choque nuevo contra la placa. La razón: el bloque NO está clavado a la
   pantalla, se desliza con el scroll dentro de su capítulo (medido: arranca
   en y 22 y en pleno tránsito se va a y -118). Anclado abajo el texto cruza
   la franja de la leyenda deprisa; anclado arriba se queda pegado a ella
   todo el tránsito. Cambiar el ancla arregla las paradas asentadas y empeora
   el tránsito, que es justo por donde el cliente sí pasa.

   LO QUE SÍ SE DEJA: el ancla abajo (la composición no se toca) y dos cosas
   chicas que sí bajaron el daño —la leyenda se ensancha para que a 360 px no
   se le parta un renglón (de 66-80 px de alto a 51: termina en y 109 en vez
   de y 124) y el texto entero baja 30 px.
   💰 PRECIO ANOTADO: el texto queda 30 px más cerca de la placa y del
   crédito de Esri, que es el aire que la ronda 11 había reservado (76 px de
   padding, ahora 46). Medido después del cambio en las 51 paradas de los dos
   teléfonos: CERO choques contra la placa y CERO contra el crédito. Si algún
   día aparece uno, este número es el primero que hay que mirar. */
@media (max-width:620px){
  .leyenda-mundo{ max-width:min(86vw,320px); }
  .bloque{ padding-bottom:calc(46px + var(--safe)); }
}

/* ⚠️ CON UN PANEL DE RANURA ABIERTO, LA ROTULACIÓN DEL MUNDO SE QUEDABA ENCIMA.
   Todo lo medido arriba —las 51 paradas, los dos teléfonos— se midió haciendo
   SCROLL por el recorrido, que es el estado asentado. El defecto no vive ahí:
   vive cuando el cliente pica "Ver el modelo" y un panel sólido de pantalla
   completa tapa el 3D. Medido a 375 px con `ranCap4` abierto, caja de letra
   contra caja de letra: la leyenda del mundo —que en teléfono vive ARRIBA
   (top = safe + 58px, media query de 620 px)— cae justo sobre el sello
   "Proyecto · lo que está por venir": 307 px de ancho de letra sobre el sello.
   Y el crédito de Esri queda acreditando una imagen satelital que en ese
   momento NO se está viendo: sobre un render, ese crédito dice algo falso.
   La regla ya existía para el cierre (`body.fin`, fondo sólido); esto es el
   mismo caso: fondo sólido encima del mundo. Se apagan las dos y vuelven
   solas al cerrar el panel, con la misma transición que ya tenían.
   💰 PRECIO ANOTADO: en un navegador sin `:has` (Safari anterior a 15.4) la
   regla no aplica y el encimado se queda exactamente como está hoy — se
   degrada a lo de ahora, nunca a algo peor. La licencia de Esri no se toca:
   el crédito completo sigue en la lista del cierre.
   Se apaga también la PLACA del capítulo, medida en el mismo estado: a 500 px
   pisa el botón «Cerrar» en 34 × 26 px de caja, y a 375 px el solape crece
   porque el botón va centrado y la placa arranca en x 15. No estorba el toque
   —la placa lleva pointer-events:none y el botón sigue siendo el elemento de
   encima— pero se lee letra sobre letra justo en el único control del panel. */
body:has(.comparador.abierto) .leyenda-mundo,
body:has(.comparador.abierto) .credito-mundo,
body:has(.comparador.abierto) .placa{
  opacity:0; transform:translateY(8px);
}

/* ─────────────────────────────────────────────────────────────
   CAPA DE TELÉFONO · 18-ago-2026
   ─────────────────────────────────────────────────────────────
   La barra superior nace con opacity:0 y solo se enciende cuando el
   visitante entra (body.dentro). Pero opacity no apaga el tacto ni el
   tabulador, y `.barra > *` devuelve pointer-events:auto a cada botón:
   medido a 375 px, el botón INVISIBLE «Capítulos» ocupa 238→361 × 2→46
   y se sienta encima de la mitad de arriba de «Saltar intro»
   (245→361 × 24→68). Centro contra centro: 22.7 px, cuando el dedo pide
   54. Quien apuntaba a saltar la intro abría el índice de capítulos.
   Se apaga de verdad con visibility —que sí heredan los hijos y sí saca
   del Tab— y se conserva en la transición para que siga apareciendo con
   el mismo fundido. No se mueve un pixel del diseño. */
.barra{
  visibility:hidden;
  transition:opacity .8s var(--paso), transform .8s var(--paso), visibility .8s var(--paso);
}
body.dentro .barra{ visibility:visible; }
