/* ══════════════════════════════════════════════════════════════════
   CABALLEROS · Barbería, Av. Angelmó, Puerto Montt — demo CristalWeb
   ------------------------------------------------------------------
   DIRECCIÓN: «SEÑAL DE PUERTO». Azul marino de casco pintado, esmalte
   hueso y un naranjo de boya. No es la barbería de salón: es la que
   está en la avenida por donde pasan los botes.

   Deslinde escrito con las otras barberías del registro:
     · bogota-barber  — crema, burdeos y latón: salón clásico cálido.
     · 68-alter-barber — negro, hueso y acero FRÍO, sin un tono cálido.
     · 76-lords-barber — cuero marrón, crema y latón.
     · 177-king-of-kings y 178-house-salon (tanda P4, Temuco).
     Ninguna es azul, y ninguna toma el lugar como identidad. Acá el
     azul es de PINTURA DE CASCO, no de cielo ni de agua: por eso
     convive con un naranjo de boya y no con un celeste.
     Décimo azul del registro, con el deslinde puesto por escrito: los
     nueve anteriores son plano, señal, rotulador, mameluco, enlozado,
     azulejo, lago, petróleo y agua quieta — ninguno es esmalte de
     casco sobre fondo, y ninguno lleva naranjo al lado.

   TRÍO
     Display · Passion One — cartel pintado a mano, peso de rótulo de
       caleta. Nueva en el registro.
     Cuerpo  · Encode Sans — grotesca sólida, legible en párrafo largo
       y con carácter de señalética. Nueva en el registro.
     Dato    · Nova Mono — segunda aparición (47-makma-lubricentro).
       Lleva los minutos de silla del tablero, que es lo que se lee de
       reojo.

   ESCENA: el mástil con bandera baja desde arriba, se asienta, y recién
     entonces la bandera empieza a ondear —1,8 s por ciclo, alternando
     entre dos polígonos del mismo número de vértices—. Es el único
     bucle infinito de la página y vale porque una bandera ondea sola.

   DOS CLIPS DE FONDO (subida de nivel del 08-09-2026): sillones vacíos
     en la portada y las herramientas en la banda de cita. La foto sigue
     siendo la base y el clip se funde encima 1,4 s después de que puede
     reproducirse; con reduced-motion o ahorro de datos no se pide ni un
     byte de video. Presupuesto: portada 1,79 MB, cita 1,10 MB.

   BOTÓN FLOTANTE (08-09-2026): abajo a la derecha, coral pleno con
     blanco encima —5,1:1 medido—, 56 px de alto. Escrito en el HTML y
     visible por defecto; el JS sólo lo aparta mientras se mira la
     portada. No dice «WhatsApp» y no es verde: esta barbería no publica
     ningún número, así que va a su Instagram, que es el único canal
     verificado. El porqué largo está junto al enlace, en el index.html.

   LUMINANCIA: la página es marino de punta a punta salvo UNA banda
     clara a media página («Cómo se pide un corte»). Sin ella el scroll
     se lee como un túnel. Todos los grises de esa banda van reescritos:
     el secundario de la paleta oscura da 1,1:1 sobre el esmalte.
   ══════════════════════════════════════════════════════════════════ */

:root {
  --marino:   #0E2130;
  --marino-2: #16303F;
  --marino-3: #1E3D4E;   /* 10,1:1 sobre ESMALTE — el gris de la banda clara */
  --esmalte:  #F2F0E9;   /* 14,4:1 con marino encima */
  --esmalte-2:#A9B8C2;   /* 7,6:1 sobre marino */
  --boya:     #F07458;   /* acento sobre marino — 5,4:1. NUNCA sobre esmalte */
  --boya-full:#C2402A;   /* relleno; blanco encima 5,1:1 · sobre esmalte 4,5:1 */
  --linea:    rgba(242,240,233,.15);

  --display: 'Passion One', 'Arial Black', sans-serif;
  --cuerpo:  'Encode Sans', 'Segoe UI', system-ui, sans-serif;
  --mono:    'Nova Mono', 'Consolas', ui-monospace, monospace;

  --p--1: clamp(.8rem, .77rem + .12vw, .88rem);
  --p-0:  clamp(1rem, .96rem + .2vw, 1.1rem);
  --p-1:  clamp(1.15rem, 1.08rem + .3vw, 1.35rem);
  --p-2:  clamp(1.4rem, 1.25rem + .7vw, 1.9rem);
  --p-3:  clamp(1.9rem, 1.5rem + 1.6vw, 3rem);
  --p-4:  clamp(2.6rem, 1.8rem + 3.4vw, 5rem);

  --aire:  clamp(3.5rem, 2.2rem + 5vw, 7rem);
  --ancho: min(100% - 2.5rem, 1120px);
  --salida: cubic-bezier(.16, 1, .3, 1);
  --suave:  ease-in-out;   /* reposo y bucles lentos (movimiento-web) */
}

