/* =============================================================================
   CONSTRUCCIONES EGLAVIN S.L. — Sistema de diseño
   -----------------------------------------------------------------------------
   Concepto: "El Plano". Tinta azul corporativa + papel, retículas de línea fina
   como en un plano técnico, tipografía display grande, fotografía real.
   Paleta extraída literalmente de construccioneseglavin.com.

   La web se recorre EN HORIZONTAL en escritorio: cada sección es un panel de
   una pantalla dentro de una pista que avanza hacia la derecha. Por debajo de
   1025px los mismos paneles se apilan en vertical sin cambiar el marcado.

   Este archivo contiene únicamente reglas en uso: sin clases huérfanas.
   ============================================================================= */

/* ---------- 0. FUENTES ---------------------------------------------------
   Inter y Syne servidas desde el propio dominio (licencia OFL): sin peticiones
   a Google, que con el RGPD requerirían consentimiento. Son fuentes variables:
   un archivo por familia cubre todos los pesos. Subconjunto latino (español
   y alemán completos).
-------------------------------------------------------------------------- */
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Syne"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("../fonts/syne-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. TOKENS ----------------------------------------------------- */
:root {
  /* Color — valores REALES extraídos de la web original */
  --eg-ink:        #0D131A;
  /* El mismo tinta, pero fijo: para cuando se usa como FONDO y no como
     color de texto, donde no debe seguir a la superficie. */
  --eg-ink-fixed:  #0D131A;
  --eg-ink-soft:   #1D1E20;
  --eg-blue:       #415BA3;
  --eg-azure:      #57A3FA;
  --eg-steel:      #B8C0CC;
  --eg-paper:      #FAFAFA;
  --eg-white:      #FFFFFF;

  /* Derivados: mismos matices, distinta luminosidad */
  --eg-night:      #111A2B;
  --eg-mist:       #E7EBF2;
  --eg-line:       #D7DCE5;
  --eg-line-dark:  rgba(255, 255, 255, .16);
  --eg-muted:      #5A6475;
  --eg-muted-dark: rgba(255, 255, 255, .62);
  /* Acento sensible a la superficie: azul medio sobre claro, azul claro
     sobre oscuro. Son los dos azules que ya tiene la marca, sin color nuevo. */
  --eg-accent:     var(--eg-blue);
  /* Color de error: granate sobre claro; rosado sobre oscuro, donde el granate
     daba 2,8:1 y los avisos del formulario no se leían. */
  --eg-error:      #B4254C;

  /* Tipografía */
  --font-display: "Syne", "Trebuchet MS", sans-serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono:    ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --fs-display:  clamp(1.8rem, .5rem + 4.95vw, 6rem);
  --fs-h1:       clamp(1.9rem, .95rem + 3.1vw, 4rem);
  --fs-h2:       clamp(1.75rem, 1.05rem + 2.9vw, 3.75rem);
  --fs-h3:       clamp(1.3rem,  1.05rem + 1.05vw, 2rem);
  --fs-lead:     clamp(1.0625rem, .99rem + .55vw, 1.5rem);
  --fs-body:     clamp(1rem, .975rem + .11vw, 1.0625rem);
  --fs-small:    .875rem;
  /* 12px: a 11 las etiquetas en versalitas eran lo que más costaba leer */
  --fs-label:    .75rem;

  --lh-display: .92;
  --lh-tight:   1.04;
  --lh-head:    1.1;
  --lh-body:    1.68;

  --tr-label: .16em;
  --tr-tight: -.025em;

  /* Espaciado — escala 4px */
  --s-2: .5rem;   --s-3: .75rem;  --s-4: 1rem;
  --s-5: 1.5rem;  --s-6: 2rem;    --s-7: 2.5rem;  --s-8: 3rem;
  --s-9: 4rem;

  --section-y-sm: clamp(3rem, 2rem + 4.5vw, 7rem);

  /* Contenedor y retícula */
  --container: 1680px;
  --measure:   68ch;
  --gutter:    clamp(1.25rem, .55rem + 2.9vw, 5rem);
  --grid-gap:  clamp(1.25rem, .6rem + 2.2vw, 3rem);

  --hairline: 1px;

  /* Movimiento */
  --ease:      cubic-bezier(.22, .61, .36, 1);
  --ease-out:  cubic-bezier(.16, 1, .3, 1);
  --t-fast:    .22s;
  --t-base:    .42s;

  /* Capas */
  --z-sticky: 50; --z-menu: 110; --z-header: 115; --z-modal: 120;

  /* 60px: con 80 la barra se comía el 11–12 % de un portátil y achataba
     todos los paneles, que miden «pantalla menos cabecera». */
  --header-h: 60px;
  /* Altura útil de un panel: la ventana menos la barra de cabecera. Toda la
     escala vertical se calcula sobre esta medida, no sobre 100vh. */
  --ph: calc(100dvh - var(--header-h));
}

@media (max-width: 860px) { :root { --header-h: 56px; } }
/* Pantallas bajas (portátiles pequeños, móviles en horizontal): la altura
   manda tanto como el ancho. En un móvil apaisado la barra llegaba al 19 %. */
@media (max-height: 680px) { :root { --header-h: 50px; } }

/* ---------- 2. RESET ------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

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

body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--eg-ink);
  background: var(--eg-white);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* 'clip' recorta sin crear contenedor de scroll. Con 'hidden' el navegador
     fuerza overflow-y:auto y eso rompe position:sticky, que es lo que sostiene
     el recorrido horizontal. No cambiar a 'hidden'. */
  overflow-x: clip;
  font-variant-ligatures: common-ligatures;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
/* <picture> no debe generar caja: así la <img> sigue siendo hija directa del
   contenedor y height:100% / object-fit resuelven contra el marco real. */
picture { display: contents; }
/* El color de reserva va en el contenedor, nunca en <img>: un PNG con
   transparencia (el logotipo) mostraría ese color como un rectángulo. */
.figure, .wpanel__media, .post-card__media, .pcard__media { background-color: var(--eg-mist); }

input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
h1, h2, h3, h4, h5, h6 { font-weight: inherit; font-size: inherit; text-wrap: balance; }
p { text-wrap: pretty; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--eg-accent); outline-offset: 3px; border-radius: 1px; }
::selection { background: var(--eg-blue); color: #fff; }
/* Los controles con estado :active propio no necesitan el recuadro gris del
   toque en móvil, que además ignora el radio de la cápsula. */
.btn, .wpanel, .menu-toggle, .tab, .lb-btn, .lb-close { -webkit-tap-highlight-color: transparent; }
/* En flujo vertical la cabecera es fija: un ancla no debe quedar debajo. */
main [id] { scroll-margin-top: var(--header-h); }

/* Paso entre páginas: fundido corto del documento entero (Chrome, Edge,
   Safari 18.2+). Los navegadores sin soporte navegan como siempre. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vtOut .24s var(--ease) both; }
::view-transition-new(root) { animation: vtIn .46s var(--ease-out) both; }
@keyframes vtOut { to { opacity: 0; } }
@keyframes vtIn  { from { opacity: 0; } }

/* Piezas de movimiento compartidas. El estado oculto vive SÓLO en el
   fotograma «from» (se usan con fill «backwards»): si la animación no llega
   a ejecutarse, el contenido se ve igual. */
@keyframes riseIn { from { opacity: 0; translate: 0 18px; } }
@keyframes fadeIn { from { opacity: 0; } }
@keyframes spin   { to { rotate: 1turn; } }

.skip-link {
  position: absolute; left: var(--gutter); top: -100%;
  z-index: var(--z-modal);
  background: var(--eg-ink-fixed); color: #fff;
  padding: var(--s-3) var(--s-5);
  font-size: var(--fs-small); font-weight: 600;
  transition: top var(--t-fast) var(--ease);
}
.skip-link:focus-visible { top: var(--s-4); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ---------- 3. SUPERFICIES ------------------------------------------------ */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }

.bg-paper { background: var(--eg-paper); }
.bg-night { background: var(--eg-night); }
/* Toda superficie oscura gira los mismos tokens, venga de una clase de fondo
   o de una cabecera de página: así ninguna hereda tinta sobre azul noche. */
.bg-night, .page-hero, .hero {
  color: #fff;
  --eg-ink: #fff;
  --eg-line: var(--eg-line-dark);
  --eg-muted: var(--eg-muted-dark);
  --eg-accent: var(--eg-azure);
  --eg-error: #FF8FA3;
}

/* Retícula de plano: sólo en superficies oscuras, casi imperceptible */
.blueprint { position: relative; isolation: isolate; }
.blueprint::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: repeating-linear-gradient(
    to right, rgba(255,255,255,.055) 0 1px, transparent 1px calc(100% / 12));
  background-size: calc(100% - (2 * var(--gutter))) 100%;
  background-position: var(--gutter) 0;
  background-repeat: no-repeat;
}
@media (max-width: 768px) { .blueprint::before { display: none; } }

/* ---------- 4. TIPOGRAFÍA ------------------------------------------------- */
.display, .h1, .h2, .h3 {
  font-family: var(--font-display);
  letter-spacing: var(--tr-tight);
  font-weight: 700;
}
.display { font-size: var(--fs-display); line-height: var(--lh-display); font-weight: 800; }
.h1      { font-size: var(--fs-h1); line-height: var(--lh-tight); }
.h2      { font-size: var(--fs-h2); line-height: var(--lh-head); }
.h3      { font-size: var(--fs-h3); line-height: 1.18; letter-spacing: -.015em; }

/* Declaración editorial: frase larga real tratada como pieza tipográfica */
.statement {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.4rem, .72rem + 2.35vw, 3rem);
  line-height: 1.16; letter-spacing: -.028em;
  text-wrap: pretty;
  max-width: 34ch;
}
/* Declaración de longitud media: algo menos de cuerpo y más medida de línea. */
.statement--mid {
  font-size: clamp(1.3rem, .78rem + 1.8vw, 2.4rem);
  line-height: 1.2; max-width: 42ch;
}
/* Párrafo largo tratado como declaración: cuerpo contenido, interlínea más
   abierta y medida de lectura, para que se lea como texto y no como muro. */
