/* ══════════════════════════════════════════════════
   RUTA EDUCATIVA — SECCIONES DE LA PORTADA

   Solo lo que usa index.html. Los tokens, la base, el
   header, el FAQ, las tarjetas de guía y el footer viven
   en site.css y se comparten con el resto del sitio.
   Cargar SIEMPRE después de site.css.
══════════════════════════════════════════════════ */

/* Flotación de las tarjetas del hero. Solo las usa esta hoja.
   La regla global de prefers-reduced-motion en site.css las anula. */
@keyframes floaty { 0%,100% { translate: 0 0; } 50% { translate: 0 -10px; } }
@keyframes drift  { 0%,100% { translate: 0 0; rotate: 0deg; } 50% { translate: 0 -14px; rotate: -1.2deg; } }

/* ══════════════════════════════════════════════════
   HERO

   MOBILE FIRST de verdad: la composición base es la de un teléfono
   (una columna, escena vertical, dos tarjetas) y el @media (min-width:
   1180px) de más abajo es el que arma la escena de escritorio completa
   — dos columnas, cuatro tarjetas flotantes, el lienzo apaisado. No al
   revés: nada aquí parte de un layout de escritorio para reducirlo.
══════════════════════════════════════════════════ */
/* Tokens propios de la portada. El resto del sitio no los usa, por eso
   viven aquí y no en site.css. */
.hero {
  --hero-card-bg: light-dark(oklch(1 0 0 / 0.86), oklch(0.245 0.018 260 / 0.85));
  min-height: 0;
  display: flex;
  align-items: center;
  padding: clamp(20px, 4vh, 56px) clamp(16px, 4vw, 40px) clamp(48px, 9vh, 104px);
}
/* En escritorio es más ancho que .wrap (1240): la escena necesita el
   aire de la referencia, y con el ancho normal las tarjetas quedaban
   tan estrechas que su contenido dejaba de leerse. En móvil, una sola
   columna a lo ancho del hero. */
/* Tres celdas con nombre (no dos): título+párrafo, botones y escena
   viven cada uno en su propia área de rejilla, así que el orden visual
   sale de dónde los coloca el mapa de abajo y no de en qué orden
   aparecen en el HTML — el DOM los sigue trayendo en el orden de
   lectura de siempre (copy → cta → stage), solo cambia dónde se pintan. */
.hero__grid {
  position: relative;
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "copy"
    "stage"
    "cta";
  gap: clamp(24px, 5vh, 44px);
  align-items: center;
}
.hero__copy { grid-area: copy; max-width: 640px; container-type: inline-size; }
.hero__cta { grid-area: cta; }
.hero h1 {
  font-size: clamp(34px, 12.5cqw, 58px);
  line-height: 1.02;
  letter-spacing: -0.035em;
  margin: 0 0 24px;
  /* Evita la línea huérfana sin igualar el largo de todas: con "balance"
     el titular caía en un renglón suelto de una sola palabra. Sustituye a
     los <br> forzados, que rompían la composición en móvil. */
  text-wrap: pretty;
}
.hero h1 em { font-style: normal; color: var(--brand); }
.hero__lead {
  font-size: clamp(15px, 4.2cqw, 18px);
  line-height: 1.55;
  color: var(--muted);
  margin-bottom: 34px;
  max-width: 46ch;
}
/* En móvil los botones se apilan a lo ancho; en escritorio vuelven a
   ser una fila (@media min-width:640px más abajo). */
.hero__cta { display: flex; flex-direction: column; align-items: stretch; gap: 12px; flex-wrap: wrap; }
.hero__cta .btn { flex: 1 1 auto; }

/* ── Escena ──────────────────────────────────────────
   Lienzo de proporción fija: todo lo de dentro se coloca en % sobre él,
   así la composición es la misma a cualquier ancho. Las tarjetas, en
   cambio, escalan su contenido con su propio ancho (unidades cq), no con
   el del lienzo: eso permite agrandarlas en móvil sin que la letra se
   quede en 6px. --mx/--my las escribe site.js con el puntero.
   En móvil el lienzo es vertical (4:5) y solo caben dos tarjetas; en
   escritorio (@media min-width:1180px) pasa a apaisado (5:4) con las
   cuatro. El tope en svh evita que en una tablet alta la escena se
   coma dos pantallas antes de la primera sección. */
.hero__stage {
  grid-area: stage;
  position: relative;
  aspect-ratio: 3 / 4;
  width: min(100%, 520px, calc(64svh * 0.8));
  margin: 0 auto;
  --mx: 0;
  --my: 0;
}
/* La ilustración es el asset oficial a color (hero-graduado-01.svg): ya
   trae su propia mancha azul de fondo, así que la imagen ES el fondo de
   la escena — no hay un blob aparte detrás. object-fit:contain evita
   deformarla; su proporción real (1774×1536) manda sobre el ancho, no
   sobre el alto, al revés que la silueta anterior.
   La imagen es apaisada: en el lienzo vertical de móvil se contiene por
   ANCHO, no por alto, así que ensancharla es lo que agranda al graduado.
   object-fit siempre muestra el archivo completo (nunca recorta), así
   que para que la cara quede POR ENCIMA de la tarjeta de notas en vez de
   detrás, el truco es alejar el borde inferior de la caja del borde
   inferior del lienzo (bottom > 0): el cuerpo/toga puede seguir tapado
   por la tarjeta —es la capa de "flotante" que ya trae el hero—, la
   cara no. */
.hero__figure {
  position: absolute;
  left: 0;
  right: auto;
  top: auto;
  bottom: 42%;
  width: 92%;
  height: 62%;
  object-fit: cover;
  object-position: 0% 100%;
  --d: 6px;
  transform: translate(calc(var(--mx) * var(--d)), calc(var(--my) * var(--d)));
  transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
}
/* Dos SVG en el mismo lugar (misma clase .hero__figure, mismo cuadro),
   uno visible a la vez según el tema — mismo mecanismo que ya usan las
   ilustraciones de .bento-card__art. Se apilan con opacity en vez de
   display para poder cruzarlas: la transición la pone .theme-switching
   en site.css, así que aquí solo se fija el estado final. */
.hero__figure--dark { opacity: 0; }
:root[data-scheme="dark"] .hero__figure--light { opacity: 0; }
:root[data-scheme="dark"] .hero__figure--dark { opacity: 1; }
/* Los mismos trazos sueltos que la ilustración lleva junto al puño,
   repetidos junto al titular y al otro costado de la escena — pero solo
   hay sitio para ese segundo trazo en la escena apaisada de escritorio
   (@media min-width:1180px lo vuelve a mostrar). */
.hero__spark {
  display: none;
  position: absolute;
  right: 1%;
  top: 44%;
  width: 6%;
  color: var(--brand);
  opacity: 0.9;
  rotate: 128deg;
  animation: floaty 7s ease-in-out infinite;
}
.hero__spark--copy {
  position: static;
  display: block;
  width: clamp(26px, 2.2vw, 34px);
  margin-bottom: clamp(14px, 1.6vh, 20px);
  rotate: -14deg;
  animation: none;
}

/* ── Tarjetas ────────────────────────────────────────
   Ilustraciones en HTML/CSS, no capturas: pesan cero, siguen el tema
   claro/oscuro por tokens y cada tarjeta es un elemento real.
   Cristal, no superficie sólida: flotan sobre la mancha de color.
   --dw es el ancho (en px) al que se diseñó la tarjeta; --u vale 1px
   justo a ese ancho y encoge o crece con ella, así que todo lo de dentro
   se escribe en px de diseño × --u.
   Ojo: --u solo lo pueden usar los hijos. En la propia tarjeta, las
   unidades cq se resuelven contra el contenedor de más arriba (aquí,
   ninguno: el viewport) y salen valores absurdos. Por eso el relleno va
   en .hc-pad, ya dentro de la tarjeta, y no en la tarjeta. */
