/* ALIC V7 — editorial.css
   Sistema editorial de la home. Se carga SOLO en index.html, después de los
   CSS heredados, para no alterar las otras 17 páginas mientras se migran.

   Principio rector: una sola variable (--fsize) escala tipografía y ritmo.
   Todo aquí está en rem y el rem está atado al ancho de viewport.
   Ver docs/07_REFERENCIA_DISENO_NORMALISBORING.md §2.1. */

/* ============================================================
   1. ESCALA FLUIDA
   ============================================================
   Solo aplica cuando <html> lleva la clase .editorial, de modo que las
   páginas todavía no migradas conservan el rem de 16px del navegador. */

html.editorial {
  --fsize: 1.0416666667vw;          /* 15px a 1440px */
  font-size: var(--fsize);
}

@media (max-width: 1440px) { html.editorial { --fsize: 1.1vw; } }
@media (max-width: 1024px) { html.editorial { --fsize: 1.953125vw; } }
@media (max-width: 768px)  { html.editorial { --fsize: 2.6041666667vw; } }
@media (max-width: 576px)  { html.editorial { --fsize: 3.4722222222vw; } }
@media (max-width: 468px)  { html.editorial { --fsize: 4.2735042735vw; } }
@media (max-width: 375px)  { html.editorial { --fsize: 5.3333333333vw; } }

html.editorial body {
  font-size: var(--ed-body);
  line-height: var(--ed-body-lh);
  background: var(--marfil);
  overflow-x: clip;
}

/* ============================================================
   2. TOKENS EDITORIALES
   ============================================================ */

html.editorial {
  /* Tipografía: 10 pasos, cada uno con su interlineado bloqueado */
  --ed-mega: 11rem;      --ed-mega-lh: 0.9;
  /* El titular de entrada es la pieza con más peso de la página: se le da
     más cuerpo y un interlineado más cerrado que al resto de la escala. */
  --ed-super: 6.6rem;    --ed-super-lh: 0.92;
  --ed-xxl: 4.2rem;      --ed-xxl-lh: 1.02;
  --ed-xl: 3rem;         --ed-xl-lh: 1.08;
  --ed-l: 2.2rem;        --ed-l-lh: 1.15;
  --ed-m: 1.6rem;        --ed-m-lh: 1.3;
  --ed-body-l: 1.35rem;  --ed-body-l-lh: 1.5;
  --ed-body: 1rem;       --ed-body-lh: 1.65;
  --ed-small: 0.85rem;   --ed-small-lh: 1.5;
  --ed-micro: 0.7rem;    --ed-micro-lh: 1.4;

  /* Ritmo vertical: se declara por sección, arriba y abajo por separado */
  --pad-xl: 12rem;
  --pad-l: 9rem;
  --pad-m: 6rem;
  --pad-s: 3rem;
  --pad-xs: 1.6rem;

  /* Retícula */
  --edge: 1.65rem;
  --gutter: 1.5rem;

  --ease-out: cubic-bezier(.22, .61, .36, 1);
}

@media (max-width: 1024px) {
  html.editorial {
    --ed-mega: 6.5rem;
    --ed-super: 4.4rem;
    --ed-xxl: 3.2rem;
    --pad-xl: 7rem; --pad-l: 5.5rem; --pad-m: 4rem;
  }
}

@media (max-width: 768px) {
  html.editorial {
    --ed-mega: 4.6rem;
    --ed-super: 2.35rem;   /* la línea más larga ("ENCUENTRA LA") debe caber a 375px */
    --ed-xxl: 2.4rem;
    --ed-xl: 2.1rem;
    --pad-xl: 5rem; --pad-l: 4rem; --pad-m: 3rem;
    --edge: 1.25rem;
  }
}

/* ============================================================
   3. UTILIDADES DE TIPO Y RITMO
   ============================================================ */

.ed-mega   { font-size: var(--ed-mega);   line-height: var(--ed-mega-lh); }
.ed-super  { font-size: var(--ed-super);  line-height: var(--ed-super-lh); }
.ed-xxl    { font-size: var(--ed-xxl);    line-height: var(--ed-xxl-lh); }
.ed-xl     { font-size: var(--ed-xl);     line-height: var(--ed-xl-lh); }
.ed-l      { font-size: var(--ed-l);      line-height: var(--ed-l-lh); }
.ed-m      { font-size: var(--ed-m);      line-height: var(--ed-m-lh); }
.ed-body-l { font-size: var(--ed-body-l); line-height: var(--ed-body-l-lh); }
.ed-body   { font-size: var(--ed-body);   line-height: var(--ed-body-lh); }
.ed-small  { font-size: var(--ed-small);  line-height: var(--ed-small-lh); }
.ed-micro  { font-size: var(--ed-micro);  line-height: var(--ed-micro-lh); }

.pt-xl { padding-top: var(--pad-xl); }   .pb-xl { padding-bottom: var(--pad-xl); }
.pt-l  { padding-top: var(--pad-l); }    .pb-l  { padding-bottom: var(--pad-l); }
.pt-m  { padding-top: var(--pad-m); }    .pb-m  { padding-bottom: var(--pad-m); }
.pt-s  { padding-top: var(--pad-s); }    .pb-s  { padding-bottom: var(--pad-s); }
.pt-xs { padding-top: var(--pad-xs); }   .pb-xs { padding-bottom: var(--pad-xs); }

/* Margen superior e inferior, en la misma escala. Existen para que ningún
   bloque necesite un atributo `style=` en el marcado: con la CSP en vigor
   un estilo escrito en el HTML solo se aplicaría abriendo `style-src` a
   'unsafe-inline', y no vale la pena rebajar la política por doce márgenes.
   Los estilos que GSAP escribe en tiempo de ejecución van por el CSSOM y la
   CSP no los alcanza. */
.mt-m  { margin-top: var(--pad-m); }     .mb-m  { margin-bottom: var(--pad-m); }
.mt-s  { margin-top: var(--pad-s); }     .mb-s  { margin-bottom: var(--pad-s); }
.self-end { align-self: end; }

.ed-wrap { padding-inline: var(--edge); }
.f-sans  { font-family: var(--font-sans); }
.f-serif { font-family: var(--font-serif); }
.f-display { font-family: var(--font-display); }
.t-upper { text-transform: uppercase; }
.italic  { font-style: italic; }

.bg-marfil { background: var(--marfil); color: var(--onice); }
.bg-onice  { background: var(--onice);  color: var(--marfil); }
.bg-pearl  { background: var(--pearl);  color: var(--onice); }
.bg-cardenal { background: var(--cardenal); color: var(--marfil); }

/* ============================================================
   4. PRELOADER
   ============================================================
   El contenido NO depende de él: si el JS falla, .ed-loader nunca recibe
   la clase .is-done pero tampoco oculta nada, porque el body jamás se
   pone a opacity 0 desde CSS. Ver AGENTS.md §8. */

.ed-loader {
  position: fixed;
  inset: 0;
  z-index: 5000;
  display: grid;
  place-items: center;
  background: var(--onice);
  color: var(--marfil);
  transition: opacity .8s var(--ease-out), visibility .8s;
}

html:not(.js-enhanced) .ed-loader { display: none; }

.ed-loader.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* Vídeo de fondo de la cortina. Va detrás del logotipo y de la barra; si no
   carga, queda el fondo onice del propio .ed-loader y nada se rompe. */
.ed-loader__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--onice);
}

.ed-loader__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity .9s var(--ease-out);
}

.ed-loader[data-loader-media="ready"] .ed-loader__media video { opacity: 1; }

/* Velo para que el logotipo se lea sobre cualquier fotograma. */
.ed-loader__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center,
      color-mix(in srgb, var(--onice) 55%, transparent) 0%,
      color-mix(in srgb, var(--onice) 30%, transparent) 55%,
      color-mix(in srgb, var(--onice) 70%, transparent) 100%);
}

.ed-loader__mark {
  position: relative;
  z-index: 2;
  font-family: var(--font-display);
  font-size: var(--ed-xxl);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  overflow: hidden;
  display: flex;
  gap: 0.04em;
}

.ed-loader__mark span { display: inline-block; }

.ed-loader__bar {
  position: absolute;
  z-index: 2;
  left: var(--edge);
  right: var(--edge);
  bottom: var(--edge);
  height: 1px;
  background: color-mix(in srgb, var(--marfil) 22%, transparent);
}

.ed-loader__bar i {
  display: block;
  height: 100%;
  width: var(--progress, 0%);
  background: var(--dorado);
}

.ed-loader__pct {
  position: absolute;
  z-index: 2;
  right: var(--edge);
  bottom: calc(var(--edge) + 1rem);
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.14em;
  color: var(--dorado);
}

/* ============================================================
   4b. CABECERA SOBRE FONDOS MIXTOS
   ============================================================
   El hero combina crema a la izquierda y una columna de imagen oscura a la
   derecha, donde caen las acciones. Un solo color de texto no puede ser
   legible en ambos, así que las acciones llevan su propia píldora. */

/* ---- Cabecera editorial: logotipo a la izquierda, navegación vertical
   pegada al borde derecho. Solo en la home migrada; las otras 17 páginas
   conservan la cabecera horizontal hasta que se migren. ---- */