.statement--long {
  font-size: clamp(1.15rem, .9rem + .95vw, 1.75rem);
  line-height: 1.45; letter-spacing: -.018em; max-width: 50ch;
}
.statement em { font-style: normal; color: var(--eg-accent); }

/* En español NO se parten palabras: una palabra larga baja entera a la línea
   siguiente, nunca dejando letras sueltas. El alemán sí se guiona, que es su
   convención tipográfica para los compuestos largos. */
.display, .h1, .h2, .h3, .statement,
.fact__v, .wpanel__name, .post-card__title {
  overflow-wrap: normal; word-break: normal; hyphens: manual;
}
/* Excepción: los nombres de proyecto son compuestos alemanes también en la
   página española ("Seniorenpflegeeinrichtung…"). Sólo se parten si no caben. */
.pcard__name, .ptable__name, .ptable__place { overflow-wrap: break-word; min-width: 0; }
html[lang="de"] .h1, html[lang="de"] .h2, html[lang="de"] .h3,
html[lang="de"] .statement, html[lang="de"] .fact__v,
html[lang="de"] .pcard__name, html[lang="de"] .wpanel__name,
html[lang="de"] .footer__v {
  hyphens: auto;
  /* Si el navegador no dispone de diccionario alemán, el compuesto se parte
     antes que desbordar. En español esta red NO se aplica. */
  overflow-wrap: break-word;
}

.lead {
  font-size: var(--fs-lead); line-height: 1.5; font-weight: 400;
  color: var(--eg-ink); max-width: 32ch; letter-spacing: -.012em;
}
.bg-night .lead { color: #fff; }

.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--s-5); }
.prose p { color: var(--eg-muted); }
.bg-night .prose p { color: rgba(255,255,255,.76); }
.prose--lg p { font-size: clamp(1.0625rem, 1rem + .3vw, 1.1875rem); }

.label {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-family: var(--font-body);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--eg-muted); line-height: 1;
}
.label--rule::before { content: ""; width: 2.5rem; height: 1px; background: currentColor; opacity: .5; flex: none; }
.bg-night .label { color: rgba(255,255,255,.66); }

.index-num {
  font-family: var(--font-display); font-size: var(--fs-label); font-weight: 700;
  letter-spacing: .14em; color: var(--eg-accent); display: block;
}

/* ---------- 5. BOTONES — píldora translúcida ------------------------------
   No llevan color propio: dejan pasar el fondo a través de un velo
   desenfocado, así el mismo botón funciona sobre fotografía o sobre papel.
-------------------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  min-height: 54px; padding: 0 var(--s-7);
  border-radius: 999px;
  border: var(--hairline) solid rgba(13, 19, 26, .14);
  background: rgba(13, 19, 26, .055);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  box-shadow: 0 1px 0 rgba(255,255,255,.7) inset, 0 6px 18px rgba(13,19,26,.08);
  color: var(--eg-ink);
  font-size: var(--fs-small); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  line-height: 1; text-align: center;
  transition: background-color var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease),
              transform var(--t-fast) var(--ease-out);
}
.btn:hover, .btn:focus-visible { background: rgba(13,19,26,.1); border-color: rgba(13,19,26,.26); }
/* Respuesta táctil: se hunde un píxel y cede un 1,5 %, sin rebote */
.btn:active { transform: translateY(1px) scale(.985); transition-duration: .08s; }

/* Sobre fondo oscuro o fotografía, el velo se invierte */
.btn--ghost-light, .bg-night .btn, .panel--hero .btn, .page-hero .btn {
  border-color: rgba(255,255,255,.22);
  background: rgba(255,255,255,.13);
  color: #fff;
  box-shadow: 0 1px 0 rgba(255,255,255,.25) inset, 0 6px 18px rgba(13,19,26,.10);
}
.btn--ghost-light:hover, .bg-night .btn:hover, .panel--hero .btn:hover, .page-hero .btn:hover {
  background: rgba(255,255,255,.24); border-color: rgba(255,255,255,.42);
}

/* El botón principal sí lleva color de marca, conservando la cápsula */
.btn--primary, .bg-night .btn--primary {
  background: var(--eg-blue); border-color: var(--eg-blue); color: #fff;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: 0 6px 18px rgba(65, 91, 163, .28);
}
.btn--primary:hover, .btn--primary:focus-visible {
  background: var(--eg-ink-fixed); border-color: var(--eg-ink-fixed); color: #fff;
  box-shadow: 0 10px 26px rgba(13, 19, 26, .26);
}

.btn__icon { transition: transform var(--t-base) var(--ease-out); flex: none; }
.btn:hover .btn__icon { transform: translateX(4px); }

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .btn { background: rgba(255,255,255,.82); }
  .btn--ghost-light, .bg-night .btn, .panel--hero .btn, .page-hero .btn { background: rgba(13,19,26,.48); }
}

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }

.link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-small); font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  padding-bottom: 4px;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size var(--t-base) var(--ease-out), color var(--t-fast) var(--ease);
}
.link:hover, .link:focus-visible { background-size: 0% 1px; color: var(--eg-accent); }
.link:hover .btn__icon { transform: translateX(4px); }

/* ---------- 6. CABECERA — barra sólida, modelo DPR ------------------------
   DPR mantiene una barra blanca fija con filete inferior y texto oscuro,
   siempre igual. Es la solución correcta: el texto nunca cambia de color, así
   que nunca hay un estado ilegible. El contenido empieza por debajo, de modo
   que la cabecera no tapa nada.
-------------------------------------------------------------------------- */
.header {
  position: fixed; inset: 0 0 auto 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex; align-items: center;
  /* Cristal oscuro de marca: degradado de la tinta al azul, translúcido y con
     desenfoque, de modo que en móvil se intuye lo que sube por detrás.
     La opacidad no baja del 82 %: con un panel blanco detrás, el texto blanco
     sigue en 5,9:1. El extremo derecho es un azul corporativo oscurecido
     (#2E4078): el #415BA3 puro, translúcido sobre blanco, se quedaba en 4,2:1. */
  background: linear-gradient(100deg,
    rgba(13, 19, 26, .9) 0%, rgba(17, 26, 43, .86) 45%, rgba(46, 64, 120, .82) 100%);
  -webkit-backdrop-filter: blur(18px) saturate(170%);
  backdrop-filter: blur(18px) saturate(170%);
  color: #fff;
  --eg-accent: var(--eg-azure);
  transition: transform .5s var(--ease-out);
}
/* En flujo vertical (tableta y móvil) la barra se retira al bajar y vuelve
   al subir: el JS pone la clase y nunca la pone con el menú abierto, con el
   foco dentro de la barra ni cerca del principio de la página. */
.header.is-hidden { transform: translate3d(0, -100%, 0); }
/* Progreso del recorrido: en horizontal la barra de scroll nativa es
   vertical y no dice cuánto falta; este hilo sobre el filo sí. */
.header::before {
  content: ""; position: absolute; left: 0; bottom: 0; z-index: 1;
  width: 100%; height: 2px; pointer-events: none;
  background: var(--eg-azure);
  box-shadow: 0 0 10px rgba(87, 163, 250, .55);
  transform-origin: 0 50%;
  transform: scaleX(var(--progress, 0));
  opacity: 0; transition: opacity var(--t-base) var(--ease);
}
.header.has-progress::before { opacity: 1; }
/* Filo de luz: separa la barra de los paneles oscuros, con los que se fundiría */
.header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, rgba(87,163,250,0) 0%, rgba(87,163,250,.55) 35%, rgba(255,255,255,.45) 65%, rgba(87,163,250,0) 100%);
  pointer-events: none;
}
/* Sin desenfoque, un fondo translúcido dejaría el texto de debajo nítido
   detrás de la barra: estorbaría al leer. En ese caso, opaco. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .header { background: linear-gradient(100deg, #0D131A 0%, #111A2B 45%, #2E4078 100%); }
}
.header__inner {
  width: 100%; max-width: var(--container); margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: var(--s-5);
}
.header__logo { display: flex; align-items: center; height: 100%; flex: none; }
.header__logo img {
  /* Sin max-width: con él, en móviles estrechos la columna del logo cedía
     todo su hueco y la imagen llegaba a medir 0px de ancho. */
  /* Proporcional a la barra: hasta el 80 % de su alto */
  height: min(clamp(38px, 3.1vw, 48px), calc(var(--header-h) * .8)); width: auto;
  /* El logo nunca se estrecha: si falta sitio, baja de alto (ver ≤420px).
     max-width:none anula el «img { max-width: 100% }» general, que en una
     columna de ancho automático lo comprimía. */
  flex: none; max-width: none;
  object-fit: contain; object-position: left center;
  /* El logotipo original es blanco y la barra es oscura: se usa tal cual */
}

.nav { display: flex; justify-content: center; }
.nav__list { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.5rem); }
.nav__link {
  position: relative; font-size: var(--fs-small); font-weight: 500;
  letter-spacing: .03em; padding: var(--s-2) 0; white-space: nowrap;
}
.nav__link::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform var(--t-base) var(--ease-out);
}
.nav__link:hover::after, .nav__link:focus-visible::after { transform: scaleX(1); transform-origin: left; }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { font-weight: 600; }

.header__aside { grid-column: 3; display: flex; align-items: center; gap: var(--s-5); }

/* Selector de idioma con bandera */
.lang { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); }
.lang__item {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  opacity: .62; padding: 4px 2px;
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase;
  transition: opacity var(--t-fast) var(--ease);
}
.lang__item:hover, .lang__item:focus-visible, .lang__item[aria-current="true"] { opacity: 1; }
.lang__flag {
  width: 18px; height: 13.5px; object-fit: cover; flex: none;
  border: var(--hairline) solid rgba(0,0,0,.18); border-radius: 1px;
}
.lang__sep { opacity: .3; }
/* Sobre la barra oscura el idioma inactivo necesita más presencia: con .62
   quedaba por debajo de 4,5:1 cuando pasa contenido claro por detrás. */
