/* ==========================================================================
   SHOWROOM — visor público (recorrido 360 + avance de obra)
   Requiere base.css cargado antes: acá no se declara ningún token.

   La interfaz es un HUÉSPED sobre la imagen del cliente (DISENO §1).
   Consecuencias que este archivo hace cumplir:
   - CERO sombras: sobre foto oscura no elevan y sobre clara ensucian.
     La jerarquía se hace con velo, desenfoque y borde rgb(255 255 255 / .14).
   - Ningún texto se apoya directo sobre la imagen: velo o placa, siempre.
   - dvh y nunca vh. safe-area-inset en los cuatro lados, SUMADO al espaciado.
   - Área táctil real de 44x44 en todo control.

   ---------------------------------------------------------------------------
   REPARTO CON animaciones.css (otro módulo, se carga junto a este)

   animaciones.css es el dueño de TODO el §5 del contrato y no se duplica acá:
     · capas de escena y transiciones .s-escenario / .s-capa--entrante|saliente
     · hotspot animado .s-hotspot y sus seis estilos
     · entrada de la interfaz .s-ui--entra
     · fondo y salida de portada .s-portada__fondo / .s-portada--sale
     · clases .anim-* del <html> y las variables --anim-*
   Este archivo pone el resto del showroom: escenario plano, controles, migas,
   menú, miniaturas, contacto, ficha de unidad, avance, tramos y el respaldo
   del CSS de los marcadores de PSV.

   OJO: la clase .s-capa está TOMADA por animaciones.css (capa de escena). La
   capa de interfaz de este archivo se llama .s-ui-capa.
   ---------------------------------------------------------------------------
   CONTRATO CON EL JS DEL VISOR (lo que este CSS espera del DOM)

   <html class="anim-trans-zoom-punto anim-hot-pulso anim-hot-tam-normal
                anim-ui-subir anim-portada-ken-burns anim-salida-retroceso"
         style="--anim-ms:450ms">          ← CONTRATO §5: solo clases + 2 vars

   <body class="s-showroom s-sobre-imagen">

   Elemento posicionable por el editor de presentación (CONTRATO §6):
   <div class="s-el s-a-abajo-izq" style="--dx:24px;--dy:96px;--escala:1">

   Hotspot: el marcado y la animación los define animaciones.css (.s-hotspot).
   Este archivo solo conserva la variante .s-hot del visor de producción como
   respaldo, por si el visor se monta con el marcado antiguo; los dos nombres
   conviven sin pisarse.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Documento
   -------------------------------------------------------------------------- */

body.s-showroom {
  /* El visor ocupa el viewport y no se desplaza: el scroll lo hacen los
     contenedores internos (menú, ficha, tira de miniaturas). */
  position: fixed;
  inset: 0;
  margin: 0;
  overflow: hidden;
  overscroll-behavior: none;
  background: #000;
  color: #fff;
  touch-action: manipulation;   /* mata el doble-tap-zoom sin matar el scroll */
  -webkit-tap-highlight-color: transparent;
}

/* La página de avance sí es un documento largo: scrollea en vertical. */
body.s-avance-pagina {
  position: static;
  overflow-y: auto;
  overflow-x: hidden;
  background: var(--fg);
  color: var(--fg-txt);
  min-height: 100dvh;
}

/* --------------------------------------------------------------------------
   2. Escenario (imagen plana, panorama, cargador)
   -------------------------------------------------------------------------- */

.s-stage {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 1;
}
.s-stage-flat { position: absolute; inset: 0; overflow: hidden; }

/* La imagen real va completa, sin recortar: si se recorta, las coordenadas
   normalizadas 0..1 de los hotspots dejan de coincidir con lo que se ve. */
.s-stage-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  opacity: 0;
  z-index: 2;
  transition: opacity var(--anim-ms, 450ms) var(--anim-easing, var(--ease-suave));
}
.s-stage-bg-active { opacity: 1; }

/* Copia borrosa de la misma imagen rellenando los costados.
   Se rasteriza al 22% y se escala x5: blur() procesa ~5% de los píxeles y el
   celular no se congela al cambiar de escena (medido en producción). */
.s-stage-blur {
  position: absolute;
  top: 50%; left: 50%;
  width: 22%; height: 22%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  filter: blur(7px) brightness(.55) saturate(1.1);
  transform: translate(-50%, -50%) scale(5);
  transform-origin: center center;
  z-index: 1;
  pointer-events: none;
  will-change: opacity;
  transition: opacity var(--anim-ms, 450ms) var(--anim-easing, var(--ease-suave));
}
.s-stage-blur-active { opacity: 1; }

.s-stage-pano { position: absolute; inset: 0; z-index: 3; }

/* Cargador de escena: encima de la imagen anterior mientras baja la nueva. */
.s-loader {
  position: absolute;
  inset: 0;
  z-index: 9;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / .28);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--ms-normal) var(--ease-ambos);
}
.s-loader.is-on { opacity: 1; pointer-events: auto; }
.s-loader-spinner {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 3px solid rgb(255 255 255 / .18);
  border-top-color: var(--p);
  animation: girar .9s linear infinite;
}

/* Velos permanentes del escenario: garantizan contraste para lo que se ancla
   arriba y abajo aunque la foto sea blanca en esa zona (§2.3). */
.s-velo {
  position: fixed;
  inset-inline: 0;
  z-index: 5;
  pointer-events: none;
}
.s-velo-arriba { top: 0; height: 34dvh; background: var(--velo-arriba); }
.s-velo-abajo  { bottom: 0; height: 44dvh; background: var(--velo-abajo); }

/* --------------------------------------------------------------------------
   3. Capa de interfaz y anclas del editor de presentación (CONTRATO §6)

   .s-ui-capa lleva el padding de safe-area SUMADO al espaciado del tramo, así
   nada queda bajo el notch ni bajo la barra de gestos. Los elementos se
   posicionan respecto de ella con las clases .s-a-* y las variables --dx/--dy.
   (Se llama .s-ui-capa y no .s-capa porque ese nombre ya es de animaciones.css.)
   -------------------------------------------------------------------------- */

