/* ==========================================================================
   ESCALATECH — Identidad visual "Cauce", variante oscura dominante
   Paleta y tipografías según Branding/Paletas-y-tipografias.txt

   Índice
   01 Fuentes          06 Botones y enlaces      11 Tablas y datos
   02 Tokens           07 Cabecera               12 FAQ
   03 Base y reset     08 Hero                   13 Cierre y pie
   04 Tipografía       09 Tarjetas               14 Utilidades
   05 Estructura       10 Metodología            15 Movimiento reducido
   ========================================================================== */

/* ---------- 01 Fuentes ---------------------------------------------------
   WOFF2 con subconjunto latino + Latin Extended, ejes variables intactos.
   Los .ttf originales de Google Fonts quedan en fonts/_originales/ como
   fuente de verdad, fuera de lo que sirve el servidor. */
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/SpaceGrotesk.woff2') format('woff2-variations'),
       url('../fonts/SpaceGrotesk.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/IBMPlexSans.woff2') format('woff2-variations'),
       url('../fonts/IBMPlexSans.woff2') format('woff2');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- 02 Tokens ---------------------------------------------------- */
:root {
  /* Paleta Cauce, literal del manual de marca */
  --tinta: #142D3B;
  --cobre: #ED8758;
  --mineral: #75919C;
  --niebla: #E6EEF1;
  --cal: #F7F9F8;

  /* Profundidades de Tinta necesarias para sostener la variante oscura.
     Tinta elevada está calculada, no elegida a ojo: es el tono más claro que
     todavía deja el Cobre por encima de 4,5:1 encima de él. Con #1B3D4F —el
     valor evidente— el acento se quedaba en 4,49:1 dentro de las tarjetas. */
  --tinta-abismo: #0C1D27;
  --tinta-elevada: #17364A;   /* Cobre encima: 4,94:1 */

  /* Derivados de contraste. Ninguno sustituye a un color de marca: cada uno
     existe porque el valor original no alcanza el mínimo WCAG AA en ese
     contexto concreto. Ratios medidos, no estimados.

       Cobre #ED8758 sobre Tinta ............ 5,59:1  ✔ se usa tal cual
       Cobre #ED8758 sobre Tinta elevada .... 4,94:1  ✔
       Cobre #ED8758 sobre Cal .............. 2,42:1  ✗ insuficiente
       Cobre oscuro #A54B1E sobre Cal ....... 5,48:1  ✔
       Cobre oscuro #A54B1E sobre Papel ..... 5,38:1  ✔
       Cobre oscuro #A54B1E sobre Niebla .... 4,93:1  ✔
       Mineral #75919C sobre Tinta .......... 4,19:1  ✗ insuficiente
       Mineral claro #8FA8B3 sobre Tinta .... 5,73:1  ✔
       Mineral oscuro #4A6470 sobre Cal ..... 5,93:1  ✔
       Tinta sobre Cobre .................... 5,59:1  ✔
       Marrón #4A2A18 sobre Cobre ........... 5,02:1  ✔                     */
  --cobre-oscuro: #A54B1E;
  --mineral-claro: #8FA8B3;
  --mineral-oscuro: #4A6470;
  --tinta-sobre-cobre: #4A2A18;

  /* Tintas con alfa, siempre derivadas de un color de marca. Ningún valor
     suelto: si hace falta una transparencia nueva, se añade aquí. */
  --alfa-niebla-14: rgba(230, 238, 241, 0.14);
  --alfa-niebla-08: rgba(230, 238, 241, 0.08);
  --alfa-tinta-14: rgba(20, 45, 59, 0.14);
  --alfa-tinta-30: rgba(20, 45, 59, 0.30);
  --alfa-cobre-10: rgba(237, 135, 88, 0.10);
  --alfa-cobre-12: rgba(237, 135, 88, 0.12);
  --alfa-cobre-20: rgba(237, 135, 88, 0.20);
  --alfa-cobre-40: rgba(237, 135, 88, 0.40);
  --alfa-cobre-50: rgba(237, 135, 88, 0.50);
  --alfa-cobre-70: rgba(237, 135, 88, 0.70);

  /* Papel: el tono exacto muestreado del esquema de la portada, para que el
     borde de la imagen no se note contra el fondo de la sección. */
  --papel: #F4F7F7;

  /* --- Roles semánticos: superficie oscura (por defecto) --- */
  --surface: var(--tinta);
  --surface-deep: var(--tinta-abismo);
  --surface-raised: var(--tinta-elevada);
  --text-strong: var(--niebla);
  --text-muted: var(--mineral-claro);
  --border: var(--alfa-niebla-14);
  --accent: var(--cobre);              /* color de acento legible en contexto */
  --accent-wash: var(--alfa-cobre-12); /* fondo tenue del acento */
  --sheen: var(--alfa-cobre-10);       /* brillo que sigue al puntero */

  /* Ritmo vertical y medidas */
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --section-y: clamp(4.5rem, 10vw, 9rem);
  --measure: 62ch;
  --radius: 2px;
  --header-h: 5rem;

  /* Movimiento. Una sola familia de curvas en toda la web: lo que da
     sensación de pieza cara es que todo se mueva con el mismo acento. */
  --ease-out: cubic-bezier(0.16, 1, 0.30, 1);   /* salida suave, larga */
  --ease-soft: cubic-bezier(0.32, 0.72, 0, 1);  /* desplazamientos */
  --dur-fast: 220ms;
  --dur-base: 420ms;
  --dur-slow: 680ms;
  /* Los rótulos de sección van deliberadamente más lentos que todo lo demás.
     Lo que se lee como caro no es el movimiento, es la paciencia: nada llega
     con prisa y nada rebota. */
  --dur-rotulo: 1000ms;
  --dur-rotulo-track: 1400ms;
}

/* Secciones claras: se invierten los roles, nunca los valores de marca */
.on-light {
  --surface: var(--cal);
  --surface-deep: var(--niebla);
  --surface-raised: #FFFFFF;
  --text-strong: var(--tinta);
  --text-muted: var(--mineral-oscuro);
  --border: var(--alfa-tinta-14);
  --accent: var(--cobre-oscuro);
  --accent-wash: var(--alfa-cobre-12);
  --sheen: var(--alfa-cobre-10);
  background: var(--surface);
  color: var(--text-strong);
}

/* Cierre en cobre pleno: el acento pasa a ser Tinta, que sí contrasta.
   Los tokens los comparte con la cabeza del bloque macizo, que también va
   sobre cobre: si no se invirtieran, el rótulo saldría cobre sobre cobre. */
.closer,
.macizo__cabeza {
  --surface: var(--cobre);
  --surface-raised: var(--cobre);
  --text-strong: var(--tinta);
  --text-muted: var(--tinta-sobre-cobre);
  --border: var(--alfa-tinta-30);
  --accent: var(--tinta);
  --sheen: rgba(20, 45, 59, 0.07);
  background: var(--surface);
  color: var(--text-strong);
  overflow: hidden;
}

/* ---------- 03 Base y reset ---------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

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

/* Ningún destino de ancla queda debajo de la cabecera fija */
:target,
[id] { scroll-margin-top: calc(var(--header-h) + 1.5rem); }

body {
  margin: 0;
  background: var(--tinta);
  color: var(--niebla);
  font-family: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* 17px a 375 → 18px a 1440. El manual pide 16-18px de cuerpo en web. */
  font-size: clamp(1.0625rem, 1.0405rem + 0.094vw, 1.125rem);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;

  /* Ajuste óptico y microtipografía. Las dos fuentes son variables y traen
     eje de optical sizing: sin activarlo el navegador dibuja la misma forma
     de letra a 12 px que a 96 px, y esa uniformidad es una de las cosas que
     más hace que un texto parezca de plantilla. El kerning y las ligaduras
     no están garantizados por defecto en todos los navegadores, así que se
     piden de forma explícita. No cambia ni una medida: solo cómo encaja
     cada letra con la siguiente. */
  font-optical-sizing: auto;
  font-kerning: normal;
  font-variant-ligatures: common-ligatures contextual;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
}

p { margin: 0; text-wrap: pretty; }   /* evita líneas huérfanas de una palabra */

/* ---------- Partición de palabras y calidad del margen derecho ------------
   El <html> lleva lang="es", así que el navegador parte con los patrones
   silábicos del español y no por donde le parece. Sin esto, palabras como
   «automatización» o «responsabilidades» empujan la línea entera y dejan un
   margen derecho muy irregular, que es de las cosas que más hacen que un
   texto parezca sin cuidar.

   Solo se aplica al texto corrido. Los titulares NO se parten: una palabra
   cortada con guion en un titular de 48 px se ve desde la otra punta de la
   habitación y siempre parece un error. */
p,
li,
dd,
.t-lead,
.t-small,
.faq__panel,
.celda__texto,
.fila__texto {
  hyphens: auto;
  -webkit-hyphens: auto;
  /* No partir palabras de menos de 8 letras, ni dejar menos de 3 letras a
     un lado: un guion detrás de dos letras se lee como una errata. */
  hyphenate-limit-chars: 8 3 3;
  orphans: 2;
  widows: 2;
}

h1, h2, h3, h4, h5, h6,
.t-hero, .t-section, .t-sub, .t-card,
.eyebrow, .btn, .fila__titulo, .celda__titulo,
.peldano__titulo, .hero-cifra__num, .destacado__cifra {
  hyphens: manual;
  -webkit-hyphens: manual;
}

/* Números, códigos y nombres de herramienta no se parten nunca: un guion
   dentro de «PostgreSQL» o de «96 h» cambia lo que se lee. */
.tnum, .chip, code, kbd, samp { hyphens: none; -webkit-hyphens: none; }

/* ---------- Texto justificado: interruptor ---------------------------------
   Para verlo justificado, añadir la clase «justificado» al <body> de una
   página. Está preparado pero NO activado, y conviene saber por qué.

   La mayoría del texto de este sitio va en columnas de 34 a 46 caracteres.
   Justificar reparte el espacio sobrante entre las palabras de cada línea, y
   cuantas menos palabras hay por línea, más le toca a cada hueco: en columnas
   estrechas eso abre «ríos» de blanco que bajan por el párrafo y se ven antes
   que las palabras. En papel se corrige partiendo palabras a mano; en pantalla
   el navegador parte donde puede y el resultado es irregular de un tamaño de
   ventana a otro.

   Alinear a la izquierda con un margen derecho cuidado —que es lo que hacen
   ahora mismo text-wrap: pretty y la partición de arriba— es lo que usan las
   publicaciones que se quieren ver caras en pantalla. Justificar aquí se
   notaría, pero hacia el otro lado.

   Si aun así se quiere probar, esto lo deja lo mejor posible: se justifica
   solo el texto corrido, nunca los titulares ni los rótulos, y la última
   línea se queda suelta a la izquierda. */
body.justificado p,
body.justificado li,
body.justificado .t-lead,
body.justificado .t-small,
body.justificado .faq__panel,
body.justificado .celda__texto,
body.justificado .fila__texto {
  text-align: justify;
  text-align-last: start;
  text-justify: inter-word;
}
/* Lo que nunca se justifica, ni con el interruptor puesto */
body.justificado .eyebrow,
body.justificado .micro-trust,
body.justificado .pasos-rapidos,
body.justificado .peldano__texto,
body.justificado .hero-cifra__texto,
body.justificado .dato__texto,
body.justificado figcaption,
body.justificado th,
body.justificado td {
  text-align: start;
}

a { color: inherit; text-decoration: none; }

img { max-width: 100%; height: auto; display: block; }

::selection { background: var(--cobre); color: var(--tinta); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius);
}

/* Enlace de salto: fuera de pantalla hasta que recibe foco de teclado */
.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 200;
  transform: translateY(calc(-100% - 1.5rem));
  transition: transform var(--dur-base) var(--ease-out);
}
.skip-link:focus-visible { transform: translateY(0); }

/* ---------- 04 Tipografía ------------------------------------------------
   Escala fluida con una única ventana de interpolación: 375px → 1440px.
   Que todos los pasos compartan ventana es lo que evita que se crucen entre
   breakpoints. Valores reales resultantes:

              375px    768px   1024px   1440px
   t-hero      44,0     63,2     75,7     96,0
   t-section   32,0     42,3     49,1     60,0
   t-sub       22,0     26,4     29,3     34,0
   t-card      19,0     20,8     22,0     24,0
   t-lead      17,5     18,4     19,1     20,0
   cuerpo      17,0     17,4     17,6     18,0
   t-small     14,5     14,7     14,8     15,0

   La familia de display crece mucho más que la de texto: es deliberado.
   Un titular a 96px y un cuerpo a 18px es la proporción que se busca en
   pantalla grande, y comprimirla en móvil es lo que mantiene la línea legible. */