.header .lang__item { opacity: .85; }
.header .lang__item:hover, .header .lang__item:focus-visible, .header .lang__item[aria-current="true"] { opacity: 1; }
.header .lang__flag { border-color: rgba(255, 255, 255, .35); }
.lang--full .lang__item { letter-spacing: .02em; text-transform: none; font-size: .8125rem; font-weight: 500; }
.lang--full .lang__flag { width: 20px; height: 15px; }

/* Botón de menú */
.menu-toggle {
  display: none; align-items: center; gap: var(--s-3);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--tr-label); text-transform: uppercase; padding: var(--s-2);
  transition: opacity var(--t-fast) var(--ease);
}
.menu-toggle:active { opacity: .7; }
.menu-toggle__bars { position: relative; width: 22px; height: 10px; flex: none; }
.menu-toggle__bars span {
  position: absolute; left: 0; width: 100%; height: 1.5px; background: currentColor;
  transition: transform var(--t-base) var(--ease-out);
}
.menu-toggle__bars span:nth-child(1) { top: 0; }
.menu-toggle__bars span:nth-child(2) { bottom: 0; }
.menu-toggle[aria-expanded="true"] .menu-toggle__bars span:nth-child(1) { transform: translateY(4.25px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] .menu-toggle__bars span:nth-child(2) { transform: translateY(-4.25px) rotate(-45deg); }

/* El menú completo cabe en todo el modo escritorio (≥1025px): ocupa ~380px
   y a 1025px quedan ~550 libres. Por debajo, botón «Menú». */
@media (max-width: 1024px) {
  .nav { display: none; }
  .menu-toggle { display: inline-flex; }
}
@media (max-width: 420px) {
  .header__inner, .header__aside { gap: var(--s-3); }
  .header__logo img { height: 34px; }
  .header .lang { gap: 6px; }
  .header .menu-toggle { gap: var(--s-2); }
}
/* Por debajo de 375px sólo se ve el icono del menú; la palabra sigue
   disponible para lectores de pantalla. */
@media (max-width: 374px) {
  .header__logo img { height: 30px; }
  .header .menu-toggle > span:first-child {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

/* Panel de menú a pantalla completa */
.menu-panel {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--eg-night); color: #fff;
  display: flex; flex-direction: column;
  padding: calc(var(--header-h) + var(--s-7)) var(--gutter) var(--s-8);
  overflow-y: auto; overscroll-behavior: contain;
  transform: translateY(-100%); opacity: 0; visibility: hidden;
  will-change: transform;
  transition: transform .62s var(--ease-out), opacity .3s var(--ease), visibility 0s linear .62s;
}
.menu-panel.is-open { transform: translateY(0); opacity: 1; visibility: visible; transition-delay: 0s, 0s, 0s; }
.menu-panel__list { display: flex; flex-direction: column; border-top: var(--hairline) solid var(--eg-line-dark); }
.menu-panel__item { border-bottom: var(--hairline) solid var(--eg-line-dark); }
.menu-panel__link {
  display: flex; align-items: baseline; gap: var(--s-4);
  padding: clamp(.85rem, 2.2vw, 1.5rem) 0;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1rem + 5vw, 3.25rem);
  font-weight: 700; letter-spacing: var(--tr-tight); line-height: 1.05;
  transition: color var(--t-fast) var(--ease);
}
.menu-panel__link:hover, .menu-panel__link:focus-visible { color: var(--eg-azure); }
@media (hover: hover) {
  .menu-panel__link { transition: color var(--t-fast) var(--ease), translate var(--t-base) var(--ease-out); }
  .menu-panel__link:hover { translate: 10px 0; }
}
/* Al abrir, las entradas suben en cascada detrás de la cortina */
.menu-panel.is-open .menu-panel__item { animation: riseIn .7s var(--ease-out) backwards; }
.menu-panel.is-open .menu-panel__item:nth-child(1) { animation-delay: .16s; }
.menu-panel.is-open .menu-panel__item:nth-child(2) { animation-delay: .22s; }
.menu-panel.is-open .menu-panel__item:nth-child(3) { animation-delay: .28s; }
.menu-panel.is-open .menu-panel__item:nth-child(4) { animation-delay: .34s; }
.menu-panel.is-open .menu-panel__item:nth-child(n+5) { animation-delay: .40s; }
.menu-panel.is-open .menu-panel__foot { animation: fadeIn .8s var(--ease) .46s backwards; }
.menu-panel__num {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: .14em;
  color: var(--eg-azure); flex: none; font-family: var(--font-body);
}
.menu-panel__foot {
  margin-top: auto; padding-top: var(--s-8);
  display: flex; flex-wrap: wrap; gap: var(--s-5) var(--s-8);
  justify-content: space-between; align-items: flex-end;
  font-size: var(--fs-small); color: rgba(255,255,255,.7);
}
.menu-panel__foot a:hover { color: #fff; }
.menu-panel .lang__flag { border-color: rgba(255,255,255,.35); }

/* =============================================================================
   7. RECORRIDO HORIZONTAL
   -----------------------------------------------------------------------------
   El contenedor exterior es alto; el interior queda fijo bajo la cabecera y la
   pista se traslada en X según el progreso. Es scroll NATIVO: la rueda, el
   gesto, la barra, las teclas y el foco funcionan sin interceptarse.
   ============================================================================= */
.hcanvas { position: relative; background: var(--eg-night); }
.hcanvas__viewport { position: relative; display: flex; flex-direction: column; }
.hcanvas__track { display: flex; flex-direction: column; }

@media (min-width: 1025px) {
  .hcanvas__viewport {
    position: sticky;
    /* Justo bajo la barra de cabecera, que así nunca tapa contenido */
    top: var(--header-h);
    height: calc(100vh - var(--header-h));
    height: calc(100dvh - var(--header-h));
    /* clip y no hidden: un contenedor «hidden» sigue siendo desplazable por
       programa, y al tabular el navegador lo movía para enseñar el foco,
       descolocando el recorrido. «clip» recorta igual pero no se desplaza.
       hidden queda como respaldo para navegadores sin clip. */
    overflow: hidden; overflow: clip; flex-direction: row;
  }
  .hcanvas__track { flex-direction: row; align-items: stretch; height: 100%; will-change: transform; }
  /* El deslizamiento lateral lo traduce el JS en recorrido; el vertical y el
     zoom con dos dedos siguen siendo del navegador. */
  .hcanvas { touch-action: pan-y pinch-zoom; }

  .panel {
    position: relative; flex: none; height: 100%;
    display: flex; flex-direction: column; justify-content: center;
    padding-block: clamp(2rem, 1.4rem + 1.8vw, 3.5rem);
    padding-inline: clamp(2rem, 1rem + 3.2vw, 5.5rem);
    border-left: var(--hairline) solid var(--eg-line);
    overflow: hidden; overflow: clip;
  }
  .panel:first-child { border-left: 0; }
  .panel.bg-night { border-left-color: var(--eg-line-dark); }

  /* Anchos deliberados: cada panel ocupa lo que su contenido necesita */
  .panel--hero    { width: 100vw; padding: 0; border-left: 0; }
  .panel--wide    { width: min(92vw, 1180px); }
  .panel--mid     { width: min(74vw, 940px); }
  .panel--narrow  { width: min(52vw, 640px); }
  .panel--work    { width: min(46vw, 560px); }
  .panel--project { width: clamp(380px, 30vw, 470px); }
  .panel--footer  { width: min(100vw, 1500px); }

  .panel__inner { width: 100%; }
}

/* Flujo vertical normal por debajo del umbral */
@media (max-width: 1024px) {
  body { padding-top: var(--header-h); }
  .panel { padding-block: var(--section-y-sm); }
  .panel + .panel { border-top: var(--hairline) solid var(--eg-line); }
  .panel--hero { padding: 0; border-top: 0; }
  .panel > .panel__inner { padding-inline: var(--gutter); }
}

/* --- Diapositivas: profundidad por apilado --------------------------------
   Cada panel avanza con la pista hasta el borde izquierdo; ahí se queda
   quieto y el siguiente se desliza POR ENCIMA, como una baraja. El que queda
   debajo retrocede un poco y se oscurece; el que entra proyecta su sombra
   sobre él. Al final el mazo entero se retira y descubre el pie, que
   esperaba fijo debajo. No hay desenfoque ni atenuado del contenido.
   Variables que escribe el JS en cada panel:
     --pin     desplazamiento que lo mantiene quieto (px)
     --sink    0 → 1, cuánto lo han cubierto: retroceso y velo
     --lift    0 → 1, sombra del panel que entra sobre el anterior
     --reveal  0 → 1, sombra del último panel sobre el pie que se descubre
     --p       0 entrando · .5 centrado · 1 saliendo (paralaje del contenido)
     --focus   1 en pantalla · 0 en los bordes (zoom de la fotografía)
-------------------------------------------------------------------------- */
@media (min-width: 1025px) {
  .panel {
    --p: .5; --focus: 1; --pin: 0px; --sink: 0; --lift: 0; --reveal: 0;
    transform: translate3d(var(--pin), 0, 0) scale(calc(1 - .05 * var(--sink)));
    transform-origin: 0% 50%;
    box-shadow:
      -26px 0 46px -18px rgba(8, 12, 20, calc(.5 * var(--lift))),
       26px 0 46px -18px rgba(8, 12, 20, calc(.5 * var(--reveal)));
  }
  /* Velo del panel que va quedando debajo */
  .panel::after {
    content: ""; position: absolute; inset: 0; z-index: 3;
    background: var(--eg-ink-fixed);
    opacity: calc(.42 * var(--sink));
    pointer-events: none;
  }

  .panel .figure img,
  .panel .wpanel__media img,
  .panel .pcard__media img,
  .panel .post-card__media img {
    transform: scale(calc(1.18 - .18 * var(--focus)));
    transform-origin: center;
    will-change: transform;
  }

  .panel__inner {
    transform: translate3d(calc((var(--p) - .5) * -44px), 0, 0);
    will-change: transform;
  }

  .panel--hero .hero__media img { transform: translate3d(calc((var(--p) - .5) * 70px), 0, 0) scale(1.1); }
  .panel--hero .hero__inner { transform: translate3d(calc((var(--p) - .5) * -34px), 0, 0); }
}

/* --- Pie que se descubre en flujo vertical ---------------------------------
   En tableta y móvil (y con movimiento reducido) el recorrido es vertical:
   el pie queda fijo abajo, detrás del contenido, y aparece cuando el último
   bloque sube. Sólo se activa si el pie cabe entero en la pantalla —el JS
   pone la clase—; si no, se vería cortado por arriba y se queda como está. */
.has-reveal .panel { position: relative; z-index: 1; }
.has-reveal .panel--footer { position: sticky; bottom: 0; z-index: 0; }
.has-reveal .panel:nth-last-child(2) { box-shadow: 0 26px 40px -22px rgba(8, 12, 20, .45); }

/* Pista de que se avanza hacia la derecha */
.hhint {
  position: fixed; right: var(--gutter); bottom: var(--s-6);
  z-index: var(--z-sticky);
  display: none; align-items: center; gap: var(--s-3);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: #fff; mix-blend-mode: difference;
  width: max-content; padding-right: 8px;
  transition: opacity var(--t-base) var(--ease);
}
@media (min-width: 1025px) { .hhint { display: flex; } }
.hhint.is-gone { opacity: 0; pointer-events: none; }
.hhint__arrow { animation: hhintSlide 1.9s var(--ease) infinite; }
@keyframes hhintSlide { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(7px); } }

/* Barra de recorrido (la crea el JS y sólo existe con el recorrido
   horizontal activo). En reposo es un hilo que no tapa contenido: queda
   dentro del margen inferior de los paneles, que nunca baja de 16 px. Al
   moverse, al pasar el ratón o al arrastrarla gana grosor y enseña la
   sección en curso sobre el pulgar.
   El carril es gris medio translúcido: se distingue igual sobre los paneles
   azul noche que sobre los de papel. El pulgar, azul claro con filete de
   tinta, también (más de 3:1 contra ambos fondos). */
.hbar {
  position: fixed; left: var(--gutter); right: var(--gutter); bottom: 6px;
  z-index: var(--z-sticky);
  display: none;
  /* Sólo el carril recibe el puntero: un enlace que quede cerca del borde
     inferior (en un portátil de 600 px de alto, «Ir al blog» está a 13 px)
     sigue siendo pulsable a ambos lados de la barra. */
  pointer-events: none;
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.hbar.is-on { display: block; }
.hbar__rail {
  position: relative; width: 100%; height: 2px; border-radius: 999px;
  background: rgba(128, 138, 156, .34);
  pointer-events: auto; cursor: pointer; touch-action: none;
  transition: height var(--t-base) var(--ease-out), background-color var(--t-base) var(--ease);
}
/* Zona de agarre invisible: del borde inferior de la ventana a 5 px por
   encima del carril (12–14 px). Con dedo, algo más alta. */
.hbar__rail::before { content: ""; position: absolute; left: -8px; right: -8px; top: -4px; bottom: -7px; }
@media (pointer: coarse) { .hbar__rail::before { top: -14px; } }
.hbar__tick {
  position: absolute; top: 50%; width: 1px; height: 6px;
  background: rgba(128, 138, 156, .7);
  transform: translate(-50%, -50%);
  transition: height var(--t-base) var(--ease-out);
}
.hbar__thumb {
  position: absolute; left: 0; top: 50%; height: 4px; border-radius: 999px;
  background: var(--eg-azure);
  box-shadow: 0 0 0 1.5px rgba(13, 19, 26, .5), 0 2px 10px rgba(13, 19, 26, .22);
  cursor: grab;
  transition: height var(--t-base) var(--ease-out);
  will-change: transform;
}
.hbar__label {
  position: absolute; left: 50%; bottom: calc(100% + 12px);
  max-width: 30ch; padding: 6px 12px; border-radius: 999px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-label); font-weight: 600; line-height: 1.2;
  letter-spacing: .12em; text-transform: uppercase; color: #fff;
  background: rgba(13, 19, 26, .82);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 6px 18px rgba(13, 19, 26, .2);
  transform: translate(-50%, 4px); opacity: 0;
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease-out);
  pointer-events: none;
}
.hbar__label:empty { display: none; }
.hbar.is-active .hbar__rail, .hbar:hover .hbar__rail, .hbar.is-dragging .hbar__rail { height: 4px; background: rgba(128, 138, 156, .44); }
.hbar.is-active .hbar__tick, .hbar:hover .hbar__tick, .hbar.is-dragging .hbar__tick { height: 10px; }
.hbar.is-active .hbar__thumb, .hbar:hover .hbar__thumb, .hbar.is-dragging .hbar__thumb { height: 8px; }
.hbar.is-active .hbar__label, .hbar:hover .hbar__label, .hbar.is-dragging .hbar__label { opacity: 1; transform: translate(-50%, 0); }
.hbar.is-dragging .hbar__thumb { cursor: grabbing; }
/* Mientras se arrastra: sin selección de texto y con la mano cerrada en
   toda la pantalla, aunque el puntero se salga de la barra. */