html.editorial .site-header {
  display: block;
  height: auto;
  padding: 0;
  pointer-events: none;   /* el hueco central no debe bloquear el contenido */
  background: none !important;
  border: 0 !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

html.editorial .site-header > * { pointer-events: auto; }

/* Aquí la cabecera no tiene altura propia (display:block y el logotipo
   posicionado dentro), así que el translateY en porcentaje del retiro
   valía 0 y solo quedaba el fundido. Con una medida fija sí se desliza. */
html.editorial .site-header[data-header-hidden] { transform: translateY(-6rem); }

/* El logotipo y la navegación quedan fijos sobre un recorrido que alterna
   paneles blancos y negros, así que ningún color fijo sirve. Con difference
   sobre blanco se invierten solos: negros sobre fondo claro, blancos sobre
   fondo oscuro. Es la misma técnica que usa el referente en su logotipo.

   La mezcla va en el <header>, no en cada hijo: el header ya crea contexto
   de apilamiento por su z-index, así que una mezcla declarada dentro solo
   se combinaría con el propio header (fondo transparente) y el texto se
   quedaba blanco siempre, invisible sobre los paneles claros. */
html.editorial .site-header { mix-blend-mode: difference; }

/* Solo el logotipo necesita la mezcla: es lo único que queda fijo sobre
   paneles claros y oscuros. La navegación ya vive dentro del hero blanco. */
html.editorial .site-logo { color: #fff; }

html.editorial .site-logo {
  position: absolute;
  top: calc(var(--edge) + 0.4rem);
  left: var(--edge);
  font-size: var(--ed-l);
  letter-spacing: 0.14em;
}

/* Los enlaces se alinean en fila y es cada uno el que gira, no el
   contenedor: rotando el contenedor se invertía el orden de lectura. */
/* La navegación se pega al borde donde arranca el vídeo, no al borde de la
   pantalla, y se queda ahí fija durante todo el recorrido. --hero-open debe
   coincidir con HERO_OPEN_VW en editorial.js. */
html.editorial { --hero-open: 78vw; }

/* La navegación se ancla al borde derecho del propio panel del hero, no al
   viewport. Con position fixed no se movía, pero el vídeo se deslizaba por
   debajo y acababa tapándola; anclada al panel viaja con él y siempre queda
   sobre el blanco, junto al canto del vídeo.

   Los enlaces se apilan en columna, todos en la misma vertical; en fila
   quedaban escalonados en diagonal. column-reverse deja el primero abajo,
   que es el orden de lectura de una navegación girada. */
html.editorial .site-nav {
  position: absolute;
  top: 50%;
  right: 0.9rem;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: clamp(1.4rem, 2.4vw, 2.6rem);
  z-index: 3;
  color: var(--onice);
}

html.editorial .site-nav > a {
  writing-mode: vertical-rl;
  rotate: 180deg;                   /* se lee de abajo hacia arriba */
  font-size: var(--ed-micro);
  letter-spacing: 0.22em;
  white-space: nowrap;
}

/* El desplegable de colecciones no cabe en vertical: aquí el enlace lleva
   directo al ancla de la sección y las tres colecciones siguen accesibles
   desde el menú completo. */

/* ---- Acciones fijas, fuera del <header> ----
   Van en su propio contenedor porque el header está en modo difference y un
   hijo no puede quedar fuera de esa mezcla. Aquí llevan fondo propio y se
   leen igual sobre el blanco que sobre el vídeo. */
html.editorial .ed-actions {
  position: fixed;
  top: var(--edge);
  right: var(--edge);
  z-index: calc(var(--layer-header) + 1);
  display: flex;
  align-items: center;
  gap: var(--pad-xs);
}

html.editorial .ed-actions button {
  border: 1px solid color-mix(in srgb, var(--marfil) 40%, transparent);
  border-radius: 999px;
  padding: 0.55rem 1.2rem;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--marfil);
  background: color-mix(in srgb, var(--onice) 62%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

html.editorial .ed-actions button:hover {
  background: var(--marfil);
  color: var(--onice);
  border-color: var(--marfil);
  opacity: 1;
}

/* El icono de hamburguesa es para móvil; en escritorio manda la palabra. */
html.editorial .ed-actions__icon { display: none; }

/* Intercambio: durante el hero se ofrece agendar; una vez pasado, el botón
   se convierte en el acceso al menú completo. */
html.editorial .ed-actions__menu { display: none; }
html.editorial body[data-ed-nav="menu"] .ed-actions__agendar { display: none; }
html.editorial body[data-ed-nav="menu"] .ed-actions__menu { display: inline-flex; }

/* ============================================================
   LA FRONTERA DE LA LECTURA VERTICAL
   ============================================================
   `@media (max-width: 1024px), (orientation: portrait)` aparece varias
   veces en esta hoja y siempre significa lo mismo: aquí el recorrido se lee
   en columna. Es la negación exacta de la consulta con la que editorial.js
   monta el riel horizontal —`(min-width: 1025px) and (orientation:
   landscape)`, la constante DESKTOP—, y las dos tienen que cambiar juntas o
   habrá un tramo de anchos con el riel en horizontal y los estilos de la
   columna, o al revés.

   Por qué 1024 y no 768: un iPad en retrato mide 810, 820 o 1024 px de
   ancho. Con la frontera en 768 se llevaba el recorrido lateral con el
   scroll anclado, que es un gesto de rueda de ratón, y encima se quedaba
   fuera de todo lo que se afinó para la columna. Con la frontera aquí,
   cualquier tableta en retrato lee como el móvil y el recorrido lateral
   queda para el portátil y el escritorio, que es donde se pensó.
   ============================================================ */
@media (max-width: 1024px), (orientation: portrait) {
  html.editorial .ed-actions__icon { display: inline; }
  html.editorial .ed-actions__label { display: none; }
  /* Sin recorrido horizontal en móvil no hay momento de intercambio: el
     menú está disponible desde el principio. */
  html.editorial .ed-actions__menu { display: inline-flex; }
  html.editorial .ed-actions__agendar { display: none; }
}

/* El botón flotante comparte color con el fondo cardenal de la sección de
   consulta y del cierre del recorrido: sin borde se desvanece. */
html.editorial .floating-consulta button {
  border: 1px solid color-mix(in srgb, var(--marfil) 55%, transparent);
}

/* ============================================================
   5. HERO EDITORIAL
   ============================================================ */

/* El hero ocupa el ancho completo y arranca en blanco, sin medios: el vídeo
   está en el panel siguiente del recorrido y se descubre al deslizar. */
.ed-hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-items: stretch;
  background: var(--marfil);
  overflow: hidden;
}

/* ---- Fondo de vídeo del hero ----
   Va muy atenuado: es atmósfera, no protagonista, y el titular tiene que
   seguir leyéndose sin esfuerzo. Ajusta --hero-video-opacity para calibrar.
   Si el iframe no llega a inyectarse, queda el blanco y no se rompe nada. */
/* Equilibrio medido sobre una zona plana del hero (255 = blanco puro):
     papel limpio ................ 249
     solo grano .................. 241   el grano cuesta 8 niveles
     grano + vídeo al 0,10 ....... ~237
   Más opacidad de vídeo agrisa la sección y le resta contraste al titular;
   menos grano y la textura deja de apreciarse. Estos son los valores donde
   se ve el grano, se intuye el vídeo y la página sigue leyéndose blanca. */
html.editorial {
  --hero-video-opacity: 0.10;
  --hero-grain-opacity: 0.7;
}

.ed-hero__backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--marfil);
}

/* Grano de película. El ruido se genera con feTurbulence en un SVG embebido:
   no añade ninguna petición y escala a cualquier tamaño.

   Sobre blanco solo multiply produce grano visible —screen y overlay no
   alteran el blanco—, pero multiply oscurece todo por igual y agrisaba la
   sección. Por eso el ruido se sesga hacia el claro con feComponentTransfer
   (gamma < 1): la mayoría de la textura queda casi blanca, que en multiply
   no cambia nada, y solo las motas más oscuras marcan el grano. Así se ve
   la textura sin perder el blanco. */
.ed-hero__backdrop::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--hero-grain-opacity);
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='gamma' exponent='0.45'/%3E%3CfeFuncG type='gamma' exponent='0.45'/%3E%3CfeFuncB type='gamma' exponent='0.45'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Un <video> local se recorta con object-fit; el iframe de Vimeo no puede,
   y necesita la técnica "cover" de 16:9 con la mayor de las dos medidas. */
.ed-hero__backdrop video,
.ed-hero__backdrop iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 0;
  opacity: 0;
  transition: opacity 1.2s var(--ease-out);
}

.ed-hero__backdrop video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* El vídeo es de taller, con negros muy cerrados. Bajar solo la opacidad
     lo mezcla con el blanco y agrisa toda la sección, restando contraste al
     titular. Aclarando primero sus negros y planchando el contraste, lo que
     se mezcla ya es casi blanco: se intuye el movimiento sin ensuciar. */
  filter: brightness(1.9) contrast(0.45) saturate(0.5);
}

.ed-hero__backdrop iframe {
  width: max(100%, 177.78vh);
  height: max(100%, 56.25vw);
}

/* ---- Fuera el botón de reproducción de iOS ----
   Safari dibuja un triángulo de "play" en el centro de cualquier <video>
   detenido, aunque no tenga controles. Estos vídeos son fondo: nadie los va
   a pulsar, y ese icono sobre la portada se lee como un fallo de carga.
   Quitándolo, mientras el vídeo espera se ve el primer fotograma —una
   fotografía— y no un reproductor averiado.

   Los cuatro selectores comparten pseudo-elemento a propósito: si el
   navegador no lo conoce descarta la regla entera, y en ese caso tampoco
   dibuja ningún botón. */
.ed-hero__backdrop video::-webkit-media-controls-start-playback-button,
.ed-flip__video::-webkit-media-controls-start-playback-button,
.ed-window__video::-webkit-media-controls-start-playback-button,
.ed-acordeon video::-webkit-media-controls-start-playback-button {
  display: none;
  -webkit-appearance: none;
}

/* Solo cuando el módulo confirma que el medio cargó se revela. */
.ed-rail__panel--hero[data-media-state="video"] .ed-hero__backdrop video,
.ed-rail__panel--hero[data-media-state="video"] .ed-hero__backdrop iframe {
  opacity: var(--hero-video-opacity);
}

/* El contenido va por encima del fondo. */
.ed-hero__body,
.ed-hero__foot,
.ed-hero .site-nav { position: relative; z-index: 2; }

/* Aquí se retiraba el fondo entero con movimiento reducido. En escritorio
   apenas se notaba —el vídeo va al 10 % sobre blanco—, pero en vertical el
   hero está compuesto ENCIMA de ese fondo: el texto baja al pie sobre un
   velo y el vídeo ocupa la pantalla. Sin fondo quedaba un rectángulo de
   papel con el rótulo abajo, que es justo lo que un cliente describe como
   "el sitio no carga".

   Y el disparador no siempre es una preferencia: iOS anuncia su modo de
   bajo consumo como `prefers-reduced-motion: reduce`. Así que el fondo se
   queda; lo que el movimiento reducido apaga son las animaciones, que es
   de lo que trata la preferencia. Si además el navegador bloquea la
   reproducción, se ve el primer fotograma y movil-video.js lo reintenta al
   primer gesto. */

/* El bloque de texto se centra como conjunto, pero conserva la bandera
   izquierda y el escalonado: centrar el texto en sí lo volvería simétrico
   y perdería el carácter editorial. */
.ed-hero__body {
  position: relative;
  display: grid;
  align-content: center;
  width: min(100%, 74rem);
  margin-inline: auto;
  padding: var(--pad-l) var(--edge) var(--pad-m);
}

/* Titular escalonado: cada línea con su propia sangría */
/* Titular de entrada en serif: en versales grandes EB Garamond lee como una
   inscripción romana, que es exactamente el registro de la casa. Pide algo de
   tracking positivo —al revés que la sans— para que las versales respiren. */
.ed-hero__title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--ed-super);
  line-height: var(--ed-super-lh);
  letter-spacing: 0.005em;
  text-transform: uppercase;
  margin: 0;
  max-width: 16ch;
}

/* Separación entre PALABRAS del titular (no entre letras): en versales de
   Garamond las palabras se pegan y la frase se lee como un bloque.
   Hacen falta las dos reglas: word-spacing cubre el titular sin JavaScript,
   y el margen cubre el titular ya partido, donde los separadores son &nbsp;
   y word-spacing no les afecta. */
.ed-hero__title { word-spacing: 0.22em; }
.ed-hero__title .ed-char--space { margin-inline: 0.11em; }

/* La palabra acentuada va un punto por encima del resto para que remate la
   frase. Su línea crece sola para acomodarla (96px -> 112px), así que la
   máscara de .ed-line no llega a recortar los descendentes de la itálica;
   comprobado midiendo el desbordamiento de cada carácter. */
.ed-hero__title .ed-char--accent,
.ed-hero__title em { font-size: 1.16em; }

/* El cardenal profundo se conserva como alias: desde el 2026-07-27 el
   cardenal del sitio ya es este tono, y mantener dos valores distintos era
   justo lo que hacía que el rojo del hero y el de los paneles no casaran. */
html.editorial { --cardenal-deep: var(--cardenal); }

/* La palabra acentuada, en oro. Va en degradado y no en un color plano
   porque un oro plano sobre papel blanco no parece metal, parece mostaza:
   el brillo del metal es precisamente que el tono cambie a lo largo de la
   letra. Arranca en el oro de marca y cierra en el oro de texto, que es el
   que sostiene el contraste; así la palabra se lee dorada de verdad y sigue
   siendo legible. Fuera del @supports queda el tono oscuro a secas, que es
   lo que verá un navegador sin recorte. */
html.editorial { --oro-hero: linear-gradient(112deg, var(--dorado) 0%, var(--dorado-light) 26%, var(--dorado-texto) 78%); }

.ed-hero__title .ed-char--accent,
.ed-hero__title em { color: var(--dorado-texto); }

