/* ══════════════════════════════════════════════════════════════════
   HAUSTIERE · Centro veterinario, Puerto Varas — demo CristalWeb
   ------------------------------------------------------------------
   DIRECCIÓN: «ORDNUNG». Duotono estricto de tinta y hueso, SIN tercer
   color en toda la página. La grilla es dura —herencia de la escuela
   de Ulm— y la calidez la ponen exclusivamente las fotos. El contraste
   entre retícula fría y foto tibia es el juego de todo el sitio, y es
   coherente con el nombre alemán en la ciudad de la colonización.

   Deslinde escrito:
     · De las DIECISÉIS veterinarias anteriores del registro, las
       dieciséis se apoyan en un color (turquesa, verde, teja, violeta,
       índigo, malva, oliva, ámbar, orquídea, granate, rojo, mostaza,
       rosa, coral y el naranjo de la pmv-07). Ésta es la primera que
       se niega a tener uno.
     · Tercer duotono del registro tras 51-casas-fabelsa (pino y
       alerce) y 77-beroiza (acero): aquéllos son cálido-madera y
       frío-metal; éste es tinta y hueso, y el destaque se hace
       INVIRTIENDO el bloque, no coloreándolo.

   TRÍO
     Display · Barlow Condensed — familia distinta de Barlow y de
       Barlow Semi Condensed en Google Fonts; nueva en el registro.
       Condensada y seca, de rotulación institucional.
     Cuerpo  · Atkinson Hyperlegible — segunda aparición (50-aktiv).
       Está hecha para legibilidad máxima, que es de lo que trata una
       página que explica vocabulario.
     Dato    · Martian Mono — cuarta aparición. Cuadriculada, encaja
       con la retícula.
   ══════════════════════════════════════════════════════════════════ */

:root {
  --hueso:   #F0EFEA;
  --hueso-2: #E2E0D8;
  --tinta:   #1A1A17;
  --tinta-2: #2C2C27;
  --medio:   #55544D;   /* 6,9:1 sobre hueso */
  --linea:   rgba(26,26,23,.2);

  --display: 'Barlow Condensed', 'Arial Narrow', sans-serif;
  --cuerpo:  'Atkinson Hyperlegible', 'Segoe UI', system-ui, sans-serif;
  --mono:    'Martian Mono', 'Consolas', ui-monospace, monospace;

  --p--1: clamp(.8rem, .77rem + .12vw, .88rem);
  --p-0:  clamp(1rem, .96rem + .2vw, 1.1rem);
  --p-1:  clamp(1.2rem, 1.1rem + .35vw, 1.45rem);
  --p-2:  clamp(1.5rem, 1.3rem + .8vw, 2.1rem);
  --p-3:  clamp(2rem, 1.6rem + 1.8vw, 3.2rem);
  --p-4:  clamp(2.8rem, 1.9rem + 4vw, 5.4rem);

  --aire:  clamp(3.5rem, 2.2rem + 5vw, 7rem);
  --ancho: min(100% - 2.5rem, 1160px);
  --salida: cubic-bezier(.16, 1, .3, 1);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body { margin: 0; background: var(--hueso); color: var(--tinta); font-family: var(--cuerpo); font-size: var(--p-0); line-height: 1.6; }
img { max-width: 100%; height: auto; }
a { color: var(--tinta); }
:focus-visible { outline: 3px solid var(--tinta); outline-offset: 2px; }
.ancho { width: var(--ancho); margin-inline: auto; }
h1, h2, h3 { font-family: var(--display); font-weight: 600; line-height: 1.05; margin: 0; text-transform: uppercase; letter-spacing: .01em; }
.mono { font-family: var(--mono); }

.rotulo { font-family: var(--mono); font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--medio); margin: 0 0 .8rem; }
.rotulo--claro { color: var(--hueso-2); }
.titulo { font-size: var(--p-3); max-width: 22ch; margin-bottom: 1rem; }
.titulo--claro { color: var(--hueso); }
.entradilla { max-width: 60ch; color: var(--medio); font-size: var(--p-1); margin: 0 0 2rem; }
.entradilla b { color: var(--tinta); font-weight: 700; }
.nota { margin-top: 1.6rem; font-size: var(--p--1); color: var(--medio); max-width: 66ch; }
.sobre { font-family: var(--mono); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--medio); margin: 0 0 1rem; }

/* ── Dato de ejemplo ───────────────────────────────────────────── */
.ej { position: relative; border: 1px dashed var(--linea); }
.ej::after {
  content: attr(data-ejemplo); position: absolute; top: -.62rem; right: .6rem;
  font-family: var(--mono); font-size: .6rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--medio); background: var(--hueso); padding: 0 .35rem;
}

