/* ==========================================================================
   CANTEC — Sistema de diseño
   Paleta de marca tomada del logotipo: ámbar #F2B02F y gris #939497.
   Recurso gráfico propio: "el arco" — la curva del isotipo, usada como
   máscara de imagen, subrayado y transición entre secciones.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   TEMA
   El sitio tiene dos temas sobre los mismos componentes. El claro es el
   predeterminado (la portada); el oscuro se activa con class="tema-oscuro" en
   el <body> y es el que usan por ahora las páginas interiores.
   Los nombres --ink / --on-dark / --paper se conservan como alias porque los
   usan más de cincuenta reglas: cambian de valor según el tema.
   -------------------------------------------------------------------------- */
:root {
  /* Marca */
  --amber:        #F2B02F;
  --amber-soft:   #F7C55F;
  --amber-deep:   #F7C55F;   /* ámbar para leer SOBRE oscuro */
  --brand-grey:   #939497;

  /* --- Base oscura ---
     El lienzo es casi negro para que la malla ámbar del fondo se lea. Los
     bloques (paneles, tarjetas, pie) siguen siendo oscuros y NO se invierten:
     la profundidad ya no la da el contraste claro/oscuro sino que la malla se
     vea en el lienzo y quede tapada bajo los bloques. */
  --fondo:        #08070A;   /* lienzo de la página */
  --fondo-2:      #101015;   /* tarjeta */
  --fondo-3:      #17171D;
  --fondo-4:      #212128;

  --texto:        #FFFFFF;
  --texto-suave:  #A9A9B2;

  --linea:        rgba(255, 255, 255, .10);
  --linea-fuerte: rgba(255, 255, 255, .22);

  /* Bloques: superficies planas sobre el lienzo, no inversiones de color */
  /* El lienzo de la página, sin remapear NUNCA. Lo necesitan las secciones
     claras para dibujar su transición: dentro de `.claro`, `--fondo` ya vale
     blanco, así que hace falta un token que siga sabiendo cuál es el oscuro. */
  --lienzo:       #08070A;
  --contra:       #0C0C11;
  --contra-2:     #15151B;
  --texto-contra: #FFFFFF;
  --texto-contra-suave: #A9A9B2;

  /* Velos sobre imagen */
  --velo:         8, 7, 10;
  /* Fondo de la cabecera cuando flota sobre el contenido */
  --velo-nav:     8, 7, 10;

  /* Contenido encima de fotografía: siempre claro, no depende del tema,
     porque debajo siempre hay imagen con velo oscuro. */
  --sobre-img:       #FFFFFF;
  --sobre-img-suave: rgba(255, 255, 255, .78);

  /* Número en fantasma detrás de las tarjetas */
  --fantasma:     rgba(255, 255, 255, .06);
  /* Líneas dentro de un bloque de contraste */
  --linea-contra: rgba(255, 255, 255, .12);

  /* Tipografía */
  --font-display: "Space Grotesk", "Segoe UI", system-ui, sans-serif;
  --font-body:    "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;

  /* Escala fluida */
  --t-hero:  clamp(2.75rem, 1.2rem + 6.6vw, 7rem);
  --t-h1:    clamp(2.25rem, 1.2rem + 4.4vw, 4.75rem);
  --t-h2:    clamp(2.1rem, 1.2rem + 3.4vw, 4.25rem);
  --t-h3:    clamp(1.45rem, 1.05rem + 1.6vw, 2.4rem);
  --t-h4:    clamp(1.1rem, 1rem + .55vw, 1.45rem);
  --t-lead:  clamp(1.05rem, .98rem + .5vw, 1.35rem);
  --t-body:  clamp(.98rem, .95rem + .18vw, 1.075rem);
  --t-small: .875rem;
  --t-micro: .75rem;

  /* Ritmo */
  --gap:        clamp(1rem, .6rem + 1.6vw, 2rem);
  /* El margen lateral. Subió de 4rem a 6rem de tope porque, con la columna en
     1440, en una ventana de 1440 el wrap ocupa todo el ancho y este relleno es
     el ÚNICO margen que queda: con el valor anterior el contenido pegaba casi
     con el borde. */
  --pad-x:      clamp(1.25rem, .5rem + 4.5vw, 6rem);
  --section-y:  clamp(4.5rem, 2rem + 9vw, 9.5rem);
  /* La columna del sitio. Subió de 1320 a 1440 para que las cuatro fichas de
     Soluciones quepan enteras sin scroll; al ser el token que usa `.wrap`, se
     ensancha TODA la página a la vez y no solo esa sección. */
  --maxw:       1440px;
  --maxw-text:  68ch;

  /* Forma: el arco */
  --arc:     14rem 14rem 14rem 1.25rem;
  --arc-sm:  7rem 7rem 7rem .75rem;
  --radius:  .875rem;
  --radius-s:.5rem;

  --ring: 0 0 0 3px rgba(242, 176, 47, .45);
  --ease: cubic-bezier(.22, 1, .36, 1);
}

/* --- `.tema-oscuro` ya no invierte nada: el sitio entero es oscuro de base.
       Se deja como marca sin efecto porque las seis páginas interiores la
       llevan puesta; quitarla de cada archivo no aportaría nada. --- */
.tema-oscuro { color-scheme: dark; }

/* --------------------------------------------------------------------------
   La malla del fondo
   Lienzo fijo detrás de TODO el documento: acompaña al visitante mientras
   recorre la página. Va con z-index negativo, así que cualquier contenido en
   flujo se pinta encima sin necesidad de darle z-index a nada. Los bloques
   opacos —paneles, tarjetas, pie— la tapan, y ahí es donde la página respira.
   -------------------------------------------------------------------------- */
.malla {
  position: fixed;
  inset: 0;
  z-index: -1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   2. Reset y base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -.025em;
  margin: 0 0 .5em;
  text-wrap: balance;
}

/* La escala de la sección 1 tiene que aplicarse de verdad: sin esto los
   encabezados caen al tamaño por defecto del navegador (1.5em sobre el cuerpo,
   unos 26px) y toda la jerarquía se aplana. */
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); }

p { margin: 0 0 1.15em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

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

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

ul, ol { margin: 0; padding: 0; list-style: none; }

button, input, textarea, select { font: inherit; color: inherit; }

:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-s);
}

::selection { background: var(--amber); color: var(--fondo); }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--amber);
  color: var(--fondo);
  padding: .75rem 1.25rem;
  font-weight: 600;
  border-radius: 0 0 var(--radius-s) 0;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   3. Layout
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

.section { padding-block: var(--section-y); position: relative; }
/* Apretado a propósito: el Home tiene que recorrerse en cinco pantallas. */
.section--tight { padding-block: clamp(2.5rem, 1rem + 3.6vw, 4.25rem); }

/* Estas dos variantes NO pintan fondo. Lo hacían cuando el sitio era claro y
   una sección oscura tenía que destacarse del blanco; sobre la base oscura de
   ahora el rectángulo solo conseguía dos cosas malas: un escalón de tono en el
   borde y, sobre todo, **tapar la malla del fondo**, que va en un lienzo fijo
   por detrás. La malla se cortaba en seco al llegar a la sección y volvía a
   aparecer al salir. Los colores de texto se quedan porque no estorban:
   `--texto-contra` vale ya lo mismo que `--texto`. */
.section--light { color: var(--texto-contra); }
.section--light h1, .section--light h2, .section--light h3, .section--light h4 { color: var(--texto-contra); }

.section--paper { color: var(--texto-contra); }

/* --------------------------------------------------------------------------
   Secciones claras
   --------------------------------------------------------------------------
   No pinta un fondo y ya: REASIGNA LOS TOKENS. Todo el sitio está escrito
   contra `--fondo`, `--texto`, `--linea`…, así que al cambiarlos aquí cada
   componente de dentro se adapta solo —la ficha del semillero, sus filetes, el
   texto de apoyo— sin una sola regla por componente. Es lo mismo que hace
   `.contraste`, pero en el otro sentido.

   Los valores no son blanco y negro puros: se toman de la referencia del
   cliente, que usa un negro CÁLIDO para el texto y grises igual de cálidos.
   Sobre blanco, el negro puro corta demasiado.

   El ámbar es el único que no se puede reasignar de golpe. Sobre oscuro
   `#F2B02F` llega a 10,2:1; sobre blanco se queda en 1,9:1 y no vale como
   texto. Así que aquí conviven dos: el de marca sigue sirviendo de RELLENO
   —botones, discos de icono— y `--amber-deep` pasa a ser un ámbar tostado que
   sí se lee, para cuando el ámbar es TEXTO. */
.claro {
  --fondo:        #FFFFFF;
  --fondo-2:      #FBF8F1;
  --fondo-3:      #F5EFE1;
  --fondo-4:      #EDE4CF;
  --texto:        #1B1B2A;
  --texto-suave:  #3A3A45;
  --linea:        #F5D79A;
  --linea-fuerte: rgba(27, 27, 42, .28);
  --fantasma:     rgba(27, 27, 42, .05);
  --amber-deep:   #8A5D06;

  /* Los tres valores de arriba salen de la presentación del cliente y no son
     los que había: su casi-negro es AZULADO (#1B1B2A), no cálido, y sus
     separadores son ÁMBAR PÁLIDO (#F5D79A), no grises. Lo segundo se nota más
     de lo que parece: `.stats` dibuja sus divisiones con `gap: 1px` sobre
     `--linea`, así que cambiando el token salen solas las hairlines ámbar de
     la referencia, sin una regla nueva.

     Y los bloques que en oscuro son «un punto más oscuro que el lienzo» aquí
     pasan a ser un punto más CÁLIDO que el blanco. Se remapean igual, y con
     eso la carta de industria —escrita contra `--contra`— se vuelve blanca
     sola, sin tocar su regla. */
  --contra:              #FFFFFF;
  --contra-2:            #FDFBF6;
  --texto-contra:        #1B1B2A;
  --texto-contra-suave:  #3A3A45;
  --linea-contra:        #F5D79A;

  /* El filo de tarjeta de la referencia no es gris: es ámbar. Y la sombra es
     cálida, no neutra. */
  --linea-tarjeta: #E7B84B;
  --sombra-clara:  0 30px 70px rgba(150, 130, 80, .12);

  /* El ámbar del texto de tamaño display: la palabra subrayada del titular y el
     número de la cifra. DECISIÓN DEL CLIENTE, y conviene dejarla escrita con
     su medida al lado.

     Aquí hubo un `#B37C08` que daba 3,62:1 sobre blanco y pasaba AA para texto
     grande. El cliente pidió el amarillo de marca, que sobre blanco mide
     **1,9:1** y no llega ni al 3:1 de texto grande. Es su marca y su encargo,
     así que manda el suyo; queda el token para que volver atrás sea cambiar
     esta línea y nada más.

     Ojo si algún día se reutiliza: esto vale para un número de 60 px, que se
     reconoce por la forma. NO lo uses para texto a tamaño de párrafo —para eso
     está `--amber-deep`, que sí se lee. */
  --amber-titular: #F2B02F;

  position: relative;
  background: var(--fondo);
  color: var(--texto);

  /* La curva de abajo tiene que recortar también al lienzo de la malla, que
     ahora es hijo suyo */
  overflow: hidden;

  /* El borde de abajo no es recto: se comba. Los dos radios de abajo llevan
     medio ancho de radio horizontal y unos pocos px de vertical, así que la
     esquina se estira en un arco muy abierto y el blanco baja más por el centro
     que por los lados. */
  border-bottom-left-radius: 50% var(--curva-claro);
  border-bottom-right-radius: 50% var(--curva-claro);

  /* La curva se cobra sitio por los dos lados y hay que reservárselo AQUÍ, no
     en la consulta de medios del salto por pantallas: la curva existe siempre,
     también en móvil. Sin esto, fuera del salto la sección no tiene relleno
     propio y la tapa oscura de arriba —26 px— se comía la primera línea del
     título. En escritorio no cambia nada visible: el contenido va centrado y
     hay aire de sobra. */
  padding-block: calc(var(--curva-claro) + clamp(1rem, 2.5vw, 2rem));
}

/* --------------------------------------------------------------------------
   La transición entre oscuro y claro
   --------------------------------------------------------------------------
   Un canto recto entre las dos superficies es exactamente lo que se veía mal.
   En la referencia del cliente la frontera es un arco muy abierto, y siempre
   en el MISMO sentido: el oscuro se derrama hacia abajo sobre el claro, arriba
   y abajo de la sección. No es un adorno; es lo que hace que el cambio de
   superficie se lea como una transición y no como un corte.

   Arriba no se puede resolver con el radio de la propia sección: un radio
   superior la haría abombarse hacia ARRIBA, y hace falta lo contrario. Por eso
   arriba va una tapa oscura con el radio en su borde inferior, que produce la
   curva en el sentido bueno. */
:root { --curva-claro: clamp(26px, 3vw, 54px); }

.claro::before {
  content: "";
  position: absolute;
  /* El píxel de más por cada lado evita la costura que deja el redondeo
     subpíxel del navegador en los extremos. */
  left: -1px;
  right: -1px;
  top: -1px;
  height: var(--curva-claro);
  background: var(--lienzo);
  border-bottom-left-radius: 50% 100%;
  border-bottom-right-radius: 50% 100%;
  pointer-events: none;
  z-index: 2;
}

/* Con DOS secciones claras seguidas la curva NO va en cada una: va en los
   bordes del TRAMO. Si no, aparecería un arco entre industrias y cifras, que
   son la misma superficie y no tienen ninguna frontera que marcar.

   El radio de abajo lo pierde la clara que lleva otra clara detrás; la tapa
   oscura de arriba la pierde la que viene detrás de otra clara. Escrito por
   relación de hermanos y no con una clase a mano, así que añadir una tercera
   sección clara al tramo funciona sin tocar nada. */
.claro:has(+ .claro) {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.claro + .claro::before { display: none; }

/* --------------------------------------------------------------------------
   La PRIMERA sección de la página, cuando es clara

   Pasa por primera vez en «Trabaja con nosotros», y tiene un problema que
   ninguna otra sección clara tiene: encima no hay una sección oscura, hay la
   CABECERA FIJA, que es transparente hasta que se hace scroll. Con la tapa
   normal —43 px a 1440— el logo y el menú, que son claros, quedaban sobre
   blanco. Medido: cuatro de las cinco piezas de la cabecera, porque el menú va
   centrado a 40 px y el arco de la tapa sube hacia los lados.

   Así que aquí la tapa mide lo que la cabecera MÁS la curva, y el radio
   vertical es solo el de la curva. Los primeros 80 px son oscuros de punta a
   punta, justo detrás de la cabecera, y debajo el oscuro se derrama sobre el
   blanco con el mismo arco que en el resto del sitio. La cabecera se ve igual
   que sobre una portada oscura y la transición no se corta en recto.

   El contenido tiene que empezar por debajo de la tapa, y eso cuesta 43 px de
   alto que las portadas oscuras no pagan: allí el texto puede subir hasta el
   borde de la cabecera. Medido en «Trabaja con nosotros»: el contenido de la
   portada mide unos 600 px y NO baja con la ventana —el titular va a 83 px a
   cualquier alto—, así que por debajo de unos 840 px de alto no cabía entre la
   tapa y el pie de la sección. A 660, que es el alto útil de un portátil de
   1366 × 768, el antetítulo quedaba 76 px metido bajo la tapa. (Y ya antes de
   todo esto chocaba: sobre oscuro se montaba encima del logo. Nadie lo vio
   porque se medía el recorte contra la sección, no contra la cabecera.)

   Así que con el salto por pantallas esta sección deja de medir exactamente
   una pantalla y pasa a medir COMO MÍNIMO una. Si el contenido cabe, es una
   pantalla justa y va centrada como todas. Si no cabe, crece lo que falte en
   vez de encoger la tipografía, que el cliente pidió así de grande. El salto
   sigue cayendo en su borde de arriba, y dentro de una sección más alta que la
   pantalla el navegador deja recorrerla antes de pasar a la siguiente.

   Sin el salto —móvil, ventana baja— la sección no se centra sola y el hueco
   va en su relleno, con algo de aire.
   -------------------------------------------------------------------------- */
main > .claro:first-child::before {
  height: calc(var(--cabecera, 5rem) + var(--curva-claro));
  border-bottom-left-radius: 50% var(--curva-claro);
  border-bottom-right-radius: 50% var(--curva-claro);
}
@media (min-width: 901px) and (min-height: 620px) {
  main > .claro:first-child.pantalla {
    height: auto;
    min-height: 100svh;
    padding-top: calc(var(--cabecera) + var(--curva-claro));
  }
}
@media not all and (min-width: 901px) and (min-height: 620px) {
  main > .claro:first-child {
    padding-top: calc(5rem + var(--curva-claro) + clamp(1rem, 2.5vw, 2rem));
  }
}

/* Las notas en cursiva ámbar son TEXTO a cuerpo pequeño —16 a 17 px—: sobre
   blanco el ámbar de marca cae a 1,9:1 y no se lee. Pasan al tostado, igual que
   el antetítulo. Es la regla de los tres ámbares: el de marca para relleno y
   titulares grandes, el tostado para letra pequeña. */
/* Las notas al margen tambien van en el amarillo de marca. */
.claro .unete__nota,
.claro .canty__nota { color: var(--amber); }

/* --------------------------------------------------------------------------
   La malla no se corta en la frontera
   --------------------------------------------------------------------------
   La curva evitaba el canto recto, pero el corte de verdad era otro: la malla
   ámbar vive en un lienzo FIJO detrás del documento, y una sección clara la
   tapaba con un rectángulo blanco opaco. La constelación se cortaba en seco al
   entrar en el blanco y volvía a aparecer al salir.

   Así que la sección clara lleva su propio lienzo, hijo suyo. No es otra
   malla: es LA MISMA, pintada en coordenadas de ventana y desplazada por la
   posición de la sección en pantalla, de modo que cada hilo entra en el blanco
   exactamente por donde salía del negro. Eso es lo que cose las dos
   superficies.

   Sobre blanco, el degradado que concentra la luz se invierte —blanco en vez
   de negro—: su trabajo es apagar la periferia, y en una superficie clara
   apagar significa aclarar. */
.malla-clara {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}
/* El contenido, por encima del lienzo. Todo menos el lienzo mismo. */
.claro > *:not(.malla-clara) { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   Ojo con esto: EL ÁMBAR DE MARCA SIGUE SIENDO EL DE MARCA cuando es RELLENO.
   Un filete, un disco, un botón: ahí `#F2B02F` va tal cual sobre blanco y se
   ve estupendo. Lo que no puede es hacer de TEXTO, porque sobre blanco cae a
   1,9:1. Las reglas de abajo solo tocan los sitios donde el ámbar es letra o
   trazo fino de lectura; todo lo demás conserva el amarillo del sitio.
   -------------------------------------------------------------------------- */
.claro .paso__num,
.claro .valor__nombre,
.claro .paso__enlace,
.claro .link-arrow { color: var(--amber-deep); }
/* El antetítulo y la nota al margen salen de esa lista y van en el amarillo de
   marca, igual que el título de pilar y por la misma decisión del cliente. Y
   por la misma razón queda dicho el coste: sobre blanco, #F2B02F da 1,80:1. */
.claro .eyebrow { color: var(--amber); }
.claro .eyebrow::before { background: var(--amber); }
/* EL TÍTULO DE PILAR SE SALE DE ESA LISTA Y VA EN EL AMARILLO DE MARCA, por
   decisión del cliente. Queda dicho lo que cuesta: #F2B02F sobre el crema de la
   ficha da 1,80:1, y a 22,4 px con peso 600 —que cuenta como texto grande— la
   norma pide 3:1. El ámbar oscuro que había daba 5,43:1.
   Se deja anotado aquí y no se discute más: es la marca del cliente sobre su
   propia superficie. Si algún día se quiere recuperar el contraste sin perder
   el amarillo, el camino no es oscurecer la letra sino oscurecer la ficha. */
.claro .pilar__nombre { color: var(--amber); }
/* El filete del antetítulo se quedaba en dorado porque esta regla iba DESPUÉS
   de la que lo pasa al amarillo de marca, y a igual especificidad gana la
   última. Se saca de aquí: el antetítulo y su filete son una sola pieza y van
   del mismo color. */
.claro .valor__idx::before { background: var(--amber-deep); }

/* Texto de tamaño display: la palabra subrayada del titular y el número de la
   cifra. Aquí manda `--amber-titular`, que a este cuerpo se lee de sobra y no
   se va al marrón.
   Aquí había una segunda regla para `.hl`, porque su subrayado se dibujaba con
   un degradado de fondo y no con `color`: cambiando solo el color, el filete se
   quedaba en el ámbar ilegible. Al retirarse el subrayado, esa regla sobra. */
.claro .hl,
.claro .stat__num { color: var(--amber-titular); }
/* El disco del icono sí conserva el ámbar de marca: ahí es relleno, no texto,
   y el símbolo de dentro va en tostado para que se lea sobre él. */
.claro .pilar__icono,
.claro .paso__icono { background: rgba(242, 176, 47, .22); color: var(--amber-deep); }

/* La luz que recorre las fichas del semillero se apaga en claro: sobre blanco
   un halo ámbar no se ve, se ensucia. Queda el filete del `:hover`. */
.claro .paso::after { animation: none; border-color: transparent; box-shadow: none; }

/* --------------------------------------------------------------------------
   Tarjetas sobre blanco, con el trato de la referencia: superficie blanca,
   filo ÁMBAR —no gris— y sombra CÁLIDA —no neutra—. El remapeo de `--contra`
   ya volvió blancas las cartas de industria; esto les devuelve el borde que en
   oscuro les daba el propio contraste de superficie y que sobre blanco
   desaparecía.
   -------------------------------------------------------------------------- */
/* La ficha de industria lleva sombra propia, más corta que la de la tarjeta
   grande: `0 30px 70px` está pensado para un bloque de 300 px y sobre una pieza
   de 96 px se lee como suciedad debajo, no como relieve. */
.claro .carta {
  border: 1px solid var(--linea-tarjeta);
  box-shadow: 0 8px 20px rgba(150, 130, 80, .10);
}
.claro .carta:hover {
  box-shadow: 0 8px 20px rgba(150, 130, 80, .10), 0 0 0 1px var(--amber);
}

.claro .stats { box-shadow: var(--sombra-clara); }

/* --------------------------------------------------------------------------
   El botón, y la trampa del remapeo.

   `.btn` escribe su tinta como `--btn-fg: var(--fondo)`, y tiene todo el
   sentido sobre oscuro: la letra del botón ámbar es del color del lienzo, o
   sea casi negra. Pero aquí `--fondo` ya vale BLANCO, así que el botón salía
   con letra blanca sobre ámbar: 1,9:1, ilegible.

   Es el mismo error de siempre en este sitio —un valor correcto, declarado en
   un sitio y consumido en otro donde ya significa otra cosa—. La tinta que
   quiere el botón no es «el fondo de la sección», es «el oscuro de la
   página», y ese token existe y no se remapea nunca: `--lienzo`.
   -------------------------------------------------------------------------- */
.claro .btn { --btn-fg: var(--lienzo); }
.claro ::selection { background: var(--amber); color: var(--lienzo); }

/* Bloque asentado: un punto más oscuro que el lienzo. Con la base ya oscura no
   invierte nada —eso era del sitio claro—; ahora solo separa la superficie del
   fondo. El fondo va SEMITRANSPARENTE para que la malla se siga leyendo
   debajo, apagada, en vez de desaparecer bajo un rectángulo opaco. */
.contraste {
  --fondo:        var(--contra);
  --fondo-2:      var(--contra-2);
  --fondo-3:      #202024;
  --fondo-4:      #2B2B31;
  --texto:        var(--texto-contra);
  --texto-suave:  var(--texto-contra-suave);
  --linea:        var(--linea-contra);
  --linea-fuerte: rgba(255, 255, 255, .22);
  --fantasma:     rgba(255, 255, 255, .055);
  --velo-nav:     8, 7, 10;

  /* Sin fondo, por lo mismo que las variantes de sección: cualquier relleno
     aquí tapa la malla y deja un canto visible donde empieza el pie. La
     separación la pone el filete de `.footer`, que basta. Las variables de
     arriba se quedan porque las usan los hijos. */
  color: var(--texto);
}

/* La luz — el ámbar tratado como iluminación.
   Cada sección con .glow enciende su propia luz al entrar en pantalla, y las
   variantes de posición hacen que parezca una sola luz recorriendo la página
   al hacer scroll.
   El centro va dentro del bloque, nunca en su borde: con el centro en el borde
   el degradado quedaba en su punto más intenso justo donde termina el
   elemento, y el corte se leía como una línea divisoria en el fondo. */
.glow { position: relative; isolation: isolate; }
.glow::before {
  content: "";
  position: absolute;
  inset: 0;
  /* El color final es el mismo ámbar con alfa 0, no "transparent": transparent
     equivale a negro transparente y al interpolar ensucia el degradado con
     tonos apagados. */
  background: radial-gradient(36% 40% at var(--luz-x, 50%) var(--luz-y, 50%),
                              rgba(242, 176, 47, .17),
                              rgba(242, 176, 47, 0) 72%);
  pointer-events: none;
  z-index: -1;
  opacity: 0;
  transform: scale(.88);
  transition: opacity 1.5s var(--ease), transform 2.2s var(--ease);
}
.glow.is-iluminada::before { opacity: 1; transform: none; }

/* El degradado tiene que apagarse ANTES de llegar al borde del elemento, o la
   caja lo recorta y el corte se ve como una línea recta.
   Con radios de 36% y 40% y el corte en 72%, la luz alcanza 25.9% en
   horizontal y 28.8% en vertical: por eso los centros no bajan del 28% ni
   pasan del 72%. Si mueves un centro, revisa que centro ± ese alcance siga
   dentro de 0–100%. */
.glow--izq    { --luz-x: 28%; }
.glow--der    { --luz-x: 72%; }
.glow--alta   { --luz-y: 32%; }
.glow--baja   { --luz-y: 68%; }

/* --------------------------------------------------------------------------
   4. Tipografía de apoyo
   -------------------------------------------------------------------------- */
/* EL ANTETÍTULO ERA EL ÚNICO NIVEL DEL SITIO QUE NO CRECÍA. Usaba `--t-micro`,
   que son 12 px fijos, mientras todos los demás niveles son `clamp()`: en una
   ventana de 1878 el titular llegaba a 68 px y el antetítulo seguía en 12, así
   que se leía minúsculo. Ahora es fluido como el resto —de 12 a 17— y el filete
   y el hueco crecen con él, que si no la pieza se desarma.
   Crece en las seis páginas a la vez, que es de lo que se trata. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: clamp(.6rem, .5rem + .4vw, .95rem);
  font-family: var(--font-display);
  font-size: clamp(.75rem, .66rem + .36vw, 1.0625rem);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 1.5rem;
}
.eyebrow::before {
  content: "";
  width: clamp(1.75rem, 1.4rem + 1.1vw, 2.75rem);
  height: 2px;
  background: var(--amber);
  border-radius: 2px;
}
.section--light .eyebrow, .section--paper .eyebrow { color: var(--amber-deep); }
.section--light .eyebrow::before, .section--paper .eyebrow::before { background: var(--amber-deep); }

.lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  color: var(--texto-suave);
  max-width: var(--maxw-text);
  /* Reparte el texto entre las líneas en vez de llenar la primera y dejar la
     segunda coja. Sin esto, el subtítulo de Clientes partía en «nos confían
     las / operaciones», cortando la frase por la mitad; equilibrado, la lista
     de sectores se queda en una línea y la afirmación en la otra, que es como
     se lee. En los subtítulos de una sola línea no hace nada. */
  text-wrap: balance;
}
.section--light .lead, .section--paper .lead { color: var(--texto-contra-suave); }
/* La idea clave del párrafo va destacada, como en la referencia. El gris del
   subtítulo sube al blanco del texto normal: sin esto, `<strong>` solo
   engordaba el trazo y sobre un gris apagado eso casi no se nota. */
.lead strong { color: var(--texto); font-weight: 600; }

/* La palabra acentuada del titular. SIN SUBRAYADO: el acento es el color.
   Llevaba un filete ámbar que se dibujaba solo al entrar en pantalla —un
   degradado de fondo, no un `::after`, para que respetara los saltos de línea—
   y el cliente lo retiró de todo el sitio.
   Lo que se va con él, y conviene saberlo si alguna vez se recupera: el
   `padding-bottom` que le reservaba sitio, la transición que lo dibujaba y la
   compensación que el encabezado de «Cantec en cifras» hacía para que ese
   filete no se comiera el hueco de debajo. */
.hl { color: var(--amber); }

/* --------------------------------------------------------------------------
   5. Botones
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--amber);
  --btn-fg: var(--fondo);
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  padding: .95rem 1.75rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  border: 1px solid transparent;
  border-radius: 999px;
  cursor: pointer;
  transition: background .3s var(--ease), color .3s var(--ease),
              transform .3s var(--ease), border-color .3s var(--ease);
}
.btn:hover { background: var(--amber-soft); transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn__arrow {
  width: .95em; height: .95em;
  flex: none;
  transition: transform .3s var(--ease);
}
.btn:hover .btn__arrow { transform: translateX(4px); }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--texto);
  border-color: var(--linea-fuerte);
}
.btn--ghost:hover {
  --btn-bg: var(--texto);
  --btn-fg: var(--fondo);
  border-color: var(--texto);
}

.btn--dark {
  --btn-bg: var(--fondo);
  --btn-fg: var(--texto);
}
.btn--dark:hover { --btn-bg: var(--fondo-3); }

/* Enlace de texto con flecha */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--amber);
  padding-bottom: .35rem;
  border-bottom: 1px solid rgba(242,176,47,.35);
  transition: color .3s var(--ease), border-color .3s var(--ease), gap .3s var(--ease);
}
.link-arrow:hover { color: var(--amber-soft); border-color: var(--amber-soft); gap: .9rem; }
.link-arrow svg { width: .9em; height: .9em; }