*, *::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(--marino); color: var(--esmalte); font-family: var(--cuerpo); font-size: var(--p-0); line-height: 1.62; }
img { max-width: 100%; height: auto; }
video { max-width: 100%; }
p { text-wrap: pretty; }
a { color: var(--boya); }
:focus-visible { outline: 3px solid var(--boya); outline-offset: 2px; }
.ancho { width: var(--ancho); margin-inline: auto; }
h1, h2, h3 { font-family: var(--display); font-weight: 700; line-height: 1.05; margin: 0; }
.vo { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.mono { font-family: var(--mono); }

.rotulo { font-family: var(--mono); font-size: var(--p--1); letter-spacing: .14em; text-transform: uppercase; color: var(--boya); margin: 0 0 .8rem; }
.rotulo--claro { color: var(--boya); }
.titulo { font-size: var(--p-3); max-width: 22ch; margin-bottom: 1rem; }
.titulo--claro { color: var(--esmalte); }
.entradilla { max-width: 58ch; color: var(--esmalte-2); font-size: var(--p-1); margin: 0 0 2rem; }
.entradilla b { color: var(--esmalte); font-weight: 600; }
.nota { margin-top: 1.6rem; font-size: var(--p--1); color: var(--esmalte-2); max-width: 64ch; }
.nota b { color: var(--esmalte); }
.sobre { font-family: var(--mono); font-size: var(--p--1); letter-spacing: .12em; text-transform: uppercase; color: var(--boya); margin: 0 0 1rem; }

/* ── Dato de ejemplo ───────────────────────────────────────────── */
.ej { position: relative; border: 1px dashed rgba(240,116,88,.55); border-radius: 3px; }
.ej::after {
  content: attr(data-ejemplo); position: absolute; top: -.62rem; right: .6rem;
  font-family: var(--mono); font-size: .62rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--boya); background: var(--marino); padding: 0 .35rem;
  white-space: nowrap; max-width: 90%; overflow: hidden; text-overflow: ellipsis;
}

/* ── Botones ───────────────────────────────────────────────────── */
.boton {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: .8rem 1.5rem;
  border: 1px solid var(--boya-full); border-radius: 2px;
  background: var(--boya-full); color: #FFFFFF;
  font-family: var(--cuerpo); font-size: var(--p-0); font-weight: 600;
  text-decoration: none; cursor: pointer;
  box-shadow: 0 10px 30px -18px rgba(194,64,42,.9);
  transition: transform .16s ease-out, background-color .16s, box-shadow .16s;
}
.boton:hover { background: #A93825; transform: translateY(-2px); box-shadow: 0 14px 32px -16px rgba(194,64,42,.95); }
.boton:active { transform: translateY(0); }
.boton--linea { background: transparent; color: var(--boya); border-color: rgba(240,116,88,.5); box-shadow: none; }
.boton--linea:hover { background: rgba(240,116,88,.12); box-shadow: none; }
/* El CTA de la cabecera es lo que más se toca de la página: 44 px SIEMPRE,
   no sólo en teléfono. En escritorio medía 41 px. */
.boton--chico { min-height: 44px; padding: .5rem 1rem; font-size: var(--p--1); }

/* ── Propuesta ─────────────────────────────────────────────────── */
.propuesta { background: var(--marino-2); color: var(--esmalte); padding: .85rem clamp(1.2rem, 5vw, 3rem); border-bottom: 3px solid var(--boya-full); }
.propuesta__que { margin: 0 0 .3rem; font-size: var(--p--1); font-family: var(--mono); }
.propuesta__que b { color: var(--boya); }
.propuesta__gancho { margin: 0; font-size: var(--p--1); color: var(--esmalte-2); 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(14,33,48,.92); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); border-bottom: 1px solid var(--linea); transition: box-shadow .2s, background-color .2s; }
.cab--flota { box-shadow: 0 8px 26px -18px #000; background: rgba(14,33,48,.985); }
.cab__marca { display: flex; align-items: center; gap: .6rem; text-decoration: none; color: var(--esmalte); }
/* El mástil con la bandera: dos formas, cero bytes de imagen. */
.mastil { position: relative; width: 18px; height: 26px; flex: none; }
.mastil::before { content: ""; position: absolute; left: 2px; top: 0; bottom: 0; width: 2px; background: var(--esmalte); }
.mastil i { position: absolute; left: 4px; top: 3px; width: 13px; height: 10px; background: var(--boya-full); clip-path: polygon(0 0, 100% 0, 72% 50%, 100% 100%, 0 100%); }
.cab__nombre { font-family: var(--display); font-size: var(--p-1); line-height: 1; }
.cab__sub { display: block; font-family: var(--mono); font-size: .6rem; letter-spacing: .1em; text-transform: uppercase; color: var(--boya); margin-top: .25rem; }
.cab__nav { display: flex; gap: 1.1rem; margin-left: auto; overflow-x: auto; }
/* 44 px de alto, como todo lo que se toca. Medidas sobre la página viva
   las cuatro anclas daban 37 px. El subrayado del hover deja de ser un
   border-bottom —en una caja de 44 px quedaría a 11 px del texto y se
   leería como una raya suelta— y pasa a un ::after anclado justo debajo
   de la línea. La cabecera no cambia de alto: ya la fijaba la marca. */
.cab__nav a { position: relative; display: inline-flex; align-items: center; min-height: 44px; color: var(--esmalte-2); text-decoration: none; font-size: var(--p--1); white-space: nowrap; }
.cab__nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 9px; height: 2px; background: transparent; transition: background-color .2s; }
.cab__nav a:hover { color: var(--boya); }
.cab__nav a:hover::after { background: var(--boya); }
.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(88vh, 780px); display: flex; flex-direction: column; justify-content: center; padding: var(--aire) 0; overflow: hidden; }
.portada__foto { position: absolute; inset: 0; z-index: -1; }
/* El video comparte el selector de la foto: misma máscara, mismo
   object-fit y mismo object-position, escritos UNA sola vez. Si se
   separan, el clip y la foto se descuadran a la primera corrección. */