/* ── Botones · sin color: el destaque es la INVERSIÓN ──────────── */
.boton {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: .8rem 1.6rem;
  border: 2px solid var(--tinta); border-radius: 0;
  background: var(--tinta); color: var(--hueso);
  font-family: var(--display); font-size: var(--p-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
  text-decoration: none; cursor: pointer;
  transition: transform .16s ease-out, background-color .16s, color .16s;
}
.boton:hover { background: transparent; color: var(--tinta); transform: translateY(-2px); }
.boton:active { transform: translateY(0); }
.boton--linea { background: transparent; color: var(--tinta); }
.boton--linea:hover { background: var(--tinta); color: var(--hueso); }
.boton--chico { min-height: 44px; padding: .4rem 1rem; font-size: var(--p-0); border-width: 1px; }

/* ── Propuesta ─────────────────────────────────────────────────── */
.propuesta { background: var(--tinta); color: var(--hueso); padding: .85rem clamp(1.2rem, 5vw, 3rem); }
.propuesta__que { margin: 0 0 .3rem; font-size: var(--p--1); font-family: var(--mono); }
.propuesta__que b { text-decoration: underline; text-underline-offset: 3px; }
.propuesta__gancho { margin: 0; font-size: var(--p--1); color: #B5B4AC; max-width: 96ch; line-height: 1.5; }

/* ── Cabecera ──────────────────────────────────────────────────── */
.cab { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 1rem; padding: .7rem clamp(1rem, 4vw, 2.4rem); background: rgba(240,239,234,.94); border-bottom: 2px solid var(--tinta); }
.cab--flota { box-shadow: 0 6px 22px -16px rgba(26,26,23,.9); }
.cab__marca { display: flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--tinta); }
/* Cuatro cuadros: la retícula misma como emblema. Cero bytes. */
.cuadro { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; width: 22px; height: 22px; flex: none; }
.cuadro i { display: block; background: var(--tinta); }
.cuadro i:nth-child(2), .cuadro i:nth-child(3) { background: transparent; border: 1.5px solid var(--tinta); }
.cab__nombre { font-family: var(--display); font-size: var(--p-1); line-height: 1; text-transform: uppercase; letter-spacing: .06em; }
.cab__sub { display: block; font-family: var(--mono); font-size: .56rem; letter-spacing: .1em; text-transform: uppercase; color: var(--medio); margin-top: .3rem; }
.cab__nav { display: flex; gap: 1.2rem; margin-left: auto; overflow-x: auto; }
/* 44 px de alto también en escritorio: medido, quedaban en 37. */
.cab__nav a { display: inline-flex; align-items: center; min-height: 44px; color: var(--medio); text-decoration: none; font-size: var(--p--1); white-space: nowrap; padding: .4rem 0; border-bottom: 2px solid transparent; }
.cab__nav a:hover { color: var(--tinta); border-bottom-color: var(--tinta); }
.cab__cta { margin-left: .4rem; }
@media (max-width: 1000px) { .cab__nav { display: none; } .cab__cta { margin-left: auto; } }

/* ── Portada ───────────────────────────────────────────────────── */
.portada { position: relative; isolation: isolate; min-height: min(84vh, 720px); display: flex; flex-direction: column; justify-content: center; padding: var(--aire) 0; overflow: hidden; }
.portada__foto { position: absolute; inset: 0; z-index: -1; }
/* El clip comparte selector con la foto: misma máscara, mismo
   object-fit y mismo object-position, escritos UNA vez. Si se separan,
   foto y video se descuadran en cuanto se toque uno. */
.portada__foto img, .portada__video {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 70% 44%;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 26%, rgba(0,0,0,.2) 42%, rgba(0,0,0,.7) 60%, #000 76%, #000 100%);
          mask-image: linear-gradient(90deg, transparent 0%, transparent 26%, rgba(0,0,0,.2) 42%, rgba(0,0,0,.7) 60%, #000 76%, #000 100%);
}
/* Velo entero en rgba y terminando en alfa 0. */
.portada__foto::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg,
      rgba(240,239,234,1) 0%, rgba(240,239,234,1) 30%,
      rgba(240,239,234,.74) 46%, rgba(240,239,234,.32) 64%,
      rgba(240,239,234,.08) 82%, rgba(240,239,234,0) 96%);
}
/* En móvil el texto deja de estar AL LADO de la foto y pasa a estar
   ENCIMA: si la máscara y el velo siguen en 90deg, la bajada cae sobre la
   hierba y se pierde. Medido a 375 px, donde no se leía.
   Las dos capas rotan a 180deg y el sujeto del clip —el perro, que está
   en el borde inferior del cuadro— se mantiene visible abajo, que es
   justo la franja que el texto no ocupa. */
@media (max-width: 760px) {
  .portada { min-height: min(92vh, 680px); padding-top: 2rem; }
  .portada__foto img, .portada__video {
    object-position: 60% 62%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 30%, rgba(0,0,0,.35) 46%, rgba(0,0,0,.8) 62%, #000 74%, #000 100%);
            mask-image: linear-gradient(180deg, transparent 0%, transparent 30%, rgba(0,0,0,.35) 46%, rgba(0,0,0,.8) 62%, #000 74%, #000 100%);
  }
  .portada__foto::after {
    background: linear-gradient(180deg,
        rgba(240,239,234,1) 0%,  rgba(240,239,234,1) 34%,
        rgba(240,239,234,.88) 48%, rgba(240,239,234,.5) 66%,
        rgba(240,239,234,.14) 84%, rgba(240,239,234,0) 100%);
  }
}

.portada__texto { width: var(--ancho); margin-inline: auto; }
.portada__titulo { font-size: var(--p-4); max-width: 16ch; font-weight: 700; }
.portada__titulo span { display: block; }
.portada__trad { font-family: var(--cuerpo); font-size: var(--p-1); font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--medio); margin-top: .5rem; }
.portada__bajada { max-width: 46ch; color: var(--medio); font-size: var(--p-1); margin: 1.4rem 0 2rem; }
.acciones { display: flex; flex-wrap: wrap; gap: .8rem; }

/* ── Escena de portada · la cola que se mueve ──────────────────────
   movimiento-web, ficha «Veterinaria» idea B, escalón 1. El reposo más
   barato del catálogo y el único de esta portada.

   DESVÍO ANOTADO: la ficha pide la silueta al 40 % de alto. Acá va al
   20 % y ABAJO DE LOS BOTONES, no al costado. El costado no existe:
   medido a 800, 1100 y 1440 px, el borde derecho del botón «Cuándo
   traerlo» cae en el 55 %, el 41 % y el 41 % del ancho, así que
   cualquier `left` fijo lo pisa en alguno de los tres —con left:40 %
   la silueta se metía 125 px DENTRO del botón a 800 px y quedaba
   cortada por detrás, porque el texto se pinta sobre el z-index -1—.
   El único hueco de hueso libre en todos los anchos es la franja de
   abajo, y ahí va, anclada a la MISMA vertical que la columna de texto
   —(100% - var(--ancho))/2— para que no sea un objeto suelto sino el
   pie de la columna. */