/* --------------------------------------------------------------------------
   6. Cabecera
   -------------------------------------------------------------------------- */
.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: background .4s var(--ease), border-color .4s var(--ease), backdrop-filter .4s;
  border-bottom: 1px solid transparent;
}
.header.is-stuck {
  background: rgba(var(--velo-nav), .82);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--linea);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 5rem;
}

.brand { display: flex; align-items: center; flex: none; }
.brand svg { width: clamp(118px, 11vw, 152px); height: auto; }
.brand__word { fill: var(--texto); transition: fill .3s var(--ease); }

.nav { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2.25rem); }

.nav__link {
  position: relative;
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 500;
  letter-spacing: .01em;
  color: var(--texto-suave);
  padding-block: .4rem;
  transition: color .25s var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--amber);
  border-radius: 999px;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .35s var(--ease);
}
.nav__link:hover, .nav__link[aria-current="page"] { color: var(--texto); }
.nav__link:hover::after, .nav__link[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* El botón de acceso al portal. Va más corto que un botón de cuerpo: con el
   relleno de `.btn` mide 46 px de alto y se come la cabecera, que son 80. Y va
   fantasma, no ámbar sólido: no es una llamada a la acción, es una puerta para
   quien ya es cliente, y el ámbar en la cabecera competiría con el botón que
   lleva al formulario en cada pantalla. */
.header__cta { flex: none; padding: .62rem 1.3rem; }

/* Las dos acciones van en una caja porque la cabecera reparte a lo ancho con
   `space-between`: sueltas, el reparto metería entre ellas el mismo hueco que
   entre la marca y el menú, y dos botones que son un grupo se leerían como dos
   cosas que no tienen nada que ver. */
.header__acciones {
  display: flex;
  align-items: center;
  gap: .65rem;
  flex: none;
}

/* El conmutador de idioma. Enseña el idioma AL QUE SE VA —en español dice EN—,
   que es lo que hacen las tres landings empaquetadas y lo que espera cualquiera
   que haya visto una web bilingüe.

   Es más pequeño y más ligero que el botón de al lado, y a propósito: cambiar
   de idioma no es lo que se ha venido a hacer aquí. Mismo filo ámbar y misma
   pastilla, para que se lea como de la misma familia, pero la mitad de peso. */
.lang {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  flex: none;
  padding: .5rem .85rem;
  background: none;
  border: 1px solid rgba(242, 176, 47, .5);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--amber);
  cursor: pointer;
  transition: border-color .25s var(--ease), background-color .25s var(--ease), color .25s var(--ease);
}
.lang svg { width: 15px; height: 15px; flex: none; }
.lang:hover {
  border-color: var(--amber);
  background: rgba(242, 176, 47, .12);
}
/* El foco se ve: es un botón, y quien navega con el teclado tiene que saber
   dónde está. El sitio ya usa este mismo anillo en el resto de controles. */
.lang:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }

/* Lo que solo se ve en inglés. Hoy es una sola cosa: la nota de los dos avisos
   legales, que advierte de que su texto se queda en español porque es el que
   vincula. Se enciende con el `lang` del documento, que es lo que cambia el
   conmutador, así que no hace falta una clase más ni una línea de guion. */
[data-solo-en] { display: none; }
html[lang="en"] [data-solo-en] { display: block; }
.aviso-idioma {
  margin: clamp(1rem, 2vw, 1.5rem) 0 0;
  max-width: 62ch;
  padding-left: .9rem;
  border-left: 2px solid var(--amber);
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--texto-suave);
}

/* Menú móvil */
.burger {
  display: none;
  width: 2.75rem; height: 2.75rem;
  align-items: center; justify-content: center;
  background: none;
  border: 1px solid var(--linea-fuerte);
  border-radius: 999px;
  cursor: pointer;
  flex: none;
}
.burger span {
  display: block;
  position: relative;
  width: 1.1rem; height: 1.5px;
  background: var(--texto);
  transition: background .2s;
}
.burger span::before, .burger span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%; height: 1.5px;
  background: var(--texto);
  transition: transform .35s var(--ease), top .25s var(--ease);
}
.burger span::before { top: -.4rem; }
.burger span::after  { top: .4rem; }
.burger[aria-expanded="true"] span { background: transparent; }
.burger[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.burger[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

.mobile-nav {
  position: fixed;
  inset: 5rem 0 0 0;
  z-index: 99;
  background: var(--fondo);
  padding: 2rem var(--pad-x) 3rem;
  display: flex;
  flex-direction: column;
  gap: .25rem;
  transform: translateY(-100%);
  opacity: 0;
  visibility: hidden;
  transition: transform .45s var(--ease), opacity .35s, visibility .45s;
  overflow-y: auto;
}
.mobile-nav.is-open { transform: translateY(0); opacity: 1; visibility: visible; }
.mobile-nav a {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 6vw, 2.4rem);
  font-weight: 500;
  letter-spacing: -.02em;
  padding-block: .55rem;
  border-bottom: 1px solid var(--linea);
}
.mobile-nav a:hover { color: var(--amber); }
/* En el menú móvil los enlaces son titulares de 2,4 rem con filete debajo. El
   botón no es un enlace más: recupera su tamaño, su filo y su tinta. Sin la
   última línea, el `:hover` del menú —más específico que el del botón— le
   ponía letra ámbar sobre el relleno blanco del fantasma: 1,9:1. */
.mobile-nav .btn { margin-top: 2rem; align-self: flex-start; font-size: var(--t-small); }
.mobile-nav .btn--ghost { border-color: var(--linea-fuerte); }
.mobile-nav .btn:hover { color: var(--btn-fg); }
/* El idioma va debajo del acceso y pegado a él: son el mismo grupo que en la
   cabecera, solo que apilado. Separación corta entre los dos y la larga arriba,
   que es la que los despega de los enlaces del menú. */
.mobile-nav .lang--movil { margin-top: .85rem; align-self: flex-start; }

/* ---- «Soluciones», que aquí es un desplegable ----------------------------
   Con `<details>`: abrir y cerrar es justo lo que ese elemento hace de fábrica,
   y con él vienen gratis el teclado, el lector de pantalla —que anuncia
   «contraído» y «expandido»— y el funcionar sin JavaScript. Lo único que se le
   quita es el triangulito del navegador, que no pega con la tipografía del
   menú: el galón lo dibuja el `::after`.

   El filete de debajo pasa del `<summary>` al `<details>` entero. Puesto en el
   `summary`, al desplegar quedaba una raya en medio, separando el rótulo de su
   propia lista. */
.mobile-nav .menu-grupo { border-bottom: 1px solid var(--linea); }
.mobile-nav summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  list-style: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 6vw, 2.4rem);
  font-weight: 500;
  letter-spacing: -.02em;
  padding-block: .55rem;
  transition: color .25s var(--ease);
}
.mobile-nav summary::-webkit-details-marker { display: none; }
.mobile-nav summary:hover { color: var(--amber); }
.mobile-nav summary:focus-visible { outline: 2px solid var(--amber); outline-offset: 4px; }
/* El galón son dos lados de un cuadrado girado: medio punto de un carácter, así
   que crece con el rótulo sin una medida más que mantener. */
.mobile-nav summary::after {
  content: "";
  flex: none;
  width: .34em;
  height: .34em;
  margin-right: .18em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-.12em) rotate(45deg);
  opacity: .5;
  transition: transform .3s var(--ease), opacity .25s var(--ease);
}
.mobile-nav .menu-grupo[open] summary::after { transform: translateY(.06em) rotate(-135deg); opacity: 1; }

/* La lista colgada. El filete de la izquierda la ata al rótulo del que
   depende, y el cuerpo baja a la mitad: son hijas, no hermanas de «Nosotros» y
   «Trabaja con nosotros». */
.mobile-nav .menu-grupo__lista {
  display: flex;
  flex-direction: column;
  margin: 0 0 .9rem .25rem;
  padding-left: 1rem;
  border-left: 1px solid var(--linea);
}
.mobile-nav .menu-grupo__lista a {
  font-size: clamp(1.05rem, 4.2vw, 1.4rem);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--texto-suave);
  padding-block: .42rem;
  border-bottom: 0;
}
.mobile-nav .menu-grupo__lista a:hover { color: var(--amber); }


/* --------------------------------------------------------------------------
   7. Intro de entrada — RETIRADA el 9 de octubre de 2026
   --------------------------------------------------------------------------
   El cliente la quito. Se fue entera: estos estilos, su marcado en index.html
   y su modulo en site.js. Esta en el historial, en el commit anterior a
   "Home: fuera la intro de entrada".

   El numero 7 se queda vacio a proposito. Renumerar las diecisiete secciones
   que vienen detras dejaria mintiendo todas las referencias "seccion N" del
   README por un hueco que no molesta a nadie.
   -------------------------------------------------------------------------- */


/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: grid;
  align-items: center;
  padding-top: 8rem;
  padding-bottom: clamp(3rem, 6vw, 6rem);
  overflow: hidden;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero__bg img,
.hero__bg video {
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: .38;
}
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to right, var(--fondo) 8%, rgba(8,7,10,.72) 48%, rgba(8,7,10,.35) 100%),
    linear-gradient(to top, var(--fondo) 2%, transparent 45%);
}

/* La portada del Home: la fotografía manda y llega a los cuatro bordes.
   El velo es DIRECCIONAL —casi opaco a la izquierda, casi limpio a la
   derecha— para que el titular se lea sobre negro y la escena siga viéndose.
   Un velo parejo obligaría a elegir entre las dos cosas. */
.hero__bg--pleno img,
.hero__bg--pleno video {
  opacity: 1;
  object-position: 68% 46%;
}
/* El encuadre vale igual para el vídeo: mide 1280 × 720 y la foto 1672 × 940,
   o sea la misma proporción, y es la misma escena. */
.hero__bg--pleno::after {
  background:
    linear-gradient(100deg,
      rgba(8,7,10,.97)  0%,
      rgba(8,7,10,.90) 30%,
      rgba(8,7,10,.55) 58%,
      rgba(8,7,10,.28) 100%),
    linear-gradient(to top, rgba(8,7,10,.92) 0%, rgba(8,7,10,0) 46%),
    linear-gradient(to bottom, rgba(8,7,10,.78) 0%, rgba(8,7,10,0) 22%);
}

/* En cuanto la ventana deja de ser ancha, ese velo direccional se vuelve en
   contra. Un degradado de izquierda a derecha, metido en una caja alta, acaba
   corriendo en diagonal: su extremo limpio cae abajo a la derecha, que es justo
   donde están la bajada y el botón. Medido sobre la foto, el ámbar del titular
   se queda en 2,3-2,5:1 y la bajada entre 2,0 y 3,3:1, cuando piden 3 y 4,5.
   No es culpa de la foto —con la anterior la bajada ya andaba en 2,5, de la
   adaptación a móvil que quedó a medias— ni se arregla moviendo el encuadre:
   se probaron ocho valores de object-position y no pasa ninguno.
   Aquí el velo manda de abajo arriba: opaco bajo el texto, que ocupa del 41 al
   68 % del alto, y abierto por encima del 38 %, que es donde quedan la cara y
   el panel. El corte va en 3/2 porque a esa proporción el direccional ya solo
   saca 4,71 en la bajada, y a 1,33 falla. */
@media (max-aspect-ratio: 3/2) {
  .hero__bg--pleno::after {
    background:
      linear-gradient(to top,
        rgba(8,7,10,.82)   0%,
        rgba(8,7,10,.82)  62%,
        rgba(8,7,10,.57)  80%,
        rgba(8,7,10,.32) 100%),
      linear-gradient(to bottom, rgba(8,7,10,.80) 0%, rgba(8,7,10,0) 18%);
  }
}

/* El "sol": disco ámbar difuso que asoma detrás del contenido */
.hero__sun {
  position: absolute;
  z-index: 0;
  right: -14vw;
  top: 18%;
  width: min(58vw, 620px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(242,176,47,.55), rgba(242,176,47,.12) 55%, rgba(242,176,47,0) 72%);
  filter: blur(12px);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
  width: 100%;
}

.hero__title {
  font-size: var(--t-hero);
  font-weight: 500;
  letter-spacing: -.04em;
  margin-bottom: 1.25rem;
}

.hero__lead {
  font-size: var(--t-lead);
  color: var(--texto-suave);
  max-width: 34ch;
  /* El titular lleva subrayado ámbar: sin este aire el texto queda pegado */
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
  /* Igual que en `.lead`: reparte el texto entre las líneas. `.hero__lead` es
     otra clase y no heredaba aquella regla. */
  text-wrap: balance;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; }

/* Imagen recortada con el arco de la marca */
.arc-media {
  position: relative;
  border-radius: var(--arc);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--fondo-3);
}
.arc-media img { width: 100%; height: 100%; object-fit: cover; }
.arc-media--flip { border-radius: 14rem 1.25rem 14rem 14rem; }
.arc-media--sm { border-radius: var(--arc-sm); aspect-ratio: 1; }

.hero__media { position: relative; }
.hero__media .arc-media { aspect-ratio: 3 / 4; }

/* Marcador de datos que flota sobre la imagen del hero */
.float-stat {
  position: absolute;
  left: -1.5rem;
  bottom: 2.5rem;
  background: rgba(18,18,21,.82);
  backdrop-filter: blur(16px);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  padding: 1.15rem 1.5rem;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.float-stat__num {
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--amber);
  line-height: 1;
}
.float-stat__label {
  font-size: var(--t-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--texto-suave);
  margin-top: .4rem;
}

/* No es un adorno: al pasar el cursor (o al pulsarlo) baja solo hasta las
   soluciones, que es donde arranca la animación del mosaico. */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 1.75rem;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .6rem;
  padding: .75rem 1.25rem;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-size: var(--t-micro);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--texto-suave);
  transition: color .3s var(--ease);
}
.scroll-cue:hover, .scroll-cue:focus-visible { color: var(--amber); }
.scroll-cue__line {
  width: 1px; height: 2.75rem;
  background: linear-gradient(to bottom, var(--amber), rgba(242, 176, 47, 0));
  animation: cue 2.4s var(--ease) infinite;
  transition: height .3s var(--ease);
}
.scroll-cue:hover .scroll-cue__line { height: 3.6rem; }
@keyframes cue {
  0%, 100% { transform: scaleY(.35); transform-origin: top; opacity: .4; }
  50%      { transform: scaleY(1);   transform-origin: top; opacity: 1; }
}

/* Hero interior, más corto, para las páginas secundarias */
.hero--page { min-height: auto; padding-top: 11rem; padding-bottom: clamp(3rem, 6vw, 5.5rem); }
.hero--page .hero__inner { grid-template-columns: 1fr; }
.hero--page .hero__title { font-size: var(--t-h1); }
.hero--page .hero__lead { max-width: 52ch; }

/* --------------------------------------------------------------------------
   9. Servicios — mosaico
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(2.5rem, 5vw, 5.5rem);
  align-items: start;
}
.split__sticky { position: sticky; top: 7.5rem; }
/* Encabezado a dos columnas de «Casos de éxito». Fuera de pantalla completa
   conserva la separación que traía en línea. */
.casos__cabeza { margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }

/* Encabezado de sección en un solo bloque.
   A dos columnas el título y su texto se leían como dos piezas sueltas, por
   mucho que se alinearan: apilados quedan como una sola unidad. */
.cabecera {
  display: block;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.cabecera h2 { margin: 0; }
.cabecera .lead {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  max-width: 56ch;
}

/* --------------------------------------------------------------------------
   Cabecera de ENUNCIADO: el titular no es una etiqueta, es una frase.

   NADIE LA USA DESDE EL 9 DE OCTUBRE DE 2026. La llevaba el encabezado de
   Soluciones mientras decía «CANTEC convierte cada operación en crecimiento.»;
   el cliente lo cambió a «Nuestro modelo» y, siendo ya una etiqueta de dos
   palabras, volvió al cuerpo normal y con él a medir lo mismo que los otros
   tres titulares del Home. Se queda la regla porque ESTE TITULAR HA CAMBIADO
   TRES VECES y el día que vuelva a ser una frase larga, esto es lo que hay que
   ponerle: se añade `cabecera--enunciado` al lado de `cabecera` y ya está.

   Lo que hace, y por qué: cuando el encabezado afirma algo en lugar de nombrar
   la sección, el titular baja de cuerpo. No es un capricho, es aritmética, y se
   midió con cada frase que pasó por aquí. Con la primera —137 caracteres—
   `--t-h2` daba CUATRO líneas y el encabezado pesaba más que el carrusel de
   debajo. Con la segunda —47 caracteres— la diferencia era menor pero seguía
   ahí: a 68 px eran dos líneas y la sección se quedaba en 33 px de aire a
   1440 × 900; a este cuerpo era UNA línea y quedaban 84.

   Antes de ponérsela a nada, vuelve a medir con la frase que haya. Y ten
   presente el precio, que es el que la ha retirado ahora: el titular que la
   lleva DEJA DE MEDIR LO MISMO que los demás. Con un enunciado se acepta —una
   frase no se compone como una etiqueta—; con una etiqueta, no.
   -------------------------------------------------------------------------- */
.cabecera--enunciado h2 {
  font-size: clamp(1.6rem, 2.8vw, 2.5rem);
  /* 1,15 y no 1,25: a este cuerpo, cada décima de interlínea son 4 px por
     renglón, y con tres renglones eso es un renglón entero de más en el alto
     del encabezado. Medido: con 1,25 la sección se quedaba en 32 px de aire y
     con 1,15 en 68, que es lo que tenía antes de todo esto. */
  line-height: 1.15;
  letter-spacing: -.015em;
}

/* Las fichas de servicio — carrusel horizontal.

   Cada ficha es una tarjeta alta: rótulo pequeño arriba, titular en dos líneas
   debajo, y la imagen ocupando la mitad inferior a sangre dentro de la tarjeta.
   La tarjeta entera es un enlace a la página de ese servicio, y el disco del
   «+» de la fila de abajo es la pista visible de que lleva a algún sitio.

   La pista lleva la clase `.wrap`, igual que el encabezado y que el resto del
   sitio, así que las tarjetas arrancan en la misma vertical que todo lo demás.
   Al ser un contenedor con scroll, el relleno del wrap hace de margen inicial y
   final del recorrido.

   El ancho de tarjeta está pensado para que se vean tres y media: la cuarta
   asomando es lo que dice «esto sigue» sin necesidad de explicarlo. */
.carrusel {
  display: flex;
  flex-direction: column;
  gap: clamp(.9rem, 2vh, 1.5rem);
  min-height: 0;
}

.carrusel__pista {
  display: flex;
  gap: clamp(.75rem, 1.4vw, 1.25rem);
  flex: 1 1 auto;
  min-height: 0;
  /* Techo de altura: sin él la pista se estira con la sección y las fichas
     salen demasiado largas en pantallas altas. Con el ancho de tarjeta en
     ~331 px esto las deja en proporción 0,73, cerca de la referencia. */
  max-height: min(50svh, 460px);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  /* Sin esto el ajuste alinearía el borde de la tarjeta con el borde del
     contenedor y se comería el margen del wrap: la primera ficha quedaría
     51 px a la izquierda del titular en cuanto se moviera el carrusel. */
  scroll-padding-inline: var(--pad-x);
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
  overscroll-behavior-x: contain;
}
.carrusel__pista::-webkit-scrollbar { display: none; }

/* ---- La ficha ---- */
.ficha {
  position: relative;
  flex: none;
  /* Ancho pensado para que las CUATRO quepan dentro de la columna:
     4 fichas + 3 huecos ≤ ancho útil del wrap. El caso más apretado es la
     ventana ancha, donde el wrap se queda en 1440 menos su relleno de 96 px por
     lado: 1248 útiles contra 4×296+60 = 1244. */
  width: clamp(210px, 20vw, 296px);
  height: 100%;
  /* Este mínimo es lo que fija la altura de verdad. El techo de la pista
     —`min(50svh, 460px)`— casi nunca llega a mandar, porque el carrusel encoge
     a su contenido y su contenido es esto. El `min(…, 50svh)` evita pedir más
     de lo que la pista puede dar en una ventana baja: sin él, a 660 de alto la
     tarjeta pedía 384 contra un techo de 330 y el rótulo se cortaba por abajo,
     que es justo donde vive el texto. */
  min-height: min(384px, 50svh);
  /* Rejilla de UNA celda: la imagen y el rótulo ocupan la misma casilla y el
     rótulo se pega abajo. Antes iban apilados en columna, y por eso el
     degradado tenía que acabar en negro opaco: debajo del texto no había
     imagen, había el color liso de la tarjeta. Con la superposición la foto
     sigue ahí y el degradado solo la atenúa.
     Va en rejilla y no en posicionamiento absoluto porque así la celda mide lo
     que mida el mayor de los dos: en el móvil, donde la imagen lleva
     `aspect-ratio` y la tarjeta crece con su contenido, sigue cuadrando sin
     reglas aparte. */
  display: grid;
  grid-template-rows: 1fr;
  overflow: hidden;
  border-radius: clamp(16px, 1.5vw, 26px);
  background: var(--contra);
  scroll-snap-align: start;
  isolation: isolate;
  /* Entrada escalonada al llegar la sección */
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .7s var(--ease) var(--dl, 0s),
              transform .7s var(--ease) var(--dl, 0s);
}
.is-visible .ficha { opacity: 1; transform: none; }
.carrusel__pista .ficha:nth-child(1) { --dl: .10s; }
.carrusel__pista .ficha:nth-child(2) { --dl: .20s; }
.carrusel__pista .ficha:nth-child(3) { --dl: .30s; }
.carrusel__pista .ficha:nth-child(4) { --dl: .40s; }

/* El texto va al PIE de la tarjeta, SOBRE la imagen: por eso el relleno
   grande está abajo y no arriba. */
/* El disco del «+» es HERMANO del rótulo, no un absoluto encima. Puesto en la
   esquina con `position: absolute` habría que reservarle sitio a mano con un
   relleno derecho, y ese cálculo se rompe solo: a 1462 de ancho dejaba el
   título en 195 px y «Experiencia 360» —el nombre más largo— se cortaba con
   puntos suspensivos. Como hermano en una fila flexible el solape es imposible
   por construcción: el rótulo encoge y el disco conserva su tamaño. */
.ficha__cabeza {
  grid-area: 1 / 1;
  align-self: end;
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  gap: clamp(.6rem, 1vw, .9rem);
  padding: clamp(.9rem, 1.4vw, 1.35rem) clamp(1.15rem, 1.6vw, 1.75rem) clamp(1.15rem, 1.6vw, 1.75rem);
}
.ficha__rotulo { flex: 1 1 auto; min-width: 0; }

/* Manda el nombre del servicio, que es lo que la gente busca; la frase que lo
   acompaña va debajo y en cuerpo de apoyo. Estaban al revés: el nombre hacía de
   antetítulo pequeño y el fragmento de titular. */
/* UNA línea siempre, por construcción. El cuerpo está elegido para que el
   nombre más largo —«Experiencia 360»— quepa sin partirse a cualquier ancho, y
   el recorte a una línea garantiza que aunque algún día entre un nombre más
   largo la cabeza no crezca y las cuatro fichas sigan cuadrando.

   Con el título libre, «Experiencia 360» ocupaba dos líneas y las otras tres
   una: su frase de apoyo y su imagen bajaban 37 px respecto a las demás. */
.ficha__titulo {
  margin: 0;
  font-size: clamp(1.2rem, 1.55vw, 1.72rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -.02em;
  color: var(--texto-contra);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Dos líneas SIEMPRE: reservadas aunque el texto ocupe una, y recortadas si
   pidiera tres. Es lo que iguala el arranque de las cuatro imágenes; con la
   altura libre, «Tu equipo de ventas externo.» ocupaba una línea y «Mejorar
   cada interacción con tu cliente.» dos, y las fotos empezaban a distinta
   altura en cada ficha. */
.ficha__apoyo {
  margin: .5rem 0 0;
  font-size: clamp(.85rem, .95vw, .98rem);
  font-weight: 400;
  line-height: 1.4;
  color: var(--texto-suave);
  min-height: 2.8em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* La imagen ocupa la tarjeta ENTERA y sangra hasta sus bordes, también por
   detrás del rótulo. */
.ficha__medio {
  grid-area: 1 / 1;
  position: relative;
  min-height: 0;
  overflow: hidden;
}
.ficha__medio img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .8s var(--ease);
}

/* Un velo, no un telón. Antes el degradado acababa en `rgb(12,12,17)` opaco
   porque debajo del texto no había imagen que enseñar; ahora sí la hay, así que
   se queda en .74 y la foto sigue leyéndose por detrás del rótulo. El arranque
   es muy suave —.14 a media altura— para que no se vea dónde empieza el velo.
   El tope de .74 no es estético sino de legibilidad: es lo que hace falta para
   que el texto de apoyo, que va en gris, mantenga contraste AA sobre las cuatro
   fotos. Si algún día entra una imagen más clara, hay que volver a medirlo. */
.ficha__medio::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px 0;
  height: 62%;
  background: linear-gradient(to bottom,
    rgba(12, 12, 17, 0)   0%,
    rgba(12, 12, 17, .12) 30%,
    rgba(12, 12, 17, .38) 55%,
    rgba(12, 12, 17, .72) 76%,
    rgba(12, 12, 17, .86) 100%);
  pointer-events: none;
}

/* El mismo zoom para todo: la imagen crece dentro de su marco y el texto crece
   con ella, anclado a su margen izquierdo para que no se descoloque.
   Con el teclado la regla iba escrita como `.ficha__abrir:focus-visible ~
   .ficha__medio img`, y no funcionaba nunca: el hermano general mira hacia
   ADELANTE y en el HTML la imagen va antes que el botón, así que la selección
   estaba vacía. Quien navega con teclado no veía respuesta ninguna. Con `:has()`
   la condición se cuelga de la tarjeta y ya no depende del orden. */
.ficha:hover .ficha__medio img,
.ficha:has(.ficha__abrir:focus-visible) .ficha__medio img { transform: scale(1.05); }

/* Crece el rótulo, no la fila entera: si el zoom se aplicara a `.ficha__cabeza`
   arrastraría también al disco, que ya tiene el suyo propio, y los dos se
   multiplicarían. */
.ficha__rotulo {
  transform-origin: left center;
  transition: transform .8s var(--ease);
}
.ficha:hover .ficha__rotulo { transform: scale(1.05); }

.ficha:hover { box-shadow: 0 22px 44px -26px rgba(0, 0, 0, .7); }

/* La ficha ENTERA es el enlace a su landing: una capa transparente por encima
   de todo, con el disco del «+» como única pista visible. Antes era un botón
   que abría un visor con la ficha completa y, dentro, un «Ver más» que llevaba
   a la landing: dos pasos para llegar al mismo sitio. Ahora el destino está en
   el primer clic.

   Y al ser un <a> y no un <button> se gana lo que un botón no da: clic con la
   rueda, «abrir en pestaña nueva», arrastrar el enlace y la vista previa del
   destino en la barra de estado. */
.ficha__abrir {
  position: absolute;
  inset: 0;
  z-index: 3;
  cursor: pointer;
}
.ficha__abrir:focus-visible { outline: 2px solid var(--amber); outline-offset: -3px; }

/* El disco va ABAJO, en la misma fila que el nombre y su frase. Estaba arriba a
   la derecha, suelto sobre la imagen; ahí se leía como un adorno del fondo y no
   como el mando de la tarjeta. `position: relative` —y no `static`— porque las
   dos barritas del signo se colocan en absoluto dentro de él. */
.ficha__cruz {
  position: relative;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, .92);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
.ficha__cruz::before,
.ficha__cruz::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  background: #0C0C11;
  border-radius: 2px;
}
.ficha__cruz::before { width: .95rem; height: 2px;    margin: -1px 0 0 -.475rem; }
.ficha__cruz::after  { width: 2px;    height: .95rem; margin: -.475rem 0 0 -1px; }

/* El disco ya no vive dentro del botón, así que la condición del foco se cuelga
   de la tarjeta con `:has()` igual que la de la imagen. */
.ficha:hover .ficha__cruz,
.ficha:has(.ficha__abrir:focus-visible) .ficha__cruz {
  background: var(--amber);
  transform: scale(1.08);
}

/* ---- Flechas ---- */
.carrusel__mandos {
  display: flex;
  justify-content: flex-end;
  gap: .6rem;
  flex: none;
}
.carrusel__flecha {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--linea);
  background: var(--fondo-2);
  color: var(--texto);
  cursor: pointer;
  transition: background .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), opacity .3s var(--ease);
}
.carrusel__flecha svg { width: 1.15rem; height: 1.15rem; }
.carrusel__flecha:hover:not(:disabled) {
  background: var(--amber);
  border-color: var(--amber);
  color: #0C0C11;
}
.carrusel__flecha:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
.carrusel__flecha:disabled { opacity: .3; cursor: default; }