.portada__foto img, .portada__video {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 70% 42%;
  -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, terminando en alfa 0. Del 0 al 30 % es el marino
   puro de la sección: el titular queda a 14,4:1 PASE LO QUE PASE con la
   foto o el fotograma que haya debajo. */
.portada__foto::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg,
      rgba(14,33,48,1) 0%, rgba(14,33,48,1) 30%,
      rgba(14,33,48,.76) 46%, rgba(14,33,48,.34) 64%,
      rgba(14,33,48,.1) 82%, rgba(14,33,48,0) 96%);
}
.portada__texto { width: var(--ancho); margin-inline: auto; }
.portada__titulo { font-size: var(--p-4); max-width: 12ch; font-weight: 900; }
.portada__titulo span { display: block; }
.portada__bajada { max-width: 46ch; color: var(--esmalte-2); font-size: var(--p-1); margin: 1.4rem 0 2rem; }
.acciones { display: flex; flex-wrap: wrap; gap: .8rem; }

/* ── Escena de portada · el mástil con bandera ─────────────────────
   movimiento-web, ficha «Barbería» en su variante de puerto. Vive en la
   mitad derecha, sobre la zona nítida de la foto; el titular ocupa la
   izquierda y no se toca. z-index -1 y después de la foto en el HTML:
   pinta sobre la foto y su velo, y siempre por debajo del texto. */
.escena { position: absolute; z-index: -1; pointer-events: none; }
.escena--mastil { top: 22%; right: 11%; height: 46%; width: 128px; }
/* Respaldo radial: el clip que corre detrás tiene lámparas encendidas
   justo en esta columna y el mástil se perdía contra ellas. Doce
   palabras de CSS que sólo se descubren mirando el video corriendo. */
.escena--mastil::before {
  content: ""; position: absolute; inset: -18% -60% -12% -80%; z-index: -1;
  background: radial-gradient(closest-side, rgba(14,33,48,.72), rgba(14,33,48,0));
}

/* El palo lleva un filete marino de 1 px: la foto tiene un espejo con
   ampolletas justo detrás y un hueso sobre blanco no se ve. */
.escena__palo {
  position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  border-radius: 3px; background: var(--esmalte);
  box-shadow: 0 0 0 1px rgba(14,33,48,.45);
}
/* La bandera ondea cambiando entre dos polígonos con el MISMO número de
   vértices: si no coinciden, el clip-path no interpola y salta. */
.escena__bandera {
  position: absolute; left: 5px; top: 4%; width: 100px; height: 24%;
  background: var(--boya);
  clip-path: polygon(0 0, 90% 0, 100% 36%, 84% 70%, 92% 100%, 0 100%);
}
/* El pie rotula el bucle y es lo que convierte el dibujo en pieza de
   diseño. Cae sobre la zona nítida del clip, así que lleva PLACA en vez
   de subir el velo: rgba(14,33,48,.85) da 5,1:1 con el esmalte-2 en el
   peor caso (fotograma blanco debajo). El auditor da falso positivo
   acá porque lee el fondo como transparente. */
