/* ============================================================
   EPIC VIEW CORP — clinical white counterpart.
   Same type system (Clash Display + Space Grotesk), inverted world:
   paper white, ink black, one thin red accent.
   ============================================================ */

:root {
  --paper: #f7f5f0;
  /* E6: los mismos componentes, para poder escribir rgba() con alfa variable
     en el degradado de salida del hero sin duplicar el color a mano. */
  --paper-rgb: 247, 245, 240;
  --ink: #0b0b0c;
  --red: #e0091d;
  --font-wordmark: 'Clash Display', 'Bricolage Grotesque', Impact, sans-serif;
  --font-body: 'Space Grotesk', 'Segoe UI', sans-serif;
  /* E17 ⑪ — segundo papel. Un solo tono de arriba abajo no daba ritmo; Apple
     alterna superficies y "el cambio de color ES el divisor" (sin líneas).
     Una sombra derivada del papel, no un color nuevo. */
  --paper-2: #efece5;
  /* E17 ② ⑤ — los mismos tokens que en ARTISTA (ver style.css) */
  --track-label: .14em;
  --track-btn: .16em;
  --sp-md: clamp(32px, 5vh, 56px);
  --sp-lg: clamp(48px, 8vh, 88px);
  --sp-xl: clamp(64px, 12vh, 128px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: auto; scrollbar-width: thin; scrollbar-color: var(--red) #e8e5de; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
::-webkit-scrollbar { width: 6px; }
::-webkit-scrollbar-track { background: #e8e5de; }
::-webkit-scrollbar-thumb { background: var(--red); }

body.corp {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--ink); color: var(--paper); }
a { color: inherit; text-decoration: none; }

/* entrance cover — fades out on arrival (content is never transformed) */
#corp-enter {
  position: fixed; inset: 0; z-index: 1150;
  background: var(--paper);
  opacity: 0;
  pointer-events: none;
}

/* exit cover for the return transition — pure fade, no parked shadow
   (the old off-screen slab's shadow bled a gray stripe into the left edge) */
#corp-exit {
  position: fixed; inset: 0; z-index: 1200;
  background: #060606;
  opacity: 0;
  pointer-events: none;
}

/* ---------- nav ---------- */
#corp-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 500;
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px clamp(18px, 3vw, 44px);
  background: linear-gradient(180deg, rgba(247, 245, 240, .92), rgba(247, 245, 240, 0));
}
.corp-brand {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: 1.3rem; letter-spacing: .02em;
}
.corp-brand sup { color: var(--red); font-size: .6em; }
.corp-brand span {
  font-size: .62em; letter-spacing: var(--track-btn); color: rgba(11, 11, 12, .45);
  margin-left: .5em; vertical-align: middle;
}
.back-artist {
  font-size: .72rem; letter-spacing: var(--track-label); font-weight: 600;
  border-bottom: 1px solid transparent;
  transition: color .2s, border-color .2s;
}
.back-artist:hover { color: var(--red); border-color: var(--red); }
.corp-nav-right { display: flex; align-items: center; gap: clamp(18px, 2.6vw, 38px); }

/* sound toggle: same quiet language as ARTISTA, on paper */
#corp-sound {
  display: inline-flex; align-items: center; gap: 8px;
  background: none; border: none; padding: 4px 2px;
  cursor: pointer;
  opacity: .75;
  transition: opacity .25s;
}
#corp-sound:hover { opacity: 1; }
.cs-bars { display: inline-flex; align-items: flex-end; gap: 2.5px; height: 12px; }
.cs-bars i {
  width: 2px; height: 3px; background: var(--red); display: block;
  opacity: .85;
  animation: csbar .9s ease-in-out infinite;
  animation-play-state: paused;
}
.cs-bars i:nth-child(2) { animation-delay: .15s; }
.cs-bars i:nth-child(3) { animation-delay: .3s; }
.cs-bars i:nth-child(4) { animation-delay: .45s; }
#corp-sound.on .cs-bars i { animation-play-state: running; }
@keyframes csbar { 0%, 100% { height: 3px; } 50% { height: 12px; } }
.cs-label {
  /* E7F 1.1: un <button> NO hereda font-family — la hoja del navegador le
     impone Arial. Sin esta línea, SOUND se pintaba en Arial. */
  font-family: var(--font-body);
  font-size: .69rem; letter-spacing: var(--track-btn); font-weight: 600;
  color: rgba(11, 11, 12, .5);
}

/* ---------- hero ---------- */
/* E8b — LA BANDA NEGRA DEL PIE Y LOS TAMAÑOS QUE NO CABÍAN, MEDIDOS EN LAS
   CAPTURAS DEL CLIENTE. En su iPhone la sección pineada medía 657 px pero la
   unidad vh valía 7,41 px (741): los cuerpos en vh crecían para un viewport de
   741 dentro de una caja de 657 (el párrafo del pilar 03 se metía en el
   módulo) y, con la barra del navegador recogida, quedaban 84 px de nada
   debajo de cada sección ("hay un espacio negro abajo siempre").

   La causa era la cadena de alturas de abajo: en un Safari sin lvh gana
   `calc(var(--vh) * 100)`, y --vh se medía con innerHeight AL CARGAR — con
   la barra desplegada, el viewport CHICO. Justo lo contrario de lo que v27
   decidió (viewport grande, la barra se absorbe con el recorte del video).

   Corrección: el respaldo es 100vh a secas. En Safari iOS —con o sin lvh— y
   en Chrome Android, 100vh ES el viewport grande, el mismo que lvh, así que
   la sección y las unidades vh de su interior vuelven a hablar del mismo
   alto. --vh deja de escribirse (main.js / corp.js). */
#corp-hero {
  position: relative; overflow: hidden;
  /* v27: same lvh chain as ARTISTA's .pin-sec (see the note there) */
  height: 100vh;
  height: 100lvh;
  background: var(--paper);
}
/* E6: el cristal pasó de secuencia de frames scrubbeada a video en loop.
   object-fit: cover porque el clip es 16:9 y el hero mide el alto del
   viewport: en pantallas altas o estrechas hay que recortar, jamás deformar.
   El fondo de papel cubre el hueco hasta que el primer frame decodifica. */
#corp-hero .crystal-loop {
  /* E6B ②: la caja vuelve a medir EXACTAMENTE el hero, para no cambiar el
     encuadre que ya estaba dado por bueno. El único margen es un `scale`
     mínimo (8%): el video se desplaza hacia arriba DESDE EL PRIMER SCROLL y,
     hasta que la marea le tapa el pie, ese 8% impide que asome el papel del
     fondo con un canto duro. Medido, el peor caso descubierto antes de que el
     blanco lo cubra son 25 px, y el scale da 29. */
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%;
  scale: 1.08;
  object-fit: cover; display: block;
  background: var(--paper);
}
/* dissolves the clip's gray backdrop into the page white — no visible frame */
.corp-veil {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(ellipse 82% 78% at 50% 48%,
    rgba(247, 245, 240, 0) 52%,
    rgba(247, 245, 240, .55) 76%,
    var(--paper) 96%);
}
/* ---- E6 ②: el blanco CRECE DESDE ABAJO ----
   Antes era una capa a pantalla completa que subía de opacidad; ahora es una
   marea. La capa mide más que el viewport, está anclada abajo y solo se
   traslada: `translate` va en el compositor, así que el barrido no repinta
   nada por frame.

   El borde superior lleva NUEVE paradas y no dos, que es la lección del
   fundido de la cuchilla CORPORATIVA (E6): sobre luminancia alta un degradado
   lineal se lee como una LÍNEA, porque la pendiente pasa de 0 a su máximo en
   un píxel y el ojo detecta esa discontinuidad (banda de Mach). Las paradas
   aproximan una curva de derivada trapezoidal — la pendiente sube desde cero,
   se mantiene en el centro y vuelve a cero — y van más juntas en los extremos,
   donde la curva se dobla, que en el tramo recto.

   E6C ④: el borde se leía duro pese a las paradas. La causa no era la curva
   sino la DISTANCIA: 34% de 155% son 379 px de difuminado a 720 de alto, y
   sobre luminancia alta eso sigue siendo una pendiente perceptible. La capa
   pasa a medir 185% y el degradado a ocupar 44% de ella: 586 px, un 55% más
   de recorrido para el mismo salto de opacidad. Misma curva, más camino.

   E6I ①: TERCERA PASADA, Y AHORA SOBRE LAS DOS DISTANCIAS.
   La caja pasa de 185% a 300% y el degradado de 44% a 56% de ella. Eso mueve
   dos números que hasta ahora se trataban como uno solo:

   · distancia ESPACIAL — el difuminado pasa de 586 px a 1210 px (a 720 de
     alto), +106%. Con 1,68 viewports de alto la rampa ya no cabe en pantalla:
     no queda un canto que cruce el cuadro, el cuadro entero se aclara a la vez.
   · distancia TEMPORAL — y esta era la que faltaba. La marea recorre su PROPIA
     altura en el mismo tramo de scroll, así que lo que decide cuánto tarda el
     blanco en pasar por un punto no es cuánto mide la caja sino QUÉ FRACCIÓN
     de ella es degradado. De 44% a 56%: de 140 px de scroll a 178 px, +27%.
     Subir solo la altura no habría cambiado este número en absoluto.

   Reparto: 44% opaco (que a 300% de alto cubre 1,32 viewports, el cuadro
   entero con margen; el blanco pleno llega en p=0,94 y no en p=0,99, así que
   la entrega al bloque siguiente ya no va al filo) y 56% de degradado.

   La curva pasa de nueve paradas trapezoidales a DIECISÉIS sobre un
   smootherstep (6u^5 - 15u^4 + 10u^3), la única de esta familia con primera
   Y SEGUNDA derivada nulas en los dos extremos: la banda de Mach nace de una
   discontinuidad de pendiente, y aquí no hay ninguna que detectar. Las
   paradas se agolpan hacia el extremo transparente —seis en su último cuarto
   contra tres en el opaco— porque ahí es donde el ojo busca el comienzo del
   blanco. */