.s-ui-capa {
  position: fixed;
  inset: 0;
  z-index: 20;
  pointer-events: none;   /* la capa no tapa el escenario; los hijos sí reciben */
  padding-top:    calc(var(--borde-pantalla) + env(safe-area-inset-top));
  padding-right:  calc(var(--borde-pantalla) + env(safe-area-inset-right));
  padding-bottom: calc(var(--borde-pantalla) + env(safe-area-inset-bottom));
  padding-left:   calc(var(--borde-pantalla) + env(safe-area-inset-left));
}
.s-ui-capa > * { pointer-events: auto; }

/* La animación de entrada NO va acá: la pone animaciones.css con la clase
   .s-ui--entra, que además escalona los controles. Duplicarla haría que dos
   animaciones peleen por el mismo elemento. */
.s-el {
  --dx: 0px;
  --dy: 0px;
  --escala: 1;
  position: absolute;
  max-width: calc(100% - var(--e-2));
}
.s-el[hidden] { display: none !important; }

/* Nueve anclas. El transform-origin apunta al ancla para que `escala` crezca
   hacia adentro de la pantalla y el elemento no se salga al agrandarse. */
.s-a-arriba-izq    { top: var(--dy);  left: var(--dx);  transform: scale(var(--escala)); transform-origin: top left; }
.s-a-arriba-centro { top: var(--dy);  left: 50%;        transform: translateX(-50%) scale(var(--escala)); transform-origin: top center; }
.s-a-arriba-der    { top: var(--dy);  right: var(--dx); transform: scale(var(--escala)); transform-origin: top right; }
.s-a-medio-izq     { top: 50%;        left: var(--dx);  transform: translateY(-50%) scale(var(--escala)); transform-origin: left center; }
.s-a-medio-centro  { top: 50%;        left: 50%;        transform: translate(-50%, -50%) scale(var(--escala)); transform-origin: center; }
.s-a-medio-der     { top: 50%;        right: var(--dx); transform: translateY(-50%) scale(var(--escala)); transform-origin: right center; }
.s-a-abajo-izq     { bottom: var(--dy); left: var(--dx);  transform: scale(var(--escala)); transform-origin: bottom left; }
.s-a-abajo-centro  { bottom: var(--dy); left: 50%;        transform: translateX(-50%) scale(var(--escala)); transform-origin: bottom center; }
.s-a-abajo-der     { bottom: var(--dy); right: var(--dx); transform: scale(var(--escala)); transform-origin: bottom right; }

/* Paneles: ocupan un costado completo y no aceptan dx/dy. */
.s-a-izquierda-panel,
.s-a-derecha-panel {
  top: 0; bottom: 0;
  width: min(420px, 92vw);
  max-width: none;
}
.s-a-izquierda-panel { left: 0; }
.s-a-derecha-panel   { right: 0; }
.s-a-abajo-panel {
  left: 0; right: 0; bottom: 0;
  max-width: none;
  max-height: 88dvh;
}

/* --------------------------------------------------------------------------
   4. Placas y controles flotantes
   Sin sombra. Jerarquía por velo + desenfoque + borde.
   -------------------------------------------------------------------------- */

.s-placa {
  background: var(--placa);
  border: var(--b-fino) solid var(--placa-borde);
  border-radius: var(--r-lg);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
  color: #fff;
  box-shadow: none;
}

/* Barra de controles. El gap de --e-2 es obligatorio: el ::after de 44x44 de
   cada botón se extiende hacia afuera y sin separación se roban el click. */
.s-barra {
  display: flex;
  align-items: center;
  gap: var(--e-2);
}