.escena__pie {
  position: absolute; left: 0; bottom: -2.2rem; white-space: nowrap;
  font-family: var(--mono); font-size: .6rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--esmalte-2);
  background: rgba(14,33,48,.85); padding: .25rem .6rem; border-radius: 4px;
}

@keyframes mastil-baja {
  from { transform: translateY(-40px); opacity: 0; }
  38%  { opacity: 1; }
  to   { transform: none; opacity: 1; }
}
@keyframes bandera-ondea {
  from { clip-path: polygon(0 0, 100% 0, 100% 30%, 90% 64%, 100% 100%, 0 100%); }
  to   { clip-path: polygon(0 0, 90% 0, 100% 36%, 84% 70%, 92% 100%, 0 100%); }
}
.js .escena--mastil  { animation: mastil-baja .8s var(--salida) both .3s; }
/* El ondeo arranca a 1,1 s: cuando el mástil YA se asentó. Antes se
   vería una bandera ondeando mientras cae, que no es lo que pasa. */
.js .escena__bandera { animation: bandera-ondea 1.8s var(--suave) 1.1s infinite alternate; }

/* En teléfono el texto pasa a ocupar todo el ancho, así que la escena se
   encoge y se sube: tiene que terminar ARRIBA de la bajada, que es el
   primer párrafo que llega hasta el borde derecho.
   Medido sobre la página viva a 500 px: con `top:13%; height:26%` el
   palo caía 17 px DENTRO de la caja de .portada__bajada —el palo es
   hueso #F2F0E9 y el párrafo es esmalte-2: 1,9:1 donde se cruzan—.
   Con estos números queda ~40 px por encima. El `min()` con el valor en
   rem es el que sostiene el caso de 375 px, donde el titular se va a
   cuatro líneas y el 20 % crecería con la portada. El titular nunca
   estuvo en riesgo: es de 12ch y termina mucho antes del borde. */
@media (max-width: 760px) {
  .escena--mastil { top: 9%; right: 5%; height: min(20%, 9.5rem); width: 78px; }
  .escena__bandera { width: 62px; }
  .escena__pie { display: none; }
}

/* En el teléfono el texto pasó de estar AL LADO a estar ENCIMA, así que
   la máscara y el velo rotan a vertical y la foto se queda con el tercio
   de abajo. Sin esto el titular cae sobre la zona nítida del sillón. */
@media (max-width: 760px) {
  .portada { min-height: 0; justify-content: flex-start; padding: 2.2rem 0 clamp(8rem, 30vh, 13rem); }
  .portada__foto img, .portada__video {
    object-position: 50% 46%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, transparent 10%, rgba(0,0,0,.4) 40%, #000 70%, #000 100%);
            mask-image: linear-gradient(180deg, transparent 0%, transparent 10%, rgba(0,0,0,.4) 40%, #000 70%, #000 100%);
  }
  .portada__foto::after {
    background: linear-gradient(180deg,
        rgba(14,33,48,1) 0%, rgba(14,33,48,.96) 34%,
        rgba(14,33,48,.66) 62%, rgba(14,33,48,.2) 88%, rgba(14,33,48,0) 100%);
  }
}

/* ── Cifras ────────────────────────────────────────────────────────
   Banda propia, ya no un apéndice de la portada. Tres datos que el
   negocio publica y la herida en la misma fila y con el mismo formato:
   así el dueño la lee sin que nadie se la señale. */
.cifras { padding: calc(var(--aire) * .62) 0; background: var(--marino-2); border-bottom: 1px solid var(--linea); }
.cifras__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.cifras__lista b { display: block; font-family: var(--display); font-size: var(--p-3); line-height: 1; color: var(--boya); font-variant-numeric: tabular-nums; }
/* El guion de «10:00–20:30» va apagado a propósito, pero no por debajo de
   AA: a .55 daba 2,33:1 sobre el marino-2 y a .75 da 3,27:1, que es lo
   que pide una display de 30 px. Sigue leyéndose como separador. */
.cifras__lista b i { font-style: normal; opacity: .75; }
/* Hijo DIRECTO del <li>: el <span class="cuenta"> que va dentro del <b>
   —el que sube contando— tiene que heredar el número, no la glosa. */
.cifras__lista > li > span { display: block; font-size: var(--p--1); color: var(--esmalte-2); margin-top: .35rem; max-width: 24ch; }
.cifras__lista .cuenta { display: inline; font: inherit; color: inherit; margin: 0; }
/* La herida no se disfraza de dato bueno: filete de boya al costado. */
.cifras__herida { border-left: 4px solid var(--boya-full); padding-left: .9rem; }

/* ── PIEZA FIRMA · tablero de cortes ───────────────────────────── */
.tablero { padding: var(--aire) 0; }
.tab { width: 100%; border-collapse: collapse; margin-top: .5rem; background: var(--marino-2); }
.tab::after { background: var(--marino); }
.tab caption { text-align: left; }
.tab th, .tab td { padding: 1rem .9rem; text-align: left; border-bottom: 1px solid var(--linea); vertical-align: top; }
.tab thead th {
  font-family: var(--mono); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--boya); font-weight: 400;
  border-bottom: 2px solid var(--boya-full); white-space: nowrap;
}
.tab tbody th { font-family: var(--display); font-size: var(--p-1); font-weight: 700; color: var(--esmalte); }
.tab td { color: var(--esmalte-2); font-size: var(--p--1); }
/* Los minutos de silla son el dato que decide: van grandes y en mono,
   como el reloj de un tablero de zarpes. */
