/* ==========================================================================
   bb2026 — PAGINA "SOBRE MI".

   Namespace .bb-ab-page (body) y .bb-ab*. No toca la portada, ni el pie,
   ni el menu, ni el cursor, ni la pagina de contacto, ni ningun z-index
   existente. De la cabecera NO anula NADA (ver bloque CABECERA).

   JERARQUIA DE CAPAS QUE YA EXISTE (no se rompe): contenido 0-99, scrim
   290, overlay de menu 300, barra 400, dialogos 500+, salto al contenido
   999, cursor 1200, cortina 1500. Aqui no se pasa de 3.

   SIETE CAPITULOS A PANTALLA COMPLETA. Reglas de oro que esta hoja
   respeta en todos ellos:

     - height: auto + min-height: Nsvh. El alto en svh es SUELO, NUNCA
       medida fija. Esto costo una ronda en la pagina de contacto: con
       height fijo, a 390px el contenido superaba el panel, se desbordaba
       hacia arriba y el overflow: hidden recortaba el h1 por la mitad.
     - svh y no vh: en movil, vh cuenta la barra de direcciones del
       navegador como si no existiera y el capitulo se corta.
     - el hueco de la barra fija se reserva en el contenido del Cap. 1 en
       TODOS los anchos, porque body.bb-ab-page .bb-main--offset lo anula
       globalmente. Sin esa reserva el logotipo se pinta encima del h1.
     - minmax(0, 1fr) y NUNCA 1fr en una pista cuyo contenido es un marco
       con aspect-ratio: 1fr es minmax(auto, 1fr), se mide por contenido,
       y con un marco dentro es una referencia circular (33.554.432px
       medidos en este proyecto).

   ##################### MEDIDAS DE CONTRASTE (WCAG AA) ##################
   Todas MEDIDAS, no estimadas. Metodo identico al de contact.css:
   composicion alfa canal a canal en sRGB, linealizacion
   ((c/255+0.055)/1.055)^2.4, luminancia relativa
   0.2126R + 0.7152G + 0.0722B y (L1+0.05)/(L2+0.05).

   Referencias fijas:
     --bb-paper  #F7F5F2 -> L = 0.914903
     --bb-ink    #1C1B19 -> L = 0.011039
     --bb-body   #565451 -> L = 0.089126
     --bb-accent #2E4A42 -> L = 0.058728

   1. CAP. 1 — TEXTO CLARO DEL HERO (h1, linea en italica) sobre el PEOR
      CASO IMAGINABLE de la foto (zona de fotografia BLANCO PURO, sRGB
      255) mas el velo inferior:
        velo 0,80 de tinta -> (73,4 / 72,6 / 71,0)   L = 0.065973
        texto --bb-paper                             L = 0.914903
        contraste = 0.964903 / 0.115973 = 8,32:1     CUMPLE 4,5:1
      El velo llega a 0,80 en el 70% de la altura del hero (medido desde
      abajo) y de ahi hacia abajo solo CRECE, asi que 8,32:1 es el peor
      punto de toda la banda de texto, no el mejor.

   2. CAP. 1 — MICRO-ROTULO "SOBRE MI" (--bb-paper al 78% de opacidad)
      sobre ese mismo peor caso:
        mezcla -> (208,81 / 207,07 / 204,38)         L = 0.625600
        contraste = 0.675600 / 0.115973 = 5,83:1     CUMPLE 4,5:1
      Por eso el rotulo NO usa --bb-label (#A6A8AB): sobre una fotografia
      velada MEDIDO da ~3,5:1 y NO cumple. Regla dura del proyecto: ese
      gris solo vale sobre fondo OSCURO de verdad.

   3. CAP. 1 — LOGOTIPO CLARO de la barra sobre el velo superior mas el
      borde alto del inferior:
        alfa combinada = 1 - 0,50 x 0,90 = 0,55
        -> (130,15 / 129,60 / 128,50)                L = 0.221837
        contraste = 0.964903 / 0.271837 = 3,55:1
      3,55:1 CUMPLE el umbral de 3:1 que WCAG 1.4.11 pide para un
      elemento GRAFICO, que es lo que el logotipo es. Subirlo a 4,5:1
      exigiria ~0,59 de tinta en la franja alta, y eso ya no se lee como
      velo sino como una banda negra sobre la fotografia: es el defecto
      que la clienta senialo. Decision consciente, igual que en contacto.

   4. CAP. 3 y CAP. 6 — TEXTO CLARO sobre VELO NEGRO PLANO al 68% (el
      MISMO valor del banner de la portada, home-cta.css) en el peor caso
      de foto blanca pura:
        fondo compuesto = 0,32 x 255 = 81,6          L = 0.083544
        contraste = 0.964903 / 0.133544 = 7,23:1     CUMPLE 4,5:1
      El velo es PLANO: no hay ningun punto de la superficie con menos
      oscuridad, asi que 7,23:1 es el minimo garantizado en todo el
      capitulo, incluida la hilera de nombres de sitios en Jost 300.

   5. CAP. 3 y CAP. 6 — MICRO-ROTULO claro (--bb-paper al 78%) sobre ese
      mismo velo del 68%:
        mezcla -> (210,61 / 209,05 / 206,71)         L = 0.639065
        contraste = 0.689065 / 0.133544 = 5,16:1     CUMPLE 4,5:1

   6. TEXTO PEQUENIO SOBRE PAPEL (micro-rotulos de los capitulos de papel,
      pies del triptico en italica, parrafos, texto de los principios):
        --bb-body #565451 sobre papel                6,94:1  CUMPLE
      NUNCA --bb-label sobre papel: 2,19:1. Este error ya se colo tres
      veces en el proyecto.

   7. TITULARES Y NEGRITAS SOBRE PAPEL:
        --bb-ink #1C1B19 sobre papel                 15,82:1 CUMPLE

   8. ENLACES SOBRE PAPEL (el del mapa, los de redes del Cap. 7):
        --bb-accent #2E4A42 sobre papel              8,88:1  CUMPLE

   9. FILETES DECORATIVOS (--bb-ink-soft): son separacion de SUPERFICIE,
      no de texto ni bordes de control, asi que no tienen umbral que
      cumplir. Ningun filete de esta hoja transmite informacion por si
      solo.
   #######################################################################
   ========================================================================== */