h1, h2, h3, h4, .font-display {
  font-family: 'Space Grotesk', 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;   /* reparte las líneas del titular, sin viudas */
}

/* El tracking se cierra a medida que crece el cuerpo: compensación óptica */
.t-hero {
  font-size: clamp(2.75rem, 1.6056rem + 4.883vw, 6rem);
  line-height: 0.99;
  letter-spacing: -0.036em;
}
.t-section {
  font-size: clamp(2rem, 1.3838rem + 2.629vw, 3.75rem);
  line-height: 1.05;
  letter-spacing: -0.028em;
}

/* Reparto equilibrado de líneas en los títulos que NO parte el JS. Evita el
   caso que más barato hace ver un titular: tres palabras arriba y una sola
   colgando abajo. No se aplica a .t-hero ni a .t-section porque esos los
   mide y reparte el script, y competirían. */
.t-sub, .t-card { text-wrap: balance; }
.t-sub {
  font-size: clamp(1.375rem, 1.1109rem + 1.127vw, 2.125rem);
  line-height: 1.16;
  letter-spacing: -0.022em;
}
.t-card {
  font-size: clamp(1.1875rem, 1.0775rem + 0.469vw, 1.5rem);
  line-height: 1.26;
  letter-spacing: -0.014em;
}
.t-lead {
  font-size: clamp(1.09375rem, 1.0387rem + 0.235vw, 1.25rem);
  line-height: 1.55;
  letter-spacing: -0.004em;
}
.t-small { font-size: clamp(0.90625rem, 0.8952rem + 0.047vw, 0.9375rem); line-height: 1.6; }

/* Etiqueta de sección: versalitas técnicas, el recurso que da el aire de
   documento de ingeniería que pide la marca. */
.eyebrow {
  font-family: 'IBM Plex Sans', ui-sans-serif, sans-serif;
  /* 15px a 375 → 17px a 1440. Antes iban a 12px y quedaban como una nota al
     pie; a este cuerpo el rótulo pesa lo que tiene que pesar sin discutirle
     la jerarquía al titular, que va de 32px para arriba. */
  font-size: clamp(0.9375rem, 0.8935rem + 0.188vw, 1.0625rem);
  font-weight: 600;
  /* En versalitas el ojo necesita más aire entre letras, pero pasarse las
     desune: 0,16em es el punto donde aún se leen como una palabra. */
  letter-spacing: 0.16em;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0;
}
/* Regla que se dibuja sola cuando la sección entra en pantalla */
.eyebrow::before {
  content: '';
  width: 2.25rem;
  height: 1px;
  background: currentColor;
  opacity: 0.75;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-out);
}
.eyebrow.is-in::before { transform: scaleX(1); }
.js .eyebrow:not(.is-in)::before { transform: scaleX(0); }

/* Entrada del rótulo, en dos capas.
   Capa 1: el bloque entero aparece. Deliberadamente sin clip-path ni máscara:
   un recorte que no se resuelva deja el rótulo invisible para siempre, y eso
   es exactamente lo que pasó la primera vez que se montó esto.
   Capa 2: si el JS ha partido el texto, cada letra sube a su turno.
   Si no lo ha partido, no hay letras que animar y el rótulo aparece igual. */
.js .eyebrow {
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.js .eyebrow.is-in { opacity: 1; }

/* La palabra es la unidad de salto de línea, no la letra */
.eyebrow__w { display: inline-block; white-space: nowrap; }

.eyebrow__c {
  display: inline-block;
  font-style: normal;
  opacity: 0;
  transform: translateY(0.5em);
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-rotulo) var(--ease-out);
  /* 26 ms por letra: por debajo de 20 se lee como un bloque, por encima de
     40 se nota el truco. Sin rebote — el overshoot abarata. */
  transition-delay: calc(var(--i, 0) * 26ms);
}
.eyebrow.is-in .eyebrow__c {
  opacity: 1;
  transform: translateY(0);
}
/* El número de sección no se estira con la palabra: mantiene su interletrado
   y llega antes. Que las dos cosas no se muevan igual es lo que hace que el
   conjunto parezca compuesto y no animado en bloque. */

/* Numeración automática de las secciones principales: 01 | CÓMO TRABAJAMOS */
main { counter-reset: seccion; }
[data-section] { counter-increment: seccion; }
[data-section] .eyebrow--index::after {
  content: counter(seccion, decimal-leading-zero);
  order: -1;
  padding-right: 0.95rem;
  border-right: 1px solid currentColor;
  opacity: 0.55;
  font-variant-numeric: tabular-nums;
  /* El número no se estira con el resto: mantiene su interletrado propio
     mientras la palabra se asienta. Que las dos cosas no se muevan igual es
     lo que hace que el conjunto parezca compuesto y no animado en bloque. */
  letter-spacing: 0.08em;
}
.eyebrow--index::before { display: none; }   /* el separador hace de regla */

/* Cifras siempre tabulares: precios, horas y pasos no deben bailar */
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ---------- 05 Estructura ------------------------------------------------ */
.shell {
  width: 100%;
  max-width: 88rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Ritmo vertical idéntico en todas las secciones, sin excepciones */
section { padding-block: var(--section-y); position: relative; }
.trust { padding-block: clamp(2rem, 4vw, 3.25rem); }

.rule { height: 1px; background: var(--border); border: 0; margin: 0; }

/* Rejilla técnica de fondo: estructura sin ruido. El #000 de la máscara no es
   un color visible — en una máscara significa "conservar el píxel". */
.grid-field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--border) 1px, transparent 1px),
    linear-gradient(90deg, var(--border) 1px, transparent 1px);
  background-size: 5.5rem 5.5rem;
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 0%, transparent 75%);
  mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 0%, transparent 75%);
  opacity: 0.6;
}
.grid-field--side {
  -webkit-mask-image: linear-gradient(100deg, #000 0%, transparent 55%);
  mask-image: linear-gradient(100deg, #000 0%, transparent 55%);
  opacity: 0.45;
}

/* Motivo "cauce": el mismo lenguaje del hero, en escala pequeña, para que
   las secciones de texto no se lean como una hoja en blanco. */
.motif {
  display: block;
  color: var(--accent);
  opacity: 0.9;
}
.motif--corner {
  position: absolute;
  pointer-events: none;
  opacity: 0.10;
  color: var(--text-strong);
}
.motif__stroke {
  stroke-dasharray: var(--len, 300);
  stroke-dashoffset: var(--len, 300);
  transition: stroke-dashoffset 1.2s var(--ease-out);
}
.is-in .motif__stroke,
.motif.is-in .motif__stroke { stroke-dashoffset: 0; }

/* ---------- 06 Botones y enlaces ----------------------------------------- */
.btn {
  --btn-bg: var(--cobre);
  --btn-fg: var(--tinta);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  min-height: 3rem;                 /* ≥44px de área táctil */
  padding: 0.875rem 1.6rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bg);
  border-radius: var(--radius);
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  white-space: nowrap;   /* un botón nunca parte su texto en dos líneas */
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  /* El desplazamiento magnético lo escribe el JS en --mag-x / --mag-y */
  translate: var(--mag-x, 0) var(--mag-y, 0);
  transition: color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              translate var(--dur-base) var(--ease-out);
}
/* Barrido de relleno: cambia el color, nunca la caja (no provoca reflow) */
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--niebla);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform var(--dur-base) var(--ease-out);
}
.btn:hover::before,
.btn:focus-visible::before { transform: scaleY(1); }
.btn:hover, .btn:focus-visible { color: var(--tinta); }
.btn:active { translate: 0 1px; transition-duration: 80ms; }
.btn__arrow { transition: transform var(--dur-base) var(--ease-out); }
.btn:hover .btn__arrow,
.btn:focus-visible .btn__arrow { transform: translateX(4px); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--text-strong);
  border-color: var(--border);
}
.btn--ghost::before { background: var(--text-strong); }
.btn--ghost:hover, .btn--ghost:focus-visible { color: var(--surface); }
.on-light .btn--ghost:hover,
.on-light .btn--ghost:focus-visible { color: var(--cal); }

.btn--lg { min-height: 3.5rem; padding: 1.05rem 2rem; font-size: 1rem; }

/* Enlace con línea que se retira y vuelve por el otro lado */
.link-underline {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  color: var(--accent);
  padding-block: 0.25rem;
}
.link-underline::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-out);
}
.link-underline:hover::after,
.link-underline:focus-visible::after { transform: scaleX(0); transform-origin: left; }
.link-underline svg { transition: transform var(--dur-base) var(--ease-out); }
.link-underline:hover svg,
.link-underline:focus-visible svg { transform: translate(3px, -3px); }

/* ---------- 07 Cabecera ---------------------------------------------------
   Barra sólida desde el primer píxel. La versión anterior era transparente
   sobre la portada y cambiaba los colores del texto con una clase que ponía
   el JavaScript: sobre el fondo oscuro los enlaces quedaban en Tinta sobre
   Tinta y desaparecían. El color del texto ya no depende de ningún estado. */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  background: var(--tinta-abismo);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
/* Al despegarse de la portada solo gana un filo y una sombra mínima */
.site-header.is-stuck {
  border-bottom-color: var(--alfa-niebla-14);
  box-shadow: 0 12px 32px -24px rgba(0, 0, 0, 0.9);
}
/* Hilo de progreso de lectura: 1px, solo visible cuando la cabecera se asienta */
.site-header__progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 1px; width: 100%;
  background: var(--cobre);
  transform: scaleX(var(--progress, 0));
  transform-origin: left;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.site-header.is-stuck .site-header__progress { opacity: 1; }

/* min-height y no height: si un día cabe un elemento más alto, la barra crece
   en lugar de dejar que el contenido se salga por abajo. */
.site-header__inner {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: clamp(1rem, 3vw, 2.75rem);
  min-height: var(--header-h);
}
/* El PNG de marca es Tinta sobre transparente y el propio manual avisa de que
   está preparado para fondos claros. Como la barra es oscura siempre, se usa
   la versión recoloreada a Niebla, que conserva el cobre del símbolo. */
.site-header__logo {
  display: block;
  flex: none;
  /* El realce va en la imagen, no aquí, para poder escalar sin arrastrar el
     área de clic. */
}
.site-header__logo img {
  /* La cabecera usa escalatech-logo-claro-recorte.png, no el PNG de marca
     original. El original es un lienzo de 500×167 con la marca ocupando solo
     el 44 % del alto: al darle 38px de alto, lo que se veía eran 17px de
     logo y el resto era aire transparente. Por eso seguía pareciendo pequeño
     aunque el número subiera. Con el recorte, el alto que se pone aquí es el
     alto que se ve: 26px a 375 → 34px a 1440. */
  height: clamp(1.625rem, 1.44rem + 0.8vw, 2.125rem);
  width: auto;
  display: block;
  transform-origin: left center;
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
/* Microanimación del logo: dos por ciento de escala y un punto de opacidad.
   Se ancla a la izquierda para que crezca hacia dentro de la barra y no
   empuje al menú. Deliberadamente por debajo del umbral de lo evidente: si
   se nota que el logo "hace algo", está mal calibrado. */
.site-header__logo:hover img,
.site-header__logo:focus-visible img {
  transform: scale(1.02);
  opacity: 0.88;
}

/* El menú completo solo aparece cuando caben de verdad los seis enlaces más
   el botón. Por debajo de 1240px se usa el desplegable: es preferible eso a
   que las etiquetas se partan en dos líneas y se salgan de la barra. */
.nav {
  display: none;
  align-items: center;
  gap: clamp(1rem, 1.7vw, 1.85rem);
  margin-inline-start: auto;
}
@media (min-width: 1240px) { .nav { display: flex; } }

/* Navegación: un punto más pequeña y con algo de interletrado. Una barra
   cara casi nunca tiene la nav al tamaño del cuerpo de texto — la baja y la
   abre, para que pese menos que la marca y que el botón de acción. */
.nav__link {
  position: relative;
  flex: none;
  white-space: nowrap;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.015em;
  color: var(--niebla);
  padding-block: 0.35rem;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--cobre);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link[aria-current='page']::after { transform: scaleX(1); transform-origin: left; }
.nav__link[aria-current='page'] { color: var(--cobre); }

/* ---------- Menú desplegable ---------------------------------------------
   Automatización tiene dos páginas: la visión general y el caso completo de
   pedidos. En lugar de poner las dos al mismo nivel en la barra —que sugiere
   que no tienen relación— cuelgan de un desplegable. Se abre al pasar el
   ratón y también con teclado, porque solo con hover sería inaccesible. */
.nav__group { position: relative; flex: none; }

.nav__toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  white-space: nowrap;
  background: none;
  border: 0;
  padding: 0.35rem 0;
  font-family: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: 0.015em;
  color: var(--niebla);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__toggle::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--cobre);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__group:hover .nav__toggle::after,