.s-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  height: 40px;
  padding: 0 var(--e-3);
  border-radius: var(--r-full);
  border: var(--b-fino) solid var(--placa-borde);
  background: var(--placa);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
  color: #fff;
  font-size: var(--t-sm);
  font-weight: var(--peso-enfasis);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--ms-instantaneo) var(--ease-ambos),
              transform var(--ms-instantaneo) var(--ease-ambos),
              border-color var(--ms-instantaneo) var(--ease-ambos);
}
.s-pill::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 100%; height: 100%;
  min-width: var(--tactil);
  min-height: var(--tactil);
  transform: translate(-50%, -50%);
  border-radius: inherit;
}
.s-pill > svg { width: 20px; height: 20px; flex: none; }
.s-pill:hover { background: var(--placa-fuerte); }
.s-pill:active { transform: scale(.96); }
.s-pill:disabled { opacity: .45; }
.s-pill-icono { width: 40px; padding: 0; }
.s-pill-primario {
  background: var(--p);
  color: var(--p-txt);
  border-color: transparent;
  font-weight: var(--peso-titulo);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.s-pill-primario:hover { background: var(--p-hover); }
.s-pill-primario:active { background: var(--p-press); }
.s-pill-cta { height: 48px; padding: 0 var(--e-5); font-size: var(--t-base); }

/* Grupo segmentado (día/noche, vista de avance) */
.s-segmento {
  display: inline-flex;
  padding: 3px;
  height: 40px;
  border-radius: var(--r-full);
  border: var(--b-fino) solid var(--placa-borde);
  background: var(--placa);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
  overflow: hidden;
}
.s-segmento-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  height: 100%;
  padding: 0 var(--e-3);
  border-radius: var(--r-full);
  color: rgb(255 255 255 / .72);
  font-size: var(--t-xs);
  font-weight: var(--peso-enfasis);
  transition: background var(--ms-instantaneo), color var(--ms-instantaneo);
}
.s-segmento-btn::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 100%; height: var(--tactil);
  min-width: var(--tactil);
  transform: translate(-50%, -50%);
}
.s-segmento-btn > svg { width: 16px; height: 16px; flex: none; }
.s-segmento-btn:hover { color: #fff; }
.s-segmento-btn[aria-pressed="true"] { background: #fff; color: var(--txt-sobre-claro); }

/* --------------------------------------------------------------------------
   5. Hotspot (DISENO §4.3) — el componente que define el producto

   El componente vivo es .s-hotspot y lo pinta animaciones.css. Lo que hay
   acá abajo es la variante .s-hot del visor de producción, que se conserva
   como respaldo: los nombres no chocan, así que si el visor se monta con el
   marcado antiguo igual se ve bien en vez de quedar sin estilo.
   En las dos variantes el botón mide 44x44 SIEMPRE y lo único que cambia de
   tamaño es el punto visible.
   -------------------------------------------------------------------------- */

/* Capa de hotspots de las escenas planas. Es el padre posicionado que
   necesitan tanto .s-hot como el .s-hotspot de animaciones.css. La capa no
   recibe el puntero (si no, tapa el arrastre del panorama), pero cada hijo
   sí: sin esta línea un .s-hotspot que no declare pointer-events queda
   dibujado pero no se puede tocar. */
.s-hotspots {
  position: absolute;
  inset: 0;
  z-index: 8;
  pointer-events: none;
}
.s-hotspots > * { pointer-events: auto; }

:where(.s-hot) {
  --hot-d: 16px;                 /* diámetro del punto visible */
  --hot-dur: 2.4s;
  --hot-halo-op: .34;
  --hot-halo-esc: 2.3;
  --hot-anim-halo: s-hot-pulso;
  --hot-anim-punto: none;
  --hot-punto-bg: var(--p);
  --hot-punto-borde-w: 2px;
  --hot-chevron: 0;
}

.s-hot {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  width: var(--tactil);
  height: var(--tactil);
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  pointer-events: auto;
  z-index: 8;
  animation: s-hot-aparecer var(--ms-normal) var(--ease-entrada) backwards;
}

.s-hot-halo {
  position: absolute;
  width: var(--hot-d);
  height: var(--hot-d);
  border-radius: 50%;
  background: var(--p-halo);
  opacity: var(--hot-halo-op);
  pointer-events: none;
  animation: var(--hot-anim-halo) var(--hot-dur) infinite var(--ease-suave);
}

.s-hot-punto {
  position: relative;
  width: var(--hot-d);
  height: var(--hot-d);
  border-radius: 50%;
  background: var(--hot-punto-bg);
  /* Borde blanco: es lo que despega el punto de CUALQUIER foto, clara u
     oscura. Sin él, un hotspot verde sobre pasto desaparece. */
  border: var(--hot-punto-borde-w) solid #fff;
  animation: var(--hot-anim-punto) var(--hot-dur) infinite var(--ease-suave);
  transition: transform var(--ms-rapido) var(--ease-ambos);
}
/* Chevrón del estilo `flecha`, dibujado con bordes: cero SVG, cero peso. */
.s-hot-punto::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 34%; height: 34%;
  border-top: 2px solid var(--p-txt);
  border-right: 2px solid var(--p-txt);
  transform: translate(-60%, -50%) rotate(45deg);
  opacity: var(--hot-chevron);
}

.s-hot:hover .s-hot-punto,
.s-hot:focus-visible .s-hot-punto { transform: scale(1.18); }

/* Etiqueta: placa desenfocada, nunca texto pelado sobre la foto. */
.s-hot-etiqueta {
  position: absolute;
  left: 50%;
  bottom: calc(50% + var(--hot-d) / 2 + var(--e-2));
  transform: translateX(-50%) translateY(4px);
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-sm);
  background: var(--placa-fuerte);
  border: var(--b-fino) solid var(--placa-borde);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: var(--t-xs);
  line-height: var(--lh-xs);
  font-weight: var(--peso-enfasis);
  white-space: nowrap;
  max-width: 40vw;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--ms-rapido) var(--ease-ambos),
              transform var(--ms-rapido) var(--ease-ambos);
}
/* En móvil el PRIMER toque muestra la etiqueta y el segundo navega: el JS
   pone .is-tocado. Sin esto el visitante viaja a ciegas y se pierde. */