.corp-outro {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 300%;
  z-index: 4; pointer-events: none;
  translate: 0 100%; /* fuera de cuadro; lo conduce initHero */
  background: linear-gradient(to top,
    rgb(var(--paper-rgb))         0%,
    rgb(var(--paper-rgb))        44%,
    rgba(var(--paper-rgb), .998) 47.4%,
    rgba(var(--paper-rgb), .986) 50.7%,
    rgba(var(--paper-rgb), .942) 55.2%,
    rgba(var(--paper-rgb), .862) 59.7%,
    rgba(var(--paper-rgb), .749) 64.2%,
    rgba(var(--paper-rgb), .611) 68.6%,
    rgba(var(--paper-rgb), .463) 73.1%,
    rgba(var(--paper-rgb), .317) 77.6%,
    rgba(var(--paper-rgb), .191) 82.1%,
    rgba(var(--paper-rgb), .093) 86.6%,
    rgba(var(--paper-rgb), .032) 91.0%,
    rgba(var(--paper-rgb), .009) 94.4%,
    rgba(var(--paper-rgb), .001) 97.2%,
    rgba(var(--paper-rgb), 0)   100%);
}
/* ---- E6C ④ (segunda parte): EL BORDE NO ERA UNA PENDIENTE, ERA BANDING ----
   Medido sobre el fondo real del cristal (RGB ~235-244), el degradado solo
   recorre 13 niveles de 8 bits: mesetas planas de decenas de píxeles. Eso no
   se ve como una rampa, se ve como líneas de contorno — y es exactamente lo
   que se percibe como "tosco" y como que se nota donde empieza el blanco.

   Y hay una trampa: ALARGAR el difuminado empeora el banding, porque reparte
   los mismos pocos niveles en más distancia y ensancha cada meseta. Por eso
   el punto 1 de la E6I —alargar aún más— solo es seguro con esta capa puesta,
   y por eso su opacidad sube de .8 a .9: con la rampa al doble de larga las
   mesetas también son el doble de anchas, y cada escalón que sobreviva se lee
   más aislado. A .9 el ruido es de ±1,26 niveles, sobre el mínimo de ±1 que
   hace falta para que la cuantización se vuelva ruido en vez de contorno.

   Dos detalles que la hacen segura:
   . `overlay` contra gris medio es la ÚNICA operación de media cero que hay
     en CSS: sube y baja el mismo valor, así que no aclara ni oscurece el
     blanco, solo lo desordena. Con `normal` habría que oscurecer la media.
   . `isolation: isolate` en la capa hace que el blend solo vea el degradado
     de su propio padre. Sin eso mezclaría contra toda la página. */
.corp-outro { isolation: isolate; }
.corp-outro::after {
  content: '';
  /* E6I ①: LA CAPA VUELVE A MEDIR LA CAJA ENTERA — Y AQUÍ HAY UNA TRAMPA.
     La primera versión de este ajuste la recortaba al 56% superior (`inset:
     0 0 44% 0`), que es donde el degradado tiene alfa parcial y donde el
     dither hace falta. Ahorraba media textura de compositor y reintroducía,
     por abajo, exactamente el bug de la E6D: el canto inferior de la capa
     caía DENTRO del blanco pleno, con ruido de un lado y liso del otro. No
     hay salto de luminancia ahí —`overlay` es de media cero— pero sí un
     salto de TEXTURA con borde recto, y ese canto entra en cuadro a partir
     de p=0,77. Medido sobre la geometría nueva: recorre la pantalla de abajo
     arriba durante el último cuarto del pin, justo cuando todo es blanco y
     nada más lo tapa. La capa mide la caja entera y el único borde que tiene
     vuelve a estar donde la marea ya no existe. */
  position: absolute; inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: .9;
  /* feTurbulence comprimido a 0,43–0,57 alrededor del gris medio: ±1,4
     niveles sobre blanco, ±1,26 tras la opacidad (era ±1,1 con la opacidad
     en .8; sube porque la rampa nueva es del doble de larga y sus mesetas
     también, así que cada contorno que sobreviva se lee más aislado).
     `color-interpolation-filters=sRGB` no es opcional: por defecto
     feTurbulence trabaja en linearRGB y su media sale a 187 en pantalla, no
     a 128 — medido, eso ACLARABA la marea 3,7 niveles en vez de dejarla
     igual. Lo justo para disolver un escalón de 1 nivel sin que el ruido se
     lea como textura propia. */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='d' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/><feComponentTransfer><feFuncR type='linear' slope='0.14' intercept='0.43'/><feFuncG type='linear' slope='0.14' intercept='0.43'/><feFuncB type='linear' slope='0.14' intercept='0.43'/></feComponentTransfer></filter><rect width='160' height='160' filter='url(%23d)'/></svg>");
  background-size: 160px 160px;
  /* E6D ①: LA MÁSCARA ES LO QUE FALTABA — Y ERA EL BUG.
     Esta capa mide toda la caja mientras que el degradado solo tiene
     sustancia en su parte superior. Donde el fondo del padre es transparente,
     `overlay` devuelve el color de origen tal cual: el ruido se pintaba
     entero ahí. El resultado era una franja con textura y, en su canto
     superior, una LÍNEA RECTA Y DURA cruzando la pantalla — el borde de esta
     caja. Con la misma rampa como máscara, el dither solo existe donde la
     marea tiene opacidad, se desvanece con ella y no tiene borde en ninguna
     parte. Las paradas son LAS MISMAS del degradado, una a una: si alguna
     vez divergen vuelve el borde, así que se editan juntas. */
  -webkit-mask-image: linear-gradient(to top,
    #000 0%, #000 44%,
    rgba(0,0,0,.998) 47.4%, rgba(0,0,0,.986) 50.7%, rgba(0,0,0,.942) 55.2%,
    rgba(0,0,0,.862) 59.7%, rgba(0,0,0,.749) 64.2%, rgba(0,0,0,.611) 68.6%,
    rgba(0,0,0,.463) 73.1%, rgba(0,0,0,.317) 77.6%, rgba(0,0,0,.191) 82.1%,
    rgba(0,0,0,.093) 86.6%, rgba(0,0,0,.032) 91.0%, rgba(0,0,0,.009) 94.4%,
    rgba(0,0,0,.001) 97.2%, transparent 100%);
  mask-image: linear-gradient(to top,
    #000 0%, #000 44%,
    rgba(0,0,0,.998) 47.4%, rgba(0,0,0,.986) 50.7%, rgba(0,0,0,.942) 55.2%,
    rgba(0,0,0,.862) 59.7%, rgba(0,0,0,.749) 64.2%, rgba(0,0,0,.611) 68.6%,
    rgba(0,0,0,.463) 73.1%, rgba(0,0,0,.317) 77.6%, rgba(0,0,0,.191) 82.1%,
    rgba(0,0,0,.093) 86.6%, rgba(0,0,0,.032) 91.0%, rgba(0,0,0,.009) 94.4%,
    rgba(0,0,0,.001) 97.2%, transparent 100%);
}
/* E6I ②: EL TITULAR VIAJA POR ENCIMA DE LA MAREA (z-index 6 > 4).
   El momento rojo de "sin el ruido" no se leía porque, al dispararse, el velo
   blanco ya estaba pasando sobre la frase: medido en el estado anterior, en
   p=0,62 la marea cubría la línea con ~10% de blanco y una muesca de rueda
   después con ~62%. El glow ocurría sobre un texto que ya se estaba borrando.
   Subiendo la copia por encima de la capa blanca, el mundo se apaga debajo y
   la frase queda intacta y a máximo contraste — rojo sobre papel puro, que es
   el mejor contraste posible en este lado. La salida ya no la decide la marea
   sino cada línea por su cuenta (initHero, E6I ②): el subtítulo se disuelve
   primero, después "Producción de nivel enterprise," y de última "sin el
   ruido.", que es lo último que queda visible antes de irse. Eso es lo que
   dice el copy, y ahora también lo que hace la página. */
.corp-hero-copy {
  position: absolute; left: clamp(20px, 6vw, 90px); bottom: 12vh; z-index: 6;
  max-width: 30ch;
}
/* E6E ①: las dos mitades del titular se revelan en pasos de scroll distintos,
   así que cada una necesita ser su propia caja animable. `inline-block` para
   que el translate funcione (un inline no acepta transform). */
.corp-hero-copy h1 .hl-a,
.corp-hero-copy h1 em {
  display: inline-block;
  opacity: 0; /* scroll-driven */
  will-change: opacity, translate;
}
.corp-hero-copy h1 {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(2rem, 4.6vw, 4.4rem);
  /* E7F 3.3: 1,02 era demasiado apretado para un titular de dos líneas en una
     display. "Producción" baja una p y "sin el ruido" sube l y d: a 1,02 esos
     trazos se enganchan. Y el interlineado apretado es un gesto agresivo, que
     contradice el posicionamiento de este lado — literalmente "sin el ruido".
     No cambia ni un píxel de ancho: el bloque solo respira a lo alto. */
  line-height: 1.12;
  letter-spacing: -0.01em;
  /* E6F ①: SIN opacity aquí. Hasta la E6E el <h1> entero se revelaba con
     una sola opacidad conducida por JS; al partirlo en dos pasos, quien
     se revela son los hijos (.hl-a y em) y esta línea quedó huérfana en
     0 — la opacidad multiplica hacia abajo, así que los hijos estaban a 1
     dentro de un padre a 0 y el titular no se veía. */
}
/* E6D ④: GLOW ROJO EN "SIN EL RUIDO" — el mismo de "ARTISTAS".
   Se reutiliza tal cual el efecto del manifiesto de ARTISTA: glow tenue
   permanente en reposo + un pulso único de 1500 ms con el pico al 45% y la
   misma curva, arrancando y terminando en el valor de reposo para que no
   haya bajón antes de encender. Las hojas de estilo de los dos lados están
   separadas (corp.css no carga style.css), así que la regla vive aquí; lo
   que se copia es el efecto, no se inventa uno nuevo.
   Único ajuste: las alfas bajan ~25% respecto de ARTISTA. Allá el rojo se
   enciende sobre negro; aquí sobre papel, y este es el lado sobrio. */