.hero-card {
  position: absolute;
  container-type: inline-size;
  --u: calc(100cqw / var(--dw));
  --d: 14px;
  background: var(--hero-card-bg);
  border: 1px solid var(--glass-line);
  border-radius: clamp(10px, 1.1vw, 16px);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: var(--sh-lg), inset 0 1px 0 var(--glass-sheen);
  overflow: hidden;
  transform: translate(calc(var(--mx) * var(--d)), calc(var(--my) * var(--d)));
  transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.hero-card .label {
  font-size: calc(var(--u) * 10);
  letter-spacing: 0.12em;
}
.hc-pad { padding: calc(var(--u) * 13) calc(var(--u) * 15); }

/* ·· Cuaderno de notas ·· */
.hero-card--notas {
  left: 0;
  top: auto;
  bottom: 0%;
  width: min(84%, 340px);
  --dw: 300;
  --d: 10px;
  animation: drift 11s ease-in-out infinite;
}
.hc-head {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 8);
  padding: calc(var(--u) * 12) calc(var(--u) * 15);
  border-bottom: 1px solid var(--line-2);
}
.hc-head b { font-size: calc(var(--u) * 12); font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }
.hc-tag {
  margin-left: auto;
  font-size: calc(var(--u) * 10);
  padding: calc(var(--u) * 3) calc(var(--u) * 8);
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand-ink);
  white-space: nowrap;
}
.hc-dot {
  width: calc(var(--u) * 7);
  height: calc(var(--u) * 7);
  border-radius: 50%;
  background: var(--brand);
  display: block;
  flex: 0 0 auto;
}

.hc-cols, .hc-row {
  display: grid;
  grid-template-columns: 1.6fr 0.7fr 0.7fr 1.15fr;
  align-items: center;
  gap: calc(var(--u) * 8);
  padding: calc(var(--u) * 9) calc(var(--u) * 15);
  font-size: calc(var(--u) * 12);
}
.hc-cols {
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-3);
  font-family: 'IBM Plex Mono', monospace;
  font-size: calc(var(--u) * 9);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-3);
}
.hc-cols i { display: block; font-style: normal; color: var(--brand); letter-spacing: 0.06em; }
.hc-row { border-top: 1px solid var(--line-3); color: var(--ink-2); }
.hc-row > span:first-child { white-space: nowrap; }
.hc-row > span:nth-child(2), .hc-row > span:nth-child(3) { color: var(--muted); }

/* Chip de nivel: el color no es el único indicador, el texto lo nombra. */
.lvl {
  display: inline-flex;
  align-items: baseline;
  gap: calc(var(--u) * 6);
  font-weight: 600;
  justify-self: end;
}
.lvl i {
  font-style: normal;
  font-weight: 500;
  font-size: calc(var(--u) * 9.5);
  padding: calc(var(--u) * 2) calc(var(--u) * 7);
  border-radius: 999px;
}
.lvl--alto     { color: var(--brand-ink); }
.lvl--alto i   { background: var(--brand-soft); }
.lvl--bajo     { color: var(--bad); }
.lvl--bajo i   { background: var(--bad-bg); color: var(--bad-ink); }
.lvl--basico   { color: var(--warn-ink); }
.lvl--basico i { background: var(--warn-bg); color: var(--warn-ink); }
.lvl--superior   { color: var(--ok-ink); }
.lvl--superior i { background: var(--ok-bg); color: var(--ok-ink); }

/* ·· Periodos del año ··
   Sin sitio en la escena vertical de móvil (solo caben dos tarjetas):
   oculta por defecto, entra con las demás en el @media min-width:1180px. */
.hero-card--periodos {
  display: none;
  left: 77.5%;
  top: 13%;
  width: 19%;
  --dw: 186;
  --d: 20px;
  animation: floaty 8s ease-in-out infinite;
}
.hero-card--periodos .label { margin-bottom: calc(var(--u) * 10); }
.hc-per {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--u) * 8);
  padding: calc(var(--u) * 6) 0;
  font-size: calc(var(--u) * 11);
  color: var(--ink-2);
  border-top: 1px solid var(--line-3);
}
.hc-per span:first-child { white-space: nowrap; }
.hc-per:first-of-type { border-top: none; }
.pill {
  font-size: calc(var(--u) * 9.5);
  padding: calc(var(--u) * 2) calc(var(--u) * 8);
  border-radius: 999px;
  white-space: nowrap;
}
.pill--ok   { background: var(--ok-bg);   color: var(--ok-ink); }
.pill--warn { background: var(--warn-bg); color: var(--warn-ink); }

/* ·· Cierre de periodo ·· */
.hero-card--cierre {
  left: auto;
  right: 0;
  top: 8%;
  width: min(46%, 180px);
  --dw: 196;
  --d: 18px;
  box-shadow: var(--sh-dark), inset 0 1px 0 var(--glass-sheen);
  animation: floaty 9.5s ease-in-out infinite 1s;
}
.hc-big {
  display: flex;
  align-items: baseline;
  gap: calc(var(--u) * 8);
  margin: calc(var(--u) * 8) 0 calc(var(--u) * 12);
}
.hc-big b {
  font-size: calc(var(--u) * 30);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ok-ink);
}
.hc-big span { font-size: calc(var(--u) * 11); color: var(--muted-2); }
.hc-bar { height: calc(var(--u) * 6); border-radius: 999px; background: var(--warn-bg); overflow: hidden; }
.hc-bar i { display: block; height: 100%; width: 96%; background: var(--ok); border-radius: 999px; }

/* ·· Indicadores ··
   Igual que .hero-card--periodos: sin sitio en móvil, entra en el
   @media min-width:1180px de más abajo. */
.hero-card--kpis {
  display: none;
  left: 72%;
  top: 61%;
  width: 21%;
  --dw: 195;
  --d: 24px;
  animation: drift 12s ease-in-out infinite 0.6s;
}
.hero-card--kpis .hc-pad { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--u) * 12); }
.hc-kpi b {
  display: block;
  font-size: calc(var(--u) * 24);
  font-weight: 600;
  letter-spacing: -0.03em;
  margin-top: calc(var(--u) * 2);
}

/* ── Saltos del hero ─────────────────────────────────
   A partir de aquí se SUMA, no se resta: los botones vuelven a ser una
   fila apenas caben cómodos, y a partir de ~1180 hay aire para la
   escena apaisada completa con sus cuatro tarjetas — por debajo de eso,
   dos columnas dejarían la escena tan estrecha que sus tarjetas ya no
   se leerían, así que la composición de escritorio empieza ahí. */
@media (min-width: 640px) {
  .hero__cta { flex-direction: row; align-items: center; }
  .hero__cta .btn { flex: 0 0 auto; }
}