/* El grano del hero, recortado dentro de las letras. El recorte solo se
   activa si el navegador lo soporta: sin la comprobación, uno sin
   background-clip:text dejaría el texto transparente, es decir, invisible.

   La misma textura va sobre el titular entero y no solo sobre la palabra en
   oro: el grano cubre toda la sección, y un titular liso en medio de una
   superficie granulada se leía pegado encima, como si fuera de otra capa.

   Y va carácter a carácter, no en el <h1>: el partidor convierte cada letra
   en su propio <span>, y un recorte a texto declarado en el padre no
   alcanza a los glifos de esos hijos —el titular entero se volvía
   invisible—. Por eso el ancla del ruido es el viewport: así la textura no
   se reinicia en cada letra y el grano cruza la palabra entera. Si el
   partidor no llega a correr no hay `.ed-char`, no hay recorte, y el
   titular se lee en su tinta de siempre.
   Es sutil a propósito —el ruido va sesgado hacia el claro y en multiply
   apenas muerde—, lo justo para que la tinta parezca impresa sobre el
   papel y no dibujada sobre él.

   Todo esto vive dentro de la consulta de escritorio. En vertical el
   titular va en marfil sobre el vídeo, sin papel que imitar, y un
   `background-attachment: fixed` recortado a texto es de lo más caro que se
   le puede pedir al compositor de un teléfono. */
@media (min-width: 1025px) and (orientation: landscape) {
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ed-hero__title .ed-char,
  .ed-hero__title .ed-char--accent,
  .ed-hero__title em {
    color: transparent;
    background-blend-mode: multiply;
    /* Anclado al viewport: si no, el ruido se reiniciaría en cada letra,
       porque el partidor convierte cada carácter en su propio elemento. */
    background-attachment: fixed;
    -webkit-background-clip: text;
    background-clip: text;
  }

  .ed-hero__title .ed-char {
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='gamma' exponent='0.6'/%3E%3CfeFuncG type='gamma' exponent='0.6'/%3E%3CfeFuncB type='gamma' exponent='0.6'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E"),
      linear-gradient(var(--onice) 0 0);
  }

  .ed-hero__title .ed-char--accent,
  .ed-hero__title em {
    background-image:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='gamma' exponent='0.6'/%3E%3CfeFuncG type='gamma' exponent='0.6'/%3E%3CfeFuncB type='gamma' exponent='0.6'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E"),
      var(--oro-hero);
  }
}
}

/* Escalonado: cada línea con su propia sangría. Se usa transform y no
   padding-left porque el partidor mide las líneas ANTES de que se aplique la
   sangría; con padding el ancho disponible cambiaba después de medir y la
   última palabra se salía. transform no afecta al layout, así que la medida
   sigue siendo válida. Sin JS el titular se lee corrido. */
/* Línea 2 al ras de la 1: "ENCUENTRA" arranca en el mismo margen que
   "DONDE". El escalonado se reserva para la última línea. */
.ed-hero__title .ed-line:nth-child(3) { transform: translateX(4%); }

/* El gesto de marca: la palabra acentuada en serif itálica y caja baja.
   Se aplica tanto al <em> original como a los caracteres que el partidor
   marca como acentuados. */
.ed-hero__accent,
.ed-char--accent,
.ed-line em,
.ed-hero__title em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0.005em;
}

/* Dorado de texto: el --dorado de marca (#C9A45B) sobre blanco se queda en
   torno a 2:1 de contraste, muy por debajo del mínimo legible. Este tono
   conserva el oro y sube el contraste a un nivel utilizable. El dorado
   original se reserva para fondos oscuros, donde sí rinde. */
html.editorial { --dorado-texto: #8A6A2C; }

.ed-hero__eyebrow {
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--dorado-texto);
  margin-bottom: var(--pad-s);
}

/* Los párrafos van en serif. EB Garamond tiene la altura de x mucho menor
   que Inter, así que al mismo cuerpo se leería más pequeña: se compensa
   subiendo un paso de escala y abriendo algo el interlineado. */
.ed-hero__lede {
  font-family: var(--font-serif);
  font-size: var(--ed-body);
  line-height: 1.5;
  color: var(--dorado-texto);
  max-width: 42ch;
  margin-top: var(--pad-s);
  margin-left: auto;
  margin-right: 18%;
}

.ed-hero__dot {
  display: inline-block;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--cardenal);
  vertical-align: middle;
  margin-left: 0.6rem;
}

/* ============================================================
   HERO EN MOVIL  (solo <=768 px; el escritorio no se toca)
   ============================================================
   En vertical el hero llegaba desordenado: la navegación en columna por el
   costado derecho, el titular escalonado contra el borde izquierdo, el
   párrafo pegado al titular y media pantalla vacía debajo. Aquí se compone
   de otra manera: todo centrado, con el mismo aire entre las tres piezas.
   Ninguna de estas reglas sale del bloque. */
@media (max-width: 1024px), (orientation: portrait) {

  /* Fuera los enlaces en vertical. Repiten exactamente lo que hay dentro del
     botón de menú, ocupan el costado entero y estorban la lectura. Lleva
     html.editorial delante porque la regla que los coloca en columna tiene
     esa especificidad y ganaba. */
  html.editorial .ed-hero .site-nav { display: none; }

  /* El logotipo, centrado. En escritorio va anclado al margen izquierdo, que
     es donde arranca el recorrido; en vertical no hay recorrido lateral y
     centrado alinea con el rótulo, el titular y el párrafo.

     Y a la misma altura que el botón de menú. Los dos son capas distintas
     —la marca va absoluta dentro del header, las acciones fijas y por
     fuera—, así que no hay una caja común que los alinee: hay que darles el
     mismo borde superior y el mismo alto. En vez de deducir cuánto mide el
     botón —relleno más línea de texto más filetes, que cambia con cada
     ajuste—, se le fija el alto a los dos con la misma variable y cada uno
     centra su contenido dentro. Así la alineación no depende de ningún
     cálculo que pueda quedarse viejo. */
  html.editorial { --alto-accion: 2.4rem; }

  html.editorial .ed-actions { height: var(--alto-accion); }

  /* Sin `display` aquí: el botón de agendar está oculto en vertical con
     `display: none`, y esta regla —más específica y posterior— se lo
     devolvía a la vista. El de menú ya viene en `inline-flex` de su propia
     regla, así que basta con centrarle el contenido. */
  html.editorial .ed-actions button {
    height: 100%;
    padding-block: 0;
    align-items: center;
  }

  html.editorial .site-logo {
    top: var(--edge);
    left: 50%;
    transform: translateX(-50%);
    height: var(--alto-accion);
    display: flex;
    align-items: center;
  }

  /* El bloque se centra de verdad: como conjunto y como texto. El escalonado
     del titular —pensado para una pantalla ancha— se anula, porque en 390 px
     esas sangrías solo desalinean. */
  .ed-hero__body {
    align-content: center;
    justify-items: center;
    width: 100%;
    padding-inline: var(--edge);
    text-align: center;
    /* La columna no puede crecer más que la pantalla. Sin esto es una
       columna automática, es decir, del ancho de su contenido más ancho: si
       una línea del titular se pasaba de largo, la columna entera se
       ensanchaba con ella y arrastraba al rótulo y al párrafo fuera de
       cuadro. Es lo que dejaba el párrafo sin aparecer en el iPad Mini
       —estaba, pero centrado en una columna más ancha que la ventana. */
    grid-template-columns: minmax(0, 1fr);
  }

  .ed-hero__title .ed-line { transform: none !important; }

  /* El titular parte antes de llegar al borde. El partidor convierte cada
     letra en un `inline-block`, y ahí se pierde el kerning entre pares: la
     línea que el navegador había medido como "cabe justo" crece un par de
     puntos al partirse y se sale. No es un ancho concreto el que falla —a
     768 px se comía la última palabra—, es que el margen entre "cabe" y "no
     cabe" era cero. Con el tope en 26ch la línea larga rompe una palabra
     antes y ese margen existe en cualquier formato. */
  .ed-hero__title {
    text-align: center;
    max-width: min(100%, 26ch);
  }

  /* Ritmo vertical unico: la misma distancia entre el logotipo y el rotulo,
     entre el rotulo y el titular, y entre el titular y el parrafo. El
     relleno superior lo fija el bloque para igualar la primera de las tres. */
  /* El ritmo lo pone el `row-gap` de la rejilla y no los margenes de cada
     pieza: asi las tres distancias son exactamente iguales, sin depender de
     que un margen se colapse con otro. El relleno superior iguala la primera,
     la que va del logotipo al rotulo. */
  .ed-hero__body {
    --ritmo-hero: 1.7rem;
    row-gap: var(--ritmo-hero);
    align-content: start;
    padding-top: calc(5.35rem + var(--ritmo-hero));
    padding-bottom: var(--pad-m);
  }

  .ed-hero__eyebrow {
    font-size: 0.62rem;
    letter-spacing: 0.2em;
    margin-bottom: 0;
  }

  .ed-hero__title { margin-bottom: 0; }

  .ed-hero__lede {
    font-size: 0.82rem;
    line-height: 1.7;
    max-width: 30ch;
    margin: 0 auto;
  }

  /* ---- El vídeo, a cara descubierta ----
     En escritorio el fondo va al 10 % sobre blanco: es atmósfera detrás de
     un titular oscuro. En vertical no hay nada que proteger arriba, así que
     el vídeo se ve entero y el texto baja sobre un velo que sube desde el
     pie. Se le quita también el filtro que lo lavaba: existía solo para que
     al 10 % no agrisara el blanco. */
  html.editorial { --hero-video-opacity: 1; }

  .ed-hero__backdrop video { filter: none; }

  /* El primer fotograma del vídeo, de fondo. La portada no puede esperar a
     que lleguen 1,6 MB: hasta entonces el papel blanco asomaba bajo un
     texto pensado para ir sobre imagen oscura. Con esta capa —28 KB— la
     entrada se ve terminada desde el primer pintado, y el vídeo funde
     encima cuando esté listo. Si nunca llega, esto es lo que queda, y no se
     nota que falte. */
  .ed-hero__backdrop {
    background-image: url("../images/brand/hero-proceso-vertical-720.webp");
    background-size: cover;
    background-position: center;
  }

  /* El grano se atenúa: en multiply sobre un vídeo ya oscuro ensuciaba. */
  html.editorial { --hero-grain-opacity: 0.22; }

  /* El velo. Arranca opaco abajo y se apaga a media altura: la parte de
     arriba queda de vídeo limpio y la de abajo sostiene el texto. */
  .ed-hero__backdrop::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(
      to top,
      rgb(10 10 10 / 92%) 0%,
      rgb(10 10 10 / 78%) 28%,
      rgb(10 10 10 / 42%) 52%,
      rgb(10 10 10 / 12%) 74%,
      transparent 100%);
  }

  /* El bloque baja sobre el velo. */
  .ed-hero__body {
    align-content: end;
    padding-top: 0;
    padding-bottom: calc(var(--pad-l) + 1.6rem);
  }

  /* Texto claro: el gris oscuro y el oro de escritorio están calculados para
     papel blanco y sobre el vídeo no llegan ni a 2:1. */
  .ed-hero__eyebrow { color: var(--dorado-light); }
  .ed-hero__title { color: var(--marfil); }
  .ed-hero__title .ed-char--accent,
  .ed-hero__title em { color: var(--dorado-light); }
  .ed-hero__lede { color: color-mix(in srgb, var(--marfil) 88%, transparent); }
  .ed-hero__foot { color: color-mix(in srgb, var(--marfil) 70%, transparent); }
}