/* --------------------------------------------------------------------------
   CASCARA DE PAGINA
   -------------------------------------------------------------------------- */

/* Fondo de carga en BLANCO puro, igual que la portada, los servicios y
   contacto: es lo que se ve debajo de la cortina y detras del hero
   mientras la persiana baja. El papel calido se percibia como gris. */
body.bb-ab-page { background: var(--bb-load-bg); }

/* header.php reserva el alto de la barra fija en todas las paginas que no
   son la portada (.bb-main--offset). Aqui el Cap. 1 va A SANGRE desde
   arriba, asi que ese hueco se anula. Se hace por CSS —con la clase del
   body, que gana en especificidad— y NO tocando header.php. */
body.bb-ab-page .bb-main--offset { padding-top: 0; }

.bb-ab { background: var(--bb-paper); }

/* --------------------------------------------------------------------------
   CABECERA — AQUI NO SE ANULA NADA, Y ES A PROPOSITO.

   inc/about-enqueue.php engancha el filtro 'bb_has_bleed_hero', asi que
   la barra arranca con .bb-bar--over-dark: logotipo Y hamburguesa
   CLAROS. En esta pagina el hero ocupa TODO el ancho, luego las dos
   cosas estan sobre fotografia y las dos deben ser claras: el
   comportamiento por defecto ya es el correcto.

   NO se copia el bloque CABECERA SOBRE MEDIA PANTALLA de contact.css.
   Alli existe porque el panel fotografico ocupa solo la mitad izquierda
   y la hamburguesa cae sobre papel. Copiarlo aqui pondria la hamburguesa
   en tinta encima de la foto.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   CAPITULO: la unidad de la pagina.

   height: auto + min-height es la regla, nunca un alto fijo (ver la
   cabecera de esta hoja).
   -------------------------------------------------------------------------- */
.bb-ab__ch {
  position: relative;
  height: auto;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: var(--bb-s6);
}

@media (min-width: 768px) {
  .bb-ab__ch { padding-block: var(--bb-s7); }
}

/* Micro-rotulo de capitulo. Sobre papel va --bb-body (6,94:1, caso 6) y
   NUNCA --bb-label. La variante --light es para los capitulos a sangre
   (5,16:1, caso 5). */
.bb-ab__label {
  margin: 0 0 var(--bb-s3);
  font-family: var(--bb-font-display);
  font-weight: 500;
  font-size: var(--bb-size-label);
  text-transform: uppercase;
  letter-spacing: var(--bb-track-label);
  line-height: 1.4;
  color: var(--bb-body);
}
.bb-ab__label--light {
  color: var(--bb-paper);
  opacity: 0.78;
}

/* --------------------------------------------------------------------------
   MARCO DE FOTO — pieza compartida de los capitulos 2 y 4.

   EL MARCO es quien lleva el recorte de la persiana; la imagen va DENTRO
   en position: absolute. Nunca una imagen en flujo con height: 100%.

   El fondo es --bb-frame-bg (blanco): es el hueco que se ve mientras la
   persiana esta cerrada. Blanco se lee como pagina; un gris se leia como
   agujero.

   ##### POR QUE max-width Y NO max-height #####
   Con aspect-ratio puesto, limitar la ALTURA no encoge el ancho: la
   proporcion se rompe y la imagen se estira. Limitando el ANCHO a
   'alto maximo x proporcion' el marco nunca pasa de ese alto Y conserva
   su forma. De ahi los calc() de abajo.
   -------------------------------------------------------------------------- */
.bb-ab-frame {
  position: relative;
  width: 100%;
  margin-inline: auto;
  overflow: hidden;
  background: var(--bb-frame-bg);
}
.bb-ab-frame__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Horizontal 16/10 (sobremi_t1, 1620x1080). */
.bb-ab-frame--wide {
  aspect-ratio: 16 / 10;
  max-width: min(100%, calc(76svh * 16 / 10));
}
/* Verticales 2/3 (sobremi_t2 1080x1620 y sobremi_t3 1280x1920). NO se
   fuerzan en marco horizontal: se recortarian mal y en la tercera la
   mirada de la niña es el tema. */