.corp-hero-copy h1 em {
  font-style: normal; color: var(--red);
  text-shadow: 0 0 18px rgba(224, 9, 29, .25);
}
.corp-hero-copy h1 em.glow-in { animation: corp-glow 1500ms cubic-bezier(.4, 0, .3, 1) 1; }
@keyframes corp-glow {
  0%   { text-shadow: 0 0 18px rgba(224, 9, 29, .25); }
  45%  { text-shadow: 0 0 34px rgba(224, 9, 29, .75), 0 0 72px rgba(224, 9, 29, .35); }
  100% { text-shadow: 0 0 18px rgba(224, 9, 29, .25); }
}
.corp-sub {
  margin-top: 2.4vh;
  font-weight: 300;
  font-size: clamp(.8rem, 1.1vw, 1rem);
  letter-spacing: .06em;
  color: rgba(11, 11, 12, .6);
  opacity: 0; /* scroll-driven */
}
/* SCROLL HUD — same pulse language as ARTISTA, red on white (best contrast
   against the pale backdrop without going full-ink) */
#corp-hud {
  position: absolute; right: clamp(30px, 5.2vw, 92px); top: 50%;
  translate: 0 -50%;
  z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 20px;
  padding: 14px 20px; /* grab area — drag-to-scroll like ARTISTA */
  pointer-events: auto;
  user-select: none; -webkit-user-select: none;
  touch-action: none;
  cursor: grab;
}
#corp-hud:active, #corp-hud.dragging { cursor: grabbing; }
/* sized to match the ARTISTA HUD exactly (v18) */
.hud-line {
  width: 4px; height: min(258px, 30vh);
  background-image:
    linear-gradient(180deg, transparent, var(--red), transparent),
    linear-gradient(rgba(224, 9, 29, .18), rgba(224, 9, 29, .18));
  background-size: 100% 36%, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  animation: hudchase-top 3.4s linear infinite;
}
@keyframes hudchase-top {
  0% { background-position: 0 -65%, 0 0; }
  45% { background-position: 0 165%, 0 0; }
  100% { background-position: 0 165%, 0 0; }
}
.hud-tag {
  font-size: 1.02rem; letter-spacing: .34em;
  color: rgba(224, 9, 29, .5);
  white-space: nowrap;
  padding-left: .38em;
  animation: hudglow 3.4s linear infinite;
}
@keyframes hudglow {
  0%, 42% { color: rgba(224, 9, 29, .5); text-shadow: none; }
  48% { color: rgba(224, 9, 29, 1); text-shadow: 0 0 12px rgba(224, 9, 29, .45); }
  56%, 100% { color: rgba(224, 9, 29, .5); text-shadow: none; }
}
.hud-arrow {
  position: relative;
  width: 4px; height: min(258px, 30vh);
  background-image:
    linear-gradient(180deg, transparent, var(--red), transparent),
    linear-gradient(rgba(224, 9, 29, .18), rgba(224, 9, 29, .18));
  background-size: 100% 36%, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  animation: hudchase-bottom 3.4s linear infinite;
}
@keyframes hudchase-bottom {
  0%, 50% { background-position: 0 -65%, 0 0; }
  100% { background-position: 0 165%, 0 0; }
}
.hud-arrow::after {
  content: '';
  position: absolute; bottom: 0; left: 50%;
  width: 9px; height: 9px; margin-left: -5.5px;
  border-right: 2px solid rgba(224, 9, 29, .8);
  border-bottom: 2px solid rgba(224, 9, 29, .8);
  transform: rotate(45deg);
}

/* ---------- content blocks ---------- */
.corp-block {
  padding: var(--sp-xl) clamp(20px, 6vw, 90px); /* E17 ⑤ */
  max-width: 1200px;
}
.kicker {
  /* E17 ⑭: 10,6 px/.4em/500 → 11,5 px/.18em/600. El filete rojo no cambia. */
  font-size: .72rem; letter-spacing: .18em; font-weight: 600;
  color: rgba(11, 11, 12, .5);
  padding-bottom: 14px; margin-bottom: 5vh;
  position: relative;
}
/* the minimal red accent: one thin rule under each kicker */
.kicker::after {
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 44px; height: 2px; background: var(--red);
}
.corp-body {
  font-weight: 400; /* E17 ⑫ */
  font-size: clamp(1.1rem, 1.9vw, 1.7rem);
  line-height: 1.55;
  max-width: 46ch;
  color: rgba(11, 11, 12, .85);
}

/* positioning statement: first block after the hero — the negative margin
   tucks it under the hero's white outro while the pin releases, said once. */
#corp-position {
  max-width: none;
  position: relative; z-index: 5;
  margin-top: -52vh;
  /* E4 ③: 4vh → 14vh. "Rigor de ingeniería" quedaba pegado al claim del
     hero. Se abre por padding y no tocando el margin negativo, que es lo
     que sostiene el solape con el pin del cristal. */
  /* E6C/E6D: 14vh → 8vh → 4vh. El pasaje en blanco se acorta por los dos lados:
     pin del hero dura menos y el bloque siguiente empieza antes. */
  padding-top: 4vh; padding-bottom: 10vh;
  text-align: center;
}
.pos-title {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(1.9rem, 3.8vw, 3.4rem);
  /* E7F 3.3: mismo criterio que el h1 del hero. */
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin-bottom: 3.4vh;
}
.pos-title em { font-style: normal; color: var(--red); }
.pos-body {
  margin: 0 auto;
  max-width: 52ch;
  /* E17 ⑫: 300 → 400. Apple corre el cuerpo en 400 y reserva el 300 a lecturas
     grandes (≥ 24 px); a 18 px en papel el 300 pierde trazo. */
  font-weight: 400;
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  line-height: 1.6;
  color: rgba(11, 11, 12, .72);
}

/* "qué hacemos": four capabilities, type as the protagonist (2×2) */
#corp-what {
  max-width: 1080px;
  margin: 0 auto;
  padding-top: var(--sp-md); padding-bottom: var(--sp-lg);
  text-align: center;
}
#corp-what .kicker::after { left: 50%; transform: translateX(-50%); }
.cap-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8vh clamp(40px, 6vw, 90px);
  text-align: left;
  margin-top: 2vh;
}
.cap-num {
  display: block;
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: .8rem; letter-spacing: var(--track-label);
  color: var(--red);
  margin-bottom: 12px;
}
.cap h3 {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(1.05rem, 1.7vw, 1.45rem);
  text-transform: uppercase;
  letter-spacing: .04em;
  line-height: 1.2;
  margin-bottom: 12px;
}
.cap p {
  /* E17 ⑫: 14,7 px/300 al 68 % → ~15,5 px/400 al 72 % */
  font-weight: 400;
  font-size: clamp(.95rem, 1.2vw, 1.05rem);
  line-height: 1.55;
  color: rgba(11, 11, 12, .72);
}

/* v23: capability hover — a work-sample panel fades in beside the block,
   and the spotlight dims the other three */
/* ---- E7 ①: EL HOVER YA NO ABRE NADA — SOLO DICE "ESTO SE PUEDE CLICKEAR" ----
   Antes el panel se abría con `mouseenter`, así que alguien que scrolleaba con
   el cursor en el centro de la pantalla disparaba videos sin querer. Ahora el
   video es exclusivamente por click (js/corp.js) y el hover se queda con un
   solo trabajo: la promesa. Crece el bloque entero y se enciende un filo
   alrededor del título. */
.cap {
  position: relative; cursor: pointer;
  transition: opacity .35s ease, scale .5s cubic-bezier(.16, 1, .3, 1);
  transform-origin: left center; /* el texto está alineado a la izquierda: ese borde no se mueve */
}
@media (pointer: fine) {
  .cap:hover { scale: 1.028; }
}
/* ---- E7 ①: IRIDISCENCIA PRESTADA AL CRISTAL DEL HERO ----
   La referencia que llegó era un botón de borde neón arcoíris. No se copia:
   ese lenguaje es de gaming y este lado es el silencioso. En su lugar, los
   colores salen MEDIDOS del propio cristal del hero — cinco fotogramas
   repartidos por una vuelta completa, 360×202, contando todo píxel con
   saturación > 0,16:

     · solo el 0,5% de la imagen es cromática — el cristal es casi todo neutro,
       y por eso su iridiscencia se lee como algo raro y caro
     · de esa parte cromática: 68,7% cálida (tono 330–45°, pico en 5°),
       29,1% fría (201–290°, pico en 225°), 1,9% magenta
     · VERDE: 0,2%. No existe. Un arcoíris habría sido una invención.

   O sea que la dispersión real es de DOS lóbulos —ámbar/rosa contra índigo—
   y no un espectro. El degradado respeta ese reparto: 72% del recorrido en
   la mitad cálida, 28% en la fría, cero verde. Y el pico cálido del cristal
   (tono 5°) es la familia del rojo de marca (355°), así que el filo entra por
   la puerta de la identidad y no como un color ajeno.

   Saturación subida de la medida (~0,29) a ~0,6 porque esto es un filo de 1 px
   sobre papel: a la saturación original sería invisible. La luminosidad se
   queda alta, que es lo que lo mantiene del lado de Apple y no del neón. */