/* ---- Panel de revelado: fondo con parallax + máscara con flip ----
   Replica el recurso del referente (flipMedia--upDown en su js_main.js):
   la capa superior sube fuera de la máscara y la inferior baja un poco.
   El contramovimiento es lo que crea la profundidad; si ambas se movieran
   igual parecería una sola imagen deslizándose. */
.ed-rail__panel--reveal {
  width: 78vw;
  position: relative;
  overflow: hidden;
  background: var(--onice);
  display: grid;
  place-items: center;
}

.ed-reveal__bg {
  position: absolute;
  inset: 0;
  /* Bastante más ancho que el panel: el parallax recorre 36 puntos y en
     ningún extremo debe asomar el borde. Con 160 % centrado quedan 30 % de
     margen a cada lado, justo por encima de lo que consume el recorrido. */
  width: 160%;
  left: -30%;
  will-change: transform;
}

.ed-reveal__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0.72;
}

/* La máscara. Todo lo que se mueve dentro queda recortado por ella. */
.ed-flip {
  position: relative;
  z-index: 2;
  margin: 0;
  width: min(46vw, 62rem);
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--onice);
}

.ed-flip__down,
.ed-flip__up {
  position: absolute;
  inset: 0;
}

.ed-flip__down { z-index: 1; }
.ed-flip__up { z-index: 2; will-change: transform; }

.ed-flip__down video,
.ed-flip__down img,
.ed-flip__up img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* El mismo recurso con dos fotografías en vez de foto y vídeo, y a sangre:
   ocupa el panel entero. Con una proporción fija de 3/4 la figura se
   quedaba más baja que el panel y dejaba una franja negra debajo que
   parecía un corte. Todo el material de marca es vertical, así que llenar
   el alto no obliga a recortar de más. */
.ed-flip--tall {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
}

/* Dentro del recuadro y no debajo: .ed-flip recorta lo que se salga, así que
   un pie colgado por fuera quedaría invisible. */
.ed-flip__caption {
  position: absolute;
  left: 1.2rem;
  bottom: 1rem;
  z-index: 3;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: var(--ed-micro-lh);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--marfil);
  text-shadow: 0 1px 8px rgb(0 0 0 / 55%);
}

/* ---- Capa de cine ----
   Se sitúa por encima del contenido pero por debajo de las acciones, para
   que el menú siga alcanzable mientras el vídeo ocupa la pantalla.
   No captura el ratón: es un momento del recorrido, no un reproductor.
   Ocupa siempre la pantalla completa; lo que se abre es el recorte, que
   arranca sobre el recuadro del panel (lo escribe editorial.js). */
.ed-cinema {
  position: fixed;
  inset: 0;
  z-index: var(--layer-header);
  background: var(--onice);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  will-change: opacity, clip-path;
}

.ed-cinema__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  will-change: transform;
}

/* ---- Ventana al vídeo del taller ----
   Misma familia que la capa de cine, pero aquí el vídeo no se mueve nunca:
   ocupa la pantalla desde el primer momento y lo único que cambia es el
   recorte. Cerrado, el recorte sigue al hueco del panel; abierto, se retiran
   los lados. Como el hueco ya mide el alto de la pantalla, la apertura es
   puramente horizontal y el encuadre no da ningún salto. */
.ed-proceso {
  position: fixed;
  inset: 0;
  /* Un punto por debajo de la cabecera, al revés que la capa de cine: esta
     se ve durante todo un tramo del recorrido, no solo un momento, y si
     fuera por encima taparía el logotipo cada vez que el hueco pasa por él. */
  z-index: calc(var(--layer-header) - 1);
  background: var(--onice);
  visibility: hidden;
  pointer-events: none;
  will-change: clip-path;
}

.ed-proceso__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* El hueco del panel. Sin JS se queda la imagen de respaldo y se lee como
   cualquier otro medio del recorrido. */
.ed-window {
  position: relative;
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--onice);
}

.ed-window img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Variante a sangre: ocupa el panel entero, de borde a borde y de arriba
   abajo. `.ed-window` ya es height:100%, así que basta con que la imagen
   recorte por cover en lugar de vivir dentro de un recuadro con proporción
   fija. */
.ed-window--llena { width: 100%; }

/* La capa que se desplaza para el parallax. Sobresale un 14 % por los
   CUATRO lados, no solo por los costados: al ensancharla únicamente en
   horizontal cambiaba la proporción de la caja y el recorte de `cover`
   pasaba a comerse la fotografía por arriba y por abajo —al cáliz le
   cortaba la peana—. Creciendo por igual, el encuadre se conserva y solo
   aparece margen para moverse. En reposo va centrada, así que la imagen se
   ve exactamente centrada en su contenedor. */
.ed-window__inner {
  position: absolute;
  inset: -14%;
  will-change: transform;
}

.ed-window__inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

.ed-window figcaption {
  position: absolute;
  left: var(--edge);
  bottom: var(--edge);
  z-index: 2;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: var(--ed-micro-lh);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--marfil);
  text-shadow: 0 1px 8px rgb(0 0 0 / 55%);
}

/* En vertical (móvil o movimiento reducido) el panel se lee como una
   imagen más: sin máscara ni parallax. */
.ed-rail[data-rail-state="static"] .ed-rail__panel--reveal { min-height: 70vh; }
.ed-rail[data-rail-state="static"] .ed-reveal__bg { width: 100%; left: 0; }
.ed-rail[data-rail-state="static"] .ed-flip { width: min(86vw, 52rem); }

.ed-hero__foot {
  position: absolute;
  left: var(--edge);
  bottom: var(--edge);
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dorado-texto);
}

/* Se retiró .ed-hero__scrollcue ("Desplace para recorrer"): el gesto es
   evidente y el rótulo competía con el pie de página del hero. */

@media (max-width: 1024px), (orientation: portrait) {
  /* Una sola fila. La segunda fila de 38vh reservaba un hueco vacío bajo el
     texto y, con el bloque alineado al final de la primera, el titular
     quedaba a media altura: el vídeo se leía como fondo recortado. Con una
     fila única el bloque baja hasta el pie y el vídeo queda entero arriba. */
  .ed-hero { grid-template-columns: 1fr; grid-template-rows: 1fr; }
  /* El tope del titular lo pone el bloque de arriba (26ch): aquí solo se
     retira el de 16ch del escritorio, que en columna partía demasiado. */
  /* Sangría mínima: el escalonado se insinúa pero ninguna línea desborda.
     Debe usar .ed-line y transform, igual que en escritorio; con los
     selectores antiguos (.line + padding) no aplicaba y la línea larga
     llegaba al borde. */
  .ed-hero__title .ed-line:nth-child(2) { transform: translateX(5%); }
  .ed-hero__title .ed-line:nth-child(3) { transform: translateX(2%); }
  /* `margin-inline: auto` y no `margin-right: 0`. El párrafo trae del
     escritorio un `margin-left: auto` con `margin-right: 18%`, que es lo que
     lo arrima al canto derecho junto al vídeo. Anulando solo el derecho
     quedaba el izquierdo en automático: mientras el párrafo ocupaba todo el
     ancho no se notaba, pero en cuanto tuvo una medida de lectura —la
     tableta— se fue contra el borde derecho. Centrado a los dos lados no
     depende de cuánto mida. */
  .ed-hero__lede { margin-inline: auto; max-width: none; }
}

/* ============================================================
   6. RECORRIDO HORIZONTAL  (Biblia §13)
   ============================================================ */

.ed-rail { position: relative; background: var(--onice); }

.ed-rail__viewport {
  position: relative;
  overflow: hidden;
  height: 100vh;
  height: 100svh;
}

.ed-rail__track {
  display: flex;
  align-items: stretch;
  height: 100%;
  width: max-content;
  will-change: transform;
}

.ed-rail__panel {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  overflow: hidden;
}

.ed-rail__panel--text {
  width: 52vw;
  display: grid;
  align-content: center;
  padding-inline: var(--edge);
  background: var(--onice);
  color: var(--marfil);
}

.ed-rail__panel--statement {
  width: 88vw;
  display: grid;
  align-content: center;
  padding-inline: var(--edge);
  background: var(--onice);
}

/* Sin white-space: nowrap. Lo llevaba para que la frase fuera una sola línea
   monumental, pero a cuerpo mega ninguna cabe en el panel y el overflow del
   panel la cortaba por el borde derecho: "Devoción hecha legado" mide unos
   1730 px y el panel deja 1217. Al dejarla partir, el partido por caracteres
   la reparte en dos líneas y se lee entera. */
.ed-rail__statement {
  font-family: var(--font-serif);
  font-size: var(--ed-mega);
  line-height: var(--ed-mega-lh);
  font-weight: 400;
  color: var(--marfil);
  margin: 0;
}

.ed-rail__statement em {
  font-style: italic;
  color: var(--dorado);
}

.ed-rail__panel--media { width: 46vw; }
.ed-rail__panel--media-wide { width: 62vw; }
.ed-rail__panel--media-narrow { width: 28vw; }

/* ---- Panel de manifiesto ----
   Compuesto como una portada: la imagen abre por la izquierda, el rótulo y
   el remate ocupan una columna estrecha, y el titular se lleva todo el ancho
   restante. El panel es ancho a propósito: el titular de antes iba sin
   partir y a cuerpo mega no cabía. */
.ed-rail__panel--manifest {
  width: 112vw;
  display: grid;
  align-content: center;
  padding-inline: var(--edge);
  background: var(--marfil);
  color: var(--onice);
}

/* El recuadro del juego de altar va al costado, no encima del texto: en
   pila se comía 230 px de alto, el bloque llegaba a 792 px de los 900 del
   panel y la firma quedaba cortada contra el borde. En columna propia el
   texto respira y el conjunto se lee como una portada.
   La fotografía de las manos sigue fuera de la retícula: ocupa el costado
   derecho del panel, a sangre. */
.ed-manifest {
  display: grid;
  grid-template-columns: 14rem minmax(0, 1fr);
  /* Sin rótulo "El manifiesto": la acotación en itálica pasa a encabezar el
     bloque, donde antes iba el rótulo. */
  grid-template-areas:
    "media note"
    "media title"
    "media by";
  column-gap: 3.6rem;
  align-items: start;
  /* El texto se detiene antes de la fotografía, con un respiro de --pad-m. */
  max-width: calc(112vw - 34vw - var(--edge) * 2 - var(--pad-m));
}

/* A sangre por la derecha: pegada al borde superior, al inferior y al
   costado, sin el margen del panel. Es el peso que sostiene la portada. */
.ed-manifest__retrato {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 34vw;
  margin: 0;
  overflow: hidden;
  background: var(--onice);
}

/* Cuadrada, no 3/4. La fotografía del juego de altar es apaisada y en un
   recuadro vertical el recorte se comía el cáliz y las vinajeras de los
   extremos; a 1/1 solo pierde un 6 % por lado y el conjunto se ve entero. */
.ed-manifest__media {
  grid-area: media;
  align-self: center;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: var(--onice);
}

.ed-manifest__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ed-manifest__label {
  grid-area: label;
  align-self: start;
  margin: 0 0 1.6rem;
  font-family: var(--font-serif);
  font-size: var(--ed-m);
  color: var(--gris-lectura);
}

/* El titular manda: serif en versales, interlínea corta y el texto partido
   en palabras para que se encienda al leerse. El cuerpo es menor que el de
   los otros titulares porque la frase es larga: a --ed-super ocuparía ocho
   líneas y dejaría de leerse como una declaración. */