@media (min-width: 1180px) {
  .hero { min-height: 84svh; }
  /* El mínimo de la columna de texto es el ancho al que los dos botones
     siguen cabiendo en una fila; por debajo, el hero ya se apila.
     Dos filas ahora en la columna de texto (título+párrafo arriba,
     botones abajo) y la escena ocupando ambas al lado — mismo mapa que
     en móvil, solo que "cta" y "stage" cambian de sitio entre sí.
     row-gap en 0 porque la separación entre párrafo y botones la sigue
     poniendo el margin-bottom de .hero__lead, igual que antes de haber
     vuelto "cta" una celda propia de la rejilla — si no, se sumarían
     las dos y quedaría el doble de aire del que había.
     "stage" abarca las dos filas de texto, y como de las dos suele ser
     la más alta, la rejilla infla ambas filas para darle sitio — eso
     es lo normal en una rejilla. El problema es solo dónde cae ese
     aire de más: sin fijarlo, align-items:center (heredado de la base)
     lo repartía dentro de CADA fila por separado, metiendo un hueco
     entre el párrafo y los botones que antes no existía (cuando
     "copy" era una sola celda con los botones ya dentro, no había dos
     filas que inflar). Pegando "copy" al final de su fila y "cta" al
     principio de la suya, las dos quedan una junto a la otra através
     del row-gap de siempre — el aire de más se va arriba del título y
     debajo de los botones, no entre medio. */
  .hero__grid {
    grid-template-columns: minmax(420px, 0.78fr) minmax(0, 1.22fr);
    grid-template-areas:
      "copy stage"
      "cta  stage";
    column-gap: clamp(28px, 4vw, 56px);
    row-gap: 0;
  }
  .hero__copy { max-width: 620px; align-self: end; }
  .hero__cta { align-self: start; }
  /* El ancho manda sobre el alto, pero nunca tanto como para empujar los
     botones fuera de la pantalla: en un portátil bajo la escena encoge
     entera (el alto sale de la proporción) en vez de alargar el hero. */
  .hero__stage { aspect-ratio: 5 / 4; width: min(100%, calc(72svh * 1.25)); margin-inline: auto; }
  /* object-fit vuelve a contain: el recorte de móvil (cover, para
     agrandar al graduado dentro de un lienzo angosto) no aplica aquí —
     en la escena apaisada de escritorio hay aire de sobra y la
     ilustración se muestra completa, como siempre. */
  .hero__figure {
    left: -6%; right: auto; top: 3%; bottom: auto; width: 106%; height: 90%;
    object-fit: contain; object-position: left bottom;
  }
  .hero__spark { display: block; }
  /* bottom:auto es necesario y no cosmético: con top Y bottom fijados a
     la vez en un elemento absoluto de alto automático, el navegador
     estira la tarjeta para llenar la distancia entre los dos en vez de
     dejar que su contenido decida el alto. */
  .hero-card--notas { left: 40%; top: 20%; bottom: auto; width: 36%; }
  .hero-card--cierre { left: 47%; top: 60%; width: 22%; }
  /* Ya hay sitio para las cuatro sin encimarlas. */
  .hero-card--periodos,
  .hero-card--kpis { display: block; }
}

/* ══════════════════════════════════════════════════
   GUÍAS (sección de la portada)
   .guias__grid y .guia-card son compartidas → site.css
══════════════════════════════════════════════════ */
.guias { padding-top: clamp(40px, 7vh, 80px); padding-bottom: clamp(40px, 7vh, 80px); }
.guias__intro { max-width: 620px; margin-bottom: clamp(24px, 4vh, 40px); }
/* El h2 de este cierre pesa menos que un .h2 de sección normal: es un
   teaser hacia /guias/, no el titular de una sección nueva. */
.guias__intro h2 { font-size: clamp(26px, 3.2vw, 38px); margin-top: 18px; }
.guias__intro p { margin-top: 14px; }
.guias__intro p a { font-size: 14px; font-weight: 500; }

/* ══════════════════════════════════════════════════
   CARACTERÍSTICAS — liquid glass premium

   Sigue el tema del sitio (light-dark() en cada token), pero con una
   temperatura propia: no reutiliza --bg/--dark globales, porque esta
   sección necesita sentirse un peldaño "más producto" que el resto de
   la portada — casi negro azulado en oscuro, blanco azulado en claro,
   nunca los grises neutros del sitio base. Todo vive en variables
   propias (--feat-*) para no tocar ningún otro bloque.

   Un solo acento (azul de marca) para las seis, no uno por tarjeta:
   la variedad la da el TAMAÑO de cada una en la rejilla (ver
   .feat__grid) y su propio micro-gráfico, no un arcoíris de hues — el
   mismo criterio que ya usa .bento__grid con los roles.

   Vidrio en dos capas de opacidad (--feat-card-bg / --feat-card-bg-2):
   la protagonista y las dos anchas del cierre llevan la capa más
   sólida porque cargan más contenido; las cuatro satélites, la más
   translúcida. Es la misma idea de "superficie física" del brief:
   variarla un poco entre tarjetas da profundidad sin añadir sombra.

   MOBILE FIRST: las reglas sin @media son el layout de un teléfono
   (una columna) y cada @media (min-width) SUMA columnas.
══════════════════════════════════════════════════ */
.feat {
  /* Fondo: casi negro azulado en oscuro (nunca negro puro), blanco
     azulado en claro — más frío que --bg del sitio a propósito. */
  --feat-bg: light-dark(#f7f9fc, #05070b);
  --feat-ink: light-dark(oklch(0.2 0.03 258), oklch(0.97 0.006 258));
  --feat-text: light-dark(oklch(0.42 0.025 258), oklch(0.7 0.02 258));
  --feat-accent: light-dark(var(--brand), oklch(0.76 0.1 262));
  --feat-icon-bg: light-dark(oklch(0.92 0.03 262 / 0.6), oklch(1 0 0 / 0.06));
  --feat-icon-line: light-dark(oklch(0.7 0.09 262 / 0.4), oklch(1 0 0 / 0.12));
  /* Vidrio: blanco translúcido en claro; en oscuro, los tres tonos de
     panel casi negros que pide el brief (#101722 / #121A27 / #161F2D),
     en rgba para poder apilarlos sobre el fondo y entre sí. */
  --feat-card-bg: light-dark(rgba(255, 255, 255, 0.58), rgba(16, 23, 34, 0.6));
  --feat-card-bg-2: light-dark(rgba(255, 255, 255, 0.74), rgba(22, 31, 45, 0.68));
  --feat-card-line: light-dark(rgba(37, 70, 150, 0.16), rgba(140, 172, 255, 0.16));
  --feat-card-line-hover: light-dark(rgba(37, 70, 150, 0.34), rgba(140, 172, 255, 0.32));
  --feat-card-sheen: light-dark(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.09));
  --feat-track: light-dark(rgba(24, 46, 100, 0.12), rgba(255, 255, 255, 0.09));
  --feat-chip-bg: light-dark(rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.06));
  --feat-line-2: light-dark(rgba(37, 70, 150, 0.12), rgba(140, 172, 255, 0.12));
  /* Sombra ambiental: mucho más suave y difusa que --sh-dark del sitio,
     para no caer en el "sombra pesada" que pide evitar el brief. */
  --feat-shadow: light-dark(0 40px 70px -46px rgba(24, 50, 110, 0.35), 0 40px 80px -40px rgba(0, 0, 0, 0.7));
  position: relative;
  overflow: clip;
  background: var(--feat-bg);
  color: var(--feat-ink);
}
/* Atmósfera: manchas de azul extremadamente tenues detrás de la
   rejilla, en los DOS temas (a diferencia de la versión anterior, que
   solo las encendía en oscuro) — el brief pide justo esto en claro:
   "pequeñas zonas de azul atmosférico detrás de algunas cards". */
.feat__halo {
  position: absolute;
  inset: -6% -10% auto -10%;
  height: 78%;
  background:
    radial-gradient(40% 55% at 16% 12%, light-dark(oklch(0.9 0.05 262 / 0.5), oklch(0.32 0.1 262 / 0.4)) 0%, transparent 70%),
    radial-gradient(32% 46% at 92% 4%, light-dark(oklch(0.92 0.04 262 / 0.32), oklch(0.28 0.08 262 / 0.28)) 0%, transparent 72%);
  pointer-events: none;
}
.feat__wrap { position: relative; }

/* ~40% del .wrap (1240px) en escritorio: columna editorial angosta a
   propósito, no un titular a todo el ancho — el aire a su derecha es
   parte de la composición, no un descuido. Por debajo de eso el valor
   deja de importar (el bloque ya es más angosto que 560px solo). */