.escena { position: absolute; z-index: -1; pointer-events: none; }
.escena--perro {
  left: max(1.25rem, calc((100% - var(--ancho)) / 2));
  bottom: 2%; height: 20%; width: auto;
  display: flex; align-items: flex-end;
}
.escena__svg { display: block; height: 100%; width: auto; }
.escena__cuerpo, .escena__cola { fill: var(--tinta); }

/* RESPALDO RADIAL. Medido a 1100 px: ahí la foto entra antes que a 1440
   y la silueta caía encima del brazo del animal fotografiado, leyéndose
   como una mancha. Doce palabras de CSS le dan su propia mancha de hueso
   y la separan del fondo en CUALQUIER ancho, sin subir el velo —que es
   lo que aplanaría la foto—. Se descubre mirando la página, no el código. */
.escena--perro::before {
  content: ""; position: absolute; inset: -20% -28%; z-index: -1;
  background: radial-gradient(closest-side, rgba(240,239,234,.94), rgba(240,239,234,.6) 62%, rgba(240,239,234,0) 100%);
}

/* La entrada: fundido corto y 12 px de subida. */
@keyframes perro-llega {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
.js .escena--perro { animation: perro-llega .4s var(--salida) .3s both; }

/* Y sólo la cola se mueve. El origen va en la BASE de la cola, en
   coordenadas del viewBox: sin transform-box la rotación giraría sobre
   el origen del SVG y la cola saldría volando. */
.escena__cola { transform-box: view-box; transform-origin: 154px 150px; }
@keyframes cola-mueve {
  from { transform: rotate(-14deg); }
  to   { transform: rotate(14deg); }
}
/* Arranca a .8 s: primero el perro se sienta, después mueve la cola. */
.js .escena__cola { animation: cola-mueve 1.1s ease-in-out .8s infinite alternate; }

/* BAJO 760 px LA SILUETA NO VA. Es un desvío de la ficha de
   movimiento-web y está mirado, no supuesto: en móvil la máscara y el
   velo rotan a vertical, así que la foto deja de estar AL LADO y pasa a
   ocupar toda la mitad inferior. Ahí no queda un solo trozo de hueso
   libre —el texto se come el de arriba y la foto el de abajo—, y la
   silueta, la pongas donde la pongas, cae sobre la hierba y sobre las
   patas del perro fotografiado. Un perro negro encima de un perro
   fotografiado es ruido: lo dice el comentario de identidad de esta
   misma hoja, y a 375, 500 y 520 px es exactamente lo que pasaba.
   Además, en esas anchuras la cola quedaba contra el borde derecho y el
   pecho contra el botón «Cuándo traerlo».
   Y no se pierde nada: con clip de fondo, el ambiente de la portada ES
   el video (§4.4 del estándar). El reposo sigue existiendo donde tiene
   sitio propio, que es de 761 px para arriba. */
@media (max-width: 760px) {
  .escena--perro { display: none; }
}

/* ── Cifras ────────────────────────────────────────────────────────
   Cuatro celdas separadas por 2 px de hueso translúcido: la retícula
   otra vez, ahora en negativo. La herida se destaca INVIRTIENDO la
   celda —fondo hueso, número tinta—, que es la única forma de destacar
   que admite un duotono sin acento.
   Contraste medido: número hueso #F0EFEA sobre tinta #1A1A17 = 15,3:1;
   rótulo #C8C7BE sobre la misma tinta = 10,3:1; y en la celda invertida
   tinta sobre hueso = 15,3:1 con --medio #55544D en el rótulo = 6,9:1. */
.cifras { background: var(--tinta); color: var(--hueso); padding: var(--aire) 0; }
/* OJO: el `auto` del margen es obligatorio. La lista lleva la clase
   .ancho, que centra con margin-inline:auto, pero esta regla se escribe
   DESPUÉS y con la misma especificidad: un `margin: 0` a secas la pisa y
   la caja —que acá tiene filete visible— queda pegada al borde izquierdo
   de la ventana mientras el resto de la página empieza 133 px adentro.
   Medido a 1440 px: left=0 contra left=133 de todos los demás bloques. */
.cifras__lista {
  list-style: none; margin: 0 auto; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px;
  background: rgba(240,239,234,.28);
  border: 2px solid rgba(240,239,234,.28);
}
.cifras__lista li { background: var(--tinta); padding: 1.4rem 1.1rem 1.2rem; display: flex; flex-direction: column; gap: .6rem; }
.cifras__lista b {
  font-family: var(--display); font-weight: 700; font-size: var(--p-4);
  line-height: .9; letter-spacing: -.01em; font-variant-numeric: tabular-nums;
  color: var(--hueso);
}
.cifras__lista span { font-family: var(--mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: #C8C7BE; line-height: 1.5; }
/* La celda de la herida, invertida. */
.cifra--herida { background: var(--hueso) !important; }
.cifra--herida b { color: var(--tinta); }
.cifra--herida span { color: var(--medio); }
/* El pie va DENTRO de un div.ancho y sin margen automático: así arranca
   en la misma vertical que el filete de la lista. Con margin:auto sobre
   un max-width de 74ch quedaba centrado en la ventana y no coincidía con
   ninguna otra línea de la página. */
.cifras__pie { margin: 1.2rem 0 0; font-size: var(--p--1); color: #A9A89F; max-width: 74ch; }
@media (max-width: 860px) { .cifras__lista { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 400px) { .cifras__lista { grid-template-columns: 1fr; } }

/* ── PIEZA FIRMA · el diccionario ──────────────────────────────── */
.dicc { padding: var(--aire) 0; }
.terminos {
  list-style: none; margin: 2.5rem auto 0; padding: 0;
  width: var(--ancho);
  display: grid; gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  background: var(--linea);
  border: 2px solid var(--tinta);
}
.term { background: var(--hueso); padding: 1.3rem; }
/* El término alemán es el titular; la traducción va debajo, chica y en
   mono, como en un diccionario impreso. */
.term__de { margin: 0; font-family: var(--display); font-size: var(--p-2); font-weight: 700; text-transform: uppercase; line-height: 1; }
.term__es { margin: .3rem 0 .9rem; font-family: var(--mono); font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--medio); }
.term__q { margin: 0; font-size: var(--p--1); color: var(--medio); }
/* Uno de cada cuatro va invertido: el ritmo de la retícula sin recurrir
   a un color. */
.term:nth-child(4n+1) { background: var(--tinta); }
.term:nth-child(4n+1) .term__de { color: var(--hueso); }
.term:nth-child(4n+1) .term__es { color: #A9A89F; }
.term:nth-child(4n+1) .term__q { color: #C8C7BE; }

/* ── Tajo ──────────────────────────────────────────────────────────
   El velo sube desde abajo y termina en alfa 0 arriba: los dos tercios
   altos de la foto quedan nítidos.
   PEOR CASO MEDIDO SOBRE LA PÁGINA VIVA, no a ojo (el auditor da falso
   1,00:1 acá, porque el fondo lo pinta un ::after y él lee el body): se
   leyó el rectángulo real de cada línea contra la caja del .tajo y se
   evaluó el gradiente en esa posición, suponiendo la foto BLANCA pura
   debajo. A 1440 px el titular arranca sobre alfa 0,59 → 3,87:1 con el
   hueso #F0EFEA; es texto de 51 px, que pide 3:1. A 1100 px da 4,52:1,
   a 800 px 5,46:1 y a 375 px 3,55:1 con 32 px, que también es texto
   grande. El párrafo cae entre alfa 0,87 y 0,93 → 7,00:1 a 1440 px y
   5,88:1 a 375 px con #C8C7BE, sobre el mínimo de 4,5 de texto normal.
   Con la foto real, que es oscura, los dos superan 12:1.
   (Antes decía «alfa .62 → 4,1:1»: estaba estimado a ojo y era medio
   punto optimista. Los números de arriba salen de la medición.) */
.tajo { position: relative; margin: 0; isolation: isolate; min-height: min(52vh, 420px); display: flex; align-items: flex-end; overflow: hidden; }
.tajo img { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; object-fit: cover; object-position: 50% 44%; }
.tajo::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(0deg, rgba(26,26,23,.95) 0%, rgba(26,26,23,.8) 34%, rgba(26,26,23,.34) 62%, rgba(26,26,23,0) 92%); }
.tajo__txt { width: var(--ancho); margin-inline: auto; padding: 2.5rem 0; }
.tajo__txt h2 { font-size: var(--p-3); max-width: 20ch; color: var(--hueso); }
.tajo__txt p { max-width: 48ch; color: #C8C7BE; margin: .9rem 0 0; }

/* ── Servicios ─────────────────────────────────────────────────── */
.servicios { padding: var(--aire) 0; background: var(--hueso-2); }
.serv { list-style: none; margin: 0; padding: 1.6rem; display: grid; gap: 1.4rem; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.serv h3{ font-size: var(--p-1); margin-bottom: .3rem; }
.serv p { margin: 0; font-size: var(--p--1); color: var(--medio); }

/* ── Mitades · qué traer ───────────────────────────────────────────
   Media pantalla de foto y media de tinta, sin nada en medio: es la
   grilla llevada al extremo. El borde de 2 px entre las dos mitades es
   el mismo filete de toda la página.
   Overrides declarados UNO POR UNO porque la luminancia se invierte:
   rótulo, entradilla, nota, negritas y numeración. Usar --medio acá
   daría 1,4:1 sobre tinta. */
.mit { display: grid; grid-template-columns: 1fr 1fr; background: var(--tinta); }
.mit__foto { margin: 0; overflow: hidden; border-right: 2px solid var(--tinta); }
.mit__foto img { display: block; width: 100%; height: 100%; min-height: 340px; object-fit: cover; object-position: 52% 46%; }
.mit__txt { color: var(--hueso); padding: var(--aire) clamp(1.4rem, 4vw, 3.4rem); }
.mit__txt .titulo { max-width: 16ch; }
.entradilla--clara { color: #C8C7BE; }          /* 10,3:1 sobre tinta */
.entradilla--clara b { color: var(--hueso); }
.nota--clara { color: #A9A89F; }                /* 7,1:1 sobre tinta */

/* Numeración dibujada: el número va en mono dentro de un cuadrado
   hueso, del mismo tamaño que el bullet de las señales. Nada de
   list-style. */
.traer { list-style: none; margin: 0 0 .4rem; padding: 0; counter-reset: t; }
.traer li {
  counter-increment: t; position: relative;
  padding: .85rem 0 .85rem 2.6rem;
  border-bottom: 1px solid rgba(240,239,234,.22);
  font-size: var(--p--1); color: #C8C7BE;
}
.traer li:last-child { border-bottom: 0; }
.traer li::before {
  content: counter(t, decimal-leading-zero);
  position: absolute; left: 0; top: .85rem;
  width: 1.9rem; height: 1.35rem;
  display: flex; align-items: center; justify-content: center;
  background: var(--hueso); color: var(--tinta);
  font-family: var(--mono); font-size: .58rem; letter-spacing: .04em;
}
.traer b { color: var(--hueso); font-weight: 700; }

/* Bajo 820 px la foto pasa arriba y se aplana a una franja: a media
   pantalla en vertical la foto se comía el texto entero. */
@media (max-width: 820px) {
  .mit { grid-template-columns: 1fr; }
  .mit__foto { border-right: 0; border-bottom: 2px solid var(--tinta); }
  .mit__foto img { min-height: 0; height: clamp(200px, 46vw, 320px); }
}

/* ── Cuándo traerlo, con telón ─────────────────────────────────── */
.cuando { padding: var(--aire) 0; }
.con-telon { position: relative; isolation: isolate; overflow: hidden; }
.telon { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
/* Foto NÍTIDA al 15%: telón, no aura. Cero desenfoque. */
.telon img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 46%; opacity: .15;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 74%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 20%, #000 74%, transparent 100%);
}
.cuando__cols { display: grid; gap: 1.6rem; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); max-width: 74ch; }
.senales { margin: 0; padding: 0; list-style: none; }
.senales li { padding: .7rem 0 .7rem 1.6rem; border-bottom: 1px solid var(--linea); position: relative; font-size: var(--p--1); color: var(--medio); }
.senales li::before { content: ""; position: absolute; left: 0; top: 1.15rem; width: 8px; height: 8px; background: var(--tinta); }

/* ── Cita ──────────────────────────────────────────────────────────
   Texto CENTRADO, así que el velo es PLANO: con un gradiente lateral la
   mitad derecha de una frase centrada quedaría sobre alfa .3 y perdería
   AA. .78 está por encima del mínimo de .72 de la casa.
   PEOR CASO MEDIDO A MANO —acá también el auditor lee 1,00:1 porque el
   fondo es un ::after—: con un fotograma BLANCO puro debajo, el velo deja
   #4C4C4B y el hueso #F0EFEA da 7,5:1. Pase lo que pase con el clip. */
.cita { position: relative; margin: 0; isolation: isolate; min-height: min(48vh, 380px); display: grid; place-items: center; overflow: hidden; }
.cita img, .cita__video { position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; object-fit: cover; object-position: 50% 46%; }
.cita::after { content: ""; position: absolute; inset: 0; z-index: -1; background: rgba(26,26,23,.78); }
.cita__txt { margin: 0; width: var(--ancho); padding: 3rem 0; }
.cita__txt p { font-family: var(--display); font-size: var(--p-3); text-transform: uppercase; color: var(--hueso); max-width: 22ch; margin: 0 auto; text-align: center; line-height: 1.08; }

/* ── Mosaico ───────────────────────────────────────────────────── */
.mos { padding: var(--aire) 0; }
/* CUATRO columnas, no tres. Con tres, las celdas 1 y 6 a doble ancho
   suman ocho huecos sobre tres columnas y sobra uno: quedaba un
   rectángulo negro al final de la retícula, medido a 1440 px.
   Con cuatro cierra exacto: fila 1 = 1(doble) + 2 + 3, fila 2 = 4 + 5 +
   6(doble). Y a dos columnas —bajo 640 px— también cierra: la 1 ocupa
   la fila entera, 2 y 3 una fila, 4 y 5 otra, y la 6 la última.
   La altura la fija grid-auto-rows y no el aspect-ratio de la foto:
   así las celdas dobles quedan del mismo alto que las simples. */
.mos__grilla {
  display: grid; gap: 2px;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: clamp(150px, 17vw, 250px);
  width: var(--ancho); margin: 2rem auto 0;
  background: var(--tinta); border: 2px solid var(--tinta);
}
.mos__p { margin: 0; overflow: hidden; }
.mos__p:nth-child(1), .mos__p:nth-child(6) { grid-column: span 2; }
.mos__p img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--salida); }
.mos__p:hover img { transform: scale(1.05); }
@media (max-width: 640px) {
  .mos__grilla { grid-template-columns: repeat(2, 1fr); grid-auto-rows: clamp(130px, 30vw, 200px); }
}

/* ── La consulta, paso a paso ──────────────────────────────────────
   Banda oscura entre el mosaico y la esquina, que eran dos claras
   seguidas. Los overrides van declarados uno por uno, igual que en la
   sección de mitades: --medio sobre tinta da 1,4:1.

   EL NÚMERO HUECO: relleno del color del fondo y contorno de 1,5 px en
   hueso al 55 %. Se lee como grabado y no compite con el h3. El tercero
   rompe el patrón —relleno sólido, sin contorno— y es lo único que
   dirige la vista en una paleta que no tiene color de acento.
   Contraste medido: h3 hueso #F0EFEA sobre tinta #1A1A17 = 15,3:1;
   párrafo #C8C7BE = 10,3:1; el número es decorativo (aria-hidden) y el
   orden lo da el <ol>, así que su contorno no necesita pasar AA. */
.pasos { padding: var(--aire) 0; background: var(--tinta); color: var(--hueso); }
.pasos__lista {
  list-style: none; margin: 2.4rem 0 0; padding: 0;
  display: grid; gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  background: rgba(240,239,234,.28);
  border: 2px solid rgba(240,239,234,.28);
}
.paso { background: var(--tinta); padding: 1.4rem 1.2rem 1.5rem; }
.paso__n {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: clamp(3rem, 2rem + 4vw, 4.6rem); line-height: .85;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  margin-bottom: .7rem;
  color: var(--tinta);
  -webkit-text-stroke: 1.5px rgba(240,239,234,.55);
}
.paso h3 { font-size: var(--p-1); color: var(--hueso); margin-bottom: .4rem; }
.paso p  { margin: 0; font-size: var(--p--1); color: #C8C7BE; }   /* 10,3:1 */
/* La celda destacada va DESPUÉS de las anteriores a propósito:
   «.paso--marca h3» y «.paso h3» tienen la MISMA especificidad (una clase
   y un tipo), así que gana la última escrita. Con el orden al revés el
   título quedaba hueso sobre hueso-2 = 1,15:1 — medido, no supuesto. */
.paso--marca { background: var(--hueso-2); }
.paso--marca .paso__n { color: var(--tinta); -webkit-text-stroke: 0; }
.paso--marca h3 { color: var(--tinta); }      /* 14,2:1 sobre hueso-2 */
.paso--marca p  { color: var(--medio); }      /* 6,4:1 sobre hueso-2 */

/* ── La esquina ────────────────────────────────────────────────── */
.esquina { padding: var(--aire) 0; background: var(--hueso-2); }
.esquina__cols { display: grid; gap: clamp(2rem, 5vw, 4rem); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; }
.datos { margin: 0 0 1.6rem; display: grid; }
.datos > div { display: grid; grid-template-columns: 10rem 1fr; gap: .6rem; padding: .75rem .6rem; border-bottom: 1px solid var(--linea); }
.datos dt { font-family: var(--mono); font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--medio); }
.datos dd { margin: 0; }
.datos .ej::after { background: var(--hueso-2); }
@media (max-width: 480px) { .datos > div { grid-template-columns: 1fr; } }

.hueco-foto {
  padding: 1.6rem; background: var(--hueso);
  background-image: repeating-linear-gradient(135deg, rgba(26,26,23,.05) 0 10px, transparent 10px 20px);
}
.hueco-foto::after { background: var(--hueso); }
.hueco-foto p { margin: 0; font-size: var(--p--1); color: var(--medio); }

.pedir { background: var(--hueso); border: 2px solid var(--tinta); padding: clamp(1.2rem, 3vw, 2rem); }
.pedir__t { font-size: var(--p-2); margin-bottom: 1rem; }
.form { display: grid; gap: .9rem; }
.form label { display: grid; gap: .3rem; font-family: var(--mono); font-size: .68rem; letter-spacing: .05em; text-transform: uppercase; color: var(--medio); }
.form input {
  font-family: var(--cuerpo); font-size: var(--p-0);
  padding: .7rem .8rem; min-height: 46px;
  border: 1px solid var(--linea); border-radius: 0;
  background: #F7F6F2; color: var(--tinta); text-transform: none;
}
.form input:focus-visible { border-color: var(--tinta); }
.form__salida { font-family: var(--mono); font-size: var(--p--1); background: var(--hueso-2); border-left: 4px solid var(--tinta); padding: .7rem .8rem; margin: .2rem 0 0; white-space: pre-wrap; color: var(--medio); }
.form__salida:empty { display: none; }
.form__acciones { display: flex; flex-wrap: wrap; gap: .7rem; }
.form__sinjs { margin: 1rem 0 0; font-size: var(--p--1); color: var(--medio); }

/* ── Para el dueño ─────────────────────────────────────────────── */
.dueno { padding: var(--aire) 0; background: var(--tinta); color: var(--hueso); }
.dueno__cols { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 1rem; }
.dueno__cols h3 { font-size: var(--p-1); color: var(--hueso); margin-bottom: .5rem; }
.dueno__cols p { margin: 0; color: #B5B4AC; font-size: var(--p--1); }
.dueno__cols b { color: var(--hueso); }
.dueno__cierre { display: flex; flex-wrap: wrap; gap: 1.6rem; margin: 2.5rem 0 0; }
.flecha { color: var(--hueso); text-decoration: none; font-weight: 700; border-bottom: 2px solid rgba(240,239,234,.4); padding-bottom: .15rem; }
.flecha:hover { border-bottom-color: var(--hueso); }

/* ── Pie ───────────────────────────────────────────────────────── */
.pie { background: #131311; color: #8B8A83; padding: 2rem clamp(1.2rem, 5vw, 3rem); }
.pie p { margin: 0; font-size: var(--p--1); max-width: 92ch; }

/* ══ Animación ═════════════════════════════════════════════════
   Números de movimiento-web (reglas atómicas): la OPACIDAD salta corta
   —0,3 s— y es el TRANSFORM el que dura, 0,6 s con la curva de salida. */
.js .rev { opacity: 0; transform: translateY(22px); }
.js .rev.ok {
  opacity: 1; transform: none;
  transition: opacity .3s ease-out, transform .6s var(--salida);
}
.js .portada__texto > * { animation: entra .8s var(--salida) both; }
.js .sobre           { animation-delay: .05s; }
.js .portada__titulo { animation-delay: .14s; }
.js .portada__bajada { animation-delay: .26s; }
.js .acciones        { animation-delay: .36s; }
@keyframes entra { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }

/* Estado final a la fuerza, puesto por main.js a los 2,2 s. Sin esto,
   cualquier navegador que no corra las animaciones deja la bajada, los
   botones y el perro en opacity 0 para siempre — pasó en Edge sin
   cabeza y pasaría en una pestaña de fondo. */
.portada.puesta .portada__texto > *,
.portada.puesta .escena--perro { animation: none; opacity: 1; transform: none; }

/* ── Cascadas (regla 4) ────────────────────────────────────────────
   Los ocho términos del diccionario y las seis fotos del mosaico entran
   escalonados por CONTENEDOR. Stagger min(60 ms, 500/8 = 62) = 60 ms:
   ocho términos son 420 ms, dentro del compás de medio segundo. Las
   tarjetas invertidas (4n+1) entran igual que las otras — una sola
   dirección y una sola curva por cascada, siempre. */
.js .terminos.rev,
.js .mos__grilla.rev,
.js .cifras__lista.rev,
.js .pasos__lista.rev,
.js .traer.rev { opacity: 1; transform: none; transition: none; }

.js .terminos.rev > *,
.js .mos__grilla.rev > *,
.js .cifras__lista.rev > *,
.js .pasos__lista.rev > *,
.js .traer.rev > * { opacity: 0; transform: translateY(28px); }

.js .terminos.rev.ok > *,
.js .mos__grilla.rev.ok > *,
.js .cifras__lista.rev.ok > *,
.js .pasos__lista.rev.ok > *,
.js .traer.rev.ok > * {
  opacity: 1; transform: none;
  transition: opacity .3s ease-out, transform .6s var(--salida);
  transition-delay: calc(var(--i, 0) * 60ms);
}
/* El retardo por índice va acá y no en un style="" del HTML: la CSP lo
   bloquea sin decir una palabra. */
.terminos > :nth-child(1), .mos__grilla > :nth-child(1),
.cifras__lista > :nth-child(1), .pasos__lista > :nth-child(1),
.traer > :nth-child(1) { --i: 0; }
.terminos > :nth-child(2), .mos__grilla > :nth-child(2),
.cifras__lista > :nth-child(2), .pasos__lista > :nth-child(2),
.traer > :nth-child(2) { --i: 1; }
.terminos > :nth-child(3), .mos__grilla > :nth-child(3),
.cifras__lista > :nth-child(3), .pasos__lista > :nth-child(3),
.traer > :nth-child(3) { --i: 2; }
.terminos > :nth-child(4), .mos__grilla > :nth-child(4),
.cifras__lista > :nth-child(4), .pasos__lista > :nth-child(4),
.traer > :nth-child(4) { --i: 3; }
.terminos > :nth-child(5), .mos__grilla > :nth-child(5),
.traer > :nth-child(5) { --i: 4; }
.terminos > :nth-child(6), .mos__grilla > :nth-child(6) { --i: 5; }
.terminos > :nth-child(7) { --i: 6; }
.terminos > :nth-child(8) { --i: 7; }

@media (prefers-reduced-motion: reduce) {
  .js .portada__texto > * { animation: none; opacity: 1; transform: none; }
  .mos__p:hover img { transform: none; }
  .boton:hover { transform: none; }
  /* Los reveals NO se desplazan, pero SÍ siguen fundiendo: un fundido
     no es movimiento y apagarlo deja la página muerta. */
  .js .rev { transform: none; }
  .js .terminos.rev > *,
  .js .mos__grilla.rev > *,
  .js .cifras__lista.rev > *,
  .js .pasos__lista.rev > *,
  .js .traer.rev > * { transform: none; }
  /* El botón flotante deja de deslizarse, pero sigue fundiendo. */
  .wapp { transition: opacity .28s ease; }
  .wapp--arriba { transform: none; }
  /* Perro puesto, cola quieta. */
  .js .escena--perro { animation: none; opacity: 1; transform: none; }
  .js .escena__cola  { animation: none; }
}

/* ── Blancos de toque ──────────────────────────────────────────────
   Regla de la casa: nada que se toque puede medir menos de 44 px de
   alto. Los enlaces sueltos —el teléfono dentro de la ficha de datos
   y las flechas del cierre— quedaban en 23 y 30 px medidos sobre la
   página a 375 px. Se les da caja propia sin cambiar cómo se ven. */
.datos dd a,
.flecha {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
/* La marca de la cabecera también es un enlace: 44 px mínimos. */
.cab__marca { min-height: 44px; }

/* ══ Difuminado al scroll ══════════════════════════════════════════
   Doce líneas que hacen en el compositor lo que una demo corriente
   resuelve con GSAP + ScrollTrigger y 70 KB por CDN — que además la
   CSP de esta página bloquearía. Donde el navegador no lo soporta,
   sencillamente no existe.
   La página es CLARA: la portada se disuelve HACIA el hueso, así que
   va blur + opacity. Sobre fondo oscuro habría que bajar el brillo en
   vez de la opacidad, que sobre negro no se ve.
   El scale(1.06) no es decoración: sin él el desenfoque deja ver el
   filo transparente de la caja.
   El filter va en .portada__foto, el CONTENEDOR, nunca en el <video>. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 761px) {
    .portada__foto {
      animation: portada-se-va linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 90vh;
    }
  }
}
@keyframes portada-se-va { to { filter: blur(7px); transform: scale(1.06); opacity: .5; } }

/* ══ Video de fondo ════════════════════════════════════════════════
   La foto sigue siendo la base y el clip se funde encima cuando puede
   reproducirse. Si el visitante pidió menos movimiento o va ahorrando
   datos, main.js no lo pide y no se descarga ni un byte.
   Presupuesto: portada ≤ 1,8 MB · banda ≤ 1,2 MB · 720p, sin audio.
   El fundido de 1,4 s es lo que hace que el clip «cobre vida» en vez
   de aparecer de golpe; con .3 s se ve el salto y con 2,5 s se ve
   lento. pointer-events:none para que el <video> no se coma los clics.
   ══════════════════════════════════════════════════════════════════ */
.portada__video, .cita__video {
  position: absolute; inset: 0;
  opacity: 0; transition: opacity 1.4s ease;
  pointer-events: none;
}
.portada__video.video--ver, .cita__video.video--ver { opacity: 1; }

/* ══ WhatsApp flotante ═════════════════════════════════════════════
   Botón fijo abajo a la derecha, 56 px de alto: por encima de los 44
   del mínimo táctil.

   LA DIRECCIÓN DEL TRUCO IMPORTA: el botón se ve SIEMPRE por defecto y
   el JS sólo lo aparta mientras el visitante está en la portada, para
   no tapar el titular. Si el script no arranca —o si rescate.js quita
   la clase .js— el botón queda visible, que es el estado que vende. Al
   revés, un fallo del script se llevaría el CTA principal.

   DESVÍO DE IDENTIDAD, ANOTADO: el verde de WhatsApp entra en una
   página que es duotono estricto. Se mantiene el COLOR —se reconoce sin
   leerlo, y eso es lo que hace que se toque— y se adapta la FORMA:
   rectángulo con filete de 2 px de tinta y la display en versalitas,
   como todos los botones de acá. La píldora redonda del estándar sería
   la única esquina curva de la página entera.
   Contraste medido: texto #07310F sobre #25D366 = 8,6:1. */
.wapp {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right, 0px));
  bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  z-index: 60;
  display: inline-flex; align-items: center; gap: .55rem;
  height: 56px; padding: 0 1.1rem;
  background: #25D366; color: #07310F;
  border: 2px solid var(--tinta); border-radius: 0;
  text-decoration: none;
  font-family: var(--display); font-size: var(--p-1); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em; line-height: 1;
  box-shadow: 6px 6px 0 rgba(26,26,23,.22);
  transition: opacity .28s ease, transform .28s ease, box-shadow .18s ease;
}
.wapp:hover { transform: translateY(-2px); box-shadow: 6px 8px 0 rgba(26,26,23,.3); }
.wapp__i { width: 24px; height: 24px; flex: none; fill: #07310F; }
/* Apartado, no borrado: sigue ocupando su sitio y vuelve solo. */
.wapp--arriba { opacity: 0; transform: translateY(18px); pointer-events: none; }
/* Bajo 520 px queda el círculo —acá, el cuadrado— y el rótulo se
   esconde sin salir del DOM: clip-path, no display:none, para que el
   lector de pantalla siga leyendo el aria-label del enlace. */
@media (max-width: 520px) {
  .wapp { padding: 0; width: 56px; justify-content: center; }
  .wapp__t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}
/* El pie deja sitio: sin esto el botón se para encima del deslinde. */
.pie { padding-bottom: 6rem; }

/* ── MAPA DE UBICACION ──────────────────────────────────────────────
   Imagen propia con mosaicos de OpenStreetMap pegados: la CSP prohibe
   pedir nada a un tercero, asi que un iframe de Google Maps quedaria en
   blanco SIN dar un solo error. El "Como llegar" si es un enlace, y un
   enlace no lo bloquea nada.
   Los colores salen de currentColor a proposito: asi el bloque se adapta
   a la paleta de cada demo sin conocerla y sin chocar con ella.
   La atribucion a OpenStreetMap la exige su licencia (ODbL). */
.mapa-sec { padding: clamp(2.5rem, 6vw, 4.5rem) 0; }
.mapa { margin: 1.4rem 0 0; border: 1px solid; border-color: color-mix(in srgb, currentColor 22%, transparent); border-radius: 10px; overflow: hidden; }
@supports not (color: color-mix(in srgb, red 50%, blue)) { .mapa { border-color: rgba(128, 128, 128, .35); } }
.mapa img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; }
.mapa__pie {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1rem;
  padding: .75rem .9rem;
  font-size: .86em; line-height: 1.45;
  border-top: 1px solid; border-top-color: color-mix(in srgb, currentColor 22%, transparent);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) { .mapa__pie { border-top-color: rgba(128, 128, 128, .35); } }
.mapa__pie b { font-weight: 700; }
.mapa__ir { color: inherit; font-weight: 700; text-decoration: underline; min-height: 44px; display: inline-flex; align-items: center; }
.mapa__cred { width: 100%; font-size: .84em; opacity: .8; }
.mapa__cred a { color: inherit; }
/* ── BOTON FLOTANTE DE CONTACTO ─────────────────────────────────────
   56 px de alto, por encima del minimo tactil de 44. Los colores de
   marca van a proposito: se reconocen sin leerlos, y eso es lo que hace
   que se toquen. Se ve SIEMPRE por defecto; el JS solo lo aparta sobre
   la portada. Al reves, un fallo del script se llevaria el CTA principal. */
.flota {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right, 0px));
  bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  z-index: 60;
  display: inline-flex; align-items: center; gap: .55rem;
  height: 56px; padding: 0 1.15rem 0 1rem;
  border-radius: 999px;
  text-decoration: none;
  font-family: var(--cuerpo, system-ui, sans-serif);
  font-size: .95rem; font-weight: 700; line-height: 1;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .26), 0 2px 6px rgba(0, 0, 0, .16);
  transition: opacity .28s ease, transform .28s ease, box-shadow .18s ease;
}
.flota--wa { background: #25D366; color: #07310F; }
.flota--ig { background: linear-gradient(120deg, #F9CE34 4%, #EE2A7B 48%, #6228D7 96%); color: #FFFFFF; }
.flota__i { width: 26px; height: 26px; fill: currentColor; flex: none; }
.flota:hover, .flota:focus-visible { transform: translateY(-2px); box-shadow: 0 10px 26px rgba(0, 0, 0, .3); }
.js .flota--arriba { opacity: 0; transform: translateY(14px) scale(.94); pointer-events: none; }

@media (max-width: 520px) {
  .flota { width: 56px; padding: 0; justify-content: center; }
  .flota__t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (prefers-reduced-motion: reduce) {
  .flota { transition: opacity .28s ease; }
  .flota:hover, .flota:focus-visible { transform: none; }
  .js .flota--arriba { transform: none; }
}