/* Sin sitio para el carrusel, las fichas se apilan una debajo de otra y se van
   las flechas, que ya no mandan nada. El enlace de la tarjeta y su disco se
   quedan: son lo mismo en todas las medidas. */
@media (max-width: 760px) {
  .carrusel__pista { scroll-snap-type: none; flex-direction: column; overflow: visible; }
  .ficha { width: auto; height: auto; min-height: 0; }
  .ficha__medio { aspect-ratio: 4 / 3; flex: none; }
  .carrusel__mandos { display: none; }
}

/* Al bajar se lee primero el encabezado y después las fichas.
   El bloque del carrusel lleva la clase `.wrap` en la pista, igual que el
   encabezado y que TODAS las demás secciones. Así comparte la columna del
   sitio por construcción y no por números repetidos: si algún día cambia
   `--maxw` o `--pad-x`, se mueve todo a la vez. */
.seccion--pantalla {
  padding-block: clamp(2.25rem, 4vw, 3.5rem) 0;
}
.seccion--pantalla .carrusel { margin-top: clamp(1.25rem, 2.4vw, 2rem); }

/* Aquí vivía el VISOR, un <dialog> que enseñaba la ficha completa —ilustración
   a tamaño entero, título, frase de apoyo y texto largo con su «Ver más»—. Se
   retiró el 5 de octubre de 2026 junto con su marca en el HTML y su bloque en
   el JS: la ficha ya no abre nada, lleva derecha a la landing del servicio, así
   que el visor se quedó sin quien lo llamara. Está en el historial de git por
   si algún día hace falta enseñar una ilustración a tamaño completo. */

/* --------------------------------------------------------------------------
   10. Marquesina de logotipos
   -------------------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  padding-block: 1rem;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  align-items: center;
  gap: clamp(2.5rem, 6vw, 5rem);
  width: max-content;
  animation: slide 38s linear infinite;
}
.marquee--reverse .marquee__track { animation-direction: reverse; animation-duration: 46s; }
.marquee:hover .marquee__track { animation-play-state: paused; }

@keyframes slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Los logotipos van sueltos sobre el lienzo, sin caja. Las tuvieron mientras el
   sitio era claro y hacía falta separarlos del blanco; sobre el negro se
   sostienen solos y la caja solo les robaba tamaño. */
.marquee__item {
  flex: none;
  display: grid;
  place-items: center;
  transition: transform .4s var(--ease);
}
.marquee__item:hover { transform: translateY(-4px); }
/* Los archivos venían como logotipo claro sobre fondo negro opaco. Se les
   quitó ese fondo (ver README), así que ahora tienen transparencia real y no
   necesitan ningún modo de fusión: funcionan sobre cualquier superficie. */
/* Los archivos son siluetas claras con transparencia. brightness(0) las vuelve
   negras conservando el alfa, que es lo que se necesita sobre fondo claro; en
   tema oscuro se dejan tal cual. */
.marquee__item img {
  height: clamp(68px, 9vw, 128px);
  width: auto;
  max-width: 340px;
  object-fit: contain;
  /* Son siluetas claras con transparencia: sobre la caja oscura van tal cual.
     El brightness(0) que las volvía negras era para el sitio claro. */
  opacity: .82;
  transition: opacity .4s var(--ease);
}
.marquee__item:hover img { opacity: 1; }

/* Los sellos de certificación necesitan más alto que un logotipo de cliente
   para pesar lo mismo: son marcas cuadradas con mucho margen dentro del propio
   archivo, así que a la altura normal de la cinta —128 px— el dibujo visible se
   quedaba en unos 70 y la fila parecía una nota al pie. */
#certificaciones .marquee__item img { height: clamp(110px, 14vw, 200px); }

/* La sección de clientes es oscura, así que la marquesina ya no necesita
   panel propio: los logotipos (blancos sobre negro) caen directo sobre ella. */
/* Sin isolation: así el modo "screen" se mezcla contra el fondo real de la
   página y el recuadro negro de cada archivo desaparece del todo. */
.logo-band {
  padding-block: clamp(1rem, 2vw, 1.75rem);
  overflow: hidden;
}

.certs-label {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: clamp(1.75rem, 3.5vw, 2.75rem) clamp(1.5rem, 4vw, 3rem) 1.25rem;
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--texto-suave);
}
.certs-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: .25;
}

/* --------------------------------------------------------------------------
   11. Industrias — el mosaico

   Los ocho sectores a la vez, en rejilla de cuatro por dos. Antes eran una
   baraja que caía sola de izquierda a derecha: se veía bien pero solo enseñaba
   tres a la vez y obligaba a esperar para leer los otros cinco. Un listado de
   ocho cosas se lee mejor de un vistazo que de uno en uno.

   Del efecto se conserva lo único que aportaba: la entrada. Las piezas aparecen
   escalonadas al llegar la sección, en orden de lectura.
   -------------------------------------------------------------------------- */
/* EL AIRE DE ESTA SECCIÓN NO ES EL QUE CABE, ES EL QUE SOBRA. El bloque entero
   —encabezado más rejilla— mide 422 px en una ventana de 900, y la sección es
   una pantalla completa: quedaban 213 px de vacío arriba y otros 213 abajo
   mientras dentro el botón y la primera fila de tarjetas se tocaban casi —18 px
   entre un botón ámbar de 55 px de alto y el filo de la primera tarjeta—. Se
   gasta parte de ese sobrante en separar lo que está pegado, que es donde se
   nota. Medido a 900 de alto: el hueco entre el botón y la rejilla pasa de 18 a
   40 px, el de entre tarjetas de 20 a 27, y el bloque sigue cabiendo de sobra
   —sube a ~470 px y deja 215 de aire a cada lado—. */
.mosaico {
  display: flex;
  flex-direction: column;
  gap: clamp(1.75rem, 4.5vh, 3.25rem);
  min-height: 0;
}

.mosaico__cabeza h2 { margin: 0; }
/* `flex` y no un párrafo normal: el botón es `inline-flex` y su caja asoma por
   debajo de la línea de texto que lo contiene, así que el hueco de abajo se
   medía desde el renglón y no desde el botón. */
.mosaico__cta {
  display: flex;
  margin: clamp(1.15rem, 2.4vh, 1.75rem) 0 0;
}

/* Las piezas llevan proporción propia, no se estiran con la pantalla. Con las
   filas en `1fr` se repartían todo el alto disponible y en una ventana alta
   salían columnas de casi 600 px. */
.mosaico__rejilla {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: auto;
  gap: clamp(.9rem, 1.9vw, 1.75rem);
  /* La rejilla NO se estira: se pega al encabezado y es el mosaico entero el
     que se centra en la pantalla. Estirándola, sus filas se centraban dentro
     de la caja sobrante y dejaban al título colgado muy arriba. */
  flex: 0 0 auto;
  min-height: 0;
}
/* La proporción es la preferida, no una obligación: en una ventana baja el
   techo de altura manda y las piezas se achatan en vez de que la segunda fila
   se salga de la pantalla. A 900 de alto el techo no llega a morder. */
.mosaico__rejilla .carta {
  /* El ancho es el de la columna, siempre. Sin declararlo, al morder el techo
     de altura la proporción encogía TAMBIÉN el ancho y las piezas dejaban de
     llenar la fila. */
  width: 100%;
  /* Bien apaisadas: dentro solo hay un número, un nombre y un icono, y con la
     proporción de antes (1,42) quedaban altísimas para tan poco contenido.
     La proporción, y no una altura fija, es lo que mantiene las ocho idénticas
     pase lo que pase con el ancho de la columna. */
  aspect-ratio: 2.6;
  /* El tope de altura sigue existiendo por si la ventana es baja, pero ahora
     casi nunca muerde: a estas alturas manda siempre la proporción. Sube de 120
     a 132 px para que el relleno nuevo no se coma el sitio del texto. */
  max-height: min(16vh, 132px);
}

/* Rectángulo apaisado y bajo: el nombre a la izquierda, el icono a la derecha.
   Antes eran casi cuadradas, con el icono grande CENTRADO DETRÁS del texto y un
   resplandor ámbar de fondo. Sobre oscuro aquello funcionaba —el icono hacía de
   iluminación—, pero sobre blanco el resplandor se leía como una mancha sucia y
   el icono competía con el nombre en vez de acompañarlo. Ahora cada cosa tiene
   su columna y la ficha no necesita fondo ninguno. */
.carta {
  position: relative;
  overflow: hidden;
  border-radius: clamp(10px, 1vw, 16px);
  background: var(--contra);
  color: var(--texto-contra);
  min-height: 0;

  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(.6rem, 1.2vw, 1.1rem);
  /* El relleno también crecía poco para el tamaño de la tarjeta: 14 px arriba
     y 16 a los lados en una pieza de 304 × 117. Con el nuevo, el texto deja de
     ir pegado al filo y la altura sigue mandándola la proporción. */
  padding: clamp(.8rem, 1.25vw, 1.2rem) clamp(.95rem, 1.45vw, 1.35rem);

  /* Entrada escalonada: es lo único que se rescató de la cascada */
  opacity: 0;
  transform: translateY(22px) scale(.985);
  transition: opacity .6s var(--ease) var(--dl, 0s),
              transform .6s var(--ease) var(--dl, 0s),
              box-shadow .35s var(--ease);
}
.is-visible .carta { opacity: 1; transform: none; }
.mosaico__rejilla .carta:nth-child(1) { --dl: 0s;   }
.mosaico__rejilla .carta:nth-child(2) { --dl: .06s; }
.mosaico__rejilla .carta:nth-child(3) { --dl: .12s; }
.mosaico__rejilla .carta:nth-child(4) { --dl: .18s; }
.mosaico__rejilla .carta:nth-child(5) { --dl: .24s; }
.mosaico__rejilla .carta:nth-child(6) { --dl: .30s; }
.mosaico__rejilla .carta:nth-child(7) { --dl: .36s; }
.mosaico__rejilla .carta:nth-child(8) { --dl: .42s; }

.carta:hover { box-shadow: 0 0 0 1px rgba(242, 176, 47, .45); }

/* El gráfico: el icono del sector. Ya no es una capa de fondo —ni posición
   absoluta, ni `z-index`, ni degradado—, es la columna derecha de la ficha. Con
   él se va el resplandor ámbar del fondo Y el halo del propio trazo: los dos
   eran iluminación pensada para el negro, y sobre blanco solo emborronan.
   No hay fotografía por industria y no me la voy a inventar. */
/* En el HTML el icono va ANTES que el texto, porque cuando era una capa de
   fondo tenía que pintarse debajo. Ahora que las dos son columnas de la misma
   rejilla, ese orden las colocaría al revés, así que se dice dónde va cada una
   en vez de reordenar el marcado en ocho sitios. */
.carta__grafico {
  grid-column: 2;
  display: grid;
  place-items: center;
}
.carta__grafico svg {
  width: clamp(30px, 3.4vw, 44px);
  height: auto;
  color: var(--amber);
  opacity: 1;
  transition: transform .45s var(--ease);
}
.carta:hover .carta__grafico svg { transform: scale(1.08); }

.carta__cara {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.carta__cima { display: grid; gap: .45rem; }

.carta__idx {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .18em;
  color: var(--texto-contra-suave);
}

.carta__nombre {
  margin: 0;
  font-size: clamp(.95rem, 1.15vw, 1.2rem);
  font-weight: 600;
  line-height: 1.15;
  color: var(--texto-contra);
  text-wrap: balance;
}

@media (max-width: 1100px) {
  .mosaico__rejilla { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* En dos columnas la ficha apaisada se queda en unos 157 px de ancho y el
   nombre y el icono se pelean por ellos. A una columna la pieza recupera todo
   el ancho y se lee como una lista de renglones, que es justo lo que es. */
@media (max-width: 760px) {
  .mosaico__rejilla { grid-template-columns: minmax(0, 1fr); }
  /* En una sola columna la altura la pone el CONTENIDO más su relleno, no una
     proporción. Con `aspect-ratio: 5.4` la caja se quedaba en 59 px a 375 de
     ancho y dentro hacían falta 70: el nombre se recortaba por arriba y por
     abajo, porque la tarjeta lleva `overflow: hidden`. Ya pasaba antes de dar
     más aire —3 px entonces, 10 después—, y en una lista de renglones la
     proporción no pinta nada. */
  .mosaico__rejilla .carta { aspect-ratio: auto; max-height: none; }
}

/* --------------------------------------------------------------------------
   12. Cifras
   -------------------------------------------------------------------------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(215px, 100%), 1fr));
  gap: 1px;
  background: var(--linea);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  overflow: hidden;
}
.section--light .stats, .section--paper .stats {
  background: var(--linea-contra);
  border-color: var(--linea-contra);
}

.stat {
  background: var(--fondo);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  transition: background .4s var(--ease);
}
.section--light .stat { background: var(--contra); }
.section--paper .stat { background: var(--contra); }
.stat:hover { background: var(--fondo-2); }
.section--light .stat:hover, .section--paper .stat:hover { background: var(--contra-2); }

/* El rótulo, el icono, la fila que los juntaba y las fichas de país vivían
   aquí y se fueron con el mosaico: ahora son `.cifra__rotulo`, `.cifra__icono`,
   `.cifra__cabeza` y `.cifra__paises`, más arriba. Las cifras de «Nosotros»
   —las únicas que siguen usando `.stats`— no llevan ninguna de las cuatro. */
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 5.5vw, 3.75rem);
  font-weight: 600;
  letter-spacing: -.045em;
  line-height: 1;
  color: var(--amber);
  margin-bottom: .7rem;
}
.section--light .stat__num, .section--paper .stat__num { color: var(--amber-deep); }

.stat__desc { font-size: .92rem; color: var(--texto-suave); margin: 0; }
.section--light .stat__desc, .section--paper .stat__desc { color: var(--texto-contra-suave); }

/* Entran escalonadas, como las oficinas y el mosaico, pero lo que se anima es
   EL CONTENIDO DE LA CELDA, no la celda.

   Antes se animaba `.stat` y ahí estaba el problema: `.stats` no dibuja sus
   divisiones con bordes, se pinta de `--linea` por debajo y deja `gap: 1px`
   para que asome. Mientras las celdas estaban a `opacity: 0` lo que se veía por
   detrás no eran unas líneas: era el fondo del contenedor ENTERO, un rectángulo
   ámbar que se iba destapando por trozos. Sobre oscuro apenas se notaba;
   en claro, con `--linea` valiendo #F5D79A, cantaba.

   Con la celda siempre opaca el ámbar queda solo donde tiene que estar: en el
   filo del cuadro y en las divisiones. `--dl` se declara en `.stat` y los hijos
   lo heredan, así que el escalonado sigue igual. */
[data-secuencia] .stat > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s var(--ease) var(--dl, 0s),
              transform .6s var(--ease) var(--dl, 0s);
}
.is-visible .stat > * { opacity: 1; transform: none; }
.stats .stat:nth-child(1) { --dl: 0s;   }
.stats .stat:nth-child(2) { --dl: .09s; }
.stats .stat:nth-child(3) { --dl: .18s; }
.stats .stat:nth-child(4) { --dl: .27s; }
.stats .stat:nth-child(5) { --dl: .36s; }
.stats .stat:nth-child(6) { --dl: .45s; }

/* --------------------------------------------------------------------------
   12 bis. «Cantec en cifras»: la constelación
   --------------------------------------------------------------------------
   Un núcleo y cuatro satélites unidos por tuberías, sobre plataformas
   isométricas. Sustituye al mosaico de seis fichas.

   SE DIBUJA TODO CON CSS Y SVG. No hay una sola imagen: las plataformas son
   pseudoelementos con degradado, las piezas isométricas son cajas de tres
   caras hechas con `rotate`/`skew`, y las tuberías un SVG de cuatro curvas. La
   única imagen de la sección son los cuatro sellos de certificación, que son
   marcas registradas y no se dibujan a mano.

   `.stats` NO se va: lo siguen usando las cifras de «Nosotros», que son otro
   bloque —cuatro celdas, sin rótulo ni icono— y no tienen por qué cambiar.

   EL ORDEN VISUAL LO PONE LA REJILLA, y es el único sitio del sitio donde pasa.
   El HTML va en orden de lectura —núcleo, y los cuatro en el sentido del
   reloj— y cada ficha lleva escrita su casilla. En una columna, la rejilla se
   deshace y vuelve a mandar el orden del HTML.
   -------------------------------------------------------------------------- */
.cn3d {
  display: grid;
  gap: clamp(1rem, 2.4vh, 1.9rem);
}

/* Las dos filas de satélites y el núcleo. Caja propia para que las tuberías se
   dibujen sobre ella y no sobre la sección entera: si cubrieran también la
   barra de certificaciones, cambiarían de forma cada vez que la barra cambia
   de alto. */
.cn3d__orbita {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr) minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: clamp(.9rem, 2.4vh, 1.8rem) clamp(1rem, 3.4vw, 3.6rem);
  align-items: center;
}
.cn3d__ficha--ai { grid-area: 1 / 1 / 2 / 2; }
.cn3d__ficha--ad { grid-area: 1 / 3 / 2 / 4; }
.cn3d__ficha--bi { grid-area: 2 / 1 / 3 / 2; }
.cn3d__ficha--bd { grid-area: 2 / 3 / 3 / 4; }
.cn3d__nucleo    { grid-area: 1 / 2 / 3 / 3; }

/* La envoltura de las cuatro cifras NO EXISTE AQUÍ: con `display: contents` el
   navegador la salta y sus cuatro hijas siguen siendo celdas de la órbita, cada
   una en el `grid-area` que lleva escrito. Está para que en el móvil haya a
   quien colgarle `data-tarjetas` —la órbita tiene diez hijos y nueve no son
   tarjetas— y allí se convierte en el carril. */
/* LOS DOS NIVELES DE ENVOLTURA NO EXISTEN AQUÍ. Con `display: contents` el
   navegador los salta y las cuatro fichas siguen siendo celdas de la órbita,
   cada una en el `grid-area` que lleva escrito. Están para el móvil: el de
   fuera se convierte en el carril —es a quien cuelga `data-tarjetas`, porque la
   órbita tiene diez hijos y nueve no son tarjetas— y cada `cn3d__par` en una
   diapositiva de dos cifras. */
.cn3d__fichas,
.cn3d__par { display: contents; }

/* --- Las tuberías ---------------------------------------------------------
   Van detrás de todo y sin tocar el ratón. `preserveAspectRatio: none` estira
   el dibujo a la caja, que es lo que se quiere —las curvas tienen que llegar a
   las fichas midan lo que midan—, y `vector-effect` evita que al estirarse el
   trazo engorde por un lado y adelgace por el otro. */
.cn3d__tubos {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  filter: drop-shadow(0 0 12px rgba(242, 176, 47, .55));
}
/* EL TUBO SON CUATRO CAPAS SOBRE EL MISMO TRAZADO, y es lo que lo separa de un
   dibujo plano: el aura difusa que lo asienta en el fondo, el cuerpo con un
   degradado vertical —claro arriba, oscuro abajo, que es como cae la luz en un
   cilindro—, el filo de luz corrido hacia arriba, y un pulso que lo recorre.
   La versión anterior era un trazo de color con un contorno oscuro: eso es
   justo lo que lo hacía parecer una ilustración vectorial. */
.cn3d__tubo-aura   { opacity: .28; }
.cn3d__tubo-luz    { opacity: .9; transform: translateY(-3px); }
/* El pulso: un trazo corto que viaja por el tubo. `pathLength` normaliza los
   cuatro trazados a 100, así que el mismo `dasharray` vale para todos aunque
   midan distinto. */
.cn3d__tubo-pulso use { stroke-dasharray: 9 91; stroke-linecap: round; opacity: .95; }
.cn3d__tubo-pulso use { animation: cn3d-pulso 2.8s linear infinite; }
.cn3d__tubo-pulso use:nth-child(2) { animation-delay: .35s; }
.cn3d__tubo-pulso use:nth-child(3) { animation-delay: .7s; }
.cn3d__tubo-pulso use:nth-child(4) { animation-delay: 1.05s; }
@keyframes cn3d-pulso { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }

/* Los cubos: degradado en diagonal y SIN contorno. El contorno oscuro que
   llevaban los dejaba en pegatina; el degradado les da cara iluminada y cara en
   sombra, que es lo que los hace cuerpo. Laten despacio, desfasados. */