.is-hdragging, .is-hdragging * { cursor: grabbing !important; -webkit-user-select: none; user-select: none; }
/* Con la barra propia sobran la vertical del navegador y el hilo de
   progreso de la cabecera, que es para el flujo vertical. */
.has-hbar { scrollbar-width: none; }
.has-hbar::-webkit-scrollbar { display: none; }
.has-hbar .header::before { display: none; }

/* ---------- 7b. APARICIÓN DEL CONTENIDO -----------------------------------
   Los bloques llegan con un desplazamiento corto en la dirección del
   recorrido (de la derecha en horizontal, de abajo en vertical) y las
   fotografías se descubren con una cortina que avanza en ese mismo sentido,
   mientras la imagen se asienta de 1.14× a 1×.
   La clase .rv la pone el JS SÓLO a lo que está fuera de pantalla al cargar:
   lo que ya se ve nunca parpadea, sin JS no se oculta nada y con movimiento
   reducido el JS no actúa. Sólo opacity, translate y clip-path: sin
   recálculo de diseño.
-------------------------------------------------------------------------- */
:root { --rv-x: 0px; --rv-y: 28px; --rv-clip: inset(0 0 100% 0); }
@media (min-width: 1025px) { :root { --rv-x: 48px; --rv-y: 0px; --rv-clip: inset(0 100% 0 0); } }

.rv { opacity: 0; translate: var(--rv-x) var(--rv-y); }
.rv--media { clip-path: inset(0 0 0 0); }
.rv.rv--media { opacity: 1; translate: none; clip-path: var(--rv-clip); }
.rv.rv--media img { scale: 1.14; }
.rv-in {
  transition: opacity .9s var(--ease-out) var(--rv-d, 0s),
              translate 1.1s var(--ease-out) var(--rv-d, 0s),
              clip-path 1.25s cubic-bezier(.7, 0, .2, 1) var(--rv-d, 0s);
}
/* .panel delante: debe ganar a las transiciones propias de cada imagen
   (.figure--zoom, galería) mientras dura la entrada. */
.panel .rv-in img { transition: scale 1.7s var(--ease-out) var(--rv-d, 0s), opacity .7s var(--ease); }

/* Fotografía diferida: aparece con un fundido al terminar de cargar en vez
   de pintarse a trozos. El JS pone la clase sólo a las que aún no han
   llegado; el fondo niebla del marco ocupa el hueco mientras tanto. */
.figure img, .wpanel__media img, .pcard__media img { transition: opacity .7s var(--ease), scale 1s var(--ease-out); }
img.is-loading { opacity: 0; }

/* ---------- 8. HERO ------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(100dvh, 1000px);
  display: flex; align-items: center;
  background: var(--eg-night);
  overflow: hidden; isolation: isolate;
}
.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: center 55%; }
.hero__veil {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    /* Arriba, donde van la etiqueta y el titular, el velo es más denso: con
       .14–.26 el cielo dejaba la etiqueta en 3:1 y, en móvil, el titular en 2,3:1.
       Medido píxel a píxel: ahora 6:1 y 5,4:1 de mediana. */
    linear-gradient(to top, rgba(17,26,43,.88) 0%, rgba(17,26,43,.46) 54%, rgba(17,26,43,.38) 74%, rgba(17,26,43,.5) 100%),
    linear-gradient(to right, rgba(46,64,120,.44), rgba(17,26,43,.04) 68%);
}
.hero__inner { position: relative; width: 100%; }
.hero__grid { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: var(--grid-gap); align-items: center; }
.hero__head { grid-column: 1 / span 10; }
.hero .label { color: rgba(255,255,255,.88); }
/* Halo muy difuso: separa la letra de las zonas claras de la foto sin verse */
.hero .label, .hero__title { text-shadow: 0 0 18px rgba(13, 19, 26, .45), 0 1px 2px rgba(13, 19, 26, .35); }
.hero__title { margin-top: var(--s-5); }

/* Las líneas se revelan con máscara: sensación editorial */
.hero__line { display: block; overflow: hidden; }
/* El estado oculto vive SÓLO en la animación (fill «backwards»), no en la
   regla: si la animación no se ejecuta —impresión, lectores, navegadores que
   la desactivan— el titular se ve, en vez de quedarse escondido. */
.hero__line > span { display: block; animation: lineUp 1.05s var(--ease-out) backwards; }
.hero__line:nth-child(1) > span { animation-delay: .18s; }
.hero__line:nth-child(2) > span { animation-delay: .29s; }
.hero__line:nth-child(3) > span { animation-delay: .40s; }
.hero__line:nth-child(4) > span { animation-delay: .51s; }
@keyframes lineUp { from { transform: translateY(105%); } to { transform: translateY(0); } }

/* Coreografía de entrada: la foto se asienta, la etiqueta abre, las líneas
   del titular suben, el filete de las cifras se traza de izquierda a derecha
   y los botones cierran. Misma regla que el titular: el estado oculto vive
   sólo en la animación. «scale» y «translate» son propiedades sueltas, así
   que se suman al transform del paralaje en vez de pisarlo. */
