/* base.css — reset, tipografía autoalojada, grano, retícula y utilidades (§8.3, §8.4, §8.5, §8.10).
   Regla: aquí no hay un solo color literal; todo sale de tokens.css (R6).
   Regla: el atributo `style` está prohibido en todo el proyecto (R8, §7.6) — se usa clase o --propiedad. */

/* ======================================================================
   1 · Tipografía autoalojada (§8.3, §8.11.14: nunca por CDN)
   Los woff2 viven en /fuentes/ y la CSP mantiene font-src 'self'.
   ====================================================================== */

@font-face {
  font-family: 'Playfair Display';
  src: url('/fuentes/playfair-display-v37-latin-700.woff2?v=02af2688') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Playfair Display';
  src: url('/fuentes/playfair-display-v37-latin-italic.woff2?v=3fcf735f') format('woff2');
  font-weight: 700; font-style: italic; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  src: url('/fuentes/inter-v20-latin-400.woff2?v=c9407645') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  src: url('/fuentes/inter-v20-latin-500.woff2?v=c9407645') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  src: url('/fuentes/inter-v20-latin-600.woff2?v=c9407645') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191,
                 U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ======================================================================
   2 · Reset mínimo
   ====================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--papel);
  color: var(--tinta-suave);
  font-family: var(--f-interfaz);
  font-size: var(--t-base);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }
fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; }
hr { border: 0; border-top: var(--filete); margin: var(--e-6) 0; }

/* ======================================================================
   3 · Tipografía de uso (§8.3.2 — la tabla se implementa tal cual)
   ====================================================================== */

/* Un titular display NUNCA parte una palabra: el deck no tiene ni un «HISTORI-A» ni un
   «OPORTUNIDADE-S». `body` hereda `overflow-wrap: break-word` (correcto para cuerpo de
   texto y URLs); aquí se revierte a `normal` y se prohíbe la partición automática.
   `text-wrap: balance` reparte las líneas; donde no exista (Safari < 17.5, Firefox < 121)
   el titular sigue cabiendo porque el tamaño es fluido — es una mejora, no un requisito. */
.display, h1, h2, h3 {
  font-family: var(--f-display);
  font-weight: 700;
  color: var(--tinta);
  text-transform: uppercase;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: manual;
  text-wrap: balance;
}

/* `--t-h1` y `--t-h2` son clamps (tokens.css): a 390 px el H1 baja a 36 px y el H2 a
   28 px, así que el titular de sección nunca pesa más que el de la pantalla. */
h1 { font-size: var(--t-h1); letter-spacing: -.015em; line-height: .94; }
h2 { font-size: var(--t-h2); letter-spacing: -.01em;  line-height: 1.02; }
h3 { font-size: var(--t-h3); letter-spacing: 0;       line-height: 1.1; }

h4 {
  font-family: var(--f-display);
  font-size: var(--t-h4);
  font-weight: 700;
  letter-spacing: .04em;
  line-height: 1.15;
  font-variant-caps: small-caps;
  color: var(--tinta);
}

/* H1 del héroe: las líneas del deck, las dos últimas en oro. Debe caber a 320 px (§8.3.2).
   El tamaño NO es `--t-hero` (36 → 104 px): con 104 px la línea más larga del deck
   («INFORMACIÓN EN», «FUENTE DE VALOR.») desbordaba la columna de texto del héroe, que
   mide 730 px a 1 440. El techo baja a 46 px: a ese tamaño las cuatro líneas del deck
   entran enteras desde 390 px, que es lo que el héroe promete.
   La cota se escribe aquí y no en tokens.css porque `--t-hero` no la usa nadie más. */
.hero__titulo {
  font-family: var(--f-display);
  font-size: clamp(2.25rem, 3.2vw, 2.875rem);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: .94;
  text-transform: uppercase;
  text-wrap: balance;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: manual;
  margin: 0;
}
.hero__linea { display: block; color: var(--tinta); }
.hero__linea--oro { color: var(--oro); }

/* Los <br> del deck sólo a partir de 620 px: por debajo el texto fluye (§8.3.2). */
.hero__titulo .salto { display: none; }
@media (min-width: 620px) {
  .hero__titulo .salto { display: block; }
}

.eyebrow {
  font-family: var(--f-interfaz);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: .24em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--gris-humo);
  margin: 0;
}

.lead {
  font-size: var(--t-lead);
  font-weight: 400;
  line-height: 1.5;
  color: var(--tinta-tenue);
  max-width: 34ch;
}