.s-hot.is-tocado .s-hot-etiqueta,
.s-hot:focus-visible .s-hot-etiqueta {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
@media (hover: hover) and (pointer: fine) {
  .s-hot:hover .s-hot-etiqueta { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Estilos globales del proyecto — :where() los deja en especificidad 0 para
   que el modificador por hotspot de más abajo siempre gane. */
:where(.anim-hot-pulso) .s-hot        { --hot-anim-halo: s-hot-pulso; --hot-anim-punto: none; }
:where(.anim-hot-latido) .s-hot       { --hot-anim-halo: none; --hot-halo-op: .22; --hot-anim-punto: s-hot-latido; --hot-dur: 1.8s; }
:where(.anim-hot-anillo) .s-hot       { --hot-anim-halo: none; --hot-halo-op: .16; --hot-anim-punto: s-hot-girar; --hot-dur: 6s; --hot-punto-bg: transparent; --hot-punto-borde-w: 3px; }
:where(.anim-hot-flecha) .s-hot       { --hot-anim-halo: none; --hot-halo-op: .20; --hot-chevron: 1; --hot-d: 22px; }
:where(.anim-hot-fijo) .s-hot         { --hot-anim-halo: none; --hot-anim-punto: none; --hot-halo-op: .20; }
:where(.anim-hot-punto-minimo) .s-hot { --hot-anim-halo: none; --hot-anim-punto: none; --hot-halo-op: 0; --hot-d: 8px; --hot-punto-borde-w: 2px; }

:where(.anim-hot-tam-chico) .s-hot  { --hot-d: 12px; }
:where(.anim-hot-tam-normal) .s-hot { --hot-d: 16px; }
:where(.anim-hot-tam-grande) .s-hot { --hot-d: 22px; }

/* Modificadores por hotspot (hotspots[].animacion del JSON) */
.s-hot--pulso        { --hot-anim-halo: s-hot-pulso; --hot-anim-punto: none; }
.s-hot--latido       { --hot-anim-halo: none; --hot-halo-op: .22; --hot-anim-punto: s-hot-latido; --hot-dur: 1.8s; }
.s-hot--anillo       { --hot-anim-halo: none; --hot-halo-op: .16; --hot-anim-punto: s-hot-girar; --hot-dur: 6s; --hot-punto-bg: transparent; --hot-punto-borde-w: 3px; }
.s-hot--flecha       { --hot-anim-halo: none; --hot-halo-op: .20; --hot-chevron: 1; --hot-d: 22px; }
.s-hot--fijo         { --hot-anim-halo: none; --hot-anim-punto: none; --hot-halo-op: .20; }
.s-hot--punto-minimo { --hot-anim-halo: none; --hot-anim-punto: none; --hot-halo-op: 0; --hot-d: 8px; }
.s-hot--tam-chico    { --hot-d: 12px; }
.s-hot--tam-normal   { --hot-d: 16px; }
.s-hot--tam-grande   { --hot-d: 22px; }

@keyframes s-hot-pulso {
  0%   { transform: scale(.85); opacity: var(--hot-halo-op); }
  70%  { transform: scale(var(--hot-halo-esc)); opacity: 0; }
  100% { transform: scale(var(--hot-halo-esc)); opacity: 0; }
}
@keyframes s-hot-latido {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}
@keyframes s-hot-girar { to { transform: rotate(360deg); } }
@keyframes s-hot-aparecer {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.4); }
  60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.12); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
/* El anillo necesita un hueco para que se note que gira. */
.s-hot--anillo .s-hot-punto,
:where(.anim-hot-anillo) .s-hot .s-hot-punto { border-top-color: transparent; }

/* --------------------------------------------------------------------------
   6. Marcadores de Photo Sphere Viewer 4.8.1 (CONTRATO §10.2)
   La clase real es .psv-marker--normal. `.psv-marker--html` NO EXISTE.
   Respaldo del CSS del plugin: sin position absoluta el marcador cae en flujo
   normal y se dibuja como una línea horizontal de ancho completo.
   -------------------------------------------------------------------------- */

.psv-markers {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 10;
  user-select: none;
}
.psv-markers-svg-container {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  z-index: 20;
}
.psv-marker { display: none; }
.psv-marker--normal {
  position: absolute;
  top: 0; left: 0;
  z-index: 30;
  background-size: contain;
  background-repeat: no-repeat;
}
.psv-marker--transparent { display: block; opacity: 0; }
.psv-marker--visible { display: block; }
.psv-marker--has-content,
.psv-marker--has-tooltip { cursor: pointer; }

/* El html del marcador es un <span> INLINE: sin display:block el width y el
   height que le pasamos al plugin se ignoran y sale un cuadradito diminuto. */
.psv-marker--normal > span,
.psv-marker--normal .s-hot-360 {
  display: block;
  width: 100%;
  height: 100%;
}

/* El marcador ya viene con width/height explícitos desde el JS (necesarios
   para que anchor:'center center' caiga donde se hizo click), así que acá
   solo se pinta. Mismo lenguaje visual que el hotspot plano. */
.psv-marker--normal .s-hot-360 {
  position: relative;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  cursor: pointer;
}
.s-hot-360 .s-hot-punto {
  width: var(--hot-d, 16px);
  height: var(--hot-d, 16px);
}
.s-hot-360 .s-hot-halo {
  position: absolute;
  width: var(--hot-d, 16px);
  height: var(--hot-d, 16px);
  border-radius: 50%;
  background: var(--p-halo);
  opacity: var(--hot-halo-op, .34);
  animation: var(--hot-anim-halo, s-hot-pulso) var(--hot-dur, 2.4s) infinite var(--ease-suave);
}

/* --------------------------------------------------------------------------
   7. Migas de pan
   -------------------------------------------------------------------------- */

.s-crumbs {
  display: flex;
  align-items: center;
  gap: var(--e-1);
  max-width: min(70vw, 560px);
  padding: var(--e-1) var(--e-3);
  border-radius: var(--r-full);
  background: var(--placa);
  border: var(--b-fino) solid var(--placa-borde);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
  font-size: var(--t-xs);
  line-height: var(--lh-xs);
  overflow: hidden;
  white-space: nowrap;
}
.s-crumb {
  color: rgb(255 255 255 / .72);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
}
.s-crumb-link { position: relative; transition: color var(--ms-instantaneo); }
.s-crumb-link:hover { color: #fff; }
.s-crumb-actual { color: #fff; font-weight: var(--peso-titulo); }
.s-crumb-sep { opacity: .4; flex: none; }
.s-crumb-volver { display: none; }   /* solo aparece en móvil y compacto */

/* --------------------------------------------------------------------------
   8. Ficha de escena flotante
   -------------------------------------------------------------------------- */

.s-info {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  max-width: min(420px, 76vw);
  padding: var(--e-3) var(--e-4);
  border-radius: var(--r-lg);
  background: var(--placa);
  border: var(--b-fino) solid var(--placa-borde);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
  color: #fff;
}
.s-info h2 {
  font-size: var(--t-h3);
  line-height: var(--lh-h3);
  margin-bottom: 2px;
}
.s-info p {
  font-size: var(--t-sm);
  line-height: var(--lh-sm);
  color: rgb(255 255 255 / .78);
}
.s-info.is-plegada .s-info-cuerpo { display: none; }

/* --------------------------------------------------------------------------
   9. Tira de miniaturas
   -------------------------------------------------------------------------- */

.s-thumbs-wrap {
  --thumb-alto: 72px;
  max-width: min(760px, calc(100vw - var(--e-6)));
  padding: var(--e-2);
  border-radius: var(--r-lg);
  background: var(--placa);
  border: var(--b-fino) solid var(--placa-borde);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
}
.s-thumbs {
  display: flex;
  gap: var(--e-2);
  /* Contenido ancho: scrollea en SU contenedor, jamás en el body. */
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  scrollbar-color: rgb(255 255 255 / .28) transparent;
}
.s-thumbs::-webkit-scrollbar { height: 6px; }
.s-thumbs::-webkit-scrollbar-track { background: transparent; }
.s-thumbs::-webkit-scrollbar-thumb { background: rgb(255 255 255 / .22); border-radius: 3px; }

.s-thumb {
  position: relative;
  flex: none;
  height: var(--thumb-alto);
  aspect-ratio: 3 / 2;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: var(--b-grueso) solid transparent;
  background: rgb(255 255 255 / .08);
  scroll-snap-align: center;
  transition: border-color var(--ms-rapido) var(--ease-ambos),
              transform var(--ms-rapido) var(--ease-ambos);
}
.s-thumb img { width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--ms-normal); }
.s-thumb img.is-cargada { opacity: 1; }
.s-thumb:hover { transform: translateY(-2px); border-color: rgb(255 255 255 / .45); }
.s-thumb.is-actual { border-color: var(--p); }
.s-thumb-tag {
  position: absolute;
  top: 3px; right: 3px;
  padding: 0 5px;
  border-radius: var(--r-full);
  background: var(--p);
  color: var(--p-txt);
  font-size: var(--t-xs);
  font-weight: var(--peso-cifra);
  line-height: 1.4;
}
/* Mini-spinner mientras baja cada miniatura */
.s-thumb::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 18px; height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / .18);
  border-top-color: var(--p);
  animation: girar .9s linear infinite;
  transition: opacity var(--ms-rapido);
}
.s-thumb.is-lista::before { opacity: 0; }