.nav__toggle:focus-visible::after,
.nav__group.is-open .nav__toggle::after,
.nav__toggle[data-current]::after { transform: scaleX(1); transform-origin: left; }
.nav__toggle[data-current] { color: var(--cobre); }

.nav__chevron {
  flex: none;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__group.is-open .nav__chevron { transform: rotate(180deg); }

/* ==========================================================================
   DESPLEGABLE
   Era un cuadradito con dos enlaces y un fondo al pasar por encima: el patrón
   que trae cualquier plantilla. Un menú se abre decenas de veces por visita,
   así que es de las piezas que más veces se ven, y por tanto de las que más
   dicen lo que cuesta el sitio.

   Lo que lo cambia: una superficie ancha y bien construida en lugar de una
   caja, filas separadas por filetes en vez de píldoras redondeadas, números
   tabulares como en el resto del sistema, un filo de cobre que se dibuja al
   abrir, entrada escalonada de cada fila y una columna de contexto que
   convierte el menú en una ayuda para decidir, no en una lista.
   ========================================================================== */
.nav__menu {
  position: absolute;
  top: calc(100% + 0.9rem);
  left: -1.1rem;
  z-index: 10;
  width: max-content;
  max-width: min(40rem, calc(100vw - 3rem));
  padding: 0;
  background: var(--tinta-elevada);
  border: 1px solid var(--alfa-niebla-14);
  border-radius: var(--radius);
  /* Sombra en tres capas: un filo de luz arriba que despega el panel del
     fondo, un contacto corto y una caída larga y muy difusa. Una sola sombra
     grande se lee como un cuadro flotando; tres capas se leen como un plano
     por encima de otro. */
  box-shadow:
    inset 0 1px 0 0 var(--alfa-niebla-08),
    0 2px 6px -2px rgba(0, 0, 0, 0.45),
    0 28px 54px -28px rgba(0, 0, 0, 0.85),
    0 56px 96px -52px rgba(0, 0, 0, 0.9);
  opacity: 0;
  visibility: hidden;
  translate: 0 -6px;
  transition: opacity var(--dur-base) var(--ease-out),
              translate var(--dur-base) var(--ease-out),
              visibility var(--dur-base);
}
/* Puente invisible sobre el hueco: si no, el menú se cierra al bajar el ratón */
.nav__menu::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  top: -0.9rem; height: 0.9rem;
}
.nav__group:hover .nav__menu,
.nav__group.is-open .nav__menu,
.nav__group:focus-within .nav__menu {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
}

/* El filo de cobre se dibuja de izquierda a derecha al abrir. Va después de
   que el panel haya aparecido, no a la vez: primero llega la superficie y
   luego se firma. */
.nav__menu::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--cobre);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 560ms var(--ease-out) 70ms;
}
.nav__group:hover .nav__menu::after,
.nav__group.is-open .nav__menu::after,
.nav__group:focus-within .nav__menu::after { transform: scaleX(1); }

/* Dos zonas: los destinos a la izquierda y el contexto a la derecha. Con el
   panel cerrado la rejilla no importa; abierto, es lo que hace que parezca
   una superficie pensada y no una lista. */
.nav__menu-inner {
  display: grid;
  grid-template-columns: 1fr;
  counter-reset: navitem;
}
/* 1180 y no 1240 a propósito: la barra solo aparece a partir de 1240, así que
   en la práctica el panel siempre sale a dos columnas. El margen de 60px es
   para que, si algún día se baja el punto de la barra, el panel no se quede
   de golpe en una sola columna sin que nadie se dé cuenta. */
@media (min-width: 1180px) {
  .nav__menu-inner { grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.85fr); }
}

.nav__menu-lista { min-width: 0; padding: 0.35rem 0; }

.nav__menu-link {
  position: relative;
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr) 0.9rem;
  gap: 0 0.85rem;
  align-items: start;
  padding: 0.95rem 1.15rem;
  counter-increment: navitem;
  transition: background var(--dur-fast) var(--ease-out);
}
.nav__menu-link + .nav__menu-link { border-top: 1px solid var(--alfa-niebla-08); }
.nav__menu-link:hover,
.nav__menu-link:focus-visible { background: var(--alfa-niebla-08); }

/* Filo de acento que crece desde el borde izquierdo, igual que en .fila: el
   mismo gesto en todo el sitio se lee como un sistema, no como adornos. */
.nav__menu-link::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--cobre);
  transform: scaleY(0);
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__menu-link:hover::before,
.nav__menu-link:focus-visible::before,
.nav__menu-link[aria-current='page']::before { transform: scaleY(1); }

.nav__menu-num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.7;
  color: var(--mineral);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease-out);
}
.nav__menu-num::before { content: counter(navitem, decimal-leading-zero); }
.nav__menu-link:hover .nav__menu-num,
.nav__menu-link[aria-current='page'] .nav__menu-num { color: var(--cobre); }

.nav__menu-titulo {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--niebla);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__menu-link:hover .nav__menu-titulo,
.nav__menu-link[aria-current='page'] .nav__menu-titulo { color: var(--cobre); }
.nav__menu-desc {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--mineral-claro);
}

/* La flecha vive fuera del borde y entra al pasar por encima */
.nav__menu-flecha {
  align-self: center;
  color: var(--cobre);
  opacity: 0;
  transform: translateX(-5px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.nav__menu-link:hover .nav__menu-flecha,
.nav__menu-link:focus-visible .nav__menu-flecha {
  opacity: 1;
  transform: translateX(0);
}

/* --- Entrada escalonada -------------------------------------------------
   Las filas entran una detrás de otra, muy seguidas. Es la diferencia entre
   un panel que aparece y un panel que se despliega. */
.nav__menu-link,
.nav__menu-aside {
  opacity: 0;
  translate: 0 -4px;
  transition:
    opacity var(--dur-base) var(--ease-out),
    translate var(--dur-base) var(--ease-out),
    background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}
.nav__group:hover .nav__menu-link,
.nav__group.is-open .nav__menu-link,
.nav__group:focus-within .nav__menu-link,
.nav__group:hover .nav__menu-aside,
.nav__group.is-open .nav__menu-aside,
.nav__group:focus-within .nav__menu-aside { opacity: 1; translate: 0 0; }

.nav__menu-link:nth-child(1) { transition-delay: 60ms; }
.nav__menu-link:nth-child(2) { transition-delay: 115ms; }
.nav__menu-link:nth-child(3) { transition-delay: 170ms; }
.nav__menu-aside { transition-delay: 150ms; }

/* --- Columna de contexto ------------------------------------------------
   Un menú que solo lista destinos obliga a elegir a quien todavía no sabe.
   Esta columna dice por dónde se empieza, que es lo que de verdad hace falta. */
.nav__menu-aside {
  padding: 1.15rem;
  border-top: 1px solid var(--alfa-niebla-08);
  background: var(--tinta-abismo);
}
@media (min-width: 1180px) {
  .nav__menu-aside {
    border-top: 0;
    border-inline-start: 1px solid var(--alfa-niebla-08);
  }
}
/* Rótulo propio, no .eyebrow. El .eyebrow del sitio arranca con opacidad 0 y
   espera a que el observador de scroll lo revele; dentro de un panel que está
   oculto casi todo el tiempo, ese revelado puede no dispararse nunca y el
   rótulo se quedaría invisible para siempre. */
.nav__menu-rotulo {
  display: block;
  margin-bottom: 0.7rem;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mineral-claro);
}
.nav__menu-aside p {
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--mineral-claro);
}
.nav__menu-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.9rem;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--cobre);
}
.nav__menu-cta svg {
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__menu-cta:hover svg,
.nav__menu-cta:focus-visible svg { transform: translateX(3px); }

/* Menú móvil: sin acordeones anidados. Un rótulo y los hijos sangrados se
   entienden de un vistazo y no esconden nada tras otro toque. */
.nav__movil-grupo {
  border-left: 1px solid var(--alfa-niebla-14);
  padding-left: 1rem;
  margin-block: 0.35rem 0.75rem;
}
.nav__movil-rotulo {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cobre);
  margin-bottom: 0.25rem;
}

/* Página aún no construida: se mantiene visible la estructura del sitio,
   pero no se finge un enlace que no lleva a ninguna parte. */
.nav__soon {
  position: relative;
  flex: none;
  white-space: nowrap;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--mineral);
  padding-block: 0.35rem;
  cursor: default;
  display: inline-flex;
  align-items: center;
}
.nav__soon > .nav__soon-note {
  position: absolute;
  top: calc(100% + 0.55rem);
  left: 50%;
  translate: -50% 4px;
  white-space: nowrap;
  background: var(--tinta-elevada);
  border: 1px solid var(--border);
  color: var(--niebla);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  padding: 0.3rem 0.55rem;
  border-radius: var(--radius);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out),
              translate var(--dur-fast) var(--ease-out);
}
.nav__soon:hover > .nav__soon-note,
.nav__soon:focus-visible > .nav__soon-note { opacity: 1; translate: -50% 0; }

/* ---------- 08 Hero ------------------------------------------------------- */
/* Portada clara sobre el esquema del proceso. La web arranca en "papel"
   —un plano técnico— y desciende a Tinta en el resto: el mismo recorrido
   que hace un proyecto al pasar del dibujo a la operación. */
.hero--schematic {
  --surface: var(--papel);
  --surface-raised: #FFFFFF;
  --text-strong: var(--tinta);
  --text-muted: var(--mineral-oscuro);
  --border: var(--alfa-tinta-14);
  --accent: var(--cobre-oscuro);
  --accent-wash: var(--alfa-cobre-12);
  position: relative;
  background: var(--papel);
  color: var(--tinta);
  padding-block: calc(var(--header-h) + clamp(1.5rem, 4vw, 3.5rem))
                 clamp(2.5rem, 5vw, 4.5rem);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 980px) {
  .hero__grid { grid-template-columns: minmax(0, 30rem) minmax(0, 1fr); }
}
.hero__copy { min-width: 0; }
/* La columna de texto mide como mucho 30rem: el titular no puede usar la
   escala completa de display o rompería en cinco líneas de dos palabras. */
.hero--schematic .t-hero {
  font-size: clamp(2.25rem, 1.6021rem + 2.765vw, 4.0625rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
}

/* Punto de control como marca de la portada: el mismo lenguaje que los nodos
   naranjas del esquema. */
.eyebrow--dot { color: var(--mineral-oscuro); }
.eyebrow--dot::before {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--cobre);
  box-shadow: 0 0 0 3px var(--alfa-cobre-20);
  opacity: 1;
  transform: none;
}
.js .eyebrow--dot:not(.is-in)::before { transform: none; }

/* Panel del esquema */
.hero__visual {
  position: relative;
  width: 100%;
  aspect-ratio: 1250 / 821;
  border-radius: 14px;
  overflow: hidden;
  background: var(--papel);
  border: 1px solid var(--niebla);
}
@media (min-width: 980px) {
  .hero__visual { aspect-ratio: 1250 / 760; }
}
.hero__visual img,
.hero__visual .hero__overlay {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  display: block;
}
.hero__visual img { object-fit: cover; object-position: 100% 50%; }

/* Los dos nodos de control respiran; el dato recorre la ruta. Es la única
   animación en bucle de la web y se detiene cuando el hero sale de pantalla. */
.pulse-dot { filter: drop-shadow(0 0 3px var(--alfa-cobre-70)); }
.glow-a { animation: respira 2.6s ease-in-out infinite; }
.glow-b { animation: respira 2.6s ease-in-out infinite 1.1s; }
@keyframes respira {
  0%, 100% { r: 9; opacity: 0.5; }
  50%      { r: 16; opacity: 0.08; }
}
/* En pantallas táctiles el bucle se queda quieto (ver initPortadaViva). */
.hero__overlay.is-quieta .glow-a,
.hero__overlay.is-quieta .glow-b { animation: none; }