/* Un titular pegado a su bajada: los `p` llevan `margin: 0` del reinicio, así que en un
   contenedor de bloque el H1 y el párrafo siguiente se TOCABAN (medido: 0 px en
   /mi-conductor y /app/conductores). El aire se declara una sola vez, aquí. */
:is(h1, .hero__titulo) + p { margin-block-start: var(--e-4); }
/* …salvo en una FILA: ahí el párrafo va AL LADO del titular (el contador de
   /app/mis-videos), el aire lo pone el `gap` y el margen sólo lo descolgaba. */
.fila > :is(h1, .hero__titulo) + p { margin-block-start: 0; }

.cuerpo { font-size: var(--t-base); line-height: 1.65; }
.cuerpo-largo { font-size: var(--t-cuerpo); line-height: 1.7; max-width: var(--ancho-lectura); }
.menor { font-size: var(--t-menor); color: var(--gris-humo); line-height: 1.5; }
.micro { font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--gris-humo); }

.cifra {
  font-family: var(--f-display);
  font-size: var(--t-cifra);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1;
  color: var(--tinta);
}

/* §8.10: ningún texto en --oro por debajo de 20 px. Esta clase sólo se aplica
   a titulares y cifras; nunca a cuerpo pequeño ni a insignias. */
.oro { color: var(--oro); }
.tinta { color: var(--tinta); }
.tenue { color: var(--tinta-tenue); }
.humo { color: var(--gris-humo); }

.medida { max-width: 60ch; }   /* medida corta 45–60 caracteres (§8.1.3) */

/* ======================================================================
   4 · Retícula y contenedores (§8.4)
   ====================================================================== */

.contenedor {
  width: 100%;
  max-width: var(--ancho-maximo);
  margin-inline: auto;
  padding-inline: var(--canal);
}
.contenedor--lectura  { max-width: calc(var(--ancho-lectura) + var(--canal) * 2); }
.contenedor--estrecho { max-width: calc(var(--ancho-estrecho) + var(--canal) * 2); }

.seccion { padding-block: var(--ritmo-seccion); }
.seccion--hundida { background: var(--papel-hundido); }
.seccion--negra { background: var(--tinta); color: var(--papel); }
.seccion--negra h1, .seccion--negra h2, .seccion--negra h3, .seccion--negra h4 { color: var(--papel); }

/* Ritmo vertical por punto de corte (§8.4) */
@media (max-width: 1023px) { :root { --ritmo-seccion: var(--e-8); } }
@media (max-width: 619px)  { :root { --ritmo-seccion: var(--e-7); } }

.rejilla { display: grid; gap: var(--e-6); }
.rejilla--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rejilla--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.rejilla--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.rejilla--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.rejilla--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }

@media (max-width: 1023px) {
  .rejilla--3, .rejilla--4, .rejilla--5, .rejilla--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 619px) {
  .rejilla--2, .rejilla--3, .rejilla--4, .rejilla--5, .rejilla--6 { grid-template-columns: minmax(0, 1fr); }
}

.pila { display: flex; flex-direction: column; }
.pila--1 { gap: var(--e-1); } .pila--2 { gap: var(--e-2); } .pila--3 { gap: var(--e-3); }
.pila--4 { gap: var(--e-4); } .pila--5 { gap: var(--e-5); } .pila--6 { gap: var(--e-6); }
.pila--7 { gap: var(--e-7); } .pila--8 { gap: var(--e-8); }

.fila { display: flex; align-items: center; gap: var(--e-4); flex-wrap: wrap; }
.fila--entre { justify-content: space-between; }
.fila--fin { justify-content: flex-end; }
.fila--centro { justify-content: center; }
.fila--arriba { align-items: flex-start; }

/* El enlace que cierra una rejilla («Ver planes», «Ver todos los formatos») iba pegado
   al borde inferior de las tarjetas: a 1 440 px el botón quedaba a 7 px de la tarjeta
   destacada y se leía como si la pisara. Una rejilla y su enlace de cierre no se tocan. */
.fila--tras-rejilla { margin-top: var(--e-7); }

/* ======================================================================
   5 · Grano, luz y textura (§8.5)
   ====================================================================== */

.grano::after {
  content: '';
  position: fixed; inset: 0;
  background-image: url('/img/grano.png?v=e6dc6299');   /* 160×160 px, ruido monocromo, se repite */
  background-repeat: repeat;
  opacity: .045;                              /* >.07 se ve sucio; <.03 no se percibe */
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: var(--z-grano);
}

.halo-calido {
  background: radial-gradient(60% 45% at 88% 4%,
              var(--halo-oro-fuerte) 0%,
              var(--halo-oro-nulo) 70%);
}