.bb-ab-frame--tall {
  aspect-ratio: 2 / 3;
  max-width: min(100%, calc(76svh * 2 / 3));
}
/* Retrato 4/5 del Cap. 4 (sobremi_estudio, 1620x1080 encajada en 4/5:
   la foto es horizontal y el marco vertical recorta a los lados, que es
   lo que se quiere aqui —los vestidos colgados quedan centrados— y no
   arriba y abajo). */
.bb-ab-frame--port {
  aspect-ratio: 4 / 5;
  max-width: min(100%, calc(72svh * 4 / 5));
}

/* --------------------------------------------------------------------------
   CAP. 1 — APERTURA A SANGRE
   -------------------------------------------------------------------------- */
.bb-ab__ch--hero {
  align-items: flex-end;
  padding-block: 0;
  overflow: hidden; /* recorta el Ken Burns y la persiana. NO se quita. */
  /* Respaldo mientras la foto carga: la tinta del sistema, nunca un gris
     que se lea como agujero. */
  background: var(--bb-ink);
}

/* EL MARCO lleva el recorte. La foto y los DOS velos van dentro, en
   absoluto: asi los velos se revelan CON la foto y no se pintan enteros
   sobre el blanco de carga (que es lo que producia el "lavado gris" a
   pantalla completa en el hero de la portada). */