.cap h3 { position: relative; padding-right: 34px; }
.cap h3::before,
.cap h3::after {
  content: '';
  /* el h3 lleva `padding-right: 34px` para no correr por debajo del "+", así
     que un inset simétrico dejaría el filo 34 px más suelto por la derecha
     que por la izquierda. 21 = 34 − 13: el anillo abraza la CAJA DE
     CONTENIDO, no la de padding, y queda parejo a los dos lados. */
  position: absolute; inset: -9px 21px -9px -13px;
  border-radius: 7px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .45s ease;
  /* E16 → E18 → E19: NÁCAR.
     El cliente sintió el paso de E18 demasiado rápido y dudó de sus colores
     (turquesa/naranja/rojo). Decisiones de diseño, tomadas mirando el resto
     del lado corporativo (papel, tinta, UN rojo — el del dato y del "+") y el
     cristal del hero:

     · COLOR: el rojo se queda fuera del anillo a propósito — es el acento
       único de la página y aquí competiría con el dato. Los colores salen de
       la dispersión real del cristal (lóbulo cálido ~5°, lóbulo frío ~225°),
       llevados a nácar: rosa cálido → oro pálido → hielo → lila. Saturación
       baja, luminosidad alta: tonos de madreperla, no de pantalla. Van con
       el papel porque nacen del mismo objeto que preside la página.
     · TEMPO: 2,8 s → 11 s por recorrido, y con curva ease-in-out en vez de
       lineal: la banda acelera, se frena y casi se detiene antes de volver
       a andar. Es un ritmo de respiración, no de cinta transportadora.
     · ORGÁNICO: dos periodos que no son múltiplos (recorrido 11 s, latido
       del resplandor 7 s) — su superposición no se repite exacta en casi un
       minuto y medio — y cada uno de los cuatro bloques arranca en una fase
       distinta (delays negativos), así que nunca se mueven al unísono: son
       cuatro cosas vivas, no un patrón.
     · BUCLE SIN SALTO: fondo al 300 % y recorrido de 150 % de posición, que
       es exactamente un mosaico (con 320 %/320 % el bucle daba un salto de
       0,64 anchos). La banda viaja de izquierda a derecha, con el rosa
       cálido al frente y el lila detrás. */
  --filo-neutro: hsl(38, 12%, 80%);
  background-size: 300% 100%;
  animation: cap-nacar 11s cubic-bezier(.45, 0, .55, 1) infinite;
}
/* el resplandor: SOLO la banda, desenfocada y detrás (el tramo neutro es
   transparente: un halo gris alrededor del título no aporta nada) */
.cap h3::before {
  filter: blur(11px);
  background-image: linear-gradient(90deg,
    transparent          0%,
    transparent         14%,
    hsl(256, 42%, 80%)  28%,
    hsl(208, 55%, 78%)  40%,
    hsl(40,  62%, 74%)  54%,
    hsl(14,  62%, 78%)  66%,
    transparent         80%,
    transparent        100%);
}
/* el filo: anillo de 1 px (máscara XOR) — neutro con la banda pasando */
.cap h3::after {
  background-image: linear-gradient(90deg,
    var(--filo-neutro)   0%,
    var(--filo-neutro)  14%,
    hsl(256, 34%, 72%)  28%,
    hsl(208, 45%, 70%)  40%,
    hsl(40,  52%, 64%)  54%,
    hsl(14,  50%, 70%)  66%,
    var(--filo-neutro)  80%,
    var(--filo-neutro) 100%);
  padding: 1px;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
@keyframes cap-nacar {
  from { background-position: 150% 50%; }
  to   { background-position:   0% 50%; }
}
/* E19: el anillo no late (un marco gris pulsando se ve raro); respira solo el
   resplandor, en un periodo distinto al del recorrido. Con ratón, el hover
   sube el anillo a pleno y el resplandor un paso. */
.cap h3::before { animation: cap-nacar 11s cubic-bezier(.45, 0, .55, 1) infinite, cap-respira-glow 7s ease-in-out infinite; }
.cap h3::after  { animation: cap-nacar 11s cubic-bezier(.45, 0, .55, 1) infinite; opacity: .8; }
@keyframes cap-respira-glow { 0%, 100% { opacity: .32; } 50% { opacity: .52; } }
/* cada bloque en su propia fase */
.cap:nth-child(2) h3::before { animation-delay: -3.7s, -1.9s; }
.cap:nth-child(2) h3::after  { animation-delay: -3.7s; }
.cap:nth-child(3) h3::before { animation-delay: -6.9s, -4.1s; }
.cap:nth-child(3) h3::after  { animation-delay: -6.9s; }
.cap:nth-child(4) h3::before { animation-delay: -9.4s, -5.6s; }
.cap:nth-child(4) h3::after  { animation-delay: -9.4s; }
@media (pointer: fine) {
  .cap:hover h3::before { animation-name: cap-nacar, cap-respira-glow-hover; }
  .cap:hover h3::after  { opacity: 1; }
}
@keyframes cap-respira-glow-hover { 0%, 100% { opacity: .5; } 50% { opacity: .68; } }
/* E7 ①: sin animación para quien la pidió apagada; el filo se queda quieto
   pero sigue estando, que es lo que comunica el click. */
@media (prefers-reduced-motion: reduce) {
  /* quieto con la banda a la vista: a 50 % la ventana (un tercio del fondo)
     muestra los stops 33–66 %, que es la banda */
  .cap h3::before, .cap h3::after { animation: none; background-position: 50% 50%; }
  .cap h3::before { opacity: .38; }
  .cap h3::after  { opacity: .8; }
  .cap:hover { scale: 1; }
}
/* E1 P5: nada decía que estos bloques se abren. Un "+" discreto en la
   esquina que gira a "×" al abrirse — se entiende sin instrucciones y no
   compite con la tipografía. Pseudo-elemento: cero markup nuevo. */
.cap::after {
  content: '+';
  position: absolute; top: -2px; right: 0;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  font-size: 1rem; font-weight: 300; line-height: 1;
  color: rgba(11, 11, 12, .42);
  border: 1px solid rgba(11, 11, 12, .16);
  border-radius: 50%;
  transition: transform .3s cubic-bezier(.16, 1, .3, 1), color .3s, border-color .3s, background .3s;
}
.cap:hover::after { color: var(--red); border-color: var(--red); }
.cap.is-open::after {
  transform: rotate(45deg);
  background: var(--red); color: var(--paper); border-color: var(--red);
}
.cap:hover { z-index: 40; } /* the hovered block (and its panel) owns the stack */
/* ---- E7B: EL PANEL ABIERTO SE APILA POR ENCIMA DE SUS VECINOS ----
   Síntoma: al abrir un panel, el texto de los bloques vecinos se veía por
   encima. Medido antes del arreglo, con 25 puntos por panel y
   `elementFromPoint`: el 1 quedaba tapado por el texto del 2 y del 4, el 2
   por el del 3, el 3 por el del 4. Un patrón por ORDEN DE DOM, no por
   translucidez.

   Y no era translucidez: el fondo del panel computa `rgb(247, 245, 240)`,
   opaco, sin canal alfa. Tampoco era un ancestro lejano: `#corp-what`,
   `.cap-grid`, `#corp-main` y `body` están todos limpios (sin transform,
   filter, opacity ni position que apilen).

   La causa estaba a un solo nivel de distancia, en el propio `.cap`: la
   animación de entrada (initReveals) anima `y: 36 → 0` con GSAP y NO limpia
   la propiedad al terminar, así que cada bloque se queda con un
   `transform: translate(0px, 0px)` en línea. Un transform distinto de `none`
   CREA UN CONTEXTO DE APILAMIENTO, aunque no mueva nada. Con eso, el
   `z-index: 50` del panel deja de competir con los vecinos y pasa a competir
   solo dentro de su propio bloque; los cuatro bloques quedan en `auto` y se
   pintan en orden de documento, de ahí que cada panel lo tapara justamente el
   texto de los bloques POSTERIORES.

   El arreglo va en el ancestro, que es donde está el problema: mientras el
   panel está abierto, el bloque entero sube a 60 —por encima del 40 del
   hover— y con él sube su panel. No se toca el `z-index` del panel ni se
   depende de que GSAP limpie su transform. */
.cap.is-open { z-index: 60; }
@media (pointer: fine) {
  .cap-grid:hover .cap:not(:hover) { opacity: .6; }
}
.cap-video {
  /* 1B: aligned to the invoking block's top edge, tethered by a red line,
     and it GROWS out of that edge (scale from the touching side) — reads as
     a consequence of the block, not a floating pop-up */
  position: absolute; top: 0; left: calc(100% + 34px);
  width: min(640px, 46vw); /* 1B: notably bigger — the work should be watchable */
  aspect-ratio: 16 / 9;
  background: var(--paper); /* v25: SOLID — neighbor text showed through the 4% tint */
  border: 1px solid rgba(11, 11, 12, .14);
  box-shadow: 0 24px 70px rgba(11, 11, 12, .16);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  opacity: 0; pointer-events: none;
  translate: -14px 0;
  scale: .94;
  transform-origin: left center;
  transition: opacity .35s ease, translate .45s cubic-bezier(.16, 1, .3, 1), scale .45s cubic-bezier(.16, 1, .3, 1);
  z-index: 50;
  box-shadow: 0 24px 70px rgba(11, 11, 12, .18);
}
/* right-column blocks open their panel to the left */
/* red tether: bridges the exact gap between block and panel */
.cap-video::before {
  content: '';
  position: absolute; top: 30px; right: 100%;
  width: 34px; height: 2px; background: var(--red);
}
.cap:nth-child(even) .cap-video {
  left: auto; right: calc(100% + 34px);
  translate: 14px 0;
  transform-origin: right center;
}
.cap:nth-child(even) .cap-video::before { right: auto; left: 100%; }
/* E1 BUG: `.cap:nth-child(even) .cap-video` pesa (0,3,0) y le ganaba a
   `.cap-video.show` (0,2,0), así que en los bloques PARES (02 y 04) el panel
   nunca revertía su `translate` en escritorio ni su `display:none` en móvil
   — el vídeo sonaba pero no se pintaba. El selector par se repite aquí para
   igualar el peso. No es el 9:16: el 04 es 16:9 y fallaba igual. */
.cap-video.show,
.cap:nth-child(even) .cap-video.show {
  opacity: 1; translate: 0 0; scale: 1;
  /* E7 ①: EL PANEL AHORA RECIBE CLICKS. Hasta acá `pointer-events: none` era
     correcto porque el panel se abría por hover y nadie tenía que tocarlo;
     con el botón de cerrar dentro, sin esto el botón sería decorativo. Solo
     en `.show`: cerrado sigue siendo transparente al puntero, así no tapa
     ni el texto vecino ni el bloque de al lado. */
  pointer-events: auto;
}
/* ---- E7 ①: BOTÓN DE CERRAR VISIBLE ----
   El "+" de la esquina del bloque ya gira a "×", pero está lejos del panel y
   hay que descubrirlo. Este está DENTRO del video, donde mira el ojo. Grande
   (40 px, por encima del mínimo táctil de 44 con su área de padding) y con
   fondo propio, porque debe leerse sobre cualquier fotograma.
   Un click en cualquier otra parte del panel también cierra: burbujea al
   bloque, que alterna. El botón no compite con eso, lo hace evidente. */
.cap-close {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  font-family: var(--font-wordmark);
  font-size: 1.45rem; font-weight: 300; line-height: 1;
  color: rgba(11, 11, 12, .72);
  background: rgba(247, 245, 240, .88);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(11, 11, 12, .14);
  border-radius: 50%;
  cursor: pointer;
  padding: 0;
  transition: background .25s ease, color .25s ease, border-color .25s ease, scale .25s ease;
}
.cap-close:hover,
.cap-close:focus-visible {
  background: var(--red); color: var(--paper); border-color: var(--red);
  scale: 1.06;
  outline: none;
}
/* the dashed frame belongs to the "PRÓXIMAMENTE" placeholder state only */
.cap-video.no-video { border: 1px dashed rgba(11, 11, 12, .18); box-shadow: none; }
.cap-video video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
}
.cap-video.no-video video { display: none; }
/* vertical material (cap 02): narrower, taller slot — same composition rules,
   the 9:16 aspect keeps cover-fit from cropping or squashing the phone frame */