/* Viñeta FOTOGRÁFICA (oscurecimiento de los bordes de una imagen), no un bullet de lista.
   El nombre corto `.vineta` se prestaba a lo segundo y acabó en un <ul> de /formatos con
   una banda gris tras cada ítem; el sufijo cierra la ambigüedad. */
.vineta-foto { box-shadow: inset 0 0 180px var(--vineta-interior); }

/* ======================================================================
   6 · Decoración editorial (§8.4) — nunca contenido necesario
   ====================================================================== */

.filete-corto { width: 40px; height: 1px; background: var(--oro); border: 0; margin: 0; }
.filete-corto--centro { margin-inline: auto; }

.rail-vertical {
  writing-mode: vertical-rl;
  font-size: var(--t-micro);
  font-weight: 400;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gris-humo);
  /* Un texto en vertical crece en ALTO, no en ancho: sin acotarlo se salía por el borde
     inferior del viewport y la cita de /formatos quedaba cortada. */
  max-block-size: 100%;
  overflow: hidden;
}
/* Dentro de un `rail-vertical` la cita hereda el modo vertical: su `font-size` de titular
   la desbordaba. Se acota al alto disponible y se deja que rompa por palabras. */
.rail-vertical .cita {
  font-size: var(--t-h4);
  max-block-size: 100%;
  overflow-wrap: break-word;
  hyphens: auto;
}

.micro-bloque {
  border-left: 1px solid var(--oro-badge);
  padding-left: var(--e-3);
  font-size: var(--t-micro);
  letter-spacing: .18em;
  text-transform: uppercase;
  line-height: 1.7;
  color: var(--tinta-tenue);
  /* El claim son TRES líneas cortas, una por `<span><br>`, y TRES es el número del deck:
     `white-space: nowrap` las fija —ninguna se parte en dos— y el ancho pasa a ser el de
     la línea más larga («MEJORES DECISIONES.», 14.77 em a 11 px ≈ 163 px). El `max-width`
     es el tope duro que impide que un texto editado desde /admin empuje a la cabecera.
     `flex-shrink: 0` impide que la cabecera lo siga estrujando al crecer los vecinos. */
  white-space: nowrap;
  max-width: 22ch;
  flex-shrink: 0;
  overflow-wrap: normal;
  hyphens: none;
}

/* El micro-bloque es lo primero que sobra cuando la cabecera se estrecha: por debajo de
   1 280 px no cabe junto al menú y el CTA (el botón «CREAR MI NOTA» se salía del viewport
   y provocaba scroll horizontal). No usa `.solo-amplio` (1 440 px) porque a 1 280–1 439
   sí hay sitio para las tres líneas con el menú ya compactado. */
.micro-bloque { display: none; }
@media (min-width: 1280px) { .micro-bloque { display: block; } }

/* Los rails desaparecen por debajo de `amplio` (§8.4). */
.solo-amplio { display: none; }
@media (min-width: 1440px) { .solo-amplio { display: block; } }
.solo-escritorio { display: none; }
@media (min-width: 1024px) { .solo-escritorio { display: block; } }
.solo-movil { display: block; }
@media (min-width: 1024px) { .solo-movil { display: none; } }

.barra-negra {
  background: var(--tinta);
  color: var(--papel);
  padding-block: var(--e-6);
  text-align: center;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: var(--t-h3);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-variant-caps: small-caps;
}

.cita {
  font-family: var(--f-display);
  font-style: italic;
  font-weight: 700;
  font-size: var(--t-h3);
  line-height: 1.25;
  text-transform: none;
  /* Lógicas, no físicas: la misma cita se pinta en vertical (writing-mode) en el rail
     del deck y ahí el filete tiene que seguir yendo al principio de la lectura. */
  border-inline-start: 2px solid var(--oro);
  padding-inline-start: var(--e-5);
  color: var(--tinta);
}

/* ======================================================================
   7 · Movimiento: estado previo al reveal (§8.6.4)
   Sin FOUC: .revelable nace invisible y movimiento.js lo libera.

   El `opacity: 0` SÓLO se aplica bajo `.con-js`, una clase que pone un script
   con nonce en `cabeza.ejs`. Sin JavaScript la regla no llega a existir y nada
   queda invisible — sin necesitar un `<noscript><style>`, que `style-src 'self'`
   bloquearía sin error visible (§7.6). El temporizador de seguridad de 1.5 s de
   movimiento.js cubre el caso de que GSAP cargue mal.
   ====================================================================== */