.tab__t { font-family: var(--mono); color: var(--esmalte) !important; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tab__t span { font-size: var(--p-2); color: var(--boya); }
.tab__destaca { background: var(--marino-3); }
/* La tabla colapsa escondiendo el <thead> sin sacarlo del DOM. Ese
   thead NO se observa nunca con el IntersectionObserver: un elemento
   recortado a área cero no dispara jamás y se bloquea solo. */
@media (max-width: 720px) {
  .tab, .tab tbody, .tab tr, .tab td, .tab th { display: block; }
  .tab thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .tab tr { border-bottom: 2px solid var(--linea); padding: .6rem 0; }
  .tab th, .tab td { border: 0; padding: .25rem .9rem; }
}

/* ── Tajo ──────────────────────────────────────────────────────── */
.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% 46%; }
.tajo::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(0deg, rgba(14,33,48,.95) 0%, rgba(14,33,48,.8) 34%, rgba(14,33,48,.34) 62%, rgba(14,33,48,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(--esmalte); }
.tajo__txt p { max-width: 46ch; color: var(--esmalte-2); margin: .8rem 0 0; }

/* ── Barberos ──────────────────────────────────────────────────── */
.barberos { padding: var(--aire) 0; background: var(--marino-2); }
.fichas { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.ficha { padding: 1.2rem; background: var(--marino-3); }
/* La etiqueta del .ej va sobre el MARINO y no sobre el marino-3 de la
   tarjeta: la boya sobre marino-3 da 4,01:1 medido en la página viva y
   no llega a AA con 10 px de letra. Sobre marino da 5,74:1, que es el
   mismo número que ya tienen la etiqueta de la tabla y la de la ficha de
   datos — así las tres se leen igual. El chip queda un escalón más
   oscuro que la tarjeta, que es como se lee una etiqueta de plano. */
.ficha::after { background: var(--marino); }
.ficha h3 { font-size: var(--p-1); margin: 0 0 .4rem; }
.ficha p { margin: 0; font-size: var(--p--1); color: var(--esmalte-2); }
.ficha__hueco {
  aspect-ratio: 3 / 4; margin-bottom: .9rem;
  display: grid; place-items: center;
  border: 1px dashed rgba(242,240,233,.28);
  color: var(--esmalte-2); font-family: var(--mono); font-size: var(--p--1);
  letter-spacing: .14em; text-transform: uppercase;
  background: repeating-linear-gradient(135deg, rgba(242,240,233,.03) 0 8px, transparent 8px 16px);
}

/* ── Cómo se pide un corte · LA BANDA CLARA ────────────────────────
   Única inversión de luminancia de la página, obligatoria porque la
   paleta base es oscura. Va a media página y lleva TODOS sus overrides
   declarados uno por uno: rótulo, título, entradilla, nota, enlaces,
   borde y fondo de la etiqueta del .ej. Contrastes medidos sobre
   esmalte #F2F0E9: marino 14,4:1 · marino-3 10,1:1 · boya-full 4,5:1.
   El acento claro (--boya) NO se usa acá: da 2,1:1 y no pasa. */
.corte { padding: var(--aire) 0; background: var(--esmalte); color: var(--marino); }
.corte__cols { display: grid; gap: clamp(2rem, 5vw, 3.5rem); grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); align-items: start; }
@media (max-width: 900px) { .corte__cols { grid-template-columns: 1fr; } }
.corte .rotulo { color: var(--boya-full); }
.corte .titulo { color: var(--marino); }
.corte .entradilla { color: var(--marino-3); }
.corte .entradilla b { color: var(--marino); }
.corte .nota--clara { color: var(--marino-3); }
.corte a { color: var(--boya-full); }
.corte .ej { border-color: rgba(194,64,42,.5); }
.corte .ej::after { color: var(--boya-full); background: var(--esmalte); }

/* Tercer escalón de claridad: blanco puro sobre el esmalte. Es lo que
   saca la banda de «bloque de color» y la vuelve una ficha. */
.pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem; }
.pasos li {
  display: grid; grid-template-columns: 2.6rem 1fr; gap: .2rem 1rem;
  background: #FFFFFF; border-left: 4px solid var(--boya-full);
  border-radius: 0 10px 10px 0; padding: 1rem 1.2rem;
  box-shadow: 0 10px 30px -22px rgba(14,33,48,.55);
}
.pasos__n {
  grid-row: span 2; font-family: var(--display); font-size: var(--p-2);
  line-height: 1; color: var(--boya-full);
}
.pasos h3 { font-size: var(--p-1); color: var(--marino); margin: 0 0 .2rem; }
.pasos p { margin: 0; font-size: var(--p--1); color: var(--marino-3); }