.cn3d__cubos rect {
  fill: url(#cn3d-cubo);
  animation: cn3d-cubo 2.8s ease-in-out infinite;
}
.cn3d__cubos rect:nth-child(even) { animation-delay: 1.4s; }
@keyframes cn3d-cubo {
  0%, 100% { opacity: .92; }
  50%      { opacity: 1; }
}

/* El globo punteado vivía aquí, suelto en la esquina de arriba a la derecha de
   la SECCIÓN, con `top: -86%` para subir por encima del encabezado. El 9 de
   octubre de 2026 se mudó dentro de la ficha de «Países», que es de lo que
   habla: las reglas están abajo, con el resto del arte de las fichas. */


/* --- Las fichas ----------------------------------------------------------- */
/* POSICIÓN SÍ, `z-index` NO, y esto importa. Un elemento con `z-index` abre un
   contexto de apilado, y dentro de él un hijo con `z-index` negativo pinta por
   DEBAJO del contenido pero por ENCIMA del fondo del propio elemento: la tarima
   se dibujaba sobre la tarjeta y las fichas salían color crema.
   Sin `z-index`, la tarima cae detrás de la tarjeta, que es su sitio, y las
   fichas siguen por delante de las tuberías porque los elementos posicionados
   sin `z-index` se pintan en el orden del HTML y las tuberías van antes. */
.cn3d__ficha,
.cn3d__barra,
.cn3d__nucleo-cuerpo {
  position: relative;
}
/* ARTE A LA IZQUIERDA, TEXTO A LA DERECHA. Es una fila de dos: la ilustración
   con ancho fijo y el texto quedándose con lo que sobre. El `min-width: 0` del
   texto no es adorno —sin él un hijo de flex no baja de su contenido mínimo y
   las pastillas de «Países» ensancharían la tarjeta hasta descuadrar la
   rejilla—. El texto va alineado a la derecha: así el hueco que queda libre
   está siempre del lado del dibujo y no repartido en dos. */
/* `align-self: stretch` IGUALA LAS DOS FICHAS DE CADA FILA. La órbita centra
   sus celdas, así que antes dos tarjetas de la misma fila con distinto alto
   quedaban flotando a distintas alturas; con el arte dentro, los textos miden
   distinto más a menudo —«Años operando en América.» cae en dos renglones,
   «Físicos.» en uno— y se notaba. Estirando, la fila tiene un solo alto y el
   contenido se centra dentro. */
.cn3d__ficha {
  display: flex;
  align-items: center;
  align-self: stretch;
  gap: clamp(.55rem, 1.1vw, 1rem);
  padding: clamp(1rem, 2.4vh, 1.6rem) clamp(1rem, 1.7vw, 1.6rem);
  border-radius: clamp(14px, 1.2vw, 20px);
  background: #fff;
  border: 1px solid rgba(242, 176, 47, .34);
  box-shadow: 0 18px 38px rgba(150, 130, 80, .16);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease);
}
.cn3d__texto {
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
}
/* LA PLATAFORMA. En la lámina cada ficha está apoyada sobre una tarima que
   sobresale por los lados y por abajo, con su canto a la vista. No es una
   sombra: es una losa, y por eso asoma TAMBIÉN por la izquierda y la derecha.
   Son dos piezas: la losa y su canto, que es la franja de abajo más oscura. */
/* LA TARIMA, rehecha. La primera versión eran dos franjas beige con un canto
   oscuro debajo, y se leía como un cartón pegado detrás de la tarjeta. Lo que
   la hacía parecer cartón eran tres cosas: el color, demasiado saturado contra
   el blanco de la ficha; el canto, un bloque opaco con un borde duro; y la
   sombra, corta y marcada.
   Ahora la losa es casi blanca —se separa por un hilo de luz, no por color—, el
   canto se insinúa con un degradado que se apaga, y la sombra es larga y
   difusa, que es como se apoya algo en la lámina. */
.cn3d__ficha::before,
.cn3d__barra::before {
  content: "";
  position: absolute;
  left: -4%;
  right: -4%;
  bottom: -17px;
  top: 20%;
  border-radius: clamp(18px, 1.7vw, 28px);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #FFFDF8 34%, #FAF4E9 72%, #F0E7D6 100%);
  box-shadow: 0 30px 46px -16px rgba(176, 150, 96, .34),
              inset 0 1px 0 rgba(255, 255, 255, .95);
  z-index: -2;
}
/* El canto: una franja finísima que se apaga hacia los lados, para que la losa
   tenga grosor sin dibujar un borde. */
.cn3d__ficha::after,
.cn3d__barra::after {
  content: "";
  position: absolute;
  left: 2%;
  right: 2%;
  bottom: -17px;
  height: 7px;
  border-radius: 0 0 clamp(14px, 1.3vw, 22px) clamp(14px, 1.3vw, 22px);
  background: linear-gradient(90deg, rgba(221, 206, 178, 0), rgba(221, 206, 178, .85) 22%, rgba(221, 206, 178, .85) 78%, rgba(221, 206, 178, 0));
  z-index: -1;
}
/* La ficha gana su propia luz suave, que es lo que la despega de la losa sin
   necesidad de contraste de color. */
.cn3d__ficha,
.cn3d__barra {
  box-shadow: 0 10px 24px -8px rgba(176, 150, 96, .28),
              0 1px 2px rgba(176, 150, 96, .14);
}
.cn3d__ficha:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 52px rgba(150, 130, 80, .24);
}

/* El rótulo: disco con el icono, filete y nombre. El disco es la pieza que más
   «3D» aporta de toda la ficha, y lo hace con dos sombras: una por dentro,
   arriba, que lo hunde, y otra por fuera, abajo, que lo levanta. */
/* `flex-end` y no `text-align`: la cabeza es una fila de flex, y en una fila de
   flex el texto se alinea pero las cajas no se mueven. El disco se queda a la
   izquierda del rótulo —ese par no se invierte, es la misma pieza— y lo que se
   va al borde derecho es la fila entera. */