/* El `opacity: 0` se acota al LAYOUT PÚBLICO, que es el único que carga
   `movimiento.js` (`cabeza.ejs` lo condiciona a `layout === 'publico'`) y por tanto el
   único donde alguien añade `.revelado`. Sin esa acotación, un `.revelable` en /app,
   /admin o en el layout desnudo quedaba invisible para siempre. La clase
   `pagina--<layout>` la escribe `cabeza.ejs` en las cuatro superficies. */
.con-js .pagina--publico .revelable,
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea,
.con-js .pagina--publico [data-mov="rejilla"] > * {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .9s cubic-bezier(.22, .61, .36, 1), transform .9s cubic-bezier(.22, .61, .36, 1);
}
.con-js .pagina--publico [data-mov="filete"] { transform: scaleX(0); transform-origin: left center; transition-duration: .8s; transition-delay: .5s; }
.con-js .pagina--publico [data-mov="barra"]  { transform: scaleX(0); transform-origin: center center; }
.con-js .pagina--publico [data-mov="foto"]   { transform: scale(1.06); transition-duration: 1.4s; }
.con-js .pagina--publico [data-mov="mockup"] { transform: translateY(40px) rotate(1.5deg); transition-duration: 1.4s; }
.con-js .pagina--publico [data-mov="entrada"] { transition-delay: .7s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea { transition-duration: 1.2s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea:nth-child(2) { transition-delay: .12s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea:nth-child(3) { transition-delay: .24s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea:nth-child(4) { transition-delay: .36s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea:nth-child(5) { transition-delay: .48s; }
.con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea:nth-child(6) { transition-delay: .60s; }
/* `--i` lo escribe movimiento.js#escalonar; tope 11 → 1.1 s. */
.con-js .pagina--publico [data-mov="rejilla"] > * { transition-delay: calc(var(--i, 0) * .1s); }

/* Estado revelado: la clase la pone movimiento.js (al cargar o al entrar en viewport). */
.con-js .pagina--publico .revelable.revelado,
.con-js .pagina--publico [data-mov].revelado,
.con-js .pagina--publico [data-mov="hero-titulo"].revelado .hero__linea,
.con-js .pagina--publico [data-mov="rejilla"].revelado > * { opacity: 1; transform: none; }

/* Las tres vías de escape van a la MISMA especificidad (0-2-0 ó mayor) que la regla
   de arriba: con 0-1-0 perdían la cascada y no rescataban nada. */
.revelado,
.sin-movimiento .revelable,
.sin-movimiento [data-mov],
.sin-movimiento [data-mov="hero-titulo"] .hero__linea,
.sin-movimiento [data-mov="rejilla"] > *,
.con-js .pagina--publico .revelado { opacity: 1; transform: none; }


.sin-movimiento *,
.sin-movimiento *::before,
.sin-movimiento *::after {
  animation: none !important;    /* §8.11.17: el !important sólo se autoriza aquí */
  transition: none !important;
}

/* `prefers-reduced-motion` NO puede depender de JavaScript: `.sin-movimiento` sólo la
   pone `movimiento.js`, que sólo se carga en el sitio público, y /app y /admin quedaban
   sin honrar la preferencia (§8.10, §8.6.4 no admiten excepción por superficie).
   Las declaraciones se duplican aquí, donde sólo manda el medio. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation: none !important;    /* §8.11.17: el !important sólo se autoriza aquí */
    transition: none !important;
  }

  .revelable,
  .con-js .pagina--publico .revelable,
  .con-js .pagina--publico [data-mov],
  .con-js .pagina--publico [data-mov="hero-titulo"] .hero__linea,
  .con-js .pagina--publico [data-mov="rejilla"] > * { opacity: 1; transform: none; transition: none; }
}

/* ======================================================================
   8 · Utilidades de accesibilidad (§8.10)
   ====================================================================== */

.visualmente-oculto {
  position: absolute !important;   /* §8.11.17: autorizado en utilidades de accesibilidad */
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.saltar-al-contenido {
  position: absolute;
  left: var(--e-4); top: calc(var(--e-4) * -4);
  z-index: calc(var(--z-modal) + 1);
  background: var(--tinta);
  color: var(--papel);
  padding: var(--e-3) var(--e-5);
  font-size: var(--t-menor);
  letter-spacing: .12em;
  text-transform: uppercase;
  transition: top .18s ease;
}
.saltar-al-contenido:focus { top: var(--e-4); }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--tinta);
  outline-offset: 2px;
}

/* Objetivos táctiles de 44×44 px mínimo (§8.10). */
.objetivo-tactil { min-width: 44px; min-height: 44px; display: inline-flex;
                   align-items: center; justify-content: center; }

@media print {
  .grano::after, .no-imprimir { display: none; }
  body { background: none; color: var(--tinta); }
}