.micro-trust { font-size: 0.8125rem; color: var(--text-muted); }

/* Salida que se ofrece bajo el aviso del formulario cuando algo impide el
   envío. Tiene que verse como algo que se pulsa, no como más texto de error. */
.form-salida {
  display: inline-block;
  margin-top: 0.6rem;
  font-weight: 600;
  color: var(--accent);
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size var(--dur-base) var(--ease-out);
}
.form-salida:hover { background-size: 0% 1px; background-position: 100% 100%; }

/* Correo de contacto: se pinta desde main.js, así que el enlace tiene que
   poder aparecer en cualquiera de los dos contextos, claro y oscuro. */
.correo-contacto {
  color: var(--text-strong);
  background-image: linear-gradient(var(--accent), var(--accent));
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size var(--dur-base) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
  white-space: nowrap;
}
.correo-contacto:hover { color: var(--accent); background-size: 0% 1px; background-position: 100% 100%; }

/* La tercera vía del bloque de contacto, debajo del formulario y de WhatsApp */
.contacto__correo {
  margin-top: 1rem;
  color: var(--text-muted);
}

/* ---------- Confianza junto al primer botón ------------------------------
   Debajo del CTA del hero van dos cosas que hasta ahora estaban repartidas
   por el sitio y llegaban tarde: qué pasa exactamente después de escribir, y
   quién está al otro lado. Es donde se decide si alguien escribe o no. */
.hero__garantia {
  margin-top: 0.35rem;
  display: grid;
  gap: 0.6rem;
}
/* Los tres hitos del paso siguiente, separados por puntos finos */
.pasos-rapidos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
.pasos-rapidos > * { display: inline-flex; align-items: center; gap: 0.45rem; }
.pasos-rapidos > * + *::before {
  content: '';
  width: 3px; height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
}
.pasos-rapidos strong {
  color: var(--text-strong);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* La firma: quién atiende. Sin foto todavía, así que el peso lo llevan los
   nombres y el enlace a las credenciales. */
.firma-hero {
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 44ch;
}
.firma-hero a {
  color: var(--text-strong);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size var(--dur-base) var(--ease-out);
}
.firma-hero a:hover { background-size: 0% 1px; background-position: 100% 100%; }

/* ---------- Cifras del hero ----------------------------------------------
   Dos números y nada más. Los dos son verdad y los dos juegan a favor: uno
   dice que hay cola, el otro que se contesta rápido. Una cifra inventada
   aquí destruiría la credibilidad de todo lo demás. */
.datos-hero {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.dato__cifra {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.dato__texto {
  display: block;
  margin-top: 0.45rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-muted);
  max-width: 24ch;
}

/* El icono de WhatsApp dentro del botón: se ve de un vistazo qué va a pasar
   al pulsar, que es media batalla de la claridad. */
.btn__whatsapp { flex: none; }

/* ---------- Franja de cifras ---------------------------------------------
   Cuatro números que se leen en dos segundos. Van juntos a propósito: por
   separado cada uno es un currículum, juntos son la capacidad de una casa. */
.cifras {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.75rem, 4vw, 3rem);
}
@media (min-width: 900px) { .cifras { grid-template-columns: repeat(4, 1fr); } }
/* Altura mínima común: una de las cuatro es texto y no un número, y sin
   esto las reglas de debajo quedarían a distintas alturas en la misma fila. */
.cifra__num {
  display: flex;
  align-items: flex-end;
  min-height: clamp(2.25rem, 4.2vw, 3.25rem);
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(2.25rem, 4.2vw, 3.25rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
/* Cuando la "cifra" son palabras y no un número, baja de cuerpo: a 52px
   "AWS · Azure" se sale de su columna y rompe la alineación de la fila. */
.cifra__num--texto {
  font-size: clamp(1.375rem, 2.1vw, 1.75rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.cifra__texto {
  display: block;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* ==========================================================================
   MAQUETACIONES ALTERNATIVAS
   El sitio repetía cuatro bloques en nueve páginas: franja de tres, rejilla
   de tarjetas, lista numerada y acordeón. Estos cuatro patrones rompen esa
   monotonía sin salirse del sistema: mismos tokens, mismas curvas.
   ========================================================================== */

/* ---------- A · Filas a ancho completo -----------------------------------
   Una lista que ocupa todo el ancho, con el número pequeño a la izquierda y
   el titular grande. Pesa mucho más que una rejilla de tarjetas y deja
   respirar: sirve para enumerar problemas, fases o comprobaciones. */
.filas {
  border-top: 1px solid var(--border);
  counter-reset: fila;
}
.fila {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.4rem 1.75rem;
  padding-block: clamp(1.35rem, 2.6vw, 1.9rem);
  padding-inline: 0;
  border-bottom: 1px solid var(--border);
  counter-increment: fila;
  transition: padding-inline-start var(--dur-base) var(--ease-soft);
}
@media (min-width: 720px) {
  .fila { grid-template-columns: 4.5rem minmax(0, 1fr); align-items: baseline; }
}
/* Filo de acento que crece desde el centro al pasar por encima */
.fila::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transition: transform var(--dur-base) var(--ease-out);
}
.fila:hover { padding-inline-start: 1.25rem; }
.fila:hover::before { transform: scaleY(1); }

.fila__num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease-out);
}
.fila__num::before { content: counter(fila, decimal-leading-zero); }
.fila:hover .fila__num { color: var(--accent); }

/* Cuando la columna de la izquierda lleva un dato en vez de un número de
   orden (una fecha de entrada en vigor, por ejemplo), no se numera y cabe
   más ancho: la fecha es la información, no la posición en la lista. */
.fila__num--dato::before { content: none; }
.fila__num--dato {
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.6875rem;
  line-height: 1.4;
  color: var(--accent);
}
@media (min-width: 720px) {
  .filas--dato .fila { grid-template-columns: 11rem minmax(0, 1fr); }
}

.fila__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.0625rem, 1.7vw, 1.375rem);
  line-height: 1.25;
  letter-spacing: -0.014em;
  margin: 0;
}
.fila__texto {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 64ch;
}

/* Fila que además es un enlace: toda la banda es la zona pulsable y la flecha
   sale de la derecha. El foco de teclado tiene que verse, porque aquí no hay
   ningún recuadro que lo delate. */
a.fila {
  text-decoration: none;
  color: inherit;
}
a.fila:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
@media (min-width: 720px) {
  a.fila { grid-template-columns: 4.5rem minmax(0, 1fr) auto; }
}
.fila__flecha {
  align-self: center;
  justify-self: end;
  color: var(--text-muted);
  transform: translateX(-6px);
  opacity: 0;
  transition:
    transform var(--dur-base) var(--ease-out),
    opacity var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}
a.fila:hover .fila__flecha,
a.fila:focus-visible .fila__flecha {
  transform: translateX(0);
  opacity: 1;
  color: var(--accent);
}
a.fila:hover .fila__titulo { color: var(--accent); }
.fila__titulo { transition: color var(--dur-fast) var(--ease-out); }
/* En móvil la flecha no se esconde: no hay puntero que la despierte */
@media (max-width: 719px) {
  .fila__flecha { opacity: 1; transform: none; }
}

/* ---------- B · Panel destacado ------------------------------------------
   Texto a la izquierda y un panel con filo de acento arriba a la derecha.
   Para lo que tiene que quedarse en la cabeza: una cifra, una condición o
   una llamada a la acción que no puede competir con nada más. */
.destacado {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}
@media (min-width: 900px) { .destacado { grid-template-columns: 1.15fr 0.85fr; } }

.destacado__panel {
  position: relative;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
/* La regla superior se dibuja de izquierda a derecha al entrar en pantalla */
.destacado__panel::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  height: 2px; width: 100%;
  background: var(--accent);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-out);
}
/* Sin JavaScript se ve entera; con JavaScript parte de cero y se dibuja */
.js .destacado__panel::before { transform: scaleX(0); }
.js .destacado__panel.is-in::before { transform: scaleX(1); }

.destacado__cifra {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  line-height: 1.05;
  letter-spacing: -0.028em;
  color: var(--text-strong);
}

/* ---------- C · Celdas con borde compartido ------------------------------
   Rejilla que se lee como una tabla de capacidades. Al no llevar sombra ni
   separación, el conjunto pesa como un bloque y no como fichas sueltas. */
.celdas {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 680px) { .celdas { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .celdas--3 { grid-template-columns: repeat(3, 1fr); } }

.celda {
  position: relative;
  background: var(--surface);
  padding: clamp(1.5rem, 2.8vw, 2rem);
  transition: background var(--dur-base) var(--ease-out);
}
/* Sube un paso, no baja: en oscuro pasa a Tinta elevada y en claro a blanco */
.celda:hover { background: var(--surface-raised); }
.celda__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.012em;
  margin: 0;
  transition: color var(--dur-fast) var(--ease-out);
}
.celda:hover .celda__titulo { color: var(--accent); }
.celda__texto {
  margin-top: 0.7rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-muted);
}

/* ---------- D · Bloque macizo de color -----------------------------------
   Un slab en cobre con la pregunta y, debajo, la respuesta sobre Tinta.
   Se usa una vez por página como mucho: es el recurso más ruidoso del
   sistema y repetirlo lo gasta. */
.macizo { display: grid; grid-template-columns: 1fr; }
/* El fondo y los tokens de color los pone la regla de contexto de arriba,
   la que comparte con .closer. Aquí solo va la caja. */
.macizo__cabeza { padding-block: clamp(2.25rem, 5vw, 3.75rem); }
.macizo__cabeza h2 { margin: 0; }
.macizo__cuerpo {
  background: var(--tinta-abismo);
  color: var(--niebla);
  padding-block: clamp(2.25rem, 5vw, 3.75rem);
}
.macizo__cuerpo .t-lead { color: var(--niebla); }
.macizo__cuerpo .t-small { color: var(--mineral-claro); }
.macizo__cuerpo p + p { margin-top: 1.25rem; }

/* ---------- Pila técnica -------------------------------------------------
   Pensada para que la lea el departamento de informática del cliente: en
   cuanto reconoce tres nombres suyos, deja de tratarte como a un proveedor
   improvisado. Por eso van con el nombre exacto y agrupados por función. */