/* La ficha de la foto queda pegada mientras se leen las cuatro
   maneras: la columna de texto es mucho más alta y, sin esto, la
   mitad derecha de la banda se lee como un vacío. */
.corte__foto { margin: 0; background: #FFFFFF; padding: .7rem; border-radius: 12px; box-shadow: 0 16px 40px -26px rgba(14,33,48,.6); position: sticky; top: 5.5rem; }
@media (max-width: 900px) { .corte__foto { position: static; } }
.corte__foto img { display: block; width: 100%; height: auto; border-radius: 8px; }
.corte__foto figcaption { font-size: var(--p--1); color: var(--marino-3); padding: .8rem .4rem .2rem; max-width: 34ch; }

/* ── El local, con telón ───────────────────────────────────────── */
.local { 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 12%: telón, no aura. Sin desenfoque en ninguna parte.
   El número se calibró MIRANDO la sección, no se copió: esta foto tiene
   medio cuadro de cielo claro y a .15 el mástil de un barco le pasaba
   por encima al párrafo. Va con mask-image y no con un ::after teñido
   porque la sección se funde con la de arriba y la de abajo, y un
   ::after dejaría un corte recto a media banda. */
.telon img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 52%; opacity: .12;
  -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%);
}
.local__cols { display: grid; gap: 1.6rem; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); max-width: 74ch; margin-bottom: 2rem; }
.local__cols p { margin: 0; color: var(--esmalte-2); }
.datos { margin: 0; display: grid; max-width: 68ch; }
.datos > div { display: grid; grid-template-columns: 11rem 1fr; gap: .6rem; padding: .75rem .6rem; border-bottom: 1px solid var(--linea); }
.datos dt { font-family: var(--mono); font-size: var(--p--1); letter-spacing: .08em; text-transform: uppercase; color: var(--esmalte-2); }
.datos dd { margin: 0; }
@media (max-width: 480px) { .datos > div { grid-template-columns: 1fr; } }

/* ── Cita ──────────────────────────────────────────────────────── */
.cita { position: relative; margin: 0; isolation: isolate; min-height: min(50vh, 400px); 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% 50%; }
/* Velo PLANO porque el texto va centrado: con un gradiente lateral la
   mitad derecha de la frase caería sobre .25 y no llegaría a AA.
   Calculado el PEOR CASO —un fotograma blanco entero bajo el velo—:
   .70 sobre blanco da #55636E y el esmalte encima queda en 5,4:1, de
   sobra para una display de 48 px que sólo necesita 3:1. A .78 el
   acero del clip se perdía y la banda se leía como un rectángulo. */
.cita::after { content: ""; position: absolute; inset: 0; z-index: -1; background: rgba(14,33,48,.70); }
.cita__txt { margin: 0; width: var(--ancho); padding: 3rem 0; }
.cita__txt p { font-family: var(--display); font-size: var(--p-3); color: var(--esmalte); max-width: 22ch; margin: 0 auto; text-align: center; line-height: 1.14; }

/* ── Mosaico ───────────────────────────────────────────────────────
   Cuatro columnas y filas de alto FIJO, con la primera y la última
   celda a doble ancho: 6 fotos que suman 8 unidades entran en dos
   filas exactas y la retícula cierra sin huecos. Con tres columnas
   sobraba una media fila vacía. El alto de fila tiene que ser fijo:
   con `height:100%` más `aspect-ratio` el alto de la celda se define
   a sí mismo y las fotos salen de distinto porte. */
.mos { padding: var(--aire) 0; }
.mos__grilla {
  display: grid; gap: 4px; width: var(--ancho); margin: 2rem auto 0;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: clamp(150px, 15.5vw, 240px);
}
.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; filter: saturate(.92); transition: transform .5s var(--salida), filter .5s ease; }
.mos__p:hover img { transform: scale(1.05); filter: saturate(1); }
@media (max-width: 640px) {
  .mos__grilla { grid-template-columns: repeat(2, 1fr); grid-auto-rows: clamp(120px, 32vw, 200px); }
}