.hero__media { animation: heroSettle 2.6s var(--ease-out) backwards; }
@keyframes heroSettle { from { scale: 1.08; } }
.hero .label { animation: riseIn .9s var(--ease-out) .05s backwards; }
.hero__meta { animation: drawIn 1.2s var(--ease-out) .55s backwards; }
@keyframes drawIn { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.hero__meta-item { animation: riseIn .8s var(--ease-out) backwards; }
.hero__meta-item:nth-child(1) { animation-delay: .66s; }
.hero__meta-item:nth-child(2) { animation-delay: .73s; }
.hero__meta-item:nth-child(3) { animation-delay: .80s; }
.hero__meta-item:nth-child(4) { animation-delay: .87s; }
.hero .btn-row { animation: riseIn .9s var(--ease-out) .95s backwards; }

/* Primer panel de las páginas interiores: la misma entrada, en cascada */
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > * { animation: riseIn .9s var(--ease-out) backwards; }
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > :nth-child(1) { animation-delay: .08s; }
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > :nth-child(2) { animation-delay: .16s; }
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > :nth-child(3) { animation-delay: .24s; }
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > :nth-child(4) { animation-delay: .34s; }
.hcanvas__track > .panel:first-child:not(.panel--hero) > .panel__inner > :nth-child(n+5) { animation-delay: .44s; }

.hero__meta {
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-7);
  margin-top: var(--s-7); padding-top: var(--s-5);
  border-top: var(--hairline) solid rgba(255,255,255,.22);
}
.hero__meta-item { display: flex; flex-direction: column; gap: 6px; }
.hero__meta-k { font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: rgba(255,255,255,.6); font-weight: 600; }
.hero__meta-v { font-family: var(--font-display); font-weight: 700; font-size: 1.0625rem; letter-spacing: -.01em; }

@media (max-width: 1280px) { .hero__head { grid-column: 1 / -1; } }

/* Móvil: el hero se recompone, no se limita a apilarse */
@media (max-width: 560px) {
  .hero { min-height: auto; padding-block: var(--s-9) var(--s-8); }
  /* El mínimo permite que "Construyendo" quepa entero a 320px */
  .hero .display { font-size: clamp(1.35rem, 8.2vw - .2rem, 2.8rem); letter-spacing: -.03em; }
  .label--rule::before { display: none; }
  .label { line-height: 1.5; }
  .hero__meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5) var(--s-4); }
  .hero__meta-item:nth-child(3), .hero__meta-item:nth-child(4) { grid-column: span 2; }
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row .btn { width: 100%; }
}

/* Página 404: ocupa la pantalla entera, sin franja vacía debajo */
.page-hero {
  position: relative;
  padding-top: calc(var(--header-h) + clamp(3rem, 2rem + 5vw, 7rem));
  padding-bottom: clamp(2.5rem, 1.75rem + 3.5vw, 5rem);
  background: var(--eg-night); overflow: hidden;
}
.page-hero--center { min-height: 100dvh; display: flex; align-items: center; }
/* Por debajo de 1025px el body ya reserva la altura de la cabecera */
@media (max-width: 1024px) { .page-hero--center { min-height: calc(100dvh - var(--header-h)); } }

/* Migas */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  font-size: var(--fs-label); letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255,255,255,.7); font-weight: 600; margin-bottom: var(--s-6);
}
.crumbs ol { display: contents; }
.crumbs li { display: inline-flex; align-items: center; gap: var(--s-2); }
.crumbs li:not(:last-child)::after { content: "/"; margin-left: var(--s-2); opacity: .45; }
.crumbs a:hover { color: #fff; }

/* ---------- 9. BLOQUE EDITORIAL ------------------------------------------- */
.editorial { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: var(--grid-gap); align-items: center; }
.editorial__media { grid-column: 1 / span 6; }
.editorial__body  { grid-column: 8 / span 5; }
@media (max-width: 900px) {
  .editorial__media, .editorial__body { grid-column: 1 / -1; }
  .editorial__body { margin-top: var(--s-6); }
}

/* Marco de imagen: relación de aspecto fija, nunca deforma */
.figure { position: relative; margin: 0; overflow: hidden; }
.figure img { width: 100%; height: 100%; object-fit: cover; }
.figure--4x5  { aspect-ratio: 4 / 5; }
/* En recorrido horizontal manda la altura del panel, no la proporción:
   la imagen se adapta al hueco disponible y recorta con object-fit. */
@media (min-width: 1025px) {
  .panel .editorial__media .figure,
  .panel .tabpanel__media .figure {
    aspect-ratio: auto;
    height: calc(var(--ph) - 7.5rem);
    max-height: none;
  }
  /* Una foto 4:5 en un panel estrecho no debe superar la altura útil */
  .panel .figure--4x5 { max-height: calc(var(--ph) - 4rem); }
}
.figure--16x9 { aspect-ratio: 16 / 9; }
.figure--zoom img { transition: transform 1.1s var(--ease-out), opacity .7s var(--ease), scale 1s var(--ease-out); }

/* ---------- 10. CIFRAS ---------------------------------------------------- */
/* Cuatro cifras en fila sólo si caben holgadas (≥880px); si no, 2×2; en
   móvil, una por fila. Así ninguna etiqueta se parte y los valores de cada
   fila quedan alineados. Se decide por el ancho real del bloque. */
.facts { container-type: inline-size; display: flex; flex-wrap: wrap; border-top: var(--hairline) solid var(--eg-line); }
.fact { container-type: inline-size; flex: 0 0 50%; min-width: 0; padding: var(--s-6) var(--s-5) var(--s-6) 0; border-bottom: var(--hairline) solid var(--eg-line); }
.fact:nth-child(even) { padding-left: var(--s-5); border-left: var(--hairline) solid var(--eg-line); }
@container (min-width: 880px) {
  .fact { flex-basis: 25%; }
  .fact + .fact { padding-left: var(--s-5); border-left: var(--hairline) solid var(--eg-line); }
}
@container (max-width: 479px) {
  .fact { flex-basis: 100%; }
  .fact:nth-child(even) { padding-left: 0; border-left: 0; }
}
.fact__k { font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--eg-muted); font-weight: 600; }
.fact__v { font-family: var(--font-display); font-weight: 700; font-size: min(clamp(1.4rem, 1.1rem + 1.3vw, 2.25rem), 17cqi); letter-spacing: -.02em; line-height: 1.1; margin-top: var(--s-3); }

/* ---------- 11. PESTAÑAS (SERVICIOS) -------------------------------------- */
.tabs { display: grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: var(--grid-gap); align-items: start; }
.tabs__nav { grid-column: 1 / span 3; }
.tabs__panels { grid-column: 4 / span 9; }

.tablist { display: flex; flex-direction: column; border-top: var(--hairline) solid var(--eg-line); }
.tab {
  position: relative; display: flex; align-items: baseline; gap: var(--s-4);
  width: 100%; text-align: left;
  padding: var(--s-5) var(--s-4) var(--s-5) 0;
  border-bottom: var(--hairline) solid var(--eg-line);
  font-family: var(--font-display);
  font-size: clamp(1.15rem, .95rem + .85vw, 1.75rem);
  font-weight: 700; letter-spacing: var(--tr-tight); line-height: 1.15;
  color: var(--eg-muted);
  transition: color var(--t-base) var(--ease), padding-left var(--t-base) var(--ease-out);
}
.tab::before {
  content: ""; position: absolute; left: 0; bottom: -1px;
  width: 100%; height: 1px; background: var(--eg-accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-base) var(--ease-out);
}
.tab__n { font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600; letter-spacing: .14em; flex: none; }
.tab:hover { color: var(--eg-ink); padding-left: var(--s-3); }
.tab[aria-selected="true"] { color: var(--eg-ink); }
.bg-night .tab:hover, .bg-night .tab[aria-selected="true"] { color: #fff; }
.tab[aria-selected="true"]::before { transform: scaleX(1); }
.tab[aria-selected="true"] .tab__n { color: var(--eg-accent); }

.tabpanel[hidden] { display: none; }
/* Sólo al cambiar de pestaña (el JS pone la clase): al cargar, el texto se ve
   desde el primer momento aunque la animación no llegue a ejecutarse. */
.tabpanel.is-entering { animation: panelIn .6s var(--ease-out) both; }
@keyframes panelIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.tabpanel__layout { display: grid; grid-template-columns: repeat(8, minmax(0,1fr)); gap: var(--grid-gap); align-items: start; }
.tabpanel__media { grid-column: 1 / span 4; }
.tabpanel__body  { grid-column: 5 / span 4; }
.tabpanel--alt .tabpanel__media { grid-column: 5 / span 4; order: 2; }
.tabpanel--alt .tabpanel__body  { grid-column: 1 / span 4; order: 1; }
/* En el recorrido horizontal el panel tiene altura fija: el texto, que es lo
   que crece, se lleva 5 de las 8 columnas y la foto 3. */
@media (min-width: 1025px) {
  .tabpanel__media { grid-column: 1 / span 3; }
  .tabpanel__body  { grid-column: 4 / span 5; }
  .tabpanel--alt .tabpanel__media { grid-column: 6 / span 3; }
  .tabpanel--alt .tabpanel__body  { grid-column: 1 / span 5; }
}

@media (max-width: 1024px) {
  .tabs__nav, .tabs__panels { grid-column: 1 / -1; }
  .tabs__panels { margin-top: var(--s-7); }
  .tablist {
    flex-direction: row; overflow-x: auto; scroll-snap-type: x mandatory;
    border-top: 0; border-bottom: var(--hairline) solid var(--eg-line);
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .tablist::-webkit-scrollbar { display: none; }
  .tab { width: auto; flex: none; border-bottom: 0; padding: var(--s-4) var(--s-6) var(--s-4) 0; scroll-snap-align: start; }
  .tab:hover { padding-left: 0; }
}
@media (max-width: 760px) {
  .tabpanel__layout, .tabpanel--alt .tabpanel__layout { grid-template-columns: 1fr; }
  .tabpanel__media, .tabpanel__body,
  .tabpanel--alt .tabpanel__media, .tabpanel--alt .tabpanel__body { grid-column: 1 / -1; order: initial; }
  .tabpanel__body { margin-top: var(--s-5); }
}

/* ---------- 12. PANEL DE PROYECTO ----------------------------------------- */
.pcard { display: flex; flex-direction: column; height: 100%; justify-content: flex-end; }
.pcard__i { margin-bottom: auto; font-size: var(--fs-label); font-weight: 600; letter-spacing: .14em; color: var(--eg-accent); }
.pcard__media { position: relative; overflow: hidden; aspect-ratio: 16 / 10; margin-bottom: var(--s-6); }
.pcard__media img { width: 100%; height: 100%; object-fit: cover; }
.pcard__year {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.6rem, 1.8rem + 2.6vw, 4.5rem); line-height: .85;
  letter-spacing: -.045em; color: transparent;
  -webkit-text-stroke: 1px rgba(255,255,255,.52);
  margin-bottom: var(--s-4);
}
.pcard__year--accent { -webkit-text-stroke-color: rgba(87,163,250,.78); }
.pcard__name { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.05rem, .95rem + .55vw, 1.4rem); letter-spacing: -.02em; line-height: 1.22; }
.pcard__place { margin-top: var(--s-3); font-size: var(--fs-small); color: rgba(255,255,255,.66); }