.bb-ab-hero__frame {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.bb-ab-hero__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.bb-ab-hero__veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* DESCENDENTE, franja alta: es lo UNICO que hace legible el logotipo
   CLARO de la barra, porque el velo inferior ya no llega hasta arriba
   (ver el bloque siguiente). Antes el logotipo se apoyaba en la suma de
   los dos velos; ahora esta franja se sostiene sola, asi que mantiene
   ~0,52 de tinta a lo largo de TODO el alto de la barra y solo despues
   cae. Muere a 300px.

   PEOR CASO MEDIDO (foto blanco puro, alfa compuesta canal a canal,
   linealizacion sRGB, mismo metodo que la cabecera de esta hoja):
     - borde inferior de la barra (88px, el punto mas claro que pisa el
       logotipo): alfa 0,52 -> fondo (136,96 / 136,44 / 135,40)
       L = 0.247967 -> contraste 0.964903 / 0.297967 = 3,24:1
       CUMPLE el umbral de 3:1 de WCAG 1.4.11 para elemento GRAFICO.
     - centro del glifo (~44px): alfa ~0,54 -> 3,44:1.
   Comparado con la hoja anterior esto NO oscurece la foto: la suma de
   los dos velos viejos daba 0,55 a 0px y 0,576 a 88px, o sea que aqui la
   franja de la barra queda IGUAL o mas clara. A 200px si que cambia
   mucho: antes 0,664 compuesta, ahora 0,20. */
.bb-ab-hero__veil--top {
  background: linear-gradient(
    to bottom,
    rgba(28, 27, 25, 0.56) 0,
    rgba(28, 27, 25, 0.52) 88px,
    rgba(28, 27, 25, 0.20) 200px,
    rgba(28, 27, 25, 0) 300px
  );
}

/* ASCENDENTE - OSCURECIMIENTO LOCAL, NO VELO GLOBAL.

   ##################### POR QUE SE CAMBIO ###############################
   El velo anterior (0,90 abajo, 0,80 hasta el 70% del alto, 0,30 al 88%)
   daba 8,32:1 en el texto cuando el umbral es 4,5:1: casi el DOBLE del
   oscurecimiento necesario. Y el precio lo pagaba la fotografia: MEDIDO
   en el centro de la mitad DERECHA (punto 75% del ancho, 45% del alto)
   la alfa compuesta era 0,8214 - el cielo, el agua y el horizonte
   quedaban reducidos a una mancha gris. Es la portada de la pagina en la
   que la fotografa se presenta: tenia que respirar.

   Ahora la tinta se concentra DONDE ESTA EL TEXTO (banda inferior,
   cargada a la izquierda) y la mitad derecha y el cielo quedan abiertos.
   TRES capas, que se componen entre si (1-(1-a1)(1-a2)(1-a3)):
     1. BANDA INFERIOR a todo el ancho: es la que sostiene el h1, la
        linea en italica y el carril de bajar. Muere al 54% del alto.
     2. LOCAL abajo a la izquierda (elipse): el empujon extra que necesita
        el MICRO-ROTULO, que va a --bb-paper OPACO y es el elemento mas
        exigente de todo el hero. Va a la izquierda porque el rotulo va a
        la izquierda.
     3. LAVADO global muy suave: solo asienta la base, 0,10 -> 0.

   OJO: los capitulos 3 y 6 siguen con su velo PLANO al 68% (casos 4 y 5
   de la cabecera). Aquellas fotos son densas y lo aguantan; esta no. NO
   se unifican.

   ############### CONTRASTES MEDIDOS (peor caso: foto blanco puro) ######
   (mismo metodo alfa + linealizacion sRGB de la cabecera)

   a) h1 y linea en italica (--bb-paper, L = 0.914903). Peor punto de la
      banda de texto = su esquina ALTA y DERECHA (x 95%, y 33% del alto
      contado desde abajo), donde las tres capas suman menos:
        capa 1 = 0,625 / capa 2 = 0,0267 / capa 3 = 0,0404
        alfa compuesta = 0,6497
        fondo compuesto (107,45 / 106,80 / 105,50)   L = 0.146565
        contraste = 0.964903 / 0.196565 = 4,91:1     CUMPLE 4,5:1
      Mas abajo y mas a la izquierda solo mejora (0,70 y mas de alfa).

   b) MICRO-ROTULO "SOBRE MI" (--bb-paper OPACO) en su POSICION REAL,
      MEDIDA sobre los pixeles renderizados de una captura de navegador
      (NO estimada): ocupa el 59,7% - 61,5% del alto del hero contado
      DESDE ARRIBA, o sea 38,5% - 40,3% contado DESDE ABAJO. El h1
      empieza en el 63,4%: solo 30px mas abajo.
      NO LA VUELVAS A ESTIMAR. La estimacion anterior daba la banda de
      texto a partir del 67% desde arriba y por eso el rotulo se quedo
      FUERA de la zona oscurecida: media 2,68:1 en escritorio y 2,88:1 en
      movil, con el fondo compuesto medido en (130,125,116).
      Ahora, en su borde ALTO (y 40,3% desde abajo, x ~10%):
        capa 1 = 0,488 / capa 2 = 0,298 / capa 3 = 0,036
        alfa compuesta = 0,6535
        fondo compuesto (106,6 / 106,6 / 106,6) sobre foto blanco puro
        L = 0.145900 -> contraste = 1.0149 / 0.195900 = 5,18:1  CUMPLE
      Hacia abajo y hacia la izquierda solo mejora. El rotulo se llevo a
      opacidad 1 (antes 0,78) porque con 0,78 el fondo tendria que bajar
      a 98 o menos, y solo con opacidad no llegaba (~3,7:1 sobre 130).

   c) CARRIL DE BAJAR (--bb-paper opaco, y ~2%): alfa ~0,71 -> 5,3:1.

   d) LOGOTIPO de la barra: lo cubre el velo superior, 3,24:1 (arriba).

   ################ QUE LA FOTO RESPIRE (condicion medida) ##############
   Alfa compuesta en el CENTRO DE LA MITAD DERECHA (x 75%, y 45%):
     - capa 1: muere al 54% del alto  -> 0 (la meseta se estiro hasta el
       38%, pero el punto de muerte NO se movio)
     - capa 2: la elipse acaba antes (radio normalizado 1,14 > 1) -> 0
     - capa 3: 0,015
     - velo superior: 0 (muere a 300px; el 45% de un hero de 100svh son
       380px a 390x844). En una ventana muy baja (~600px) su cola aporta
       hasta 0,06 mas.
     ALFA TOTAL = 0,015  (0,075 en el caso de ventana baja)
   ANTES ERA 0,8214. Umbral pedido: <= 0,25. CUMPLE con mucho margen.
   #######################################################################
   -------------------------------------------------------------------------- */
.bb-ab-hero__veil--bot {
  background:
    /* 2. LOCAL abajo a la izquierda: sostiene el micro-rotulo. */
    radial-gradient(
      ellipse 92% 66% at 4% 100%,
      rgba(28, 27, 25, 0.46) 0%,
      rgba(28, 27, 25, 0.38) 52%,
      rgba(28, 27, 25, 0.10) 84%,
      rgba(28, 27, 25, 0) 100%
    ),
    /* 1. BANDA INFERIOR a todo el ancho: sostiene h1, italica y carril. */
    linear-gradient(
      to top,
      rgba(28, 27, 25, 0.70) 0%,
      rgba(28, 27, 25, 0.68) 22%,
      rgba(28, 27, 25, 0.62) 38%,
      rgba(28, 27, 25, 0.16) 46%,
      rgba(28, 27, 25, 0) 54%
    ),
    /* 3. LAVADO global: solo asienta la base. */
    linear-gradient(
      to top,
      rgba(28, 27, 25, 0.10) 0%,
      rgba(28, 27, 25, 0.02) 50%,
      rgba(28, 27, 25, 0) 70%
    );
}

/* EL HUECO DE LA BARRA FIJA SE RESERVA EN TODOS LOS ANCHOS, no solo en
   escritorio: body.bb-ab-page .bb-main--offset lo anula globalmente y sin
   esta reserva el logotipo se pinta justo ENCIMA del h1 (medido a 390px
   en la pagina de contacto). */
.bb-ab-hero__over {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--bb-max);
  margin-inline: auto;
  padding: calc(var(--bb-bar-h) + var(--bb-s4)) var(--bb-gutter) var(--bb-s4);
  color: var(--bb-paper);
}