/* ── Pedir hora ────────────────────────────────────────────────── */
.hora { padding: var(--aire) 0; background: var(--marino-2); }
.hora__cols { display: grid; gap: clamp(2rem, 5vw, 4rem); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); align-items: start; }
.pedir { background: var(--marino-3); border: 1px solid var(--linea); border-radius: 3px; 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: var(--p--1); letter-spacing: .05em; text-transform: uppercase; color: var(--esmalte-2); }
.form input, .form select {
  font-family: var(--cuerpo); font-size: var(--p-0);
  padding: .7rem .8rem; min-height: 48px;
  border: 1px solid rgba(242,240,233,.24); border-radius: 2px;
  background: #10283A; color: var(--esmalte); text-transform: none;
}
.form input:focus-visible, .form select:focus-visible { border-color: var(--boya); }
.form__salida { font-family: var(--mono); font-size: var(--p--1); background: var(--marino); border-left: 3px solid var(--boya-full); padding: .7rem .8rem; margin: .2rem 0 0; white-space: pre-wrap; word-break: break-word; color: var(--esmalte-2); }
.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(--esmalte-2); }

/* ── Para el dueño ─────────────────────────────────────────────── */
.dueno { padding: var(--aire) 0; background: var(--marino); border-top: 1px solid var(--linea); }
.dueno__cols { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 1rem; }
.dueno__cols h3 { font-family: var(--mono); font-size: var(--p-0); letter-spacing: .04em; color: var(--boya); margin-bottom: .5rem; }
.dueno__cols p { margin: 0; color: var(--esmalte-2); font-size: var(--p--1); }
.dueno__cierre { display: flex; flex-wrap: wrap; gap: 1.6rem; margin: 2.5rem 0 0; }
.flecha { color: var(--boya); text-decoration: none; font-weight: 600; border-bottom: 1px solid rgba(240,116,88,.4); padding-bottom: .15rem; }
.flecha:hover { border-bottom-color: var(--boya); }
.flecha span { display: inline-block; transition: transform .2s var(--salida); }
.flecha:hover span { transform: translateX(4px); }

/* ── Pie ───────────────────────────────────────────────────────── */
/* El padding de abajo deja libres los 56 px del botón flotante más su
   margen: sin esto el botón se sienta encima de la última línea del
   deslinde legal, que es justo la que no se puede tapar. */