/* Botón que abre la tira en compacto */
.s-thumbs-toggle { display: none; }

/* --------------------------------------------------------------------------
   10. Menú (árbol de escenas)
   Lateral en tablet/escritorio, pantalla completa en móvil y compacto.
   -------------------------------------------------------------------------- */

.s-menu { position: fixed; inset: 0; z-index: 60; }
.s-menu-fondo {
  position: absolute;
  inset: 0;
  background: rgb(0 0 0 / .55);
  animation: s-fundido-in var(--ms-normal) var(--ease-entrada);
}
.s-menu-panel {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: min(360px, 92vw);
  display: flex;
  flex-direction: column;
  gap: var(--e-4);
  background: var(--fg);
  color: var(--fg-txt);
  border-right: var(--b-fino) solid var(--fg-borde);
  padding: calc(var(--e-5) + env(safe-area-inset-top)) var(--e-4)
           calc(var(--e-5) + env(safe-area-inset-bottom))
           calc(var(--e-4) + env(safe-area-inset-left));
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: s-menu-entrar var(--ms-normal) var(--ease-entrada);
}
.s-menu-cabecera { display: flex; align-items: flex-start; gap: var(--e-2); }
.s-menu-cabecera h2 { font-size: var(--t-h3); }
.s-menu-cabecera p { font-size: var(--t-sm); color: var(--fg-txt-2); }
.s-menu-cerrar { margin-left: auto; }

.s-menu-titulo-seccion {
  font-size: var(--t-xs);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-txt-3);
  font-weight: var(--peso-enfasis);
}

.s-arbol { display: flex; flex-direction: column; gap: var(--e-1); }
.s-arbol-hijos {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  margin-top: var(--e-1);
  padding-left: var(--e-4);
  border-left: var(--b-fino) solid var(--fg-borde);
  margin-left: var(--e-3);
}
.s-nodo {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e-2);
  width: 100%;
  min-height: var(--tactil);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-md);
  border: var(--b-fino) solid transparent;
  background: color-mix(in oklab, var(--fg-txt) 5%, transparent);
  color: var(--fg-txt);
  text-align: left;
  font-size: var(--t-sm);
  transition: background var(--ms-instantaneo), border-color var(--ms-instantaneo);
}
.s-nodo:hover { background: color-mix(in oklab, var(--fg-txt) 10%, transparent); border-color: var(--fg-borde); }
.s-nodo.is-actual { background: var(--p-suave); border-color: var(--p-borde); color: var(--p); }
.s-nodo-icono { width: 20px; height: 20px; flex: none; color: var(--fg-txt-3); }
.s-nodo.is-actual .s-nodo-icono { color: var(--p); }
.s-nodo-titulo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.s-nodo-tag {
  flex: none;
  padding: 1px 6px;
  border-radius: var(--r-full);
  background: color-mix(in oklab, var(--fg-txt) 10%, transparent);
  color: var(--fg-txt-2);
  font-size: var(--t-xs);
  font-weight: var(--peso-enfasis);
}
.s-nodo-tag.is-360 { background: var(--p-suave); color: var(--p); }

@keyframes s-menu-entrar { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes s-fundido-in { from { opacity: 0; } to { opacity: 1; } }

/* --------------------------------------------------------------------------
   11. Contacto (canal configurable — AJUSTES §3)
   NO es WhatsApp fijo: el tipo lo decide el cliente. Si no hay canal
   configurado el botón no existe, así que acá no hay estado "vacío".
   -------------------------------------------------------------------------- */

.s-contacto {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  height: 48px;
  padding: 0 var(--e-4);
  border-radius: var(--r-full);
  background: var(--p);
  color: var(--p-txt);
  border: var(--b-fino) solid transparent;
  font-size: var(--t-sm);
  font-weight: var(--peso-titulo);
  text-decoration: none;
  transition: background var(--ms-instantaneo), transform var(--ms-instantaneo);
}
.s-contacto > svg { width: 22px; height: 22px; flex: none; }
.s-contacto:hover { background: var(--p-hover); }
.s-contacto:active { transform: scale(.97); }
.s-contacto-icono { width: 48px; padding: 0; justify-content: center; }

/* Los canales secundarios viven en una lista, no en más botones flotantes. */
.s-canales {
  display: flex;
  flex-direction: column;
  gap: var(--e-1);
  padding: var(--e-2);
  border-radius: var(--r-lg);
  background: var(--placa);
  border: var(--b-fino) solid var(--placa-borde);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
}
.s-canal {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  min-height: var(--tactil);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-md);
  color: #fff;
  font-size: var(--t-sm);
  text-decoration: none;
}
.s-canal:hover { background: rgb(255 255 255 / .10); }
.s-canal > svg { width: 20px; height: 20px; flex: none; color: var(--p); }