/* ---------- 13. OBRA EN PANEL --------------------------------------------- */
.wpanel { display: flex; flex-direction: column; height: 100%; justify-content: center; width: 100%; text-align: left; }
.wpanel__media { position: relative; overflow: hidden; max-height: 62dvh; }
.wpanel__media img { width: 100%; height: 100%; object-fit: cover; }
.wpanel__meta { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); margin-top: var(--s-4); padding-top: var(--s-3); border-top: var(--hairline) solid var(--eg-line); }
.wpanel__name { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; letter-spacing: -.015em; transition: color var(--t-fast) var(--ease); }
/* La foto abre la galería: cursor de lupa y una pastilla «ampliar» en la
   esquina. Con ratón aparece al pasar; en táctil, donde no hay «pasar», está
   siempre, algo más discreta. */
.wpanel { cursor: zoom-in; }
.wpanel__media::after {
  content: ""; position: absolute; right: 14px; bottom: 14px;
  width: 44px; height: 44px; border-radius: 999px;
  border: var(--hairline) solid rgba(255, 255, 255, .38);
  background: rgba(13, 19, 26, .38) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23fff' stroke-width='1.4'%3E%3Cpath d='M8 1v14M1 8h14'/%3E%3C/svg%3E") center / 14px no-repeat;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 0; transform: scale(.82);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease-out);
  pointer-events: none;
}
.wpanel:hover .wpanel__media::after, .wpanel:focus-visible .wpanel__media::after { opacity: 1; transform: none; }
.wpanel:hover .wpanel__name, .wpanel:focus-visible .wpanel__name { color: var(--eg-accent); }
@media (hover: hover) { .wpanel:hover .wpanel__media img { scale: 1.04; } }
@media (hover: none) { .wpanel__media::after { opacity: .85; transform: scale(.86); } }
.wpanel__tag { font-size: var(--fs-label); letter-spacing: .12em; text-transform: uppercase; color: var(--eg-muted); font-weight: 600; flex: none; }

/* ---------- 14. TABLA DE PROYECTOS ---------------------------------------- */
.ptable { width: 100%; border-collapse: collapse; text-align: left; }
.ptable th {
  font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--eg-muted); font-weight: 600;
  padding: 0 var(--s-4) var(--s-4) 0; border-bottom: var(--hairline) solid var(--eg-ink);
}
.ptable td { padding: var(--s-4) var(--s-4) var(--s-4) 0; border-bottom: var(--hairline) solid var(--eg-line); vertical-align: baseline; }
.ptable tbody tr { transition: background-color var(--t-fast) var(--ease); }
.ptable tbody tr:hover { background: rgba(65, 91, 163, .05); }
.ptable__n { font-size: var(--fs-label); font-weight: 600; letter-spacing: .12em; color: var(--eg-accent); width: 3rem; }
.ptable__name { font-family: var(--font-display); font-weight: 600; font-size: clamp(1rem, .95rem + .4vw, 1.2rem); letter-spacing: -.015em; }
.ptable__place { color: var(--eg-muted); font-size: var(--fs-small); }
.ptable__year { font-family: var(--font-display); font-weight: 700; text-align: right; width: 5rem; padding-right: 0; }
@media (max-width: 640px) {
  .ptable thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .ptable { table-layout: fixed; }
  .ptable tr { display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; gap: 0 var(--s-3); padding-block: var(--s-4); border-bottom: var(--hairline) solid var(--eg-line); }
  .ptable td { border: 0; padding: 0; }
  .ptable__n, .ptable__name, .ptable__year { grid-row: 1; }
  .ptable__name { grid-column: 2; }
  .ptable__year { grid-column: 3; text-align: right; width: auto; }
  .ptable__place { grid-column: 2; margin-top: 4px; }
  .ptable__name, .ptable__place { overflow-wrap: anywhere; }
}

/* ---------- 15. BLOG ------------------------------------------------------ */
.post-list { display: grid; gap: var(--grid-gap); }
.post-list--stack { gap: var(--s-6); }
.post-card__media { overflow: hidden; }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; }
.post-card__body { margin-top: var(--s-5); }
.post-card__kicker { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--eg-muted); font-weight: 600; }
.post-card__kicker--light { color: rgba(255,255,255,.64); }
.post-card__title { margin-top: var(--s-4); font-family: var(--font-display); font-weight: 700; letter-spacing: var(--tr-tight); line-height: 1.16; font-size: clamp(1.15rem, 1rem + .75vw, 1.6rem); }
.post-card__excerpt { margin-top: var(--s-4); color: var(--eg-muted); }
.post-card__title { transition: color var(--t-fast) var(--ease); }
.post-card a:hover .post-card__title { color: var(--eg-blue); }
.bg-night .post-card a:hover .post-card__title { color: var(--eg-azure); }
@media (hover: hover) { .post-card a:hover .post-card__media img { scale: 1.04; } }

.article-body { max-width: 68ch; }
.article-body p { color: var(--eg-ink-soft); font-size: clamp(1.0625rem, 1rem + .35vw, 1.1875rem); line-height: 1.75; }
.article-body p + p { margin-top: var(--s-5); }
.article-body h2 {
  margin-top: var(--s-8);
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.25rem, 1.1rem + .55vw, 1.6rem);
  line-height: 1.2; letter-spacing: -.02em; color: var(--eg-ink);
}
.article-body > h2:first-child { margin-top: 0; }
.article-body h2 + p, .article-body h2 + ul, .article-body p + ul { margin-top: var(--s-4); }
.article-body ul + p { margin-top: var(--s-5); }
.article-body ul { padding-left: 1.15em; list-style: disc; }
.article-body li {
  color: var(--eg-ink-soft); font-size: clamp(1rem, .96rem + .3vw, 1.125rem); line-height: 1.65;
}
.article-body li + li { margin-top: var(--s-3); }
.article-body li::marker { color: var(--eg-accent); }
/* Enlaces internos dentro del texto ([texto](/ruta) en articles.mjs): se ven
   como enlace sin romper la lectura — mismo tratamiento que las fuentes. */
.article-body a {
  color: var(--eg-accent); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: .2em;
  transition: color .2s ease;
}
@media (hover: hover) { .article-body a:hover { color: var(--eg-ink); } }

/* Fuentes y fecha de revisión */
.article-sources { margin-top: var(--s-8); padding-top: var(--s-5); border-top: var(--hairline) solid var(--eg-line); max-width: 68ch; }
.article-sources__title {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--eg-muted);
}
.article-sources ul { margin-top: var(--s-4); }
.article-sources li { font-size: var(--fs-small); line-height: 1.55; }
.article-sources li + li { margin-top: var(--s-3); }
.article-sources a {
  color: var(--eg-accent); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.article-sources a:hover { text-decoration-thickness: 2px; }
.article-sources__note { margin-top: var(--s-5); font-size: var(--fs-small); color: var(--eg-muted); line-height: 1.55; }

/* En el recorrido horizontal el artículo se lee en columnas que avanzan
   hacia la derecha. El ancho del panel lo ajusta el JS al número de
   columnas; la medida de cada una (30rem ≈ 60 caracteres) no cambia. */
@media (min-width: 1025px) {
  .panel--article { width: auto; }
  .panel--article .panel__inner { height: 100%; }
  .article-flow {
    width: 30rem; height: 100%;
    column-width: 30rem; column-gap: clamp(3rem, 2rem + 2.4vw, 5rem);
    column-fill: auto;
    column-rule: var(--hairline) solid var(--eg-line);
  }
  .article-flow .article-body, .article-flow .article-sources { max-width: none; }
  .article-flow h2 { break-after: avoid; }
  .article-flow li, .article-flow .article-sources { break-inside: avoid; }
  .article-flow p, .article-flow li { orphans: 3; widows: 3; }
}

/* Mapa del sitio: tres grupos; el del blog, con los títulos largos, ocupa
   el doble y reparte sus enlaces en dos columnas. */
.sitemap { display: grid; gap: var(--s-7) var(--grid-gap); }
.sitemap__group { min-width: 0; } /* hijo de rejilla: no lo ensanchan los títulos largos */
@media (min-width: 761px) {
  .sitemap { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
  .sitemap__group--blog .sitemap__list { columns: 2; column-gap: var(--grid-gap); }
}
.sitemap__title {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--eg-muted);
  padding-bottom: var(--s-3); border-bottom: var(--hairline) solid var(--eg-line);
}
.sitemap__list { margin-top: var(--s-3); }
.sitemap__list li { break-inside: avoid; }
.sitemap__link {
  display: block; padding-block: var(--s-2);
  font-size: var(--fs-small); line-height: 1.4; color: var(--eg-ink);
  transition: color var(--t-fast) var(--ease);
}
.sitemap__link:hover, .sitemap__link:focus-visible { color: var(--eg-accent); }

/* ---------- 16. CONTACTO / FORMULARIO ------------------------------------- */
.dl { border-top: var(--hairline) solid var(--eg-line); }
.dl__row { padding: var(--s-4) 0; border-bottom: var(--hairline) solid var(--eg-line); display: grid; gap: var(--s-2); }
.dl__k { font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--eg-muted); font-weight: 600; }
.dl__v { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.0625rem, 1rem + .55vw, 1.4rem); letter-spacing: -.015em; word-break: break-word; }
.dl__v a {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 3px; transition: background-size var(--t-base) var(--ease-out);
}
.dl__v a:hover, .dl__v a:focus-visible { background-size: 100% 1px; }