@media (min-width: 768px) {
  .bb-ab-hero__over {
    padding-bottom: var(--bb-s5);
  }
}

/* Micro-rotulo del hero: papel OPACO -> 5,18:1 (caso b). */
.bb-ab-hero__label {
  margin: 0 0 var(--bb-s2);
  font-family: var(--bb-font-display);
  font-weight: 500;
  font-size: var(--bb-size-label);
  text-transform: uppercase;
  letter-spacing: var(--bb-track-label);
  line-height: 1.4;
  color: var(--bb-paper);
  opacity: 1;
}

.bb-ab-hero__h1 {
  margin: 0 0 var(--bb-s2);
  color: var(--bb-paper);
}

/* La linea en EB Garamond italica debajo del nombre. 8,32:1 (caso 1). */
.bb-ab-hero__lyric {
  margin: 0;
  font-family: var(--bb-font-lyric);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
  line-height: 1.3;
  color: var(--bb-paper);
}

/* --------------------------------------------------------------------------
   SENIAL DE BAJAR — carril vertical con un trazo que lo recorre.

   ############ PROCEDENCIA: assets/css/home-hero.css ####################
   Estas reglas son las de .bb-hhero__scroll / .bb-hhero__scroll-line y su
   @keyframes de la PORTADA, copiadas aqui con el namespace de esta
   pagina. Se copian y no se reutiliza la hoja porque home-hero.css NO se
   encola en /sobre-mi/ y traerla entera arrastraria el carrusel, la
   persiana diagonal y la etiqueta de la portada por 30 lineas de CSS.
   El @keyframes se renombra a bb-ab-scroll-run para que no pueda chocar
   con el de la portada si algun dia las dos hojas coinciden.
   Si el carril de la portada cambia, hay que cambiarlo tambien aqui.
   #######################################################################
   -------------------------------------------------------------------------- */
.bb-ab-hero__scroll {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--bb-s2);
  margin-top: var(--bb-s4);
  color: var(--bb-paper);
  font-family: var(--bb-font-display);
  font-weight: 500;
  font-size: var(--bb-size-label);
  text-transform: uppercase;
  letter-spacing: var(--bb-track-label);
}
.bb-ab-hero__scroll:hover,
.bb-ab-hero__scroll:focus-visible { color: var(--bb-paper); }
.bb-ab-hero__scroll:focus-visible { outline-color: var(--bb-paper); }

/* El carril: 1px de ancho, atenuado, y recorta el trazo que lo recorre. */
.bb-ab-hero__scroll-line {
  position: relative;
  display: block;
  width: 1px;
  height: 48px;
  overflow: hidden;
  background: rgba(247, 245, 242, 0.3);
  transform-origin: top;
  transition: transform 0.5s var(--bb-ease);
}
/* El trazo. Sin motion se queda quieto arriba del carril: sobrio y
   legible, pero sin animacion (regla de prefers-reduced-motion). */
.bb-ab-hero__scroll-line::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 40%;
  background: var(--bb-paper);
}
@media (prefers-reduced-motion: no-preference) {
  .bb-ab-hero__scroll-line::after {
    animation: bb-ab-scroll-run 1.9s var(--bb-ease) infinite;
  }
}
/* De fuera del carril por arriba a fuera por abajo: el trazo entra, baja
   y sale, sin cortes visibles. */
@keyframes bb-ab-scroll-run {
  from { transform: translateY(-100%); }
  to   { transform: translateY(250%); }
}
.bb-ab-hero__scroll:hover .bb-ab-hero__scroll-line { transform: scaleY(1.2); }

/* --------------------------------------------------------------------------
   CAP. 2 — EL TRIPTICO

   minmax(0, 5fr) minmax(0, 7fr) y NUNCA 5fr 7fr: las pistas contienen
   marcos con aspect-ratio (ver la cabecera de esta hoja).

   align-items: start es OBLIGATORIO, no cosmetico: el valor por defecto
   de un item de rejilla es 'stretch', que le da la altura de la fila
   completa, y un elemento tan alto como su contenedor no tiene recorrido
   donde pegarse con position: sticky. Es exactamente la leccion del panel
   de la pagina de contacto.
   -------------------------------------------------------------------------- */
.bb-ab__ch--tri { align-items: flex-start; }

.bb-ab-tri__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--bb-s5);
}

@media (min-width: 1024px) {
  .bb-ab-tri__grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--bb-s6);
    align-items: start;
  }
}

/* LA CITA SE QUEDA QUIETA a media pantalla mientras pasan las tres fotos.
   position: sticky NATIVO y no ScrollTrigger.pin: el pin pelea con Lenis
   y ademas reescribe el layout, mientras que el sticky es del navegador y
   no se puede desincronizar del scroll.
   Por debajo de 1024px no hay dos columnas: deja de ser sticky y va
   primera, que es su orden en el DOM. */
.bb-ab-tri__quote { min-width: 0; }

@media (min-width: 1024px) {
  .bb-ab-tri__quote {
    position: sticky;
    top: calc(50svh - 4rem);
  }
}