.ed-manifest__title {
  grid-area: title;
  align-self: center;
  margin: 0;
  font-family: var(--font-serif);
  font-size: 3.9rem;
  line-height: 1.04;
  font-weight: 400;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

/* La frase que niega ("no es un adorno") queda de apoyo: en serif itálica
   para que se lea como una acotación y no compita con el titular. */
.ed-manifest__note {
  grid-area: note;
  align-self: start;
  margin: 0 0 1.6rem;
  font-family: var(--font-serif);
  font-size: var(--ed-m);
  line-height: 1.4;
  font-style: italic;
  color: var(--gris-lectura);
}

.ed-manifest__by {
  grid-area: by;
  margin: 2.2rem 0 0;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: var(--ed-micro-lh);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dorado-texto);
}

/* ---- Lectura progresiva ----
   Las palabras entran apagadas y toman cuerpo conforme se recorre el texto.
   El valor de reposo lo escribe el CSS para que sin JS el texto se lea
   entero; GSAP solo lo apaga cuando va a animarlo. */
.ed-w { opacity: 1; }

/* ---- Collage ----
   El panel del collage y el que lo sustituyó (la fotografía del baño de
   electrogalvanizado) ya no existen: el manifiesto cierra con las manos y
   el cáliz y de ahí se pasa directo a La Doctrina. Se retiran también
   .ed-collage y sus celdas, que llevaban sin marcado desde que el collage
   de nueve imágenes dejó paso a una sola. */

/* Ritmo lateral: los paneles de texto alternan claro y oscuro conforme se
   recorren, para que la tira no se lea como un bloque negro continuo. */
.ed-rail__panel--light {
  background: var(--marfil);
  color: var(--onice);
}

.ed-rail__panel--light .ed-chapter__text { color: var(--gris-lectura); }
.ed-rail__panel--light .ed-chapter__num { color: var(--cardenal); }
.ed-rail__panel--light .ed-rail__statement { color: var(--onice); }
.ed-rail__panel--light .ed-rail__statement em { color: var(--cardenal); }

/* Paneles con profundidad: el rezago lo escribe editorial.js en línea, aquí
   solo se avisa al compositor. */
.ed-rail__panel[data-ed-stack] { will-change: transform; }

/* Cierre del recorrido: un compás en cardenal antes de volver al vertical.
   Va un punto por debajo del cardenal general del sitio: es el último
   acorde, y conviene que pese más que las secciones que lo preceden.
   Blanco sobre este fondo mide 15,3:1 y el dorado claro 7,9:1. */
/* El fondo se elige por el color RESULTANTE, no por el que se escribe: el
   grano en screen levanta la media, así que la base va deliberadamente por
   debajo del tono al que se quiere llegar. Sin esta compensación el panel
   acababa más claro que el rojo anterior y la petición de oscurecerlo se
   quedaba en nada. */
html.editorial { --cardenal-noche: #340A12; }

.ed-rail__panel--cardenal {
  background: var(--cardenal-noche);
  color: var(--marfil);
  /* Aísla la mezcla del grano: sin esto se mezclaría con los paneles que
     quedan por detrás durante el solape. */
  isolation: isolate;
}

/* Grano fijo, no animado. Es la imagen especular del grano del hero.

   Allí, sobre papel blanco, solo multiply marcaba textura, y el ruido se
   sesgaba hacia el claro (gamma < 1) para no agrisar la página. Aquí el
   fondo es casi negro: multiply no haría nada y overlay tampoco —medido,
   subía la desviación a 0,71 niveles, invisible—, porque sobre una base
   oscura el overlay comprime todo el rango. Así que el ruido se sesga hacia
   el negro (gamma > 1) y se mezcla en screen: el grueso del ruido queda casi
   negro, que en screen no cambia nada, y solo las motas claras levantan el
   rojo. La textura se ve y la media apenas se mueve. */
.ed-rail__panel--cardenal::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0.4;
  mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='gamma' exponent='5'/%3E%3CfeFuncG type='gamma' exponent='5'/%3E%3CfeFuncB type='gamma' exponent='5'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
}

.ed-rail__panel--cardenal .ed-rail__statement { color: var(--marfil); }
.ed-rail__panel--cardenal .ed-rail__statement em { color: var(--dorado-light); }

/* Ancho y con la palabra arrimada a la izquierda, no centrada en 16vw.
   Medido: el panel siguiente invade hasta 154 px por el rezago del bloque,
   y en un panel de 230 px con el rótulo centrado eso se comía la palabra
   según avanzabas: parecía que la animación iba al revés, ocultando en vez
   de mostrar. Con más ancho y el texto fuera de la zona de solape, el
   rótulo se lee entero todo el rato. */
.ed-rail__panel--label {
  width: 30vw;
  display: grid;
  align-items: center;
  justify-items: start;
  padding-left: var(--pad-m);
  background: var(--onice);
  isolation: isolate;
}

.ed-label__fondo {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.ed-label__fondo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* Velo: el rótulo va en dorado y sobre la fotografía a plena luz se perdía.
   Con este peso el oro se sostiene y la imagen sigue leyéndose. */
.ed-label__fondo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgb(10 10 10 / 86%) 0%, rgb(10 10 10 / 62%) 60%, rgb(10 10 10 / 78%) 100%);
}

/* El mismo grano del resto del sitio. */
.ed-label__grano {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.3;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23d)'/%3E%3C/svg%3E");
}

.ed-rail__panel--label .ed-rail__vertical { position: relative; z-index: 2; }

/* El hero es el primer panel del recorrido: se entra por él y el scroll
   vertical lo desplaza lateralmente hacia el resto de capítulos. */
.ed-rail__panel--hero {
  width: 100vw;
  background: var(--marfil);
}

.ed-rail__panel--hero .ed-hero {
  height: 100%;
  min-height: 0;
}

.ed-rail__vertical {
  font-family: var(--font-display);
  font-size: var(--ed-xxl);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--dorado);
  writing-mode: vertical-rl;
  white-space: nowrap;
  margin: 0;
}

.ed-chapter { max-width: 30ch; }

.ed-chapter__num {
  font-family: var(--font-display);
  font-size: var(--ed-micro);
  letter-spacing: 0.3em;
  color: var(--dorado);
  display: block;
  margin-bottom: var(--pad-s);
}

/* Serif, como el titular de entrada. Los titulares de capítulo iban en la
   sans y rompían la voz que fija el hero: la casa habla en serif. */
.ed-chapter__title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--ed-xl);
  line-height: var(--ed-xl-lh);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin: 0 0 var(--pad-s);
}

/* Cuerpo menor y línea más aireada. El párrafo competía con el titular por
   tamaño y el capítulo se leía denso; con menos cuerpo y más interlínea el
   bloque respira y el titular recupera la jerarquía. */
.ed-chapter__text {
  font-family: var(--font-serif);
  font-size: var(--ed-body);
  line-height: 1.75;
  color: color-mix(in srgb, var(--marfil) 66%, transparent);
  margin: 0;
  max-width: 34ch;
}

.ed-rail__progress {
  position: absolute;
  left: var(--edge);
  right: var(--edge);
  bottom: var(--edge);
  height: 1px;
  background: color-mix(in srgb, var(--marfil) 18%, transparent);
  z-index: 3;
}

.ed-rail__progress i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--dorado);
}

/* Sin JS o con movimiento reducido, la tira se lee en vertical */
.ed-rail[data-rail-state="static"] .ed-rail__viewport { height: auto; overflow: visible; }
.ed-rail[data-rail-state="static"] .ed-rail__track { flex-direction: column; width: 100%; }
.ed-rail[data-rail-state="static"] .ed-rail__panel { width: 100%; height: auto; min-height: 62vh; }
/* Los paneles de texto se ajustan a su contenido: reservarles 62vh dejaba un
   hueco enorme sobre cada capítulo en la lectura vertical. */
.ed-rail[data-rail-state="static"] .ed-rail__panel--text,
.ed-rail[data-rail-state="static"] .ed-rail__panel--statement { min-height: 0; }
.ed-rail[data-rail-state="static"] .ed-rail__panel--label { min-height: 0; padding-block: var(--pad-m); }
.ed-rail[data-rail-state="static"] .ed-rail__panel--hero { min-height: 100vh; min-height: 100svh; }
.ed-rail[data-rail-state="static"] .ed-rail__panel--hero .ed-hero { min-height: 100vh; min-height: 100svh; }
.ed-rail[data-rail-state="static"] .ed-rail__statement { font-size: var(--ed-xxl); }

/* En vertical el manifiesto se apila y el titular baja de cuerpo; la retícula
   de tres columnas no cabe y los desplazamientos de línea sobran. */
.ed-rail[data-rail-state="static"] .ed-rail__panel--manifest { min-height: 0; padding-block: var(--pad-m); }

.ed-rail[data-rail-state="static"] .ed-manifest {
  grid-template-columns: 1fr;
  grid-template-areas: "media" "label" "title" "note" "retrato" "by";
  row-gap: var(--pad-s);
  max-width: none;
}

/* En vertical vuelve al flujo: aquí no hay costado que ocupar. El ancho va
   explícito porque el bloque alinea sus hijos a la izquierda y la figura,
   cuyo único hijo está posicionado, se quedaba en 0 px. */
.ed-rail[data-rail-state="static"] .ed-manifest__retrato {
  position: static;
  width: 100%;
  aspect-ratio: 3 / 4;
}

.ed-rail[data-rail-state="static"] .ed-manifest__media { width: 100%; }

/* El titular baja mas en vertical de lo que pedia --ed-xxl. A 360 px la
   palabra "recordatorio" medía 358 px en un hueco de 312: como el minimo
   automatico de un elemento de rejilla es su contenido minimo, esa palabra
   ensanchaba el bloque entero y sacaba 22 px de TODO el manifiesto fuera de
   la pantalla. Con 2,9rem la palabra mide 279 px y entra con holgura.
   El corte por palabra queda de red de seguridad: preferible partir una
   palabra larga a que el texto se salga. */
.ed-rail[data-rail-state="static"] .ed-manifest__title {
  font-size: 2.9rem;
  overflow-wrap: break-word;
}

/* Que el bloque pueda encoger en vez de empujar. */
.ed-rail[data-rail-state="static"] .ed-manifest,
.ed-rail[data-rail-state="static"] .ed-manifest > * { min-width: 0; }
.ed-rail[data-rail-state="static"] .ed-manifest__media { aspect-ratio: 4 / 3; }
.ed-rail[data-rail-state="static"] .ed-flip--tall { width: min(86vw, 40rem); }
/* En vertical el rotulo se tumba y pierde el nowrap: a --ed-xxl "La doctrina"
   medía 445 px en una pantalla de 360 y el panel se lo comía por el lado.
   Con 2,4rem y el interletraje mas corto entra entero. */
.ed-rail[data-rail-state="static"] .ed-rail__vertical {
  writing-mode: horizontal-tb;
  white-space: normal;
  font-size: 2.4rem;
  letter-spacing: 0.12em;
}
.ed-rail[data-rail-state="static"] .ed-rail__progress { display: none; }
.ed-rail[data-rail-state="static"] .ed-chapter { max-width: none; padding-block: var(--pad-m); }

/* ============================================================
   6a1b. EL RECORRIDO EN VERTICAL
   ============================================================
   Todo lo que sigue corrige la lectura en columna, la única que hay por
   debajo de 1025 px y en cualquier pantalla en retrato: es la frontera que
   se explica arriba, la que editorial.js usa para poner
   data-rail-state="static". El recorrido lateral no entra en ninguna de
   estas reglas. */