.pila {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 720px) { .pila { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .pila { grid-template-columns: repeat(3, 1fr); } }

.pila__bloque {
  background: var(--surface);
  padding: clamp(1.4rem, 2.6vw, 1.9rem);
  transition: background var(--dur-base) var(--ease-out);
}
.pila__bloque:hover { background: var(--surface-deep); }
.pila__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.012em;
  margin: 0.9rem 0 0;
}
.pila__lista {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  margin: 1.1rem 0 0;
  padding: 0;
}
.chip {
  display: inline-block;
  padding: 0.28rem 0.6rem 0.3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.78125rem;
  line-height: 1.3;
  color: var(--text-muted);
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.pila__bloque:hover .chip { border-color: var(--alfa-cobre-40); color: var(--text-strong); }

/* ---------- Retrato del equipo ------------------------------------------
   Va al final, no en la portada: primero se gana la credibilidad con lo que
   se ha hecho y después se pone cara. Al revés es una tarjeta de visita. */
.equipo {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 900px) { .equipo { grid-template-columns: 1.1fr 0.9fr; } }
.equipo__firma {
  display: grid;
  gap: 1.25rem;
  margin-top: 2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
@media (min-width: 560px) { .equipo__firma { grid-template-columns: 1fr 1fr; } }
.equipo__nombre {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.012em;
}
.equipo__rol {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
}
/* El enlace al perfil: discreto en reposo y con el icono subrayándose al
   pasar. No compite con el nombre, pero está ahí para quien quiera comprobar. */
.equipo__perfil {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.6rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-muted);
  transition: color var(--dur-fast) var(--ease-out);
}
.equipo__perfil svg {
  flex: none;
  transition: transform var(--dur-base) var(--ease-out);
}
.equipo__perfil:hover,
.equipo__perfil:focus-visible { color: var(--accent); }
.equipo__perfil:hover svg { transform: translateY(-1px); }

/* ---------- Reparto del esfuerzo ----------------------------------------
   Dos columnas enfrentadas. Lo que pone el cliente va primero y con el
   acento encima, porque es lo único que él tiene que decidir. */
.reparto {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 620px) { .reparto { grid-template-columns: 1fr 1fr; } }
.reparto__lado {
  background: var(--surface);
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}
.reparto__lado--nuestro { background: var(--surface-deep); }
.reparto__lado--nuestro .eyebrow { color: var(--text-muted); }

/* ---------- Fotografía ---------------------------------------------------
   Reglas tomadas de Material Web/GUIA-DE-COLOCACION.md: bordes de 16-20px,
   sombra tenue en azul tinta, color intacto y sin filtros. La guía prohíbe
   además parallax, zoom y movimiento de cámara sobre las fotos, así que
   aquí no hay ninguna transformación: solo entran con el mismo fundido que
   el resto del contenido. */
.foto {
  margin: 0;
  border-radius: 18px;
  overflow: hidden;
  background: var(--surface-raised);
  box-shadow: 0 28px 56px -34px rgba(20, 45, 59, 0.6);
}
.foto img {
  width: 100%;
  height: auto;
  display: block;
}
.foto--recorte img {
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
.foto figcaption {
  padding: 0.9rem 1.1rem 1.05rem;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-muted);
  background: var(--surface-raised);
  border-top: 1px solid var(--border);
}

/* Pareja de fotografía y explicación, en el orden que pide la guía:
   en móvil manda siempre el texto y la foto va debajo. */
.foto-par {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
}
@media (min-width: 900px) {
  .foto-par { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .foto-par--foto-izquierda .foto-par__texto { order: 2; }
  .foto-par--foto-izquierda .foto-par__foto { order: 1; }
}
.foto-par__foto { order: 2; }
.foto-par__texto { order: 1; }

/* Franja de pruebas bajo la portada */
.proof { background: var(--papel); padding-block: 0 clamp(2.5rem, 6vw, 4.5rem); }
.proof__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem clamp(1rem, 2.5vw, 2rem);
  border-top: 1px solid var(--alfa-tinta-14);
  padding-top: clamp(1.5rem, 3vw, 2rem);
}
@media (min-width: 780px) { .proof__grid { grid-template-columns: repeat(3, 1fr); } }
.proof__item {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  color: var(--tinta);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.proof__num {
  flex: none;
  width: 1.75rem; height: 1.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--alfa-cobre-40);
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 0.8125rem;
  color: var(--cobre-oscuro);
  font-variant-numeric: tabular-nums;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-soft);
}
.proof__item:hover .proof__num {
  background: var(--alfa-cobre-12);
  border-color: var(--cobre-oscuro);
  transform: translateY(-2px);
}

/* --- Variante A · Pilares ------------------------------------------------
   Sin círculos numerados: tres columnas separadas por una regla vertical y
   un rótulo corto encima. La misma información pesa distinto cuando no va
   numerada, y así la franja no se reconoce de página en página. */
.proof--pilares .proof__grid {
  gap: 0 clamp(1.5rem, 3.5vw, 3rem);
  row-gap: clamp(1.75rem, 3vw, 2rem);
}
.proof--pilares .proof__item {
  display: block;
  position: relative;
  padding-inline-start: 0;
}
@media (min-width: 780px) {
  .proof--pilares .proof__item + .proof__item {
    padding-inline-start: clamp(1.5rem, 3.5vw, 3rem);
  }
  /* La regla arranca desde arriba y crece hacia abajo al entrar en pantalla */
  .proof--pilares .proof__item + .proof__item::before {
    content: '';
    position: absolute;
    inset-block: 0.15rem 0.15rem;
    inset-inline-start: 0;
    width: 1px;
    background: var(--alfa-tinta-14);
  }
}
.proof__rotulo {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--cobre-oscuro);
  margin-bottom: 0.7rem;
  transition: letter-spacing var(--dur-slow) var(--ease-out);
}
.proof--pilares .proof__item:hover .proof__rotulo { letter-spacing: 0.2em; }

/* --- Variante B · Aserto -------------------------------------------------
   Una frase grande a la izquierda y dos apoyos pequeños a la derecha. Sirve
   cuando de las tres ideas una manda y las otras dos la sostienen. */
.proof--aserto .proof__grid { grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .proof--aserto .proof__grid {
    grid-template-columns: 1.1fr 0.9fr;
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
  .proof--aserto .proof__item--principal { grid-row: span 2; }
}
.proof__item--principal {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--tinta);
}
.proof--aserto .proof__item:not(.proof__item--principal) {
  display: block;
  padding-top: 1rem;
  border-top: 1px solid var(--alfa-tinta-14);
}

/* ==========================================================================
   PORTADAS ALTERNATIVAS
   Seis de las nueve páginas abrían con el mismo esquema de proceso. La imagen
   es buena, pero repetida seis veces deja de decir nada y hace que todas las
   páginas parezcan la misma. El esquema se queda en la portada del sitio, que
   es su sitio; las demás abren con lo que de verdad va de esa página.
   ========================================================================== */

/* ---------- A · Escalera numerada ----------------------------------------
   En vez de una ilustración, los pasos del proceso en la propia portada. El
   visitante ve el recorrido entero antes de bajar. Referencia 1. */
.hero-escalera {
  display: grid;
  gap: 0;
  align-content: center;
  counter-reset: peldano;
  width: 100%;
}
/* La escalera es texto: el marco crece con ella en vez de recortarla. */
.hero__visual:has(.hero-escalera) { aspect-ratio: auto; }
.peldano {
  position: relative;
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  gap: 1.25rem;
  align-items: baseline;
  padding-block: clamp(1.1rem, 2.2vw, 1.5rem);
  border-top: 1px solid var(--border);
  counter-increment: peldano;
  transition: padding-inline-start var(--dur-base) var(--ease-soft);
}
.peldano:last-child { border-bottom: 1px solid var(--border); }
.peldano:hover { padding-inline-start: 0.85rem; }
.peldano__num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-base) var(--ease-out);
}
.peldano__num::before { content: counter(peldano, decimal-leading-zero); }
.peldano:hover .peldano__num { color: var(--accent); }
.peldano__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1rem, 1.5vw, 1.1875rem);
  line-height: 1.3;
  margin: 0;
}
.peldano__texto {
  margin-top: 0.3rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--text-muted);
}
/* La marca de «sin coste» tiene que verse sin leer: es el argumento */
.peldano__nota {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.2rem 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 2px;
}

/* ---------- B · Columna de cifras con regla ------------------------------
   Titular ancho a la izquierda y, separada por una línea de un píxel, una
   columna estrecha con las cifras que sostienen lo que dice el titular.
   Referencia 3. */
.hero-cifras {
  display: grid;
  gap: clamp(1.75rem, 3vw, 2.5rem);
  align-content: center;
  width: 100%;
  padding-inline-start: 0;
  border-inline-start: none;
}
@media (min-width: 1000px) {
  .hero-cifras {
    padding-inline-start: clamp(2rem, 4vw, 3.5rem);
    border-inline-start: 1px solid var(--border);
  }
}
.hero-cifra__num {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(2rem, 4.5vw, 3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text-strong);
  font-variant-numeric: tabular-nums;
}
.hero-cifra__texto {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--text-muted);
  max-width: 30ch;
}
/* Un filo de acento que aparece al pasar por encima, sin mover nada */
.hero-cifra {
  position: relative;
  padding-inline-start: 1rem;
  margin-inline-start: -1rem;
}
.hero-cifra::before {
  content: '';
  position: absolute;
  inset-block: 0.1rem;
  inset-inline-start: 0;
  width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform var(--dur-base) var(--ease-out);
}
.hero-cifra:hover::before { transform: scaleY(1); }
/* En móvil la columna va debajo del texto, así que cuatro cifras a tamaño de
   escritorio alargarían la portada hasta hacerla incómoda. Se aprietan. */
@media (max-width: 999px) {
  .hero-cifras { gap: 1.25rem; margin-top: 2.5rem; }
  .hero-cifra__num { font-size: 1.75rem; }
  .hero-cifra__texto { margin-top: 0.3rem; font-size: 0.8125rem; }
}

/* Hero oscuro original, aún disponible para páginas sin esquema */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding-block: 9rem 4rem;
  background: var(--tinta-abismo);
  overflow: hidden;
}
/* Centrado con margin auto y no con translateY: GSAP anima x/yPercent sobre
   este elemento y sobrescribiría cualquier transform declarada aquí. */
.hero__flow {
  position: absolute;
  top: 0; bottom: 0; right: -10%;
  margin-block: auto;
  width: min(70vw, 54rem);
  aspect-ratio: 420 / 150;
  height: auto;
  opacity: 0.07;
  pointer-events: none;
}
.hero__block {
  position: absolute;
  top: 0; left: 0;
  width: clamp(4rem, 11vw, 10rem);
  aspect-ratio: 1;
  background: var(--cobre);
  z-index: 1;
}

/* Titular animado por líneas. Lo aplica también el JS a los h2 de sección. */
.reveal-line { display: block; overflow: hidden; }
.reveal-line > span { display: block; }

/* will-change SOLO mientras el titular está esperando a entrar. Dejarlo
   puesto para siempre mantiene el texto en su propia capa de composición:
   se rasteriza una vez y se recompone, y con el tracking negativo de
   .t-hero / .t-section eso se ve como letras mal encajadas. Se retira en
   cuanto el titular ya se ha leído. */
.js [data-split-lines]:not(.is-revealed) .reveal-line > span,
.js [data-hero]:not(.is-revealed) .reveal-line > span { will-change: transform; }

/* ---------- 09 Tarjetas y bloques ---------------------------------------- */
.trust {
  background: var(--tinta-abismo);
  border-block: 1px solid var(--border);
}
.trust__grid {
  display: grid;
  gap: clamp(1.5rem, 3vw, 3rem);
  grid-template-columns: 1fr;
}
@media (min-width: 780px) { .trust__grid { grid-template-columns: repeat(3, 1fr); } }
.trust__item {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  transition: transform var(--dur-base) var(--ease-soft);
}
.trust__item svg { transition: transform var(--dur-base) var(--ease-soft); }
.trust__item:hover svg { transform: scale(1.08) rotate(-3deg); }

.card {
  position: relative;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  height: 100%;
  overflow: hidden;
  isolation: isolate;
  transition: border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
/* Realce mínimo al pasar el cursor. Tres píxeles: lo justo para que la
   tarjeta responda sin despegarse. Es la única propiedad que se añade al
   hover — encima ya están el brillo y el filo de acento, y una cuarta capa
   de movimiento convertiría la microinteracción en ruido. */
.card:hover { transform: translateY(-3px); }
/* Brillo que sigue al puntero: la microinteracción que más "caro" hace ver
   una tarjeta, siempre que se quede por debajo del umbral de lo evidente. */
.card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(16rem circle at var(--mx, 50%) var(--my, 0%),
                              var(--sheen), transparent 68%);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
  pointer-events: none;
}
.card:hover::before,
.card:focus-within::before { opacity: 1; }
/* Filo de acento que crece en el borde superior */
.card::after {
  content: '';
  position: absolute;
  top: 0; left: 0;
  height: 2px; width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-out);
}
.card:hover::after,
.card:focus-within::after { transform: scaleX(1); }
.card:hover { border-color: var(--alfa-cobre-50); }
.card--link { cursor: pointer; }
.card--link:hover .link-underline svg { transform: translate(3px, -3px); }

/* Bloque de datos dentro de tarjeta */
.card dl dd { margin: 0; }

/* Nota destacada */
.notice {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  padding: clamp(1.25rem, 2.4vw, 1.75rem);
  background: var(--accent-wash);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.notice svg { color: var(--accent); }

/* ---------- 10 Metodología ------------------------------------------------ */
.method__layout {
  display: grid;
  gap: clamp(2rem, 5vw, 5rem);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 1024px) {
  .method__layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .method__stage { position: sticky; top: calc(var(--header-h) + 3rem); }
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: 3.25rem 1fr;
  gap: clamp(1rem, 2vw, 2rem);
  padding-block: clamp(1.5rem, 2.5vw, 2.25rem);
  padding-inline: 0.75rem 0;
  border-top: 1px solid var(--border);
  /* 0.92: mínimo que cumple el contraste WCAG AA (4,5:1) que mide Google. */
  opacity: 0.92;
  cursor: default;
  /* Tiempos largos a propósito. Los pasos se encadenan al hacer scroll, así
     que cada cambio se ve entero: a 420 ms el relevo entre uno y otro se
     percibía como un parpadeo, y es justo eso lo que abarata un bloque que
     por lo demás está bien construido. */
  transition: opacity var(--dur-slow) var(--ease-out),
              border-color var(--dur-slow) var(--ease-out),
              padding-inline-start var(--dur-slow) var(--ease-soft);
}
/* Marca de paso activo: una barra de acento que se despliega desde el centro */
.step::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transition: transform var(--dur-slow) var(--ease-out);
}
.step.is-active {
  opacity: 1;
  padding-inline-start: 1.5rem;
  /* El filo superior del paso activo se tiñe: liga la fila con la barra de
     acento en lugar de dejarla flotando sobre una línea gris. */
  border-top-color: var(--alfa-cobre-40);
}
.step.is-active::before { transform: scaleY(1); }
.step__num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--accent);
  padding-top: 0.3rem;
  transition: transform var(--dur-base) var(--ease-soft);
}
.step.is-active .step__num { transform: translateY(-2px); }
.step__body p { color: var(--text-muted); margin-top: 0.5rem; max-width: 46ch; }
.step.is-active .step__body p { color: var(--text-strong); }

