/* ============================================================================
   TIPOGRAFÍA — carácter editorial. Space Grotesk display + Inter cuerpo (marca)
   + Space Mono para el "estrato instrumento" (índices, eyebrows, datos).
   Regla del kit: máximo 2 pesos por contexto. Cargar tras base.css.
   ============================================================================ */

.t-mega {
  font-family: var(--font-display);
  font-weight: 700;   /* tope de Space Grotesk variable (300-700) */
  font-size: var(--fs-mega);
  line-height: 0.86;
  letter-spacing: var(--tracking-mega);
  text-wrap: balance;
}
.t-hero {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-hero);
  line-height: 0.94;
  letter-spacing: var(--tracking-hero);
}
.t-section {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-section);
  line-height: 1.02;
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
.t-statement {
  font-family: var(--font-display);
  font-weight: 500;
  /* Escala section (change escala-editorial-display): el análogo proporcional de los beats de
     75px de topology; el rescate móvil del token section aplica solo. */
  font-size: var(--fs-section);
  line-height: 1.1;
  letter-spacing: var(--tracking-tight);
  text-wrap: pretty;
}
.t-body {
  font-family: var(--font-body);   /* Inter: la prosa de lectura es del cuerpo, no del display */
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 46ch;
}
.t-body strong { color: var(--ink); font-weight: 600; }

/* Estrato instrumento: mono, mayúsculas, tracking abierto. Eyebrows, índices, meta. */
.t-label {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--fs-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-3);
}
.t-label--accent { color: var(--accent-bright); }
/* El rotulo de seccion pesa mas que su propio indice y que los eyebrows (change
   titulo-de-seccion-con-jerarquia). Selector acotado al h2 del head: gana por especificidad
   sobre .t-label, sin !important, y no alcanza al nav ni a los botones, que siguen en el
   token compartido porque son chrome, no contenido. */
/* El indice y el rotulo son un PAR en la misma linea, alineados por linea base: suben juntos
   (change indice-hace-par-con-el-rotulo). Dejarlos con 3px de diferencia no producia jerarquia
   entre ellos, producia desajuste, y en numerales monoespaciados se nota mas porque los digitos
   son estrechos. La distincion dentro del par la sostienen el peso 700 y el color de acento del
   indice, no el tamano.
   Los otros indices YA NO se quedan en el token chico, y este comentario decia lo contrario: los
   7 pasos del proceso subieron a --fs-step-index (18px) y el indice del aside pinneado a
   --fs-display-index (22.5px a 1440), cada uno dimensionado contra el titulo que acompana. En el
   token de label quedan solo el nav y el drawer, que son chrome. La regla del sistema, en una
   linea: un numeral de CONTENIDO escala con su titulo; uno de CHROME no. */
.section__head h2.t-label,
.section__head .t-index { font-size: var(--fs-section-label); }
.t-index {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--fs-label);
  letter-spacing: 0.1em;
  color: var(--accent);
}

/* Registro CAPTION (tipografia-contratos): frases de caption de mas de 6 palabras. Viste
   JUNTO a .t-label en el DOM (los selectores de layout siguen anclando en .t-label); esta
   regla, mas tardia en la cascada, corrige la tipografia: cuerpo, sentence case, tracking
   normal. El registro label queda para labels de verdad (cortos). */
.t-caption {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  letter-spacing: 0.01em;
  text-transform: none;
}

.accent { color: var(--accent-bright); }

/* --- Máscara de reveal por línea: el hijo sube desde abajo; el contenedor recorta. --- */
.line { display: block; overflow: hidden; }
.line > span { display: block; will-change: transform; }
/* Estado inicial SOLO cuando el motion está encendido y JS aún no revela.
   Se oculta por OPACIDAD (no por transform): así gsap es el único dueño del transform
   y no se componen dos translate. Con motion apagado o sin JS, el texto se ve completo. */
html.motion-on .reveal-lines .line > span,
html.motion-on .reveal-mask { opacity: 0; }
/* Failsafe de arranque (change lcp-movil-revelado; una-sola-rama por el change
   entrada-que-no-pierde-la-carrera): si los vendors tardan, el CSS revela solo, animando
   SOLO opacidad (el transform sigue siendo de GSAP: cero shift). Hero corto (0.5 s), resto
   global (2.2 s). Las .hero__phrase del pin NO participan (su opacity: 0 vive en layout.css
   y es propiedad de las escenas).
   Presupuestos DECLARADOS CON SU MEDICIÓN (2026-08-02, localhost, 3 corridas por motor):
   el CSS termina en 43-69 ms en ambos motores y los vendors en 46-108 ms; el motor toma
   control en 251-559 ms en Chromium y en 1,567-11,458 ms en WebKit (lo variable es la
   ejecución del grafo de módulos ES, no el CSS ni los vendors). El hero de 0.5 s cubre a
   Chromium con margen; en WebKit el failsafe gana hoy, y eso YA NO elige una rama de
   página: scroll.js adopta bloque por bloque lo revelado y orquesta lo oculto. */
@keyframes reveal-failsafe { to { opacity: 1; } }
html.motion-on .reveal-lines .line > span,
html.motion-on .reveal-mask { animation: reveal-failsafe 0.5s 2.2s both; }
html.motion-on .hero .reveal-lines .line > span,
html.motion-on .hero .reveal-mask { animation: reveal-failsafe 0.35s 0.5s both; }
/* El motor al llegar toma la propiedad de TODA la opacidad (js-take): cancela los failsafe
   pendientes de lo que va a orquestar. Lo ya revelado se adoptó ANTES con opacidad inline,
   en el mismo task (sin paint intermedio: nada parpadea al cancelar). Las reglas del hero
   se repiten con su selector completo A PROPÓSITO: la cancelación genérica (3 clases,
   0,3,2) PERDÍA contra el failsafe del hero (4 clases, 0,4,2) y el hero nunca se cancelaba
   en la rama rápida — bug de especificidad cazado por el panel del 2026-08-02. */
html.js-take .reveal-lines .line > span,
html.js-take .reveal-mask { animation: none; }
html.js-take .hero .reveal-lines .line > span,
html.js-take .hero .reveal-mask { animation: none; }
/* (Aquí vivían html.hero-revealed y html.page-revealed, las dos ramas del sello global.
   Retiradas por entrada-que-no-pierde-la-carrera: la adopción es por bloque, no por página.) */
/* El elemento LCP (el lead del hero) NUNCA se oculta: se pinta visible desde el primer frame
   y su entrada anima solo transform en el motor (transform no cuenta para CLS ni para LCP).
   Es la diferencia entre LCP ~2 s y ~4 s en 4G (medido en el apply de lcp-movil-revelado). */
html.motion-on .hero__lead.reveal-mask { opacity: 1; animation: none; }