.cap-video--tall {
  width: min(310px, 23vw);
  aspect-ratio: 9 / 16;
}
.cap-video-ph {
  font-size: .69rem; letter-spacing: var(--track-btn);
  color: rgba(11, 11, 12, .4);
  text-align: center; padding: 0 14px;
}

/* ============ E7D — RESULTADOS: TRES HITOS, EL DATO PRIMERO ============
   Antes eran tres frases grises del mismo tamaño: nadie las leía. Ahora cada
   hito tiene un dato en rojo de marca —el único color de la sección— y una
   línea de apoyo claramente subordinada debajo.

   El reto real era el EQUILIBRIO ÓPTICO. Los tres datos miden 31, 2 y 24
   caracteres: al mismo cuerpo, el "2×" —que es el dato más contundente—
   desaparecería. Los tamaños salen de una relación, no del gusto: para una
   masa de tinta parecida el cuerpo va con 1/√(nº de caracteres), y para una
   ALTURA de bloque parecida en una columna de ancho W, altura ≈ k·N·S²/W, de
   donde S = √(H·W/(k·N)). Las dos cuentas piden que el "2×" sea del orden de
   3× los otros. Los números finales están medidos en pantalla, no calculados
   a ojo (ver el informe de la ronda). */
#corp-results {
  /* E17 ⑪: la sección va a ancho completo para llevar el segundo papel a
     sangre; los 1180 px centrados pasan a .res-inner (corp.html). Un
     pseudo-elemento desbordando con -50vw fue la primera versión y abría
     scroll horizontal (scrollWidth 1270 → 1865): descartado. */
  background: var(--paper-2);
  /* Esta sección respira más que ninguna otra de CORP, que es lo que le da
     peso al dato. Arriba "qué hacemos" cierra con 8vh y abajo los logos
     abren con 5vh: sumados dan ~20vh y ~19vh de aire a cada lado. */
  padding: clamp(72px, 12vh, 132px) clamp(20px, 6vw, 90px) clamp(84px, 13.5vh, 150px);
  text-align: center;
}
/* el mismo ancho de contenido que tenía la sección (1180 menos su padding),
   para que las tres columnas midan lo mismo que antes (299 px a 1280) */
.res-inner { max-width: calc(1180px - 2 * clamp(20px, 6vw, 90px)); margin: 0 auto; }
#corp-results .kicker { display: inline-block; margin-bottom: clamp(46px, 7.5vh, 82px); }
#corp-results .kicker::after { left: 50%; transform: translateX(-50%); }

.res-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(34px, 5vw, 78px);
  align-items: start;
}
.res-item { display: flex; flex-direction: column; align-items: center; }

/* ---- SEPARADORES: NO. Sólo aire. ----
   Probadas las dos, la decisión es espacio solo, por tres razones concretas:
   · las tres columnas tienen alturas distintas (160, 173 y 175 px de dato, y
     2, 3 y 4 renglones de apoyo), así que una línea vertical a media altura
     quedaría desalineada con todo y una a altura completa dibujaría celdas —
     que es justo el aire de infografía que el brief descarta;
   · CORP ya tiene un idioma de filete: el rojo de 44×2 px bajo cada
     antetítulo. Repetirlo como separador vertical lo devaluaría de acento a
     mobiliario;
   · lo que hace que las tres se lean como hermanas no es una línea, es que
     compartan geometría: misma columna (299 px), mismo índice, la misma caja
     reservada para el dato y las tres líneas de apoyo arrancando en el mismo
     píxel (medido: y=466 en las tres).

   Si en pantalla se prefiere con filete, es una regla: descomentar esto.
   .res-item + .res-item { border-left: 1px solid rgba(11, 11, 12, .09); }
   .res-grid { gap: 0; }
   .res-item { padding: 0 clamp(20px, 3vw, 44px); }
   (y en el bloque móvil: .res-item + .res-item { border-left: 0 }) */

/* El índice NO va en rojo. En "qué hacemos", justo arriba, los 01–04 sí lo
   están; aquí el rojo es del dato y no puede tener con quién competir. Queda
   como una marca de orden, apenas visible. */
.res-idx {
  /* E7F C2: mismo tratamiento que .cap-num, que es el mismo elemento (un
     índice 01–04) en la sección de al lado. Se igualan peso y tracking; el
     tamaño se queda algo menor y el color mucho más tenue a propósito, porque
     aquí el rojo es del dato y el índice no puede competir. */
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: .68rem; letter-spacing: var(--track-label);
  color: rgba(11, 11, 12, .26);
  margin-bottom: clamp(16px, 2.4vh, 26px);
}

.res-dato {
  font-family: var(--font-wordmark);
  font-weight: 600;
  text-transform: uppercase; /* el texto va en caja normal en el HTML: un
                                lector de pantalla no debe deletrear siglas */
  color: var(--red);
  line-height: .95;
  letter-spacing: -0.012em;
  text-wrap: balance; /* reparte los renglones en vez de dejar una viuda */
  font-size: var(--sz);
  /* La caja del dato se reserva IGUAL en los tres, y el dato se centra dentro.
     Es lo que hace que las tres líneas de apoyo arranquen exactamente a la
     misma altura aunque el dato ocupe uno o tres renglones — sin esto las
     columnas se leen como tres cosas sueltas y no como hermanas. */
  min-height: var(--caja);
  display: flex; align-items: center; justify-content: center;
}
.res-item { --caja: clamp(120px, 14.3vw, 190px); }
.res-1 .res-dato { --sz: clamp(1.55rem, 3.13vw, 2.6rem);  max-width: 13ch; }
.res-2 .res-dato { --sz: clamp(4rem, 11.88vw, 9.5rem);    letter-spacing: -0.035em; }
.res-3 .res-dato { --sz: clamp(1.7rem, 3.44vw, 2.85rem);  max-width: 7ch; }

.res-linea {
  margin-top: clamp(18px, 2.6vh, 30px);
  font-weight: 400; /* E17 ⑫ */
  font-size: clamp(.83rem, 1.02vw, .96rem);
  line-height: 1.62;
  color: rgba(11, 11, 12, .62);
  max-width: 30ch;
}

/* ---------- logos v18: two tiers — 3 featured in color + brand marquee ---------- */
#corp-logos {
  max-width: 1160px;
  margin: 0 auto;
  padding-top: var(--sp-md); padding-bottom: var(--sp-lg); /* E17 ⑤ */
  text-align: center;
}
#corp-logos .kicker::after { left: 50%; transform: translateX(-50%); }
.featured-logos {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(44px, 8vw, 120px);
  flex-wrap: wrap;
}
.feat-logo {
  cursor: pointer;
  transition: transform .4s cubic-bezier(.16, 1, .3, 1);
  position: relative;
}
/* v25: clearer affordance — growth plus a red baseline that draws in */
.feat-logo::after {
  content: '';
  position: absolute; left: 50%; bottom: -14px;
  width: 0; height: 2px; background: var(--red);
  transform: translateX(-50%);
  transition: width .35s cubic-bezier(.16, 1, .3, 1);
}
.feat-logo:hover::after { width: 46px; }
.feat-logo img {
  height: clamp(56px, 8.5vw, 96px); /* uniform presence across the three */
  max-width: 300px;
  object-fit: contain;
  /* full color — these are the explorable flagships */
}
/* the ministry's banner reads smaller at equal height — compensate */
.feat-logo[data-case="mtc"] img {
  height: clamp(68px, 10.4vw, 118px);
  max-width: 360px;
}
/* v23: Linio's wide wordmark read heavier than TC/MTC — rein it in and
   lift it slightly so the three baselines sit together */
.feat-logo[data-case="linio"] img {
  height: clamp(44px, 6.6vw, 74px);
  transform: translateY(-4px);
}
.feat-logo:hover { transform: scale(1.11) translateY(-4px); }

/* additional brands: slow grayscale marquee, context only (not clickable) */
#corp-brands {
  padding: var(--sp-md) 0; /* E17 ⑤ */
  overflow: hidden;
  background: var(--paper-2); /* E17 ⑪: segunda banda en el segundo papel */
}
/* E3: `.brands-tag` (la cifra "+15 MARCAS Y CONTANDO") se eliminó — ver
   corp.html. No se reemplaza por otro texto. */