/* El filete del que cuelga la cita. */
.bb-ab-tri__rule {
  display: block;
  width: 64px;
  height: 1px;
  margin-bottom: var(--bb-s3);
  background: var(--bb-ink);
  opacity: 0.5;
}

.bb-ab-tri__q { margin: 0; }
.bb-ab-tri__q p {
  margin: 0;
  font-family: var(--bb-font-lyric);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.75rem, 3.6vw, 3.25rem);
  line-height: 1.22;
  color: var(--bb-ink); /* 15,82:1 (caso 7) */
}

/* La columna de las tres fotos. Cada una pide su propio capitulo de
   ~90svh: es lo que da el ritmo de "una foto, una pantalla" y lo que
   deja que la entrada y la salida de cada una se vean completas. */
.bb-ab-tri__col { min-width: 0; }

.bb-ab-tri__item {
  min-height: 90svh;
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--bb-s3);
}

.bb-ab-tri__cap {
  margin: 0;
  max-width: 46ch;
  font-family: var(--bb-font-body);
  font-size: var(--bb-size-body);
  line-height: 1.7;
}
/* El titular del pie en tinta y en negrita (15,82:1); el resto en
   --bb-body y en italica (6,94:1). Nunca --bb-label sobre papel. */
.bb-ab-tri__cap-t {
  display: block;
  font-family: var(--bb-font-display);
  font-weight: 700;
  font-size: 0.9375rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--bb-ink);
  margin-bottom: var(--bb-s1);
}
.bb-ab-tri__cap-x {
  display: block;
  font-style: italic;
  color: var(--bb-body);
}

/* --------------------------------------------------------------------------
   CAPITULOS A SANGRE (Cap. 3 y Cap. 6) — pieza compartida.

   El recorte de la persiana lo lleva LA SECCION (data-bb-inout-block),
   asi que la foto, el velo y el texto entran y salen a la vez. Por eso el
   marco y el velo van DENTRO, en absoluto.

   EL RECORTE VA EN EL MARCO, y es OBLIGATORIO, no cosmetico: el revelado
   de entrada aplica transform: scale(1.04) a .bb-ab-bleed__img, o sea que
   la foto mide un 4% MAS que su caja y sobresale ~2% por cada lado.
   MEDIDO a 390px sin el recorte: 8px de scroll horizontal REAL en toda la
   pagina (documentElement.scrollWidth 383 con clientWidth 375, y
   window.scrollTo(50, y) dejaba window.scrollX en 8). Subia en cadena
   marco -> seccion -> .bb-ab -> .bb-main -> documento, todos 383/375.
   El Cap. 1 no lo tenia porque .bb-ab__ch--hero SI lleva overflow:
   hidden, y los marcos del triptico tambien recortan: el unico que se
   escapaba era este.

   EL RECORTE VA EN EL MARCO Y NO EN LA SECCION, por dos razones:
     - el marco es el padre directo de la imagen escalada, o sea el nivel
       MINIMO que contiene el desborde sin tocar nada mas del capitulo;
     - overflow: hidden crea un contenedor de desplazamiento, y en la
       SECCION ahogaria cualquier position: sticky que se metiera dentro
       mas adelante. Dentro del marco no hay ni puede haber sticky: solo
       la foto y el velo, los dos en absolute inset: 0.
   Comprobado en esta hoja: el UNICO position: sticky de la pagina es
   .bb-ab-tri__quote (Cap. 2, #bb-ab-triptico), que no es un capitulo a
   sangre. #bb-ab-ria y #bb-ab-sola no tienen ninguno. Queda intacto.
   -------------------------------------------------------------------------- */
.bb-ab__ch--bleed {
  /* Respaldo mientras la foto carga. */
  background: var(--bb-ink);
  color: var(--bb-paper);
}

.bb-ab-bleed__frame {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* RECORTA el scale(1.04) del revelado. Sin esto son 8px de scroll
     horizontal real a 390px (ver el bloque de arriba). NO SE QUITA. */
  overflow: hidden;
}
.bb-ab-bleed__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* VELO NEGRO PLANO al 68%: EL MISMO VALOR del banner de la portada
   (home-cta.css, .bb-hcta__overlay). No se inventa otro numero, para que
   el contraste medido alli siga valiendo aqui: 7,23:1 en el peor caso
   (caso 4). Plano y no degradado a proposito: asi no hay ninguna franja
   del capitulo con menos oscuridad que la medida. */
.bb-ab-bleed__veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: rgba(0, 0, 0, 0.68);
}

.bb-ab-bleed__in {
  position: relative;
  z-index: 1;
  max-width: 900px;
  margin-inline: auto;
}
.bb-ab-bleed__h2 {
  margin: 0 0 var(--bb-s4);
  color: var(--bb-paper);
}
.bb-ab-bleed__p {
  margin: 0;
  max-width: 60ch;
  font-family: var(--bb-font-body);
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.75;
  color: var(--bb-paper); /* 7,23:1 (caso 4) */
}

/* --- CAP. 3: hilera tipografica de los sitios ---
   El punto medio de separacion lo pinta el ::after y NO va en el texto:
   metido en la cadena, un lector de pantalla leeria "punto" ocho veces.
   El ultimo no lo lleva. */