.cn3d__cabeza {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(.55rem, .9vw, .8rem);
  margin-bottom: clamp(.5rem, 1.4vh, .9rem);
}
.cn3d__disco {
  flex: none;
  display: grid;
  place-items: center;
  width: clamp(2.3rem, 3.2vw, 3.1rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: linear-gradient(160deg, #fff, #FBF4E6);
  box-shadow: inset 0 2px 4px rgba(255, 255, 255, .9),
              inset 0 -3px 6px rgba(190, 165, 110, .22),
              0 8px 16px rgba(150, 130, 80, .2);
}
.cn3d__ico {
  width: 52%;
  height: auto;
  color: var(--amber);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cn3d__rotulo {
  margin: 0;
  padding: .15rem 0 .15rem clamp(.55rem, .9vw, .8rem);
  border-left: 1px solid rgba(242, 176, 47, .5);
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #6B6257;
}
.cn3d__num {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 3.4vw, 3.25rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
}
/* `margin-left: auto` por la medida máxima: con 22ch y alineado a la derecha,
   la CAJA seguiría pegada a la izquierda y el texto bailaría dentro de ella.
   El margen automático empuja la caja al borde y entonces las dos cosas
   coinciden. */
.cn3d__desc {
  margin: .4rem 0 0 auto;
  max-width: 22ch;
  font-size: var(--t-body);
  line-height: 1.35;
  color: #6B6257;
}
.cn3d__paises {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: .3rem;
  margin: .55rem 0 0;
  padding: 0;
  list-style: none;
}
.cn3d__paises li {
  padding: .22rem .55rem;
  border: 1px solid rgba(242, 176, 47, .4);
  border-radius: 999px;
  font-size: var(--t-micro);
  line-height: 1.2;
  color: #6B6257;
}

/* --- El núcleo ------------------------------------------------------------
   Un rombo de oro con su base extruida, y el texto ENCIMA y derecho. El rombo
   es un pseudoelemento girado 45°, no la caja: así el contenido no hay que
   contragirarlo, que es donde esto se suele torcer. */
.cn3d__nucleo {
  position: relative;
  display: grid;
  place-items: center;
  justify-self: center;
  width: min(100%, clamp(13rem, 24vw, 20rem));
  aspect-ratio: 1;
}
/* EL 14 % NO ES A OJO. Un cuadrado girado 45° tiene una diagonal 1,414 veces su
   lado, así que para que quepa en su caja sin asomar por las esquinas el lado
   no puede pasar del 70,7 % de la caja: 14,6 % de margen por lado.

   SON DOS PIEZAS, no una. En la lámina la cara de arriba es casi BLANCA y lo
   que brilla es la base: un bloque de oro grueso debajo, con su luz derramada.
   Con un solo rombo ambarino —el primer intento— se perdía justo eso.

   La base se mueve con `translate(d, d)`: dentro de un marco girado 45°, mover
   lo mismo en las dos locales da un desplazamiento recto hacia ABAJO en
   pantalla —(d·cos45 − d·sen45, d·sen45 + d·cos45) = (0, 1,414·d)—. Mover solo
   en `y` lo sacaría en diagonal. */
/* LA BASE ES UNA PIEZA HERMANA, no un pseudoelemento del rombo blanco, y es por
   lo mismo que la tarima de las fichas: el rombo lleva `transform`, que abre un
   contexto de apilado, y dentro de él un hijo con `z-index` negativo pinta por
   encima del fondo de su padre. Como pseudoelemento, la base tapaba la cara
   blanca entera. Como hermana y antes en el HTML, se pinta debajo. */
.cn3d__base,
.cn3d__diamante {
  position: absolute;
  inset: 14%;
  border-radius: clamp(22px, 2.8vw, 40px);
}
.cn3d__base {
  transform: rotate(45deg) translate(13px, 13px);
  background: linear-gradient(150deg, #FCD88A 0%, #F2B02F 48%, #D9981C 100%);
  box-shadow: 0 0 46px rgba(242, 176, 47, .95),
              0 0 110px rgba(242, 176, 47, .55);
}
.cn3d__diamante {
  transform: rotate(45deg);
  background: linear-gradient(150deg, #FFFFFF 0%, #FFFCF4 52%, #FDF0D6 100%);
  box-shadow: inset 0 0 0 1px rgba(242, 176, 47, .34),
              inset 0 2px 14px rgba(255, 255, 255, .95),
              0 6px 18px rgba(176, 131, 36, .18);
}
/* El halo que derrama sobre el fondo, fuera del rombo y sin girar. Respira:
   es el latido del centro de la lámina, y marca el compás al que viajan los
   pulsos de los tubos —los dos en 2,8 s— para que la sección tenga un solo
   tiempo y no tres. */
.cn3d__nucleo::before {
  content: "";
  position: absolute;
  inset: -12%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(247, 197, 95, .45), rgba(247, 197, 95, 0) 72%);
  pointer-events: none;
  animation: cn3d-respira 2.8s ease-in-out infinite;
}
@keyframes cn3d-respira {
  0%, 100% { transform: scale(1);    opacity: .85; }
  50%      { transform: scale(1.07); opacity: 1; }
}

/* Las piezas flotan, cada una a su aire. Es un movimiento de cinco píxeles: se
   nota que la sección está viva y no se nota que algo se mueve. Los retrasos
   son negativos para que al cargar la página ya estén repartidas por el ciclo
   en vez de arrancar las cuatro juntas. */
.cn3d__arte img { animation: cn3d-flota 7s ease-in-out infinite; }
.cn3d__arte--globo img  { animation-delay: -1.2s; }
.cn3d__arte--rack img   { animation-delay: -2.4s; }
.cn3d__arte--puesto img { animation-delay: -4.6s; }
@keyframes cn3d-flota {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-5px); }
}
.cn3d__nucleo-cuerpo {
  display: grid;
  justify-items: center;
  text-align: center;
  padding: 0 12%;
}
.cn3d__ico--grande {
  width: clamp(1.8rem, 2.8vw, 2.6rem);
  color: #7A5A12;
  stroke-width: 1.7;
  margin-bottom: .35rem;
}
.cn3d__nucleo .cn3d__rotulo {
  border-left: 0;
  padding: 0;
  color: #7A5A12;
  letter-spacing: .26em;
}
.cn3d__num--grande {
  font-size: clamp(2.6rem, 5vw, 4.4rem);
  color: #2B2015;
  margin-top: .1rem;
}
.cn3d__nucleo .cn3d__desc {
  color: #5D4718;
  font-weight: 500;
  max-width: none;
}

/* --- La barra de certificaciones -----------------------------------------
   MIDE LO QUE MIDE SU CONTENIDO, y va centrada. Como elemento de la rejilla se
   estiraba de margen a margen —1.225 px a 1440— mientras el rótulo y los cuatro
   sellos ocupaban 621: la mitad derecha era blanco, y en una pastilla con los
   extremos redondeados ese vacío se ve más que en una caja. `justify-self:
   center` hace las dos cosas de una vez: la encoge a su contenido y la centra,
   sin un ancho inventado que haya que revisar cada vez que cambie un sello.
   Así vuelve a ser lo que es en la lámina del cliente: una pastilla centrada
   bajo el núcleo, de media anchura. */
.cn3d__barra {
  display: flex;
  align-items: center;
  justify-self: center;
  max-width: 100%;
  gap: clamp(.9rem, 2.4vw, 2.2rem);
  padding: clamp(.7rem, 1.8vh, 1.15rem) clamp(1rem, 2.4vw, 2.2rem);
  border-radius: 999px;
  background: #fff;
  border: 1px solid rgba(242, 176, 47, .34);
  box-shadow: 0 18px 38px rgba(150, 130, 80, .16);
}
.cn3d__barra::before { border-radius: 999px; }
.cn3d__barra::after { border-radius: 0 0 999px 999px; }
.cn3d__disco--barra { width: clamp(2.4rem, 3.4vw, 3.3rem); }
.cn3d__barra-txt {
  margin: 0;
  padding-right: clamp(.9rem, 2.4vw, 2.2rem);
  border-right: 1px solid rgba(242, 176, 47, .4);
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.5vw, 1.35rem);
  font-weight: 700;
  line-height: 1.15;
  color: #2B2015;
}
.cn3d__sellos {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(.9rem, 2.2vw, 2rem);
  margin: 0;
  padding: 0;
  list-style: none;
}
.cn3d__sellos img {
  display: block;
  height: clamp(1.9rem, 3vw, 2.9rem);
  width: auto;
}

/* --- Las piezas isométricas ----------------------------------------------
   SON RECORTES DE LA LÁMINA DEL CLIENTE, no dibujos. Se intentó levantarlas con
   polígonos —tres caras por caja, con vértices compartidos— y el resultado era
   honrado pero no era aquello: la lámina es arte renderizado, con luz, cristal,
   sillas, monitores encendidos y rack con pilotos. Eso no se reproduce con
   polígonos, y acercarse a medias se nota más que no intentarlo.

   Pesan 36 KB los cuatro, en WebP.

   Son decoración: `aria-hidden` y `alt` vacío.

   DÓNDE VIVEN, Y POR QUÉ CAMBIÓ. Hasta el 9 de octubre de 2026 las tres escenas
   flotaban sueltas en la órbita con desplazamientos negativos —`left: -19.4%`,
   `right: -16%`— y asomaban por detrás de las tarjetas, repitiendo la relación
   de la lámina. Tenía dos problemas, y el cliente señaló los dos:

     1. SE SALÍAN DEL MARGEN. Medido a 1440 de ventana, con el `wrap` empezando
        en 73: la ciudad ocupaba de −175 a 98 y el puesto de 1298 a 1557. O sea
        que las piezas se cortaban contra el borde de la ventana mientras todo
        lo demás del sitio guardaba sus 73 px. La sección parecía mal recortada.
     2. DEJABAN LAS FICHAS MEDIO VACÍAS. El texto iba a la izquierda y la mitad
        derecha de cada tarjeta era blanco, mientras la ilustración que le
        correspondía se escondía fuera.

   Ahora cada pieza vive DENTRO de su ficha, a la izquierda, y el texto se va a
   la derecha. Nada sale del `wrap`, y el blanco que sobraba es justo el sitio
   que ocupa el dibujo. El globo, que antes flotaba recortado en la esquina de
   la sección sin pertenecer a nada, es el arte de «Países». */
.cn3d__arte {
  position: relative;
  flex: none;
  width: clamp(84px, 9.6vw, 144px);
  align-self: center;
  pointer-events: none;
}
/* `multiply` BORRA EL FONDO BLANCO DEL RECORTE. Los cuatro vienen de un JPEG
   plano, sin transparencia, y sobre el fondo de la sección —que no es blanco
   puro— se veían como cuatro parches rectangulares. Multiplicando, el blanco
   del recorte deja pasar lo que haya debajo y solo queda el dibujo. Es el mismo
   recurso que se usó con el vídeo de Canty en «Trabaja con nosotros».

   Dentro de la ficha sigue haciendo falta, y además sale gratis: el fondo de la
   tarjeta es blanco puro y multiplicar por blanco no cambia nada, así que el
   dibujo se ve igual y su marco blanco desaparece en la tarjeta. */
.cn3d__arte img {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: multiply;
}
/* El globo se queda un punto por debajo de opaco, como estaba cuando flotaba
   en la esquina: es alambre, no una pieza sólida como las otras tres. La
   opacidad va en la IMAGEN y no en el `span`, porque cualquier `opacity` por
   debajo de 1 en el contenedor abre un contexto de apilado y entonces el
   `multiply` se mezclaría contra un fondo transparente: el recorte volvería a
   verse como un parche blanco. En la propia imagen conviven las dos cosas. */
/* El globo NO baja de opacidad dentro de la ficha. Llevaba un .85 cuando era
   una pieza de fondo del tamaño de media sección: ahí sobraba presencia. A
   138 px es lo contrario —es una trama de puntos muy claros— y con el velado
   de los bordes encima se quedaba en nada. */
.cn3d__arte--globo img { opacity: 1; }

/* --- Los dos recortes que no se pudieron rescatar enteros ------------------
   El 9 de octubre de 2026 se volvieron a recortar las piezas de la lámina
   porque, al meterlas dentro de la ficha, el tajo con el que se cortaron dejó
   de estar tapado y se veía. La ciudad y el rack salieron ENTEROS —plataforma
   completa, esquinas redondeadas y todo—. Los otros dos no pueden:

     el puesto  en la lámina su mitad izquierda está DEBAJO de la ficha de
                «Centros de contacto», que es opaca. No hay plataforma que
                rescatar porque ahí no está dibujada.
     el globo   no es un objeto, es un fondo: el mapa punteado se sale por
                arriba y por la derecha de la propia lámina.

   A los dos se les disuelve el borde con una máscara en vez de cortarlo en
   seco. La máscara va en la IMAGEN, no en un velo encima, porque un velo
   blanco por delante taparía el `multiply`; una máscara deja el píxel en alfa
   cero y entonces el `multiply` simplemente no aporta nada: el blanco de la
   tarjeta queda intacto. Y va en la misma capa que el `mix-blend-mode`, que ya
   abre su propio contexto de apilado, así que no añade ninguno nuevo. */
.cn3d__arte--puesto img {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 19%);
          mask-image: linear-gradient(90deg, transparent 0, #000 19%);
}
.cn3d__arte--globo img {
  -webkit-mask-image: radial-gradient(closest-side, #000 74%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 74%, transparent 100%);
}

/* --- Entrada escalonada ---------------------------------------------------
   EL ARTE YA NO ENTRA POR SU CUENTA. Cuando las piezas flotaban sueltas tenían
   su propio turno al final de la secuencia, el `--dl: .54s`; ahora son hijas de
   la ficha y entran con ella, que es lo correcto: una tarjeta y su ilustración
   son una sola cosa y aparecer por separado las delataría como dos. */
[data-secuencia] .cn3d__ficha,
[data-secuencia] .cn3d__nucleo,
[data-secuencia] .cn3d__barra {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .6s var(--ease) var(--dl, 0s),
              transform .6s var(--ease) var(--dl, 0s);
}
.is-visible .cn3d__ficha,
.is-visible .cn3d__nucleo,
.is-visible .cn3d__barra { opacity: 1; transform: none; }
/* Las tres piezas sólidas se quedan un punto por debajo de opaco, que es lo que
   las asienta en la tarjeta en vez de dejarlas pegadas encima. Va en la IMAGEN
   y no en el `span` por lo de siempre: una opacidad en el contenedor abriría un
   contexto de apilado y mataría el `multiply`. */
.cn3d__arte img { opacity: .94; }
.cn3d__nucleo         { --dl: 0s;   }
.cn3d__ficha--ai      { --dl: .12s; }
.cn3d__ficha--ad      { --dl: .2s;  }
.cn3d__ficha--bi      { --dl: .28s; }
.cn3d__ficha--bd      { --dl: .36s; }
.cn3d__barra          { --dl: .46s; }
/* Las tuberías se dibujan solas al entrar la sección. */
[data-secuencia] .cn3d__tubos g path { stroke-dasharray: 420; stroke-dashoffset: 420; }
.is-visible .cn3d__tubos g path {
  animation: cn3d-tubo 1.1s var(--ease) .35s forwards;
}
@keyframes cn3d-tubo { to { stroke-dashoffset: 0; } }

/* --- Medidas pequeñas -----------------------------------------------------
   Por debajo de 1000 la constelación no cabe: se deshace en dos columnas, las
   tuberías desaparecen —son decoración de un acomodo que ya no existe— y el
   orden vuelve a ser el del HTML.

   EL ARTE SE QUEDA, y es la diferencia respecto a cuando las piezas flotaban
   sueltas: aquello era el acomodo, esto es contenido de la tarjeta. Mientras
   haya tarjeta hay sitio para su dibujo; cuando deja de haberlo —a 760, donde
   la tarjeta se queda en 327 px— se va, y eso lo decide el bloque del móvil. */
@media (max-width: 1000px) {
  .cn3d__orbita {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto;
  }
  .cn3d__ficha--ai, .cn3d__ficha--ad,
  .cn3d__ficha--bi, .cn3d__ficha--bd { grid-area: auto; }
  .cn3d__nucleo { grid-area: auto; grid-column: 1 / -1; width: min(100%, 17rem); }
  .cn3d__tubos { display: none; }
}
@media (max-width: 620px) {
  .cn3d__orbita { grid-template-columns: minmax(0, 1fr); }
  .cn3d__barra { flex-wrap: wrap; justify-content: center; text-align: center; border-radius: clamp(18px, 4vw, 28px); }
  .cn3d__barra::before { border-radius: clamp(18px, 4vw, 28px); }
  .cn3d__barra-txt { border-right: 0; padding-right: 0; }
}
/* Todo el movimiento de la sección se apaga de una vez, tanto por la
   preferencia del sistema como por el conmutador de la propia página. Las
   piezas que se dibujaban solas se quedan dibujadas; las que viajaban, quietas
   y fuera de la vista. */
@media (prefers-reduced-motion: reduce) {
  .cn3d__ficha:hover { transform: none; }
  .is-visible .cn3d__tubos g use { animation: none; }
  .cn3d__tubo-pulso { display: none; }
  .cn3d__cubos rect,
  .cn3d__nucleo::before,
  .cn3d__arte img { animation: none; }
}
html[data-motion="off"] .cn3d__tubo-pulso { display: none; }
html[data-motion="off"] .cn3d__cubos rect,
html[data-motion="off"] .cn3d__nucleo::before,
html[data-motion="off"] .cn3d__arte img { animation: none !important; }

/* --------------------------------------------------------------------------
   13. Tarjetas genéricas
   -------------------------------------------------------------------------- */
.grid { display: grid; gap: var(--gap); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }

/* --------------------------------------------------------------------------
   13 bis. Declaraciones — misión y visión
   -------------------------------------------------------------------------- */
/* El filete ámbar bajo el título va como pseudoelemento del propio título y no
   como un elemento aparte: así no puede quedarse huérfano si algún día se
   reordena el bloque, y su separación se mide desde la línea base del título. */
/* Apilados en el móvil, con el hueco normal de rejilla los dos bloques se
   pegaban a 26 px y el título «Visión» parecía la continuación del párrafo de
   arriba. La separación entre columnas no necesita crecer, solo la de filas. */
.declaraciones {
  position: relative;
  row-gap: clamp(2.75rem, 7vw, 4rem);
  /* El hueco entre las dos fichas es mayor que el de una rejilla normal porque
     por él pasa la curva que las une: con `--gap` (32 px como mucho) la curva
     salía casi vertical. */
  --hueco: clamp(2rem, 5vw, 5.5rem);
  column-gap: var(--hueco);

  /* El relleno de la ficha vive AQUÍ, en una variable, y no suelto dentro de
     `.claro .declaracion`, porque la curva que une las dos fichas también lo
     necesita: sus extremos caen en el centro del disco del número, o sea
     relleno más medio disco. Escrito dos veces, los 11 px de diferencia entre
     una fórmula y otra se notaban a simple vista. Así no pueden separarse. */
  --relleno-ficha: clamp(1.75rem, 3.2vw, 3rem);
}

/* El número, en su disco. Es la misma pieza que `.card__icon` pero con cifra
   dentro; el icono de al lado va suelto, sin disco, porque dos círculos
   seguidos competirían entre sí. */
.declaracion__num {
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  margin: 0 0 clamp(1.1rem, 2.2vw, 1.6rem);
  border-radius: 50%;
  background: rgba(242,176,47,.16);
  color: var(--amber);
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .04em;
}
.claro .declaracion__num,
.section--light .declaracion__num,
.section--paper .declaracion__num { background: rgba(242,176,47,.2); color: var(--amber-deep); }

.declaracion__cabeza {
  display: flex;
  align-items: flex-start;
  gap: clamp(.75rem, 1.5vw, 1.1rem);
}
.declaracion__icono {
  flex: none;
  width: clamp(2rem, 2.6vw, 2.5rem);
  margin-top: .12em;            /* para que el icono case con la altura de la X del título */
  color: var(--amber);
}
.claro .declaracion__icono,
.section--light .declaracion__icono,
.section--paper .declaracion__icono { color: var(--amber-deep); }
.declaracion__icono svg { display: block; width: 100%; height: auto; }

/* ---- La curva que une las dos declaraciones ----
   Solo cuando hay dos columnas de verdad: `.grid--2` las forma a partir de
   320 px por columna, o sea desde unos 750 px de ventana; se toma 820 para
   entrar con margen. Apiladas, una curva horizontal no uniría nada.

   DE ENTRADA NO EXISTE, y esto hay que declararlo. Toda su hoja vivía dentro
   del `@media` de 820: por debajo el `<span>` se quedaba sin posición, sin
   medida y sin `display`, así que no desaparecía —caía en el flujo como un
   `<span>` cualquiera y el `<svg>` de dentro se dibujaba a su tamaño por
   defecto—. En el móvil eso era una raya suelta debajo de las dos fichas,
   uniendo nada. Lo avisó el cliente el 13 de octubre de 2026.
   No basta con no darle estilos: hay que apagarlo.

   Las dos medidas que la colocan NO son a ojo: empieza a la altura del centro
   del disco del número —relleno de la ficha más medio disco— y baja exactamente
   el desnivel de la segunda ficha, así que termina en el centro del disco de la
   otra. Si mañana cambia el relleno de `.card`, la curva sigue en su sitio. */
.declaraciones__union { display: none; }

@media (min-width: 820px) {
  .declaraciones { --desnivel: clamp(2.25rem, 4.5vw, 4rem); }
  .declaraciones .declaracion:nth-child(2) { margin-top: var(--desnivel); }

  .declaraciones__union {
    display: block;
    position: absolute;
    left: 50%;
    top: calc(var(--relleno-ficha) + 1.375rem);
    width: var(--hueco);
    height: var(--desnivel);
    /* Se centra con margen y NO con `transform: translateX(-50%)`: este
       elemento lleva `.reveal`, y `.reveal.is-visible` declara
       `transform: none` con más peso, así que al aparecer la sección se comía
       el centrado y la curva quedaba media anchura a la derecha —36 px a
       1440—. Los puntos no tocaban ninguna de las dos fichas. */
    margin-left: calc(var(--hueco) / -2);
    color: var(--amber);
    pointer-events: none;
  }
  .declaraciones__union svg { display: block; width: 100%; height: 100%; overflow: visible; }

  /* Los extremos. Van como pseudoelementos del envoltorio porque un <svg> no
     admite ::before ni ::after, y con `preserveAspectRatio: none` dos círculos
     dentro del SVG saldrían ovalados. */
  .declaraciones__union::before,
  .declaraciones__union::after {
    content: "";
    position: absolute;
    width: .45rem; height: .45rem;
    border-radius: 50%;
    background: currentColor;
    transform: translate(-50%, -50%);
    opacity: 0;
    transition: opacity .45s var(--ease);
  }
  .declaraciones__union::before { left: 0;    top: 0;    }
  .declaraciones__union::after  { left: 100%; top: 100%; }

  /* Se dibuja al entrar la sección: `pathLength="1"` normaliza el trazado, así
     que un solo valor vale para cualquier tamaño de curva. */
  .declaraciones__union path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset 1.1s var(--ease) .1s;
  }
  .declaraciones__union.is-visible path { stroke-dashoffset: 0; }
  .declaraciones__union.is-visible::before { opacity: 1; transition-delay: .15s; }
  .declaraciones__union.is-visible::after  { opacity: 1; transition-delay: 1.05s; }
}

/* --------------------------------------------------------------------------
   13 ter. Trabaja con nosotros — portada, semillero y Canty
   -------------------------------------------------------------------------- */
/* La referencia del cliente es un diseño CLARO: fondo crema, blobs amarillos y
   una letra manuscrita para las notas al margen. Aquí se respeta la
   maquetación —qué va a la izquierda, qué a la derecha, en qué orden— pero el
   fondo sigue siendo el del sitio. Las notas manuscritas se quedan sin letra
   caligráfica a propósito: el sitio se sostiene sobre DOS tipografías y meter
   una tercera solo para tres frases rompería esa regla. Van en cursiva ámbar,
   que hace el mismo papel de apunte al margen. */
/* La foto pide más sitio del que parece. Es apaisada 3:2, y en una columna de
   580 px se quedaba en 386 de alto dentro de una columna de texto de 805: 379
   px de aire repartidos arriba y abajo, que es lo que se veía como hueco. Se
   arregla por el ancho, no por el alto —estirarla la deformaría—: la columna
   crece y además la imagen SANGRA hasta el borde de la ventana, saliéndose del
   relleno lateral del `.wrap`. */
.unete__rejilla {
  display: grid;
  /* Columnas parejas. Estaban 1 / 1,2 a favor de la foto; al pedir el cliente
     un titular más grande hubo que devolverle sitio al texto, porque el cuerpo
     de letra que cabe sale de la anchura de SU columna. La foto pasa de 762 a
     ~694 px y sigue sangrando hasta el borde. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 3.5vw, 3.5rem);
  align-items: center;
}
.unete .eyebrow { margin-bottom: 1rem; }
/* El cuerpo de portada a sangre completa —112 px— es de cuando el titular
   tenía toda la página para él. En dos columnas la caja se queda en 564 px y
   «Únete al equipo» pedía 780: por eso se partía en tres líneas en vez de las
   dos de la referencia. Con el cuerpo de titular de página entra de sobra. */
/* Más cuerpo y más peso que el titular de portada normal, a petición del
   cliente. El 600 es el mismo grosor que usan los nombres de las fichas, así
   que no entra ningún peso nuevo en el sistema. */
.unete .hero__title { font-size: var(--t-h1); font-weight: 600; }
/* AQUÍ VIVÍA UNA EXCEPCIÓN Y SE RETIRÓ. Las bajadas de esta página subían de
   21,6 a 25,6 px y de peso 400 a 500, para parecerse a una lámina de referencia
   que era clara. El efecto, visto con el sitio entero delante, era que «Trabaja
   con nosotros» hablaba un punto más alto que las otras cinco páginas: mismo
   titular, misma cajita, bajada distinta.
   Ahora usan `.lead` como todo el mundo —`--t-lead`, peso 400 y el gris de
   apoyo—, que es lo que hace que una página se lea como parte de un sitio y no
   como una pieza suelta. */
@media (min-width: 901px) {
  /* Las dos líneas no pueden depender de la suerte. «Únete al equipo» mide
     unas 6,96 veces el cuerpo de letra, y la columna de texto se queda en algo
     menos del 39 % de la ventana: de ahí sale el tope de 5,4vw, que garantiza
     que la primera línea entra entera a CUALQUIER anchura de escritorio. Con
     `--t-h1` a secas entraba por 35 px a 1462 y se partía en tres en cuanto la
     ventana se estrechaba un poco. Debajo de 901 la maqueta es de una sola
     columna, el titular tiene todo el ancho y este tope sobra. */
  /* Dos topes, y los dos hacen falta, porque la columna crece con la ventana
     hasta que deja de hacerlo:
       · `5.8vw` manda mientras la columna crece. Medido: la primera línea ocupa
         6,97 veces el cuerpo de letra y la columna se queda en un 42,5 % de la
         ventana, así que caben hasta 6,1vw; se deja en 5,8 para no ir al filo.
       · `5.2rem` manda a partir de ~1435 px, que es cuando el `.wrap` topa con
         `--maxw` y la columna se congela en 596 px. Ahí caben 85,5 px de cuerpo
         como mucho. Con el techo en 88 que probé primero, a 1900 el titular se
         partía en TRES líneas: la ventana seguía creciendo pero la caja no. */
  .unete .hero__title { font-size: min(5.2rem, 5.8vw); }
}
.unete__cta { margin: clamp(1.5rem, 3vw, 2.25rem) 0 0; }
/* Dos botones, uno por país. En fila mientras quepan y apilados cuando no:
   `flex-wrap` basta, no hace falta un corte por ancho de ventana porque lo que
   manda aquí es el ancho de la columna del hero, que cambia con el acomodo. */
.unete__botones {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(.6rem, 1.2vw, 1rem);
}
/* El icono de WhatsApp va DELANTE del texto y la flecha detrás, así que el
   botón tiene que ser flex para que los tres se alineen por su centro. */
.btn__wa {
  flex: none;
  width: 1.15em;
  height: 1.15em;
  margin-right: -.1em;
}

/* La foto es un RECORTE con transparencia real, así que va suelta sobre el
   fondo como en la referencia: sin marco, sin filo y sin esquinas redondeadas.
   Un recuadro aquí devolvería el problema que acabamos de quitar del sitio: un
   canto que interrumpe la malla. */
.unete__foto {
  margin: 0;
  position: relative;
  /* Sangra por la derecha hasta el borde de la ventana. En una ventana muy
     ancha el `.wrap` se topa con `--maxw`, así que además del relleno hay que
     recuperar la mitad del sobrante; el `max` deja el valor en el relleno
     cuando no hay sobrante y nunca en negativo. */
  margin-right: calc(-1 * max(var(--pad-x), (100vw - var(--maxw)) / 2 + var(--pad-x)));
}
/* El recorte es limpio por arriba y por los lados —alfa 0 en las esquinas
   altas— pero por abajo NO: la mesa llega hasta el borde del lienzo y termina
   en un canto recto (alfa 219 en las esquinas bajas). Sobre el fondo oscuro
   eso se lee como una banda clara cortada con tijera. La máscara la disuelve
   en el último 16 %, que es justo donde está la mesa y no toca ni las manos ni
   la taza. */
.unete__foto img {
  width: 100%;
  height: auto;
  -webkit-mask-image: linear-gradient(to bottom, #000 84%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 84%, transparent 100%);
}

/* Los tres pilares al pie de la columna, sin caja: en la referencia son
   icono + nombre + frase sueltos sobre el fondo, no tarjetas. */
.pilares {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: clamp(1.75rem, 3.5vw, 3rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  list-style: none;
}
/* Sueltos sobre el fondo no se sostenían: justo detrás corre la malla, que es
   una trama de líneas ámbar, y los tres bloques —icono ámbar, nombre y frase
   gris— competían con ella en el mismo color y perdían. Con superficie propia
   se despegan del fondo y se leen como un grupo.
   El filete y el radio son los de la tarjeta del sitio, pero SIN el
   desplazamiento al pasar el cursor que llevan las del semillero: aquí son
   tres piezas de lectura, no cuatro tarjetas navegables, y a cuatro dedos de
   distancia la repetición del gesto cansaría. */
.pilar {
  padding: clamp(1.15rem, 2.4vh, 1.6rem);
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  transition: border-color .4s var(--ease);
}
.pilar:hover { border-color: rgba(242, 176, 47, .28); }

.pilar__icono {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: rgba(242, 176, 47, .18);
  color: var(--amber);
}
.pilar__icono svg { width: 1.75rem; height: 1.75rem; }

/* El nombre va en ámbar. Es el mismo papel que hace el ámbar en las cifras del
   Home: marcar el dato que se quiere que salte a la vista. Aquí además resuelve
   el problema de fondo —tres bloques todos en gris sobre una malla ámbar no
   destacaban—, porque le da al ojo un ancla de color por pieza. */
.pilar__nombre {
  margin: 0 0 .5rem;
  font-size: clamp(1.15rem, 1.45vw, 1.4rem);
  font-weight: 600;
  line-height: 1.25;
  color: var(--amber);
}
.pilar__texto { margin: 0; font-size: 1rem; line-height: 1.55; color: var(--texto-suave); }

/* ---- Semillero: cuatro pasos en escalera ----
   En la referencia las cuatro tarjetas van escalonadas en altura, unidas por
   una línea de puntos. La escalera se conserva con un desplazamiento por
   columna; la línea no, porque solo funciona con las cuatro en fila y aquí se
   reordenan en pantallas menores. */
.pasos {
  /* El hueco vive en una variable porque las flechas que unen las piezas se
     colocan justo en él: si cambia uno, cambia la otra sin tocar dos sitios. */
  /* El hueco es también el ancho de la flecha, así que tira en dos direcciones:
     más hueco es flecha más visible, pero también columnas más estrechas, y con
     columnas más estrechas el texto largo de la pieza 04 gana líneas y ESTIRA
     las cuatro cajas. A 3vw las dejaba en 389 px contra los 362 de partida. */
  --hueco-pasos: clamp(1.25rem, 2.5vw, 1.75rem);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: var(--hueco-pasos);
  /* Las cuatro iguales: mismo alto y alineadas arriba. La rejilla las estira
     sola, así que basta con NO poner `align-items: start`. */
  margin: 0;
  padding: 0;
  list-style: none;
}
.paso {
  position: relative;
  padding: clamp(1.4rem, 2.6vw, 2rem);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  background: var(--fondo-2);
  transition: border-color .4s var(--ease), transform .4s var(--ease);
}
.paso:hover { border-color: rgba(242, 176, 47, .3); transform: translateY(-4px); }
.paso__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  font-weight: 700;
  line-height: 1;
  color: var(--amber);
}
.paso__icono {
  position: absolute;
  top: clamp(1.4rem, 2.6vw, 2rem);
  right: clamp(1.4rem, 2.6vw, 2rem);
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 50%;
  background: rgba(242, 176, 47, .12);
  color: var(--amber);
}
.paso__icono svg { width: 1.3rem; height: 1.3rem; }
/* Vuelve al cuerpo de texto normal. Subirlo en las cuatro alargaba las cajas
   —de 362 a 436 px— porque la altura de la fila la marca la pieza 04, que es la
   del texto largo, y eso no era lo que se pedía. */
.paso__texto {
  margin: clamp(1.1rem, 2vw, 1.5rem) 0 0;
  line-height: 1.55;
  color: var(--texto-suave);
}
.paso__texto strong { color: var(--texto); font-weight: 600; }

/* La frase que abre la serie sí crece: es el enunciado del que cuelgan las
   otras tres. Con la escalera, ojo, ya no sale gratis: la 01 es el escalón más
   bajo y su texto puede ser el que marque el alto de las filas —en ventana baja
   lo es—, así que agrandarla sube la escalera entera. */
.paso__texto--clave {
  font-size: clamp(1.2rem, 1rem + .55vw, 1.5rem);
  line-height: 1.35;
}

/* --------------------------------------------------------------------------
   La escalera

   Las cuatro piezas iban a la misma altura, la de la 04, que es la del texto
   largo, y la 01 quedaba casi media caja vacía: 175 px de 358. Pero el texto
   CRECE de la 01 a la 04, así que la escalera sale casi sola: basta con que
   cada pieza mida lo que necesita y todas se apoyen en la misma base. Y encaja
   con lo que cuenta la sección —empiezas en una posición, avanzas, los líderes
   de hoy empezaron en operación—.

   Casi sola: soltadas a su contenido suben a saltos desiguales —+15, +53 y
   +107 px— y eso se lee como el desnivel que se quitó en su día, no como una
   escalera. Así que los escalones son IGUALES, y los pone la rejilla: siete
   filas de `1fr` y cada pieza abarca una fila más que la anterior —4, 5, 6 y
   7—, todas hasta la última línea. En una rejilla de alto automático, las
   filas `1fr` miden lo que pide el contenido más exigente repartido entre las
   filas que ocupa, así que el texto cabe siempre y el escalón se ajusta solo a
   cualquier tamaño. `row-gap: 0` para que un escalón sea exactamente una fila.

   Medido a 1440 × 900: 205 · 256 · 307 · 358 px, escalones de 51, y la 04 se
   queda en los 358 de antes, así que la sección no crece. En ventana baja la
   fila la marca la 01 y la 04 gana algo: a 660 de alto, de 267 a 284 px, con
   63 px de aire todavía.

   Las flechas suben con la escalera sin tocarlas, porque cada una sale del
   centro de su pieza. Y todo esto solo desde 1100 px, que es cuando van las
   cuatro en fila: en dos columnas una escalera no tiene sentido.
   -------------------------------------------------------------------------- */
@media (min-width: 1100px) {
  .pasos { grid-template-rows: repeat(7, 1fr); row-gap: 0; }
  .pasos .paso:nth-child(1) { grid-column: 1; grid-row: 4 / 8; }
  .pasos .paso:nth-child(2) { grid-column: 2; grid-row: 3 / 8; }
  .pasos .paso:nth-child(3) { grid-column: 3; grid-row: 2 / 8; }
  .pasos .paso:nth-child(4) { grid-column: 4; grid-row: 1 / 8; }
}

/* La flecha que enlaza una pieza con la siguiente. Es un elemento de la
   referencia —allí una línea de puntos— que se había descartado mientras las
   piezas iban en escalera, porque una línea recta no unía nada; a nivel y en
   fila sí funciona. Se dibuja DENTRO del hueco de la rejilla, así que no roba
   sitio a ninguna caja. */
.paso__enlace {
  position: absolute;
  top: 50%;
  left: 100%;
  width: var(--hueco-pasos);
  transform: translateY(-50%);
  display: none;
  /* Ámbar pleno y con halo. La primera versión iba de puntos y al 55 % de
     opacidad, y sobre el fondo oscuro —con la malla ámbar corriendo por
     detrás— sencillamente no se veía: competía con las líneas del fondo en el
     mismo color y con menos fuerza. */
  color: var(--amber);
  filter: drop-shadow(0 0 7px rgba(242, 176, 47, .45));
}
.paso__enlace svg { display: block; width: 100%; height: auto; }

@media (min-width: 1100px) {
  /* Cuatro columnas fijas. Con el `auto-fit` la fila se parte en dos a ciertos
     anchos y la flecha de la segunda pieza apuntaría al vacío; las flechas solo
     se encienden donde hay de verdad cuatro en fila. */
  .pasos { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .paso__enlace { display: block; }
}

/* La luz recorre las cuatro piezas, una tras otra. Va en un pseudoelemento y no
   en el borde de la propia pieza por una razón concreta: una animación gana a
   cualquier declaración normal, así que animar `border-color` aquí dejaría el
   `:hover` sin efecto. Con el filete de luz en una capa aparte, las dos cosas
   conviven: el borde reacciona al cursor y la luz sigue su ronda. */
.paso::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  pointer-events: none;
  animation: paso-luz 6.4s var(--ease) infinite;
}
.pasos .paso:nth-child(1)::after { animation-delay: 0s;   }
.pasos .paso:nth-child(2)::after { animation-delay: 1.6s; }
.pasos .paso:nth-child(3)::after { animation-delay: 3.2s; }
.pasos .paso:nth-child(4)::after { animation-delay: 4.8s; }

/* Encendido y apagado suaves dentro del primer cuarto del ciclo; el resto del
   tiempo la pieza está apagada, esperando su turno. */
@keyframes paso-luz {
  0%, 30%, 100% { border-color: transparent; box-shadow: none; }
  8%, 20% {
    border-color: rgba(242, 176, 47, .62);
    box-shadow: 0 0 0 1px rgba(242, 176, 47, .16), 0 0 30px -8px rgba(242, 176, 47, .5);
  }
}

/* ---- Los sites, en vídeo ----
   Dos mosaicos que abren un recorrido en YouTube. Son enlaces, no vídeos
   incrustados: el porqué está en el marcado de la página.

   La rejilla es la de siempre, `auto-fit` con un mínimo: dos columnas donde
   caben y una sola cuando no, sin una consulta de medios propia. */
/* LOS CUADROS NO OCUPAN TODO EL ANCHO, y es a petición del cliente: a lo ancho
   del `wrap` cada uno medía 622 px y pesaban más que el encabezado que los
   presenta. Con el tope van a 356 y se leen como lo que son, dos accesos, no
   como el contenido principal de la sección. El tope va aquí y no en un ancho
   por tarjeta para que sigan repartiéndose el sitio solas. */
.sites {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(1.25rem, 3vw, 2.25rem);
  max-width: 47rem;
  margin-top: clamp(2rem, 4vw, 3.25rem);
}
.site {
  display: block;
  color: inherit;
}
/* El recorte lleva la proporción del vídeo, así que la miniatura entra justa y
   las dos piezas miden lo mismo aunque sus archivos no: la de México sale de
   una miniatura de 640 y la de Ecuador de una de 1120. */
.site__medio {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--fondo-2);
  border: 1px solid var(--linea);
}
.site__medio img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .6s var(--ease);
}
.site:hover .site__medio img { transform: scale(1.04); }

/* El botón de reproducir. Va centrado con `inset: 0` y `place-items`, no con
   `top: 50%` y una traslación: así no hay un `transform` que estorbe al de la
   imagen ni que abra un contexto de apilado de más. */
.site__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.site__play svg {
  width: clamp(3.4rem, 7vw, 4.4rem);
  height: auto;
  padding: clamp(.9rem, 1.9vw, 1.2rem);
  border-radius: 50%;
  background: rgba(10, 9, 13, .55);
  border: 1px solid rgba(255, 255, 255, .35);
  color: #fff;
  /* El triángulo está dibujado desde su punta izquierda, así que dentro del
     círculo pesa a la izquierda. Dos píxeles lo devuelven al centro óptico. */
  transform: translateX(2px);
  transition: background-color .35s var(--ease), border-color .35s var(--ease), color .35s var(--ease);
}
.site:hover .site__play svg {
  background: var(--amber);
  border-color: var(--amber);
  color: #0A090D;
}
.site:focus-visible .site__medio { outline: 2px solid var(--amber); outline-offset: 4px; }

/* EL RÓTULO VA ENCIMA DEL CUADRO, no debajo. Lo pidió el cliente: debajo se
   leía como un pie de foto —algo que explica lo que ya has visto— y arriba es
   lo que es, el nombre de lo que vas a abrir. */
.site__rotulo {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin-bottom: clamp(.7rem, 1.4vw, .95rem);
}
/* La bandera, con el mismo tratamiento que en el pie de página: recortada en
   pastilla y con un filete que la despega del fondo oscuro. */
.site__bandera {
  flex: none;
  width: 1.9rem;
  aspect-ratio: 3 / 2;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid var(--linea);
}
.site__bandera img { display: block; width: 100%; height: 100%; object-fit: cover; }
.site__nombre {
  font-family: var(--font-display);
  font-size: var(--t-lead);
  font-weight: 600;
  letter-spacing: -.01em;
  transition: color .25s var(--ease);
}
.site:hover .site__nombre { color: var(--amber); }

/* ---- Canty ---- */
.canty {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
}
.canty h2 { margin: .75rem 0 0; }

/* Los dos párrafos de la sección son del mismo rango y van al mismo nivel, pero
   ese nivel es el del SITIO —`.lead`, que los dos llevan puesto en el marcado—,
   no uno propio. El problema original era real: el cierre iba al cuerpo de
   texto normal y leído detrás de la entradilla parecía una nota al pie. La
   respuesta no era subir los dos por encima de la escala, sino poner los dos en
   el mismo peldaño de la escala que ya existe. */
.canty .lead { margin-top: clamp(1rem, 2vw, 1.5rem); }
.canty__cierre { margin: clamp(1.5rem, 3vw, 2rem) 0 0; }

.rasgos {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin: clamp(1.5rem, 3vw, 2rem) 0 0;
  padding: 0;
  list-style: none;
}
.rasgo {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem 1rem .5rem .75rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  /* Al cuerpo de texto del sitio. Tenía una medida propia que subió cuando
     subieron los párrafos; al volver estos a la escala, la excepción sobra. */
  font-size: var(--t-body);
  font-weight: 500;
}
.rasgo svg { width: 1.1rem; height: 1.1rem; color: var(--amber); display: block; }

/* La ilustración es ahora un RECORTE con transparencia real, así que va suelta
   sobre el fondo. Antes venía sobre fondo blanco y había que disolverla con una
   máscara radial —un apaño, porque un recorte por umbral se habría comido el
   pelo, que es casi todo borde suave—. Con el archivo bueno esa máscara sobra. */
.canty__figura { margin: 0; position: relative; }
.canty__figura img { width: 100%; height: auto; }

/* LA IMAGEN QUIETA ES LA DEL MÓVIL, y el vídeo la de escritorio. Se reparten
   abajo, en el bloque de pantallas pequeñas; aquí solo se declara que de
   entrada manda el vídeo. El porqué está en el marcado de la página: el Safari
   del iPhone no mezcla un <video> con lo que tiene detrás, y sin mezcla el
   fondo de plató es un rectángulo blanco. La imagen lleva alfa de verdad y no
   depende de nadie. */
.canty__quieta { display: none; }

/* El vídeo ocupa el mismo hueco que ocupaba el recorte —literalmente el mismo:
   la proporción es la del PNG, 760x726, así que la sección no cambia ni un
   píxel de alto—, y por dos razones hay que tratarlo distinto. La primera:
   viene en 16:9 y el hueco es casi cuadrado. Medido a lo largo de los diez
   segundos, el personaje nunca sale del 31 % al 68 % del ancho, así que el
   recorte por el centro —que empieza en el 20,5 %— lo contiene entero y aún
   sobra margen por los dos lados. La segunda: el fondo es un plató gris, no
   transparente, y la sección tampoco es blanca lisa: lleva la malla detrás. Un
   vídeo opaco la tapa y se ve el recuadro, cosa que el PNG no hacía porque su
   alfa dejaba pasar la rejilla.
   Se arregla multiplicando, no recortando. Multiplicar por blanco no cambia
   nada, así que todo lo que sea blanco puro desaparece y la malla sigue de
   largo; el personaje, que es oscuro, se queda. Para eso el fondo tiene que
   llegar a blanco DE VERDAD.

   EL 1,16 NO LLEGABA, Y EN EL MÓVIL SE VEÍA. El cliente avisó el 12 de octubre
   de 2026: en el teléfono la mascota salía dentro de un cuadro blanco con el
   borde a la vista. Medido sobre seis momentos del vídeo, el píxel más oscuro
   del marco con `brightness(1.16)` se quedaba en **248**: un 2,7 % de gris que
   en un monitor no se aprecia y en una pantalla de teléfono —más contraste,
   otra gamma— se lee como un recuadro. Con **1,22 el marco entero es 255
   exacto**, comprobado píxel a píxel, y entonces el `multiply` lo borra del
   todo. El personaje aguanta el empujón: su ámbar más vivo pasa de #feac25 a
   #ffa41a, que sigue siendo el de la marca, y los ojos siguen negros.

   Y EL BORDE SE DIFUMINA, que es lo que pidió el cliente: una máscara apaga el
   vídeo contra sus cuatro lados, así que aunque el `multiply` falle —en Safari
   de iPhone la mezcla sobre un <video> no es de fiar, el vídeo se compone en su
   propia capa— no hay un rectángulo con filo, sino algo que se deshace en el
   blanco. Los números no son a ojo: con `object-fit: cover` la ventana visible
   es el 58,9 % central del vídeo, y dentro de la caja Canty ocupa de 16,4 % a
   82,4 % a lo ancho y de 12,2 % a 90,8 % a lo alto —medido en seis momentos—.
   El velado entra por 13 % y 86 % a los lados y por 9 % y 94 % arriba y abajo:
   siempre por fuera del personaje, nunca se le come un píxel. */
.canty__figura video {
  display: block;
  width: 100%;
  /* `height: auto` no es decorativo: el atributo height="720" del HTML llega
     como altura declarada y le gana a aspect-ratio. Sin esta línea la caja
     sale de 538x720 en vez de 538x514. */
  height: auto;
  aspect-ratio: 760 / 726;
  object-fit: cover;
  filter: brightness(1.22) contrast(1.05);
  mix-blend-mode: multiply;
  /* Dos degradados que se cruzan. `intersect` es la sintaxis nueva y
     `source-in` la de WebKit; si un navegador no entendiera ninguna de las dos
     se quedaría en `add`, que es la unión: no habría velado, pero tampoco se
     rompería nada. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 13%, #000 86%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 9%, #000 94%, transparent 100%);
          mask-image:
    linear-gradient(90deg, transparent 0, #000 13%, #000 86%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 9%, #000 94%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}

/* Las notas al margen de la referencia. Cursiva ámbar en vez de manuscrita,
   por la regla de las dos tipografías. */
.unete__nota,
.canty__nota {
  margin-top: 1rem;
  font-style: italic;
  /* Sube al nivel de la entradilla: estaba a 17,6 px cuando el párrafo de al
     lado va a 21,6, y una nota más pequeña que todo lo demás en una ventana
     ancha se lee como un pie de foto perdido. */
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--amber);
  text-align: center;
}

@media (max-width: 900px) {
  .unete__rejilla, .canty { grid-template-columns: 1fr; }
  /* LA FOTO VA DEBAJO DEL TEXTO, no encima. Llevaba `order: -1` de cuando esta
     portada se apilaba como las demás —la imagen primero, a modo de cabecera—,
     pero aquí la imagen no es la portada: la portada es el titular «Únete al
     equipo CANTEC» con sus dos botones de vacantes. Con la foto delante había
     que bajar media pantalla para saber de qué iba la página, y lo primero que
     se leía era el pie en cursiva de la imagen. Ahora manda el orden del HTML,
     que ya es el de lectura. */
  .unete__foto { order: 0; }
  .paso__icono { position: static; margin-top: .75rem; }
}

/* ---- Los tres valores ----
   La referencia del cliente marcaba cada valor con un punto de color distinto
   —verde, ámbar y azul—. Aquí van los tres en ámbar: es el único acento del
   sitio y meter dos colores más solo para esta tarjeta rompería esa regla en la
   única página donde aparecen. El orden ya lo dice la numeración. */
.valores { list-style: none; margin: 0; padding: 0; }

/* El icono va en la MISMA fila que el r&oacute;tulo, no en una esquina absoluta.
   Puesto con `position: absolute` habr&iacute;a que repetir el relleno de `.card`
   —clamp(1.5rem, 3vw, 2.25rem)— para separarlo del borde, y esa f&oacute;rmula
   duplicada es justo el fallo que ya cost&oacute; 11 px en la curva de misi&oacute;n y
   visi&oacute;n. En la fila no hay ninguna medida que copiar: el relleno de la
   tarjeta lo pone la tarjeta y el icono cae solo arriba a la derecha. */
.valor__cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.valor__idx {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--texto-suave);
}
.valor__idx::before {
  content: "";
  width: .45rem;
  height: .45rem;
  border-radius: 50%;
  background: var(--amber);
  flex: none;
}
.section--light .valor__idx::before,
.section--paper .valor__idx::before { background: var(--amber-deep); }
.section--light .valor__idx,
.section--paper .valor__idx { color: var(--texto-contra-suave); }