@media (max-width: 1024px), (orientation: portrait) {

  /* ---- Panel del pórtico: el vídeo ocupa la sección entera ----
     El recuadro de 16/9 dejaba la catedral asomando arriba y abajo, y
     encima la fotografía fija tapaba el vídeo para siempre: sin recorrido
     horizontal, el flip que la retira nunca se ejecuta. Aquí la máscara
     mide la pantalla y la fotografía pasa DETRÁS del vídeo, donde sigue
     valiendo de respaldo si el archivo no llega. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--reveal {
    min-height: 100vh;
    min-height: 100svh;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--reveal .ed-flip {
    width: 100%;
    height: 100vh;
    height: 100svh;
    aspect-ratio: auto;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--reveal .ed-flip__up {
    z-index: 0;
  }

  /* ---- El retrato del manifiesto, a su tamaño ----
     En vertical la figura pasaba a `position: static`, así que su capa de
     parallax —absoluta y con un 14 % de desbordamiento— dejaba de medirse
     contra la figura y se anclaba al panel entero: la fotografía se
     ampliaba hasta ocupar la pantalla y solo se veía el cáliz y una mano.
     Con `relative` vuelve a su caja, y sin desbordamiento se ve completa. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__retrato {
    position: relative;
    width: min(100%, 22rem);
    margin-inline: auto;
    aspect-ratio: 3 / 4;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__retrato .ed-window__inner {
    inset: 0;
  }

  /* ---- Un solo ritmo para los cuatro capítulos ----
     El capítulo I está aprobado: rótulo, titular y párrafo separados por
     --pad-s, y --pad-m de aire arriba y abajo. Los demás heredaban esas
     distancias de márgenes sueltos que se colapsan entre sí, y el IV
     añadía 4,8 rem entre el párrafo y el catálogo. Aquí el ritmo lo pone
     el `row-gap` de la rejilla, que no se colapsa: las tres distancias son
     idénticas en los cuatro capítulos. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-chapter {
    --ritmo-cap: var(--pad-s);
    display: grid;
    row-gap: var(--ritmo-cap);
    padding-block: var(--pad-m);
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-chapter__num,
  html.editorial .ed-rail[data-rail-state="static"] .ed-chapter__title {
    margin-bottom: 0;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-tipos__lista {
    margin-top: 0;
    padding-top: var(--ritmo-cap);
  }

  /* ---- El vídeo del taller, en su hueco ----
     Sin recorrido horizontal no hay capa de cine que lo abra, así que el
     panel se quedaba en la fotografía de respaldo. movil-video.js inyecta
     aquí un <video> ligero; la fotografía se retira solo cuando el vídeo
     está puesto, nunca antes. */
  html.editorial .ed-window--video > img { display: none; }

  html.editorial .ed-window__video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  /* ---- Los huecos negros de los paneles de fotografía ----
     No faltaba ninguna imagen: estaban puestas y medían cero. `.ed-window`
     pide `height: 100%`, y en vertical su panel ya no tiene alto fijo sino
     `min-height: 62vh` con alto automático, así que ese porcentaje no se
     resolvía contra nada y caía en `auto`. Como el único hijo de las
     ventanas a sangre es su capa de parallax, que va absoluta, la figura se
     quedaba en 0 px de alto y lo que se veía era el fondo ónice del panel:
     el hueco negro sobre el capítulo II, el de encima del IV y el que
     seguía al vídeo del taller.

     La cura es darles alto propio con una proporción y dejar que el panel
     se ajuste a ella, en vez de reservar 62vh que nadie ocupa. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--media,
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--media-wide,
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--media-narrow {
    min-height: 0;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-window {
    height: auto;
  }

  /* 4/5 y no la proporción de cada fotografía: son verticales de 3/4 largo
     y a pantalla completa cada una pedía 520 px de alto. Recortadas a 4/5
     miden lo mismo que la caja de un capítulo y el bloque no se descuelga. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-window--llena {
    aspect-ratio: 4 / 5;
  }

  /* El hueco del taller toma la proporción de su vídeo: así no sobra ni
     falta un píxel por debajo de la imagen. */
  html.editorial .ed-rail[data-rail-state="static"] [data-ed-window] {
    aspect-ratio: 16 / 9;
  }

  /* ---- El manifiesto ----
     La fotografía del juego de altar trae una franja de fondo de estudio en
     la parte de arriba. Anclando el recorte abajo, lo que `cover` se lleva
     es esa franja y no las piezas. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__media img {
    object-position: center bottom;
  }

  /* El orden que pidió la casa: primero las piezas, después la acotación
     ("Cada pieza de Alic no es un adorno") y al final la frase que manda. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest {
    grid-template-areas: "media" "note" "title" "retrato" "by";
  }

  /* Un punto menos de cuerpo: a 2,9rem la primera palabra llegaba a tocar
     el borde de la pantalla. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__title {
    font-size: 2.6rem;
  }

  /* ---- Los paneles se apilan ----
     El panel se queda clavado arriba y el siguiente sube por encima: el
     anterior parece meterse por debajo. La marca la pone movil-apilado.js,
     que solo se la da a los paneles que caben en la pantalla —a uno más
     alto se le vería siempre la misma franja y el resto no llegaría nunca.
     La sombra hacia arriba es lo que separa una capa de la siguiente; sin
     ella el relevo se lee como un corte y no como profundidad. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel--pegado {
    position: sticky;
    top: 0;
    box-shadow: 0 -1.4rem 3rem rgb(0 0 0 / 45%);
  }

  /* ---- Ni una capa de compositor de más ----
     `will-change: transform` está puesto para el recorrido horizontal, donde
     esas capas sí se mueven en cada fotograma. En vertical no se mueve
     ninguna: el riel está quieto y los paneles se apilan con `sticky`, que
     el navegador resuelve por su cuenta. Lo que quedaba era una decena de
     capas del tamaño de la pantalla reservadas en la memoria de vídeo del
     teléfono —más el vídeo a pantalla completa, más los tres del acordeón—,
     y cuando esa memoria se agota el navegador deja de pintar: son los
     bloques que aparecían en blanco o en negro. En el emulador del
     escritorio no pasa, porque ahí la memoria de vídeo es la del portátil. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__track,
  html.editorial .ed-rail[data-rail-state="static"] .ed-rail__panel[data-ed-stack],
  html.editorial .ed-rail[data-rail-state="static"] .ed-window__inner,
  html.editorial .ed-rail[data-rail-state="static"] .ed-flip__up,
  html.editorial .ed-rail[data-rail-state="static"] .ed-reveal__bg {
    will-change: auto;
  }

  /* ---- El catálogo de tipologías, centrado ----
     Se centran las dos cosas: la columna dentro del capítulo y el par
     icono + nombre dentro de cada renglón. Centrar solo una de las dos
     deja el bloque a la izquierda o los nombres desalineados entre sí. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-tipos__lista {
    justify-items: center;
    text-align: center;
  }

  html.editorial .ed-rail[data-rail-state="static"] .ed-tipos__lista li {
    grid-template-columns: auto auto;
    justify-content: center;
    align-items: center;
  }
}

/* ---- La franja de tableta (769-1024 px) ----
   Todo lo de la columna se afinó midiendo en un teléfono de 390 px, y en
   esas reglas los cuerpos van en rem. El truco es que --fsize, de donde
   sale el rem, ronda los 16-20 px en TODOS los cortes: un 0,82rem mide
   prácticamente lo mismo en un teléfono que en una tableta. Es decir, el
   texto no se hacía pequeño, se quedaba igual mientras la pantalla crecía
   al doble, y ahí sí se veía perdido. Aquí recupera la proporción.

   El corte no lleva `orientation` a propósito: una tableta apaisada de
   1024 px o menos también entra, y es exactamente el mismo caso. Empieza en
   700 y no en 769 porque el iPad Mini mide 768 justos y es una tableta,
   no un teléfono grande. Y pide 600 px de alto para dejar fuera al teléfono
   apaisado, que también mide entre 700 y 1024 de ancho pero solo 390 de
   alto: allí estos cuerpos no caben.

   El titular se declara aquí y no se hereda: entre 700 y 768 venía con el
   cuerpo del teléfono (47 px) y de 769 en adelante daba un salto a 88. Un
   solo valor para toda la franja quita el escalón. */
@media (min-width: 700px) and (max-width: 1024px) and (min-height: 600px) {
  html.editorial { --ed-super: 3.6rem; }

  .ed-hero__eyebrow { font-size: 0.78rem; letter-spacing: 0.26em; }
  .ed-hero__lede { font-size: 1.05rem; max-width: 44ch; }

  /* El velo del hero sube un poco: en una pantalla más alta el texto queda
     más lejos del borde inferior y necesita fondo bajo él, no solo al pie. */
  .ed-hero__body { padding-bottom: calc(var(--pad-l) + 3rem); }

  /* El capítulo y el manifiesto respiran: la medida de lectura vuelve a su
     sitio en vez de estirarse a lo ancho de la tableta. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-chapter { max-width: 46ch; }
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__title { font-size: 4.2rem; }
  html.editorial .ed-rail[data-rail-state="static"] .ed-manifest__retrato { width: min(100%, 30rem); }

  /* Las fotografías a sangre pueden ser algo menos altas: 4/5 en una
     tableta son 800 px de alto y el panel se comía la pantalla entera. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-window--llena { aspect-ratio: 1 / 1; }

  /* Dos columnas para las tipologías: en una sola, centradas y con esta
     anchura, la lista quedaba como una tira flotando en medio del panel. */
  html.editorial .ed-rail[data-rail-state="static"] .ed-tipos__lista {
    grid-template-columns: repeat(2, minmax(0, auto));
    justify-content: center;
  }

}

/* ============================================================
   6a2. PANEL "NUESTRAS PIEZAS"
   ============================================================
   Rótulo y catálogo de tipologías sobre la fotografía del juego de altar.
   El velo oscuro no es decorativo: sin él, el texto blanco cae sobre los
   dorados de la foto y deja de leerse. */

/* Grano de película sobre la fotografía, con el mismo ruido del resto del
   sitio. Va en su propia capa para poder mezclarlo en overlay sin afectar a
   los textos, que van por encima. */
.ed-piezas__grano {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.34;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23p)'/%3E%3C/svg%3E");
}

/* El rótulo hereda de .ed-window figcaption, que va en versales y con
   interletraje ancho. Aquí se anula: el catálogo se lee en caja baja, como
   en la referencia. */
/* Sin velo oscuro: la fotografía se ve limpia. Solo queda la leyenda, y su
   legibilidad la sostiene la sombra del propio texto. */
/* El selector lleva .ed-window delante a propósito: la regla base
   `.ed-window figcaption` fija left y bottom para los pies de foto, gana por
   especificidad y desplazaba este bloque 18 px a la derecha. Medido: la
   leyenda quedaba 13 px fuera del centro. */
.ed-window .ed-piezas__cara {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  /* Centrada también en vertical: pegada arriba parecía un rótulo suelto
     sobre la fotografía en vez de formar parte de ella. */
  align-content: center;
  /* La leyenda y la cruz se recuestan a la izquierda, sobre la zona más
     tranquila de la fotografía: centradas caían justo encima del copón
     dorado y se peleaban con él. */
  justify-items: start;
  gap: 1.6rem;
  padding: 3rem 2.4rem;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  font-size: inherit;
  color: var(--marfil);
  text-shadow: none;
  background: none;
}

/* El encuadre se corre a la izquierda: la peana y las dos piezas quedaban
   pegadas al borde derecho y el aire se acumulaba todo del otro lado. */
.ed-piezas .ed-window__inner img { object-position: 68% center; }