/* Llamada a la acción en línea: ocupa el sitio que antes ocupaba el precio,
   dentro de listas y tarjetas. La variante destacada es para el peldaño sin
   coste, que es el que abre la conversación. */
.cta-inline {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--accent);
  padding-block: 0.2rem;
}
.cta-inline::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-out);
}
.cta-inline:hover::after,
.cta-inline:focus-visible::after { transform: scaleX(0); transform-origin: left; }
.cta-inline svg { transition: transform var(--dur-base) var(--ease-out); }
.cta-inline:hover svg,
.cta-inline:focus-visible svg { transform: translateX(4px); }

.cta-inline--free {
  background: var(--accent-wash);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 0.45rem 0.85rem;
  min-height: 2.5rem;
  transition: background var(--dur-base) var(--ease-out);
}
.cta-inline--free::after { content: none; }
.cta-inline--free:hover,
.cta-inline--free:focus-visible { background: var(--accent); color: var(--surface); }
.on-light .cta-inline--free:hover,
.on-light .cta-inline--free:focus-visible { color: var(--cal); }

/* Panel ilustrado del paso activo */
.stage {
  position: relative;
  aspect-ratio: 4 / 3.4;
  background: var(--surface-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.stage__panel {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(1.5rem, 3vw, 2.5rem);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out),
              visibility var(--dur-slow);
}
.stage__panel.is-active { opacity: 1; visibility: visible; transform: none; }
.stage__figure { flex: 1; display: grid; place-items: center; min-height: 0; }
.stage__figure svg { width: 100%; height: 100%; max-height: 15rem; }

/* Los diagramas se dibujan solos al activarse el paso */
.stage__panel [data-draw-path] {
  stroke-dasharray: var(--len, 400);
  stroke-dashoffset: var(--len, 400);
}
.stage__panel.is-active [data-draw-path] {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1s var(--ease-out) 120ms;
}
.stage__panel [data-draw-fill] {
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.stage__panel.is-active [data-draw-fill] { opacity: 1; transition-delay: 620ms; }

/* ---------- 11 Tablas y datos --------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
thead th {
  text-align: left;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 1.1rem 1.25rem;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
tbody th,
tbody td { padding: 1.15rem 1.25rem; border-bottom: 1px solid var(--border); vertical-align: top; }
tbody th { text-align: left; font-weight: 600; }
tbody tr:last-child > * { border-bottom: 0; }
tbody tr { transition: background var(--dur-fast) var(--ease-out); }
tbody tr:hover { background: var(--accent-wash); }
/* Filo de acento que entra por la izquierda al pasar por encima */
tbody tr > *:first-child { position: relative; }
tbody tr > *:first-child::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--accent);
  transform: scaleY(0);
  transition: transform var(--dur-base) var(--ease-out);
}
tbody tr:hover > *:first-child::before { transform: scaleY(1); }
.cell-price {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 1rem;
  color: var(--accent);
  white-space: nowrap;
}
.cell-price small { font-weight: 400; font-size: 0.8125rem; color: var(--text-muted); }

/* En móvil la tabla deja de ser tabla y pasa a ser una lista de fichas.
   Sigue siendo una <table> para el lector de pantalla y el teclado. */
@media (max-width: 719px) {
  .table-wrap { border: 0; border-radius: 0; overflow: visible; }
  .table-wrap table,
  .table-wrap tbody,
  .table-wrap tr { display: block; width: 100%; }
  .table-wrap thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .table-wrap tbody tr {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.25rem 1.25rem 1.1rem;
    margin-bottom: 0.75rem;
    background: var(--surface-raised);
  }
  .table-wrap tbody tr:hover { background: var(--surface-raised); }
  .table-wrap tbody th,
  .table-wrap tbody td {
    display: block;
    padding: 0;
    border: 0;
  }
  .table-wrap tbody tr > *:first-child::before { display: none; }
  .table-wrap tbody th {
    font-family: 'Space Grotesk', sans-serif;
    font-size: 1.0625rem;
    padding-bottom: 0.35rem;
  }
  .table-wrap td[data-label] { padding-top: 0.75rem; }
  .table-wrap td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.2rem;
  }
  .table-wrap td.cell-price { white-space: normal; }
}

/* ---------- Partes de un entregable de ejemplo ---------------------------
   Cada parte se anuncia con su número y su título a tamaño legible. Antes
   esto lo llevaba un rótulo de 11 px, y con eso no se veía que el bloque
   fueran tres páginas distintas de un mismo documento. */
.parte + .parte {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--border);
}
.parte__cabecera {
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  margin-bottom: clamp(1.5rem, 2.5vw, 2rem);
}
.parte__num {
  flex: none;
  padding: 0.25rem 0.6rem 0.28rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.parte__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.125rem, 1.9vw, 1.4375rem);
  line-height: 1.2;
  letter-spacing: -0.016em;
  margin: 0;
}

/* Nota de encabezado dentro de un bloque de ejemplo: dice qué es lo que se
   está mirando antes de que el lector tenga que deducirlo. */
.parte-intro {
  max-width: 62ch;
  padding-bottom: clamp(1.5rem, 3vw, 2rem);
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
  border-bottom: 1px solid var(--border);
}

/* ---------- Tabla de pasos -----------------------------------------------
   Una escalera no es una tabla de datos: tiene orden y progresión, y eso hay
   que verlo antes de leer nada. Se numera con un contador CSS, se enhebra con
   un hilo vertical y se agrupa por familia, porque mezclar los peldaños de
   automatización con los de cumplimiento en una sola lista era justo lo que
   hacía que no se entendiera. */
.tabla-pasos { counter-reset: paso; }
.tabla-pasos table { border-collapse: separate; border-spacing: 0; }

.tabla-pasos tbody tr { counter-increment: paso; }
.tabla-pasos tbody th,
.tabla-pasos tbody td {
  border-bottom: 1px solid var(--border);
  padding-block: 1.35rem;
  transition: color var(--dur-base) var(--ease-out);
}

/* Rótulo de familia: parte la lista en dos mitades legibles */
.tabla-pasos tbody tr.fila-grupo { counter-increment: none; }
.tabla-pasos tbody tr.fila-grupo:hover { background: none; }
.tabla-pasos tbody tr.fila-grupo th {
  padding: 2rem 1.25rem 0.9rem;
  border-bottom: 1px solid var(--border);
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.tabla-pasos tbody tr.fila-grupo:first-child th { padding-top: 1.25rem; }
.tabla-pasos tbody tr.fila-grupo > *:first-child::before { display: none; }

/* Número del peldaño, en su propio disco */
.tabla-pasos tbody tr:not(.fila-grupo) th[scope='row'] {
  position: relative;
  padding-left: 4.5rem;
  padding-right: 1.5rem;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  min-width: 15rem;
}
.tabla-pasos tbody tr:not(.fila-grupo) th[scope='row']::after {
  content: counter(paso, decimal-leading-zero);
  position: absolute;
  left: 1.25rem;
  top: 1.15rem;
  width: 2.1rem;
  height: 2.1rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  z-index: 1;
  transition: color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-soft);
}
/* Hilo que enhebra un peldaño con el siguiente */
.tabla-pasos tbody tr:not(.fila-grupo) th[scope='row']::before {
  content: '';
  position: absolute;
  left: calc(1.25rem + 1.05rem);
  top: 1.15rem;
  bottom: -1.35rem;
  width: 1px;
  background: var(--border);
  transform: scaleY(var(--hilo, 1));
  transform-origin: top;
  transition: background var(--dur-base) var(--ease-out);
}
.tabla-pasos tbody tr:last-child th[scope='row']::before { display: none; }

.tabla-pasos tbody tr:not(.fila-grupo):hover th[scope='row']::after {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--accent-wash);
  transform: translateY(-2px);
}
.tabla-pasos tbody tr:not(.fila-grupo):hover th[scope='row']::before { background: var(--accent); }

/* La celda del medio lleva el peso de la lectura; la tercera es apoyo */
.tabla-pasos .celda-incluye { color: var(--text-strong); }
.tabla-pasos .celda-coste { color: var(--text-muted); font-size: 0.875rem; }

/* ---------- Formulario de contacto ----------------------------------------
   Vive dentro de .closer, que invierte los roles de color: fondo Cobre y
   texto Tinta. Por eso los campos no llevan color propio, heredan los tokens
   de esa sección y funcionarían igual si un día el cierre cambia de fondo. */
.contacto { display: grid; gap: 1rem; }

.contacto__fila {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  .contacto__fila { grid-template-columns: 1fr 1fr; }
}

.campo { display: block; }
.campo__et {
  display: block;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-strong);
  margin-bottom: 0.4rem;
}
.campo__opt { font-weight: 400; color: var(--text-muted); }

.campo__in {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text-strong);
  background: rgba(247, 249, 248, 0.55);
  border: 1px solid var(--alfa-tinta-30);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.campo__in--area { resize: vertical; min-height: 5.5rem; line-height: 1.5; }

.campo__in::placeholder { color: var(--text-muted); }
.campo__in:hover { background: rgba(247, 249, 248, 0.75); }
.campo__in:focus {
  outline: none;
  background: var(--cal);
  border-color: var(--text-strong);
}
.campo__in:focus-visible { outline: 2px solid var(--text-strong); outline-offset: 2px; }

/* Campo marcado como incorrecto por el JS, no por :invalid — así no se pinta
   en rojo todo el formulario antes de que el visitante escriba nada. */
.campo__in.is-mal {
  border-color: #7A1F12;
  background: rgba(247, 249, 248, 0.9);
}

.contacto__enviar { justify-content: center; margin-top: 0.25rem; }
.contacto__enviar[disabled] { opacity: 0.62; pointer-events: none; }

.contacto__estado {
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-muted);
  min-height: 1.4rem;
}
.contacto__estado.is-ok { color: var(--text-strong); font-weight: 600; }
.contacto__estado.is-mal { color: #5E1A10; font-weight: 600; }

.contacto__wa { margin-top: 0.75rem; justify-content: center; }

/* Consentimiento: casilla obligatoria antes de enviar (RGPD) */
.campo-check {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  font-size: 0.875rem;
  line-height: 1.5;
  cursor: pointer;
}
.campo-check input {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.15rem;
  accent-color: var(--tinta);
}
.campo-check a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.campo-check.is-mal { color: #5E1A10; font-weight: 600; }

/* Oferta y lista del cierre: el cierre con formulario está en todas las
   páginas (el latido del punto solo se anima en la portada, home.css). */
.oferta { display: inline-flex; align-items: center; gap: 0.6rem; margin-top: 1.5rem; font-weight: 700; font-size: 0.95rem; background: var(--tinta); color: var(--cal); padding: 0.55rem 0.9rem; }
.oferta::before { content: ''; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--cobre); box-shadow: 0 0 0 4px rgba(237, 135, 88, 0.25); }
.cierre__lista { margin-top: 1.5rem; list-style: none; padding: 0; display: grid; gap: 0.55rem; }
.cierre__lista li { display: flex; gap: 0.6rem; align-items: baseline; font-weight: 500; }
.cierre__lista li::before { content: '✓'; font-weight: 700; }

/* Desplegable: contenido de consulta (la pila técnica) que no debe
   alargar la página para quien no lo busca. */
.desplegable { margin-top: 3.5rem; border-block: 1px solid var(--border); }
.desplegable > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.4rem;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text-strong);
}
.desplegable > summary::-webkit-details-marker { display: none; }
.desplegable > summary::after {
  content: '+';
  flex: none;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--accent);
  transition: transform var(--dur-base) var(--ease-out);
}
.desplegable[open] > summary::after { transform: rotate(45deg); }
.desplegable > summary:focus-visible { outline: 2px solid var(--text-strong); outline-offset: 4px; }
.desplegable__cuerpo { padding-bottom: 2rem; }