.feat__head { position: relative; max-width: 560px; }

/* Va ANTES del titular a propósito: promesa corta, luego el titular
   grande, luego el enlace de salida — sin eyebrow, sin nada delante. */
.feat__lead {
  margin: 14px 0 0;
  font-size: clamp(15px, 1.4vw, 17px);
  line-height: 1.6;
  color: var(--feat-text);
  max-width: 46ch;
}

/* El titular: el elemento gráfico de la sección. Gana protagonismo por
   escala fluida (clamp), tracking negativo y peso alto — nunca por
   invadir el espacio de otro elemento. */
.feat__title {
  margin: 18px 0 0;
  font-size: clamp(36px, 9vw, 98px);
  line-height: 0.98;
  letter-spacing: -0.04em;
  font-weight: 650;
}
.feat__title em { font-style: normal; color: var(--feat-accent); }

.feat__more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 22px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--feat-text);
}
.feat__more:hover { color: var(--feat-ink); }
.feat__more span { display: inline-block; transition: translate .2s ease; }
.feat__more:hover span { translate: 3px 0; }

/* Rejilla: una columna en móvil, en el mismo orden en que se lee la
   protagonista → detalle → cierre. Los pasos a 2 y 4 columnas están
   más abajo, en los @media (min-width). */
.feat__grid {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "hero"
    "tall"
    "role"
    "log"
    "promote";
  gap: 16px;
  margin-top: clamp(32px, 9vw, 48px);
}

/* ── Columna "Notas" + "Estructura" ──
   Un solo item de rejilla (grid-area: tall) que por dentro se reparte
   en flex: 60% para Notas, 40% para Estructura — ver el comentario en
   el HTML. El gap repite el de .feat__grid para que la costura entre
   ambas quede igual a la que separa cualquier otro par de tarjetas.
   En móvil (una sola columna) "tall" es una fila normal de alto
   automático: ahí las dos tarjetas solo se apilan con su alto natural
   (flex por defecto). El reparto 60/40 con flex-basis:0 necesita un
   alto ya definido para repartir — eso solo existe desde 640px, donde
   "tall" pasa a ocupar dos filas de la rejilla (ver los @media más
   abajo); min-height:0 va junto porque si no, el alto de contenido
   mínimo de cada tarjeta le gana al reparto igual. */
.feat-col--notas {
  grid-area: tall;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

@media (min-width: 640px) {
  .feat-col--notas .feat-card--tall { flex: 3 1 0; min-height: 0; }
  .feat-col--notas .feat-card--structure { flex: 2 1 0; min-height: 0; }
}

.feat-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: 28px;
  padding: clamp(22px, 2vw, 30px);
  background: var(--feat-card-bg);
  border: 1px solid var(--feat-card-line);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  /* Tres capas: sombra ambiental muy difusa afuera, un brillo interior
     arriba (el "reflejo" del vidrio) y un trazo casi invisible abajo
     que le da grosor a la superficie sin oscurecerla. */
  box-shadow:
    var(--feat-shadow),
    inset 0 1px 0 var(--feat-card-sheen),
    inset 0 -1px 0 light-dark(rgba(24, 50, 110, 0.06), rgba(0, 0, 0, 0.35));
  transition: transform .3s cubic-bezier(.2, .8, .3, 1), border-color .25s ease, box-shadow .25s ease,
              opacity .6s ease var(--reveal-delay, 0s), translate .6s ease var(--reveal-delay, 0s);
}
.feat-card:hover { transform: translateY(-3px); border-color: var(--feat-card-line-hover); }
.feat-card__top { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.feat-card__icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: 11px;
  background: var(--feat-icon-bg);
  border: 1px solid var(--feat-icon-line);
  color: var(--feat-accent);
}
.feat-card__icon svg { width: 18px; height: 18px; display: block; }

/* ── Iconos con gesto propio ──────────────────────────
   Dos disparadores distintos, a propósito:
   - .feat-ico__draw y .feat-ico__seal (el chequeo del sello, el check
     del escudo, la línea de tendencia) se dibujan/aparecen con el mismo
     .is-in que ya revela la tarjeta — funcionan igual en un teléfono
     sin mouse. Sin .js (JS apagado) o con menos movimiento, se ven
     completos de una vez: es progresivo, igual que .feat__grid arriba.
   - El resto (barras, capas, la manecilla) es un empujón extra SOLO al
     pasar el cursor: el reposo ya se lee completo sin él, así que en
     móvil no falta nada por no tener hover. */
.js .feat-ico__draw {
  stroke-dasharray: 12;
  stroke-dashoffset: 12;
  transition: stroke-dashoffset .5s ease .15s;
}
.js .feat-ico__seal { transform-box: fill-box; transform-origin: 50% 50%; transform: scale(.4); transition: transform .4s ease .15s; }
.js .feat__grid[data-reveal].is-in .feat-ico__draw { stroke-dashoffset: 0; }
.js .feat__grid[data-reveal].is-in .feat-ico__seal { transform: scale(1); }

.feat-ico__bar { transition: transform .3s cubic-bezier(.3, .7, .4, 1); transform-box: fill-box; transform-origin: 50% 100%; }
.feat-card:hover .feat-ico__bar { transform: scaleY(1.1); }

.feat-ico__hand { transition: transform .3s ease; transform-box: view-box; transform-origin: 16.6px 15.8px; }
.feat-card:hover .feat-ico__hand { transform: rotate(24deg); }

.feat-ico__layer-top,
.feat-ico__layer-bottom { transition: transform .3s ease; transform-box: fill-box; transform-origin: 50% 50%; }
.feat-card:hover .feat-ico__layer-top { transform: translateY(-1.6px); }
.feat-card:hover .feat-ico__layer-bottom { transform: translateY(1.6px); }

@media (prefers-reduced-motion: reduce) {
  .feat-ico__draw, .feat-ico__seal,
  .feat-ico__bar, .feat-ico__hand,
  .feat-ico__layer-top, .feat-ico__layer-bottom { transition: none; }
  .js .feat-ico__draw { stroke-dashoffset: 0; }
  .js .feat-ico__seal { transform: scale(1); }
}
.feat-card__tag {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--feat-text);
  opacity: .75;
}
.feat-card h3 { font-size: clamp(17px, 1.5vw, 20px); letter-spacing: -0.02em; color: var(--feat-ink); }
.feat-card p { font-size: 14px; line-height: 1.55; color: var(--feat-text); margin-top: 8px; max-width: 34ch; }

/* ── 01 · Boletines automáticos: la protagonista ──
   Vidrio más sólido (--feat-card-bg-2) y el único acento a todo color:
   es quien manda en la rejilla y su acento tiene que leerse primero.
   El anillo (.feat-ring) es su único elemento gráfico — el mismo dato
   que el "52" de al lado, dibujado, no una ilustración aparte. */
.feat-card--hero {
  --feat-icon-bg: light-dark(oklch(0.85 0.06 262 / 0.55), oklch(0.5 0.13 262 / 0.24));
  --feat-icon-line: light-dark(oklch(0.64 0.12 262 / 0.5), oklch(0.72 0.11 262 / 0.4));
  grid-area: hero;
  background: var(--feat-card-bg-2);
  border-color: light-dark(rgba(60, 100, 200, 0.28), rgba(140, 172, 255, 0.24));
}
.feat-card--hero h3 { font-size: clamp(22px, 2vw, 28px); }
.feat-card--hero p { max-width: 38ch; }
/* La ilustración vive en el mismo aire que ya dejaba la card (entre el
   párrafo y la fila de "52"/anillo, ver .feat-hero__body): flujo
   normal, alineada a la derecha con align-self — nunca se recorta ni
   se sale de la tarjeta en ningún ancho. Es el mismo dibujo de marca
   que .feat-card__art (trazo en --brand, ver docente-blue-2-01.svg),
   pero a diferencia de esa card no lleva plancha detrás: ya viene
   coloreado para leerse solo sobre el vidrio.
   El contenedor fija el tamaño real (ancho + aspect-ratio cuadrado, a
   juego con los 1080×1080 de los SVG) y queda position:relative para
   que las dos imágenes (clara/oscura) se apilen una sobre otra ahí
   dentro — el cruce por opacity (ver más abajo) las necesita en el
   mismo sitio, no una debajo de la otra en el flujo. */