.form { display: grid; gap: var(--s-5); }
.form__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5); }
.field { display: grid; gap: var(--s-3); }
.field__label { font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; font-weight: 600; color: var(--eg-muted); }
.field__req { color: var(--eg-accent); }
.field input, .field textarea {
  width: 100%; padding: var(--s-3) 0;
  background: transparent; border: 0; border-bottom: var(--hairline) solid var(--eg-line); border-radius: 0;
  font-size: clamp(1rem, .95rem + .45vw, 1.25rem);
  font-family: var(--font-display); font-weight: 500; letter-spacing: -.01em;
  /* Al enfocar, un trazo de 2px se dibuja de izquierda a derecha sobre el
     filete: es un fondo, así que no mueve ni un píxel de diseño. */
  background-image: linear-gradient(var(--eg-accent), var(--eg-accent));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 2px;
  transition: border-color var(--t-base) var(--ease), background-size .55s var(--ease-out);
}
.field textarea { min-height: 96px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--eg-steel); font-weight: 400; }
.field input:focus, .field textarea:focus { border-bottom-color: var(--eg-accent); background-size: 100% 2px; }
.field__label { transition: color var(--t-fast) var(--ease); }
.field:focus-within .field__label { color: var(--eg-accent); }
.field__error { font-size: var(--fs-small); color: var(--eg-error); }
.field__error:not(:empty) { animation: riseIn .4s var(--ease-out); }
.field.is-invalid input, .field.is-invalid textarea {
  border-bottom-color: var(--eg-error);
  background-image: linear-gradient(var(--eg-error), var(--eg-error)); background-size: 100% 2px;
}
.field.is-invalid .field__label { color: var(--eg-error); }

.form__consent {
  display: flex; gap: var(--s-4); align-items: flex-start;
  font-size: var(--fs-small); color: var(--eg-muted); line-height: 1.55;
  padding: var(--s-2) 0; cursor: pointer; min-height: 44px;
}
.form__consent input { width: 22px; height: 22px; flex: none; margin-top: 1px; accent-color: var(--eg-blue); cursor: pointer; }
@media (pointer: coarse) { .form__consent input { width: 26px; height: 26px; } }
/* La casilla no vive en un .field: su aviso es el borde de error */
.form__consent input[aria-invalid="true"] { outline: 2px solid var(--eg-error); outline-offset: 2px; }
.form__status { font-size: var(--fs-small); font-weight: 500; }
.form__status:not(:empty) { animation: riseIn .45s var(--ease-out); }
.form__status[data-state="ok"] { color: var(--eg-accent); }
.form__status[data-state="error"] { color: var(--eg-error); }
.form[aria-busy="true"] .btn { opacity: .6; cursor: progress; }
/* Enviando: la flecha cede su sitio a un indicador giratorio */
.form[aria-busy="true"] .btn--primary .btn__icon { opacity: 0; }
.form[aria-busy="true"] .btn--primary::after {
  content: ""; position: absolute; right: calc(var(--s-7) - 1px); top: 50%;
  width: 14px; height: 14px; margin-top: -7px; border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .35); border-top-color: #fff;
  animation: spin .7s linear infinite;
}
/* Campo trampa: fuera de la vista y del orden de tabulación */
.form__trap {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
@media (max-width: 760px) { .form__grid { grid-template-columns: 1fr; } }

/* ---------- 17. LIGHTBOX -------------------------------------------------- */
.lightbox {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(10, 16, 26, .96);
  display: grid; grid-template-rows: auto 1fr auto;
  padding: var(--s-5) var(--gutter) var(--s-6);
  opacity: 0; visibility: hidden;
  transition: opacity var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.lightbox.is-open { opacity: 1; visibility: visible; transition-delay: 0s, 0s; }
.lightbox__bar { display: flex; justify-content: space-between; align-items: center; gap: var(--s-5); color: rgba(255,255,255,.7); font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; font-weight: 600; }
.lightbox__stage { display: grid; place-items: center; min-height: 0; padding-block: var(--s-5); touch-action: pan-y pinch-zoom; }
/* Al abrir la imagen se acerca un 4 %; al cambiar, la que sale se funde y
   la nueva entra desde el lado hacia el que se avanza. */
.lightbox__img {
  max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain;
  transform: scale(.96); opacity: 0;
  transition: opacity .38s var(--ease), transform .6s var(--ease-out);
}
.lightbox.is-open .lightbox__img { transform: none; opacity: 1; }
.lightbox.is-open .lightbox__img.is-swapping { opacity: 0; transform: translateX(calc(var(--lb-dir, 0) * 24px)); transition-duration: .18s; }
.lightbox__bar, .lightbox__foot { transition: opacity var(--t-base) var(--ease) .1s; }
.lightbox:not(.is-open) .lightbox__bar, .lightbox:not(.is-open) .lightbox__foot { opacity: 0; transition-delay: 0s; }
.lightbox__foot { display: flex; justify-content: space-between; align-items: center; gap: var(--s-5); color: #fff; }
.lightbox__cap { font-size: var(--fs-small); color: rgba(255,255,255,.78); }
.lightbox__nav { display: flex; gap: var(--s-3); }
.lb-btn {
  width: 48px; height: 48px; display: grid; place-items: center; border-radius: 999px;
  border: var(--hairline) solid rgba(255,255,255,.3); color: #fff;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease-out);
}
.lb-btn:hover { background: rgba(255,255,255,.12); border-color: #fff; }
.lb-btn:active { transform: scale(.94); transition-duration: .08s; }
.lb-close { font-size: var(--fs-label); letter-spacing: var(--tr-label); text-transform: uppercase; font-weight: 600; color: #fff; display: inline-flex; align-items: center; gap: var(--s-2); }

/* =============================================================================
   18. PIE — una parada más del recorrido
   -----------------------------------------------------------------------------
   Patrón tomado de la referencia: filas de etiqueta pequeña en versales +
   valor grande en tipografía display, con aire entre ellas; debajo, enlaces en
   dos columnas a tamaño pequeño y el crédito a la derecha. Así el pie se lee
   como un panel más del recorrido, no como un bloque pegado al final.
   ============================================================================= */
.footer { display: flex; flex-direction: column; height: 100%; justify-content: center; }
.footer__grid { display: grid; gap: clamp(1.25rem, .8rem + 1.6vw, 2.5rem); }
.footer__brand { display: flex; align-items: center; gap: var(--s-6); flex-wrap: wrap; }
.footer__logo { display: inline-block; }
.footer__logo img {
  height: clamp(40px, 3.4vw, 54px); width: auto;
  object-fit: contain; object-position: left center;
  filter: invert(1) brightness(.12);
}
.footer__claim {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.05rem, .95rem + .6vw, 1.4rem);
  line-height: 1.26; letter-spacing: -.025em;
  max-width: 26ch; color: var(--eg-muted);
}

/* Filas: etiqueta pequeña + valor grande */
.footer__rows {
  /* Una sola columna de etiquetas para todas las filas (subgrid): mide lo
     que la etiqueta más larga y los valores quedan alineados. */
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--s-6); container-type: inline-size;
  border-top: var(--hairline) solid var(--eg-line);
}
.footer__row {
  grid-column: 1 / -1; display: grid;
  grid-template-columns: minmax(min-content, 15%) minmax(0, 1fr);
  grid-template-columns: subgrid;
  align-items: baseline;
  padding-block: clamp(.7rem, .4rem + 1vw, 1.35rem);
  border-bottom: var(--hairline) solid var(--eg-line);
}
.footer__k {
  font-size: var(--fs-label); font-weight: 600; white-space: nowrap;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  color: var(--eg-muted); padding-top: .45em;
}
.footer__v {
  /* Las etiquetas son palabras normales y no se parten; el correo, que es
     una cadena sin espacios, sí lo hace cuando no cabe en la medida. */
  overflow-wrap: break-word;
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.15rem, .85rem + 1.35vw, 2.1rem);
  line-height: 1.14; letter-spacing: -.03em; color: var(--eg-ink);
}
/* Etiqueta y valor en la misma fila sólo si el bloque mide ≥640px; el valor
   se limita a lo que deja libre la etiqueta, así el correo (32 caracteres sin
   espacios) cabe entero. Más estrecho, la etiqueta va encima del valor. */
@container (min-width: 640px) {
  .footer__v { font-size: min(clamp(1.15rem, .85rem + 1.35vw, 2.1rem), calc((100cqi - 15rem) / 19)); }
}
@container (max-width: 639px) {
  .footer__row { grid-template-columns: minmax(0, 1fr); gap: var(--s-2); }
  .footer__k { padding-top: 0; }
  .footer__v a[href^="mailto:"] { font-size: min(1em, calc(100cqi / 19.5)); }
}
.footer__v a {
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 3px;
  transition: background-size var(--t-base) var(--ease-out), color var(--t-fast) var(--ease);
}
.footer__v a:hover, .footer__v a:focus-visible { background-size: 100% 1px; color: var(--eg-accent); }
.footer__arrow { display: inline-block; vertical-align: .15em; margin-left: .3em; transition: transform var(--t-base) var(--ease-out); }
.footer__v a:hover .footer__arrow { transform: translate(2px, -2px); }

/* Enlaces en dos columnas, como en la referencia */
.footer__nav {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3) var(--s-6); justify-items: start; max-width: 420px;
}
.footer__nav a {
  font-size: .8125rem; color: var(--eg-muted);
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px; background-repeat: no-repeat; background-position: 0 100%;
  padding-bottom: 2px;
  transition: background-size var(--t-base) var(--ease-out), color var(--t-fast) var(--ease);
}
.footer__nav a:hover { background-size: 100% 1px; color: var(--eg-ink); }

.footer__foot {
  display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6);
  justify-content: space-between; align-items: flex-end;
  padding-top: clamp(.75rem, .5rem + 1.2vw, 1.75rem);
}
.footer__legal { font-size: var(--fs-label); color: var(--eg-muted); line-height: 1.8; }
.footer__map { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.footer__map:hover, .footer__map:focus-visible { color: var(--eg-ink); }

/* Marca de GTIA Labs: trazados, proporciones y colores tomados de gtialabs.com
   (es una marca ajena: se respetan sus colores, no se tiñe con la paleta). */
.footer__dev { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); font-size: var(--fs-label); color: var(--eg-muted); }
.footer__dev-label { text-transform: uppercase; letter-spacing: .12em; white-space: nowrap; }
.gtia { display: inline-flex; align-items: center; gap: 11px; color: #171A17; transition: opacity var(--t-fast) var(--ease); }
.gtia:hover { opacity: .68; }
.gtia__mark { display: block; height: 17px; width: auto; transition: transform .35s var(--ease-out); }
.gtia:hover .gtia__mark { transform: translateY(-1.5px); }
.gtia__ia { color: #4C5F3F; }
.gtia__labs {
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; line-height: 1;
  letter-spacing: .3em; text-transform: uppercase; color: var(--eg-muted);
  padding-left: 11px; border-left: 1px solid var(--eg-line);
}

@media (min-width: 760px) {
  .footer__grid {
    grid-template-columns: minmax(270px, .9fr) minmax(0, 1.6fr);
    grid-template-areas:
      "marca filas"
      "pie   nav";
    column-gap: clamp(2.5rem, 1.5rem + 3vw, 5rem);
    align-items: start;
  }
  .footer__brand { grid-area: marca; flex-direction: column; align-items: flex-start; gap: var(--s-5); }
  .footer__rows  { grid-area: filas; }
  .footer__nav   { grid-area: nav; align-self: start; }
  .footer__foot  { grid-area: pie; flex-direction: column; align-items: flex-start; gap: var(--s-5); padding-top: 0; }
}

@media (max-width: 620px) {
  .footer__foot { flex-direction: column; align-items: flex-start; }
  /* Los enlaces son etiquetas breves: en dos columnas el pie se acorta
     sin apretarlos. */
  .footer__nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-5); max-width: none; }
}