/* Socios: nombre, rol, dos líneas de trayectoria y contacto directo */
.socios { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 900px) { .socios { grid-template-columns: repeat(2, 1fr); } }
.socio__nombre { font-family: 'Space Grotesk', sans-serif; font-size: 1.5rem; font-weight: 600; line-height: 1.2; color: var(--text-strong); margin: 0; }
.socio__rol { margin-top: 0.35rem; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); }
.socio__texto { margin-top: 1rem; color: var(--text-muted); line-height: 1.6; max-width: 46ch; }
.socio__enlaces { margin-top: 1.25rem; display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem; }

/* Ruta: la trayectoria en hitos con icono, una línea cada uno (Quiénes somos).
   En escritorio va en fila con una línea que los une; en móvil, en columna. */
.ruta { list-style: none; margin-inline: 0; margin-bottom: 0; padding: 0; position: relative; display: grid; gap: 1.75rem; grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .ruta { grid-template-columns: repeat(5, 1fr); gap: 1.5rem; }
  .ruta::before { content: ''; position: absolute; left: 1.4rem; right: 1.4rem; top: 1.4rem; height: 1px; background: var(--border); }
}
.ruta__hito { position: relative; display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: start; }
@media (min-width: 900px) { .ruta__hito { grid-template-columns: 1fr; } }
.ruta__ico {
  position: relative;
  z-index: 1;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--accent);
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.ruta__hito:hover .ruta__ico { border-color: var(--accent); transform: translateY(-2px); }
.ruta__hito--fin .ruta__ico { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.ruta__tag { font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.ruta__tit { margin: 0.35rem 0 0; font-family: 'Space Grotesk', sans-serif; font-size: 1.125rem; font-weight: 600; line-height: 1.25; color: var(--text-strong); }
.ruta__txt { margin-top: 0.35rem; font-size: 0.875rem; line-height: 1.55; color: var(--text-muted); }

/* Sellos: cuatro ideas cortas con icono, sin párrafo */
.sellos { display: grid; gap: 0.75rem; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 900px) { .sellos { grid-template-columns: repeat(4, 1fr); } }
.sello {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border);
  background: var(--surface-raised);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-strong);
}
.sello svg { flex: none; color: var(--accent); }

/* ---------- Camino de cuatro pasos ----------------------------------------
   Sustituye al cuadro de pasos de Presupuesto, que le contaba el método
   entero a cualquier competidor. Aquí queda solo el recorrido.

   Tratamiento editorial, no de plantilla: nada de iconos dentro de círculos
   ni de colores fijos. Cifra grande y ligera, un filo fino encima de cada
   paso y el texto justo. El cobre nunca está quieto: solo aparece al pasar
   el cursor, cuando el filo se llena de izquierda a derecha y la cifra se
   enciende. En reposo, los cuatro pasos pesan lo mismo. */
.camino {
  --hueco: clamp(1.5rem, 3vw, 2.75rem);
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2.75rem var(--hueco);
  grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .camino { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .camino { grid-template-columns: repeat(4, 1fr); } }

.camino__paso {
  position: relative;
  padding-top: 1.75rem;
  cursor: default;
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 110ms);
}

/* Filo neutro: se dibuja al entrar, un paso detrás de otro */
.camino__paso::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--border);
  transform-origin: left center;
  transition: transform var(--dur-rotulo) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 160ms + 150ms);
}

/* Filo de acento: por encima de la línea neutra, solo al pasar el cursor */
.camino__paso::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  z-index: 1;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-slow) var(--ease-out);
}
.camino__paso:hover::before { transform: scaleX(1); }

.camino__cabeza {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.camino__num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(2.5rem, 2rem + 1.4vw, 3.5rem);
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  opacity: 0.5;
  transition: color var(--dur-slow) var(--ease-out),
              opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.camino__paso:hover .camino__num {
  color: var(--accent);
  opacity: 1;
  transform: translateY(-3px);
}

/* "Sin coste" es un dato, no un reclamo: sin color de acento ni cápsula */
.camino__nota {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-muted);
}

.camino__titulo {
  margin: 1.5rem 0 0;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.3125rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--text-strong);
}

.camino__texto {
  margin-top: 0.55rem;
  max-width: 26ch;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--text-muted);
}

/* Entrada: solo se esconde si hay JS para volver a mostrarlo */
.js .camino:not(.is-in) .camino__paso { opacity: 0; transform: translateY(14px); }
.js .camino:not(.is-in) .camino__paso::after { transform: scaleX(0); }

.camino-pie {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--border);
}

/* Variante de tres columnas del camino. La usa Cumplimiento para los motivos
   de la regulación: mismo lenguaje editorial que los pasos de Presupuesto,
   pero con tres piezas en fila en vez de cuatro y algo más de ancho de texto. */
@media (min-width: 1080px) {
  .camino--tres { grid-template-columns: repeat(3, 1fr); }
}
.camino--tres .camino__texto { max-width: 34ch; }

/* ---------- ¿Os afecta? (Cumplimiento) -----------------------------------
   Cuatro usos de IA con icono y estado. El estado es lo primero que se lee,
   así que va en cápsula arriba: "en vigor" con filo de acento, "prohibido"
   relleno, y lo que está por llegar en neutro. */
.riesgos { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 700px)  { .riesgos { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .riesgos { grid-template-columns: repeat(4, 1fr); } }
.riesgo { display: flex; flex-direction: column; gap: 1rem; }
.riesgo__icono {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent);
}
.riesgo__estado {
  align-self: flex-start;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.riesgo__estado--vigor { border-color: var(--accent); color: var(--accent); }
.riesgo__estado--prohibido { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.riesgo__titulo {
  margin: 0;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.1875rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text-strong);
}
.riesgo__texto { margin: 0; font-size: 0.9375rem; line-height: 1.6; color: var(--text-muted); }

/* ---------- Tres pasos para pedirlo --------------------------------------
   Versión mínima del cuadro de pasos: número, título y una línea. Sin tabla
   y sin tarjeta, porque aquí el contenido es una secuencia corta y cualquier
   caja alrededor le daría más peso del que merece al lado del botón. */
.pide {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0;
}
.pide__paso {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 1rem;
  align-items: start;
  padding-block: 1.35rem;
  border-bottom: 1px solid var(--border);
}
.pide__paso:first-child { border-top: 1px solid var(--border); }
.pide__num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--accent);
  padding-top: 0.15rem;
}
.pide__titulo {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.012em;
  color: var(--text-strong);
}

/* ---------- Ficha de datos -----------------------------------------------
   Cuatro datos sueltos que antes eran tarjetas con párrafo. Como ficha se
   leen de un vistazo y ocupan la mitad: la etiqueta pequeña arriba y el dato
   con peso debajo, separados por un filo, sin caja alrededor. */
.ficha {
  margin: 0;
  display: grid;
  gap: 1px;
  background: var(--border);
  border-block: 1px solid var(--border);
  grid-template-columns: 1fr;
}
@media (min-width: 700px) { .ficha { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .ficha { grid-template-columns: repeat(4, 1fr); } }

.ficha__dato {
  background: var(--surface);
  padding: 1.35rem 1.5rem 1.5rem;
  transition: background var(--dur-base) var(--ease-out);
}
.ficha__dato:hover { background: var(--accent-wash); }

.ficha__dato dt {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.ficha__dato dd {
  margin: 0.6rem 0 0;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.012em;
  color: var(--text-strong);
  text-wrap: balance;
}

/* ---------- Línea de tiempo del reglamento -------------------------------
   Sustituye a la tabla de cuatro filas del calendario. Una tabla las trataba
   como iguales, y no lo son: dos fechas ya han vencido y dos no. Aquí el hilo
   vertical se corta donde termina lo que ya está en vigor, así que el lector
   ve en qué punto está antes de leer una sola palabra. Sin rayado de filas,
   sin cabecera: solo el hilo, las marcas y el texto. */
.linea-tiempo {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2.25rem, 4vw, 3.5rem);
}

.hito {
  position: relative;
  padding-left: clamp(2.5rem, 4vw, 3.5rem);
  max-width: 58ch;
}
/* El hilo baja hasta el hito siguiente; el último no lo dibuja */
.hito::before {
  content: '';
  position: absolute;
  left: 7px;
  top: 1.6rem;
  bottom: calc(-1 * clamp(2.25rem, 4vw, 3.5rem) - 0.4rem);
  width: 1px;
  background: var(--border);
}
.hito:last-child::before { display: none; }

/* La marca: anillo hueco por defecto, disco lleno cuando ya está en vigor */
.hito::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55rem;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1.5px solid var(--border);
  background: var(--surface);
}
.hito--vigor::after {
  border-color: var(--accent);
  background: var(--accent);
}
/* El hilo que sale de una fecha vencida va en cobre: se ve de un vistazo
   hasta dónde llega lo que ya es obligatorio. */
.hito--vigor::before { background: var(--alfa-cobre-40); }

/* Halo del hito que importa hoy */
.hito--ahora::after { box-shadow: 0 0 0 6px var(--accent-wash); }

.hito__estado {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.hito--vigor .hito__estado { color: var(--accent); }

.hito__fecha {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(1.5rem, 1.25rem + 0.75vw, 2.125rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin-top: 0.5rem;
  color: var(--text-muted);
}
.hito--vigor .hito__fecha { color: var(--text-strong); }

.hito__que { margin-top: 0.85rem; color: var(--text-strong); }
.hito:not(.hito--vigor) .hito__que { color: var(--text-muted); }

.hito__vos {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  color: var(--text-muted);
}

/* Cierre de un cuadro de pasos: una sola acción, bien separada de la tabla.
   Va sobre el lavado de acento para que se lea como el final del bloque y no
   como otra fila más. La letra pequeña vive fuera de este panel, debajo. */
.cuadro-cierre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.5rem, 3vw, 3rem);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  background: var(--accent-wash);
  border: 1px solid var(--alfa-cobre-20);
  border-radius: var(--radius);
}
.cuadro-cierre .btn { flex: none; }
@media (max-width: 560px) {
  .cuadro-cierre .btn { width: 100%; justify-content: center; }
}

/* Distintivo de lo que no se factura */
.badge-gratis {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.55rem;
  padding: 0.2rem 0.6rem 0.22rem;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--accent-wash);
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.badge-gratis::before {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
}

@media (max-width: 719px) {
  .tabla-pasos tbody tr.fila-grupo { display: block; }
  .tabla-pasos tbody tr.fila-grupo th { padding: 1.5rem 0 0.6rem; border-bottom: 0; }
  .tabla-pasos tbody tr:not(.fila-grupo) th[scope='row'] {
    padding-left: 3.4rem;
    min-width: 0;
  }
  .tabla-pasos tbody tr:not(.fila-grupo) th[scope='row']::after {
    left: 0; top: 0.1rem;
    width: 1.9rem; height: 1.9rem;
  }
  .tabla-pasos tbody tr:not(.fila-grupo) th[scope='row']::before { display: none; }
}

/* Comparación visual de horas: sustituye a tres cifras sueltas por una
   lectura inmediata, y funciona igual de bien en móvil que en escritorio. */