.brand-marquee {
  overflow: hidden;
  /* E17 ⑪: sin hairlines — el cambio de superficie ya separa la franja */
  padding: 4vh 0;
  /* hover enabled for the edge accelerator; images stay inert below */
  /* E8 ⑬: arrastrable. pan-y = la horizontal es arrastre (JS), la vertical
     sigue siendo scroll del navegador. */
  touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
  cursor: grab;
}
.brand-marquee.is-drag { cursor: grabbing; }
.brand-track {
  display: inline-flex; align-items: center;
  gap: clamp(50px, 6.2vw, 96px);
  white-space: nowrap;
  will-change: transform;
}
.brand-track img {
  /* v25: real alpha files — no blend tricks needed. Three weight tiers
     so square marks read as large as the wide wordmarks.
     E8 ⑬: los cuatro escalones bajan un 12% (y el hueco entre marcas un
     11%): entran más marcas en pantalla a la vez. Las proporciones entre
     escalones no cambian. */
  height: clamp(34px, 3.7vw, 46px);
  width: auto; max-width: 220px;
  object-fit: contain;
  filter: grayscale(1) opacity(.6);
  pointer-events: none;
  -webkit-user-drag: none;
}
.brand-track img.bm-mid { height: clamp(42px, 4.75vw, 58px); }
.brand-track img.bm-big { height: clamp(55px, 6.2vw, 78px); }
/* E3: escalón nuevo para Loco Mate, la única pieza vertical del set. Es la
   más alta pero también la más angosta (~84px), así que su área queda por
   debajo de los wordmarks anchos: crece sin dominar. */
.brand-track img.bm-xl { height: clamp(67px, 7.6vw, 95px); }
.brand-track img.bm-white { filter: brightness(0) opacity(.5); }

/* ---------- CTA ---------- */
#corp-cta { padding-top: var(--sp-lg); } /* v19 → E17 ⑤ */
#corp-cta h2 {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(2rem, 4.4vw, 4rem);
  /* E7F 3.4: era el ÚNICO titular Clash del sitio sin line-height declarado —
     heredaba el del cuerpo (~1,5). Hoy no se nota porque cabe en un renglón,
     pero en pantallas estrechas parte en dos y se abre como un párrafo, con
     una separación que no tiene ninguno de sus hermanos. */
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin-bottom: 5vh;
}
.corp-btn {
  display: inline-block;
  /* E17 ⑬: la única acción de la página era un botón fantasma. Apple y
     Ferrari RELLENAN la acción principal: tinta con texto papel (la gramática
     button-dark-utility de Apple), hover a rojo. Sigue habiendo un solo
     acento. ③: 58 px/12,8 px → ~52 px/14 px, tracking .26 → .16em. */
  padding: 18px 40px;
  background: var(--ink); color: var(--paper);
  border: 1px solid var(--ink);
  font-size: .875rem; font-weight: 600; letter-spacing: var(--track-btn);
  transition: background .25s, color .25s, border-color .25s, scale .08s ease-out;
}
.corp-btn:hover { background: var(--red); border-color: var(--red); color: var(--paper); }
.corp-btn:active { scale: .97 !important; } /* E17 ③: pulsación (ver .btn en style.css) */

/* ---------- cierre ---------- */
#corp-close {
  padding: var(--sp-lg) clamp(20px, 6vw, 90px) var(--sp-md); /* E17 ⑤ */
  border-top: 1px solid rgba(11, 11, 12, .08);
}
.close-line {
  font-family: var(--font-wordmark);
  font-weight: 300;
  font-size: clamp(1.4rem, 2.6vw, 2.4rem);
  line-height: 1.2;
  margin-bottom: 6vh;
  opacity: 0; /* scroll reveal */
  translate: 0 30px;
}
.close-line em { font-style: normal; color: var(--red); }
.back-artist-big {
  display: inline-block;
  font-size: .8rem; letter-spacing: var(--track-btn); font-weight: 600;
  padding-bottom: 4px;
  border-bottom: 2px solid var(--red);
  transition: color .2s, letter-spacing .3s;
}
.back-artist-big:hover { color: var(--red); letter-spacing: .22em; }
.corp-foot-meta {
  margin-top: var(--sp-lg);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px;
  font-size: .69rem; letter-spacing: var(--track-label); /* E17 ①: 9,6 → 11 px */
  color: rgba(11, 11, 12, .55);
}

/* ---------- case study modal (in-page, per client) ---------- */
#case-modal {
  position: fixed; inset: 0; z-index: 1100;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden;
  transition: opacity .35s ease, visibility .35s ease;
}
#case-modal.open { opacity: 1; visibility: visible; }
.case-backdrop {
  position: absolute; inset: 0;
  background: rgba(11, 11, 12, .42);
  backdrop-filter: blur(6px);
}
.case-panel {
  position: relative;
  width: min(880px, 92vw);
  background: var(--paper);
  display: grid;
  grid-template-columns: 38% 1fr;
  gap: clamp(20px, 3vw, 44px);
  padding: clamp(28px, 4vw, 56px);
  box-shadow: 0 30px 90px rgba(11, 11, 12, .3);
  transform: translateY(22px) scale(.985);
  transition: transform .35s cubic-bezier(.16, 1, .3, 1);
}
#case-modal.open .case-panel { transform: none; }
.case-panel::before {
  content: '';
  position: absolute; top: 0; left: 0;
  width: 56px; height: 3px; background: var(--red);
}
/* E1 P4: era un glifo suelto que en pantalla chica no se leía como botón.
   Ahora es una pastilla redonda con borde, en la voz limpia de CORP.
   Vive sobre .case-panel (que NO scrollea), así que nunca se va de vista. */
.case-close {
  /* E7F 1.1: misma fuga que .cs-label. El × se pintaba en Arial. */
  font-family: var(--font-wordmark);
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  font-size: 1.5rem; line-height: 1;
  color: rgba(11, 11, 12, .6);
  background: var(--paper);
  border: 1px solid rgba(11, 11, 12, .18);
  border-radius: 50%;
  cursor: pointer;
  transition: color .2s, border-color .2s, transform .25s;
}
.case-close:hover { color: var(--red); border-color: var(--red); transform: rotate(90deg); }
.case-logo {
  display: flex; align-items: center; justify-content: center;
  padding: 8%;
}
.case-logo img { max-width: 100%; max-height: 180px; object-fit: contain; }
.case-logo img.lg-white { filter: brightness(0) opacity(.85); }
.case-logo img.lg-multiply { mix-blend-mode: multiply; }
.case-body { display: flex; flex-direction: column; gap: 18px; }
.case-title {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(1.3rem, 2.2vw, 1.9rem);
  letter-spacing: -0.01em;
}
.case-desc {
  font-weight: 300;
  font-size: clamp(.92rem, 1.2vw, 1.05rem);
  line-height: 1.6;
  color: rgba(11, 11, 12, .75);
  white-space: pre-line; /* the real case copy runs in two paragraphs */
}
.case-media {
  aspect-ratio: 16 / 9;
  background: rgba(11, 11, 12, .05);
  border: 1px dashed rgba(11, 11, 12, .18);
  display: flex; align-items: center; justify-content: center;
  font-size: .69rem; letter-spacing: var(--track-btn);
  color: rgba(11, 11, 12, .4);
  overflow: hidden;
}
/* real project imagery: fills the same 16:9 slot, dashed frame retires */
.case-media.has-img { border: none; background: none; }
.case-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 700px) {
  .logo-grid { grid-template-columns: repeat(2, 1fr); }
  .cap-grid { grid-template-columns: 1fr; gap: 6vh 0; }
  /* tap-to-open, in flow (no floating panels on small screens) */
  .cap-video, .cap:nth-child(even) .cap-video {
    position: static; left: auto; right: auto;
    width: 100%; margin-top: 14px;
    display: none; translate: 0 0;
  }
  /* vertical slot on mobile: centered, never full column width (would tower).
     E1: mismo empate de especificidad — el 02 es hijo par, así que el
     `width:100%` de (0,3,0) le ganaba y la torre 9:16 salía a 611px de alto */
  .cap-video--tall,
  .cap:nth-child(even) .cap-video--tall { width: min(300px, 68vw); margin-left: auto; margin-right: auto; }
  /* the tether bridges a side gap that doesn't exist in the stacked layout */
  .cap-video::before { display: none; }
  /* mismo empate de especificidad que arriba: sin el selector par, 02 y 04
     se quedaban en display:none */
  .cap-video.show,
  .cap:nth-child(even) .cap-video.show { display: flex; opacity: 1; }
  /* E7D móvil: apilados, y cada bloque con su propio aire. El problema
     reportado antes en esta zona era el amontonamiento de las líneas de
     apoyo; la separación entre bloques (gap) es ahora casi el triple que la
     que hay entre el dato y su propia línea, así que cada hito se lee como
     una unidad y no como un párrafo corrido. */
  #corp-results { padding: 8vh clamp(20px, 6vw, 90px) 9vh; }
  #corp-results .kicker { margin-bottom: 4.5vh; }
  .res-grid { grid-template-columns: 1fr; gap: clamp(46px, 6.5vh, 64px); }
  /* la caja fija deja de tener sentido apilado: ahí no hay nada que alinear
     al lado, y reservar 150 px bajo un dato de un renglón sería un agujero */
  .res-item { --caja: 0px; }
  .res-dato { min-height: 0; }
  /* El "2×" sigue siendo el protagónico. Apilado no hay que igualar alturas
     —los bloques se leen uno tras otro, no en fila— así que la referencia es
     la ventaja de cuerpo: medido a 375, 101,3 px contra 28,5 y 31,1 = 3,4×,
     con el 74% de la tinta del bloque más pesado. */
  .res-1 .res-dato { --sz: clamp(1.7rem, 7.6vw, 2.4rem);  max-width: 15ch; }
  .res-2 .res-dato { --sz: clamp(5rem, 27vw, 7.5rem); }
  .res-3 .res-dato { --sz: clamp(1.85rem, 8.3vw, 2.6rem); max-width: 13ch; }
  .res-linea { max-width: 34ch; }
  .corp-hero-copy { bottom: 9vh; }
  /* E4 ③ móvil: el claim y el bloque siguiente también necesitan separarse */
  #corp-position { padding-top: 11vh; }
  #corp-hud { display: none; }
  /* E1 P3: el scroll NO vive en .case-panel sino en .case-body. Si scrollea
     el panel, el botón de cerrar (absolute sobre él) se va con el contenido.
     Así el panel queda fijo, el cuerpo desliza con el dedo y el cierre
     siempre está a la vista. */
  .case-panel {
    grid-template-columns: 1fr;
    /* la 2ª fila (.case-body) toma el resto y PUEDE encoger: con filas `auto`
       el grid las dimensiona por contenido, desbordaba el panel y el
       overflow:hidden recortaba la imagen en vez de dejar scrollear */
    grid-template-rows: auto minmax(0, 1fr);
    max-height: 88vh;
    overflow: hidden;
    padding-top: 60px; /* despeja el botón de cerrar */
  }
  .case-body {
    overflow-y: auto;
    overscroll-behavior: contain; /* no encadena el scroll a la página */
    -webkit-overflow-scrolling: touch;
    min-height: 0; /* sin esto un item de grid no encoge bajo su contenido */
  }
  /* la imagen NO cede: como flex-item se dejaba aplastar a 82px (contra los
     168 de su 16:9) para hacer caber todo sin scroll. Preferimos que
     conserve su proporción y que el cuerpo se deslice. */
  .case-media { flex-shrink: 0; }
  .case-close { width: 46px; height: 46px; font-size: 1.7rem; } /* objetivo táctil ≥44 */
  .case-logo img { max-height: 90px; }
}