/* Los tres iconos son de l&iacute;nea y sin disco detr&aacute;s: el disco ya lo lleva el
   punto del r&oacute;tulo, y dos redondeles seguidos en la misma fila compiten. */
.valor__icono {
  flex: none;
  width: clamp(1.55rem, 2.1vw, 1.9rem);
  height: auto;
  color: var(--amber);
  opacity: .55;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.section--light .valor__icono,
.section--paper .valor__icono { color: var(--amber-deep); }

/* El filete bajo el nombre viene de la referencia y hace un trabajo real:
   separa el nombre del valor de su explicación sin gastar un hueco grande. */
.valor__nombre {
  margin: clamp(.7rem, 1.4vw, 1rem) 0 0;
  padding-bottom: clamp(.7rem, 1.4vw, 1rem);
  border-bottom: 1px solid var(--linea);
  font-size: clamp(1.3rem, 1.7vw, 1.65rem);
  font-weight: 600;
  letter-spacing: -.02em;
}
.section--light .valor__nombre,
.section--paper .valor__nombre { border-bottom-color: var(--linea-contra); }

.valor__texto {
  margin: clamp(.9rem, 1.8vw, 1.25rem) 0 0;
  color: var(--texto-suave);
  line-height: 1.6;
}
.section--light .valor__texto,
.section--paper .valor__texto { color: var(--texto-contra-suave); }

/* ---- El guion de la escena de los valores ---------------------------------
   La sección se cuenta en seis tiempos, los del guion del cliente:

     0,0  el encabezado sube y su filete ámbar se dibuja
     0,8  el velo se retira hacia la derecha y aparece la malla del fondo
     1,5  entra Lealtad, con un resplandor
     2,5  entra Honestidad
     3,5  entra Resultados y se traza la onda que enlaza los tres
     4,5  empieza el bucle: la luz recorre la onda y cada valor reacciona

   UN SOLO RELOJ. El `data-secuencia` va en el <section>, así que el observador
   le pone `is-visible` una vez y los seis tiempos cuelgan de ese instante con
   su retardo. Con un `.reveal` por pieza —como estaba— cada una arrancaba
   cuando ella misma entraba en pantalla y el orden del guion no se podía
   garantizar: el encabezado iba primero por estar más arriba, pero las tres
   tarjetas entraban casi a la vez.

   LA MALLA NO SE DIBUJA, SE DESTAPA. El fondo del sitio ya es una malla de
   ondas en perspectiva, en un lienzo fijo y ya en movimiento; el tiempo 2 del
   guion es exactamente eso apareciendo. Pintar otra malla aquí habría sido
   dibujar encima de la que hay.

   Los segundos de arriba son los del guion TAL CUAL y se multiplican por
   `--compas`. A 1 la escena dura los 6 s del papel; a .62 dura 3,7 y mantiene
   las mismas proporciones, que es lo que pide una sección a la que se llega
   con el scroll y no un vídeo que se mira desde el principio. Un número, y el
   guion entero se estira o se aprieta. Las DURACIONES no se tocan: lo que se
   comprime es el tiempo entre golpes, no el golpe. */
.escena-valores {
  --compas: .62;
  --ciclo: 9s;                          /* la vuelta completa del bucle */
  --bucle: calc(4.5s * var(--compas));  /* cuándo empieza el bucle */
  --onda-alto: clamp(2rem, 4.5vh, 3.25rem);
}

/* Tiempo 1 — el encabezado.
   El filete del titular no lleva código nuevo: `.is-visible .hl` ya dibujaba el
   subrayado ámbar, y ahora quien recibe `is-visible` es la sección entera. */
.escena-valores .cabecera { opacity: 0; }
.escena-valores.is-visible .cabecera { animation: valores-sube .8s var(--ease) both; }
@keyframes valores-sube {
  from { opacity: 0; translate: 0 22px; }
  to   { opacity: 1; translate: none; }
}

/* Tiempo 2 — el velo.
   Viaja en `background-position` y NO desplazando la caja. Una caja más ancha
   que la sección y empujada hacia fuera saca barra horizontal en móvil, donde
   `.pantalla` no recorta: su `overflow: hidden` solo existe dentro del salto
   por pantallas. Con el degradado a 300 % de ancho, la ventana que se ve es un
   tercio del dibujo: a 100 % cae en el tercio opaco y a 0 % en el transparente,
   y el paso de uno a otro es el barrido. */
.valores__velo {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: linear-gradient(90deg, rgba(8,7,10,0) 0 33%, var(--fondo) 50% 100%);
  background-size: 300% 100%;
  background-repeat: no-repeat;
  background-position: 100% 0;
}
/* La ÚNICA pieza de la escena que no usa `--ease`. Esa curva —expo-out— gasta
   el 95 % del recorrido en el primer 40 % del tiempo: la malla no se formaba,
   aparecía de golpe y luego el velo se quedaba quieto en el borde. Medido: a
   los 430 ms de los 950 ya estaba al 5 %. Una cortina necesita velocidad
   pareja, y con `ease-in-out` el frente destapa el tercio de cada tarjeta
   siempre ANTES de que esa tarjeta entre: 829 ms la primera contra 930 de su
   entrada, 971 contra 1550 y 1180 contra 2170. */
.escena-valores.is-visible .valores__velo {
  animation: valores-velo .95s ease-in-out calc(.8s * var(--compas)) both;
}
@keyframes valores-velo {
  from { background-position: 100% 0; }
  to   { background-position: 0% 0; }
}
/* El contenido, por delante del velo. Sin esto el velo taparía el titular: un
   elemento posicionado, aunque vaya a z-index 0, se pinta DESPUÉS de todos los
   bloques en flujo. */
.escena-valores .wrap { position: relative; z-index: 1; }

/* Tiempos 3, 4 y 5 — las tarjetas.
   Entran con `translate` y no con `transform`, y la razón es concreta: la
   animación lleva `both`, o sea que se queda fijando lo que anima, y `.card`
   levanta la tarjeta con `transform` en el `:hover`. Animando `transform` estas
   tres tarjetas se quedaban SIN hover para siempre. `translate` es una
   propiedad independiente: se compone con el `transform` del hover y conviven. */
.escena-valores .valor { opacity: 0; }
.escena-valores.is-visible .valor { animation: valor-entra .8s var(--ease) var(--t) both; }
@keyframes valor-entra {
  from { opacity: 0; translate: 0 26px; }
  to   { opacity: 1; translate: none; }
}

/* El resplandor de la entrada va en un pseudo aparte por lo mismo: una
   `box-shadow` animada con `both` se quedaría fija y se comería la sombra del
   `:hover` de las secciones claras. */
.valor::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 0 1px rgba(242,176,47,.45), 0 18px 50px -14px rgba(242,176,47,.5);
}
.escena-valores.is-visible .valor::before { animation: valor-destello 1.1s var(--ease) var(--t) both; }
@keyframes valor-destello {
  0%   { opacity: 0; }
  35%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Cada valor tiene DOS tiempos: `--t`, cuándo entra, y `--fase`, el momento del
   bucle en que la luz pasa por su nodo.

   LA FASE NO ES A OJO. La onda son seis tramos congruentes —un nodo cada 200
   unidades de las 1200 del dibujo—, así que el destello, que avanza a longitud
   de trazado constante, recorre un sexto de la onda en un sexto del ciclo y
   llega a los nodos de las tres tarjetas a 1/6, 3/6 y 5/6 de la vuelta. Cada
   índice declara su fase UNA vez y la leen la tarjeta y su punto. */
.escena-valores .valor:nth-child(1),
.escena-valores .valores__nodos i:nth-child(1) { --fase: calc(var(--ciclo) / 6); }
.escena-valores .valor:nth-child(2),
.escena-valores .valores__nodos i:nth-child(2) { --fase: calc(var(--ciclo) / 2); }
.escena-valores .valor:nth-child(3),
.escena-valores .valores__nodos i:nth-child(3) { --fase: calc(var(--ciclo) * 5 / 6); }

.escena-valores .valor:nth-child(1) { --t: calc(1.5s * var(--compas)); }
.escena-valores .valor:nth-child(2) { --t: calc(2.5s * var(--compas)); }
.escena-valores .valor:nth-child(3) { --t: calc(3.5s * var(--compas)); }

/* Tiempo 6 — la reacción de la tarjeta al paso de la luz: un barrido por su
   borde de arriba. Va metido el radio por cada lado para no asomar por las
   esquinas redondeadas. Cruza la tarjeta en un 16 % del ciclo —1,44 s— y sale
   0,72 s ANTES de que la luz llegue al nodo, de modo que va por la mitad de la
   tarjeta justo cuando el destello pasa por encima. */
.valor::after {
  content: "";
  position: absolute;
  top: -1px;
  left: var(--radius); right: var(--radius);
  height: 2px;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent, rgba(242,176,47,.85) 42%, rgba(255,225,160,1) 50%, rgba(242,176,47,.85) 58%, transparent) no-repeat;
  background-size: 42% 100%;
  background-position: -45% 0;
  filter: drop-shadow(0 0 6px rgba(242,176,47,.55));
}
.escena-valores.is-visible .valor::after {
  animation: valor-barrido var(--ciclo) linear calc(var(--bucle) + var(--fase) - .72s) infinite;
}
@keyframes valor-barrido {
  0%   { background-position: -45% 0; }
  16%  { background-position: 145% 0; }
  100% { background-position: 145% 0; }
}

/* El punto del rótulo y el icono se encienden a la vez, al paso de la luz. El
   icono crece con `scale`, otra propiedad independiente, así que no pisa nada. */
.escena-valores.is-visible .valor__idx::before {
  animation: valor-punto var(--ciclo) var(--ease) calc(var(--bucle) + var(--fase) - .36s) infinite;
}
@keyframes valor-punto {
  0%, 26%, 100% { box-shadow: 0 0 0 0 rgba(242,176,47,0); }
  4%  { box-shadow: 0 0 0 4px rgba(242,176,47,.18), 0 0 14px 2px rgba(242,176,47,.55); }
  18% { box-shadow: 0 0 0 7px rgba(242,176,47,0),   0 0 14px 2px rgba(242,176,47,0); }
}
.escena-valores.is-visible .valor__icono {
  animation: valor-icono var(--ciclo) var(--ease) calc(var(--bucle) + var(--fase) - .36s) infinite;
}
@keyframes valor-icono {
  0%, 14%, 100% { opacity: .55; scale: 1; }
  4%            { opacity: 1;   scale: 1.14; }
}

/* ---- La onda que enlaza los tres valores ----
   Solo cuando hay tres columnas de verdad: apilada, una línea horizontal no
   une nada. El corte es el mismo que usaba el hilo recto y no es a ojo: la
   rejilla pasa a tres columnas cuando mide 880 px —`minmax(280px, 1fr)` por
   tres más dos huecos de 20— y mide un 88 % del ancho de ventana, así que eso
   ocurre a partir de 1000 px. Medido: a 980 hay dos columnas, a 1040 hay tres.
   Se toma 1024 para entrar con margen.

   La onda va ARRIBA de las tarjetas y no a la altura de su borde: entre tres
   tarjetas solo hay dos huecos de 20 px, y una línea que pasara por detrás se
   vería en 40 px de los 1200. El sitio se lo da `.valores__campo` con su
   relleno de arriba, así que la onda nunca se come el aire del encabezado. */
.valores__campo { position: relative; }
.valores__onda,
.valores__nodos { display: none; }

@media (min-width: 1024px) {
  .valores__campo { padding-top: var(--onda-alto); }

  .valores__onda,
  .valores__nodos {
    display: block;
    position: absolute;
    top: 0; left: 0; right: 0;
    height: var(--onda-alto);
    color: var(--amber);
    pointer-events: none;
  }
  /* Los dos extremos se apagan: así la onda no choca de canto con el borde de
     las tarjetas y, de paso, el destello entra y sale sin dar el salto de la
     vuelta. */
  .valores__onda {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
            mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  }
  .valores__onda path { stroke: currentColor; }

  /* Se dibuja sola en el tiempo 5. `pathLength="1"` normaliza el trazado, así
     que un solo valor de `stroke-dashoffset` vale para cualquier ancho. */
  /* Sube a 1,2 px y a .45 de opacidad —no a .3 y 1 px, que es lo primero que
     se probó— porque detrás pasa la malla del fondo con hilos del mismo color
     y a un grueso parecido: a .3 la onda no se leía como una línea puesta a
     propósito, se confundía con el fondo. */
  .valores__onda-base {
    stroke-width: 1.2;
    opacity: .45;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  .escena-valores.is-visible .valores__onda-base {
    animation: onda-traza 1.2s var(--ease) calc(3.5s * var(--compas)) both;
  }

  /* El destello del bucle. El guion de rayas mide 0,05 + 0,95 = 1, o sea
     exactamente el trazado: solo hay una raya a la vista y, cuando sale por la
     derecha, la siguiente entra por la izquierda en el mismo fotograma. El
     bucle no tiene costura. */
  .valores__onda-luz {
    stroke-width: 2;
    stroke-linecap: round;
    stroke-dasharray: .05 .95;
    stroke-dashoffset: 0;
    opacity: 0;
    filter: drop-shadow(0 0 5px rgba(242,176,47,.65));
  }
  .escena-valores.is-visible .valores__onda-luz {
    animation: onda-luz var(--ciclo) linear var(--bucle) infinite;
  }

  /* Los tres puntos caen en los nodos de la onda: el dibujo cruza su eje a
     1/6, 3/6 y 5/6 del ancho, que es donde se colocan. Se centran con márgenes
     y no con `transform`, que es lo que ya rompió la curva de misión y visión
     cuando una animación lo anuló. */
  .valores__nodos i {
    position: absolute;
    top: calc(var(--onda-alto) / 2);
    width: 7px; height: 7px;
    margin: -3.5px 0 0 -3.5px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0;
  }
  .valores__nodos i:nth-child(1) { left: 16.6667%; }
  .valores__nodos i:nth-child(2) { left: 50%; }
  .valores__nodos i:nth-child(3) { left: 83.3333%; }
  .escena-valores.is-visible .valores__nodos i {
    animation: nodo-entra .5s var(--ease) calc(3.7s * var(--compas)) both,
               nodo-luz var(--ciclo) var(--ease) calc(var(--bucle) + var(--fase)) infinite;
  }
}
@keyframes onda-traza {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}
@keyframes onda-luz {
  from { stroke-dashoffset: 0;  opacity: 1; }
  to   { stroke-dashoffset: -1; opacity: 1; }
}
@keyframes nodo-entra {
  from { opacity: 0; }
  to   { opacity: .5; }
}
@keyframes nodo-luz {
  0%   { opacity: 1;  box-shadow: 0 0 0 0 rgba(242,176,47,.5), 0 0 12px 3px rgba(242,176,47,.75); }
  12%  { opacity: .5; box-shadow: 0 0 0 9px rgba(242,176,47,0), 0 0 12px 3px rgba(242,176,47,0); }
  12.01%, 100% { opacity: .5; box-shadow: none; }
}

.declaracion__titulo { margin: 0; }
.declaracion__titulo::after {
  content: "";
  display: block;
  width: 3.25rem;
  height: 3px;
  border-radius: 2px;
  background: var(--amber);
  margin: clamp(1rem, 2vw, 1.5rem) 0 clamp(1.25rem, 2.4vw, 1.75rem);
}
.section--light .declaracion__titulo::after,
.section--paper .declaracion__titulo::after { background: var(--amber-deep); }

/* Medida corta: son dos párrafos que se leen en paralelo, uno al lado del otro,
   y a la medida larga del `.lead` la vista pierde el renglón al saltar. */
.declaracion .lead { max-width: 46ch; }

/* Sobre blanco, las dos declaraciones sueltas en el vacío se leían pobres: dos
   columnas de texto y nada más. Con superficie propia el bloque tiene cuerpo y
   la sección deja de parecer una página a medio hacer. Solo en claro: sobre
   oscuro ya funcionaban sueltas, con la malla detrás dándoles fondo. */
.claro .declaracion {
  position: relative;
  z-index: 1;
  /* El valor lo pone `.declaraciones`; el de aquí es la red por si alguna vez
     se usa una declaración fuera de esa rejilla. */
  padding: var(--relleno-ficha, clamp(1.75rem, 3.2vw, 3rem));
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
}
.claro .declaracion__titulo::after { width: 4rem; height: 4px; }

/* Las palabras destacadas suben al blanco del texto principal. En el original
   el resaltado es solo de peso, pero sobre el gris del `.lead` la negrita sola
   apenas se distingue. */
.declaracion strong { color: var(--texto); font-weight: 600; }
.section--light .declaracion strong,
.section--paper .declaracion strong { color: var(--texto-contra); }

/* Igual en la bajada de la portada: la negrita sola no basta sobre el gris. */
.hero__lead strong { color: var(--texto); font-weight: 600; }

.card {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
  transition: border-color .4s var(--ease), transform .4s var(--ease), background .4s var(--ease);
  height: 100%;
}
.card:hover { border-color: rgba(242,176,47,.3); transform: translateY(-4px); }

.section--light .card, .section--paper .card {
  background: var(--contra);
  border-color: var(--linea-contra);
}
.section--light .card:hover, .section--paper .card:hover {
  border-color: rgba(200,139,20,.4);
  box-shadow: 0 18px 46px rgba(var(--velo), .09);
}

.card__icon {
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(242,176,47,.14);
  color: var(--amber);
  margin-bottom: 1.35rem;
}
.card__icon svg { width: 1.35rem; height: 1.35rem; }
.section--light .card__icon, .section--paper .card__icon {
  background: rgba(242,176,47,.2);
  color: var(--amber-deep);
}

.card__title { font-size: var(--t-h4); margin-bottom: .55rem; }
.card__text { font-size: .95rem; color: var(--texto-suave); margin: 0; }
.section--light .card__text, .section--paper .card__text { color: var(--texto-contra-suave); }

/* Bloque alternado imagen / texto */
.feature {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.feature + .feature { margin-top: clamp(3.5rem, 7vw, 7rem); }
.feature--reverse > :first-child { order: 2; }

/* --------------------------------------------------------------------------
   14. Paneles de país
   -------------------------------------------------------------------------- */
.countries {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: var(--gap);
}

.country {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(300px, 42vw, 420px);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
}
.country__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.country__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .8s var(--ease);
}
.country:hover .country__bg img { transform: scale(1.06); }
.country::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(var(--velo), .97) 20%, rgba(var(--velo), .78) 52%, rgba(var(--velo), .42));
}
.country__name {
  font-size: var(--t-h2);
  font-weight: 500;
  margin-bottom: .5rem;
  color: var(--sobre-img);
}
.country__meta {
  font-size: .92rem;
  color: var(--sobre-img-suave);
  margin-bottom: 1.5rem;
}

/* --------------------------------------------------------------------------
   15. Galería del equipo
   -------------------------------------------------------------------------- */
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: .875rem;
}
.gallery__item {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 3 / 4;
  background: var(--fondo-3);
}
.gallery__item img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .8s var(--ease), filter .5s var(--ease);
  filter: grayscale(.35);
}
.gallery__item:hover img { transform: scale(1.05); filter: grayscale(0); }
.gallery__item--wide { aspect-ratio: 3 / 2; grid-column: span 2; }

/* --------------------------------------------------------------------------
   16. Formulario
   -------------------------------------------------------------------------- */
/* La portada centrada de Contacto. El `max-width` del titular y de la bajada
   se anula y se reparte a los dos lados, que si no el texto queda centrado
   dentro de una caja que sigue pegada a la izquierda. */
.hero--centrado .hero__inner { text-align: center; }
.hero--centrado .hero__title,
.hero--centrado .hero__lead { margin-inline: auto; }
.hero--centrado .hero__lead { max-width: 52ch !important; }

/* ---- El marco del formulario de contacto ----
   El formulario es lo único que hay que hacer en esa página, así que va en el
   centro y con una medida de lectura. Antes ocupaba la mitad derecha de un
   `split` cuya mitad izquierda se quedó vacía al retirar los WhatsApp, y la
   página se leía descuadrada: todo contra un borde y un hueco al lado.

   SIN RELLENO: no es una tarjeta sobre el fondo, es el fondo de la página con
   un hilo de ámbar alrededor. La tarjeta gris tapaba la onda del `hero` y
   metía un segundo plano entre la página y el texto para no decir nada; el
   hilo delimita igual y no apaga nada de lo que hay detrás. Va al 45 %: por
   debajo de eso desaparece contra el negro, y por encima deja de ser un
   contorno para ser un recuadro amarillo. Queda un punto por encima del trazo
   de los campos —que es blanco al 22 %— para que el marco mande sobre ellos y
   no se confunda con un campo más.

   Desde el 8 de octubre de 2026 la sección es CLARA, así que lo que se ve es
   el valor de abajo, el de `.claro`. Este se queda por si el bloque vuelve a
   caer sobre oscuro: el marco sigue siendo correcto en las dos superficies. */
.contacto__caja {
  max-width: 52rem;
  margin-inline: auto;
  padding: clamp(1.5rem, 3.5vw, 3rem);
  border: 1px solid rgba(242, 176, 47, .45);
  border-radius: var(--radius);
}

/* --------------------------------------------------------------------------
   El formulario sobre blanco
   --------------------------------------------------------------------------
   La sección pasó a `.claro` y el remapeo de tokens hace casi todo solo: la
   tinta, los filetes, el fondo de los campos. Esto es la lista de lo que el
   remapeo NO puede arreglar, que es siempre lo mismo —los ámbares y los
   colores escritos a pelo— y cada línea lleva su medida.

   El hilo del marco: sobre negro iba a `rgba(ámbar, .45)`; sobre blanco ese
   mismo valor se aclara hasta rgb(249, 219, 161) y desaparece. Pasa al filo de
   tarjeta de la referencia, que es el que ya llevan las cartas de industria
   sobre blanco: ámbar, no gris.

   Y AQUÍ SÍ VUELVE EL RELLENO, pero opaco y del color de la sección: la malla
   ámbar atraviesa el blanco —es lo que da la luz de esta superficie— y pasaba
   también por DENTRO del formulario, con sus hilos cruzando los campos y el
   texto. Sobre el fondo oscuro no molestaba porque allí era la única textura;
   sobre blanco compite con lo que hay que leer. El relleno la corta en el
   borde del marco y la deja alrededor, que es donde se ve bien. No es la
   tarjeta de antes: aquel gris metía un plano intermedio, este es el mismo
   blanco de la sección y solo tapa la malla. */
.claro .contacto__caja {
  border-color: var(--linea-tarjeta);
  background: var(--fondo);
}

/* EL MARCADOR DE POSICIÓN ERA EL PROBLEMA GORDO. Heredaba `--texto-suave`, que
   sobre oscuro es un gris claro —se lee como lo que es, un ejemplo— pero en
   claro vale #3A3A45: 11,2:1, casi la misma tinta que el texto de verdad. Los
   siete campos parecían RELLENOS, y eso no es un matiz de estilo: quien entra
   duda de si tiene que borrar algo antes de escribir. Al 62 % de la tinta mide
   4,8:1 —pasa AA— y se distingue del valor escrito. */
.claro .field input::placeholder,
.claro .field textarea::placeholder { color: rgba(27, 27, 42, .62); }

/* El ámbar de marca como TEXTO mide 1,9:1 sobre blanco. El asterisco de
   obligatorio y el enlace de la nota legal pasan al tostado —5,8:1—, que es lo
   mismo que ya hace `.link-arrow`. Los ámbares de relleno no se tocan: el
   botón, la palomita y el fondo de la píldora marcada siguen siendo el de
   marca. */
.claro .field__label .req { color: var(--amber-deep); }
.claro .form__note a { color: var(--amber-deep); }

/* La flecha del desplegable va DIBUJADA EN EL FONDO, así que no hereda el
   color de nadie: hay que repetir el SVG con el trazo tostado. */
.claro .field select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A5D06' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}

/* El rojo de los errores está pensado para fondo oscuro: sobre blanco se queda
   en 2,3:1 y el mensaje que avisa de que falta algo es justo el que no se
   puede perder. El de claro mide 6,5:1. */
.claro .field__error { color: #B3261E; }
.claro .field.has-error input,
.claro .field.has-error textarea,
.claro .field.has-error select,
.claro .field.has-error .servicio { border-color: #B3261E; }
.claro .form-status.is-err { background: rgba(179, 38, 30, .08); border-color: rgba(179, 38, 30, .45); }

/* DOS COLUMNAS DENTRO DEL FORMULARIO, no una lista de siete campos en fila.
   Los cortos van de dos en dos —nombre con empresa, teléfono con país— y los
   que piden espacio ocupan el ancho entero. Siete campos apilados hacen una
   columna larguísima que obliga a desplazarse para ver el botón; emparejados,
   el formulario entra de una vez. */
.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.35rem clamp(1rem, 2vw, 1.6rem);
}
.form > .field--ancho,
.form > div:not(.field),
.form > p { grid-column: 1 / -1; }
@media (max-width: 620px) {
  .form { grid-template-columns: minmax(0, 1fr); }
}

.field { display: grid; gap: .5rem; }
.field__label {
  font-family: var(--font-display);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: .02em;
}
.field__label .req { color: var(--amber); }

/* Los campos tampoco se rellenan. Antes valían `--fondo-2`, el mismo color que
   la tarjeta: dentro de ella no se veían como cajas, solo como contornos. Al
   retirar la tarjeta ese relleno pasaba a ser MÁS CLARO que la página y los
   campos aparecían de pronto como siete bloques grises. Transparentes se leen
   igual que antes: el trazo y el texto. */
.field input, .field textarea, .field select {
  width: 100%;
  padding: .9rem 1.1rem;
  background: transparent;
  border: 1px solid var(--linea-fuerte);
  border-radius: var(--radius-s);
  color: var(--texto);
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.field input::placeholder, .field textarea::placeholder { color: var(--texto-suave); }
.field input:hover, .field textarea:hover { border-color: var(--linea-fuerte); }
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--amber);
  background: var(--fondo-3);
  box-shadow: var(--ring);
}
.field textarea { resize: vertical; min-height: 8rem; }