.pie { background: #0A1A26; color: #93A4B0; padding: 2rem clamp(1.2rem, 5vw, 3rem) 5.5rem; }
.pie p { margin: 0; font-size: var(--p--1); max-width: 80ch; }

/* ── Botón flotante de contacto ────────────────────────────────────
   56 px de alto —por encima de los 44 del mínimo táctil— fijo abajo a
   la derecha. Va en coral pleno (--boya-full #C2402A) con blanco
   encima: 5,1:1 medido, y es el mismo color del CTA de la página, así
   que se lee como «el botón» y no como un pegote de otra marca.

   La dirección del truco importa: el botón se ve SIEMPRE por defecto y
   el JS sólo lo aparta mientras el visitante mira la portada, para no
   tapar el titular. Si main.js no arranca, o si rescate.js quita la
   clase .js, el botón queda visible, que es el estado que vende. Al
   revés —oculto por defecto, revelado por JS— un fallo del script se
   lleva el CTA principal.

   No dice «WhatsApp» porque la barbería no publica ningún número: va a
   su Instagram, que es el único canal verificado. El porqué completo
   está en el comentario del HTML, al lado del enlace. */
.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.2rem 0 1.05rem;
  border-radius: 999px;
  background: var(--boya-full); color: #FFFFFF;
  font-family: var(--cuerpo); font-size: var(--p-0); font-weight: 600;
  line-height: 1; text-decoration: none;
  box-shadow: 0 10px 30px -10px rgba(0,0,0,.55), 0 2px 6px rgba(0,0,0,.3);
  transition: opacity .28s ease, transform .28s var(--salida), background-color .16s;
}
.wapp:hover { background: #A93825; transform: translateY(-2px); }
.wapp__i { width: 22px; height: 22px; flex: none; fill: currentColor; }
/* Apartado sobre la portada: se va hacia abajo y deja de recibir el
   toque, pero sigue existiendo en el DOM y vuelve solo al bajar. */
.wapp--arriba {
  opacity: 0; transform: translateY(14px) scale(.94);
  pointer-events: none;
}
/* Bajo 520 px queda el círculo y el rótulo se esconde con clip-path:
   así el botón no le come media pantalla al teléfono. Se esconde
   recortado y no con display:none para que el lector de pantalla
   siga teniendo el texto. */
@media (max-width: 520px) {
  .wapp { width: 56px; padding: 0; justify-content: center; gap: 0; }
  .wapp__t { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .wapp__i { width: 26px; height: 26px; }
}

/* ══ 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; } }

/* ── Cascadas (regla 4) ────────────────────────────────────────────
   El CONTENEDOR se neutraliza y animan los hijos: si no se neutraliza,
   contenedor e hijos bajan a la vez y el grupo entero se desplaza 44 px.
   Stagger min(60 ms, 500/N): con 4, 5 y 6 hijos da 60 ms y el grupo
   entero aterriza en menos de medio segundo. */
.js .cascada.rev { opacity: 1; transform: none; transition: none; }
.js .cascada.rev > * { opacity: 0; transform: translateY(28px); }
.js .cascada.rev.ok > * {
  opacity: 1; transform: none;
  transition: opacity .3s ease-out, transform .6s var(--salida);
  transition-delay: calc(var(--i, 0) * 60ms);
}
/* Los minutos de silla llegan 120 ms DESPUÉS de su fila y sólo con
   opacidad: el número es un dato que aparece, no un objeto que entra. */
.js .cascada.rev > tr .tab__t span { opacity: 0; }
.js .cascada.rev.ok > tr .tab__t span {
  opacity: 1;
  transition: opacity .3s ease-out;
  transition-delay: calc(var(--i, 0) * 60ms + 120ms);
}
/* El retardo por índice va acá y no en un style="" del HTML: la CSP lo
   bloquea sin decir una palabra. */
.cascada > :nth-child(1) { --i: 0; }
.cascada > :nth-child(2) { --i: 1; }
.cascada > :nth-child(3) { --i: 2; }
.cascada > :nth-child(4) { --i: 3; }
.cascada > :nth-child(5) { --i: 4; }
.cascada > :nth-child(6) { --i: 5; }
.cascada > :nth-child(7) { --i: 6; }
.cascada > :nth-child(8) { --i: 7; }

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

/* ── El difuminado al scroll ───────────────────────────────────────
   Lo que una demo corriente resuelve con 70 KB de librería y una
   petición a un CDN que la CSP bloquearía. Doble puerta: sólo donde
   animation-timeline existe, sólo si no se pidió menos movimiento y
   sólo de 761 px para arriba. La página es oscura, así que la portada
   se hunde con BRILLO y no con opacidad —bajar la opacidad sobre
   marino no hace nada visible—, y el scale(1.06) acompaña siempre para
   que el desenfoque no muestre el filo transparente de la caja.
   El filter va en 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;
    }
    .cita {
      animation: cita-enfoca linear both;
      animation-timeline: view(block);
      animation-range: entry 0% entry 95%;
    }
  }
}
@keyframes portada-se-va { to { filter: blur(13px) brightness(.78); transform: scale(1.06); } }
@keyframes cita-enfoca   { from { filter: blur(10px); } to { filter: blur(0); } }

/* ── Menos movimiento ──────────────────────────────────────────────
   Se apaga lo intrusivo (autoplay, bucles, desplazamientos) y se
   conserva lo que da vida: los fundidos de opacidad y los hovers de
   color. En Windows esta preferencia viene puesta de fábrica muy
   seguido; apagarlo todo deja la página muerta en media clientela. */
@media (prefers-reduced-motion: reduce) {
  .js .portada__texto > * { animation: none; opacity: 1; transform: none; }
  .mos__p:hover img { transform: none; }
  .boton:hover { transform: none; }
  .flecha:hover span { transform: none; }
  /* Del botón flotante se apaga el desplazamiento, no el fundido: que
     desaparezca sobre la portada y vuelva al bajar es información, no
     adorno. */
  .wapp:hover, .wapp--arriba { transform: none; }
  /* Los reveals NO se desplazan, pero SÍ siguen fundiendo. */
  .js .rev, .js .cascada.rev > * { transform: none; }
  .js .cascada.rev > tr .tab__t span { opacity: 1; }
  /* El mástil queda puesto y la bandera quieta, pero con el polígono
     ondulado: una bandera recta parece una tabla. */
  .js .escena--mastil { animation: none; }
  .js .escena__bandera {
    animation: none;
    clip-path: polygon(0 0, 90% 0, 100% 36%, 84% 70%, 92% 100%, 0 100%);
  }
}
/* ── 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;
  /* inline-flex convierte el texto y la <span> de la flecha en dos
     items de flex y se COME el espacio en blanco que los separa en el
     HTML: sin este gap el resultado es «por correo→», pegado. */
  gap: .45rem;
}
/* La marca de la cabecera también es un enlace: 44 px mínimos. */
.cab__marca { min-height: 44px; }
/* (el .boton--chico ya va a 44 px en su propia regla, sin consulta de
    medios: en escritorio medía 41 px y también se toca) */

/* ── 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; }
}