/* --------------------------------------------------------------------------
   12. Portada
   El contenedor .s-portada, su fondo (.s-portada__fondo) y la salida
   (.s-portada--sale) son de animaciones.css. Acá va solo la composición del
   contenido y el velo que lo hace legible: nada de posición ni de animación,
   para no pelear con ese archivo.
   -------------------------------------------------------------------------- */

.s-portada {
  display: grid;
  place-items: center;
  padding: calc(var(--e-6) + env(safe-area-inset-top))
           calc(var(--e-5) + env(safe-area-inset-right))
           calc(var(--e-6) + env(safe-area-inset-bottom))
           calc(var(--e-5) + env(safe-area-inset-left));
  background: #000;
}
/* Doble velo: el texto de portada es el más grande y el más importante, y
   una foto clara arriba lo borraría. */
.s-portada::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--velo-abajo), var(--velo-arriba),
              radial-gradient(ellipse at center, rgb(0 0 0 / .25) 0%, rgb(0 0 0 / .62) 78%);
}
.s-portada-contenido {
  position: relative;
  z-index: 2;
  max-width: 640px;
  text-align: center;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-3);
}
.s-portada-logo { max-height: 72px; width: auto; margin-bottom: var(--e-2); }
.s-portada-titulo {
  font-size: var(--t-display);
  line-height: var(--lh-display);
  font-weight: var(--peso-titulo);
  letter-spacing: -.01em;
  text-shadow: var(--txt-sombra);
}
.s-portada-sub {
  font-size: var(--t-base);
  color: rgb(255 255 255 / .84);
  text-shadow: var(--txt-sombra);
}
.s-portada-acciones { display: flex; flex-wrap: wrap; gap: var(--e-2); justify-content: center; margin-top: var(--e-3); }
.s-portada-pista { font-size: var(--t-xs); color: rgb(255 255 255 / .72); }

/* --------------------------------------------------------------------------
   13. Unidades (MÓDULO OPCIONAL, apagado por defecto — AJUSTES §1)
   Nada de esto se emite si projects.unidades_activas = 0.
   La ficha es INFORMATIVA: precio y estado como dato y un botón de contacto.
   Dentro del showroom no hay cobro de ningún tipo (AJUSTES §2).
   -------------------------------------------------------------------------- */

.s-pin {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  min-height: 28px;
  padding: 0 var(--e-2);
  border-radius: var(--r-full);
  border: var(--b-grueso) solid #fff;
  font-family: var(--fuente-num);
  font-size: var(--t-xs);
  font-weight: var(--peso-cifra);
  line-height: 1;
  color: #fff;
  pointer-events: auto;
  transition: transform var(--ms-rapido) var(--ease-ambos);
}
/* Área táctil 44x44 aunque la píldora mida 28 de alto. */
.s-pin::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 100%; height: 100%;
  min-width: var(--tactil);
  min-height: var(--tactil);
  transform: translate(-50%, -50%);
  border-radius: inherit;
}
.s-pin:hover { transform: translate(-50%, -50%) scale(1.15); }
.s-pin[aria-pressed="true"] { box-shadow: 0 0 0 3px currentColor; }

/* Color + FORMA + texto: 1 de cada 12 hombres es daltónico y esto es una
   decisión de compra (§2.4). La forma va en el punto de la izquierda.

   Los fondos salen de --est-* y NO de --ok/--aviso/--error: esos cuatro se
   aclaran a oklch 70-78% cuando el visitante tiene el sistema en oscuro, y con
   el código en blanco encima quedaban en ~2.5:1. El pin vive sobre una foto,
   no sobre una superficie del panel, así que no sigue el tema del sistema. */
.s-pin-marca { width: 10px; height: 10px; border-radius: 50%; border: 2px solid currentColor; flex: none; }
.s-pin--disponible    { background: var(--est-ok); }
.s-pin--disponible    .s-pin-marca { background: currentColor; }
.s-pin--reservada     { background: var(--est-aviso); color: var(--txt-sobre-claro); }
.s-pin--reservada     .s-pin-marca { border-style: dotted; }
.s-pin--vendida       { background: var(--est-error); }
.s-pin--vendida       .s-pin-marca { background: linear-gradient(to bottom right,
                          transparent 44%, currentColor 44%, currentColor 56%, transparent 56%); }
.s-pin--proximamente  { background: var(--est-neutro); }
.s-pin--proximamente  .s-pin-marca { background: transparent; }

/* Cúmulo cuando hay más de 40 pines y quedan a menos de 24px */
.s-pin-cumulo {
  background: var(--placa-fuerte);
  border-color: var(--placa-borde);
  backdrop-filter: var(--placa-blur);
  -webkit-backdrop-filter: var(--placa-blur);
}

/* Ficha de unidad: lateral en escritorio, hoja al 88% en móvil.
   Orden fijo del contenido (es el orden en que se decide una compra):
   estado y precio → tipología y superficie → dormitorios/baños/orientación →
   plano → tour 360 → PDF → contacto. */