/* El mínimo manda en móvil (una sola columna, tarjeta a todo el ancho
   del wrap): con 132px de tope la ilustración de "Notas" y "Todo queda
   registrado" quedaba perdida en tanto aire. 208px sigue siendo el
   techo real en escritorio (la rejilla de 3-4 columnas ya la deja
   justa ahí), así que solo se nota el cambio por debajo de ~490px de
   ancho de viewport, que es donde vivía el problema. */
.feat-card__illustration {
  position: relative;
  /* Centrada en móvil (una sola columna: no hay "derecha" contra la que
     alinear, solo aire disparejo a los lados) — vuelve a flex-end desde
     tablet, donde ya hay una rejilla de verdad. */
  align-self: center;
  width: clamp(208px, 44vw, 216px);
  aspect-ratio: 1 / 1;
  margin: 10px 0 0;
}
@media (min-width: 640px) {
  .feat-card__illustration { align-self: flex-end; }
}
/* La protagonista tiene casi el doble de ancho y alto que cualquier
   otra tarjeta con ilustración: el mismo tope de 208px la dejaba
   perdida en tanto aire. Aquí crece mucho más — es la tarjeta ancla,
   así que su dibujo es el elemento más grande e imponente de la
   rejilla, y centrado (no pegado a la derecha) para que domine el aire
   de la tarjeta en vez de esconderse en una esquina.
   El propio SVG (docente-blue-2-01.svg) trae de fábrica un margen
   vertical grande dentro de su lienzo 1080×1080 — a este tamaño se
   nota como aire de sobra encima y debajo del personaje. En vez de un
   cuadrado exacto, el contenedor usa una proporción 5:4 (más bajo que
   ancho) con object-fit:cover: recorta ese margen sobrante arriba y
   abajo sin tocar los lados, donde el dibujo ya viene más ajustado.
   (El contenido real del SVG mide ~76% del lienzo en alto — pasar de
   5:4 a algo más agresivo como 4:3 empieza a comerse la cabeza/los
   pies, así que este es el límite seguro.) */
.feat-card--hero .feat-card__illustration {
  align-self: center;
  width: clamp(280px, 48vw, 520px);
  aspect-ratio: 5 / 4;
  overflow: hidden;
}
.feat-card--hero .feat-card__illustration img { object-fit: cover; }
.feat-card__illustration img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* El azul de marca del dibujo pierde luminosidad sobre el vidrio casi
   negro del tema oscuro (mismo criterio que ya usan los logos del
   footer): un empujón leve, no un dibujo aparte. */
:root[data-scheme="dark"] .feat-card__illustration img { filter: brightness(1.3) saturate(1.1); }
/* Antes con margin-top:auto se clavaba al fondo de la tarjeta — con
   la ilustración ya grande, en pantallas anchas eso dejaba un hueco
   feo entre el dibujo y esta fila. Ahora va justo debajo, a una
   distancia fija; si a la tarjeta le sobra alto (la fila de la
   rejilla es más alta que el contenido) ese aire queda al final,
   después del anillo, no partiendo el dibujo de la fila de datos. */
.feat-hero__body { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin-top: 24px; }
.feat-meter { flex: 1 1 auto; min-width: 0; }
.feat-meter__row { display: flex; align-items: baseline; gap: 10px; }
.feat-meter__row b { font-size: clamp(34px, 3vw, 46px); font-weight: 600; letter-spacing: -0.03em; color: var(--feat-ink); }
.feat-meter__row span { font-size: 13px; color: var(--feat-text); }
/* "Extremadamente fina": 3px, no una barra de progreso convencional. */
.feat-meter__bar { height: 3px; margin-top: 14px; border-radius: 999px; background: var(--feat-track); overflow: hidden; }
.feat-meter__bar i { display: block; height: 100%; width: 96%; border-radius: 999px; background: var(--feat-accent); }
.feat-meter__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--feat-ink);
  background: var(--feat-chip-bg);
  border: 1px solid var(--feat-icon-line);
}
.feat-meter__badge em { font-style: normal; color: var(--feat-accent); }
/* El anillo: mismo lenguaje que .feat-meter__bar (un solo trazo, el
   acento de marca), solo que en forma de dial — el micro-gráfico de
   "control" que pide el brief, sin ser una ilustración figurativa. */
.feat-ring { width: clamp(58px, 8vw, 84px); height: auto; flex: 0 0 auto; overflow: visible; }
.feat-ring__track { fill: none; stroke: var(--feat-track); stroke-width: 6; }
.feat-ring__value {
  fill: none;
  stroke: var(--feat-accent);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-dasharray: 320.4;
  stroke-dashoffset: 320.4;
  transform-box: fill-box;
  transform-origin: 50% 50%;
  transform: rotate(-90deg);
  transition: stroke-dashoffset 1s ease .2s;
}
.js .feat__grid[data-reveal].is-in .feat-ring__value { stroke-dashoffset: 25.6; }
@media (prefers-reduced-motion: reduce) {
  .feat-ring__value { transition: none; stroke-dashoffset: 25.6; }
}

/* ── 02 · Notas: tarjeta alta con su propia mini-interfaz ──
   En vez de una ilustración, tres barras con su promedio — la prueba
   visual de "los promedios se calculan solos", no una decoración. */
.feat-card--tall { background: var(--feat-card-bg-2); }
/* Solo en móvil "Notas" puede crecer más que el tamaño compartido de
   .feat-card__illustration: ahí es, junto con "Todo queda registrado",
   la única tarjeta de su columna, así que le sobra alto para una
   ilustración más grande. Desde tablet (640px) esta regla ya no
   aplica y vuelve al tamaño de siempre. */
@media (max-width: 639px) {
  .feat-card--tall .feat-card__illustration { width: min(272px, 68vw); }
}
.feat-grades { margin-top: auto; padding-top: 22px; display: flex; flex-direction: column; gap: 11px; }
.feat-grades__row { display: flex; align-items: center; gap: 10px; }
.feat-grades__row i {
  position: relative;
  flex: 1 1 auto;
  height: 4px;
  border-radius: 999px;
  background: var(--feat-track);
  overflow: hidden;
}
.feat-grades__row i::after {
  content: "";
  position: absolute;
  inset: 0;
  width: var(--w, 60%);
  border-radius: inherit;
  background: var(--feat-accent);
}
.feat-grades__row b {
  flex: 0 0 auto;
  width: 2.6em;
  text-align: right;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  font-weight: 500;
  color: var(--feat-ink);
}

/* ── 03 · Acceso por rol: red de nodos ──
   Un hub y cuatro satélites — rectoría, docentes, estudiantes,
   familias — sin etiquetas: la tarjeta ya los nombra en el texto. */
.feat-card--role { grid-area: role; }
.feat-nodes { width: 100%; height: auto; margin-top: auto; padding-top: 16px; overflow: visible; }
.feat-nodes__link { fill: none; stroke: var(--feat-card-line); stroke-width: 1.4; }
.feat-nodes__hub { fill: var(--feat-accent); transition: transform .3s ease; transform-box: fill-box; transform-origin: 50% 50%; }
.feat-nodes__dot { fill: light-dark(oklch(0.82 0.04 262), oklch(0.42 0.05 262)); stroke: var(--feat-card-bg); stroke-width: 3; }
.feat-card:hover .feat-nodes__hub { transform: scale(1.18); }
@media (prefers-reduced-motion: reduce) { .feat-nodes__hub { transition: none; } }