/* ============ E2 B.2 — GRANO DE PELÍCULA (voz de CORP) ============ */
/* Sobre una superficie casi blanca `overlay` se apagaría justo donde más
   falta (el papel), así que la mezcla es `multiply`: deja textura sobre el
   blanco y se atenúa sola en las zonas oscuras del cristal — la misma curva
   de película, leída desde el otro extremo del rango.

   E2B: .032 → .06. Sigue siendo la mitad que ARTISTA — este lado no puede
   competir en textura. `multiply` oscurece según la media del ruido, así que
   subir la opacidad tiñe el papel: a .06 el blanco baja ~3% (de 247 a ~240).
   Ése es el número a vigilar; si el cliente lo ve sucio, esta constante es
   el único punto a bajar. */
#corp-grain {
  position: fixed; inset: 0; width: 100%; height: 100%;
  /* E2C: la opacidad final es esta BASE por el multiplicador de sección
     (ver GRAIN_SECTION en corp.js). El hero del cristal se queda en 1.00 —
     el cliente lo dio por perfecto — y el resto baja un 10%. */
  z-index: 900; opacity: calc(.06 * var(--grain-mul, 1)); pointer-events: none;
  mix-blend-mode: multiply;
}

/* ============ v26: MOBILE SCROLL CUE (ink-on-paper voice) ============ */
#m-cue {
  position: fixed; left: 50%; bottom: 16px; z-index: 550;
  display: none; flex-direction: column; align-items: center;
  transform: translateX(-50%);
  pointer-events: none;
  transition: opacity .6s ease;
}
#m-cue .mc-line {
  width: 2px; height: 30px;
  background: linear-gradient(180deg, transparent, var(--ink));
}
/* E13 ⑤: cabeza hacia ARRIBA (el sentido del gesto), el asta cuelga debajo */
#m-cue .mc-arrow {
  width: 9px; height: 9px; margin-bottom: -6px;
  border-left: 2px solid var(--ink);
  border-top: 2px solid var(--ink);
  transform: rotate(45deg);
}
#m-cue .mc-line, #m-cue .mc-arrow { animation: mcPulse 1.7s ease-in-out infinite; }
#m-cue.gone { opacity: 0; }
@keyframes mcPulse { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@media (max-width: 700px) { #m-cue { display: flex; } }

/* ============ E7E — prefers-reduced-motion ============
   Mismo criterio que en ARTISTA (ver style.css): se apaga lo que se mueve
   solo y para siempre —los pulsos del HUD, las barras del botón de sonido, el
   aviso de scroll móvil y la deriva del filo iridiscente de las capacidades—
   y NO se toca el movimiento que responde al scroll del usuario, que aquí es
   el hero entero. La regla del filo ya existía más arriba en el archivo (E7 ①);
   este bloque cubre el resto.

   El cristal del hero es un <video loop>: se pausa desde JS, no desde aquí. */
@media (prefers-reduced-motion: reduce) {
  .cs-bars i,
  .hud-line,
  .hud-tag,
  .hud-arrow,
  #m-cue .mc-line,
  #m-cue .mc-arrow {
    animation: none !important;
  }
  .hud-tag { color: rgba(224, 9, 29, .85); }
  .cs-bars i { transform: scaleY(.62); }
  * { transition-duration: .08s !important; }
}

/* E7G 12 — CRÉDITO SOBRE EL VIDEO DE "MÚSICA & AUDIO".
   La pieza es una publicidad de Linio en la que Epic View grabó y dirigió las
   voces, no el video ni la producción musical. El crédito lo dice sobre la
   propia imagen, en pequeño, y se va con el panel porque vive dentro de él.
   El degradado es lo que garantiza que se lea sobre cualquier fotograma. */
.cap-credito {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 26px 16px 11px;
  font-size: .6rem; font-weight: 400; line-height: 1.35;
  letter-spacing: .04em;
  color: rgba(255, 255, 255, .9);
  text-align: left;
  text-shadow: 0 1px 6px rgba(0, 0, 0, .8);
  background: linear-gradient(to top, rgba(0, 0, 0, .78), rgba(0, 0, 0, .45) 55%, transparent);
  pointer-events: none;
}
/* el marcador de "próximamente" y el crédito no pueden convivir: si no hay
   video, no hay nada que acreditar */
.cap-video.no-video .cap-credito { display: none; }

/* ============ E10 ⑦⑧ — CRISTAL EN TELÉFONO: FRANJA BLANCA Y CRISTAL MENOR ====
   ⑦ A pantalla vertical el video 16:9 se recortaba con object-fit: cover a la
   altura del hero (741): el cristal ocupaba casi todo el ancho y se ampliaba
   (×1,1 en px CSS, ×3,3 en píxeles físicos) — se veía blando. Ahora la
   cabecera es una FRANJA de papel (92 px, la altura del nav más aire) y el
   video vive en una caja más baja debajo: min(48vh, 420px). En esa caja el
   cover ESCALA HACIA ABAJO (×0,56): el cristal mide ~260 px de alto en vez
   de ~520 y cada píxel físico lleva más de un píxel de fuente. La franja no
   se ve "cortada" porque el video lleva una máscara vertical: su borde
   superior e inferior se disuelven a transparente sobre el papel, y el grano
   global lo homogeneiza. El velo radial se ciñe a la misma caja.
   ⑧ Justo debajo, "DESLIZA" con la flecha: el aviso móvil cambia de sitio
   (era una flecha muda al pie) y se va con el primer scroll, como antes. */
/* E11 ①②: la caja mide una FRACCIÓN de --hero-h (px, congelado en corp.js),
   no vh: así no crece al recogerse la barra del navegador. Y sube del 48% del
   viewport al 70% del alto útil bajo la franja (a 659 → 397 px de caja, el
   cristal ~260 px; a 741 → 454 px, ~296): entre un 26 y un 44% más grande que
   la versión "chiquita" (206 px), sin llegar al tamaño original (~520). El
   titular aparece con el scroll —al cargar no está— y cuando entra, el video
   ya se está retirando y apagando, así que pueden compartir la zona baja. */
@media (max-width: 700px) {
  /* E12 ⑦: el papel del hero, apenas más gris (247,245,240 → 242,240,235):
     el fondo del video es un gris de estudio y contra el papel puro el canto
     se sentía duro. Solo el hero, solo teléfono; la paleta no cambia. */
  #corp-hero { height: var(--hero-h, 100vh); background: #f2f0eb; }
  .corp-hero-copy { bottom: calc(var(--hero-h, 100vh) * .09); }
  /* E12 ⑥: caja al 78% del alto útil (+11% de cristal: ~330 px a 741, ~290 a
     660) y el fundido superior más largo (46 → 70 px) */
  #corp-hero .crystal-loop {
    top: 92px; bottom: auto;
    height: calc((var(--hero-h, 100vh) - 92px) * .78);
    scale: 1;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 70px, #000 calc(100% - 56px), transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 70px, #000 calc(100% - 56px), transparent 100%);
  }
  .corp-veil { top: 92px; bottom: auto; height: calc((var(--hero-h, 100vh) - 92px) * .78); transform-origin: 50% 50%; }
  #corp-hero .crystal-loop { transform-origin: 50% 50%; }
  /* E12 ⑧: "DESLIZA" más caleta: letras y flecha en gris neutro claro, asta
     de 60 px, y fundidos largos — entra en 1,6 s (clase .viva, corp.js) y se
     va en 1,4 s con el primer scroll. */
  #m-cue {
    top: calc(92px + (var(--hero-h, 100vh) - 92px) * .78 - 78px); bottom: auto;
    gap: 6px;
    opacity: 0;
    transition: opacity 1.6s ease;
  }
  #m-cue.viva { opacity: 1; }
  #m-cue.gone { opacity: 0; transition-duration: 1.4s; }
  #m-cue .mc-label {
    font-size: .56rem; font-weight: 500; letter-spacing: .34em; padding-left: .34em;
    color: rgba(11, 11, 12, .34);
  }
  #m-cue .mc-line { height: 60px; background: linear-gradient(180deg, rgba(11, 11, 12, .38), transparent); }
  #m-cue .mc-arrow { border-color: rgba(11, 11, 12, .38); }
}

/* ============ E10 ⑨ — FOOTER: EPIC VIEW · INSTAGRAM · CONTACTO ============ */
/* E11 ⑥: en columna, como el footer de ARTISTA — el wordmark grande arriba,
   INSTAGRAM y CONTACTO debajo, todo sobre el mismo margen izquierdo. */
.corp-foot-links {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 14px;
  margin-top: var(--sp-lg);
}
.corp-foot-brand {
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(2.4rem, 7vw, 5.5rem); letter-spacing: .02em; line-height: .9;
  margin-bottom: 14px;
}
.corp-foot-brand sup { color: var(--red); font-size: .6em; }
.corp-foot-links a:not(.corp-foot-brand) {
  font-size: .75rem; letter-spacing: var(--track-label); font-weight: 600;
  color: rgba(11, 11, 12, .75);
  border-bottom: 1px solid transparent;
  transition: color .2s, border-color .2s;
}
.corp-foot-links a:not(.corp-foot-brand):hover { color: var(--red); border-color: var(--red); }
.corp-foot-meta { margin-top: var(--sp-md); }