.bb-ab-ria__places {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 var(--bb-s4);
  padding: 0;
  font-family: var(--bb-font-display);
  font-weight: 300;
  font-size: clamp(0.875rem, 1.5vw, 1.125rem);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  line-height: 1.9;
  color: var(--bb-paper); /* 7,23:1 (caso 4) */
}
.bb-ab-ria__place { display: inline-flex; }
.bb-ab-ria__place::after {
  content: "·";
  padding-inline: 0.6em;
  opacity: 0.6;
}
.bb-ab-ria__place:last-child::after { content: none; }

/* --- CAP. 6: la declaracion --- */
.bb-ab-sola__p { max-width: 54ch; }

/* --------------------------------------------------------------------------
   CAP. 4 — EL ESTUDIO (split 50/50)
   -------------------------------------------------------------------------- */
.bb-ab-est__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--bb-s5);
  align-items: center;
}

@media (min-width: 1024px) {
  .bb-ab-est__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--bb-s6);
  }
}

.bb-ab-est__media { min-width: 0; }
.bb-ab-est__text { min-width: 0; }

.bb-ab-est__h2 {
  margin: 0 0 var(--bb-s4);
  color: var(--bb-ink); /* 15,82:1 */
}
.bb-ab-est__p {
  margin: 0 0 var(--bb-s3);
  max-width: 46ch;
  font-family: var(--bb-font-body);
  font-size: var(--bb-size-body);
  line-height: 1.76;
  color: var(--bb-body); /* 6,94:1 */
}
.bb-ab-est__more {
  margin: var(--bb-s4) 0 0;
  font-family: var(--bb-font-display);
  font-weight: 500;
  font-size: var(--bb-size-label);
  text-transform: uppercase;
  letter-spacing: var(--bb-track-label);
}
.bb-ab-est__more a { color: var(--bb-accent); } /* 8,88:1 */

/* --------------------------------------------------------------------------
   CAP. 5 — COMO TRABAJO (papel, sin fotos)

   Numero en Jost 700 y titulo en Jost 300: la mezcla bold/thin es el
   recurso tipografico aprobado por la clienta, el mismo de los tres pasos
   de la pagina de contacto.
   -------------------------------------------------------------------------- */
.bb-ab-met__in { width: 100%; }

.bb-ab-met__h2 {
  margin: 0 0 var(--bb-s5);
  color: var(--bb-ink);
}

.bb-ab-met__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bb-ab-met__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--bb-s3);
  align-items: start;
  padding-block: var(--bb-s4);
  border-top: 1px solid var(--bb-ink-soft);
}
.bb-ab-met__item:first-child { border-top: none; padding-top: 0; }

@media (min-width: 768px) {
  .bb-ab-met__item {
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--bb-s5);
    padding-block: var(--bb-s5);
  }
}

.bb-ab-met__n {
  font-family: var(--bb-font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--bb-ink); /* 15,82:1 */
}
.bb-ab-met__body { min-width: 0; }
.bb-ab-met__title {
  margin: 0 0 var(--bb-s2);
  font-family: var(--bb-font-display);
  font-weight: 300;
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: var(--bb-ink);
}
.bb-ab-met__text {
  margin: 0;
  max-width: 52ch;
  font-family: var(--bb-font-body);
  font-size: var(--bb-size-body);
  line-height: 1.76;
  color: var(--bb-body); /* 6,94:1 */
}

.bb-ab-met__closing {
  margin: var(--bb-s5) 0 0;
  padding-top: var(--bb-s4);
  border-top: 1px solid var(--bb-ink-soft);
  max-width: 60ch;
  font-family: var(--bb-font-lyric);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  line-height: 1.45;
  color: var(--bb-ink); /* 15,82:1 */
}

/* --------------------------------------------------------------------------
   CAP. 7 — CIERRE

   El banner de CTA que va debajo NO tiene ni una regla en esta hoja:
   reutiliza .bb-hcta y home-cta.css tal cual, con las mismas cifras de
   contraste medidas alli (7,2:1).
   -------------------------------------------------------------------------- */
.bb-ab__ch--fin { text-align: left; }
.bb-ab-fin__in { width: 100%; }

.bb-ab-fin__q { margin: 0; }
.bb-ab-fin__q p {
  margin: 0;
  max-width: 42ch;
  font-family: var(--bb-font-lyric);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.75rem, 4vw, 3.5rem);
  line-height: 1.2;
  color: var(--bb-ink); /* 15,82:1 */
}

.bb-ab-fin__social {
  margin: var(--bb-s5) 0 0;
  padding-top: var(--bb-s4);
  border-top: 1px solid var(--bb-ink-soft);
  max-width: 52ch;
  font-family: var(--bb-font-body);
  font-size: var(--bb-size-body);
  line-height: 1.76;
  color: var(--bb-body); /* 6,94:1 */
}
.bb-ab-fin__social a { color: var(--bb-accent); } /* 8,88:1 */