/* ── 04 · Todo queda registrado ── */
.feat-card--log { grid-area: log; }

/* ── 05 · Estructura académica: ahora en la columna de "Notas"
   (ver .feat-col--notas), a un 40% de su alto — .feat-card--wide queda
   como el estilo compartido de "vidrio más sólido" que también usa
   Promoción, sin posicionamiento propio. ── */
.feat-card--wide { background: var(--feat-card-bg-2); }
.feat-tags { margin-top: auto; padding-top: 18px; display: flex; flex-wrap: wrap; gap: 8px; }
.feat-tags span {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 11px;
  border-radius: 999px;
  color: var(--feat-text);
  background: var(--feat-chip-bg);
  border: 1px solid var(--feat-line-2);
}

/* ── 06 · Promoción automática: a todo el ancho de su fila ──
   Única ilustración que sobrevive de la versión anterior (el asset
   oficial de Promoción). Con la tarjeta a fila completa ya no hace
   falta contenerla en una esquina pequeña: crece a la par del texto y
   queda como el segundo elemento gráfico más grande de la rejilla,
   después del de la protagonista. El space-between separa texto e
   ilustración en vez de dejarlos apretados a la izquierda con media
   tarjeta en blanco. Sin plancha de vidrio detrás — el dibujo (claro
   u oscuro, ya trae su propio color por tema) flota directo sobre la
   tarjeta, igual que el de la protagonista. */
.feat-card--promote { grid-area: promote; flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 18px; }
.feat-card--promote .feat-card__text { flex: 1 1 240px; min-width: 0; display: flex; flex-direction: column; }
.feat-card--promote .feat-card__illustration {
  flex: 0 0 auto;
  align-self: center;
  width: clamp(220px, 30vw, 440px);
  margin: 0;
}
/* En móvil, texto e ilustración no caben en la misma fila y el
   space-between de arriba los apila en dos líneas — pero esa misma
   propiedad empuja la ilustración, ya sola en su línea, contra el
   borde izquierdo en vez de centrarla. margin-inline:auto la centra
   en el espacio libre de su línea sin tocar el layout de escritorio. */
@media (max-width: 639px) {
  .feat-card--promote { justify-content: flex-start; }
  .feat-card--promote .feat-card__illustration { margin-inline: auto; }
}

/* ── Entrada al hacer scroll: mismo patrón que .bento__grid ──
   El delay se fija por hijo directo de .feat__grid (con *, no
   .feat-card): desde que "Notas" y "Estructura" viven dentro de
   .feat-col--notas, ese hijo ya no es una .feat-card, y el --reveal-delay
   que le cae encima llega a sus dos tarjetas por herencia normal de
   custom property. */
.js .feat__grid[data-reveal] .feat-card { opacity: 0; translate: 0 20px; }
.js .feat__grid[data-reveal].is-in .feat-card { opacity: 1; translate: 0 0; }
.feat__grid > *:nth-child(2) { --reveal-delay: .06s; }
.feat__grid > *:nth-child(3) { --reveal-delay: .12s; }
.feat__grid > *:nth-child(4) { --reveal-delay: .18s; }
.feat__grid > *:nth-child(5) { --reveal-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  .js .feat__grid[data-reveal] .feat-card { opacity: 1; translate: 0; }
  .feat-card { transition: border-color .25s ease, box-shadow .25s ease; }
}

/* ── A partir de aquí, tableta: 2 columnas ──
   "tall" (ahora la columna Notas+Estructura) ocupa dos filas, a la
   misma altura que role+log, sin encimarse con nada. Promoción ya
   queda a fila completa aquí — no hay "wide" con quien repartirla. */
@media (min-width: 640px) {
  .feat__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas:
      "hero hero"
      "tall role"
      "tall log"
      "promote promote";
  }
  .feat-card--hero, .feat-card--tall { min-height: 240px; }
}

/* ── Escritorio: la composición asimétrica completa, en 4 columnas ──
   La protagonista ocupa 2 de 4 columnas (50% del ancho) y 2 de 3
   filas; Notas+Estructura se reparten esa misma altura en su propia
   columna (60/40, ver .feat-col--notas); role/log se apilan en la
   última columna; Promoción cierra sola, a todo el ancho. */
@media (min-width: 1040px) {
  .feat__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    /* Las dos primeras filas (hero/tall/role/log) se reparten el fr a
       partes iguales, pero con mínimo "auto" (no 0): si la protagonista
       — que abarca ambas — necesita más alto por su ilustración grande,
       las filas crecen con ella en vez de recortarla. La tercera queda
       "auto" por la misma razón, para la fila de Promoción. */
    grid-template-rows: repeat(2, minmax(auto, 1fr)) auto;
    grid-template-areas:
      "hero hero tall role"
      "hero hero tall log"
      "promote promote promote promote";
    min-height: clamp(480px, 42vw, 620px);
    margin-top: clamp(40px, 5vw, 64px);
  }
  .feat-card--hero, .feat-card--tall { min-height: 0; }
}

/* ══════════════════════════════════════════════════
   DOLORES → RESPUESTA

   Antes/después en la voz literal del colegio: la fila tacha el
   problema a la izquierda y responde a la derecha con lo que ya hace
   la plataforma (nada nuevo, son las mismas funciones de las otras
   secciones, solo nombradas desde el dolor y no desde la feature).

   Sin eyebrow a propósito: el titular ya hace ese trabajo, y una
   etiqueta encima de "esto es lo que te pasa" sonaría a departamento
   de marketing hablándole a otro departamento de marketing.

   La flecha es el único elemento con color (--brand, el mismo azul de
   marca de siempre): el texto de respuesta se queda en --ink para que
   se lea como afirmación, no como decoración. Una versión anterior le
   daba a cada fila un hue distinto (a juego con un .feat-card que
   también tenía seis colores); se revirtieron los dos a la vez —ver el
   comentario de .feat más abajo—, así que ya no hace falta que esta
   sección "haga juego" con una paleta que dejó de existir.
══════════════════════════════════════════════════ */
.pains__head { max-width: 700px; }
.pains__head h2 em { font-style: normal; color: var(--brand); }
.pains__head .lead { margin-top: 14px; }

.pains__grid {
  display: flex;
  flex-direction: column;
  margin-top: clamp(32px, 5vw, 48px);
  border-top: 1px solid var(--line);
}

.pain-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px 22px;
  padding: clamp(18px, 2.6vw, 26px) 4px;
  border-bottom: 1px solid var(--line);
  opacity: 0;
  translate: 0 14px;
  transition: opacity .6s ease var(--reveal-delay, 0s), translate .6s ease var(--reveal-delay, 0s);
}
.js .pains__grid[data-reveal].is-in .pain-row { opacity: 1; translate: 0 0; }
.pain-row:nth-child(2) { --reveal-delay: .06s; }
.pain-row:nth-child(3) { --reveal-delay: .12s; }
.pain-row:nth-child(4) { --reveal-delay: .18s; }
.pain-row:nth-child(5) { --reveal-delay: .24s; }
.pain-row:nth-child(6) { --reveal-delay: .3s; }

.pain-row__before {
  grid-column: 1;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted-2);
  text-decoration: line-through;
  text-decoration-color: var(--line-dash);
  text-decoration-thickness: 1.5px;
  max-width: 42ch;
}
.pain-row__arrow {
  grid-column: 2;
  grid-row: 1 / 3;
  display: none;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 20px;
  color: var(--brand);
}
.pain-row__after {
  grid-column: 1;
  font-size: clamp(15.5px, 1.4vw, 17px);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--ink);
  max-width: 46ch;
}