.field__error {
  font-size: var(--t-small);
  color: #FF8A80;
  display: none;
}
.field.has-error input, .field.has-error textarea, .field.has-error select { border-color: #FF8A80; }
.field.has-error .field__error { display: block; }
.field select:hover { border-color: var(--linea-fuerte); }
.field select:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px rgba(242, 176, 47, .18); }
/* El desplegable sin el gris del sistema: fondo y tinta del sitio, y la flecha
   dibujada aquí porque `appearance: none` se lleva también la del navegador. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F2B02F' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 1.1rem;
  cursor: pointer;
}
/* El `option` lo pinta el sistema y no se puede estilar en todos los
   navegadores; al menos no se queda en blanco sobre blanco. */
.field select option { background: var(--contra-2); color: var(--texto); }

/* ---- Servicios de interés: casillas pintadas como botones ----
   `appearance: none` sobre la casilla la deja sin dibujo pero VIVA: sigue
   recibiendo el foco, se marca con la barra espaciadora y viaja en el
   `FormData`. Lo que se ve es la etiqueta que la envuelve, y el `:checked` de
   la casilla manda sobre ella con `:has`. */
/* El `fieldset` viene con marco, relleno y márgenes propios del navegador, y
   `min-width: auto` metido en el agente de usuario, que es lo que impide que
   se encoja dentro de una rejilla. Se desarma entero: con el marco puesto, el
   grupo salía con un recuadro negro y su encabezado incrustado en el filo. */
.field--servicios { border: 0; padding: 0; margin: 0; min-width: 0; }
.field--servicios legend { padding: 0; }
.servicios { display: flex; flex-wrap: wrap; gap: .6rem; }
.servicio {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem 1.05rem;
  border: 1px solid var(--linea);
  border-radius: 999px;
  font-size: var(--t-body);
  font-weight: 500;
  color: var(--texto-suave);
  cursor: pointer;
  transition: border-color .3s var(--ease), color .3s var(--ease), background .3s var(--ease);
}
.servicio input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  border: 1px solid var(--linea-fuerte);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  transition: border-color .3s var(--ease), background .3s var(--ease);
}
.servicio:hover { border-color: var(--linea-fuerte); color: var(--texto); }
/* La palomita se dibuja con dos trazos del propio fondo, para no meter otro
   elemento dentro de la etiqueta. */
.servicio input:checked {
  border-color: var(--amber);
  background: var(--amber)
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230A0A0A' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E")
    center / .72rem no-repeat;
}
.servicio:has(input:checked) {
  border-color: var(--amber);
  background: rgba(242, 176, 47, .12);
  color: var(--texto);
}
/* El foco se dibuja sobre la ETIQUETA, no sobre la casilla: la casilla mide
   17 px y el anillo quedaba perdido dentro de la píldora. */
.servicio:has(input:focus-visible) {
  outline: 3px solid var(--amber);
  outline-offset: 3px;
}
/* Vale para los dos grupos de píldoras —servicios y oficina—, que es por lo que
   el error se escribe contra `.field` y no contra uno de los dos. */
.field.has-error .servicio { border-color: #FF8A80; }
.field__opcional { color: var(--texto-suave); font-weight: 400; text-transform: none; letter-spacing: normal; }

/* Aquí vivían las dos píldoras con bandera de «Oficina que te atiende», que el
   cliente retiró el 8 de octubre de 2026: preguntaban lo mismo que el
   desplegable de país y ocupaban el doble. El encaminado a una oficina o a la
   otra lo hace ahora ese desplegable, con un `data-destino` por opción. */
@media (prefers-reduced-motion: reduce) {
  .servicio, .servicio input { transition: none; }
}

.form__note {
  font-size: var(--t-small);
  color: var(--texto-suave);
}
.form__note a { color: var(--amber); text-decoration: underline; text-underline-offset: 3px; }

.form-status {
  display: none;
  padding: 1rem 1.25rem;
  border-radius: var(--radius-s);
  font-size: .95rem;
}
.form-status.is-ok  { display: block; background: rgba(242,176,47,.14); border: 1px solid rgba(242,176,47,.4); }
.form-status.is-err { display: block; background: rgba(255,138,128,.12); border: 1px solid rgba(255,138,128,.4); }

/* --------------------------------------------------------------------------
   17. Llamado final
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  background: var(--amber);
  color: var(--fondo);
  border-radius: var(--radius);
  padding: clamp(2.5rem, 6vw, 5rem);
  overflow: hidden;
  isolation: isolate;
}
.cta-band::after {
  content: "";
  position: absolute;
  right: -12%;
  top: -55%;
  width: min(60%, 460px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--linea-fuerte);
  z-index: -1;
}
.cta-band h2 { color: var(--fondo); font-size: var(--t-h2); max-width: 20ch; }
.cta-band p { color: rgba(10,10,11,.72); max-width: 48ch; margin-bottom: 2rem; }

/* --------------------------------------------------------------------------
   18. Pie de página
   -------------------------------------------------------------------------- */
/* El pie es siempre bloque de contraste: cierra el sitio claro en negro */
/* Nada de `background: var(--fondo)` aquí. Era el causante real del corte del
   pie: `.contraste` —que va en el mismo elemento— redefine `--fondo` a
   `var(--contra)`, que es OPACO, así que esta línea pisaba el fondo al 82 % que
   `.contraste` declaraba justo debajo y que sí dejaba ver la malla. El mismo
   tropiezo de siempre: una variable resuelta en el sitio donde se usa, no donde
   uno cree que la definió. */
.footer {
  border-top: 1px solid var(--linea);
  padding-block: clamp(2.75rem, 4.5vw, 4rem) 1.75rem;
}

.footer__top {
  padding-bottom: clamp(2rem, 4vw, 3rem);
  border-bottom: 1px solid var(--linea);
}

.footer__brand svg { width: 158px; height: auto; margin-bottom: 1.5rem; }
.footer__tagline { color: var(--texto-suave); font-size: .95rem; max-width: 34ch; }

.footer__nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
  gap: 1.75rem;
}
.footer__heading {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 1.1rem;
}
.footer__list { display: grid; gap: .6rem; }
.footer__list a, .footer__list li {
  font-size: .92rem;
  color: var(--texto-suave);
  transition: color .25s var(--ease);
}
.footer__list a:hover { color: var(--texto); }

/* Seis oficinas: 3x2 cuadra mejor que dejarlo a auto-fit, que daba 4+2 */
.offices {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
  padding-block: clamp(2.5rem, 5vw, 3.5rem);
  border-bottom: 1px solid var(--linea);
}
@media (max-width: 900px) { .offices { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .offices { grid-template-columns: 1fr; } }

/* Cada oficina entra un poco después de la anterior, de izquierda a derecha */
.office {
  display: flex;
  align-items: flex-start;
  gap: .85rem;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
.is-visible .office { opacity: 1; transform: none; }
.is-visible .office:nth-child(1) { transition-delay: 0s;   }
.is-visible .office:nth-child(2) { transition-delay: .11s; }
.is-visible .office:nth-child(3) { transition-delay: .22s; }
.is-visible .office:nth-child(4) { transition-delay: .33s; }
.is-visible .office:nth-child(5) { transition-delay: .44s; }
.is-visible .office:nth-child(6) { transition-delay: .55s; }

.office__bandera {
  flex: none;
  width: 2.4rem;
  aspect-ratio: 3 / 2;
  border-radius: .3rem;
  overflow: hidden;
  border: 1px solid var(--linea-fuerte);
  box-shadow: 0 3px 10px rgba(0,0,0,.5);
  transition: transform .4s var(--ease);
}
.office__bandera img { width: 100%; height: 100%; object-fit: cover; }
.office:hover .office__bandera { transform: translateY(-2px) scale(1.05); }

.office__country {
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 600;
  margin-bottom: .4rem;
}
.office__address {
  font-size: .85rem;
  line-height: 1.6;
  color: var(--texto-suave);
  margin: 0;
  font-style: normal;
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-top: 2rem;
}
.footer__legal { font-size: .8rem; color: var(--texto-suave); margin: 0; max-width: 62ch; }
.footer__legal a { color: var(--texto-suave); text-decoration: underline; text-underline-offset: 3px; }
.footer__legal a:hover { color: var(--amber); }

.social { display: flex; gap: .6rem; }
.social a {
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border: 1px solid var(--linea-fuerte);
  border-radius: 50%;
  color: var(--texto-suave);
  transition: color .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease);
}
.social a:hover { color: var(--fondo); background: var(--amber); border-color: var(--amber); }
.social svg { width: 1.05rem; height: 1.05rem; }

/* --------------------------------------------------------------------------
   19. Páginas legales
   -------------------------------------------------------------------------- */
.legal {
  max-width: 78ch;
  font-size: 1rem;
  line-height: 1.8;
}
.legal h2 {
  font-size: var(--t-h3);
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--linea);
}
.legal h2:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.legal p { color: var(--texto-suave); }
.legal ul { display: grid; gap: .6rem; margin-block: 1.25rem 1.75rem; }
.legal li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--texto-suave);
}
.legal li::before {
  content: "";
  position: absolute;
  left: 0; top: .7em;
  width: .4rem; height: .4rem;
  border-radius: 50%;
  background: var(--amber);
}
.legal a { color: var(--amber); text-decoration: underline; text-underline-offset: 3px; word-break: break-word; }

.legal-toc {
  position: sticky;
  top: 7.5rem;
  display: grid;
  gap: .55rem;
  padding: 1.5rem;
  background: var(--fondo-2);
  border: 1px solid var(--linea);
  border-radius: var(--radius);
}
.legal-toc a {
  font-size: .88rem;
  color: var(--texto-suave);
  transition: color .25s var(--ease);
}
.legal-toc a:hover { color: var(--amber); }

/* --------------------------------------------------------------------------
   20. Animación de entrada
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: .09s; }
.reveal[data-delay="2"] { transition-delay: .18s; }
.reveal[data-delay="3"] { transition-delay: .27s; }
.reveal[data-delay="4"] { transition-delay: .36s; }

/* --------------------------------------------------------------------------
   21. Adaptación a pantallas pequeñas
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .hero__inner { grid-template-columns: 1fr; }
  .hero__media { display: none; }
  .hero__lead { max-width: 46ch; }
  .split { grid-template-columns: 1fr; }
  .split__sticky { position: static; }
  .footer__top { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .cabecera { grid-template-columns: 1fr; align-items: start; }
}

@media (max-width: 860px) {
  .nav, .header__acciones { display: none; }
  .burger { display: inline-flex; }
  .feature--reverse > :first-child { order: 0; }
  .gallery__item--wide { grid-column: span 1; aspect-ratio: 3 / 4; }
  .ind { grid-template-columns: auto minmax(0, 1fr); }
  .ind__mark { display: none; }
  .legal-toc { position: static; }
}

@media (max-width: 560px) {
  .float-stat { left: auto; right: 1rem; bottom: 1rem; padding: .9rem 1.15rem; }
  .footer__bottom { flex-direction: column; align-items: flex-start; }
  :root { --arc: 8rem 8rem 8rem 1rem; }
}

/* --------------------------------------------------------------------------
   22. Preferencias del sistema
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .reveal { opacity: 1; transform: none; }
  .marquee__track { animation: none; }
  /* La ronda de luz por los cuatro pasos se apaga del todo */
  .paso::after { animation: none; border-color: transparent; box-shadow: none; }
  /* La cortina y el asentamiento de la imagen se saltan por completo */
  .duo img { transform: none; }
  .ficha { opacity: 1; transform: none; }
  .ficha:hover .ficha__medio img { transform: none; }
  .carrusel__pista { scroll-behavior: auto; }
  .office { opacity: 1; transform: none; }
  /* La escena de los valores: `--compas: 0` pone a cero los SEIS tiempos de
     una vez. Hace falta decirlo aquí porque la regla de arriba deja las
     duraciones en .01 ms pero NO toca los retardos, y en esta sección los hay
     de hasta 2,2 s: sin esto la sección se quedaría vacía ese rato. El bucle
     no se queda a medias, se apaga; el destello de la onda se retira entero,
     porque su animación termina con la raya otra vez al principio. */
  .escena-valores { --compas: 0; }
  .valor::after,
  .valor__icono,
  .valor__idx::before { animation: none; }
  .valores__onda-luz { display: none; }
  .valores__nodos i { animation: none; opacity: .5; }
  /* Con movimiento reducido la luz no se enciende: el JS ni siquiera la activa */
  .glow::before { display: none; }
}

@media print {
  .header, .mobile-nav, .scroll-cue, .marquee, .footer__nav { display: none; }
  body { background: #fff; color: #000; }
}

/* --------------------------------------------------------------------------
   23. La página por pantallas

   Cada sección ocupa exactamente una pantalla y el scroll salta de una a otra:
   un gesto, una sección. Es `scroll-snap` del navegador, no JavaScript, así que
   la rueda, la barra, el teclado, los anclajes y el gesto del trackpad hacen lo
   mismo y nada se pelea con el scroll nativo.

   `scroll-snap-stop: always` es la pieza que impide que un gesto rápido se
   salte tres secciones de golpe. Y `scroll-padding-top` vuelve a 0 porque aquí
   cada sección se alinea al borde de la pantalla y ya reserva por dentro el
   sitio de la cabecera fija.

   Se activa solo si hay pantalla de sobra. Por debajo de 901 px de ancho o de
   620 px de alto no hay saltos: la página vuelve a fluir normal, que es lo que
   toca en un móvil y en una ventana baja. Con movimiento reducido, igual.
   -------------------------------------------------------------------------- */
@media (min-width: 901px) and (min-height: 620px) {
  html {
    scroll-snap-type: y mandatory;
    scroll-padding-top: 0;
  }

  .pantalla {
    height: 100svh;
    min-height: 0;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    overflow: hidden;
  }

  /* Hueco de la cabecera fija, que va por encima de todo */
  .pantalla { --cabecera: 5rem; }

  /* --- Portada ---
     La imagen del hero se dimensiona por su proporción 3/4, o sea por el ancho:
     en una ventana baja crecía por encima de la pantalla y se recortaba por
     abajo. Aquí manda el alto disponible y la proporción cede. */
  .hero.pantalla {
    padding-top: var(--cabecera);
    padding-bottom: clamp(1rem, 3vh, 2.5rem);
  }
  /* La portada ya no lleva foto en columna: la imagen es el fondo entero y la
     segunda columna de la rejilla queda vacía a propósito, reservando el sitio
     donde la escena se ve limpia. */
  .hero.pantalla .hero__inner { align-items: center; }
  .hero.pantalla .hero__title { margin-bottom: clamp(.6rem, 1.6vh, 1.25rem); }
  .hero.pantalla .hero__lead { margin-bottom: clamp(1rem, 2.4vh, 1.75rem); }

  /* --- Soluciones: encabezado arriba, acordeón llenando el resto --- */
  /* El bloque va centrado en la pantalla, no pegado arriba. Antes el relleno
     inferior era 0 y todo el sobrante caía debajo de las fichas: la sección se
     leía como contenido apretado contra el techo y un hueco muerto al pie. */
  .seccion--pantalla.pantalla {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--cabecera);
  }
  /* La cabecera se aprieta para dejarle la pantalla al acordeón: el título en
     una línea, la bajada a dos y el botón pegado. Sin esto el encabezado se
     comía un tercio de la pantalla y las imágenes se quedaban en la mitad. */
  .seccion--pantalla.pantalla .cabecera { margin-bottom: 0; }
  /* El subtítulo va al MISMO cuerpo en las cuatro secciones. Este de Soluciones
     lo había encogido a 15,2 px —contra los 21,6 de Clientes y la portada— para
     que el encabezado no se comiera la pantalla, y se notaba: leído seguido, el
     de Soluciones parecía un pie de foto y el de Clientes un subtítulo. Ahora
     hereda `--t-lead` y los 56ch de `.cabecera .lead`, igual que el resto. Cabe
     de sobra: con las fichas centradas quedaban 254 px de aire por lado. */
  .seccion--pantalla.pantalla .cabecera .lead + p { margin-top: clamp(.9rem, 2vh, 1.3rem); }

  /* --- Los cuatro subtítulos, con una sola regla ---
     Antes cada sección llevaba el suyo por su cuenta y no coincidía ninguno:
     Soluciones a 15,2 px y 763 de ancho, Clientes a 21,6 px y 608, y las otras
     dos sin subtítulo. Ahora comparten cuerpo, medida y separación.

     Sobre la MEDIDA: los 56ch de Clientes daban 608 px y no 763 como en las
     demás, y no era un valor distinto sino el mismo mal declarado. `ch` se
     resuelve contra el cuerpo de letra del elemento DONDE se escribe, y allí
     estaba puesto en el contenedor, que va al cuerpo del texto normal —16 px—,
     no en el subtítulo, que va a 21,6. Declarado sobre el propio subtítulo, los
     56 caracteres son de verdad 56 caracteres suyos.

     Sobre la SEPARACIÓN: aquí había un relleno de .22em en cada título para
     hacerle sitio al subrayado de `.hl`, que sobresalía 13 px por debajo de la
     caja y se pegaba al subtítulo. Retirado el subrayado, ese hueco ya no lo
     pide nadie: se queda en el margen normal. */
  .cabecera h2,
  .clientes__cabeza h2,
  .mosaico__cabeza h2,
  .cifras__cabeza h2 {
    margin: 0;
  }
  .cabecera .lead,
  .clientes__cabeza .lead,
  .mosaico__cabeza .lead,
  .cifras__cabeza .lead {
    /* El `min` con `vh` no rompe la igualdad que se busca: afecta a los cuatro
       a la vez, así que siguen midiendo lo mismo entre sí a cualquier tamaño.
       Solo entra en una ventana baja, donde el subtítulo a 21,6 px le robaba el
       sitio al mosaico: a 660 de alto Industrias se salía 14 px por abajo.
       A partir de unos 810 de alto no hace nada y manda `--t-lead`. */
    font-size: min(var(--t-lead), 2.5vh);
    max-width: 56ch;
    margin: clamp(.8rem, 1.6vh, 1.2rem) 0 0;
  }
  /* `flex: 0 1 auto` y no `1 1 auto`: si el carrusel crece, crece SU CAJA, pero
     dentro la pista tiene techo (`max-height: min(50svh, 460px)`) y las flechas
     miden lo que miden. El sobrante —76 px a 900 de alto— se quedaba al fondo
     de la caja, debajo de las flechas, y la sección se leía alta con un hueco
     muerto al pie. Encogiendo la caja a su contenido, el `justify-content:
     center` de la sección reparte ese aire arriba y abajo por igual. */
  .seccion--pantalla.pantalla .carrusel {
    position: relative;
    flex: 0 1 auto;
    min-height: 0;
    margin-top: clamp(1rem, 2.4vh, 1.75rem);
  }

  /* Las flechas salen del flujo. Pesaban 65 px —44 de alto más 21 de hueco— al
     repartir el centrado, pero a la vista no pesan nada: son dos ángulos finos
     en una esquina. El resultado era que la caja medía centrada y el bloque que
     de verdad se ve —título, texto y tarjetas— quedaba 65 px por encima del
     centro, con todo ese vacío debajo. Medido a 1462 × 1050: 209 px sobre el
     título contra 274 bajo las tarjetas.
     En `top: 100%` cuelgan del borde inferior del carrusel sin empujarlo, y con
     `left/right: 0` conservan la columna del sitio, que es lo que ya les daba
     su clase `.wrap`. Caben de sobra: el relleno inferior de la sección son
     80 px y ellas miden 44. */
  .seccion--pantalla.pantalla .carrusel__mandos {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: clamp(.9rem, 2vh, 1.5rem);
  }

  /* --- Clientes: se centra y respira --- */
  /* Aquí la caja se centraba perfecta —221 px arriba y 221 abajo— y aun así la
     sección se LEÍA alta. La razón: bajo el último logotipo cuelgan 36 px de
     relleno transparente (20 de la banda y 16 de la cinta, que reservan sitio
     para la sombra y el crecimiento del logotipo al pasar el cursor), mientras
     que arriba el título arranca pegado al borde del bloque. El ojo mide tinta,
     no cajas, y contaba 213 px de aire arriba contra 257 abajo.
     Se compensa empujando el bloque desde arriba: con `align-content: center` un
     relleno superior extra baja el contenido justo su mitad, así que basta con
     que ese extra valga lo que la cola. Va escrito con las mismas variables que
     lo producen, para que no se descuadre si cambian. */
  #clientes.pantalla {
    --pad-banda: clamp(1.1rem, 2.2vh, 1.6rem);
    --cola-logos: calc(var(--pad-banda) + 1rem);
    display: grid;
    align-content: center;
    padding-block: calc(var(--cabecera) + var(--cola-logos)) var(--cabecera);
  }
  /* Sin caja alrededor, el logotipo puede ocupar todo lo que antes gastaba el
     recuadro: otro 30 % sobre los 153 px, o sea 198 px a 900 de alto. */
  #clientes.pantalla .marquee__item img { height: clamp(150px, 22vh, 282px); }
  #clientes.pantalla .marquee__track { gap: clamp(2.5rem, 5vw, 4.5rem); }
  #clientes.pantalla .logo-band { padding-block: var(--pad-banda); }
  /* La cinta se pega al encabezado con la misma separación que las otras dos
     secciones. El hueco salía de 56 px contra los 18 del mosaico y el bloque se
     leía partido en dos; venía de un `margin-bottom` EN LÍNEA en el HTML, que
     gana a cualquier regla de la hoja. Ahora el margen vive aquí y el aire lo
     pone el centrado de la sección, no una separación interna. */
  /* La medida de 56ch que había aquí se mudó al propio subtítulo, más arriba:
     declarada en el contenedor, los `ch` se medían con el cuerpo del texto
     normal (16 px) y salían 608 px, mientras que en las otras tres secciones
     salían 763. El mismo número escrito en el sitio equivocado. */
  .clientes__cabeza { margin-bottom: clamp(.9rem, 1.8vh, 1.4rem); }
  /* Los huecos internos del pie vuelven al ritmo del resto del sitio. Estaban
     inflados a 54 y 63 px para llenar la pantalla, y el resultado era el
     contrario del buscado: el bloque se leía alto y con un agujero en medio,
     entre las oficinas y el aviso legal. El aire lo pone el centrado. */
  /* El agujero del pie no estaba en los márgenes que ya apreté, sino en tres
     rellenos heredados que sumaban 149 px entre el logotipo y las oficinas:
       · 24 px de `margin-bottom` bajo el SVG, reservados para un `footer__tagline`
         que ya no existe en ningún HTML del sitio;
       · 48 px de `padding-bottom` en `.footer__top`, pensados para cuando ahí
         vivía además el menú de enlaces;
       · 56 px de `padding-block` en `.offices`.
     Se quedan sin tocar fuera de la portada, que es donde el pie sí es un
     bloque largo al final de una página con scroll. */
  .footer.pantalla .footer__brand svg { margin-bottom: 0; }
  .footer.pantalla .footer__top {
    padding-bottom: clamp(1rem, 2vh, 1.5rem);
    margin-bottom: clamp(1rem, 2vh, 1.5rem);
  }
  .footer.pantalla .offices {
    padding-block: clamp(1.25rem, 2.5vh, 1.9rem);
    row-gap: clamp(1.5rem, 3vh, 2.25rem);
  }
  .footer.pantalla .footer__bottom { padding-top: clamp(1.1rem, 2.2vh, 1.6rem); }

  /* --- Cifras: las tres celdas centradas en su pantalla ---
     El encabezado separa lo mismo que en Clientes y en el mosaico, y el aire
     lo pone el centrado de la sección, no un hueco interno. La rejilla va con
     `flex: 0 0 auto` por lo mismo que el carrusel: si crece su caja, el
     sobrante se queda al fondo y la sección se lee alta. */
  #cifras.pantalla {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--cabecera);
  }
  .cifras__cabeza { margin-bottom: clamp(1.4rem, 2.6vh, 2.2rem); }
  /* La constelación no se estira: `flex: 0 0 auto` por lo mismo que el
     carrusel. Si creciera su caja, el sobrante se quedaría al fondo y la
     sección se leería alta con un agujero debajo. */
  #cifras.pantalla .cn3d { flex: 0 0 auto; }

  /* VENTANAS BAJAS. La constelación es alta —dos filas de fichas, el núcleo
     entre ellas y la barra debajo— y `.pantalla` recorta lo que sobra. Aquí, y
     solo aquí, el núcleo renuncia a su tamaño máximo y las cifras aceptan un
     techo en `vh`, que es la medida que importa cuando lo que falta es alto. */
  @media (max-height: 780px) {
    #cifras.pantalla .cn3d__nucleo { width: min(100%, clamp(11rem, 20vw, 15rem)); }
    #cifras.pantalla .cn3d__num { font-size: min(clamp(2.1rem, 3.4vw, 3.25rem), 6.4vh); }
    #cifras.pantalla .cn3d__num--grande { font-size: min(clamp(2.6rem, 5vw, 4.4rem), 8.6vh); }
    #cifras.pantalla .cn3d__ficha { padding-block: clamp(.75rem, 1.6vh, 1.1rem); }
  }
  /* Aquí vivían dos reglas para que las cinco banderas cupieran en una sola fila
     dentro de la celda —`flex: 1 1 0` para repartir el ancho que hubiera—. Los
     nombres que las sustituyen no las necesitan: pasan de línea cuando no caben,
     que es lo normal en una lista de palabras. */

  /* La portada de las páginas interiores hereda un relleno asimétrico —11rem
     arriba, mucho menos abajo— que venía de cuando la página fluía y el hero
     solo tenía que librar la cabecera fija. Dentro de una pantalla eso deja el
     contenido 52 px por encima del centro. Se iguala. */
  .hero--page.pantalla { padding-block: var(--cabecera); }

  /* --- Nosotros: seis pantallas ---
     Portada, misión y visión, valores, certificaciones, casos de éxito y el pie
     con las seis sedes. Todas centradas en alto y en ancho, como el Home. */
  #mision-vision.pantalla,
  #valores.pantalla,
  #certificaciones.pantalla,
  #casos.pantalla {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--cabecera);
  }

  /* Las dos secciones con encabezado propio aprietan su separación: dentro de
     una pantalla el aire lo pone el centrado, no el hueco interno. */
  #valores.pantalla .cabecera,
  #certificaciones.pantalla .cabecera { margin-bottom: clamp(1.25rem, 3.5vh, 3rem); }
  /* Este margen estaba EN LÍNEA en el HTML y por tanto ganaba a cualquier regla
     de la hoja: obligaba a un `!important` para poder apretarlo. Ahora vive en
     `.casos__cabeza` y se puede ajustar como cualquier otra cosa. Es la tercera
     vez que aparece este resto en el proyecto; conviene mirarlo antes de dar por
     rota una regla que parece correcta. */
  #casos.pantalla .casos__cabeza { margin-bottom: clamp(1.5rem, 4vh, 3.5rem); }

  /* La cinta de certificaciones es lo más alto de su sección: 200 px por sello
     más los rellenos de la banda. Cede con la ventana para no salirse. */
  #certificaciones.pantalla .marquee__item img { height: min(200px, 26vh); }

  /* --- Trabaja con nosotros: cuatro pantallas ---
     Mismo sistema que el Home. Cada sección se centra en su pantalla, en alto
     y en ancho, y el contenido cede tamaño cuando la ventana es baja: aquí hay
     una foto grande y otra de la mascota, y a `svh` fijos se salían por abajo
     en cuanto la ventana bajaba de unos 900. */
  .unete.pantalla,
  #semillero.pantalla,
  #canty.pantalla {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--cabecera);
  }

  /* Las dos imágenes se someten al alto disponible. Sin este techo mandaba su
     proporción y la sección crecía por debajo del borde. `object-fit: contain`
     mantiene la proporción dentro del techo, y como las dos son recortes con
     transparencia, el sobrante no se ve. */
  .unete.pantalla .unete__foto img { max-height: 46svh; object-fit: contain; }
  /* Ojo con el selector: en «Únete» las clases `unete` y `pantalla` van juntas
     en la misma <section>, pero en Canty la clase `canty` está en el <div>
     interior y `pantalla` en la <section>, así que `.canty.pantalla` no casaba
     con nada y este techo llevaba sin aplicarse desde que se escribió. Medido a
     1280x560: la sección ocupaba 695 px, 161 por debajo del borde. Por el id,
     como el resto de esta consulta. */
  #canty.pantalla .canty__figura img { max-height: 62svh; object-fit: contain; }

  /* El vídeo baja por el mismo techo, y al bajar enseña MÁS cuadro, no menos:
     con la caja más baja, `cover` escala menos y descubre ancho. Medido en el
     caso más apretado, 1280x620: la caja queda en 541x384 y se ve del 10,4 % al
     89,6 % del cuadro, con el personaje entre el 31 % y el 68 %. Sin este techo
     la sección medía 753 px contra 620 de pantalla. */
  #canty.pantalla .canty__figura video { max-height: 62svh; }

  /* Los pilares se aprietan contra la portada: dentro de una pantalla el aire
     lo pone el centrado, no la separación interna. */
  .unete.pantalla .pilares { margin-top: clamp(1.5rem, 3.5vh, 2.75rem); }
  /* El icono y el nombre, ya crecidos, ceden con la ventana: la portada es la
     sección con menos holgura de la página —31 px por lado a 660 de alto— y sin
     este techo el aumento se la comía. Por encima de unos 900 mandan los
     valores de escritorio y esto no hace nada. */
  .unete.pantalla .pilar__icono { width: min(3.5rem, 6.2vh); height: min(3.5rem, 6.2vh); }
  .unete.pantalla .pilar__icono svg { width: 50%; height: 50%; }
  .unete.pantalla .pilar__nombre { font-size: min(1.4rem, 2.6vh); }
  .unete.pantalla .unete__cta { margin-top: clamp(1rem, 2.4vh, 1.75rem); }

  /* El pie tiene cuatro pantallas por delante: se centra como una más. */
  .footer.pantalla { justify-content: center; }

  /* El semillero es la sección más apretada de la página: cuatro fichas cuya
     altura la marca el texto largo de la 04. A 660 de alto pedía 542 px contra
     los 500 disponibles y se salía por arriba y por abajo. El relleno y el
     cuerpo del texto ceden con la ventana; el `min` deja mandar al valor de
     escritorio en cuanto hay alto de sobra, así que por encima de unos 750 no
     cambia nada. */
  #semillero.pantalla .cabecera { margin-bottom: clamp(1rem, 3vh, 2.5rem); }
  #semillero.pantalla .paso { padding: clamp(1.25rem, 3.4vh, 2rem); }
  #semillero.pantalla .paso__texto { font-size: min(1.075rem, 2.3vh); }
  #semillero.pantalla .paso__texto--clave { font-size: min(1.5rem, 3.4vh); }

  /* --- Industrias: el mosaico llena la pantalla --- */
  #industrias.pantalla {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-block: var(--cabecera);
  }
  /* El mosaico se queda con todo el alto que sobra tras el encabezado: con
     `flex: 0 1 auto` la rejilla colapsaba a su mínimo y las piezas salían de
     82 px, con el icono encima del texto. */
  #industrias.pantalla .mosaico { flex: 0 1 auto; min-height: 0; }


  /* --- Pie --- */
  .footer.pantalla {
    display: grid;
    align-content: center;
    padding-block: var(--cabecera);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
  .pantalla { height: auto; min-height: 0; overflow: visible; }
}