.bar-compare { display: grid; gap: clamp(1.25rem, 2.5vw, 1.75rem); }
.bar-row { display: grid; gap: 0.5rem; }
.bar-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.bar-row__label { font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--text-muted); }
.bar-row__value {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.bar-row__track {
  position: relative;
  height: 0.625rem;
  background: var(--border);
  border-radius: 1px;
  overflow: hidden;
}
.bar-row__fill {
  position: absolute;
  inset: 0;
  transform-origin: left;
  transform: scaleX(var(--fill, 1));
  background: var(--text-muted);
  border-radius: 1px;
}
.bar-row--after .bar-row__value { color: var(--accent); }
.bar-row--after .bar-row__fill { background: var(--accent); }
.js .bar-row__fill { transform: scaleX(0); }
.js .bar-compare.is-in .bar-row__fill {
  transform: scaleX(var(--fill, 1));
  transition: transform 1.1s var(--ease-out);
}
.js .bar-compare.is-in .bar-row--after .bar-row__fill { transition-delay: 220ms; }

/* La cifra NO se cuenta desde cero. Antes se animaba de 0 a 96 y durante un
   segundo y medio la página mostraba números que no son ciertos, justo en la
   sección cuyo argumento es que las horas están medidas. Ahora sale la cifra
   final desde el primer fotograma y lo que se anima es su entrada, al ritmo
   de la barra que tiene al lado. */
.js .bar-row__value {
  opacity: 0;
  transform: translateY(10px);
}
.js .bar-compare.is-in .bar-row__value {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}
.js .bar-compare.is-in .bar-row--after .bar-row__value { transition-delay: 220ms; }

/* Comparación hoy / después */
.compare {
  display: grid;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 860px) { .compare { grid-template-columns: 1fr 1fr; } }
.compare__col { background: var(--surface); padding: clamp(1.75rem, 3vw, 2.5rem); }
.compare__col--after { background: var(--surface-raised); }
.flow-item {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: 0.9rem;
  padding-block: 0.7rem;
  align-items: start;
  transition: transform var(--dur-base) var(--ease-soft);
}
.flow-item:hover { transform: translateX(3px); }
.flow-item + .flow-item { border-top: 1px dashed var(--border); }
.flow-item__mark { color: var(--text-muted); padding-top: 0.15rem; font-variant-numeric: tabular-nums; }
.flow-item--human .flow-item__mark { color: var(--accent); }
.flow-item--human { background: var(--accent-wash); margin-inline: -0.75rem; padding-inline: 0.75rem; }

/* Lista numerada de entregables */
.deliver {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 1.5rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--border);
  transition: padding-inline-start var(--dur-base) var(--ease-soft);
}
.deliver:last-child { border-bottom: 1px solid var(--border); }
.deliver:hover { padding-inline-start: 0.75rem; }
.deliver__num {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* ---------- 12 FAQ -------------------------------------------------------- */
.faq__item {
  border-top: 1px solid var(--border);
  transition: padding-inline-start var(--dur-base) var(--ease-soft);
}
.faq__item:last-child { border-bottom: 1px solid var(--border); }
.faq__item:hover { padding-inline-start: 0.5rem; }
.faq__item.is-open { padding-inline-start: 0.5rem; }
.faq__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 4.5rem;
  padding: 1.4rem 0;
  background: none;
  border: 0;
  color: inherit;
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -0.014em;
  text-align: left;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.faq__trigger:hover,
.faq__trigger[aria-expanded='true'] { color: var(--accent); }
.faq__icon {
  position: relative;
  flex: none;
  width: 1.75rem; height: 1.75rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.faq__icon::before,
.faq__icon::after {
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 0.6875rem; height: 1.5px;
  margin: -0.75px 0 0 -0.34375rem;
  background: var(--accent);
  transition: transform var(--dur-base) var(--ease-out);
}
.faq__icon::after { transform: rotate(90deg); }
.faq__trigger:hover .faq__icon { border-color: var(--accent); }
.faq__trigger[aria-expanded='true'] .faq__icon {
  background: var(--accent-wash);
  border-color: var(--accent);
  transform: rotate(180deg);
}
.faq__trigger[aria-expanded='true'] .faq__icon::after { transform: rotate(0deg); }
.faq__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-base) var(--ease-out);
}
.faq__panel.is-open { grid-template-rows: 1fr; }
.faq__panel > div { overflow: hidden; }
.faq__panel p {
  padding-bottom: 1.6rem;
  color: var(--text-muted);
  max-width: var(--measure);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.faq__panel.is-open p { opacity: 1; transform: none; transition-delay: 120ms; }

/* ---------- 13 Portada del informe, cierre y pie -------------------------- */
/* Portada real del entregable descargable, no un marcador de posición. */
.report {
  perspective: 1400px;
  perspective-origin: 50% 40%;
}
.report__cover {
  position: relative;
  aspect-ratio: 1 / 1.414;               /* proporción A4 */
  background: var(--tinta);
  border: 1px solid var(--border);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  transform-style: preserve-3d;
  transition: transform var(--dur-slow) var(--ease-out),
              border-color var(--dur-slow) var(--ease-out);
}
.report:hover .report__cover {
  transform: rotateY(-6deg) rotateX(2deg) translateZ(12px);
  border-color: var(--alfa-cobre-50);
}
/* Lomo: el detalle que convierte un rectángulo en un objeto */
.report__cover::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 0.5rem;
  background: linear-gradient(90deg, var(--alfa-niebla-08), transparent);
  border-right: 1px solid var(--border);
}
.report__band {
  position: absolute;
  top: 0; right: clamp(1.5rem, 3vw, 2.5rem);
  width: clamp(1.75rem, 3.5vw, 2.75rem);
  height: clamp(4rem, 9vw, 7rem);
  background: var(--cobre);
}
.report__title {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(1.25rem, 2.4vw, 1.875rem);
  line-height: 1.12;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
.report__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--mineral-claro);
}

.site-footer { background: var(--tinta-abismo); border-top: 1px solid var(--border); }
.footer-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--mineral-claro);
  font-size: 0.9375rem;
  padding-block: 0.15rem;
  transition: color var(--dur-fast) var(--ease-out),
              gap var(--dur-base) var(--ease-soft);
}
.footer-link::after {
  content: '';
  width: 0.5rem; height: 0.5rem;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  rotate: 45deg;
  opacity: 0;
  translate: -6px 0;
  transition: opacity var(--dur-base) var(--ease-out),
              translate var(--dur-base) var(--ease-soft);
}
.footer-link:hover,
.footer-link:focus-visible { color: var(--niebla); gap: 0.6rem; }
.footer-link:hover::after,
.footer-link:focus-visible::after { opacity: 0.8; translate: 0 0; }
/* No es un enlace: es la estructura del sitio anunciada con honestidad.
   Sin flecha, sin cambio de color y sin foco, porque no lleva a ninguna parte. */
.footer-link--soon { cursor: default; opacity: 0.8; }
.footer-link--soon:hover { color: var(--mineral-claro); gap: 0.4rem; }
.footer-link--soon::after { content: none; }

/* Marcador de contenido pendiente de datos reales */
.placeholder {
  position: relative;
  border: 1px dashed var(--alfa-cobre-50);
  background: repeating-linear-gradient(
    135deg,
    transparent, transparent 9px,
    var(--alfa-cobre-10) 9px, var(--alfa-cobre-10) 18px
  );
}
.placeholder__tag {
  position: absolute;
  top: 0; right: 0;
  font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  background: var(--cobre);
  color: var(--tinta);
  padding: 0.25rem 0.6rem;
}

/* ---------- 14 Utilidades ------------------------------------------------- */
/* Clases propias en lugar de las utilidades de Tailwind: styles.css se carga
   después y .btn{display:inline-flex} ganaría a .hidden. */
.at-desktop { display: none !important; }
.at-mobile { display: inline-flex !important; }
@media (min-width: 1240px) {   /* debe coincidir con el punto de .nav */
  .at-desktop { display: inline-flex !important; }
  .at-mobile { display: none !important; }
}

/* Estados de entrada. Solo se ocultan si hay JS para volver a mostrarlos. */
/* Sin will-change en espera: con decenas de elementos aún por entrar, cada
   fotograma de la animación de la portada obligaba a recomponer todas esas
   capas (Lighthouse: 12 s de bloqueo en móvil). GSAP ya promueve la capa
   mientras dura cada animación. */
.js [data-anim='fade-up'] { opacity: 0; transform: translateY(22px); }
.js [data-anim='fade'] { opacity: 0; }
.js [data-hero-item] { opacity: 0; transform: translateY(16px); }
.js .reveal-line > span { transform: translateY(105%); }

/* Un titular que aún no se ha repartido en líneas no debe llegar a pintarse
   sin repartir: se vería saltar. El JS añade .is-split en cuanto lo mide, y
   lo añade igualmente si algo falla. */
.js [data-split-lines]:not(.is-split) { opacity: 0; }

/* ---------- 14b Diagrama hoy / después ------------------------------------
   Esquema de los dos recorridos de un pedido. Hereda los tokens del tema, así
   que funciona igual sobre fondo oscuro y sobre .on-light. En móvil no se
   encoge hasta ser ilegible: se desplaza en horizontal, como las tablas. */
.flujo-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.flujo {
  display: block;
  width: 100%;
  min-width: 680px;
  height: auto;
}

.flujo__head {
  font-family: 'Space Grotesk', 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.16em;
  fill: var(--text-muted);
}
.flujo__head--after { fill: var(--accent); }

.flujo__sub {
  font-family: 'Space Grotesk', 'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;
  font-size: 17px;
  font-weight: 600;
  fill: var(--text-strong);
}

.flujo__div { stroke: var(--border); stroke-width: 1; }

.flujo__box {
  fill: none;
  stroke: var(--border);
  stroke-width: 1;
}

/* El paso que hoy duele: el error que se ve tarde */
.flujo__box--mal { stroke: var(--alfa-cobre-40); }

/* El único nodo donde sigue interviniendo una persona */
.flujo__box--persona {
  fill: var(--accent-wash);
  stroke: var(--accent);
  stroke-width: 1.4;
}

.flujo__num {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  fill: var(--text-muted);
  opacity: 0.7;
}

.flujo__txt { font-size: 14.5px; fill: var(--text-muted); }
.flujo__txt--persona { fill: var(--text-strong); }

.flujo__icono { color: var(--accent); }

.flujo__link line { stroke: var(--text-muted); stroke-width: 1.2; opacity: 0.45; }
.flujo__link path { fill: var(--text-muted); opacity: 0.45; }

.flujo__leyenda rect { fill: var(--accent-wash); stroke: var(--accent); stroke-width: 1.2; }
.flujo__leyenda text { font-size: 13px; fill: var(--text-muted); }

/* ---------- 15 Movimiento reducido ---------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
  .js [data-anim],
  .js [data-hero-item] { opacity: 1 !important; transform: none !important; }
  .js .reveal-line > span { transform: none !important; }
  .step { opacity: 1; }
  .js .eyebrow::before { transform: scaleX(1) !important; }
  .js .camino .camino__paso { opacity: 1 !important; transform: none !important; }
  .js .camino .camino__paso::after { transform: none !important; }
  .camino__paso:hover .camino__num { transform: none; }
  .js .eyebrow { opacity: 1 !important; }
  .eyebrow__c {
    opacity: 1 !important;
    transform: none !important;
    transition-delay: 0ms !important;
  }
  .js .bar-row__fill { transform: scaleX(var(--fill, 1)) !important; }
  .js .bar-row__value { opacity: 1 !important; transform: none !important; }
  .stage__panel [data-draw-path] { stroke-dashoffset: 0 !important; }
  .stage__panel [data-draw-fill] { opacity: 1 !important; }
  .report:hover .report__cover { transform: none; }
  .btn { translate: 0 0 !important; }
  /* Maquetaciones nuevas: el acento se ve entero y las filas no se desplazan.
     El filo de la fila sigue apareciendo al pasar por encima, pero de golpe. */
  .js .destacado__panel::before { transform: scaleX(1) !important; }
  .fila:hover { padding-inline-start: 0; }
  /* El desplegable aparece de una pieza: sin escalonado ni desplazamiento.
     El filo de cobre se dibuja entero desde el principio. */
  .nav__menu-link,
  .nav__menu-aside { opacity: 1 !important; translate: 0 0 !important; }
  .nav__menu::after { transform: scaleX(1) !important; }
  .nav__menu-flecha { opacity: 1; transform: none; }
  .card:hover { transform: none !important; }
  .faq__panel p { opacity: 1 !important; transform: none !important; }
}

/* Ejemplo de diagnóstico: hoja limpia en lugar de la caja rayada */
.ejemplo {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.75rem);
  background: var(--surface-raised, #fff);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(20, 45, 59, .05), 0 18px 40px -24px rgba(20, 45, 59, .35);
}
.ejemplo__tag {
  display: inline-block;
  margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem);
  padding: 0.3rem 0.75rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-wash);
  border-radius: 999px;
}
/* Servicios: etiqueta (Obligatoria, De pago…) dentro de una tarjeta */
.servicio__chip { align-self: flex-start; margin-top: 1rem; }
/* Preguntas frecuentes: portada y temas */
.faq-portada { padding-block: clamp(7.5rem, 13vw, 10rem) clamp(2.5rem, 5vw, 3.5rem); }
.faq-temas { margin-top: 2rem; display: flex; flex-wrap: wrap; gap: 0.6rem 1.5rem; font-weight: 600; }