@media (prefers-reduced-motion: reduce) {
  .js .pains__grid[data-reveal] .pain-row { opacity: 1; translate: 0; }
  .pain-row { transition: none; }
}

/* ── A partir de tableta: la flecha entra entre las dos frases ── */
@media (min-width: 720px) {
  .pain-row {
    grid-template-columns: minmax(0, 1fr) 28px minmax(0, 1fr);
    gap: 0 22px;
  }
  .pain-row__before { grid-column: 1; }
  .pain-row__arrow { grid-column: 2; grid-row: auto; display: block; text-align: center; }
  .pain-row__after { grid-column: 3; }
}

/* ══════════════════════════════════════════════════
   ROLES (bento)

   MOBILE FIRST de verdad: la base es una columna con cada tarjeta
   apilada (título, luego dibujo). Desde min-width:640px la rectoría y
   docentes pasan a fila con el dibujo al costado; desde min-width:1000px
   se arma la composición bento fija de escritorio:

     ┌───────────────┬───────────────┐
     │               │   docentes    │   lead  → 2 col × 2 fil
     │   rectoría    ├───────┬───────┤   wide  → 2 col
     │               │ estud.│ famil.│   sm    → 1 col
     └───────────────┴───────┴───────┘

   Cada variante fija su art (flex/width/align-self/aspect-ratio) por
   completo en cada nivel, en vez de apoyarse en una regla general
   .bento-card__art de baja especificidad que una tarjeta puntual
   sobreescribe — así no hay que rastrear qué gana entre dos reglas.
══════════════════════════════════════════════════ */
.bento__intro { max-width: 640px; margin-bottom: clamp(26px, 4.5vh, 48px); }
.bento__intro h2 { margin: 16px 0 14px; }

.bento__grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: none;
  grid-auto-rows: auto;
  min-height: 0;
  gap: 16px;
}

.bento-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
  border-radius: 22px;
  padding: 22px;
  background: var(--pill-bg);
  border: 1px solid var(--glass-line);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: inset 0 1px 0 var(--glass-sheen);
  /* transform para el hover y translate (propiedad aparte) para la entrada:
     así una animación no pisa a la otra. */
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease,
              opacity .6s ease var(--reveal-delay, 0s), translate .6s ease var(--reveal-delay, 0s);
}
.bento-card:hover {
  transform: translateY(-3px);
  border-color: var(--btn-line-hover);
  box-shadow: var(--sh-sm), inset 0 1px 0 var(--glass-sheen);
}
.bento-card h3 { font-size: clamp(17px, 1.5vw, 19px); letter-spacing: -0.02em; }
.bento-card p { font-size: 14.5px; line-height: 1.55; color: var(--muted); margin-top: 8px; }
.bento-card__dash {
  display: block;
  width: 26px;
  height: 3px;
  margin-top: 18px;
  border-radius: 2px;
  background: var(--brand);
}

/* Sin plancha: cada ilustración trae su propia versión clara y su
   versión --dark ya pensada para el vidrio oscuro (ver
   .bento-card__art-img--dark más abajo), así que ninguna de las dos
   necesita una superficie de respaldo detrás. */
.bento-card__art {
  position: relative;
  min-height: 0;
  overflow: hidden;
  border-radius: 16px;
  --art-pad: 6px;
}
/* La imagen va posicionada, no en el flujo. Es la única forma de que no
   aporte nada al alto mínimo de la tarjeta: en flujo, un PNG de
   1080×861 suma el alto que le toque por su proporción y estira la
   rejilla entera (un alto en % no lo evita, porque contra un
   contenedor de alto todavía indefinido el navegador lo resuelve como
   automático). Así el hueco lo decide la rejilla y object-fit encoge
   el dibujo hasta caber. */
.bento-card__art-img {
  position: absolute;
  top: var(--art-pad);
  left: var(--art-pad);
  width: calc(100% - var(--art-pad) * 2);
  height: calc(100% - var(--art-pad) * 2);
  object-fit: contain;
  display: block;
}
/* Interruptor claro/oscuro: misma marca (data-scheme) que ya usa el
   logo del footer, porque light-dark() no sirve para decidir CUÁL
   <img> se pinta, solo colores. Sin JS (data-scheme nunca llega a
   "dark") se queda en la versión clara — nunca en blanco.
   Igual que en .hero__figure, el swap es por opacity (no display) para
   que .theme-switching pueda cruzarlas en vez de que salten de golpe. */
.bento-card__art-img--dark { opacity: 0; }
:root[data-scheme="dark"] .bento-card__art-img--light { opacity: 0; }
:root[data-scheme="dark"] .bento-card__art-img--dark { opacity: 1; }

/* ── 1 · Rectoría: la tarjeta ancla ───────────────
   Apilada en móvil, en fila desde tablet, 2×2 en escritorio (ver los
   dos @media más abajo). */
.bento-card--lead {
  grid-column: span 1;
  grid-row: auto;
  flex-direction: column;
  align-items: stretch;
  padding: clamp(22px, 2.4vw, 30px);
  /* Ya no es el único bloque en color pleno: es una tarjeta de vidrio
     más, igual que las otras tres — el tamaño (2×2 en escritorio) ya
     basta para leerla como el ancla de la rejilla, sin necesitar un
     fondo distinto que además obligaba a un juego de colores aparte
     (--on-brand) solo para esta tarjeta. */
}
.bento-card--lead h3 { font-size: clamp(21px, 2.3vw, 28px); line-height: 1.1; }
.bento-card--lead p {
  font-size: clamp(15px, 1.3vw, 16.5px);
  max-width: 42ch;
}
.bento-card--lead .bento-card__art {
  flex: 1;
  width: auto;
  align-self: stretch;
  /* 1080 / 861: la proporción real del PNG, no un 16:11 de compromiso
     — así "contain" ya no deja aire de sobra a los lados. */
  aspect-ratio: 1080 / 861;
  --art-pad: clamp(8px, 1vw, 16px);
}

/* ── 2 · Docentes: el dibujo arriba en móvil, al costado desde tablet ── */
.bento-card--wide {
  grid-column: span 1;
  flex-direction: column;
  align-items: center;
  background: var(--brand-soft);
  border-color: var(--line-brand);
}
.bento-card--wide .bento-card__body { flex: 1 1 auto; min-width: 0; }
.bento-card--wide .bento-card__art {
  flex: 0 0 auto;
  width: auto;
  align-self: stretch;
  aspect-ratio: 1080 / 861;
}

/* ── 3 y 4 · Estudiantes y familias: el dibujo arriba ──
   Cambia el orden en pantalla, no en el HTML: el título sigue siendo lo
   primero que encuentra un lector de pantalla dentro de la tarjeta.
   Sin altura de rejilla que llenar (grid-auto-rows:auto en móvil y
   tablet), el dibujo necesita su propia proporción; en escritorio la
   fila fija de .bento__grid vuelve a repartirle el alto (@media min-width
   más abajo resetea el aspect-ratio). */
.bento-card--sm .bento-card__art { order: -1; flex: 1; aspect-ratio: 1080 / 861; }

/* ── Entrada al hacer scroll ─────────────────────
   El JS pone .is-in cuando la rejilla entra en pantalla; el desfase de
   cada tarjeta es puramente CSS. Todo cuelga de :root.js (la marca que
   deja el script del <head>): sin JS no se esconde nada. */
.js .bento__grid[data-reveal] .bento-card { opacity: 0; translate: 0 20px; }
.js .bento__grid[data-reveal].is-in .bento-card { opacity: 1; translate: 0 0; }
.bento__grid .bento-card:nth-child(2) { --reveal-delay: .08s; }
.bento__grid .bento-card:nth-child(3) { --reveal-delay: .16s; }
.bento__grid .bento-card:nth-child(4) { --reveal-delay: .24s; }