/* --------------------------------------------------------------------------
   24. Las tarjetas en el móvil: una sola a la vista

   EL PROBLEMA. Los grupos de tarjetas están escritos como rejillas, y en el
   móvil una rejilla no tiene a dónde encoger: pasa a una columna y apila. Ocho
   industrias apiladas son 672 px; los cuatro pasos del semillero, 1.022. La
   página se volvía un rollo de papel y, leyendo, no se sabía si quedaban dos
   tarjetas o diez.

   LO QUE SE HACE. Por debajo de 760 px cada grupo se convierte en un carril
   horizontal con ajuste por tarjeta: se ve UNA, ocupa el ancho útil, y se pasa
   a la siguiente deslizando, tocando un punto o sola, que de eso se encarga el
   JavaScript. Es el mismo mecanismo que ya usaban las fichas de servicio en
   escritorio —scroll-snap del navegador, no un carrusel a mano—, así que la
   rueda, el gesto del trackpad, el teclado y la barra siguen funcionando y no
   hay nada que sincronizar.

   POR QUÉ EL CONTENEDOR Y NO CADA GRUPO. El atributo va en el contenedor que ya
   existe —la rejilla del mosaico, la lista de pilares, la de pasos— y estas
   reglas ganan por orden, al ir las últimas del archivo. Ninguna tarjeta
   cambia: siguen midiendo lo que miden y conservando sus animaciones.
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
  [data-tarjetas] {
    display: flex;
    /* La rejilla manda sobre `display: flex` si se queda puesta: hay que
       anularla, que estos contenedores son `grid` en su regla propia. */
    grid-template-columns: none;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: clamp(.75rem, 3vw, 1.1rem);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* UN CARRIL DENTRO DE UNA REJILLA TIENE QUE PODER ENCOGER. El ancho de un
       elemento de rejilla o de caja flexible se calcula contra su contenido
       —`min-width: auto`—, y el contenido de un carril son todas sus tarjetas
       en fila: la pieza que lo contiene se estiraba al doble del ancho de la
       pantalla. Le pasó a la órbita de «Cantec en cifras», que salió de 673 px
       en una ventana de 390 y se llevó el rombo fuera de cuadro. */
    min-width: 0;
    /* Sin esto, al llegar al final el gesto sigue y arrastra la página entera
       de lado, o peor, dispara el «volver atrás» del navegador. */
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  [data-tarjetas]::-webkit-scrollbar { display: none; }

  [data-tarjetas] > * {
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    scroll-snap-align: center;
    /* Un gesto, una tarjeta: sin esto un deslizamiento rápido se salta tres. */
    scroll-snap-stop: always;
  }

  /* Las fichas de servicio dejan de apilarse: tenían su propia regla de móvil
     —columna y sin ajuste— de cuando no había carrusel aquí. */
  [data-tarjetas].carrusel__pista {
    scroll-snap-type: x mandatory;
    flex-direction: row;
    overflow-x: auto;
  }
  [data-tarjetas].carrusel__pista > .ficha { height: auto; min-height: 0; }

  /* Los pasos se unen con flechas dibujadas en el hueco de la rejilla. En un
     carril no unen nada: apuntarían al aire entre dos tarjetas que ya no están
     una al lado de la otra. */
  [data-tarjetas].pasos .paso::before { display: none; }

  /* ---- El encabezado de sección: titular y entradilla, separados ----
     La separación entre los dos vive en la consulta del salto por pantallas
     —`margin: clamp(.8rem, 1.6vh, 1.2rem)` sobre la entradilla—, así que por
     debajo de 901 px no existe: medido, en Industrias el titular TOCABA su
     entradilla, 0 px, mientras en Clientes quedaban 17 por otra regla. Aquí se
     igualan los cuatro encabezados del Home en 17,5. */
  .cabecera .lead,
  .clientes__cabeza .lead,
  .mosaico__cabeza .lead,
  .cifras__cabeza .lead { margin-top: clamp(1.25rem, 6.5vw, 1.9rem); }

  /* LA CURVA SE COME EL RELLENO DE LA SECCIÓN CLARA. El arco oscuro de arriba
     es una tapa de 26 px dibujada DENTRO de la sección, y el relleno la
     incluye: de los 42 px medidos a 396 de ancho, 26 son tapa y quedan 16 de
     aire real entre el arco y el titular. Por eso seguía viéndose apretado
     aunque el titular y su entradilla ya estuvieran separados.
     EL RELLENO SE MIDE DESPUÉS DE LA CURVA, y el que se pone es el de las
     secciones oscuras —`--section-y`—, no uno nuevo: medido a 396, la sección
     oscura dejaba 98 px sobre su titular y la clara 58, y leídas seguidas la
     blanca parecía otra retícula. Ahora las dos dan lo mismo y la curva se paga
     aparte, que es lo que ocupa de más. */
  .claro { padding-block: calc(var(--curva-claro) + var(--section-y)); }

  /* Los logotipos de clientes, más grandes. Su suelo de 68 px está pensado para
     una franja de 1.440 px donde desfilan seis a la vez; en un móvil se ven uno
     y medio y a 68 px parecen pegatinas. */
  .marquee__item img { height: clamp(92px, 24vw, 128px); }

  /* ---- La entradilla, un punto más corta ----
     No es el tamaño de letra lo que molestaba, es el BLOQUE: a 390 px la
     entradilla daba 17,6 px con interlineado 1,55 y la de Soluciones —la más
     larga del sitio, 212 caracteres— ocupaba seis líneas y 190 px antes de que
     asomara la primera tarjeta. A 16,8 con 1,5 son cinco líneas y 152 px. La
     letra baja un 5 %, que no se nota leyendo, y el bloque un 20 %, que sí.
     Sigue por encima del cuerpo de texto, que a este ancho mide 15,9. */
  .lead {
    font-size: clamp(1rem, .95rem + .4vw, 1.25rem);
    line-height: 1.5;
  }

  /* ---- La foto de las fichas de servicio, sin cortar cabezas ----
     Las cuatro miden 900 × 1200 —retrato 3:4— y la regla de móvil las metía en
     una caja 4:3 apaisada: al cubrir, el navegador escala la foto a 452 px de
     alto para llenar los 339 de ancho y recorta 198, el 44 %, mitad por arriba.
     De ahí las cabezas cortadas. En cuadrado la pérdida baja a 113 px.
     EL ENCUADRE VA AL 10 %, no al 30: en estas cuatro fotos el retratado está
     alto en el cuadro —Ventas es el caso extremo, la coronilla casi toca el
     borde— y el 30 % se llevaba 34 px de arriba, que eran justo pelo. Al 10 %
     son 11 px y los otros 102 se van por abajo, donde hay mesa y portátil.
     Comprobado una por una: las cuatro cabezas entran enteras. */
  [data-tarjetas].carrusel__pista .ficha__medio { aspect-ratio: 1 / 1; }
  [data-tarjetas].carrusel__pista .ficha__medio img { object-position: 50% 10%; }

  /* ---- «Cantec en cifras» en el móvil ----
     LA CONSTELACIÓN NO SOBREVIVE A UNA COLUMNA. Es una lámina isométrica: las
     tuberías van de ficha a ficha, el globo y las tres escenas se apoyan en los
     huecos que dejan, y la tarima de cada ficha es una losa vista en
     perspectiva. Apilado, nada de eso dice nada —y las tarimas, recortadas por
     el carril, se leían como cartones pegados detrás—. Así que en el móvil la
     sección se queda con lo que SÍ es la información: el núcleo y las cuatro
     cifras, estas en el mismo carril que el resto del sitio.

     EL ARTE SIGUE FUERA AUNQUE AHORA VIVA DENTRO DE LA FICHA. En escritorio
     ocupa el blanco que sobraba; aquí no sobra nada —la tarjeta mide 327 y el
     texto la llena—, y meterle una ilustración de 90 px por la izquierda sería
     quitárselos a la cifra, que es lo único que esta sección tiene que decir.
     Con el arte fuera, el texto vuelve a la izquierda: alinearlo a la derecha
     solo tenía sentido para dejarle sitio al dibujo. */
  /* ---- Canty en el móvil: la imagen, no el vídeo ----
     El vídeo trae fondo de plató y se limpia mezclándolo con lo que tiene
     detrás —blanco por blanco se va—, pero el Safari del iPhone no aplica esa
     mezcla a un `<video>`: lo compone en su propia capa. Sin mezcla queda un
     rectángulo blanco, y encima no coincide con el blanco de la sección porque
     el vídeo pasa por gestión de color y el CSS no: por eso se ve «más
     brillante que el fondo». Ningún ajuste de brillo arregla eso; lo que hay
     que quitar es el rectángulo.
     La imagen es un fotograma del propio vídeo —el saludo, segundo 4,2— con
     alfa de verdad: 69 % del archivo es transparente puro y el contorno son
     9.368 píxeles de alfa intermedia. No depende de ninguna mezcla, la malla
     pasa por detrás en cualquier navegador, y pesa 34 KB contra los 987 del
     vídeo, que en el móvil ya no se descarga. */
  .canty__figura video { display: none; }
  .canty__quieta { display: block; }

  .cn3d__tubos,
  .cn3d__arte { display: none; }
  .cn3d__ficha { display: block; }
  .cn3d__texto { text-align: left; }
  .cn3d__cabeza { justify-content: flex-start; }
  .cn3d__paises { justify-content: flex-start; }
  .cn3d__desc { margin-left: 0; }

  /* La órbita deja de ser rejilla de tres columnas: con las piezas de adorno
     fuera, lo que queda —núcleo y carril— se apila solo. Y las dos cajas que la
     envuelven tienen que poder encoger por la misma razón que el carril: son
     elementos de rejilla, y su ancho se mide contra el contenido. */
  .cn3d { grid-template-columns: minmax(0, 1fr); }
  .cn3d__orbita { display: block; min-width: 0; }

  /* Fuera la tarima y su canto, en las fichas y en la barra de sellos. Lo que
     las separa del fondo pasa a ser lo mismo que al resto de tarjetas del
     sitio sobre blanco: el filete ámbar y una sombra corta. */
  .cn3d__ficha::before,
  .cn3d__ficha::after,
  .cn3d__barra::before,
  .cn3d__barra::after { display: none; }
  .cn3d__ficha,
  .cn3d__barra { box-shadow: 0 6px 16px -8px rgba(176, 150, 96, .3); }

  /* EL ROMBO TAMPOCO CABE EN UN MÓVIL, y no es cuestión de tamaño: un cuadrado
     girado 45° solo ofrece a su contenido la mitad de su caja, y menos todavía
     en los extremos, donde se estrecha en punta. A 179 px de lado eso son unos
     120 útiles a la altura del número: «INTERACCIONES» se salía por los dos
     lados y «Atendidas cada mes.» partía en dos líneas que caían fuera del
     rombo, encima de la base de oro. Agrandarlo solo mueve el problema —el
     texto crece con la caja— y robarle cuerpo a la letra deja la cifra
     principal de la sección en letra pequeña.
     Así que en el móvil el núcleo deja de ser rombo y pasa a ser la PIEZA DE
     ORO de la sección: una tarjeta a lo ancho con el mismo contenido. Es la
     última pieza isométrica que quedaba; las otras —tuberías, escenas,
     tarimas— ya se habían ido por la misma razón. El oro lo hereda de la base
     del rombo, que era justo lo que le daba su presencia. */
  .cn3d__nucleo {
    width: 100%;
    aspect-ratio: auto;
    display: block;
    margin-bottom: clamp(1.35rem, 6.5vw, 2rem);
    padding: clamp(1.4rem, 6.5vw, 2rem) clamp(1.15rem, 5vw, 1.5rem);
    border-radius: clamp(14px, 1.2vw, 20px);
    background: linear-gradient(135deg, #FCD88A 0%, #F2B02F 55%, #E8A51F 100%);
    box-shadow: 0 10px 24px -8px rgba(176, 131, 36, .5);
  }
  .cn3d__base,
  .cn3d__diamante,
  .cn3d__nucleo::before { display: none; }
  /* El cuerpo ya no tiene que esquivar las puntas del rombo. */
  .cn3d__nucleo-cuerpo { padding: 0; }
  /* Las tintas estaban calculadas sobre la cara BLANCA del rombo. Sobre el oro,
     el ámbar oscuro del rótulo se queda en 3,3:1 —no llega—, así que rótulo,
     icono y pie bajan a un pardo que mide 4,7:1 contra el extremo más oscuro
     del degradado. La cifra no se toca: ya daba 6,4:1. */
  .cn3d__nucleo .cn3d__rotulo,
  .cn3d__nucleo .cn3d__desc,
  .cn3d__ico--grande { color: #4A3607; }

  /* ---- El aire de la sección ----
     TODAS SUS SEPARACIONES ESTABAN MEDIDAS EN `vh`, y tiene sentido en la
     lámina isométrica: allí la sección ocupa una pantalla entera y el hueco se
     reparte en vertical. En un móvil eso se vuelve en contra —1,4vh de 844 son
     12 px— y encima las piezas ya no se separan en diagonal, sino apiladas,
     donde el hueco es lo único que las distingue. Resultado medido: el
     encabezado tocaba la primera caja —0 px—, entre caja y caja quedaban 16 y
     dentro de cada tarjeta el número se comía su propio pie, a 6.
     En el móvil el ritmo se mide en `vw`, que es la dimensión que manda aquí:
     29 px entre el encabezado y el bloque, 25 entre cajas, 23 de relleno y 10
     entre el número y su pie. */
  .cifras__cabeza { margin-bottom: clamp(1.75rem, 8.5vw, 2.6rem); }
  .cn3d { gap: clamp(1.35rem, 6.5vw, 2rem); }
  .cn3d__ficha,
  .cn3d__barra { padding: clamp(1.3rem, 6vw, 1.8rem) clamp(1.15rem, 5vw, 1.5rem); }

  /* ---- «Certificaciones internacionales», en un solo renglón ----
     En escritorio el rótulo va partido en dos con un `<br>` y así cabe al lado
     de los sellos. En el móvil la pastilla reparte sus piezas en dos filas, el
     rótulo tiene el ancho entero para él, y partirlo lo único que hacía era
     dejarlo alto y estrecho —120 px de caja en una fila de 288—. El cliente
     pidió una sola línea.

     El `<br>` no se quita del marcado: se apaga. En escritorio sigue haciendo
     falta, y un solo elemento con dos comportamientos es mejor que dos rótulos
     distintos que haya que mantener a la vez.

     LA CUENTA, a 375: la pastilla da 326 y sus rellenos dejan 288 de contenido;
     el disco mide 38 y el hueco 14,4, así que al rótulo le quedan 235,6. En una
     línea a 16 px pide 241 —seis de más—. Se compra el sitio por los dos lados:
     el hueco y los rellenos se aprietan en el móvil, donde sobraba aire, y el
     cuerpo cede con la ventana por debajo de 375 para que siga entrando en
     pantallas de 360 y de 320. */
  .cn3d__barra { gap: .6rem; padding-inline: .9rem; }
  .cn3d__barra-txt br { display: none; }
  .cn3d__barra-txt {
    white-space: nowrap;
    font-size: min(1rem, 4.25vw);
  }
  .cn3d__cabeza { margin-bottom: clamp(.8rem, 3.5vw, 1.15rem); }
  .cn3d__desc { margin-top: clamp(.55rem, 2.5vw, .85rem); }
  .cn3d__num--grande { margin-top: clamp(.35rem, 2vw, .65rem); }

  /* ---- Las cuatro cifras: dos cajas de dos renglones, deslizándose ----
     Esto cambió dos veces el 13 de octubre de 2026 y las dos a petición del
     cliente. Era un carril de una tarjeta; pasó a una caja de cuatro renglones
     apilados —que leía bien pero dejaba la sección en 1.364 px y el Home en
     seis pantallas—; y acabó en el punto medio: **de dos en dos, y las
     siguientes se deslizan**.

     El carril vuelve a ser `.cn3d__fichas`, con su `data-tarjetas`, y cada
     diapositiva es un `.cn3d__par`. El guion no se entera del cambio: cuenta
     hijos del carril, así que monta dos puntos en vez de cuatro sin tocar una
     línea.

     Cada par es una caja con el mismo recurso que `.stats`: se pinta del color
     del filete y los renglones del color del fondo, separados por un hueco de
     UN píxel. Esa rendija es la línea divisoria —no hay bordes que cuadrar
     entre sí ni un `:last-child` que acordarse de quitar— y `overflow: hidden`
     redondea las esquinas de los extremos. Las fichas pierden ahí su filete, su
     redondeo y su sombra: dentro de la caja no son tarjetas sueltas, son
     celdas. */
  .cn3d__par {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    background: rgba(242, 176, 47, .34);
    border: 1px solid rgba(242, 176, 47, .34);
    border-radius: clamp(14px, 3.4vw, 20px);
    overflow: hidden;
  }
  /* CADA CAJA MIDE LO QUE MIDE SU CONTENIDO. Por omisión una caja flexible
     estira a sus hijos al alto del más alto, y el par de «Países» —que lleva
     cinco pastillas debajo del número— es 29 px más alto que el otro: el par
     corto se quedaba con una franja blanca dentro del filete, que se lee como
     un error. Alineados al principio, cada caja termina donde termina lo que
     tiene dentro. */
  [data-tarjetas].cn3d__fichas { align-items: start; }
  .cn3d__par .cn3d__ficha {
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  /* El `:hover` de escritorio levanta la tarjeta cuatro píxeles. Dentro de la
     caja eso abriría una rendija blanca entre renglones, y en un teléfono el
     `:hover` se queda pegado después de tocar. */
  .cn3d__par .cn3d__ficha:hover { transform: none; box-shadow: none; }

  /* La industria, de renglón a tarjeta. Apiladas eran renglones de 71 px y
     estaba bien: ocho seguidas se leen como una lista. Sola en el carril, un
     renglón es una raya perdida en medio de la sección con ocho puntos debajo.
     Recupera cuerpo —el `min-height` y no una proporción, que la tarjeta
     recorta lo que se salga— y el contenido sigue centrado por su propia
     rejilla, sin una regla más. El relleno es el mismo de las cifras. */
  [data-tarjetas].mosaico__rejilla .carta {
    min-height: 8.5rem;
    padding: clamp(1.3rem, 6vw, 1.8rem) clamp(1.15rem, 5vw, 1.5rem);
  }

  /* El botón de la sección, con el mismo aire que el resto: su separación
     también iba en `vh` —2,4 de 844 son 20 px— y se quedaba pegado a la
     entradilla. */
  .mosaico__cta { margin-top: clamp(1.75rem, 8.5vw, 2.4rem); }

  /* ---- Los puntos ----
     Los pone el JavaScript, uno por tarjeta, y son botones de verdad: se
     alcanzan con el teclado y dicen a dónde van. Sin JavaScript no hay puntos,
     pero el carril sigue deslizándose con el dedo. */
  .tarjetas-mandos {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: .55rem;
    /* Medido en `vw` y no en `rem`: a 390 px el `rem` dejaba los puntos a 16 px
       de la tarjeta, que es menos de lo que separa a dos tarjetas entre sí, y
       se leían como parte de la de arriba. */
    margin-top: clamp(1.1rem, 5.5vw, 1.6rem);
  }
  .tarjetas-punto {
    position: relative;
    width: .5rem;
    height: .5rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: var(--linea-fuerte);
    cursor: pointer;
    transition: width .3s var(--ease), background .3s var(--ease);
  }
  /* La activa no cambia de color: cambia de FORMA. Un punto ámbar entre puntos
     grises se pierde sobre un fondo que ya es ámbar por la malla; una barra se
     reconoce de un vistazo. */
  .tarjetas-punto[aria-current="true"] {
    width: 1.6rem;
    background: var(--amber);
  }
  .tarjetas-punto:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; }
  /* El área de toque real son 44 px, la mínima recomendada, sin que el punto
     crezca ni separe a los demás. */
  .tarjetas-punto::after {
    content: "";
    position: absolute;
    inset: -1.2rem -.4rem;
  }
}

/* Por encima del salto no hay carril ni puntos: cada grupo vuelve a su rejilla
   sin que haya que deshacer nada, porque todo lo anterior vive dentro de la
   consulta de medios. */
@media (min-width: 761px) {
  .tarjetas-mandos { display: none; }
}

/* ==========================================================================
   Portal del equipo (CRM a pantalla completa, sin salir del sitio)
   Lo monta site.js al pulsar "Iniciar sesión". Colores fijos y no variables:
   el portal flota sobre secciones .claro y oscuras por igual.
   ========================================================================== */
.portal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  flex-direction: column;
  background: #08070A;
  opacity: 0;
  visibility: hidden;
  transform: scale(.985);
  transition: opacity .35s ease, transform .35s cubic-bezier(.16, 1, .3, 1), visibility 0s linear .35s;
}
.portal.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .35s ease, transform .35s cubic-bezier(.16, 1, .3, 1), visibility 0s;
}
.portal__barra {
  flex: none;
  height: 44px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: #08070A;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  color: #FFFFFF;
}
.portal__titulo { font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 14px; letter-spacing: .04em; }
.portal__titulo span { color: #A9A9B2; font-weight: 500; letter-spacing: 0; }
.portal__cerrar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 999px;
  background: transparent;
  color: #FFFFFF;
  font: 600 13px/1 'Inter', sans-serif;
  cursor: pointer;
  transition: border-color .2s, color .2s;
}
.portal__cerrar:hover, .portal__cerrar:focus-visible { border-color: #F2B02F; color: #F2B02F; }
.portal__cerrar span { font-size: 18px; line-height: 1; }
.portal__marco { flex: 1; width: 100%; border: 0; background: #0F0F11; }
@media (max-width: 560px) { .portal__titulo span { display: none; } }
@media (prefers-reduced-motion: reduce) { .portal, .portal.is-open { transition: none; transform: none; } }