/* ---------- 19. UTILIDADES ------------------------------------------------ */
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
.mt-8 { margin-top: var(--s-8); }
.mt-9 { margin-top: var(--s-9); }
.no-scroll { overflow: hidden; }

/* ---------- 20. OBJETIVOS TÁCTILES ---------------------------------------- */
@media (max-width: 1024px), (pointer: coarse) {
  .lang__item { min-height: 44px; }
  .link { padding-top: 8px; padding-bottom: 12px; }
  .dl__v a { display: inline-block; max-width: 100%; padding-block: 13px; }
  .footer__nav { gap: 0 var(--s-6); }
  .footer__nav a { padding-block: 11px; }
  .footer__v a { display: inline-block; max-width: 100%; padding-block: 6px; }
  .menu-toggle { min-height: 44px; }
  /* Zona de toque de 44px sin mover nada: un pseudo-elemento invisible la
     amplía por encima y por debajo del enlace, sin cambiar alturas. */
  .footer__v a, .footer__map, .crumbs a { position: relative; }
  .footer__v a::after, .footer__map::after, .crumbs a::after {
    content: ""; position: absolute; left: 0; right: 0; top: 50%;
    height: 44px; transform: translateY(-50%);
  }
  .sitemap__link { padding-block: 12px; }
  /* Enlaces de fuentes: varios seguidos y a veces en dos líneas; en táctil
     se separan para que cada uno tenga su zona de 44px. */
  .article-sources a { display: inline-block; padding-block: 12px; }
  .article-sources li + li { margin-top: 0; }
  .gtia { padding-block: 14px; }
  .lb-close { min-height: 44px; padding-inline: var(--s-3); margin-right: calc(-1 * var(--s-3)); }
  .crumbs a { display: inline-block; max-width: 100%; padding-block: 8px; }
  .menu-panel__foot a { display: inline-block; max-width: 100%; padding-block: 12px; }
}

/* ---------- 21. ESCALA LIMITADA POR LA ALTURA -----------------------------
   En recorrido horizontal cada panel mide una pantalla, así que la altura es
   un límite tan real como el ancho: los titulares se dimensionan por el menor
   de los dos. Evita ir parcheando pantalla por pantalla.
-------------------------------------------------------------------------- */
@media (min-width: 1025px) {
  .panel .display   { font-size: min(var(--fs-display), calc(var(--ph) * .108)); }
  .panel .h1        { font-size: min(var(--fs-h1), calc(var(--ph) * .086)); }
  .panel .h2        { font-size: min(var(--fs-h2), calc(var(--ph) * .076)); }
  .panel .h3        { font-size: min(var(--fs-h3), calc(var(--ph) * .045)); }
  .panel .statement        { font-size: min(clamp(1.4rem, .72rem + 2.35vw, 3rem), calc(var(--ph) * .058)); }
  .panel .statement--mid   { font-size: min(clamp(1.3rem, .78rem + 1.8vw, 2.4rem), calc(var(--ph) * .047)); }
  .panel .statement--long  { font-size: min(clamp(1.15rem, .9rem + .95vw, 1.75rem), calc(var(--ph) * .034)); }
  .panel .lead      { font-size: min(var(--fs-lead), calc(var(--ph) * .034)); }
  .panel--hero .hero { min-height: 0; height: 100%; }
}

@media (min-width: 1025px) and (max-height: 940px) {
  .panel:not(.panel--hero) { padding-block: 2rem; }
  .prose p + p { margin-top: var(--s-4); }
  .mt-8 { margin-top: var(--s-6); }
  .mt-9 { margin-top: var(--s-7); }
  .field input, .field textarea { padding-block: var(--s-3); font-size: 1rem; }
  .field textarea { min-height: 88px; }
  .form { gap: var(--s-4); }
  .form__consent { min-height: 0; padding-block: var(--s-2); }
}

@media (min-width: 1025px) and (max-height: 820px) {
  .panel:not(.panel--hero) { padding-block: 1.5rem; }
  /* Las pestañas de servicios son el panel con más texto seguido: se compacta
     su prosa, que es donde está el exceso, no la escala general. */
  .panel .tabpanel .prose p { font-size: .9375rem; line-height: 1.55; }
  .panel .tabpanel .prose p + p { margin-top: var(--s-3); }
  .panel .tabpanel .h3 { margin-top: var(--s-3); }
  .panel .tablist .tab { padding-block: var(--s-2); }
  .tab { padding-block: var(--s-3); }
  .ptable td { padding-block: var(--s-3); }
  .dl__row { padding-block: var(--s-3); }
  .prose p { font-size: 1rem; line-height: 1.6; }
  .field textarea { min-height: 72px; }
  .footer__row { padding-block: .6rem; }
}

/* Portátiles con la barra del navegador (~600–700px útiles): se compacta el
   aire vertical y la altura de las fotos de tarjeta, no la tipografía. */
@media (min-width: 1025px) and (max-height: 700px) {
  .panel:not(.panel--hero) { padding-block: 1rem; }
  .panel .mt-9 { margin-top: var(--s-6); }
  .panel .mt-8, .panel .mt-7 { margin-top: var(--s-5); }
  .panel .mt-6 { margin-top: var(--s-4); }
  .panel .mt-5 { margin-top: var(--s-3); }
  .panel .post-list--stack { gap: var(--s-4); }
  .panel .post-card__body { margin-top: var(--s-4); }
  .panel .post-card__media { aspect-ratio: auto; height: calc(var(--ph) * .36); }
  .panel .post-card__excerpt { margin-top: var(--s-3); }
  .panel .facts .fact { padding-block: var(--s-4); }
  .panel .tabpanel .prose p { font-size: .9375rem; line-height: 1.5; }
  .panel .tabpanel .prose p + p { margin-top: var(--s-2); }
  .panel .prose p { line-height: 1.5; }
  .panel .footer__grid { row-gap: var(--s-4); }
  .panel .footer__v { font-size: 1.3rem; }
  .panel .footer__row { padding-block: .45rem; }
  .panel .footer__foot { gap: var(--s-3); }
}

/* ---------- 22. MOVIMIENTO REDUCIDO --------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  @view-transition { navigation: none; }
  body { padding-top: var(--header-h); }
  .header.is-hidden { transform: none; }
  .rv, .rv--media { opacity: 1 !important; translate: none !important; clip-path: none !important; }
  .hero__media img, .hero__line > span { transform: none; }
  .hhint { display: none !important; }
  /* El recorrido horizontal pasa a flujo vertical */
  .hcanvas__viewport { position: static !important; height: auto !important; overflow: visible !important; flex-direction: column !important; }
  .hcanvas__track { flex-direction: column !important; transform: none !important; height: auto !important; }
  .panel { width: 100% !important; height: auto !important; padding-block: var(--section-y-sm) !important; border-left: 0 !important; }
  .panel + .panel { border-top: var(--hairline) solid var(--eg-line); }
  .panel, .panel__inner, .panel--hero .hero__inner { transform: none !important; box-shadow: none !important; }
  .panel::after { content: none !important; }
  .panel .figure img, .panel .wpanel__media img, .panel .pcard__media img,
  .panel .post-card__media img, .panel--hero .hero__media img { transform: none !important; }
}

/* ---------- 23. IMPRESIÓN ------------------------------------------------- */
@media print {
  .header, .menu-panel, .hhint, .hbar, .lightbox { display: none !important; }
  body { color: #000; background: #fff; padding-top: 0; }
  .hero, .page-hero, .bg-night, .hcanvas { background: #fff !important; color: #000 !important; }
  .hcanvas__viewport { position: static !important; height: auto !important; overflow: visible !important; flex-direction: column !important; }
  .hcanvas__track { flex-direction: column !important; transform: none !important; height: auto !important; }
  .panel { width: 100% !important; height: auto !important; break-inside: avoid; }
  .panel__inner { opacity: 1 !important; filter: none !important; transform: none !important; }
  .rv, .rv--media { opacity: 1 !important; translate: none !important; clip-path: none !important; }
  .rv img, img.is-loading { opacity: 1 !important; scale: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