.ed-piezas__cruz {
  width: 2.4rem;
  height: 2.4rem;
  fill: none;
  stroke: var(--dorado);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ed-piezas__cruz path:nth-child(2) { fill: var(--dorado); stroke: none; }

.ed-piezas__sub {
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: 1.9;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--marfil);
  max-width: 20ch;
  /* Doble sombra: al correrse a la izquierda la leyenda pasó de la zona
     roja al cáliz plateado, y blanco sobre plata no llega ni a 2:1 de
     contraste. La sombra cerrada dibuja el borde de la letra y la abierta
     apaga el fondo. */
  text-shadow: 0 1px 2px rgb(0 0 0 / 80%), 0 2px 14px rgb(0 0 0 / 70%);
}

/* El catálogo de tipologías, ya dentro del capítulo IV: en blanco sobre el
   ónice, con los iconos en vector del mismo color. Dos columnas, que en una
   sola caía demasiado por debajo del párrafo. */
/* Filas de altura idéntica. "Custodias (Ostensorios)" ocupa dos renglones y
   con filas automáticas estiraba solo la suya, así que el espacio vertical
   entre unas y otras salía desigual. */
.ed-tipos__lista {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
  gap: 1.3rem 2rem;
  /* Antes eran 6rem de margen más 6rem de relleno: 180 px de vacío entre el
     párrafo y el catálogo que empujaban el rótulo "Capítulo IV" hasta los
     131 px, muy por encima de los 283 px de los demás capítulos. Al cerrar
     ese hueco el bloque baja y el catálogo sube. */
  margin: 2.4rem 0 0;
  padding: 2.4rem 0 0;
  list-style: none;
  /* Una línea muy tenue: separa sin dibujar. */
  border-top: 1px solid color-mix(in srgb, var(--dorado) 22%, transparent);
}

.ed-tipos__lista li {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  align-items: start;
  gap: 0.65rem;
  font-family: var(--font-serif);
  font-size: var(--ed-body);
  line-height: 1.3;
  color: var(--marfil);
}

.ed-tipos__lista svg {
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.16em;
  fill: none;
  stroke: var(--marfil);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ed-tipos__lista em { font-style: normal; display: block; }

/* Sobre los paneles claros el blanco no se ve: se invierte. */
.ed-rail__panel--light .ed-tipos__lista li { color: var(--onice); }
.ed-rail__panel--light .ed-tipos__lista svg { stroke: var(--onice); }

/* El capítulo que lleva el catálogo necesita más caja que los demás. */
/* El capítulo que lleva el catálogo necesita más caja que los demás.
   Probado a 50ch: el titular seguía partiendo en dos líneas, así que ese
   ancho no devolvía altura y solo desalineaba el bloque. */
.ed-chapter--ancho { max-width: 42ch; }

/* ============================================================
   6a3. CIERRE DEL RECORRIDO
   ============================================================
   La fotografía va al fondo con un velo en cardenal noche encima. El grano
   del panel (.ed-rail__panel--cardenal::after, z-index 3) se pinta sobre
   todo esto, así que la textura alcanza también a la imagen. */

/* El cierre ocupa la pantalla entera. Con los 88vw del panel de manifiesto
   quedaba a la vista una franja del panel anterior a la izquierda, y el
   remate del recorrido perdía toda la fuerza. */
.ed-rail__panel--cierre {
  width: 100vw;
  display: grid;
  place-items: center;
}

/* El velo cardenal, colgado del panel y no de .ed-cierre__fondo, con un
   píxel de holgura por cada lado. El hilo dorado que asomaba en el borde
   durante el zoom no lo arreglaba esto —lo comprobé: seguía igual—, sino
   quitarle la capa de compositor a la fotografía (force3D: false y fuera
   el will-change). Se queda aquí de todos modos: un velo que desborda el
   recorte no puede dejar ver la imagen cruda por ninguna costura. */
.ed-rail__panel--cierre::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: 1;
  pointer-events: none;
  background: color-mix(in srgb, var(--cardenal-noche) 82%, transparent);
}

/* La fotografía entra con un punto de más de escala y se asienta al llegar:
   es el movimiento que pedía el cierre sin añadir otro mecanismo. */
/* Sin `will-change: transform`: promocionaba la fotografía a capa del
   compositor y el recorte del panel dejaba escapar un píxel sin velo. */

.ed-cierre__fondo {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.ed-cierre__fondo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  display: block;
}

/* El velo ya no vive aquí: lo pone .ed-rail__panel--cierre::before. Lo que
   queda es el color de fondo, para que ni un instante de carga deje ver
   blanco bajo la fotografía. */
.ed-cierre__fondo { background: var(--cardenal-noche); }

.ed-cierre {
  position: relative;
  z-index: 2;
  display: grid;
  justify-items: center;
  gap: 1.4rem;
  padding-block: var(--pad-s);
  text-align: center;
  max-width: 46rem;
}

.ed-cierre__intro {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--marfil);
}

.ed-cierre__claim {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--ed-xl);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.045em;
  text-transform: uppercase;
  color: var(--dorado-light);
}

.ed-cierre__marca { width: 13rem; height: auto; display: block; }

.ed-cierre__lema {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: 1.9;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--marfil) 78%, transparent);
}

.ed-cierre__firma {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--ed-small);
  line-height: 1.7;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--dorado-light);
}

@media (max-width: 900px) {
  .ed-cierre__marca { width: 9rem; }
  /* En estrecho el catálogo vuelve a una sola columna. */
  .ed-tipos__lista { grid-template-columns: 1fr; }
}

/* ============================================================
   6b. ACORDEÓN DE PIEZAS
   ============================================================
   Tres vídeos verticales que se solapan un poco, como tres cartas abiertas
   en abanico. No se amplían ni piden clic: se reproducen solos mientras la
   sección está a la vista.

   El desnivel va en transform y no en margen para que el ratón pueda
   levantarlos sin descolocar la fila. Por eso mismo el bloque no lleva
   entrada animada pieza a pieza: GSAP escribiría su propia transform encima
   y borraría el desnivel. La entrada se anima en el contenedor. */

.ed-acordeon {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-inline: var(--edge);
}

.ed-acordeon__item {
  --lift: 2.8rem;
  position: relative;
  flex: 0 0 auto;
  width: 26vw;
  aspect-ratio: 9 / 16;
  margin: 0;
  overflow: hidden;
  background: var(--onice);
  transform: translateY(var(--lift));
  transition: transform 0.7s var(--ease-out);
}

/* El del medio manda: va arriba del todo y por delante. */
.ed-acordeon__item:nth-child(2) { --lift: 0rem; z-index: 3; }
.ed-acordeon__item:nth-child(1) { z-index: 1; }
.ed-acordeon__item:nth-child(3) { z-index: 2; }
.ed-acordeon__item + .ed-acordeon__item { margin-left: -3vw; }

.ed-acordeon__item:hover,
.ed-acordeon__item:focus-within {
  --lift: -1.4rem;
  z-index: 4;
}

.ed-acordeon__item video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ed-acordeon__item figcaption {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  display: grid;
  gap: 0.35rem;
  padding: 4rem 1.6rem 1.4rem;
  color: var(--marfil);
  /* El degradado asienta el rótulo sobre cualquier fotograma. */
  background: linear-gradient(to top, rgb(0 0 0 / 78%), transparent);
}

.ed-acordeon__num {
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.2em;
  color: var(--dorado-light);
}

.ed-acordeon__name {
  font-family: var(--font-serif);
  font-size: var(--ed-l);
  line-height: 1.1;
}

.ed-acordeon__meta {
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: var(--ed-micro-lh);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--marfil) 72%, transparent);
}

/* En estrecho el abanico no cabe: se apilan y se leen de una en una. */
@media (max-width: 900px) {
  .ed-acordeon { flex-direction: column; align-items: center; gap: var(--pad-s); }
  .ed-acordeon__item { --lift: 0rem; width: min(78vw, 34rem); }
  .ed-acordeon__item + .ed-acordeon__item { margin-left: 0; }
  .ed-acordeon__item:hover,
  .ed-acordeon__item:focus-within { --lift: 0rem; }
}

/* ============================================================
   7. MEDIA: barrido + parallax
   ============================================================ */

.ed-media {
  --clip: 0%;
  --shift: 0%;
  position: relative;
  overflow: hidden;
  background: var(--onice);
  clip-path: inset(var(--clip) 0 0 0);
}

/* Solo dentro del recorrido el medio ocupa todo el alto del panel. Fuera de
   él manda el aspect-ratio del contenedor (tarjeta o bloque editorial); si se
   fuerza height:100% con altura automática, el contenido desborda la sección. */
.ed-rail__panel > .ed-media { height: 100%; }

.ed-media__inner {
  position: absolute;
  inset: -12% 0;
  height: 124%;
  transform: translateY(var(--shift));
  will-change: transform;
}

.ed-media__inner img,
.ed-media__inner video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ed-media__caption {
  position: absolute;
  left: var(--edge);
  bottom: var(--edge);
  z-index: 2;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--marfil);
  mix-blend-mode: difference;
}

/* ============================================================
   8. SECCIONES VERTICALES
   ============================================================ */

.ed-section { position: relative; }

.ed-grid12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
  padding-inline: var(--edge);
}

.ed-quote {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: var(--ed-xxl);
  line-height: var(--ed-xxl-lh);
  color: var(--cardenal);
  margin: 0;
  grid-column: 2 / 11;
  text-wrap: balance;
}

.ed-quote__by {
  grid-column: 2 / 11;
  margin-top: var(--pad-s);
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gris-santo);
}

.ed-sectionhead { grid-column: 1 / 7; }
.ed-sectionhead--right { grid-column: 7 / 13; }

.ed-label {
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gris-santo);
  display: block;
  margin-bottom: var(--pad-xs);
}

.ed-h2 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--ed-xxl);
  line-height: var(--ed-xxl-lh);
  text-transform: uppercase;
  letter-spacing: -0.015em;
  margin: 0;
}

.ed-h2 em {
  font-family: var(--font-serif);
  font-style: italic;
  text-transform: none;
  font-weight: 400;
}

.ed-p {
  font-family: var(--font-serif);
  font-size: var(--ed-body-l);
  line-height: 1.5;
  color: var(--gris-lectura);
  margin: 0;
  max-width: 46ch;
}

.bg-onice .ed-p { color: color-mix(in srgb, var(--marfil) 62%, transparent); }
.bg-onice .ed-label { color: var(--dorado); }
.bg-cardenal .ed-label { color: var(--dorado-light); }
.bg-cardenal .ed-p { color: color-mix(in srgb, var(--marfil) 78%, transparent); }

/* ---- Piezas clásicas ----
   La otra mitad de la casa: cadenas, cruces y anillos. Va en marfil entre
   dos secciones oscuras y su trabajo es dejar respirar el sitio, así que
   aquí las fotografías no se tocan como en el catálogo: llevan calle ancha
   y desnivel alterno. */
.ed-clasicas__tira {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1.2rem;
  align-items: start;
  margin-top: var(--pad-m);
  padding-inline: var(--edge);
}

.ed-clasicas__foto {
  margin: 0;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  background: var(--onice);
}

/* El desnivel alternando. Alineadas a la misma altura las seis se leían
   como un muestrario; escalonadas, como una tira de contactos. */
.ed-clasicas__foto:nth-child(even) { margin-top: 3.2rem; }

.ed-clasicas__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 1.1s var(--ease-out);
}

.ed-clasicas__foto:hover img { transform: scale(1.04); }

@media (max-width: 1100px) {
  .ed-clasicas__tira { grid-template-columns: repeat(3, 1fr); gap: 1rem; }
}