.s-ficha {
  position: fixed;
  z-index: 80;
  display: flex;
  flex-direction: column;
  background: var(--fg);
  color: var(--fg-txt);
  border: var(--b-fino) solid var(--fg-borde);
  overflow: hidden;
  top: 0; right: 0; bottom: 0;
  width: min(420px, 92vw);
  border-radius: var(--r-lg) 0 0 var(--r-lg);
  animation: s-ficha-lateral var(--ms-normal) var(--ease-entrada);
}
.s-ficha-cabecera {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  padding: calc(var(--e-4) + env(safe-area-inset-top)) var(--e-4) var(--e-3);
  border-bottom: var(--b-fino) solid var(--fg-borde);
}
.s-ficha-codigo { font-family: var(--fuente-num); font-size: var(--t-h2); font-weight: var(--peso-cifra); }
.s-ficha-cuerpo {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--e-4);
  display: flex;
  flex-direction: column;
  gap: var(--e-4);
}
.s-ficha-precio { font-family: var(--fuente-num); font-size: var(--t-h1); font-weight: var(--peso-cifra); }
.s-ficha-nota { font-size: var(--t-xs); color: var(--fg-txt-3); }
.s-ficha-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--e-3);
}
.s-ficha-dato { display: flex; flex-direction: column; gap: 2px; }
.s-ficha-dato dt { font-size: var(--t-xs); color: var(--fg-txt-3); }
.s-ficha-dato dd { font-family: var(--fuente-num); font-size: var(--t-base); font-weight: var(--peso-enfasis); }
.s-ficha-plano { border-radius: var(--r-md); border: var(--b-fino) solid var(--fg-borde); overflow: hidden; }
.s-ficha-pie {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-4) var(--e-4) calc(var(--e-4) + env(safe-area-inset-bottom));
  border-top: var(--b-fino) solid var(--fg-borde);
  background: var(--fg-2);
}
/* Manija de arrastre: solo tiene sentido cuando la ficha es una hoja. */
.s-ficha-manija { display: none; }

@keyframes s-ficha-lateral { from { transform: translateX(100%); } to { transform: none; } }
@keyframes s-ficha-hoja    { from { transform: translateY(100%); } to { transform: none; } }

/* --------------------------------------------------------------------------
   14. Avance de obra (parte del producto, encendido por defecto)
   -------------------------------------------------------------------------- */

.s-avance { max-width: 960px; margin-inline: auto; padding: var(--e-5) var(--e-4) var(--e-8); }
.s-avance-cabecera { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-4); margin-bottom: var(--e-6); }
.s-avance-titulo h1 { color: var(--fg-txt); }
.s-avance-titulo p { color: var(--fg-txt-2); font-size: var(--t-sm); }

/* Anillo de porcentaje: el dato se repite en texto adentro, nunca solo color. */
.s-anillo {
  position: relative;
  width: 84px; height: 84px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(var(--p) calc(var(--pct, 0) * 1%),
                             color-mix(in oklab, var(--fg-txt) 14%, transparent) 0);
  display: grid;
  place-items: center;
}
.s-anillo::after {
  content: "";
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  background: var(--fg);
}
.s-anillo span {
  position: relative;
  z-index: 1;
  font-family: var(--fuente-num);
  font-size: var(--t-base);
  font-weight: var(--peso-cifra);
  color: var(--fg-txt);
}

.s-etapas { display: flex; flex-direction: column; gap: var(--e-3); }
.s-etapa {
  border: var(--b-fino) solid var(--fg-borde);
  border-radius: var(--r-md);
  background: var(--fg-2);
  padding: var(--e-4);
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
}
.s-etapa-fila { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; }
.s-etapa h3 { color: var(--fg-txt); }
.s-etapa-barra {
  flex: 1 1 180px;
  height: 8px;
  min-width: 120px;
  border-radius: var(--r-full);
  background: color-mix(in oklab, var(--fg-txt) 14%, transparent);
  overflow: hidden;
}
.s-etapa-barra > i {
  display: block;
  height: 100%;
  width: calc(var(--pct, 0) * 1%);
  background: var(--p);
  border-radius: inherit;
}
.s-etapa-pct { font-family: var(--fuente-num); font-weight: var(--peso-cifra); color: var(--fg-txt); }

/* Vista línea de tiempo: es la que arranca en móvil, porque una tabla de 8
   columnas con scroll horizontal en un celular es inutilizable. */
.s-linea { display: flex; flex-direction: column; gap: var(--e-4); }
.s-linea-item {
  position: relative;
  padding-left: var(--e-5);
  border-left: var(--b-grueso) solid var(--fg-borde);
  padding-bottom: var(--e-4);
}
.s-linea-item::before {
  content: "";
  position: absolute;
  left: calc(var(--b-grueso) * -1 - 5px);
  top: 4px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--p);
  border: 2px solid var(--fg);
}
.s-linea-fecha { font-family: var(--fuente-num); font-size: var(--t-xs); color: var(--fg-txt-3); }
.s-fotos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--e-2);
  margin-top: var(--e-2);
}
.s-fotos img { border-radius: var(--r-sm); aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }

/* La tabla del Gantt scrollea dentro de su caja, nunca en el body. */
.s-gantt-wrap { overflow-x: auto; overscroll-behavior-x: contain; }

/* --------------------------------------------------------------------------
   15. Animaciones configurables (CONTRATO §5)
   Las define animaciones.css completas: clases .anim-* del <html>, keyframes
   de transición de escena, entrada de interfaz, portada y hotspots. Acá no se
   repite ni una: dos archivos animando el mismo elemento terminan con una
   animación pisando a la otra según el orden de carga, que es de los bugs más
   caros de diagnosticar.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   16. Tramos (CONTRATO §7 + DISENO §6)
   Cuatro tramos reales. El orden es de mayor a menor: cada uno solo declara
   lo que cambia respecto del anterior.
   -------------------------------------------------------------------------- */