@media (prefers-reduced-motion: reduce) {
  .js .bento__grid[data-reveal] .bento-card { opacity: 1; translate: 0; }
  .bento-card { transition: border-color .25s ease, box-shadow .25s ease; }
}

/* ── Tablet: dos columnas. La grande y la ancha ocupan la fila entera
   y se acuestan (dibujo al costado); las dos pequeñas quedan lado a
   lado con el dibujo arriba, como en móvil. ── */
@media (min-width: 640px) {
  .bento__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bento-card--lead,
  .bento-card--wide { grid-column: span 2; }
  .bento-card--lead { flex-direction: row; align-items: center; }
  .bento-card--lead .bento-card__art {
    width: min(50%, 340px);
    align-self: center;
    aspect-ratio: 1080 / 861;
  }
  .bento-card--wide {
    flex-direction: row;
    align-items: center;
  }
  .bento-card--wide .bento-card__art {
    width: min(42%, 230px);
    align-self: center;
    aspect-ratio: 1080 / 861;
  }
}

/* ── Escritorio: la composición bento fija (2×2 + ancha + dos pequeñas),
   con el alto repartido por la rejilla en vez de por el contenido. ── */
@media (min-width: 1000px) {
  .bento__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-rows: repeat(2, minmax(0, 1fr));
    min-height: clamp(470px, 46vw, 620px);
  }
  .bento-card--lead {
    grid-row: span 2;
    flex-direction: column;
    align-items: stretch;
  }
  .bento-card--lead .bento-card__art {
    width: auto;
    align-self: stretch;
    aspect-ratio: auto;
  }
  .bento-card--wide .bento-card__art {
    align-self: stretch;
    aspect-ratio: auto;
  }
  .bento-card--sm .bento-card__art { aspect-ratio: auto; }
}

/* ══════════════════════════════════════════════════
   CENTRALIZACIÓN Y SEGURIDAD

   Ya no es un bloque fijo-oscuro: sigue el tema, igual que .feat. En
   oscuro se ve idéntico a como se veía (los light-dark() de abajo
   resuelven a los mismos --dark/--dark-text/--dark-glass-* de siempre);
   en claro pasa a un lavado cian clarísimo, tarjetas de vidrio blanco y
   texto oscuro — mismo patrón que .feat, con su propio acento.

   Las cuatro cifras de .vault-tile no son analítica del negocio (no
   hay datos de uso reales que mostrar): describen una propiedad del
   sistema — cuánto vive en un solo lugar, cuánto depende del papel,
   qué tan al día se ve el colegio y quién puede ver qué. Por eso el
   número es a veces una palabra ("En vivo", "Por rol") y no una
   estadística que no podamos sostener.

   Acento cian solo en oscuro (mismo hue que .feat-card--wide, 200, sin
   tocar): es la tarjeta que ahí "sostiene a todas las demás". En claro
   se une al mismo azul y al mismo --brand-halo que .feat, .final y
   .article-cta — un solo azul en todo el sitio en vez de un cian propio.
══════════════════════════════════════════════════ */
.vault {
  --vault-accent: light-dark(var(--brand-dark), oklch(0.78 0.1 200));
  --vault-bg: light-dark(var(--brand-halo), var(--dark));
  --vault-ink: light-dark(var(--ink), #fff);
  --vault-text: light-dark(var(--muted), var(--dark-text));
  --vault-card-bg: light-dark(oklch(1 0 0 / 0.55), var(--dark-glass-bg));
  --vault-card-line: light-dark(var(--line-brand), var(--dark-glass-line));
  --vault-card-sheen: light-dark(oklch(1 0 0 / 0.85), var(--dark-glass-sheen));
  --vault-line-2: light-dark(var(--line-2), var(--dark-line-2));
  position: relative;
  overflow: clip;
  background: var(--vault-bg);
  color: var(--vault-ink);
}
/* Solo en oscuro, igual que .feat__halo: en claro la sección ya es
   blanco+azul sin degradados, sin el cian que llevaba este blob. */
.vault__halo {
  position: absolute;
  inset: -10% -10% auto -10%;
  height: 65%;
  background: radial-gradient(40% 60% at 82% 10%, light-dark(transparent, oklch(0.4 0.09 200 / 0.35)) 0%, transparent 72%);
  pointer-events: none;
}
.vault__wrap { position: relative; }
.vault__head { max-width: 780px; }
.vault__title {
  font-size: clamp(28px, 4.2vw, 46px);
  line-height: 1.12;
  letter-spacing: -0.03em;
  font-weight: 600;
}
.vault__title em { font-style: normal; color: var(--vault-accent); }
.vault__lead { margin-top: 18px; font-size: clamp(15px, 1.4vw, 17px); line-height: 1.6; color: var(--vault-text); max-width: 62ch; }

.vault__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
  margin-top: clamp(32px, 5vw, 48px);
}
.vault-tile {
  border-radius: 20px;
  padding: clamp(20px, 2vw, 26px);
  background: var(--vault-card-bg);
  border: 1px solid var(--vault-card-line);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  box-shadow: inset 0 1px 0 var(--vault-card-sheen);
  opacity: 0;
  translate: 0 16px;
  transition: opacity .6s ease var(--reveal-delay, 0s), translate .6s ease var(--reveal-delay, 0s);
}
.js .vault__grid[data-reveal].is-in .vault-tile { opacity: 1; translate: 0 0; }
.vault__grid .vault-tile:nth-child(2) { --reveal-delay: .08s; }
.vault__grid .vault-tile:nth-child(3) { --reveal-delay: .16s; }
.vault__grid .vault-tile:nth-child(4) { --reveal-delay: .24s; }

.vault-tile b { display: block; font-size: clamp(32px, 3.4vw, 42px); font-weight: 600; letter-spacing: -0.03em; color: var(--vault-accent); }
.vault-tile__label {
  display: block;
  margin-top: 6px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vault-text);
  opacity: .8;
}
.vault-tile p { margin-top: 12px; font-size: 14px; line-height: 1.55; color: var(--vault-text); }

.vault__foot {
  margin-top: clamp(28px, 4vw, 40px);
  padding-top: clamp(24px, 3vw, 32px);
  border-top: 1px solid var(--vault-line-2);
  font-size: clamp(15.5px, 1.4vw, 17px);
  font-weight: 500;
  line-height: 1.55;
  max-width: 68ch;
  color: var(--vault-ink);
}

@media (prefers-reduced-motion: reduce) {
  .js .vault__grid[data-reveal] .vault-tile { opacity: 1; translate: 0; }
  .vault-tile { transition: none; }
}

@media (min-width: 640px) {
  .vault__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1040px) {
  .vault__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ══════════════════════════════════════════════════
   CIERRE FINAL

   Ya no es oscuro en los dos temas: en claro pasa a --brand-halo (el
   lavado de marca ya usado en otras superficies claras nuevas), con
   texto --ink; en oscuro se ve idéntico a como se veía (--dark + #fff).
══════════════════════════════════════════════════ */
.final {
  --final-ink: light-dark(var(--ink), #fff);
  background: light-dark(var(--brand-halo), var(--dark));
  color: var(--final-ink);
  text-align: center;
  padding: clamp(80px, 14vh, 170px) clamp(18px, 4vw, 40px);
}
.final__inner { max-width: 820px; margin: 0 auto; }
.final h2 { font-size: clamp(36px, 5.4vw, 68px); line-height: 1.02; letter-spacing: -0.035em; margin-bottom: 18px; }
.final p { font-size: clamp(17px, 1.5vw, 20px); line-height: 1.55; color: light-dark(var(--muted), var(--dark-text)); }
.final__cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 34px;
}