/* ============ E10 ⑨ — VISOR DEL CORREO, EN PAPEL ============
   El mismo contrato que #mail-modal en ARTISTA (ver style.css), traducido a
   la paleta de este lado: papel, tinta, un filete rojo. */
#mail-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center;
  opacity: 0; transition: opacity .35s ease;
}
#mail-modal[hidden] { display: none; }
#mail-modal.abierto { opacity: 1; }
.mail-backdrop {
  position: absolute; inset: 0;
  background: rgba(247, 245, 240, .86);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.mail-box {
  position: relative;
  width: min(560px, 88vw);
  padding: clamp(34px, 5vw, 56px) clamp(22px, 4vw, 48px) clamp(30px, 4vw, 44px);
  text-align: center;
  background: var(--paper);
  border: 1px solid rgba(11, 11, 12, .12);
  box-shadow: 0 0 0 1px rgba(224, 9, 29, .14), 0 30px 80px rgba(11, 11, 12, .14);
  scale: .97; opacity: 0;
  transition: scale .45s cubic-bezier(.16, 1, .3, 1), opacity .35s ease;
}
#mail-modal.abierto .mail-box { scale: 1; opacity: 1; }
.mail-box::before {
  content: '';
  position: absolute; top: 0; left: 50%; translate: -50% 0;
  width: 56px; height: 2px; background: var(--red);
}
.mail-kicker {
  font-size: .69rem; letter-spacing: .18em; padding-left: .18em;
  color: var(--red);
  margin-bottom: clamp(16px, 2.4vw, 26px);
}
.mail-address {
  display: inline-block;
  font-family: var(--font-wordmark);
  font-weight: 600;
  font-size: clamp(1.25rem, 4.2vw, 2.3rem);
  letter-spacing: .01em; line-height: 1.1;
  color: var(--ink);
  word-break: break-all;
  border-bottom: 1px solid rgba(224, 9, 29, .45);
  padding-bottom: 6px;
  transition: color .25s, border-color .25s;
}
.mail-address:hover { color: var(--red); border-color: var(--red); }
.mail-copy {
  display: inline-flex; align-items: center;
  margin-top: clamp(22px, 3vw, 32px);
  padding: 12px 20px; padding-left: calc(20px + var(--track-btn));
  font-size: .69rem; font-weight: 500; letter-spacing: var(--track-btn);
  color: rgba(11, 11, 12, .7);
  border: 1px solid rgba(11, 11, 12, .22);
  transition: color .25s, border-color .25s;
}
.mail-copy:hover, .mail-copy.listo { color: var(--red); border-color: var(--red); }
.mail-close {
  position: absolute; top: -14px; right: -14px; z-index: 2;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  font-family: var(--font-wordmark);
  font-size: 1.5rem; font-weight: 300; line-height: 1;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid rgba(224, 9, 29, .6);
  border-radius: 50%;
  transition: background .25s, color .25s, border-color .25s, rotate .35s cubic-bezier(.16, 1, .3, 1);
}
.mail-close:hover, .mail-close:focus-visible {
  background: var(--red); color: var(--paper); border-color: var(--red);
  rotate: 90deg; outline: none;
}
@media (max-width: 700px) {
  .mail-close { top: -12px; right: -6px; width: 40px; height: 40px; }
}

/* ============ E14 ② — EL TAJO DE LUZ DEL CORTE ============
   El "efecto de luz" del paso 4 era solo el resplandor del texto rojo y se
   perdía. Ahora, con el corte de sonido, una línea de luz roja CRUZA la
   pantalla de lado a lado a la altura de "sin el ruido.": entra desde la
   izquierda en 0,55 s con un frente brillante, se sostiene y se apaga en
   0,7 s. Va sobre el hero (z 7, encima del titular) y no captura punteros.
   El resplandor del texto sube también (corp-glow). */
.corp-tajo {
  /* dentro de .corp-hero-copy (que va a clamp(20px, 6vw, 90px) del borde):
     se sale hacia la izquierda ese mismo margen y mide el ancho de la pantalla */
  position: absolute; left: calc(-1 * clamp(20px, 6vw, 90px)); width: 100vw; top: 50%; z-index: 7;
  height: 2px; margin-top: -1px;
  pointer-events: none;
  opacity: 0;
  transform: scaleX(0); transform-origin: left center;
  background: linear-gradient(90deg, rgba(224, 9, 29, .35), var(--red) 40%, #ff4a5c 92%, #fff 100%);
  box-shadow: 0 0 10px 1px rgba(224, 9, 29, .85), 0 0 34px 6px rgba(224, 9, 29, .45), 0 0 90px 18px rgba(224, 9, 29, .22);
}
.corp-tajo.va { animation: corp-tajo 1.5s cubic-bezier(.2, 0, .1, 1) 1 forwards; }
@keyframes corp-tajo {
  0%   { opacity: 1; transform: scaleX(0); }
  36%  { opacity: 1; transform: scaleX(1); }
  60%  { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1); }
}
.corp-hero-copy h1 em.glow-in { animation: corp-glow 1500ms cubic-bezier(.4, 0, .3, 1) 1; }
@keyframes corp-glow {
  0%   { text-shadow: 0 0 18px rgba(224, 9, 29, .25); }
  40%  { text-shadow: 0 0 22px rgba(224, 9, 29, 1), 0 0 48px rgba(224, 9, 29, .85), 0 0 110px rgba(224, 9, 29, .5); }
  100% { text-shadow: 0 0 18px rgba(224, 9, 29, .25); }
}
@media (prefers-reduced-motion: reduce) {
  .corp-tajo.va { animation: none; opacity: 0; }
}

/* ============ E14 ③ — LAS CAPACIDADES DICEN QUE SE PUEDEN PULSAR ============
   En teléfono no hay hover (el filo prismático solo vive con ratón) y el "+"
   gris pasaba desapercibido: nadie tocaba los títulos. El título lleva ahora
   un filete rojo debajo —el mismo recurso de la casa (antetítulos, ENTRAR, el
   correo del visor)— y el "+" se dibuja en rojo. En escritorio igual, para
   que las dos versiones digan lo mismo; el hover sigue sumando su filo. */
.cap h3 {
  display: inline-block;
  /* E18 ①: el filete rojo bajo el título se RETIRA (cliente: "no se ve
     bien" — sobresalía del anillo por la derecha y duplicaba el marco). El
     inline-block se queda: es lo que ciñe el anillo al texto. */
}
.cap::after {
  color: var(--red);
  border-color: rgba(224, 9, 29, .6);
  width: 28px; height: 28px;
}

/* ============ E16 ① — SIN BOTÓN DE PLAY DE iOS EN LOS VIDEOS DE FONDO ====
   WebKit pinta un "play" gigante sobre cualquier <video> inline que esté
   pausado y sin `controls` — y nuestros videos de fondo se pausan a
   propósito (el cristal en el corte, el cubo tras la carta) o porque el Modo
   de Bajo Consumo les niega el autoplay. El glifo es un pseudo-elemento de
   la interfaz nativa: se apaga aquí. Los videos CON controles (el visor del
   reel) conservan su interfaz. */
video:not([controls])::-webkit-media-controls-start-playback-button { display: none !important; -webkit-appearance: none; }
video:not([controls])::-webkit-media-controls { display: none !important; }

/* ============ E17 ④ — FOCO DE TECLADO, UNA SOLA REGLA ============
   Antes solo tres controles tenían :focus-visible; el resto caía en el
   anillo azul del navegador, ajeno a la paleta. Un filete rojo separado del
   elemento (el único acento) para todo lo que se pueda enfocar. Los
   controles con su propio foco (portada, cierre del reel, del correo) siguen
   mandando por especificidad. */
:where(a, button, [tabindex]):focus-visible { outline: 1px solid var(--red); outline-offset: 4px; }

/* ============ E24 — GATE DE ENTRADA TÁCTIL (solo pointer: coarse) ============
   El nodo lo crea corp.js únicamente con pointer: coarse; estas reglas viven
   bajo la misma consulta por si acaso. Vidrio grueso: desenfoque (backdrop,
   GPU) + un tinte de papel casi nulo; la ondulación va en el propio video
   (filtro SVG #gate-vidrio) mientras la capa está puesta. */
@media (pointer: coarse) {
  #corp-gate {
    position: fixed; inset: 0; z-index: 480; /* bajo el nav (500): la marca queda nítida y usable */
    display: grid; place-items: center;
    touch-action: none; overscroll-behavior: none;
    cursor: pointer;
    -webkit-backdrop-filter: blur(var(--gate-blur, 12px)) saturate(1.06);
            backdrop-filter: blur(var(--gate-blur, 12px)) saturate(1.06);
    background: rgba(247, 245, 240, var(--gate-alfa, .2));
  }
  html.corp-gate-activa #corp-hero .crystal-loop { filter: url(#gate-vidrio); }
  /* el botón: vidrio sobre vidrio. Translúcido, filete finísimo, un
     highlight arriba que sugiere volumen; ninguna sombra dura. Se ve chico
     (11,5 px de tinta) pero el área táctil es de 48 px de alto. */
  #corp-gate-btn {
    -webkit-appearance: none; appearance: none;
    min-width: 44px; min-height: 48px;
    padding: 14px 28px 14px calc(28px + .32em);
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .62);
    background: rgba(255, 255, 255, .26);
    -webkit-backdrop-filter: blur(12px) saturate(1.1);
            backdrop-filter: blur(12px) saturate(1.1);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, .78),
      inset 0 -1px 0 rgba(11, 11, 12, .035),
      0 1px 2px rgba(11, 11, 12, .05);
    font-family: var(--font-body);
    font-size: .72rem; font-weight: 600; line-height: 1;
    letter-spacing: .32em; text-transform: uppercase;
    color: var(--ink);
    cursor: pointer;
    transition: scale .12s ease-out, background .2s;
    will-change: opacity;
  }
  #corp-gate-btn:active { scale: .97; background: rgba(255, 255, 255, .34); }
  #corp-gate-btn:focus-visible { outline: 1px solid var(--red); outline-offset: 5px; }
}
@media (prefers-reduced-motion: reduce) {
  html.corp-gate-activa #corp-hero .crystal-loop { filter: none; }
}
