/* ═══════════════════════════════════════════════════════════════════════
   LA PORTADA NUEVA de Fluidity — composición (bloques 03 a 08, 7 sep 2026)

   Los cimientos están en css/cara-nueva.css (tokens con las dos caras, reset,
   fuentes, interruptor) y las piezas del corte en css/corte.css. Aquí vive
   SOLO la composición de la portada.

   Reglas de la casa, heredadas del bloque 01:
   · claro es el tema principal; el oscuro sale de light-dark() en los tokens,
     así que aquí no hay ni una regla por tema;
   · cero JavaScript para la presentación: lo que se mueve lo mueve el scroll
     con animation-timeline nativo, y lo que no se soporta degrada con @supports;
   · nada se esconde esperando a un script.

   🔴 POR QUÉ scroll(root) Y NO view(). El hero es lo PRIMERO de la página, así
   que el scroll del documento ES su progreso, y los rangos se escriben en vh,
   que son legibles y verificables uno a uno. `view()` mediría la entrada del
   elemento en el viewport, que aquí no aporta nada y complica los rangos de un
   elemento más alto que la ventana. Si algún día el hero deja de estar arriba
   del todo, esto hay que cambiarlo a un view-timeline con nombre.
   ═══════════════════════════════════════════════════════════════════════ */

@layer reset, base, layout, componentes, motion;

@layer base {
  :root {
    /* 🔴 El hero vuelve a UNA pantalla. Medía 250svh porque el corte necesitaba
       ese recorrido para abrirse; sin corte, dos pantallas y media de scroll
       enseñando lo mismo es hacer bajar al visitante para nada. El movimiento
       ahora es del propio loop, no del scroll. */
    --hf-alto: auto;
    /* 🔴 Las fases del recorrido, y el techo que las limita.
       El hero mide --hf-alto y se pega arriba, así que el scroll que produce es
       (--hf-alto − 100vh) = 150vh. Medido: 154vh con el header. Cualquier rango
       que pase de ahí NUNCA se alcanza — el gas terminaba en 175vh y no se
       encendía jamás. Todos los rangos caben ahora en 150vh, así que el hero
       cuenta su historia entera esté solo o con secciones debajo. */
    /* El cruce foto → corte solapa MUCHO a propósito. Medido con los dos a
       la vez: con la foto acabando en 55 y el corte empezando en 42, a mitad
       del cruce sumaban 0,35 de opacidad entre los dos y se abría un valle en
       el que el hueco quedaba casi vacío. Entrando el corte en 26 el mínimo
       sube a 0,67 y el relevo se lee como un cambio, no como un parpadeo. */
    --hf-foto-fin: 48vh;      /* la foto termina de irse */
    --hf-corte-ini: 26vh;     /* el corte empieza a entrar, muy solapado */
    --hf-encaje-ini: 42vh;    /* y sus partes empiezan a encajar */
    --hf-corte-fin: 103vh;    /* todas las partes han encajado */
    --hf-gas-ini: 101vh;      /* el gas detenido se apaga */
    --hf-gas-fin: 148vh;      /* el gas ha recorrido el conducto entero */
    /* El loop2.0 se midió del vídeo original en 10,8 % de recorrido y 6,43 s
       de ciclo. El 9 sep 2026 el hero pasa de 3 series a 6, y para que las seis
       quepan sin alargar la vuelta se acortan LAS DOS COSAS A LA VEZ:
       recorrido y ciclo a la mitad.

       🔴 Por qué a la vez y no solo el tiempo: velocidad = recorrido ÷ ciclo.
       Acortando solo el ciclo la pieza se mueve al doble y se lee nerviosa;
       acortando ambos la velocidad NO cambia — flota igual de tranquila en un
       arco más corto. Es un péndulo más corto, no uno acelerado.

       Y el intervalo sigue siendo EXACTAMENTE un ciclo, así que el vuelo no se
       puede cortar a medias: es el defecto nº 1 que documentó silenciadores.

       La vuelta completa sigue durando 19,29 s — lo mismo que hoy tardan tres
       series— con el doble de producto dentro. */
    --ciclo: 3.215s;
    --ciclo6: 19.29s;
    --ease-mec: cubic-bezier(.16,.84,.24,1);   /* entra rápido y se asienta */
    --top-alto: 69px;                          /* medido: el alto de la cabecera sticky */
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   HERO — dos pantallas: la pieza real y, al bajar, el corte que se abre
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .hf { position: relative; }

  /* ya no se pega: sin recorrido que acompañar, un sticky de una sola pantalla
     no hace nada salvo complicar el apilado */
  .hf__pega {
    min-height: calc(100svh - var(--top-alto));
    display: grid;
    grid-template-columns:
      [borde-i] var(--container-padding)
      [texto-i] repeat(12, minmax(0, 1fr))
      [borde-d] var(--container-padding);
    grid-template-rows: auto auto 1fr auto auto;
    grid-template-areas:
      ". num  num  num  num  num  num  num  vis vis vis vis vis ."
      ". eye  eye  eye  eye  eye  eye  eye  vis vis vis vis vis ."
      ". tit  tit  tit  tit  tit  tit  tit  vis vis vis vis vis ."
      ". lead lead lead lead cta  cta  cta  vis vis vis vis vis ."
      ". sell sell sell sell sell sell sell vis vis vis vis vis .";
    column-gap: clamp(12px, 2vw, 28px);
    align-items: end;
    /* 🔴 La cabecera es sticky y mide 69 px: con solo --space-xl arriba, el
       número de sección quedaba 29 px por debajo de ella y se veía cortado por
       la mitad. El hero arranca por debajo de la cabecera, no detrás. */
    padding-block: calc(var(--top-alto) + var(--space-md)) var(--space-2xl);
    isolation: isolate;
    overflow: clip;   /* el corte sangra dentro del hero, no fuera de la página */
  }

  .hf__num  { grid-area: num; align-self: start; }
  .hf__eye  { grid-area: eye; }
  .hf__tit  { grid-area: tit; }
  .hf__lead { grid-area: lead; }
  .hf__cta  { grid-area: cta; align-self: end; }
  .hf__sellos { grid-area: sell; }
  .hf__vis  { grid-area: vis; align-self: stretch; }

  /* ── numeración editorial ── */
  /* el 01 del hero, con el mismo criterio que el resto de secciones */
  .hf__num {
    font-family: var(--font-mono);
    font-size: clamp(56px, 8vw, 116px); font-weight: 400; line-height: 1;
    color: var(--brand-text);
    user-select: none;
  }

  .hf__eye {
    font-family: var(--font-mono);
    font-size: 12px; letter-spacing: .22em; text-transform: uppercase;
    color: var(--brand-text);
    display: flex; align-items: center; gap: 12px;
    margin-top: var(--space-md);
  }
  .hf__eye::before { content: ""; width: 28px; height: 1px; background: var(--brand); }

  /* ── el elemento firma tipográfico: la escala, no una familia nueva ──
     mínimo 52 px y no 56: «Electroválvulas» mide 6,45 em y a 56 son 361 px,
     18 más que la columna de un móvil de 375. */
  /* 🔴 El TOPE lo pone el generador, no esta hoja. Un `clamp(...,120px)` fijo
     trata igual a «Purga temporizada» —17 caracteres, 2 líneas— y a «Válvula de
     pulso 09F para limpieza de colectores de polvo», que a 120 px se comía
     cinco líneas y sacaba el hero de la pantalla. `--tit-max` sale de
     `topeTitular()`, calibrado con la landing aprobada: fluidity pone 39
     caracteres en 3 líneas a 8.4vw, así que 8.4 sigue siendo el tope de lo que
     ya cabe y solo baja lo que no. Va en vw y no en px porque quien decide
     cuántas líneas salen es el ancho de la columna — y acompañado de
     `--tit-alto` en vh, que es quien manda en una ventana baja, donde lo que
     falta no es anchura sino sitio debajo. */
  .hf__tit {
    font-size: clamp(52px, min(var(--tit-max, 8.4vw), var(--tit-alto, 100vh)), 120px);
    font-weight: 600; line-height: .94; letter-spacing: -.045em;
    text-wrap: balance; margin-top: var(--space-md);
  }
  .hf__tit em {
    font-style: normal; color: var(--brand-text);
    font-family: var(--font-mono); font-weight: 400; letter-spacing: -.02em;
  }

  .hf__lead {
    font-size: clamp(16px, 1.25vw, 19px); line-height: 1.5;
    color: var(--muted); max-width: 46ch;
    margin-top: var(--space-lg); text-wrap: pretty;
  }

  /* Los CTA no se parten en dos líneas: «Encuentra tu serie» caía en dos con
     dos columnas de grid, y un botón partido se lee como un error de maqueta.
     Con tres columnas y nowrap entra entero en todos los anchos medidos. */
  .hf__cta { display: grid; gap: 10px; justify-items: start; margin-top: var(--space-lg); }
  .hf__cta .btn { white-space: nowrap; }

  /* ── los sellos de confianza, como DATO y no como sección aparte ── */
  .hf__sellos {
    display: flex; flex-wrap: wrap; gap: 10px 22px;
    margin-top: var(--space-xl); padding-top: var(--space-md);
    border-top: 1px solid var(--line);
    font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .08em;
    color: var(--muted);
    /* 🔴 SIN `text-transform: uppercase`. En mayúsculas «500 µm» se convierte
       en «500 ΜM» —la µ mayúscula es la mu griega, que se lee como M— o sea
       micras publicadas como MILÍMETROS, factor 1000, en un dato de filtración
       y en el hero. El DOM era correcto, así que ningún verificador lo veía:
       salió mirando la página. El texto se escribe en el payload tal y como
       debe leerse, que además es lo que corresponde a un dato técnico. */
  }
  .hf__sellos li { display: flex; align-items: center; gap: 8px; }
  .hf__sellos li::before {
    content: ""; width: 5px; height: 5px; border-radius: 50%;
    background: var(--brand); flex: none;
  }
  .hf__sellos b { color: var(--text); font-weight: 600; letter-spacing: .04em; }
}

/* ═══════════════════════════════════════════════════════════════════════
   EL VISUAL — la pieza y su corte, tres series
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .hf__vis {
    position: relative;
    min-height: clamp(420px, 60svh, 700px);
    /* sangra hasta el borde de la ventana. Hay que descontar el padding del
       contenedor Y el column-gap del grid: con solo el padding quedaban 28 px
       de aire a 1440 y la pieza no llegaba a sangre. Medido, no supuesto. */
    margin-right: calc(-1 * (var(--container-padding) + clamp(12px, 2vw, 28px)));
    /* el halo: derivado del rojo de marca, no un color escrito a mano, y no la
       capa `glow` del loop2.0 — esa está calculada para fondo oscuro */
    background: radial-gradient(58% 52% at 52% 48%, var(--brand-suave), transparent 72%);
  }
  .hf__serie { position: absolute; inset: 0; }

  /* la foto: SOLO producto y sombra. `fondo` es un rectángulo de estudio
     oscuro y `glow` va en modo screen: las dos están calculadas para fondo
     negro y sobre papel dibujan una mancha. */
  .hf__foto { position: absolute; inset: 0; }
  /* 🔴 Con chips dentro, `.hf__foto` DEJA de ser el hueco y pasa a ser el
     lienzo: mismo ancho y alto que la imagen dibujada por `contain`, centrada.
     Sin esto un `top: 8%` es el 8% del hueco —que en 09F empieza 121 px por
     encima de la foto— y el chip acota el aire. `min()` reproduce lo que hace
     `contain`: manda el ancho, salvo que el alto se agote antes. */
  /* 🔴 Aquí se probó `container-type: size` + `100cqh`, y se cayó: en 375 la
     consulta devolvía CERO —la contención se resuelve antes que el alto del
     contenedor— y la foto salía 0x0, o sea el hero SIN PIEZA. En escritorio no
     se veía porque el `min()` ganaba por el otro lado. Lo que sí funciona sin
     depender de nada: que la caja la dicte la propia imagen. La capa de
     producto va EN FLUJO con `max-*: 100%`, así que `.hf__foto` con
     `fit-content` mide exactamente lo dibujado; el resto de capas se apilan
     encima en absoluto. */
  .hf__foto:has(> .dato) {
    inset: 0; margin: auto;
    width: fit-content; height: fit-content;
    max-width: 100%; max-height: 100%;
  }
  .hf__foto:has(> .dato) > .hf__capa--producto {
    position: relative; display: block;
    width: auto; height: auto; max-width: 100%; max-height: 100%;
  }
  .hf__capa {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: contain; object-position: center;
  }
  .hf__capa--sombra { opacity: .55; }

  /* el corte, en el mismo hueco que la foto */
  /* El corte respira dentro del hueco: sin este margen las bocas del cuerpo
     llegaban al borde sangrado y `overflow: clip` del contenedor las cortaba a
     la mitad. El corte es la firma; recortarlo es lo contrario de enseñarlo. */
  /* El corte ya no vive en el hero (Mario, 7 sep 2026). Sus estilos de
     colocación se van con él a la ficha de serie; lo que queda aquí es el
     estado degradado de más abajo, por si el hero volviera a montarlo. */

  /* ── las etiquetas de dato ──
     Van en posición porcentual sobre el visual, que es lo que ya se midió sin
     overflow en los cinco anchos. Donde el navegador trae anchor positioning
     se anclan de verdad a la caja del visual, que las mantiene pegadas a la
     pieza cuando el hueco cambia de proporción. */
  /* El aire va corto a propósito (Mario, 9 sep 2026, viéndolo montado): un chip
     con 8/12 de relleno y una línea de 200 px se lee como una etiqueta suelta
     al lado de la foto, no como una acotación de la pieza. */
  .dato {
    position: absolute; display: grid; gap: 1px; padding: 5px 9px;
    background: color-mix(in srgb, var(--bg-2) 86%, transparent);
    backdrop-filter: blur(10px);
    border: 1px solid var(--line); border-radius: 8px;
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); white-space: nowrap;
    box-shadow: var(--shadow-card);
  }
  .dato b { font-size: 15px; letter-spacing: 0; text-transform: none; color: var(--text); font-weight: 600; }
  .dato::before {
    content: ""; position: absolute; width: var(--l, 48px); height: 1px;
    background: linear-gradient(90deg, var(--brand), transparent); top: 50%;
  }
  .dato--i::before { right: 100%; }
  .dato--d::before { left: 100%; transform: scaleX(-1); }
  .dato--1 { top: 10%; left: 3%;    --l: 56px; }
  .dato--2 { top: 36%; right: 5%;   --l: 44px; }
  .dato--3 { bottom: 32%; left: 2%; --l: 64px; }
  .dato--4 { bottom: 10%; right: 9%; --l: 40px; }

  /* ── PRODUCTO ÚNICO: los datos señalan HACIA DENTRO ──
     🔴 Con varias series el chip vive al borde y su línea sale hacia afuera:
     la pieza cambia de silueta en cada diapositiva, así que una línea que
     apunte a un punto concreto acertaría en una y fallaría en las otras cinco.
     Con UNA sola pieza eso deja de ser cierto, y Mario lo vio en la purga: los
     datos quedaban pegados a la foto y sus líneas se iban por fuera, sin
     señalar nada.

     Aquí la línea se invierte —nace en el chip y entra en la foto— y se alarga,
     que es lo que convierte una etiqueta suelta en una acotación. Y los chips
     se van al borde del contenedor para devolverle aire a la pieza.

     Va acotado a la hija única a propósito: fluidity está aprobada y en
     producción con el trato de carrusel, y ese trato es correcto ahí. */
  /* ── LAS ACOTACIONES ──────────────────────────────────────────────────
     La piel pone el MECANISMO —dónde nace la línea y hacia dónde va—; el
     payload pone la GEOMETRÍA, porque es de la foto y no del molde: la pieza
     de 09F ocupa x 30-71% de su lienzo (bandas vacías a los lados) y la de la
     purga x 15-86% (bandas arriba y abajo). Unos porcentajes escritos aquí
     solo podrían servir a una de las dos. */
  .dato[style*="--x"] {
    top: var(--y); left: var(--x); right: auto; bottom: auto;
  }
  .dato--i, .dato--d { translate: 0 -50%; }
  .dato--a, .dato--b { translate: -50% 0; }
  .dato--i { translate: -100% -50%; }          /* el chip queda a la IZQUIERDA */
  .dato--i::before { left: 100%;  width: var(--l); transform: scaleX(-1); }
  .dato--d::before { right: 100%; width: var(--l); }
  .dato--a::before, .dato--b::before {
    width: 1px; height: var(--l); left: 50%; right: auto;
  }
  .dato--a::before { top: 100%;                 /* el chip está ARRIBA */
    background: linear-gradient(180deg, var(--brand), transparent); }
  .dato--b::before { bottom: 100%;              /* el chip está ABAJO */
    background: linear-gradient(0deg, var(--brand), transparent); }

  .hf__leyenda {
    position: absolute; right: var(--container-padding); bottom: 0;
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .18em;
    text-transform: uppercase; color: var(--muted);
  }
  .hf__leyenda b { color: var(--text); font-weight: 600; }
}