/* --------------------------------------------------------------------------
   ENTRADA DEL CAP. 1 — persiana vertical DESCENDENTE, en CSS puro.

   Va en CSS y no en JS porque el estado inicial tiene que estar aplicado
   ANTES del primer pintado; si lo pusiera el JS se veria la foto un
   fotograma antes de colapsar. Misma direccion que el hero de la portada,
   el de servicio y el panel de contacto: es el estilo aprobado para la
   entrada de PAGINA.

   ############ TRAMPA PAGADA: LOS DOS EXTREMOS, 4 COMPONENTES ###########
   Un inset() de 4 componentes NO interpola contra uno de 1: el navegador
   serializa inset(0% 0% 100% 0%) con tres o cuatro piezas e inset(0) con
   una, y con estructuras distintas la animacion se queda CLAVADA en el
   valor inicial y salta al final. Por eso los dos fotogramas de abajo
   llevan los CUATRO lados explicitos y todos en %.
   (En @keyframes de CSS los navegadores actuales interpolan el valor
   computado componente a componente y esto no se manifiesta; en GSAP si.
   Se escriben igual en los dos sitios: una sola regla que recordar.)
   #######################################################################

   'both' es obligatorio: durante el retardo (mientras pasa la cortina
   blanca) el elemento tiene que estar ya en el estado 'from'.

   TODO EL BLOQUE VIVE DENTRO DE prefers-reduced-motion: no-preference.
   Si estuviera fuera, el retardo dejaria la foto oculta medio segundo
   incluso con las animaciones neutralizadas.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {

  .bb-ab-hero__frame {
    animation: bb-ab-open 1.25s var(--bb-ease-diag) var(--bb-delay-curtain) both;
  }

  /* Cascada del texto, con los retardos pedidos (0,55 / 0,68 / 0,80s). */
  .bb-ab-hero__h1     { animation: bb-ab-rise 0.9s var(--bb-ease) 0.68s both; }
  .bb-ab-hero__lyric  { animation: bb-ab-rise 0.9s var(--bb-ease) 0.80s both; }
  .bb-ab-hero__scroll { animation: bb-ab-rise 0.9s var(--bb-ease) 0.92s both; }

  /* El rotulo va al 78% de opacidad (5,83:1 medidos). Con el keyframe
     normal acabaria en 1 y quedaria mas claro de lo medido: lleva su
     propio fotograma final. */
  .bb-ab-hero__label { animation: bb-ab-rise-soft 0.9s var(--bb-ease) 0.55s both; }

  /* KEN BURNS: se REUTILIZAN los @keyframes bb-ken de home-kenburns.css
     (12s, curva simetrica, alternate, escala 1 -> 1,07, deriva 1,2%), que
     es el valor aprobado. Esa hoja los aplica solo a .bb-hhero__img y
     .bb-hstrip__img, que son selectores de la portada; aqui se aplica al
     selector propio, exactamente como hacen service.css y contact.css. NO
     se copia la aritmetica: esta documentada en home-kenburns.css.

     NO CHOCA CON LA PERSIANA: la persiana es clip-path sobre el MARCO
     (.bb-ab-hero__frame) y el Ken Burns es transform sobre la IMAGEN
     (.bb-ab-hero__img). Dos propiedades distintas sobre dos elementos
     distintos. Y es el UNICO Ken Burns de la pagina: en los capitulos 2,
     3, 4 y 6 la imagen ya recibe la micro-escala de la entrada, que
     tambien es un transform, y dos animaciones peleando por el transform
     del mismo elemento es justo lo que la regla del proyecto prohibe. */
  .bb-ab-hero__img {
    animation: bb-ken 12s cubic-bezier(0.45, 0, 0.55, 1) infinite alternate;
  }
}

@keyframes bb-ab-open {
  from { clip-path: inset(0% 0% 100% 0%); }
  to   { clip-path: inset(0% 0% 0% 0%); }
}
@keyframes bb-ab-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes bb-ab-rise-soft {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   MOVIMIENTO REDUCIDO — todo en su estado final visible.

   Ni cortina (la retira home-curtain.css), ni Ken Burns, ni entrada, ni
   salida, y NINGUN recorte: los bloques que en modo normal abre y cierra
   page-reveals.js quedan visibles porque este CSS nunca les aplica
   clip-path por su cuenta. Que no haya en toda la hoja ninguna regla de
   clip-path fuera del bloque de arriba (que vive dentro de
   no-preference) es la garantia; el clip-path: none de aqui es el cinturon
   de seguridad por si la animacion hubiera dejado un valor aplicado.

   La cita sticky del Cap. 2 tambien se suelta: quedarse pegada media
   pantalla es movimiento, aunque lo produzca el navegador.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .bb-ab-hero__frame,
  .bb-ab-hero__img,
  .bb-ab-hero__label,
  .bb-ab-hero__h1,
  .bb-ab-hero__lyric,
  .bb-ab-hero__scroll,
  .bb-ab-hero__scroll-line::after {
    animation: none;
  }
  .bb-ab-hero__frame { clip-path: none; }
  .bb-ab-tri__quote { position: static; }
  .bb-ab-tri__item { min-height: 0; }
}