@media (max-width: 640px) {
  .ed-clasicas__tira { grid-template-columns: repeat(2, 1fr); }
  .ed-clasicas__foto:nth-child(even) { margin-top: 2rem; }
}

/* ---- Cierre: consulta privada ----
   La fotografía del juego de altar va al fondo, bajo el velo cardenal y el
   grano. El texto se queda por encima, sobre el mismo color de siempre. */
/* overflow oculto porque el velo desborda un píxel: sin él, ese píxel
   ensanchaba el documento y aparecía barra horizontal. Medido: 1 px. */
.ed-cierre-cta { position: relative; isolation: isolate; overflow: hidden; }

.ed-cierre-cta > *:not(.ed-cierre-cta__fondo) { position: relative; z-index: 3; }

.ed-cierre-cta__fondo {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}

.ed-cierre-cta__fondo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
  display: block;
}

/* El velo cuelga de la sección, no del recuadro de la fotografía, y desborda
   un píxel por cada lado: es la misma precaución que en el cierre del
   recorrido, donde una capa recortada dejaba asomar un hilo sin velar. */
.ed-cierre-cta::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: 1;
  pointer-events: none;
  background: color-mix(in srgb, var(--cardenal-noche) 88%, transparent);
}

.ed-cierre-cta::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.28;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='q'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23q)'/%3E%3C/svg%3E");
}

/* ---- Fichas de colección ----
   Tira continua: las piezas se tocan y el nombre va dentro de la fotografía,
   sobre un degradado que sube desde abajo. Antes iban separadas 1,5rem con
   los rótulos debajo, en gris sobre marfil, y el conjunto se leía como tres
   tarjetas sueltas en vez de como un catálogo. */
.ed-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  padding-inline: 0;
}

/* El catálogo completo va en cuatro columnas: son diez piezas y en tres
   quedaban filas de sobra; en cuatro la tira se lee de un vistazo. */
.ed-cards--catalogo { grid-template-columns: repeat(4, 1fr); }

/* Diez piezas en cuatro columnas son 4 + 4 + 2, y esa última fila dejaba
   media pantalla en blanco justo antes de la sección cardenal. Las dos
   últimas ocupan dos columnas cada una y cierran la tira; con 3/2 en vez de
   3/4 quedan a la misma altura que las filas de arriba (479 px contra 476)
   y no se leen como una excepción. */
.ed-cards--catalogo .ed-card:nth-last-child(-n + 2) {
  grid-column: span 2;
  aspect-ratio: 3 / 2;
}

/* La ficha es una retícula de tres filas y la fotografía las ocupa las tres:
   así el alto lo sigue marcando la imagen, pero los rótulos van en flujo, en
   las dos últimas filas, y se empujan entre sí. Con los rótulos absolutos un
   título de dos líneas —"Cáliz Corazón de Oro"— crecía hacia arriba y se
   montaba encima de la categoría. */
.ed-card {
  position: relative;
  display: grid;
  /* La columna va declarada aunque sea una sola: sin retícula explícita de
     columnas, el `-1` de `grid-area` en la figura apunta a la línea 1 —el
     final de un grid explícito vacío— y la fotografía se quedaba en 0 px de
     ancho, o en el ancho del rótulo. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 1fr auto auto auto;
  /* La proporción va en la ficha, no en la figura. Con ella en la figura, y
     la figura ocupando las tres filas, el alto lo decidían las filas —auto,
     auto y un 1fr sin nada que lo estirara— y la ficha se quedaba en 114 px
     con los rótulos fuera de la fotografía. */
  aspect-ratio: 3 / 4;
  color: inherit;
}

.ed-card__media {
  grid-area: 1 / 1 / -1 / -1;
  position: relative;
  height: 100%;
  overflow: hidden;
  background: var(--onice);
}

.ed-card__media img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transition: transform 1.1s var(--ease-out);
}

/* Velo cardenal de abajo arriba. Sube hasta media altura y ahí se apaga del
   todo: la pieza tiene que verse entera, el velo solo está para que el
   nombre en blanco tenga sobre qué apoyarse. */
.ed-card__media::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--cardenal-noche) 94%, transparent) 0%,
    color-mix(in srgb, var(--cardenal-noche) 62%, transparent) 26%,
    color-mix(in srgb, var(--cardenal-noche) 22%, transparent) 48%,
    transparent 66%);
}

/* El mismo grano del resto del sitio, apenas insinuado. */
.ed-card__media::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23c)'/%3E%3C/svg%3E");
}

/* La categoria, debajo del nombre y a la izquierda: es el dato menor de los
   tres y arriba, alineada a la derecha, competia con el titulo. */
.ed-card__cat {
  grid-column: 1;
  grid-row: 4;
  z-index: 3;
  margin: 0;
  padding: 0 1.6rem 1.4rem;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  line-height: var(--ed-micro-lh);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--marfil) 64%, transparent);
}

.ed-card:hover .ed-card__media img { transform: scale(1.03); }

/* Relevo al pasar el ratón: la segunda vista de la misma pieza se funde
   sobre la primera. Va apagada de entrada y solo se enciende con :hover y
   con :focus-visible, para que también responda al tabulador. */
.ed-card__relevo {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.55s var(--ease-out), transform 1.1s var(--ease-out);
}

.ed-card:hover .ed-card__relevo,
.ed-card:focus-visible .ed-card__relevo { opacity: 1; }

/* En un teléfono no hay ratón que pasar por encima, así que esa segunda
   vista no se llega a ver nunca: son diez fotografías que se descargan para
   nada mientras el catálogo intenta pintarse. Sin caja no hay carga
   diferida que atender, y el navegador se las ahorra. */
@media (hover: none) {
  .ed-card__relevo { display: none; }
}

/* Rótulos dentro de la fotografía. Van absolutos para que la ficha mida
   exactamente lo que mide la imagen y las piezas encajen unas con otras. */
.ed-card__meta {
  /* La columna va explicita: sin ella los rotulos se auto-colocaban en una
     segunda columna implicita, que se llevaba 313 de los 357 px de la ficha
     y dejaba la fotografia en 44. */
  grid-column: 1;
  grid-row: 2;
  z-index: 3;
  padding: 0 1.6rem 0.35rem;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--ed-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--marfil) 74%, transparent);
}

.ed-card__title {
  grid-column: 1;
  grid-row: 3;
  z-index: 3;
  padding: 0 1.6rem 0.3rem;
  font-family: var(--font-sans);
  font-weight: 300;
  /* Cuerpo pequeño, como en la referencia: a --ed-m (1,6rem) el nombre
     pesaba más que la propia fotografía. */
  font-size: var(--ed-small);
  line-height: var(--ed-small-lh);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0;
  color: var(--marfil);
}

@media (max-width: 1100px) {
  /* Diez piezas a cuatro columnas en una pantalla mediana dejan la ficha por
     debajo de 250 px y el nombre no cabe en una línea. */
  .ed-cards--catalogo { grid-template-columns: repeat(2, 1fr); }
  /* A dos columnas las diez encajan solas: sin fila coja no hace falta el
     ensanche del final. */
  .ed-cards--catalogo .ed-card:nth-last-child(-n + 2) { grid-column: auto; aspect-ratio: 3 / 4; }
}

@media (max-width: 768px) {
  /* El catalogo se queda en dos columnas tambien en movil: es una cuadricula
     de piezas y de una en una se pierde la lectura de conjunto. Las de
     coleccion, que son tres rotulos anchos, si van de una en una. */
  .ed-cards { grid-template-columns: 1fr; }
  .ed-cards--catalogo { grid-template-columns: repeat(2, 1fr); }
  /* Los rótulos van dentro de la fotografía, así que cada punto de cuerpo
     que se les quita es fotografía que se ve. A 0,78rem el nombre partía en
     dos renglones y la categoría en otros dos: cuatro líneas de texto sobre
     la pieza. Con estos cuerpos casi todos los nombres entran en uno.
     El interletraje también se recoge: es lo que hacía partir "Piezas
     Monumentales", no el tamaño. */
  .ed-cards--catalogo .ed-card__meta {
    padding-inline: 0.9rem;
    font-size: 0.56rem;
    letter-spacing: 0.12em;
  }

  .ed-cards--catalogo .ed-card__title {
    padding-inline: 0.9rem;
    padding-bottom: 0.2rem;
    font-size: 0.66rem;
    letter-spacing: 0.04em;
  }

  .ed-cards--catalogo .ed-card__cat {
    padding-inline: 0.9rem;
    padding-bottom: 1rem;
    font-size: 0.54rem;
    letter-spacing: 0.1em;
  }
  .ed-quote, .ed-quote__by { grid-column: 1 / -1; }
  .ed-sectionhead, .ed-sectionhead--right { grid-column: 1 / -1; }
}

/* Bloque editorial a dos columnas */
.ed-split {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
  padding-inline: var(--edge);
  align-items: center;
}

.ed-split__text { grid-column: 1 / 6; }
.ed-split__media { grid-column: 7 / 13; aspect-ratio: 4 / 5; }

@media (max-width: 768px) {
  .ed-split__text, .ed-split__media { grid-column: 1 / -1; }
  .ed-split__media { margin-top: var(--pad-m); }
}

/* ============================================================
   9. REVEALS
   ============================================================
   Estado inicial oculto SOLO si el JS ya tomó el control. Sin JS, todo
   se ve. Ver AGENTS.md §8 y Biblia §4.1. */

/* Las líneas ya vienen medidas y cerradas por el partidor, así que no deben
   volver a fluir: sin nowrap el navegador las re-rompe y deja palabras
   sueltas; con caracteres además cortaría a mitad de palabra.

   El overflow hace de máscara para el revelado vertical, pero también
   recortaría en horizontal el espacio final que cada línea lleva para no
   pegar palabras al copiar. El padding da esa holgura y el margen negativo
   la descuenta, de modo que el ancho de layout no cambia. */
.ed-line {
  display: block;
  overflow: hidden;
  white-space: nowrap;
}

/* La máscara solo sirve mientras el texto entra. Una vez revelado se
   retira: si se deja, recorta cualquier movimiento posterior que saque
   contenido de la caja de la línea, como la deriva de "Artesanía".
   Retirarla además evita tener que dar holgura lateral a la caja, que en
   móvil desbordaba el ancho de pantalla unos pocos píxeles. */
[data-ed-revealed] .ed-line { overflow: visible; }

/* Solo estructura. El estado oculto lo aplica GSAP con estilos en línea, no
   el CSS: si se declara aquí, GSAP lee ese valor como destino de la
   animación y acaba animando de 105% a 105%, dejando el párrafo invisible
   para siempre. Sin JavaScript no hay estado oculto y el texto se lee. */
.js-enhanced [data-ed-lines] .ed-line > span { display: block; }

/* Caracteres: cada uno es un bloque en línea para poder desplazarlo en Y
   dentro de su línea, que actúa de máscara. */
.ed-char {
  display: inline-block;
  will-change: transform;
}

/* Igual que arriba: el estado oculto lo pone GSAP en línea, nunca el CSS. */

/* ============================================================
   10. MOVIMIENTO REDUCIDO
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .ed-loader { display: none !important; }
  .js-enhanced [data-ed-lines] .ed-line > span { transform: none !important; }
  .js-enhanced [data-ed-fade] { opacity: 1 !important; transform: none !important; }
  .ed-media { --clip: 0% !important; }
  .ed-media__inner { transform: none !important; }
  /* El relevo sigue funcionando, pero sin fundido: el cambio de vista es
     información, la transición solo era el gusto de verla. */
  .ed-card__media img { transition: none; }
  .ed-card__relevo { transition: none; }
  .ed-clasicas__foto img { transition: none; }
}