/* ── 🔴 POR QUÉ AQUÍ NO SE USA ANCHOR POSITIONING ──
   Se montó y se midió, y el resultado fue peor: las etiquetas y la pieza viven
   DENTRO del mismo contenedor posicionado, que es justo el caso en que
   `anchor()` no aporta —sirve para anclar entre contenedores distintos— y al
   resolver contra la caja del ancla los cuatro `top` computados se colapsaban a
   0. Las posiciones porcentuales de abajo ya están medidas dentro de la ventana
   en los cinco anchos, con y sin la mejora.

   Se anota en vez de borrarse en silencio: el plan lo pedía «con degradación»,
   y la degradación de algo que no aporta es no usarlo. Si algún día las
   etiquetas salen del contenedor de la pieza, este es el sitio donde vuelve. */

/* ═══════════════════════════════════════════════════════════════════════
   MOVIMIENTO — mecánico. Nada levita: las partes se desplazan en su eje,
   encajan y se asientan. Todo ligado al scroll, cero JavaScript.
   ═══════════════════════════════════════════════════════════════════════ */
@layer motion {

  /* ═══════════════════════════════════════════════════════════════════
     EL LOOP 2.0 — la pieza flotando, con el movimiento medido del original

     🔴 Vuelve, y revierte una decisión del plan. El plan decía «movimiento
     mecánico, la levitación se retira: una válvula no flota». Mario, viéndolo
     montado, decidió lo contrario el 7 sep 2026: en el hero quiere la pieza
     real flotando y nada más. Y tiene el argumento a favor: el loop 2.0 lleva
     desde el 17 ago en producción en las dos fluidity —comprobado hoy contra
     el servidor: el JS servido referencia sus capas y las cuatro responden
     200— y es lo que ya funciona.

     Las cifras NO son de gusto: salen de medir 121 fotogramas del vídeo
     original que el loop 2.0 sustituyó. Recorrido 10,79 % del encuadre, ciclo
     6,43 s, y subida en el 42 % del ciclo contra bajada en el 58 %. Esa
     asimetría es lo que se lee como impulso y asentamiento; con 50/50 parece
     un metrónomo.

     El recorrido va en PORCENTAJE, no en píxeles: así el gesto es el mismo en
     cualquier pantalla. Con px fijos, cuanto más grande el hero menos se movía.
     ═══════════════════════════════════════════════════════════════════════ */
  @media (prefers-reduced-motion: no-preference) {
    .hf__capa--producto {
      animation: hf-flota var(--ciclo) infinite cubic-bezier(.45,.05,.55,.95);
    }
    /* la sombra va en CONTRAFASE: se encoge y se aclara cuando la pieza sube.
       Sin eso el producto no levita, se desliza. */
    .hf__capa--sombra {
      animation: hf-asienta var(--ciclo) infinite cubic-bezier(.45,.05,.55,.95);
      transform-origin: 50% 100%;
    }
    /* recorrido a la mitad (5,4 % total contra 10,8 %), y la asimetría 42/58
       intacta: es lo que se lee como impulso y asentamiento. */
    @keyframes hf-flota   { 0%, 100% { transform: translateY(2.7%); }
                            42%      { transform: translateY(-2.7%); } }
    /* la sombra acompaña en contrafase, con su delta también a la mitad */
    @keyframes hf-asienta { 0%, 100% { transform: scale(1.02); opacity: .50; }
                            42%      { transform: scale(.95);  opacity: .38; } }
  }


  /* ── LA ROTACIÓN DE LAS TRES SERIES ──
     Cambio por DESPLAZAMIENTO, no por fundido: la serie que sale se va por la
     izquierda y la que entra llega desde la derecha y se asienta. El ciclo es
     el del loop2.0 —6,43 s por serie, 19,29 s las tres— medido del vídeo
     original que esto sustituye.

     La opacidad solo acompaña al desplazamiento para que el salto de posición
     entre el final y el principio del ciclo ocurra con la pieza ya invisible. */
  .hf__serie {
    opacity: 0;
    animation: hf-rota var(--ciclo6) infinite var(--ease-mec);
  }
  /* 🔴 Los desfases van en múltiplos de UN ciclo, no de tres. El ciclo entero
     dura 3 × 6,43 s, así que un retraso de −3 ciclos es un desfase de CERO: con
     −0,15c / −3,15c / −6,15c las tres series aparecían a la vez, superpuestas,
     y a simple vista parecía una sola. Lo cazó medir la animación, no mirarla.
     El −0,15 común adelanta el arranque para que la primera serie ya esté
     puesta cuando la página carga, en vez de entrar desde fuera. */
  /* ── UNA SOLA PIEZA NO ROTA ──
     🔴 Con un único producto la rotación no es que sobre: es que hace daño.
     La animación sigue corriendo su ciclo completo y la pieza solo está en
     cuadro el 14,7 % del tiempo —el resto es un hueco en negro esperando a
     que «vuelva» algo que nunca se fue—. Mario lo vio en la purga temporizada
     el 9 sep 2026: «hay un espacio y un tiempo en blanco hasta que vuelve a
     cargar la imagen».

     Se apaga por ESTRUCTURA, no por una clase que haya que acordarse de
     poner: si la pieza es hija única, no hay carrusel. La levitación se queda
     —el movimiento que sí cuenta algo— y con ella su sombra en contrafase. */
  .hf__vis:has(> .hf__serie:only-child) .hf__serie {
    animation: none;
    opacity: 1;
    translate: 0 0;
  }

  .hf__serie:nth-child(1) { animation-delay: calc(var(--ciclo) * -0.15); }
  .hf__serie:nth-child(2) { animation-delay: calc(var(--ciclo) * -1.15); }
  .hf__serie:nth-child(3) { animation-delay: calc(var(--ciclo) * -2.15); }
  .hf__serie:nth-child(4) { animation-delay: calc(var(--ciclo) * -3.15); }
  .hf__serie:nth-child(5) { animation-delay: calc(var(--ciclo) * -4.15); }
  .hf__serie:nth-child(6) { animation-delay: calc(var(--ciclo) * -5.15); }
  /* Con SEIS series cada una ocupa 1/6 = 16,667 % del ciclo largo, no 1/3.
     Los porcentajes son los de antes divididos entre dos: si se dejan los de
     tres, cada serie se queda puesta el doble de lo que le toca y se solapan
     de dos en dos — que es la misma familia de fallo que el desfase de −3
     ciclos, y tampoco se ve a simple vista. */
  @keyframes hf-rota {
    0%      { opacity: 0; translate: 26% 0; }
    2%      { opacity: 1; translate: 0 0; }
    14.65%  { opacity: 1; translate: 0 0; }
    16.667% { opacity: 0; translate: -26% 0; }
    16.677% { opacity: 0; translate: 26% 0; }
    100%    { opacity: 0; translate: 26% 0; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   RESPONSIVE — el hero se apila y la pieza va a sangre
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  /* ── ventanas BAJAS: el hero respira menos ───────────────────────────
     Medido el 9 sep 2026 a 1280x800: el hero de 09F terminaba 14 px por debajo
     del borde y el de fluidity —la aprobada— 74. O sea que el desbordamiento en
     pantallas bajas es PREVIO y afecta a las dos; lo que lo destapó fue meter
     un titular más largo. El aire de arriba y el de los sellos son lo que sobra
     ahí, y recortarlos no toca la composición en 900, donde nada de esto se
     aplica. */
  @media (min-width: 1001px) and (max-height: 860px) {
    .hf__pega { padding-top: 56px; padding-bottom: 48px; }
    .hf__sellos { margin-top: 24px; }
  }

  @media (max-width: 1000px) {
    .hf { height: auto; }
    .hf__pega { position: static; min-height: auto; }
    /* minmax(0,1fr) y no 1fr: un 1fr no baja de su min-content y la palabra
       más larga del titular ensancharía el grid en una ventana de 375. */
    .hf__pega {
      grid-template-columns: var(--container-padding) minmax(0, 1fr) var(--container-padding);
      grid-template-areas: ". num ." ". vis ." ". eye ." ". tit ." ". lead ." ". cta ." ". sell .";
      grid-template-rows: repeat(7, auto);
      align-items: start;
    }
    .hf__vis { grid-column: 1 / -1; margin-inline: 0; min-height: 56svh; }
    .hf__num { font-size: 56px; }
    .dato { font-size: 10px; padding: 6px 9px; }
    .dato b { font-size: 13px; }
    /* las líneas conectoras asomaban 40-64 px por fuera del borde: en móvil la
       etiqueta ya está pegada a la pieza y la línea no aporta */
    .dato::before { display: none; }
    /* 🔴 En móvil NO se acota: se reparte. El lienzo llena la ventana, así que
       no queda banda libre donde poner un chip fuera de la pieza, y los que
       comparten franja se solapan —«500 µm» encima de «Latón CW617N», medido a
       375—. Vuelven las cuatro esquinas, que es lo que ya estaba resuelto.
       La especificidad tiene que ganar a `.dato[style*="--x"]`: sin el
       `[style]` la posición en línea sigue mandando y el chip más largo se sale
       9 px por la izquierda. */
    .dato[style].dato--1 { top: 7%;  left: 3%;  right: auto; bottom: auto; translate: none; }
    .dato[style].dato--2 { top: 29%; right: 3%; left: auto;  bottom: auto; translate: none; }
    .dato[style].dato--3 { bottom: 26%; left: 2%; right: auto; top: auto;  translate: none; }
    .dato[style].dato--4 { bottom: 7%;  right: 4%; left: auto; top: auto;  translate: none; }
    .dato--1 { top: 7%;  left: 3%; }
    .dato--2 { top: 29%; right: 3%; }
    .dato--3 { bottom: 26%; left: 2%; }
    .dato--4 { bottom: 7%;  right: 4%; }
    /* 🔴 A 375 el `nowrap` de la etiqueta la sacaba de la ventana y el visual la
       recortaba: «1/8" · 1/4" · 3/8" · 1/2"» se leía sin su última medida. Es el
       mismo defecto de los chips de spec truncados que este proyecto ya cerró
       una vez. En móvil las etiquetas envuelven y ninguna pasa de media pantalla. */
    /* 🔴 A 375 el chip de «Temperatura» —el más largo— salía 9 px por la
       izquierda: la acotación lo ancla por su borde derecho y en móvil el
       lienzo llena la ventana, así que no queda sitio hacia fuera. El tope no
       se elige a ojo: con 44vw de ancho máximo, anclar el borde derecho en
       46vw deja el chip dentro por construcción, y lo mismo por el otro lado.
       Sin esto el dato se lee cortado, que es el defecto que este proyecto ya
       cerró una vez en los chips de spec. */
    .dato { white-space: normal; max-width: 52vw; }
    .hf__leyenda { left: var(--container-padding); text-align: right; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MOVIMIENTO REDUCIDO — el corte abierto y quieto, una serie fija,
   los fundidos se conservan (Windows lo trae activado de fábrica).
   ═══════════════════════════════════════════════════════════════════════ */
@layer motion {
  @media (prefers-reduced-motion: reduce) {
    .hf__foto { animation: none !important; opacity: .2; filter: saturate(.4) contrast(.9) brightness(.85); }
    /* el corte salió del hero: su estado reducido vive donde vive el corte */
    /* una sola serie, fija, con sus datos */
    .hf__serie { animation: none !important; }
    .hf__serie:nth-child(1) { opacity: 1; translate: 0 0; }
    .hf__serie:not(:nth-child(1)) { display: none; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   SECCIONES — la cabecera numerada común a las siete
   El ritmo vertical sale de la escala del taller: el aire ENTRE secciones
   (--space-3xl) supera al aire entre hermanas (--space-lg), y la cabecera
   queda más cerca de su contenido que de la sección anterior. Es proximidad,
   no decoración: sin esa diferencia la página no sabe decir «aquí empezó
   otro tema».
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .sec {
    padding-block: var(--space-3xl);
    padding-inline: var(--container-padding);
    border-top: 1px solid var(--line);
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xl);
  }
  /* 🔴 El número va en ROJO DE MARCA, en los dos temas. Decisión de Mario,
     7 sep 2026: en hueco con el trazo del color de línea casi no se veía sobre
     el fondo claro — el contorno medía 1 px de un gris al 24 % de opacidad, que
     sobre papel es prácticamente nada. En rojo el número deja de ser una marca
     de agua y pasa a ser lo que ordena la página.
     Se pinta con --brand-text y no con --brand: es texto, y el rojo de marca
     como texto da 3,92 sobre el fondo oscuro cuando AA pide 4,5. */
  .sec__num {
    font-family: var(--font-mono); font-size: clamp(40px, 5vw, 72px); line-height: 1;
    color: var(--brand-text); user-select: none;
  }
  .sec__cab { display: grid; gap: var(--space-md); max-width: 62ch; }
  .sec__tit {
    font-size: clamp(32px, 4.4vw, 60px); font-weight: 600; line-height: 1.02;
    letter-spacing: -.035em; text-wrap: balance;
  }
  .sec__tit em { font-style: normal; color: var(--brand-text); }
  .sec__lead { color: var(--muted); font-size: clamp(15px, 1.1vw, 17px); line-height: 1.55; text-wrap: pretty; }
  .sec__sub {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .18em;
    text-transform: uppercase; color: var(--brand-text);
  }

  /* ── la barra de cifras: el dato como elemento gráfico ── */
  .cifras { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: 1px solid var(--line); }
  .cifras li {
    display: grid; gap: 8px; align-content: start;
    padding: var(--space-lg) var(--space-lg) var(--space-lg) 0;
    margin-right: var(--space-lg); border-right: 1px solid var(--line);
  }
  .cifras li:last-child { border-right: 0; margin-right: 0; }
  /* La cuarta cifra es una lista de cinco sellos y ocupa tres líneas a 28 px.
     Las cifras cortas mandan el tamaño y la larga baja sola con la unidad de
     container: es la misma celda, no una excepción escrita a mano. */
  .cifras li { container-type: inline-size; }
  .cifras b { font-family: var(--font-mono); font-weight: 400;
              font-size: clamp(17px, 7cqi, 28px);
              line-height: 1.15; letter-spacing: -.02em; overflow-wrap: break-word; }
  .cifras span { font-size: 13px; color: var(--muted); line-height: 1.45; text-wrap: pretty; }
  @media (max-width: 900px) {
    .cifras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cifras li:nth-child(2) { border-right: 0; margin-right: 0; }
  }

  /* ── series: filtro pegajoso a la izquierda, rejilla a la derecha ── */
  .series { display: grid; grid-template-columns: minmax(220px, 3fr) 9fr; gap: clamp(20px, 3vw, 56px); align-items: start; }
  .series__aside { position: sticky; top: 84px; }
  /* 🔴 Sin filtro, la rejilla ocupa el ancho entero. Con `3fr 9fr` fijo, una
     landing cuyo filtro se cae —porque ninguno de sus chips devolvía nada—
     dejaba una columna vacía del 25 % a la izquierda. El contenedor no está,
     pero la RESERVA de su columna sí: es el hueco de una sección retirada, un
     nivel más abajo. */
  .series:not(:has(> .series__aside)) { grid-template-columns: minmax(0, 1fr); }
  @media (max-width: 1000px) { .series { grid-template-columns: minmax(0, 1fr); } .series__aside { position: static; } }

  .filtro { display: grid; gap: 2px; }
  .filtro__tit { font-family: var(--font-mono); font-size: 11px; letter-spacing: .18em;
                 text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
  .filtro label {
    display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px;
    padding: 11px 0; border-bottom: 1px solid var(--line);
    font-size: 16px; font-weight: 500; cursor: pointer;
    transition: color .2s, padding-left .25s var(--ease-out), border-color .2s;
  }
  .filtro label small { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }
  /* el radio real, fuera de pantalla pero enfocable: el filtro funciona con
     teclado y sin JavaScript, que es de lo que se trata */
  .filtro input { position: absolute; opacity: 0; pointer-events: none; }
  .filtro input:checked + label { color: var(--brand-text); padding-left: 12px; border-color: var(--brand); }
  .filtro input:focus-visible + label { outline: 2px solid var(--focus); outline-offset: 3px; }

  .rejilla { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
             gap: var(--space-lg); align-items: start; }

  /* ── la tarjeta responde a SU ancho, no al de la ventana ── */
  .tj {
    container-type: inline-size; container-name: tj;
    display: grid; gap: 12px; padding: 16px;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-md);
    transition: border-color .25s, background .25s, opacity .35s, scale .35s var(--ease-out), filter .35s;
  }
  .tj:hover { border-color: var(--line-strong); background: var(--panel-strong); }
  .tj:focus-within { outline: 2px solid var(--focus); outline-offset: 3px; }
  .tj__enlace { display: grid; gap: 12px; }
  .tj__media { display: block; aspect-ratio: 1.6; border-radius: 10px; overflow: hidden;
               background: radial-gradient(62% 62% at 50% 58%, var(--brand-suave), transparent 72%);
               display: grid; place-items: center; }
  /* 🔴 Limitar SOLO por ancho corta las piezas altas. Medido el 9 sep 2026 en
     la purga: la caja es `aspect-ratio: 1.6`, o sea 0,625 de alto, y con
     `width: 82%` el temporizador analógico —390x636— ocupa 1,34. `overflow:
     hidden` se comía la mitad de la pieza, y con ella el encuadre del que sale
     la transición hacia la ficha: por eso el viaje no era fluido justo en las
     tarjetas altas. Se salían TRES de cada cuatro; la única que cabía era la
     válvula, apaisada. Limitando por las dos, manda la dimensión que primero
     toca el borde y la pieza entra entera sea cual sea su forma. */
  .tj__media img {
    width: auto; height: auto; max-width: 82%; max-height: 82%;
    object-fit: contain;
    /* 🔴 `min-height: 0` NO es decorado: sin él, `max-height` no se cumple. La
       foto es un ítem de grid y un ítem de grid trae `min-*: auto`, o sea que
       no baja de su tamaño de contenido por mucho máximo que le pongas — la
       misma trampa del `minmax(0, 1fr)` que ya muerde en el titular del hero.
       Medido: 185x302 con el máximo puesto, 86x141 al añadir esta línea. */
    min-width: 0; min-height: 0;
  }
  .tj__cab { display: grid; gap: 4px; }
  .tj__serie { font-family: var(--font-mono); font-size: 11px; letter-spacing: .18em;
               text-transform: uppercase; color: var(--brand-text); }
  .tj__nom { font-size: 19px; font-weight: 600; letter-spacing: -.015em; line-height: 1.15; }
  .tj__desc { font-size: 13.5px; color: var(--muted); line-height: 1.45; }
  .tj__chips { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .chip { display: grid; gap: 2px; padding: 8px 10px; border-radius: 8px;
          background: var(--panel); border: 1px solid var(--line); min-width: 0; }
  .chip small { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
                text-transform: uppercase; color: var(--muted); }
  /* 🔴 sin nowrap ni overflow hidden: en una landing técnica un rango de
     temperatura sin su valor máximo no es información degradada, es
     información ausente. El valor pasa a dos líneas donde no cabe. */
  .chip b { font-size: 13px; font-weight: 600; overflow-wrap: break-word; }

  /* tres columnas de chips cuando la tarjeta tiene sitio de sobra */
  @container tj (min-width: 400px) { .tj__chips { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
  /* y una sola cuando va justa: nunca más un valor partido a 68 px */
  @container tj (max-width: 250px) { .tj__chips { grid-template-columns: minmax(0, 1fr); } }
  /* sin @container: dos columnas, que es el caso que ya cabe en los cinco anchos */

  /* ── el filtro atenúa lo que no encaja, con :has() y sin una línea de JS ── */
  .series:has(#f-laton:checked) .tj:not([data-mat="laton"]),
  .series:has(#f-inox:checked)  .tj:not([data-mat="inox"]),
  .series:has(#f-tecno:checked) .tj:not([data-mat="tecno"]),
  .series:has(#f-otros:checked) .tj:not([data-mat="otros"]) {
    opacity: .26; scale: .98; filter: saturate(.25);
  }
}

@layer motion {
  /* reveal ligado al scroll, nativo. Sin soporte de view() la regla entera no
     aplica y todo se ve: degradación sin red de seguridad porque no hace falta. */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .tj { animation: entra linear both; animation-timeline: view(); animation-range: entry 8% entry 42%; }
      @keyframes entra { from { opacity: 0; translate: 0 26px; } }
    }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   05 · EL ARGUMENTO — cuatro bloques donde hoy hay cinco secciones
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .arg { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2xl) var(--space-xl); }
  @media (max-width: 900px) { .arg { grid-template-columns: minmax(0, 1fr); } }
  .arg__bloque { display: grid; gap: var(--space-md); align-content: start; }
  .arg__tit { font-size: var(--fs-3); font-weight: 600; letter-spacing: -.01em; }
  .arg__lead { font-size: 14.5px; color: var(--muted); line-height: 1.55; text-wrap: pretty; }
  .arg__lista { display: grid; gap: 10px; }
  .arg__lista li { position: relative; padding-left: 20px; font-size: 14.5px; line-height: 1.55; color: var(--text); }
  .arg__lista li::before {
    content: ""; position: absolute; left: 0; top: .62em;
    width: 7px; height: 1px; background: var(--brand);
  }
  .arg__temas { display: grid; gap: 12px; }
  .arg__temas li { display: grid; gap: 4px; padding: 12px 14px; border-radius: var(--radius-sm);
                   background: var(--panel); border: 1px solid var(--line); }
  .arg__temas b { font-size: 14.5px; font-weight: 600; }
  .arg__temas span { font-size: 13.5px; color: var(--muted); line-height: 1.5; }

  /* ── el semáforo de materiales ──
     🔴 Color FUNCIONAL: cada aptitud tiene el suyo y ese color no decora nada
     más en la página. Un color que significa algo deja de significarlo en
     cuanto se usa de adorno. Y no es SOLO color: cada fila lleva su aptitud
     escrita, porque quien no distingue los tonos tiene que poder leerla. */
  .semaforo { display: grid; gap: 10px; }
  .sem {
    display: grid; grid-template-columns: auto 1fr; gap: 4px 12px;
    padding: 12px 14px 12px 16px; border-radius: var(--radius-sm);
    background: var(--panel); border: 1px solid var(--line);
    border-left: 3px solid var(--sem, var(--line-strong));
  }
  .sem__mat { font-size: 14.5px; font-weight: 600; grid-column: 1; }
  .sem__apt {
    grid-column: 2; justify-self: start; align-self: center;
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
    color: var(--sem-tx, var(--muted));
    border: 1px solid var(--sem, var(--line-strong)); border-radius: 999px; padding: 3px 9px;
  }
  .sem__txt { grid-column: 1 / -1; font-size: 13.5px; color: var(--muted); line-height: 1.5; }
  /* los tres colores del semáforo, con sus dos caras y medidos sobre panel */
  .sem--general  { --sem: light-dark(#1d6b45, #6fc79a); --sem-tx: light-dark(#155235, #8fd9b4); }
  .sem--agresivo { --sem: light-dark(#8a5a12, #e0ad5a); --sem-tx: light-dark(#6d4610, #eec48a); }
  .sem--ligero   { --sem: light-dark(#1e5f8a, #6fb6de); --sem-tx: light-dark(#164a6d, #8fcbea); }

  /* ── los cuatro tipos de accionamiento ── */
  .tipos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .tipos li { display: grid; gap: 4px; padding: 12px 14px; border-radius: var(--radius-sm);
              background: var(--panel); border: 1px solid var(--line); align-content: start; }
  .tipo__metrica { font-family: var(--font-mono); font-size: 15px; font-weight: 400; color: var(--brand-text); }
  .tipo__label { font-size: 14px; font-weight: 600; }
  .tipo__txt { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
  @container (max-width: 380px) { .tipos { grid-template-columns: minmax(0, 1fr); } }
}

/* ═══════════════════════════════════════════════════════════════════════
   06 · PROBLEMA → SOLUCIÓN — dos columnas que se contestan
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .ps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-lg); }
  @media (max-width: 860px) { .ps { grid-template-columns: minmax(0, 1fr); } }

  /* ── el corte energizable dentro de la sección 06 ──
     Debajo del problema y la solución, a todo el ancho: texto a la izquierda,
     el dibujo a la derecha.
     🔴 SIN `content-visibility`, y se probó. Reservaba 560 px mientras el
     bloque estaba fuera de pantalla y medía 728 al pintarse: la página saltaba
     168 px justo cuando alguien llegaba haciendo scroll —la primera captura lo
     pilló a medias, con el dibujo cortado—. Lo que ahorraba era pintar 10 KB de
     SVG; no compensa un salto donde se está mirando. */
  .ps__corte {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: calc(var(--space-md) * 2); align-items: center;
    margin-top: calc(var(--space-md) * 3); padding-top: calc(var(--space-md) * 2);
    border-top: 1px solid var(--line-strong);
  }
  .ps__corte-txt { display: grid; gap: var(--space-md); align-content: start; }
  .ps__corte-link {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--brand-text); text-decoration: none;
  }
  .ps__corte-link:hover, .ps__corte-link:focus-visible { text-decoration: underline; }
  @media (max-width: 900px) { .ps__corte { grid-template-columns: minmax(0, 1fr); } }
  .ps__col { display: grid; gap: var(--space-md); align-content: start;
             padding: var(--space-lg); border-radius: var(--radius-md); border: 1px solid var(--line); }
  /* La columna del problema va sobre superficie ALTA y la de la solución sobre
     el rojo de marca. En claro eso no puede ser «un panel oscuro» sin más: el
     texto se mide sobre el fondo compuesto, no sobre el color declarado. */
  .ps__col--problema { background: var(--panel-high); }
  .ps__col--solucion { background: var(--brand); border-color: var(--brand); color: var(--white); }
  /* 🔴 Blanco PURO, no al 88 %. Medido: el blanco sobre el rojo de marca da
     4,96 y bajarlo al 88 % lo deja en 4,12 — por debajo del 4,5 que pide AA
     para texto pequeño. Ese 88 % era un atenuado por costumbre, del que solo
     se entera un medidor. */
  .ps__col--solucion .ps__txt, .ps__col--solucion .ps__pun li { color: var(--white); }
  .ps__col--solucion .ps__pun li::before { background: var(--white); }
  .ps__tit { font-size: var(--fs-3); font-weight: 600; letter-spacing: -.01em; }
  .ps__txt { font-size: 14.5px; line-height: 1.55; color: var(--muted); text-wrap: pretty; }
  .ps__pun { display: grid; gap: 10px; }
  .ps__pun li { position: relative; padding-left: 20px; font-size: 14px; line-height: 1.5; color: var(--muted); }
  .ps__pun li::before { content: ""; position: absolute; left: 0; top: .6em; width: 7px; height: 1px; background: var(--brand); }
}

/* ═══════════════════════════════════════════════════════════════════════
   07 · EL CIERRE
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .cierre { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
            gap: var(--space-xl); align-items: end; }
  @media (max-width: 860px) { .cierre { grid-template-columns: minmax(0, 1fr); align-items: start; } }
  .cierre__texto { display: grid; gap: var(--space-md); }
  .cierre__datos { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
                   gap: 12px; margin-top: var(--space-sm); }
  .cierre__datos li { display: grid; gap: 2px; }
  .cierre__datos small { font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
                         text-transform: uppercase; color: var(--muted); }
  .cierre__datos a, .cierre__datos span { font-size: 14px; }
  .cierre__datos a { border-bottom: 1px solid var(--line-strong); }
  .cierre__datos a:hover { color: var(--brand-text); border-color: var(--brand); }
  .cierre__acciones { display: grid; gap: 10px; justify-items: start; align-content: end; }
  .cierre__acciones .btn { white-space: nowrap; }
}

/* ── la tira de hechos: los cuatro bullets del hero como cifras ── */
@layer layout {
  .hechos { padding-inline: var(--container-padding); border-top: 1px solid var(--line); }
  .hechos__lista { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .hechos__lista li {
    display: grid; gap: 8px; align-content: start; container-type: inline-size;
    padding: var(--space-xl) var(--space-lg) var(--space-xl) 0;
    margin-right: var(--space-lg); border-right: 1px solid var(--line);
  }
  .hechos__lista li:last-child { border-right: 0; margin-right: 0; }
  .hechos__lista b { font-family: var(--font-mono); font-weight: 400;
                     font-size: clamp(18px, 8cqi, 30px); line-height: 1.1; letter-spacing: -.02em;
                     overflow-wrap: break-word; }
  .hechos__lista span { font-size: 13.5px; color: var(--muted); line-height: 1.45; text-wrap: pretty; }
  @media (max-width: 900px) {
    .hechos__lista { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .hechos__lista li:nth-child(2) { border-right: 0; margin-right: 0; }
  }
  .arg__tit--sub { margin-top: var(--space-sm); }
}

/* ═══════════════════════════════════════════════════════════════════════
   02 · ELIGE TU SERIE — el configurador y sus atajos de entrada
   La herramienta la pinta js/main.js; aquí va su marco y los atajos, que se
   leen SIN JavaScript. Las clases internas del configurador (.configurador__*)
   vienen de la hoja vieja y se re-visten al final de este archivo.
   ═══════════════════════════════════════════════════════════════════════ */
@layer layout {
  .elige { display: grid; grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
           gap: clamp(20px, 3vw, 48px); align-items: start; }
  @media (max-width: 1000px) { .elige { grid-template-columns: minmax(0, 1fr); } }
  .elige__atajos { display: grid; gap: var(--space-sm); align-content: start; }

  .atajos { display: grid; gap: 8px; }
  .atajo { display: grid; gap: 3px; padding: 12px 14px; border-radius: var(--radius-sm);
           background: var(--panel); border: 1px solid var(--line); transition: border-color .2s, background .2s; }
  .atajo:hover { border-color: var(--brand); background: var(--panel-strong); }
  .atajo b { font-size: 14.5px; font-weight: 600; }
  .atajo span { font-size: 12.5px; color: var(--muted); line-height: 1.45; }

  /* las cinco industrias, en <details>: se leen sin JavaScript y se despliegan
     con teclado, que es lo que el elemento hace de fábrica */
  .inds { display: grid; gap: 6px; }
  .ind { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--panel); }
  .ind__cab { cursor: pointer; padding: 11px 14px; font-size: 14px; font-weight: 600;
              display: flex; align-items: center; justify-content: space-between; gap: 10px; }
  .ind__cab::after { content: "+"; font-family: var(--font-mono); color: var(--brand-text); }
  .ind[open] .ind__cab::after { content: "−"; }
  .ind__cab::-webkit-details-marker { display: none; }
  .ind:focus-within { outline: 2px solid var(--focus); outline-offset: 2px; }
  .ind__cuerpo { padding: 0 14px 12px; display: grid; gap: 8px; }
  .ind__cuerpo p { font-size: 13px; color: var(--muted); line-height: 1.5; }
  .ind__cuerpo small { display: block; font-family: var(--font-mono); font-size: 10px;
                       letter-spacing: .12em; text-transform: uppercase; color: var(--brand-text); margin-bottom: 2px; }
  .ind__series { display: flex; flex-wrap: wrap; gap: 6px; }
  .ind__series a { font-family: var(--font-mono); font-size: 11.5px; padding: 3px 9px;
                   border: 1px solid var(--line-strong); border-radius: 999px; color: var(--text); }
  .ind__series a:hover { border-color: var(--brand); color: var(--brand-text); }
}

/* ═══════════════════════════════════════════════════════════════════════
   LA PIEL NUEVA SOBRE LAS DOS HERRAMIENTAS
   El configurador y el comparador traen sus clases de la hoja vieja, que no
   se carga aquí. Se re-visten con los tokens del bloque 01 — sin un solo
   !important, porque van en @layer componentes y la hoja vieja no está.
   ═══════════════════════════════════════════════════════════════════════ */
@layer componentes {

  /* 🔴 La cabecera interna del configurador sobra AQUÍ, y solo aquí.
     La sección ya se titula «Elige tu serie. En siete preguntas» con su bajada;
     dejando también el «¿Qué electroválvula Fluidity necesitas?» del JS quedan
     dos titulares seguidos diciendo lo mismo, que es exactamente el defecto que
     esta portada viene a arreglar (14 secciones que repiten la promesa).
     Se oculta el eyebrow y el h2; la bajada SE QUEDA, porque lleva el contador
     vivo de series disponibles y ese dato no lo dice nadie más. */
  #configuradorRaiz > .configurador__head > .eyebrow,
  #configuradorRaiz > .configurador__head > h2 { display: none; }
  /* La bajada del configurador se queda —lleva el contador vivo de series
     disponibles, que la de la sección no puede dar sin JavaScript— pero pasa a
     leerse como instrucción de uso y no como una segunda bajada: mono, pequeña
     y pegada a las preguntas. Dos párrafos grandes seguidos diciendo variantes
     de lo mismo es el defecto que esta portada viene a arreglar. */
  #configuradorRaiz > .configurador__head > p {
    font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .04em;
    color: var(--muted); line-height: 1.6; margin-bottom: var(--space-md);
    padding-left: 13px; border-left: 2px solid var(--line-strong); max-width: 68ch;
  }

  /* ── las siete preguntas ──
     ⚠️ Estas reglas se perdieron al reescribir el bloque de al lado por
     posición en el archivo en vez de por su texto: el corte se llevó por
     delante las que había debajo. Los botones volvieron al estilo por defecto
     del navegador —`border: 2px outset`, fondo gris— y no lo dijo nadie.
     Un reemplazo por índices no avisa de lo que borra; uno por texto exacto sí. */
  .configurador__qcard {
    display: grid; gap: 11px; padding: 15px 17px; border-radius: var(--radius-md);
    background: var(--panel); border: 1px solid var(--line);
    transition: border-color .2s, background .2s;
  }
  .configurador__qcard:has(.configurador__option[aria-pressed="true"]) {
    border-color: var(--brand); background: var(--brand-suave);
  }
  .configurador__qhead { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; }
  .configurador__qnum {
    font-family: var(--font-mono); font-size: 11px; color: var(--brand-text);
    border: 1px solid var(--line-strong); border-radius: 999px; padding: 2px 9px; flex: none;
  }
  .configurador__qcard:has(.configurador__option[aria-pressed="true"]) .configurador__qnum {
    border-color: var(--brand); background: var(--brand); color: var(--white);
  }
  .configurador__question-title { font-size: 15.5px; font-weight: 600; letter-spacing: -.01em; }
  .configurador__qstate {
    margin-left: auto; font-family: var(--font-mono); font-size: 10px;
    letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
  }
  .configurador__options { display: flex; flex-wrap: wrap; gap: 7px; }
  .configurador__option {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 13px; border-radius: 999px; cursor: pointer;
    background: transparent; border: 1px solid var(--line-strong); color: var(--text);
    font-family: inherit; font-size: 13.5px; line-height: 1.2;
    transition: border-color .18s, background .18s, color .18s, opacity .18s;
  }
  .configurador__option:hover { border-color: var(--brand); }
  .configurador__option:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  .configurador__option[aria-pressed="true"] { background: var(--brand); border-color: var(--brand); color: var(--white); }
  .configurador__option img, .configurador__option svg { width: 17px; height: 17px; flex: none; }
  /* 🔴 Una opción imposible NO se esconde: se apaga y enseña su cero. Sin ese
     cero el visitante no sabe si está apagada porque no existe o porque la
     página falló — es la regla que cerró los caminos muertos del proyecto. */
  .configurador__option.is-imposible { opacity: .42; cursor: not-allowed; border-style: dashed; }
  .configurador__option .configurador__option small { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
  .configurador__option[aria-pressed="true"] small { color: color-mix(in srgb, var(--white) 82%, transparent); }

  /* 🔴 LOS NOMBRES DE CLASE SALEN DE LEER EL MARCADO, NO DE SUPONERLOS.
     La primera pasada estilizó `.configurador__chip`, `.configurador__serie`,
     `.configurador__count` y `.configurador__resultado`: NINGUNA existe. Las
     reales son `.configurador__pieza`, `.configurador__thumb` y
     `.configurador__counter-*`. El resultado fue el mosaico sin un solo estilo
     de estado: el JS ponía `is-dentro` e `is-fuera` en cada serie —el motor
     entero funcionando— y en pantalla no se movía nada. Un CSS que apunta a
     clases inventadas no falla: no hace nada, y parece que lo roto es el motor. */
  /* Mitad y mitad exacta: las preguntas y el resultado en vivo pesan lo mismo
     en la decisión, así que ninguna es el margen de la otra. Mario, 7 sep 2026. */
  .configurador__layout {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(20px, 3vw, 44px); align-items: start;
  }
  @media (max-width: 960px) { .configurador__layout { grid-template-columns: minmax(0, 1fr); } }
  .configurador__questions { display: grid; gap: 10px; }

  /* ── el panel de resultado, pegado mientras se responde ── */
  .configurador__panel {
    position: sticky; top: 84px; display: grid; gap: var(--space-md);
    padding: var(--space-md); border-radius: var(--radius-md);
    background: var(--panel-strong); border: 1px solid var(--line);
  }
  .configurador__panel-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  .configurador__panel-label { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .14em;
                               text-transform: uppercase; color: var(--muted); }
  .configurador__reset { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
                         text-transform: uppercase; color: var(--muted); cursor: pointer;
                         background: transparent; border: 1px solid var(--line-strong);
                         border-radius: 999px; padding: 4px 10px; }
  .configurador__reset:hover { color: var(--brand-text); border-color: var(--brand); }
  .configurador__reset:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

  /* el contador: la cifra que baja mientras se responde */
  /* ⚠️ Estas cuatro se perdieron al limpiar reglas muertas con un patrón sin
     límite de palabra: `configurador__count` casaba también con
     `configurador__counter-arrow`. Segunda vez en la sesión que un reemplazo
     automático se lleva por delante reglas buenas — la primera fue cortar por
     posición en el archivo. Un patrón de borrado se ancla, siempre. */
  .configurador__counter { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
  .configurador__counter-now {
    font-family: var(--font-mono); font-size: clamp(30px, 4vw, 44px);
    line-height: 1; color: var(--brand-text); letter-spacing: -.03em;
  }
  .configurador__counter-arrow, .configurador__counter-total {
    font-family: var(--font-mono); font-size: 15px; color: var(--muted);
  }
  .configurador__counter-caption { font-size: 13px; color: var(--muted); line-height: 1.4; }

  .configurador__bar { height: 3px; border-radius: 999px; background: var(--line); overflow: hidden; }
  .configurador__bar > * , .configurador__bar::after { display: block; height: 100%; background: var(--brand); }

  /* ── EL MOSAICO: las series que siguen vivas ──
     Es la pieza que cuenta la historia del configurador: al responder, las que
     ya no encajan se apagan y las que quedan se encienden. Sin estilos de
     estado el mecanismo corre y no se ve, que es como estaba. */
  /* Mosaico más grande: con 60 px la miniatura de la serie no se distinguía de
     la de al lado, y el mosaico es lo que enseña QUÉ queda vivo al responder.
     Mario, 7 sep 2026. */
  .configurador__mosaico { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px; }
  .configurador__pieza {
    display: grid; gap: 5px; justify-items: center; padding: 9px 6px 8px;
    border-radius: 9px; border: 1px solid var(--line); background: var(--panel);
    transition: opacity .28s var(--ease-out), filter .28s var(--ease-out),
                border-color .22s, background .22s, scale .28s var(--ease-out);
  }
  .configurador__pieza img { width: 100%; max-width: 64px; height: auto; }
  .configurador__pieza i { font-family: var(--font-mono); font-style: normal; font-size: 11px;
                           letter-spacing: .06em; color: var(--muted); text-align: center; }
  .configurador__pieza:hover { border-color: var(--line-strong); }
  .configurador__pieza:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  /* la que sigue compatible tras responder: se enciende */
  .configurador__pieza.is-dentro {
    border-color: var(--brand); background: var(--brand-suave); scale: 1.04;
  }
  .configurador__pieza.is-dentro i { color: var(--brand-text); }
  /* la que ya no encaja: se apaga, pero SIGUE AHÍ y se puede abrir. No se
     esconde — igual que las opciones imposibles enseñan su cero, una serie
     descartada tiene que poder verse descartada. */
  .configurador__pieza.is-fuera { opacity: .22; filter: saturate(.15); scale: .96; }

  /* ── LO QUE DIBUJA CADA PREGUNTA ──
     🔴 Estas siete clases estaban SIN estilo y por eso la pregunta del diámetro
     salía vacía: el círculo estaba en el DOM, sin fondo. Es la cuarta vez en
     esta sesión que estilizo clases inventadas y me dejo las reales, así que
     ahora hay un check que compara lo que el JS emite contra lo que la hoja
     estiliza — ver _tools/verificar_piel.js. */

  /* el disco de diámetro: su tamaño guarda la proporción REAL entre conexiones.
     22, 34, 48 y 64 px para 6, 13, 25 y 50 mm — el círculo no decora, mide. */
  .configurador__option:has(.configurador__disco) {
    flex-direction: column; align-items: center; gap: 6px;
    padding: 14px 18px 12px; border-radius: var(--radius-md); min-width: 108px;
  }
  .configurador__disco {
    display: block; border-radius: 50%; flex: none;
    background: radial-gradient(circle at 38% 34%,
      color-mix(in srgb, var(--brand) 26%, transparent), transparent 62%);
    border: 1.5px solid var(--line-strong);
    transition: border-color .18s, background .18s;
  }
  .configurador__option:hover .configurador__disco { border-color: var(--brand); }
  .configurador__option[aria-pressed="true"] .configurador__disco {
    border-color: var(--white);
    background: radial-gradient(circle at 38% 34%, color-mix(in srgb, var(--white) 42%, transparent), transparent 64%);
  }
  .configurador__op-lb { font-size: 13.5px; font-weight: 500; }
  .configurador__op-sub {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; color: var(--muted);
  }
  .configurador__option[aria-pressed="true"] .configurador__op-sub {
    color: color-mix(in srgb, var(--white) 80%, transparent);
  }

  /* el símbolo neumático de la pregunta de función, y el orificio de la de
     caudal: son SVG con su propio trazo, así que solo se les da tamaño y el
     color de línea del tema */
  .configurador__simb, .configurador__orif {
    width: 26px; height: 22px; flex: none;
    stroke: currentColor; fill: none; opacity: .85;
  }
  .configurador__orif { width: 24px; height: 24px; }
  .configurador__fl { stroke: var(--brand); }
  .configurador__option[aria-pressed="true"] .configurador__fl { stroke: var(--white); }

  .configurador__ficha-link { color: var(--brand-text); font-size: 12.5px; }
  .configurador__ficha-link:hover { text-decoration: underline; }

  .configurador__ficha { display: grid; gap: 8px; padding-top: var(--space-sm); border-top: 1px solid var(--line); }
  .configurador__ficha-cab { font-size: 15px; font-weight: 600; }
  .configurador__ficha-sp { display: grid; gap: 4px; font-size: 12.5px; color: var(--muted); }
  .configurador__ficha-cods { display: flex; flex-wrap: wrap; gap: 5px; }
  .configurador__ficha-cods code { font-family: var(--font-mono); font-size: 11px; padding: 3px 7px;
                                   border-radius: 6px; background: var(--panel-high); color: var(--text); }
  .configurador__ficha-mas { font-family: var(--font-mono); font-size: 11px; color: var(--muted); }
  .configurador__aviso { font-size: 13px; color: var(--muted); line-height: 1.5;
                         padding: 10px 12px; border-radius: var(--radius-sm);
                         background: var(--panel); border: 1px solid var(--line); }
  .configurador__note { font-size: 12px; color: var(--muted); line-height: 1.45; }
  .configurador__cta { width: 100%; justify-content: center; text-align: center; }

  /* ── el comparador ──
     🔴 Los nombres de clase salen de LEER el marcado que emite js/main.js, no
     de suponerlos. La primera pasada estilizó `.compare-bar` y `.compare-chip`,
     que no existen —son `.compare-sticky-bar` y los chips de
     `.comparator-filters`—, así que la barra flotante se quedó sin estilo y
     además invisible al medirla. Un CSS que apunta a clases inventadas no falla:
     simplemente no hace nada. */
  .comparator-header { display: grid; gap: var(--space-sm); margin-bottom: var(--space-md); }
  .comparator-filters { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: var(--space-sm); }
  .comparator-filters button, .comparator-filters [role="button"] {
    padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line-strong);
    background: transparent; color: var(--text); font-size: 13px; cursor: pointer;
    transition: border-color .18s, background .18s, color .18s;
  }
  .comparator-filters button:hover { border-color: var(--brand); }
  .comparator-filters button:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  .comparator-filters button.is-active, .comparator-filters [aria-pressed="true"] {
    background: var(--brand); border-color: var(--brand); color: var(--white);
  }
  .comparator-counter { font-family: var(--font-mono); font-size: 12px; color: var(--muted); margin-bottom: var(--space-md); }
  .comparator-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: var(--space-md); }

  .compare-card {
    position: relative; display: grid; gap: 10px; padding: 14px;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-md);
    transition: border-color .2s, background .2s;
  }
  .compare-card:hover { border-color: var(--line-strong); background: var(--panel-strong); }
  .compare-card.is-selected { border-color: var(--brand); background: var(--brand-suave); }
  .compare-card.is-hidden { display: none; }
  .compare-card img { width: 100%; height: auto; border-radius: 8px; }
  .compare-card__identity-main { font-size: 16px; font-weight: 600; }
  .compare-card__meta, .compare-app { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
  .compare-badge { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px;
                   font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
                   border: 1px solid var(--line-strong); color: var(--muted); }
  .metric-pill { display: grid; gap: 1px; padding: 7px 9px; border-radius: 8px;
                 background: var(--panel-strong); border: 1px solid var(--line); }
  .metric-pill__value { font-family: var(--font-mono); font-size: 12.5px; }
  .metric-pill__label { font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .1em;
                        text-transform: uppercase; color: var(--muted); }
  .metric-pill.is-best { border-color: var(--brand); }
  /* el padding ES el área táctil: 40px de alto sin un elemento extra que
     ocupe sitio al lado de la casilla. El margen negativo lo devuelve a su
     posición para que no empuje al resto de la tarjeta. */
  .compare-select {
    display: inline-flex; align-items: center; cursor: pointer;
    padding: 11px; margin: -11px; border-radius: 10px;
    transition: background .18s var(--ease-out);
  }
  .compare-select:hover { background: var(--panel); }
  .compare-select__input { width: 18px; height: 18px; accent-color: var(--brand); cursor: pointer; }
  .compare-select__input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  .compare-link { color: var(--brand-text); font-size: 13px; }

  /* la barra flotante: sale cuando hay algo seleccionado, no antes */
  .compare-sticky-bar {
    position: sticky; bottom: 14px; z-index: 30; margin-top: var(--space-md);
    opacity: 0; transform: translateY(8px); pointer-events: none;
    transition: opacity .25s var(--ease-out), transform .25s var(--ease-out);
  }
  .compare-sticky-bar.is-visible { opacity: 1; transform: none; pointer-events: auto; }
  .compare-sticky-bar__inner {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: space-between;
    padding: 12px 18px; border-radius: 999px;
    background: color-mix(in srgb, var(--bg-2) 94%, transparent);
    backdrop-filter: blur(14px); border: 1px solid var(--line-strong); box-shadow: var(--shadow-hover);
  }
  /* 🔴 el contador va con --brand-text y no con --brand: el rojo de marca como
     TEXTO da 3,92 sobre el fondo oscuro y AA pide 4,5 */
  .compare-sticky-bar__count { font-family: var(--font-mono); font-size: 12.5px; color: var(--muted); }
  .compare-sticky-bar__count span { color: var(--brand-text); font-size: 15px; }
  .compare-sticky-bar__actions { display: flex; gap: 8px; }
  .btn-micro {
    padding: 8px 14px; border-radius: 999px; font-size: 13px; cursor: pointer;
    border: 1px solid var(--line-strong); background: transparent; color: var(--text);
  }
  .btn-micro:hover { border-color: var(--text); }
  .btn-micro:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
  .btn-micro--primary { background: var(--brand); border-color: var(--brand); color: var(--white); }

  /* el modal */
  .compare-modal { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 4vmin; }
  .compare-modal__overlay { position: absolute; inset: 0;
    background: color-mix(in srgb, var(--bg) 76%, transparent); backdrop-filter: blur(8px); }
  .compare-modal__content {
    position: relative; max-width: min(1000px, 96vw); max-height: 90vh; overflow: auto;
    background: var(--bg-2); border: 1px solid var(--line-strong);
    border-radius: var(--radius-lg); box-shadow: var(--shadow); padding: var(--space-lg);
  }
  .compare-modal__content:focus-visible:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
  .compare-modal__header { display: flex; align-items: center; justify-content: space-between;
                           gap: 14px; margin-bottom: var(--space-md); }
  .compare-modal__close { border: 1px solid var(--line-strong); background: transparent; color: var(--text);
                          width: 34px; height: 34px; border-radius: 999px; cursor: pointer; font-size: 16px; }
  .compare-modal__close:hover { border-color: var(--brand); color: var(--brand-text); }
  .compare-modal__table-wrap { overflow-x: auto; }
  .compare-modal__table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
  .compare-modal__table th, .compare-modal__table td {
    padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top;
  }
  .compare-modal__table thead th { font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em;
                                   text-transform: uppercase; color: var(--brand-text); font-weight: 400; }
  .compare-modal__table tbody th { font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
                                   text-transform: uppercase; color: var(--muted); font-weight: 400; white-space: nowrap; }
  .compare-modal__cell-img img { width: 100%; max-width: 150px; height: auto; border-radius: 8px; }
  .compare-modal__footer { display: flex; justify-content: flex-end; gap: 10px; margin-top: var(--space-md); }
}

@layer componentes {
  /* el contador de cada chip: dice cuántas series hay detrás ANTES de pulsarlo */
  .filter-chip__n { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin-left: 5px; }
  .filter-chip.is-active .filter-chip__n { color: color-mix(in srgb, var(--white) 84%, transparent); }
}

/* ── la sección de atajos, ahora aparte del configurador ── */
@layer layout {
  .sec--atajos { border-top: 1px solid var(--line); }
  .sec__tit--menor { font-size: clamp(24px, 2.8vw, 34px); }
  /* Las dos columnas arrancan a la MISMA altura y con la misma cabecera. Antes
     la de industrias caía un escalón por llevar su título dentro y la otra no:
     una diagonal a medias se lee como descuadre. Mario, 7 sep 2026. */
  .atajos-fila { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
                 gap: clamp(20px, 3vw, 48px); align-items: start; }
  .atajos-col { display: grid; gap: var(--space-sm); align-content: start; }
  .atajos-col__t { font-size: var(--fs-3); font-weight: 600; letter-spacing: -.01em; }
  @media (max-width: 900px) { .atajos-fila { grid-template-columns: minmax(0, 1fr); } }
  .atajos { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; align-content: start; }
  .inds-bloque { display: grid; gap: var(--space-sm); align-content: start; }
}

/* ── el comparador: primero lo que decide ── */
@layer componentes {
  .compare-modal__body { display: grid; gap: var(--space-lg); }
  .compare-dif {
    display: grid; gap: 10px;
    padding: var(--space-md); border-radius: var(--radius-md);
    background: var(--brand-suave); border: 1px solid var(--brand);
  }
  .compare-dif--nada { background: var(--panel); border-color: var(--line); }
  .compare-dif__cab { display: flex; align-items: baseline; gap: 10px; }
  .compare-dif__t {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--brand-text);
  }
  .compare-todas .compare-dif__t { color: var(--muted); }
  .compare-dif__n {
    font-family: var(--font-mono); font-size: 11px; color: var(--muted);
    border: 1px solid var(--line-strong); border-radius: 999px; padding: 2px 9px;
  }
  .compare-dif__resto { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
  /* en el bloque de diferencias el valor manda: por eso va en negrita y el
     resto de la tabla no. Si todo se destaca, no se destaca nada. */
  .compare-modal__table--dif td b { font-weight: 600; font-size: 14.5px; }
  .compare-modal__table--dif th, .compare-modal__table--dif td { border-bottom-color: var(--line-strong); }
  .compare-todas { display: grid; gap: 10px; }
}

/* ── lo que faltaba por vestir del comparador ──
   Lo destapó _tools/verificar_piel.js comparando lo que el JS pinta contra lo
   que esta hoja estiliza. Las cuatro columnas de la tarjeta y la casilla de
   selección salían sin caja, así que la tarjeta se leía como una lista suelta. */
@layer componentes {
  .compare-wrap { display: grid; gap: var(--space-md); }
  .compare-card__col { display: grid; gap: 6px; min-width: 0; }
  .compare-card__col--identity { gap: 4px; }
  .compare-card__col--metrics { grid-template-columns: repeat(auto-fit, minmax(82px, 1fr)); gap: 6px; }
  .compare-card__col--sizes { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
  .compare-card__col--action { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 2px; }
  /* la casilla, con su área de toque real: 18 px de casilla dentro de 40 de
     zona pulsable, que es lo mínimo cómodo con el dedo */
  /* `.compare-select__box` ya no existe en el marcado: era un span vacío que
     se dibujaba al lado de la casilla en vez de encima. Si vuelve a aparecer en
     el HTML, `verificar_piel.js` avisará de que nadie lo viste. */
  .compare-modal__close--footer { width: auto; padding: 0 16px; border-radius: 999px; }
  .compare-badge--laton { border-color: color-mix(in srgb, #C29A4B 60%, transparent); }
  .compare-badge--inox  { border-color: color-mix(in srgb, #A8B2BF 60%, transparent); }
  .compare-badge--tecno { border-color: color-mix(in srgb, #6FB6DE 60%, transparent); }
}

/* ═══════════════════════════════════════════════════════════════════════
   EL CONFIGURADOR — la sección que decide en una landing de producto único
   ═══════════════════════════════════════════════════════════════════════
   🔴 Se escribió el marcado y el JS antes que esto, y el resultado fue un
   configurador que calculaba bien y se veía crudo: 17 clases sin una sola
   regla. Es el defecto de `verificar_piel.js` en el sentido contrario —ese
   caza el CSS que apunta a clases que no existen; esto era marcado sin piel—
   y no da error ninguno: la página funciona y se ve mal.
   ═══════════════════════════════════════════════════════════════════════ */
@layer components {
  .sec--cfg .sec__caja { max-width: var(--container); }

  .cfg {
    display: grid; gap: var(--space-lg);
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    margin-top: var(--space-xl);
  }
  .cfg__paso { border: 0; padding: 0; margin: 0; min-width: 0; }
  .cfg__preg {
    display: flex; align-items: center; gap: 10px; padding: 0 0 12px;
    font-size: 14px; font-weight: 600; color: var(--text); line-height: 1.3;
  }
  .cfg__n {
    flex: none; width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--brand); color: var(--white);
    font-family: var(--font-mono); font-size: 11px;
  }
  .cfg__ops { display: flex; flex-wrap: wrap; gap: 8px; }
  .cfg__op { position: relative; }
  .cfg__op input {
    position: absolute; inset: 0; opacity: 0; cursor: pointer; margin: 0;
  }
  .cfg__op span {
    display: block; padding: 9px 14px; border-radius: 999px;
    border: 1px solid var(--line-strong); background: var(--panel);
    font-family: var(--font-mono); font-size: 12.5px; color: var(--muted);
    transition: background var(--dur-corta, .16s) var(--e-suave),
                border-color var(--dur-corta, .16s) var(--e-suave),
                color var(--dur-corta, .16s) var(--e-suave);
  }
  .cfg__op:hover span { border-color: var(--text); color: var(--text); }
  /* el foco del teclado tiene que verse: el input real es invisible */
  .cfg__op input:focus-visible + span { outline: 2px solid var(--focus); outline-offset: 2px; }
  .cfg__op input:checked + span {
    background: var(--brand); border-color: var(--brand); color: var(--white); font-weight: 600;
  }

  .cfg__salida {
    display: block; grid-column: 1 / -1;
    margin-top: var(--space-md); padding: var(--space-lg);
    border: 1px solid var(--line); border-radius: var(--radius-md);
    background: var(--panel);
  }
  .cfg__eyebrow {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
    text-transform: uppercase; color: var(--brand-text); margin: 0 0 12px;
  }
  .cfg__nota { margin: 0 0 14px; color: var(--muted); font-size: 14.5px; max-width: 62ch; }
  .cfg__aviso {
    margin: 0 0 8px; font-size: 15.5px; font-weight: 600; color: var(--text);
    padding-left: 14px; border-left: 3px solid var(--brand);
  }

  .cfg__piezas { list-style: none; margin: 0 0 var(--space-lg); padding: 0;
    display: grid; gap: 10px; }
  .cfg__pieza {
    display: grid; align-items: baseline; gap: 4px 16px;
    grid-template-columns: 116px minmax(0, 1fr);
    padding: 12px 14px; border-radius: var(--radius-sm);
    background: var(--bg); border: 1px solid var(--line);
  }
  .cfg__rol {
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--muted); grid-row: 1 / 3;
  }
  /* el código es el dato que el visitante copia: tabular para que no baile */
  .cfg__cod {
    font-family: var(--font-mono); font-size: 15px; color: var(--text);
    font-weight: 600; font-variant-numeric: tabular-nums;
  }
  .cfg__que { color: var(--muted); font-size: 13.5px; }
  .cfg__det { grid-column: 2; color: var(--muted); font-size: 12.5px; opacity: .85; }

  @media (max-width: 560px) {
    .cfg__pieza { grid-template-columns: 1fr; }
    .cfg__rol { grid-row: auto; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   LA FICHA — los datos del producto principal
   ═══════════════════════════════════════════════════════════════════════
   Se escribe ANTES de generar la sección: con el configurador lo hice al
   revés y salió una sección que funcionaba y se veía cruda. El orden importa
   porque nada avisa — marcado sin piel no da error.

   Es una `<dl>`: cada dato es un par etiqueta/valor y eso es exactamente lo
   que una lista de definición significa. Un `<div>` con dos `<span>` se vería
   igual y no diría nada a quien la lea con un lector de pantalla.
   ═══════════════════════════════════════════════════════════════════════ */
@layer components {
  /* la ficha respira ancha: son pares de dato y cuantas más columnas quepan,
     menos scroll para comparar */
  .sec--ficha .sec__caja { max-width: var(--container); }

  .fic {
    margin: var(--space-xl) 0 0; padding: 0;
    display: grid; gap: 1px;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    background: var(--line); border: 1px solid var(--line);
    border-radius: var(--radius-md); overflow: hidden;
  }
  .fic__fila {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 20px; padding: 15px 18px; background: var(--bg);
  }
  .fic__k {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .08em;
    text-transform: uppercase; color: var(--muted); margin: 0; flex: none;
  }
  /* el valor manda: alineado a la derecha para que la columna se lea de un
     vistazo, y tabular para que las cifras no bailen entre filas */
  .fic__v {
    margin: 0; text-align: right; color: var(--text);
    font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
  }
  .fic__nota { margin: var(--space-md) 0 0; color: var(--muted); font-size: 13.5px; max-width: 70ch; }

  @media (max-width: 520px) {
    /* apilado: a 375 px la etiqueta y el valor competían por el ancho y el
       valor quedaba en una columna de ~110 px — el defecto de los chips de
       spec truncados que este proyecto ya cerró dos veces */
    .fic__fila { flex-direction: column; align-items: flex-start; gap: 4px; }
    .fic__v { text-align: left; }
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   EL COMPARADOR EN TABLA — cuando los productos caben sin selector
   ═══════════════════════════════════════════════════════════════════════
   La gama lo pinta con JS porque 24 columnas no se leen. Una serie de tres
   medidas cabe entera, y entonces la tabla gana: se lee sin JavaScript, se
   imprime, y no hay nada que elegir antes de ver nada.
   ═══════════════════════════════════════════════════════════════════════ */
@layer components {
  /* 🔴 `.sec--compara` llevaba emitiéndose sin una sola regla: un modificador
     huérfano que nadie vio porque la sección se veía bien heredando `.sec`.
     Se le da lo que de verdad necesita —ancho— en vez de quitarlo, porque la
     comparación es lo que más se beneficia de que quepan más columnas. */
  .sec--compara .sec__cab, .sec--compara .cmp__scroll { max-width: var(--container); }

  /* la tabla scrollea en SU caja, nunca el documento */
  .cmp__scroll { overflow-x: auto; margin-top: var(--space-xl);
    border: 1px solid var(--line); border-radius: var(--radius-md); }
  .cmp { width: 100%; border-collapse: collapse; min-width: 520px; }
  .cmp__cap {
    caption-side: bottom; padding: 14px 18px; text-align: left;
    color: var(--muted); font-size: 13px; border-top: 1px solid var(--line);
  }
  .cmp th, .cmp td {
    padding: 13px 18px; text-align: left; border-bottom: 1px solid var(--line);
    font-variant-numeric: tabular-nums;
  }
  .cmp thead th {
    background: var(--panel); color: var(--text); font-size: 13.5px; font-weight: 600;
    position: sticky; top: 0;
  }
  .cmp thead th:first-child {
    font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--muted); font-weight: 400;
  }
  /* la etiqueta de la fila en mono y apagada: el dato es lo que se lee */
  .cmp tbody th {
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); font-weight: 400; white-space: nowrap;
  }
  .cmp tbody td { color: var(--text); font-size: 14.5px; font-weight: 600; }
  .cmp tbody tr:last-child th, .cmp tbody tr:last-child td { border-bottom: 0; }
  .cmp tbody tr:hover td, .cmp tbody tr:hover th { background: var(--panel); }
}

/* ═══════════════════════════════════════════════════════════════════════
   UNA SERIE DE MODELOS — selector y comparador (disposición `modelos`)
   ═══════════════════════════════════════════════════════════════════════
   Bloque 04 de frl-molde-nuevo. Las preguntas visten con la piel del
   configurador (.cfg__*) y la tabla con la del comparador (.cmp): las
   herramientas del molde se ven igual en todas las landings. Aquí solo lo
   que es nuevo. */
@layer components {
  .sec--sel .sec__cab, .sec--sel .sel, .sec--sel .sel__res,
  .sec--compara .cmp__chips { max-width: var(--container); }
  /* el contador de cada opción, y la opción que ya no deja nada: tachada y
     sin puntero, para que se lea POR QUÉ no se puede pulsar */
  .cfg__op small { margin-left: 6px; opacity: .72; }
  .cfg__op input:disabled { cursor: not-allowed; }
  .cfg__op input:disabled + span { opacity: .4; text-decoration: line-through; }
  .sel__res { margin-top: var(--space-xl); }
  .sel__barra { display: flex; align-items: baseline; gap: 16px; margin: 0 0 12px; }
  .sel__cuenta { margin: 0; font-family: var(--font-mono); font-size: 13px; color: var(--muted); }
  .sel__cuenta b { color: var(--text); font-size: 18px; }
  .sel__reset { background: none; border: 0; padding: 0; font: inherit; font-size: 13px;
    color: var(--brand-text); text-decoration: underline; cursor: pointer; }
  .sel__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); }
  .sel__unidad a { display: grid; gap: 4px; padding: 12px 14px; border-radius: var(--radius-sm);
    border: 1px solid var(--line); background: var(--panel); color: var(--text); text-decoration: none; }
  .sel__unidad a:hover { border-color: var(--brand); }
  .sel__unidad b { font-size: 15.5px; }
  .sel__unidad span { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }
  .cmp__chips { margin-top: var(--space-lg); }
  .cmp--modelos thead th a { color: inherit; text-decoration: none; }
  .cmp--modelos thead th a:hover { color: var(--brand-text); }
  /* con once columnas la de las etiquetas se queda quieta al scrollear */
  .cmp--modelos tbody th, .cmp--modelos thead th:first-child {
    position: sticky; left: 0; z-index: 1; background: var(--bg); }
}

/* `hero.sinLineas`: chips de dato sin su línea de acotación (ver acotar() en
   portada.js — en FRL MINI las doce acababan en el aire) */
@layer components {
  .dato--sin-linea::before { display: none; }
}

/* 🔴 `hidden` en el formulario del selector y en los chips del comparador: el JS
   los enseña al arrancar, y sin JavaScript no deben verse (no harían nada).
   `.cfg { display: grid }` y `.cfg__ops { display: flex }` ganaban al
   `[hidden] { display: none }` del navegador y los dos salían sin JS, con
   botones muertos. Lo cazó verificador-visual con JavaScript apagado. */
@layer components {
  .sel[hidden], .cmp__chips[hidden] { display: none; }
}

/* 🔴 TRES PIEZAS, CICLO DE TRES. `hf-rota` reparte el ciclo largo en SEIS
   ventanas (las seis series de Fluidity), así que con tres piezas la mitad del
   tiempo no había ninguna en cuadro: un hueco negro en el hero, que Mario vio
   en FRL MINI el 14 sep 2026. Se corrige por ESTRUCTURA —igual que la pieza
   única deja de rotar—: si el tercero es el último, cada pieza ocupa 1/3. Los
   porcentajes son los de seis multiplicados por dos, y los desfases de −0,15c,
   −1,15c y −2,15c siguen valiendo porque cada pieza sigue durando un ciclo. */
@layer components {
  .hf__vis:has(> .hf__serie:nth-child(3):last-child) .hf__serie {
    animation-name: hf-rota3;
    animation-duration: calc(var(--ciclo) * 3);
  }
  @keyframes hf-rota3 {
    0%      { opacity: 0; translate: 26% 0; }
    4%      { opacity: 1; translate: 0 0; }
    29.3%   { opacity: 1; translate: 0 0; }
    33.333% { opacity: 0; translate: -26% 0; }
    33.343% { opacity: 0; translate: 26% 0; }
    100%    { opacity: 0; translate: 26% 0; }
  }
}

/* 🔴 ACOTACIÓN HACIA LA DERECHA (`hacia: "d"`): el chip queda a la derecha del
   punto y la línea tiene que ir hacia la IZQUIERDA, a la pieza. La regla del
   carrusel (`.dato--d::before { left: 100% }`) seguía viva, y con `left` y
   `right` a la vez el navegador se queda con `left`: la línea salía hacia
   fuera, al aire. Medido en FRL MINI el 14 sep 2026 —las cinco puntas de los
   chips de la derecha caían entre el 87 y el 99 % del lienzo—. Va acotado a
   las acotaciones (`[style*="--x"]`) para no tocar el carrusel de Fluidity. */
@layer components {
  .dato--d[style*="--x"]::before { left: auto; right: 100%; }
}