/* ── Escritorio (>=1024px) es el default declarado arriba ─────────────────
   thumbs 72px · menú 360px · ficha lateral 420px · controles 40px visuales
   con 44 táctiles · etiquetas de hotspot al pasar el mouse.               */

/* ── Tablet (<1024px) ─────────────────────────────────────────────────── */
@media (max-width: 1023.98px) {
  .s-thumbs-wrap { --thumb-alto: 56px; }
  .s-menu-panel { width: min(320px, 92vw); }
  .s-ficha { width: min(380px, 92vw); }
  .s-pill, .s-segmento { height: var(--tactil); }
  .s-pill-icono { width: var(--tactil); }
}

/* ── Móvil (<640px) ───────────────────────────────────────────────────── */
@media (max-width: 639.98px) {
  :root { --borde-pantalla: var(--e-4); }

  .s-thumbs-wrap { --thumb-alto: 44px; max-width: calc(100vw - var(--e-5)); }

  /* La ficha de escena flotante se va al menú: en 640px de ancho tapa la
     imagen, que es justamente lo que el visitante vino a ver. */
  .s-info { display: none; }

  /* Migas: solo los dos últimos niveles. */
  .s-crumbs > .s-crumb:not(.s-crumb-actual):not(:nth-last-child(3)),
  .s-crumbs > .s-crumb-sep:not(:nth-last-child(2)) { display: none; }

  /* Menú a pantalla completa. */
  .s-menu-panel {
    width: 100%;
    border-right: 0;
    animation-name: s-fundido-in;
  }

  /* La ficha de unidad pasa a ser hoja hasta el 88% del alto, con manija. */
  .s-ficha {
    top: auto; right: 0; left: 0; bottom: 0;
    width: auto;
    max-height: 88dvh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    animation-name: s-ficha-hoja;
  }
  .s-ficha-manija {
    display: block;
    width: 40px; height: 4px;
    margin: var(--e-2) auto 0;
    border-radius: var(--r-full);
    background: var(--fg-txt-3);
    flex: none;
    /* zona de arrastre real de 44px de alto sin dibujar 44px */
    position: relative;
  }
  .s-ficha-manija::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 120px; height: var(--tactil);
    transform: translate(-50%, -50%);
  }

  /* Avance: bajo 640px manda la línea de tiempo. Una carta Gantt de ocho
     columnas con scroll horizontal en un celular no se puede leer, así que
     la tabla no se ofrece aunque el JS no haya cambiado de vista. */
  .s-gantt-wrap { display: none; }
  .s-linea { display: flex; }

  .s-hot-etiqueta { max-width: 60vw; }
  .s-portada-acciones { width: 100%; flex-direction: column; }
  .s-portada-acciones > * { width: 100%; }
  .s-avance { padding-inline: var(--e-4); }
}

/* ── Compacto (<380px) ────────────────────────────────────────────────────
   Tramo de diseño, no un breakpoint más chico: se QUITA contenido, no se
   encoge. Ningún texto baja de 13px y ningún control baja de 44px.
   Máximo 3 acciones visibles a la vez; el resto vive en el menú.          */
@media (max-width: 379.98px) {
  :root { --borde-pantalla: var(--e-3); }

  /* Lo secundario se va al menú. El JS marca con .s-secundario todo lo que
     puede desaparecer sin dejar al visitante sin salida. */
  .s-secundario { display: none !important; }

  /* Migas: solo el nivel actual y el botón volver. */
  .s-crumbs > .s-crumb:not(.s-crumb-actual),
  .s-crumbs > .s-crumb-sep { display: none; }
  .s-crumb-volver { display: inline-flex; }
  .s-crumbs { max-width: calc(100vw - var(--e-6)); }

  /* La tira de miniaturas arranca cerrada y se abre con un botón. */
  .s-thumbs-wrap { display: none; }
  body.s-thumbs-abiertos .s-thumbs-wrap { display: block; }
  .s-thumbs-toggle { display: inline-flex; }

  /* Controles agrupados en UNA barra, a 44px: el mínimo no se relaja. */
  .s-barra { gap: var(--e-2); }
  .s-pill { height: var(--tactil); padding: 0 var(--e-2); }
  .s-pill-icono { width: var(--tactil); }
  .s-pill-texto { display: none; }        /* se va el texto, no el tamaño */
  .s-pill-cta { height: var(--tactil); padding: 0 var(--e-4); }
  .s-segmento { height: var(--tactil); }

  /* Nada de letra más chica: 13px es el piso del sistema. */
  .s-info p, .s-crumbs, .s-hot-etiqueta, .s-nodo, .s-canal,
  .s-portada-sub, .s-portada-pista { font-size: var(--t-xs); }

  .s-portada-titulo { font-size: clamp(1.75rem, 8vw, 2.25rem); }
  .s-ficha-datos { grid-template-columns: 1fr 1fr; }
  .s-fotos { grid-template-columns: 1fr 1fr; }
}

/* ── Alto chico: celular acostado ────────────────────────────────────────
   Solo menú, volver y hotspots. Todo lo demás estorba: la imagen es lo
   único que cabe.                                                         */
@media (max-height: 480px) {
  :root { --borde-pantalla: var(--e-3); }
  .s-info,
  .s-thumbs-wrap,
  .s-crumbs,
  .s-canales,
  .s-secundario { display: none !important; }
  .s-portada { padding-block: var(--e-4); }
  .s-portada-logo { max-height: 40px; }
  .s-portada-titulo { font-size: clamp(1.5rem, 5vw, 2rem); }
  .s-ficha { max-height: 100dvh; top: 0; }
  .s-velo-arriba { height: 28dvh; }
  .s-velo-abajo { height: 32dvh; }
}

/* Punteros gruesos: el hover no existe, así que el estado de reposo tiene
   que bastarse solo. Se agranda el punto para que se vea sin pasar el dedo. */
@media (hover: none) {
  :where(.s-hot) { --hot-d: 18px; }
}
