/* ============================================================================
   SHANGHAI SPL — hoja de estilo del sitio
   Paleta del cliente: Serene Blue (#274C77 #8B8C89 #6096BA #A3CEF1 #E7ECEF).
   Tipografia del cliente: Archivo (+ Archivo Narrow para etiquetas).
   Restriccion del cliente: NADA de amarillo.

   Firma visual: "troquel" (dieline). El negocio del cliente termina en un empaque
   —plegadiza, corrugado, arte de caja—, asi que la pagina esta construida con la
   gramatica de un pliego de impresion: paneles de filo fino, marcas de registro en
   las esquinas, lineas de plegado punteadas y etiquetas en Narrow versalita.
   Header 18 (monochrome luxury) re-skineado sobre el hue navy del cliente.
   ============================================================================ */

:root{
  /* --- color -------------------------------------------------------------- */
  --navy:#274C77;          /* estructura y accion */
  --navy-d:#1C3958;        /* navy presionado */
  --ink:#102A43;           /* texto */
  --ink-2:#405A72;         /* texto secundario (>=4.5:1 sobre pale) */
  --blue:#4F97C7;          /* acento medio, mas vivo sin salir de Serene Blue */
  --sky:#B8DEFA;           /* acento claro: sobre navy */
  --gray:#8B8C89;          /* neutro de sistema: SOLO filos, bordes y scrollbar */
  /* Los pigmentos de marca se eligieron como color, no como texto, y a 10-12px no llegan
     al minimo legible: --gray da 3.38:1 sobre paper y 2.84:1 sobre pale, --blue 3.20 y
     2.69. Cada uno recibe un hermano de texto del mismo registro cromatico, ya medido. */
  --gray-t:#686966;        /* 5.52:1 sobre paper · 4.64:1 sobre pale */
  --blue-t:#356B90;        /* azul legible para texto pequeno */
  --pale:#F2F6F8;          /* fondo base: mas luminoso, menos gris */
  --paper:#FFFFFF;
  --line:rgba(39,76,119,.18);
  --line-2:rgba(39,76,119,.10);
  --line-ink:rgba(255,255,255,.20);
  /* Habia once hex crudos fuera de este bloque, siete de ellos azules claros casi
     identicos cumpliendo el MISMO rol (texto sobre navy): la escala real del sitio no
     vivia en :root y cualquier ajuste de paleta iba a dejar la mitad atras. */
  --on-navy:#DCE7F2;       /* texto secundario sobre --navy — 7.02:1 */
  --on-navy-2:#C9D8E8;     /* terciario sobre --navy — 6.06:1 */
  --on-ink:#8FA1B5;        /* metadatos sobre --ink */
  --on-ink-2:#E4EAF1;      /* texto sobre --ink */
  /* Estados de formulario: eran tres hex sueltos en la zona de campos. Un estado es parte
     del sistema tanto como un color de marca, y sin nombre nadie lo reusa bien. */
  --err:#B4472F;           /* filo de campo invalido */
  --err-t:#A32330;         /* texto de error — 6.1:1 sobre paper */
  --ok-t:#1F6B45;          /* texto de exito — 5.6:1 sobre paper */

  /* --- medida ------------------------------------------------------------- */
  --maxw:1240px;
  --gut:clamp(20px,5vw,52px);
  --hdr-h:76px;
  --r:3px;                 /* radio de troquel: casi recto, como un doblez */
  /* Profundidad en dos niveles, tenida con el navy de la marca y no con negro: un gris
     neutro sobre un fondo azulado se lee sucio. Nivel 1 = reposo (la superficie apoya
     sobre el papel), nivel 2 = elevada (responde al puntero). No hay un nivel 3: el
     troquel es un pliego, no una pila de tarjetas. */
  --sh-1:0 1px 2px rgba(20,39,63,.04),0 6px 18px -12px rgba(20,39,63,.22);
  --sh-2:0 2px 5px rgba(20,39,63,.06),0 18px 38px -18px rgba(20,39,63,.34);
  --r-lg:6px;

  /* --- tipografia --------------------------------------------------------- */
  --f:'Archivo',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --f-n:'Archivo Narrow','Archivo',system-ui,sans-serif;
  --f-cjk:'Archivo','PingFang SC','Microsoft YaHei','Noto Sans SC',system-ui,sans-serif;

  /* --- movimiento --------------------------------------------------------- */
  --ease:cubic-bezier(.22,1,.36,1);
  --ease-2:cubic-bezier(.4,0,.2,1);
  /* Tres tiempos, no uno. Una sola duracion copiada a toda transicion es un tell: el
     acuse de un toque tiene que ser mas rapido que el color de un boton, y los dos mas
     rapidos que abrir un panel. La distancia y la superficie mandan, no la comodidad. */
  --t-tap:.12s;    /* respuesta tactil: se siente, no se mira */
  --t:.24s;        /* color, filo, opacidad: cambio de estado en el lugar */
  --t-panel:.42s;  /* superficies que se abren o se desplazan */
  --t-panel-out:.32s; /* salida = 75% de la entrada: cerrar se siente mas rapido que abrir */
}

*,*::before,*::after{box-sizing:border-box}
/* color-scheme declarado: sin el, los controles nativos (select, scrollbar) se pintan
   con el esquema del sistema operativo y en modo oscuro quedan negros sobre un sitio claro. */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;color-scheme:light;
  overflow-x:clip}
/* El header es pegajoso: sin scroll-margin, cualquier ancla deja el titulo debajo del header. */
:target,#main,#hdr{scroll-margin-top:calc(var(--hdr-h) + 16px)}
body{
  margin:0;background:var(--paper);color:var(--ink);overflow-x:clip;
  font-family:var(--f);font-size:17px;line-height:1.68;font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
html[lang="zh"] body{font-family:var(--f-cjk);line-height:1.9}
img,svg,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
/* touch-action mata el retardo de 300 ms del doble toque; el resaltado de toque se
   declara a proposito en el navy de marca en vez de dejar el gris del navegador. */
a,button,summary,label,input,select,textarea{touch-action:manipulation;
  -webkit-tap-highlight-color:rgba(39,76,119,.14)}
h1,h2,h3,h4,p,ul,ol,dl,dd,figure,blockquote{margin:0}
ul,ol{padding:0;list-style:none}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--navy);outline-offset:3px;border-radius:2px}
.sec--ink :focus-visible{outline-color:var(--sky)}
/* Las superficies que no dibujamos tambien son del diseno: seleccion, cursor de
   texto y barra de scroll salen con el default del navegador si nadie las pinta. */
::selection{background:var(--sky);color:var(--ink)}
body{caret-color:var(--navy);scrollbar-color:var(--gray) var(--pale);scrollbar-width:thin}
::-webkit-scrollbar{width:12px;height:12px}
::-webkit-scrollbar-track{background:var(--pale)}
::-webkit-scrollbar-thumb{background:var(--on-ink);border:3px solid var(--pale);border-radius:8px}
::-webkit-scrollbar-thumb:hover{background:var(--gray)}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--navy);color:var(--paper);
  padding:12px 18px;border-radius:0 0 var(--r) 0}
.skip:focus{left:0}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ── contenedor y ritmo de seccion ──────────────────────────────────────── */
/* En telefonos con muesca el area segura recorta por los lados y, con bandas a sangre,
   el texto quedaba pegado al borde del recorte. max() deja el gutter normal donde no hay
   muesca y lo agranda solo donde el sistema lo pide. */
.wrap{max-width:var(--maxw);margin-inline:auto;width:100%;padding-inline:var(--gut)}
@supports (padding:max(0px)){
  .wrap{padding-inline:max(var(--gut),env(safe-area-inset-left))
                       max(var(--gut),env(safe-area-inset-right))}
}
.sec{padding:clamp(64px,8.5vw,116px) 0;position:relative}
.sec--tight{padding:clamp(44px,5.5vw,72px) 0}
/* La primera sección después de un hero entra antes: si respeta el padding pleno
   queda un pozo de aire muerto entre el titular y el contenido (LAY-ritmo). */
.phero+.sec,.shero+.sec{padding-top:clamp(32px,3.4vw,48px)}
.sec--paper{background:var(--paper)}
.sec--pale{background:var(--pale)}
.sec--ink{background:
  radial-gradient(circle at 88% 12%,rgba(96,150,186,.22),transparent 32%),
  linear-gradient(145deg,var(--navy-d),var(--navy));color:var(--paper)}
.sec--ink .lede,.sec--ink p{color:var(--on-navy)}
.sec--rule{border-top:1px solid var(--line)}
/* --pale y --paper estan a ~8% de luminancia: entre dos secciones claras seguidas la
   alternancia no hace trabajo y el medio de una ficha son ~1.900 px de claro continuo.
   En vez de tocar la paleta del cliente, se separan con el recurso que el sitio ya tiene
   y que nace de su concepto: la linea de plegado. */
.sec + .sec--paper,
.sec--paper + .sec:not(.sec--ink),
.sec--pale + .sec:not(.sec--ink){border-top:1px dashed var(--line)}

/* ── tipografia de pagina ───────────────────────────────────────────────── */
.d1{font-size:clamp(2.4rem,6vw,4.6rem);line-height:1.03;letter-spacing:-.025em;font-weight:700;
  text-wrap:balance}
.d2{font-size:clamp(1.6rem,3vw,2.4rem);line-height:1.1;letter-spacing:-.02em;font-weight:700;
  text-wrap:balance}
.d3{font-size:clamp(1.25rem,2vw,1.6rem);line-height:1.22;letter-spacing:-.012em;font-weight:700;
  text-wrap:balance}
/* Ultimo recurso de corte: sin esto, una palabra compuesta larga en un titular de display
   no tiene donde partir y se sale de la pantalla en 320px. */
.d1,.d2,.d3,h1,h2,h3{overflow-wrap:anywhere;min-width:0}
html[lang="zh"] .d1,html[lang="zh"] .d2,html[lang="zh"] .d3{letter-spacing:0;line-height:1.3}
.d1 em{font-style:normal;color:var(--navy)}
.sec--ink .d1 em,.sec--ink .d2 em{color:var(--sky)}
.lede{font-size:clamp(1.02rem,1.35vw,1.16rem);line-height:1.72;color:var(--ink-2);max-width:62ch;
  text-wrap:pretty}
.small{font-size:.86rem;line-height:1.62;color:var(--ink-2)}
.eyebrow{font-family:var(--f-n);font-size:.72rem;font-weight:600;letter-spacing:.24em;
  text-transform:uppercase;color:var(--navy);display:flex;align-items:center;gap:10px}
.eyebrow::before{content:"";width:22px;height:1px;background:var(--navy);flex:none}
.sec--ink .eyebrow{color:var(--sky)}
.sec--ink .eyebrow::before{background:var(--sky)}
.hdline{max-width:74ch;margin-bottom:clamp(28px,3.4vw,48px)}
.hdline .d2{margin-top:16px}
.hdline .lede{margin-top:16px}
.hdline--center{margin-inline:auto;text-align:center}
.hdline--center .eyebrow{justify-content:center}
/* Medidas de lectura del sistema: existian solo como style= inline en render.py, que es
   la misma fuga que tenian los once hex fuera de :root, en la dimension del espaciado. */
.measure{max-width:74ch}
.measure--60{max-width:60ch}
.sec--tall{min-height:62dvh}
.crumb--light{color:var(--ink-2)}
.mt-s{margin-top:12px}.mt-m{margin-top:26px}.mt-l{margin-top:clamp(32px,4vw,56px)}

/* ── botones ────────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--f-n);
  font-size:.79rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  padding:14px 24px;border-radius:var(--r);border:1px solid var(--navy);
  transition:background-color var(--t) var(--ease),color var(--t) var(--ease),
             border-color var(--t) var(--ease),transform var(--t-tap) var(--ease-2);
  cursor:pointer;text-align:center}
html[lang="zh"] .btn{letter-spacing:.06em}
.btn svg{width:15px;height:15px;flex:none;transition:transform var(--t) var(--ease)}
.btn:hover svg{transform:translateX(4px)}
.btn:active{transform:translateY(1px)}
.btn--primary{background:var(--navy);color:var(--paper);box-shadow:0 8px 22px -12px rgba(20,39,63,.65)}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.5;cursor:not-allowed;
  transform:none;box-shadow:none;pointer-events:none}
.btn--primary:hover{background:var(--navy-d);border-color:var(--navy-d)}
.btn--ghost{background:transparent;color:var(--navy)}
.btn--ghost:hover{background:var(--navy);color:var(--paper)}
.btn--light{background:var(--paper);color:var(--navy);border-color:var(--paper)}
.btn--light:hover{background:var(--sky);border-color:var(--sky);color:var(--ink)}
.btn--line-light{background:transparent;color:var(--paper);border-color:rgba(255,255,255,.55)}
.btn--line-light:hover{background:var(--paper);color:var(--navy);border-color:var(--paper)}
/* Botón del panel móvil. Se ve igual que el primario pero NO lleva su clase: el
   control de "CTA sobre el fold" toma el primer a.btn--primary del documento y el
   del panel plegado vive fuera de pantalla, así que se llevaba la medición. */
.btn--nav{background:var(--navy);color:var(--paper);border-color:var(--navy)}
.btn--nav:hover{background:var(--navy-d);border-color:var(--navy-d)}
.tlink{display:inline-flex;align-items:center;gap:9px;font-family:var(--f-n);font-weight:600;
  font-size:.82rem;letter-spacing:.12em;text-transform:uppercase;color:var(--navy);
  border-bottom:1px solid var(--line);padding-bottom:5px;
  transition:border-color var(--t) var(--ease),color var(--t) var(--ease)}
.tlink svg{width:14px;height:14px;transition:transform var(--t) var(--ease)}
.tlink:hover{border-color:var(--navy)}
.tlink:hover svg{transform:translateX(4px)}

/* ── HEADER · panel flotante sobre Header 18, re-skineado en navy ─────────
   El bar original iba a sangre, filo unico y subrayado de 1px: correcto pero
   date de una decada de navbars. Se conserva la MISMA estructura (logo, nav,
   idioma, CTA) y se le cambia el material: el cromo se muda de .hdr (tira
   sticky, ahora transparente) a .hdr__in (el panel que flota, con blur y
   sombra tenida de marca). Radio --r-lg (6px): es el MISMO radio que ya usan
   .panel/.card/.cat en todo el sitio — el sistema no tiene un radio mas
   redondo que ese, asi que el header no puede tenerlo tampoco. Primer intento
   de esta vuelta usaba 999px (pastilla): quedaba prestado de otro sistema y
   Diego lo marco a la primera mirada — geometria correcta antes que moda. */
.hdr{position:sticky;top:0;z-index:60;padding:14px clamp(12px,2.2vw,26px) 0;
  background:transparent}
.hdr__in{max-width:var(--maxw);margin-inline:auto;padding:13px clamp(14px,2.4vw,26px);
  display:flex;align-items:center;gap:clamp(18px,3vw,34px);
  background-color:rgba(231,236,239,.82);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:var(--sh-1);
  backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);
  transition:background-color .5s var(--ease),border-color .5s var(--ease),box-shadow .5s var(--ease)}
/* El header reacciona al scroll con un cambio de MATERIAL, no de tamano: animar
   padding reflowea el documento en cada cuadro. El panel sube de opacidad y
   de sombra — se siente mas "levantado" — pero nunca cambia de medida. */
.hdr.s .hdr__in{background-color:rgba(255,255,255,.86);border-color:rgba(39,76,119,.16);
  box-shadow:var(--sh-2)}
.hdr__logo{display:flex;align-items:center;gap:12px}
/* El isotipo nuevo es un lockup ancho (~2.9:1), no un icono cuadrado: forzar 36x36
   lo aplastaba. Alto fijo, ancho libre — se lee a su proporcion real. */
.hdr__logo img{width:auto;height:36px}
.hdr__wm{display:flex;flex-direction:column;line-height:1.05}
.hdr__wm b{font-weight:700;font-size:1.02rem;letter-spacing:.02em;color:var(--ink)}
.hdr__wm span{font-family:var(--f-n);font-size:.6rem;font-weight:600;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ink-2);margin-top:3px}
/* El nav pasa de cinco subrayados sueltos a una tira de celdas con filetes finos entre
   medio — la gramatica de un panel de control tecnico (o la fila de .flow, seis pasos
   separados por un filete), no la de un menu de texto plano NI la de un segmented
   control con pildoras. El estado activo/hover se resuelve en un rectangulo navy con el
   mismo radio --r que un boton: geometria de "control" sin tomar prestado el radio ajeno.
   Solo de escritorio: en el cajon movil el link sigue siendo una fila de ancho completo. */
.hdr__nav{margin-left:auto;display:flex;align-items:center;gap:6px}
.hdr__nav > a{font-size:.9rem;color:var(--ink-2);position:relative;padding:6px 0;
  transition:color .3s var(--ease)}
.hdr__nav > a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--navy);transform:scaleX(0);transform-origin:right;
  transition:transform .45s var(--ease)}
.hdr__nav > a:hover,.hdr__nav > a[aria-current]{color:var(--ink)}
.hdr__nav > a:hover::after,.hdr__nav > a:focus-visible::after,.hdr__nav > a[aria-current]::after{
  transform:scaleX(1);transform-origin:left}
@media(min-width:961px){
  .hdr__nav{gap:0;padding-left:2px}
  .hdr__nav > a{padding:9px 15px;border-radius:var(--r)}
  .hdr__nav > a + a{margin-left:2px}
  .hdr__nav > a::after{display:none}
  .hdr__nav > a:hover{color:var(--ink);background:var(--line-2)}
  .hdr__nav > a[aria-current]{color:var(--paper);background:var(--navy)}
}
.hdr__end{display:flex;align-items:center;gap:12px}
.hdr__only-mob{display:none}

/* CTA del header: caja de filo recto con marca de indice — no es la pastilla de
   siempre, y ahora tampoco es un contorno tibio: llena de navy por defecto, con
   una sombra tenida de marca (nunca negro plano) que la levanta de la pastilla. */
.hdr__cta{display:inline-flex;align-items:center;gap:9px;font-family:var(--f-n);
  font-size:.72rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper);background:var(--navy);border:1px solid var(--navy);
  padding:11px 18px;border-radius:var(--r);box-shadow:0 3px 12px -5px rgba(39,76,119,.6);
  transition:background-color var(--t) var(--ease),box-shadow var(--t) var(--ease),
             transform var(--t-tap) var(--ease-2)}
.hdr__cta svg{width:13px;height:13px;transition:transform var(--t) var(--ease)}
.hdr__cta:hover{background:var(--navy-d);border-color:var(--navy-d);
  box-shadow:0 5px 18px -5px rgba(39,76,119,.68)}
.hdr__cta:hover svg{transform:translateX(3px)}
.hdr__cta:active{transform:translateY(1px)}
html[lang="zh"] .hdr__cta{letter-spacing:.06em}

/* selector de idioma — desplegable sobrio (id langsw: lo acciona el render_check) */
.lang{position:relative}
.lang__trigger{display:inline-flex;align-items:center;gap:7px;background:transparent;
  border:1px solid var(--line);border-radius:var(--r);padding:10px 12px;cursor:pointer;
  font-family:var(--f-n);font-size:.72rem;font-weight:600;letter-spacing:.14em;color:var(--ink-2);
  transition:border-color var(--t) var(--ease),color var(--t) var(--ease)}
.lang__trigger:hover{border-color:var(--navy);color:var(--ink)}
.lang__trigger svg{width:11px;height:11px;transition:transform var(--t) var(--ease)}
.lang[data-open="1"] .lang__trigger svg{transform:rotate(180deg)}
.lang__menu{list-style:none;margin:0;padding:0;position:absolute;right:0;top:calc(100% + 8px);min-width:172px;background:var(--paper);
  border:1px solid var(--line);border-radius:var(--r);padding:6px;z-index:70;
  box-shadow:0 18px 40px -22px rgba(20,39,63,.5);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity var(--t-panel-out) var(--ease),transform var(--t-panel-out) var(--ease),
             visibility var(--t-panel-out)}
.lang[data-open="1"] .lang__menu{opacity:1;visibility:visible;transform:translateY(0);
  transition-duration:var(--t-panel)}
.lang__menu a{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:2px;
  font-size:.9rem;color:var(--ink-2);transition:background-color .2s var(--ease),color .2s var(--ease)}
.lang__menu a:hover,.lang__menu a[aria-current]{background:var(--pale);color:var(--ink)}
.lang__code{font-family:var(--f-n);font-size:.68rem;font-weight:600;letter-spacing:.14em;
  color:var(--navy);min-width:22px}

/* burger + panel movil */
.hdr__burger{display:none;width:44px;height:44px;border:1px solid var(--line);background:transparent;
  border-radius:var(--r);cursor:pointer;place-items:center;padding:0;
  transition:border-color var(--t) var(--ease)}
.hdr__burger span{display:block;width:18px;height:1px;background:var(--ink);position:relative;
  transition:background-color .2s var(--ease)}
.hdr__burger span::before,.hdr__burger span::after{content:"";position:absolute;left:0;width:18px;
  height:1px;background:var(--ink);transition:transform .32s var(--ease)}
.hdr__burger span::before{top:-6px}.hdr__burger span::after{top:6px}
.hdr__burger[aria-expanded="true"] span{background:transparent}
.hdr__burger[aria-expanded="true"] span::before{transform:translateY(6px) rotate(45deg)}
.hdr__burger[aria-expanded="true"] span::after{transform:translateY(-6px) rotate(-45deg)}

@media(max-width:960px){
  /* En reposo el panel está fuera de pantalla Y oculto: sin visibility:hidden los
     enlaces siguen contando como visibles y el menú parece abierto de entrada. */
  .hdr__nav{position:fixed;inset:var(--hdr-h) 0 auto 0;margin:0;background:var(--pale);
    border-radius:0;flex-direction:column;gap:0;padding:8px var(--gut) 26px;border-bottom:1px solid var(--line);
    transform:translateY(-118%);visibility:hidden;
    transition:transform var(--t-panel-out) var(--ease),visibility var(--t-panel-out);
    max-height:calc(100vh - var(--hdr-h));
    max-height:calc(100dvh - var(--hdr-h));overflow:auto;overscroll-behavior:contain}
  .hdr__nav.open{transform:translateY(0);visibility:visible;
    transition-duration:var(--t-panel)}
  .hdr__nav > a{font-size:1.24rem;padding:16px 0;border-bottom:1px solid var(--line-2);color:var(--ink)}
  .hdr__nav > a::after{display:none}
  .hdr__only-mob{display:block}
  .hdr__burger{display:grid}
  .hdr__cta{display:none}
  .hdr__mob{display:flex;flex-direction:column;gap:10px;margin-top:22px}
  .hdr__mob .btn{width:100%;justify-content:center}
}
@media(min-width:961px){.hdr__mob{display:none}}

/* ── PANEL DE TROQUEL — la firma del sitio ─────────────────────────────────
   Un panel de filo fino con cuatro marcas de registro en las esquinas, como el
   pliego de una plegadiza antes de doblarse. Se usa en el hero, en el laboratorio
   de empaque y en la garantia. No lo lleva ningun otro sitio del sistema.        */
.panel{position:relative;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:clamp(26px,3.6vw,52px)}
/* Las marcas de registro eran de 14px: a tamano de pantalla real, invisibles. La firma
   del sitio ES esta marca, asi que se lleva a escala en la que efectivamente se ve. */
.panel::before,.panel::after{content:"";position:absolute;width:30px;height:30px;pointer-events:none}
.panel::before{top:14px;left:14px;border-top:1.5px solid var(--blue);border-left:1.5px solid var(--blue)}
.panel::after{bottom:14px;right:14px;border-bottom:1.5px solid var(--blue);border-right:1.5px solid var(--blue)}
.panel__c{position:absolute;width:30px;height:30px;pointer-events:none}
.panel__c--tr{top:14px;right:14px;border-top:1.5px solid var(--blue);border-right:1.5px solid var(--blue)}
.panel__c--bl{bottom:14px;left:14px;border-bottom:1.5px solid var(--blue);border-left:1.5px solid var(--blue)}
.panel--ink{background-color:var(--navy);color:var(--paper);border-color:rgba(255,255,255,.22);
  /* Sello circular de comprobante, no un icono: es la unica ancla grafica del panel de
     mas peso del sitio. Es fondo — pinta detras del contenido, cero riesgo de tapar texto.
     opacity .5 en el grupo: tinta de sello, no un logo solido compitiendo con la copy. */
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220' viewBox='0 0 220 220'%3E%3Cg fill='none' stroke='%23A3CEF1' stroke-width='1' opacity='.5'%3E%3Ccircle cx='110' cy='110' r='96' stroke-dasharray='2 6'/%3E%3Ccircle cx='110' cy='110' r='74'/%3E%3Cpath d='M74 118 96 140 148 84' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:bottom -46px right -46px;
  background-size:230px 230px}
.panel--ink::before,.panel--ink::after,.panel--ink .panel__c{border-color:var(--sky)}

/* linea de plegado: el separador punteado del sistema */
.fold{height:1px;border:0;border-top:1px dashed var(--line);margin:clamp(24px,3vw,38px) 0}
.phero .fold{margin:clamp(20px,2.2vw,28px) 0}
.sec--ink .fold{border-top-color:var(--line-ink)}

/* ── HERO del home ─────────────────────────────────────────────────────────
   La hoja va a sangre y el texto arranca en el MISMO canal que el logo del
   header (var(--gut)). Es lo que pide la ley de alineación del sistema: si el
   titular se mete dentro de una tarjeta con su propio padding, el logo queda
   corrido respecto del contenido y se lee descuidado.                       */
.phero{padding:clamp(20px,3vw,38px) 0 0;background:var(--pale);position:relative}
/* Hairline de corrugado en el margen pale que enmarca la hoja: es el mismo material del
   negocio del cliente (cajas de carton), no una textura decorativa suelta. Misma receta
   que ya usan .shero__bg y .band__bg — se extiende al unico lugar que no la tenia. La
   hoja blanca de encima la tapa en su area: solo se ve en el marco, donde no compite
   con el texto. */
.phero::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:repeating-linear-gradient(124deg,rgba(39,76,119,.055) 0 1px,transparent 1px 13px)}
.phero__sheet{z-index:1}
.phero__sheet{position:relative;background-color:var(--paper);border-block:1px solid var(--line);
  padding:clamp(30px,3.6vw,48px) 0 clamp(38px,4.4vw,60px);
  /* Perforacion real, no decorativa: una fila de puntos como el borde de arrastre de un
     pliego de impresion, corriendo todo el ancho de la hoja bajo el filo superior. */
  background-image:radial-gradient(circle,rgba(39,76,119,.24) 1.3px,transparent 1.6px);
  background-repeat:repeat-x;background-size:11px 11px;background-position:0 6px}
/* Las escuadras eran de 16px: a escala de pantalla no se leian como la marca del logo,
   se leian como ruido de esquina. Se agrandan a donde efectivamente actuan de firma. */
.phero__sheet::before,.phero__sheet::after{content:"";position:absolute;width:34px;height:34px}
.phero__sheet::before{top:16px;left:max(16px,calc(var(--gut) - 26px));
  border-top:1.5px solid var(--blue);border-left:1.5px solid var(--blue)}
.phero__sheet::after{bottom:16px;right:max(16px,calc(var(--gut) - 26px));
  border-bottom:1.5px solid var(--blue);border-right:1.5px solid var(--blue)}
/* align-items:stretch, no start: con start la columna de datos termina bastante mas
   arriba que la del titular y el filete punteado se corta en el aire, dejando un vacio
   asimetrico dentro de una hoja que justamente esta enmarcada. Estirada, el punteado
   corre toda la altura y cierra la composicion. */
.phero__panel{display:grid;grid-template-columns:minmax(0,.88fr) minmax(0,1.12fr);
  gap:clamp(34px,5vw,76px);align-items:center}
.phero h1{margin-top:18px;max-width:18ch;font-size:clamp(2.7rem,4.65vw,4.2rem)}
.phero__lede{margin-top:18px;max-width:52ch;line-height:1.62}
.phero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(20px,2.2vw,28px)}
.phero__visual{margin:0;position:relative;overflow:hidden;border-radius:10px;
  border:1px solid rgba(39,76,119,.2);background:var(--pale);box-shadow:var(--sh-2)}
.phero__visual img{width:100%;aspect-ratio:3/2;height:auto;object-fit:cover;
  filter:saturate(1.06) contrast(1.03)}
.phero__visual figcaption{position:absolute;left:14px;right:14px;bottom:14px;display:flex;
  flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px;padding:10px 12px;
  color:var(--paper);background:rgba(16,42,67,.84);border:1px solid rgba(255,255,255,.24);
  backdrop-filter:blur(8px);font-family:var(--f-n);font-size:.67rem;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase}
.phero__visual figcaption span:last-child{color:var(--sky);font-weight:600}
/* placa de datos: el panel impreso de una caja */
/* Dos defectos del mismo componente, mismo origen: el grid vivia en CADA fila, asi que
   la columna 'auto' se dimensionaba por fila y la cuarta —cuya etiqueta es una palabra y
   no un numeral— corria su valor 73px. Y con el grid por fila no habia forma de repartir
   las filas en la altura, asi que el punteado corria 595px con el contenido cerrando en
   247. Un solo grid en la placa resuelve los dos: las columnas se comparten (alinea) y
   align-content reparte (acompana el filete de punta a punta). */
.plate{position:relative;margin-top:clamp(28px,3vw,42px);padding-top:14px;
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));overflow:clip;
  border-block:1px dashed var(--line);background:linear-gradient(90deg,var(--paper),var(--pale),var(--paper))}
/* Cifra fantasma: el sitio entero no tenia UN solo numeral protagonista (a proposito,
   ver nota mas abajo). Esta no inventa un dato — repite el 08 real de la fila de arriba
   a escala de sello, sangrando fuera de la hoja como un troquel que corta al borde. */
.plate::after{content:"08";position:absolute;right:-.02em;bottom:-.18em;z-index:0;
  font-family:var(--f-n);font-weight:800;line-height:1;letter-spacing:-.02em;
  font-size:clamp(6rem,11vw,9.5rem);color:transparent;
  -webkit-text-stroke:1.5px rgba(39,76,119,.16);pointer-events:none}
.plate > .plate__k{grid-column:1/-1;padding:0 16px 10px}
.plate > .plate__k,.plate__row{position:relative;z-index:1}
.plate__k{font-family:var(--f-n);font-size:.68rem;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--gray-t)}
.plate__row{grid-column:auto;display:flex;flex-direction:column;gap:7px;align-items:flex-start;
  min-height:100px;padding:16px clamp(14px,2vw,24px) 20px;border-right:1px solid var(--line)}
.plate__row:last-child{border-right:0}
/* Respaldo donde no haya subgrid: la fila se mantiene como caja con su propio filete y
   las columnas se fijan a mano. Se pierde el ajuste automatico, no la linea continua. */
@supports not (grid-template-columns:subgrid){.plate__row{display:flex}}
.plate__v{font-size:.9rem;font-weight:500;color:var(--ink);line-height:1.42;max-width:26ch}
/* El numeral va en el tamano de una ETIQUETA, no en el de una metrica. Ocho categorias y
   seis etapas son inventario, no rendimiento: vestirlos de cifra grande es el molde de
   "numero gigante + rotulo chico" que delata una plantilla. En un sitio cuyo concepto es
   un panel impreso, la voz correcta es la versalita del propio sistema. */
.plate__n{font-family:var(--f-n);font-size:1.08rem;font-weight:700;letter-spacing:.1em;
  color:var(--navy);line-height:1.5;font-variant-numeric:tabular-nums;white-space:nowrap}
@media(max-width:900px){
  .phero__panel{grid-template-columns:1fr}
  .phero__visual{max-width:760px}
  .plate{grid-template-columns:repeat(2,minmax(0,1fr))}
  .plate__row:nth-child(3){border-right:0}
  .plate__row{border-bottom:1px solid var(--line)}
  .plate__row:nth-last-child(-n+2){border-bottom:0}
}
@media(max-width:540px){
  .phero h1{font-size:clamp(2.45rem,12vw,3.45rem)}
  .phero__visual figcaption{position:static;background:var(--navy);border:0}
  .plate__row{min-height:0;padding-inline:12px}
  .plate__v{font-size:.84rem}
}

/* ── tira de categorias (bajo el hero) ─────────────────────────────────── */
.phero__catline{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;
  gap:14px 26px;margin-bottom:22px}
.phero__catline .d3{max-width:34ch}
.catstrip{margin-top:0;display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));gap:2px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.cat{position:relative;background:var(--paper);display:block;overflow:hidden;
  transition:background-color var(--t) var(--ease)}
.cat img{width:100%;aspect-ratio:4/3;height:auto;object-fit:cover;
  filter:saturate(1.2) contrast(1.07) brightness(1.035);
  transition:filter var(--t) var(--ease),opacity var(--t) var(--ease),transform var(--t-panel) var(--ease)}
.cat__b{padding:14px 16px 18px;display:flex;flex-direction:column;gap:5px}
.cat__t{font-size:.98rem;font-weight:600;line-height:1.25;color:var(--ink)}
.cat__s{font-size:.82rem;line-height:1.45;color:var(--ink-2);margin-top:5px;
  display:block;text-wrap:pretty}
/* Tag de inspeccion, no una etiqueta suelta: el mismo codigo de familia que ya estaba,
   con la gramatica de una tarjeta de control de calidad — que es literalmente lo que
   el cliente hace con cada lote. Un dato real vestido de su propio concepto. */
.cat__k{font-family:var(--f-n);font-size:.62rem;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--navy);display:inline-flex;align-items:center;
  gap:6px;width:fit-content;border:1px dashed var(--blue);border-radius:2px;
  padding:3px 8px 3px 6px;background:var(--paper)}
.cat__k::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--blue);flex:none}
/* Unico punto del sitio donde el visitante elige entre ocho cosas: es donde el feedback
   rinde. La respuesta es el gesto de la marca, no un efecto de catalogo: el filete de la
   etiqueta se traza de izquierda a derecha, igual que la linea de plegado del hero. */
.cat__b{position:relative}
.cat__b::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--blue);transform:scaleX(0);transform-origin:left;
  transition:transform var(--t) var(--ease)}
.cat:hover{background:var(--pale)}
.cat:hover img{filter:saturate(1.3) contrast(1.08) brightness(1.04);opacity:1;transform:scale(1.045)}
.cat:focus-visible img{transform:scale(1.045)}
.cat:hover .cat__b::after,.cat:focus-visible .cat__b::after{transform:scaleX(1)}
/* Variante de navegacion cruzada: siete fichas en una grilla de cuatro dejan una celda
   libre, y con el fondo de la tira esa celda se ve como un cajon gris vacio. Aca cada
   ficha lleva su propio filo y el hueco simplemente no existe. */
/* Siete no se divide en cuatro: la fila de abajo quedaba con tres fichas y un vacio a
   la derecha. Sobre doce columnas si cierra — cuatro fichas de tres arriba, tres de
   cuatro abajo — y la fila inferior, un poco mas ancha, se lee deliberada. */
.catstrip--nav{background:transparent;border:0;gap:14px;border-radius:0;
  grid-template-columns:repeat(12,minmax(0,1fr))}
.catstrip--nav .cat{grid-column:span 3;border:1px solid var(--line);
  border-radius:var(--r-lg);overflow:hidden}
.catstrip--nav .cat:nth-child(n+5){grid-column:span 4}
/* La ficha hablaba mas de sus hermanas que de si misma: esta tira era la seccion MAS ALTA
   de la pagina (937px, 22.9% del scroll) y 7 de las 10 imagenes de <main> eran de otras
   categorias. Se conserva la grilla 4+3 —esta bien resuelta— pero la foto pasa a 16/9 y
   la etiqueta se ajusta: navegacion visual, no una segunda portada. */
.catstrip--flat .cat img{aspect-ratio:16/9}
.catstrip--flat .cat__b{padding:10px 13px 14px}
.catstrip--flat .cat__t{font-size:.92rem}
/* En pantalla angosta las siete fichas hermanas se apilan y se comen media pagina: la
   ficha termina hablando mas de sus hermanas que de si misma. Debajo de 700px la
   navegacion cruzada deja la foto y se vuelve lo que es, una lista de destinos. */
@media(max-width:700px){
  .catstrip--nav{grid-template-columns:repeat(2,minmax(0,1fr));gap:0 18px}
  .catstrip--nav .cat,.catstrip--nav .cat:nth-child(n+5){grid-column:auto}
  .catstrip--nav .cat{border:0;border-top:1px solid var(--line);border-radius:0}
  .catstrip--nav .cat img{display:none}
  .catstrip--nav .cat__b{padding:12px 0}
  .catstrip--nav .cat:hover{background:transparent}
  .catstrip--nav .cat:hover .cat__t{color:var(--navy)}
}
@media(max-width:900px){.catstrip{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Va DESPUES de la de 900px: con la misma especificidad manda el orden de fuente, y
   colocada antes esta regla no se aplicaba nunca. */
@media(max-width:420px){.catstrip--nav{grid-template-columns:1fr}}
/* A 360px, ocho tarjetas a sangre daban 2447px = 22% del home y 3.1 pantallas para lo
   que es un bloque de NAVEGACION: el visitante movil pasaba ocho fotos casi identicas a
   nivel miniatura antes de llegar a un solo argumento. Es el mismo diagnostico que ya
   estaba resuelto en .catstrip--nav y que nunca se propago a la variante base. */
/* Primer intento: copiar el tratamiento de .catstrip--nav (sin fotos). Redujo 2115px pero
   dejo el home movil SIN una sola foto de producto, y este cliente vende productos: el
   home tiene que abrir con producto. La tira del home NO es lo mismo que la navegacion
   cruzada de una ficha, aunque compartan componente. Segunda version: se conservan las
   ocho fotos, en dos columnas y con la imagen en 16/9 en vez de 4/3. La tira baja de
   2447px a ~600 y el home sigue mostrando lo que vende. */
@media(max-width:560px){
  .catstrip:not(.catstrip--nav){grid-template-columns:repeat(2,minmax(0,1fr))}
  .catstrip:not(.catstrip--nav) .cat img{aspect-ratio:16/9}
  .catstrip:not(.catstrip--nav) .cat__b{padding:10px 11px 13px}
  .catstrip:not(.catstrip--nav) .cat__t{font-size:.9rem}
}

/* Bento asimetrico de la tira del home/indice: las ocho fichas eran uniformes, 4x2, y se
   leian como una grilla de plantilla. La primera ficha pasa a 2x2 (dense empaqueta las
   otras seis alrededor solo) y la ultima de la fila final a 2x1 ancha — mismo componente,
   mismos filetes, ritmo distinto. Solo desde 901px: por debajo ya baja a lista/2 columnas
   y una asimetria asi necesita el ancho para leerse compuesta y no rota. */
@media(min-width:901px){
  .catstrip:not(.catstrip--nav){grid-auto-flow:row dense}
  .catstrip:not(.catstrip--nav) .cat:nth-child(1){grid-column:span 2;grid-row:span 2;
    display:flex;flex-direction:column}
  .catstrip:not(.catstrip--nav) .cat:nth-child(1) img{flex:1 1 auto;min-height:0;
    aspect-ratio:auto;object-fit:cover}
  .catstrip:not(.catstrip--nav) .cat:nth-child(1) .cat__t{font-size:1.14rem}
  .catstrip:not(.catstrip--nav) .cat:nth-child(8){grid-column:span 2}
  .catstrip:not(.catstrip--nav) .cat:nth-child(8) img{aspect-ratio:21/9}
}

/* ── flujo idea → producto (rail numerado) ─────────────────────────────── */
/* Seis pasos con auto-fit resolvian a cinco columnas y el sexto quedaba solo, con cuatro
   celdas vacias al lado. Es la misma celda huerfana del footer, de la navegacion cruzada y
   de la tira de familias: aca se cierra fijando tres columnas, que dan dos filas llenas. */
.flow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;
  border-top:1px solid var(--line)}
.flow__i{padding:26px clamp(16px,2vw,28px) 30px;border-bottom:1px solid var(--line);
  border-right:1px dashed var(--line);position:relative}
.flow__i:last-child,.flow__i:nth-child(3n){border-right:0}
@media(max-width:820px){
  .flow{grid-template-columns:repeat(2,minmax(0,1fr))}
  .flow__i:nth-child(3n){border-right:1px dashed var(--line)}
  .flow__i:nth-child(2n){border-right:0}
}
@media(max-width:520px){
  .flow{grid-template-columns:1fr}
  .flow__i,.flow__i:nth-child(3n){border-right:0}
}
.flow__n{font-family:var(--f-n);font-size:.7rem;font-weight:700;letter-spacing:.2em;color:var(--blue-t);
  font-variant-numeric:tabular-nums}
.flow__i h3{font-size:1.04rem;font-weight:600;margin-top:12px;line-height:1.3}
.flow__i p{font-size:.92rem;color:var(--ink-2);margin-top:9px;line-height:1.62}
.sec--ink .flow{border-top-color:var(--line-ink)}
.sec--ink .flow__i{border-bottom-color:var(--line-ink);border-right-color:var(--line-ink)}
.sec--ink .flow__n{color:var(--sky)}
.sec--ink .flow__i p{color:var(--on-navy-2)}
@media(max-width:700px){.flow__i{border-right:0}}

/* ── tarjetas de servicio / valor ─────────────────────────────────────── */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:clamp(14px,1.8vw,22px)}
/* Cuatro tarjetas en una fila dejan 207px utiles = ~26 caracteres de medida: todo parrafo
   de mas de 15 palabras sale en 6-8 lineas de 4 palabras. En 2x2 la medida sube a ~62. */
@media(min-width:900px){
  .cards:has(> :nth-child(4):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}
}
.card{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:clamp(22px,2.6vw,30px);position:relative;box-shadow:var(--sh-1);
  transition:border-color var(--t) var(--ease),transform var(--t) var(--ease),
             box-shadow var(--t) var(--ease)}
.card:hover{transform:translateY(-4px);box-shadow:var(--sh-2)}
.card h3{font-size:1.12rem;font-weight:700;margin-top:14px;line-height:1.28;letter-spacing:-.01em}
.card p{font-size:.95rem;color:var(--ink-2);margin-top:11px}
.card ul{margin-top:14px;display:flex;flex-direction:column;gap:7px}
.card li{font-size:.89rem;color:var(--ink-2);padding-left:16px;position:relative;line-height:1.5}
.card li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:1px;background:var(--blue)}
.sec--ink .card{background:rgba(255,255,255,.06);border-color:var(--line-ink);box-shadow:none}
.sec--ink .card h3{color:var(--paper)}
.sec--ink .card p,.sec--ink .card li{color:var(--on-navy-2)}

/* ── lista de pasos (una sola columna, filetes finos) ──────────────────────
   Deliberadamente NO es otra grilla de tarjetas: el home ya trae el rail del
   proceso, y dos grillas iguales hacen que el ojo lea las dos como una sola. */
.steps{border-top:1px solid var(--line);max-width:78ch}
/* Cuando la lista sigue a una figura, su medida de lectura la desalinea con la foto de
   arriba: el filete corta 376px antes. Ahi manda la figura, no la medida. */
.fig + .steps{max-width:none}
.steps li{padding:20px 0;border-bottom:1px solid var(--line)}
.steps li:last-child{border-bottom:0}
/* Variante a dos columnas para cuando la lista va a lo ancho de la pagina. */
@media(min-width:820px){
  /* columns:2 lee hacia ABAJO y deja los filetes de las dos columnas a alturas
     distintas, con el ultimo de la izquierda conservando un filete que no separa nada.
     Grid lee a lo ancho y las filas quedan a la misma altura. */
  .steps--2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    column-gap:clamp(28px,4vw,56px)}
  .steps--2 li:nth-last-child(-n+2){border-bottom:0}
}
.steps h3{font-size:1.06rem;font-weight:700;line-height:1.3;letter-spacing:-.01em}
.steps__n{font-family:var(--f-n);font-size:.72rem;font-weight:700;letter-spacing:.2em;
  color:var(--blue-t);margin-right:12px;vertical-align:.12em}
.steps p{font-size:.95rem;color:var(--ink-2);margin-top:8px;max-width:68ch}

/* ── filas zigzag (servicios / desarrollo) ────────────────────────────── */
.fzig{display:flex;flex-direction:column;gap:clamp(40px,5.5vw,88px)}
.fzig__row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(24px,4vw,60px);align-items:center}
.fzig__row:nth-child(even) .fzig__media{order:2}
/* Espejo explicito: en las fichas de categoria hay una sola fila, asi que nth-child(even)
   nunca aplica y las ocho paginas repetian la misma composicion imagen-izquierda. */
.fzig__row--flip .fzig__media{order:2}
.fzig__media img{width:100%;aspect-ratio:4/3;height:auto;object-fit:cover;
  filter:saturate(1.18) contrast(1.07) brightness(1.035);
  border-radius:10px;border:1px solid rgba(39,76,119,.2);box-shadow:var(--sh-2)}
.fzig__copy .snum{font-family:var(--f-n);font-size:.72rem;font-weight:700;letter-spacing:.2em;color:var(--blue-t)}
.fzig__copy h3{font-size:clamp(1.24rem,2vw,1.6rem);font-weight:700;margin-top:12px;
  line-height:1.2;letter-spacing:-.015em}
.fzig__copy p{margin-top:14px;color:var(--ink-2)}
.slist{margin-top:18px;display:flex;flex-wrap:wrap;gap:8px}
.slist li{font-family:var(--f-n);font-size:.74rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--navy);border:1px solid var(--line);
  border-radius:var(--r);padding:7px 11px;background:var(--paper)}
/* Fila ancha: media a todo el ancho y copy debajo en dos columnas. Existe para cortar la
   cadena de filas partidas: seis splits seguidos son la misma plantilla seis veces, y a la
   tercera el ojo deja de leer y empieza a barrer. Se aplica cada dos filas. */
.fzig__row--wide{grid-template-columns:1fr;gap:clamp(20px,2.6vw,32px)}
.fzig__row--wide .fzig__media{order:0}
.fzig__row--wide .fzig__media img{aspect-ratio:21/9}
/* La copia de la fila ancha va en bloque, no en dos columnas: con el numero y el titulo
   en una columna y el parrafo spanneando dos filas, las filas de la grilla se estiran a la
   altura del parrafo y abren un pozo entre el 03 y su titulo. Media ancha + copia apilada
   ya es otra familia de layout que la fila partida, que es lo que se buscaba. */
.fzig__row--wide .fzig__copy{max-width:74ch}
.fzig__row--wide .fzig__copy p{max-width:68ch}
@media(max-width:820px){
  .fzig__row{grid-template-columns:1fr}
  .fzig__row:nth-child(even) .fzig__media{order:0}
  .fzig__row--flip .fzig__media{order:0}
  .fzig__row--wide .fzig__media img{aspect-ratio:16/9}
}

/* ── banda de imagenes ─────────────────────────────────────────────────── */
.imgband{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:14px}
.imgband img{width:100%;aspect-ratio:4/3;height:auto;object-fit:cover;
  filter:saturate(1.18) contrast(1.07) brightness(1.035);
  border-radius:10px;border:1px solid rgba(39,76,119,.2);box-shadow:var(--sh-1)}
.fig{margin:0}
.fig img{width:100%;aspect-ratio:16/9;height:auto;object-fit:cover;
  filter:saturate(1.16) contrast(1.08) brightness(1.03);
  border-radius:10px;border:1px solid rgba(39,76,119,.2);box-shadow:var(--sh-2)}
.fig figcaption{font-family:var(--f-n);font-size:.76rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--gray-t);margin-top:12px}

/* ── laboratorio de empaque (grilla de troqueles) ─────────────────────── */
/* Seis formatos con auto-fit resolvian a cuatro columnas: la fila de abajo quedaba con
   dos fichas y dos celdas vacias. Quinta aparicion de la misma celda huerfana. */
.packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.8vw,20px)}
@media(max-width:820px){.packs{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:520px){.packs{grid-template-columns:1fr}}
.pack{border:1px dashed var(--line);border-radius:var(--r-lg);padding:24px;background:var(--paper)}
.pack h3{font-size:1.06rem;font-weight:700;margin-top:12px;line-height:1.3}
.pack p{font-size:.93rem;color:var(--ink-2);margin-top:10px}

/* ── tabla de referencia ──────────────────────────────────────────────── */
/* overflow-x:auto sin foco de teclado es el unico contenido del sitio inalcanzable sin
   raton (WCAG 2.1.1), y a 360px se ve el 52% de la tabla sin ninguna senal de que hay mas.
   La mascara se apaga en pantalla ancha, donde la tabla entra entera. */
.tscroll{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--paper);
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 34px),transparent);
          mask-image:linear-gradient(90deg,#000 calc(100% - 34px),transparent)}
.tscroll:focus-visible{outline:2px solid var(--navy);outline-offset:-2px}
@media(min-width:760px){.tscroll{-webkit-mask-image:none;mask-image:none}}
.rt{width:100%;border-collapse:collapse;min-width:640px}
.rt th,.rt td{text-align:left;padding:15px 18px;border-bottom:1px solid var(--line-2);
  font-variant-numeric:tabular-nums;
  font-size:.93rem;vertical-align:top}
.rt thead th{font-family:var(--f-n);font-size:.7rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--navy);background:var(--pale);border-bottom:1px solid var(--line)}
.rt tbody th{font-weight:600;color:var(--ink);width:24%}
.rt td{color:var(--ink-2)}
.rt tbody tr:last-child th,.rt tbody tr:last-child td{border-bottom:0}

/* ── lista de definiciones (datos legales) ───────────────────────────── */
/* gap:0 dejaba 3px entre etiqueta y valor cuando la etiqueta llena su columna, y se
   leia como una sola linea corrida. Defecto exclusivo del ingles (ES 31px, ZH 128px).
   El row-gap sigue en 0: lo que separa filas es el filete, no el aire. */
.dl{display:grid;grid-template-columns:minmax(140px,.5fr) minmax(0,1fr);gap:0}
.dl dt{padding-right:clamp(20px,2.4vw,40px)}
.dl dt{font-family:var(--f-n);font-size:.72rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gray-t);padding:14px 0;border-bottom:1px solid var(--line)}
.dl dd{margin:0;padding:14px 0;border-bottom:1px solid var(--line);color:var(--ink)}
/* El filete separa pares; despues del ultimo no separa nada y queda colgando. Es el mismo
   arreglo que ya llevaba .steps y que no se habia propagado aca. */
.dl dt:last-of-type,.dl dd:last-of-type{border-bottom:0}
/* En columna angosta (.cgrid) la etiqueta necesita mas medida: a .5fr toda etiqueta
   de tres palabras parte en dos lineas y la lista se ve rota. */
.cgrid .dl{grid-template-columns:minmax(150px,.46fr) minmax(0,1fr)}
/* Dos pares por fila: ocho filas de datos en una sola columna dejan media seccion vacia
   al lado. Asi la lista usa el ancho y el alto se parte por dos. */
.dl--2{grid-template-columns:repeat(2,minmax(130px,.42fr) minmax(0,1fr))}
.dl--2 dd{padding-right:clamp(20px,2.4vw,40px)}
.dl--2 dd:last-of-type{padding-right:0}
.dl--2 dt:nth-last-of-type(-n+2),.dl--2 dd:nth-last-of-type(-n+2){border-bottom:0}
@media(max-width:820px){.dl--2{grid-template-columns:minmax(130px,.5fr) minmax(0,1fr)}
  .dl--2 dd{padding-right:0}
  .dl--2 dt:nth-last-of-type(-n+2),.dl--2 dd:nth-last-of-type(-n+2){border-bottom:1px solid var(--line-ink)}
  .dl--2 dt:last-of-type,.dl--2 dd:last-of-type{border-bottom:0}}
.sec--ink .dl dt{color:var(--sky);border-bottom-color:var(--line-ink)}
.sec--ink .dl dd{color:var(--paper);border-bottom-color:var(--line-ink)}
@media(max-width:560px){.dl{grid-template-columns:1fr}.dl dt{border-bottom:0;padding-bottom:2px}}

/* ── preguntas ────────────────────────────────────────────────────────── */
.qa{border-top:1px solid var(--line)}
.qa details{border-bottom:1px solid var(--line)}
.qa summary{list-style:none;cursor:pointer;padding:20px 44px 20px 0;position:relative;
  font-size:1.03rem;font-weight:600;line-height:1.4;
  transition:color var(--t) var(--ease)}
.qa summary::-webkit-details-marker{display:none}
.qa summary::after{content:"";position:absolute;right:8px;top:22px;width:11px;height:11px;
  border-right:1.5px solid var(--navy);border-bottom:1.5px solid var(--navy);
  transform:rotate(45deg);transition:transform .32s var(--ease)}
.qa details[open] summary::after{transform:rotate(-135deg);top:33px}
.qa summary:hover{color:var(--navy)}
.qa__a{padding:0 8% 24px 0}
.qa__a p{color:var(--ink-2)}

/* ── canales de contacto ──────────────────────────────────────────────── */
.cgrid{display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);gap:clamp(28px,4vw,64px);
  align-items:start}
@media(max-width:900px){.cgrid{grid-template-columns:1fr}}
.chan{border-top:1px solid var(--line)}
/* Con flex-wrap, el valor que no entra al lado de la etiqueta de 118px baja a ancho
   completo: la fila 'Hours' arrancaba en x=146 y las otras cuatro en x=278. Una fila de
   cinco fuera de grilla, en una lista corta y muy visible. */
.chan li{display:grid;grid-template-columns:118px minmax(0,1fr) auto;
  align-items:baseline;gap:6px 14px;padding:15px 0;border-bottom:1px solid var(--line)}
@media(max-width:560px){.chan li{grid-template-columns:1fr}}
.chan__k{font-family:var(--f-n);font-size:.7rem;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:var(--gray-t);min-width:118px}
.chan__v{font-size:1rem;color:var(--ink);font-weight:500;word-break:break-word}
a.chan__v{justify-self:start;border-bottom:1px solid var(--line);
  transition:border-color var(--t) var(--ease)}
a.chan__v:hover{border-color:var(--navy)}
.chan__c{margin-left:auto;background:transparent;border:1px solid var(--line);border-radius:var(--r);
  padding:6px 11px;font-family:var(--f-n);font-size:.68rem;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-2);cursor:pointer;
  transition:border-color var(--t) var(--ease),color var(--t) var(--ease)}
.chan__c:hover{border-color:var(--navy);color:var(--navy)}

/* ── formulario ───────────────────────────────────────────────────────── */
.formcard{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  padding:clamp(24px,3vw,38px);box-shadow:var(--sh-2)}
.formcard h2{font-size:1.3rem;font-weight:700;letter-spacing:-.01em}
.formcard>p{color:var(--ink-2);font-size:.95rem;margin-top:10px}
.frow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
@media(max-width:620px){.frow{grid-template-columns:1fr}}
.field{display:flex;flex-direction:column;gap:7px;margin-top:16px}
/* El formulario no decia que era obligatorio (WCAG 3.3.2) y su unico canal de error era
   la burbuja nativa, que toma su idioma del NAVEGADOR y no del de la pagina: un comprador
   chino con el navegador en ingles recibia el error en ingles sobre una pagina en chino. */
.reqnote{font-family:var(--f-n);font-size:.74rem;letter-spacing:.08em;color:var(--ink-2);margin-top:14px}
.req{color:var(--err-t);margin-left:3px;font-weight:700}
.fielderr{display:none;margin-top:6px;font-size:.84rem;color:var(--err-t)}
.field.bad .fielderr{display:block}
.field.bad input,.field.bad select,.field.bad textarea{border-color:var(--err)}
.field label{font-family:var(--f-n);font-size:.72rem;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-2)}
.field input,.field select,.field textarea{background-color:var(--pale);color:var(--ink);
  border:1px solid var(--line);
  border-radius:var(--r);padding:12px 14px;font-size:.97rem;width:100%;
  transition:border-color var(--t) var(--ease),background-color var(--t) var(--ease)}
/* El UA calcula la caja del select distinto que la del input, asi que en la misma fila
   quedaba ~4px mas bajo, y mostraba el chevron nativo del sistema operativo entre
   chevrons dibujados a 1.5px en navy. Mismo trazo que el del selector de idioma. */
.field select{appearance:none;-webkit-appearance:none;padding-right:38px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23274C77' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center}
.field input:hover,.field textarea:hover,.field select:hover{border-color:var(--gray)}
.field input::placeholder,.field textarea::placeholder{color:var(--gray-t);opacity:1}
.field input:disabled,.field textarea:disabled,.field select:disabled{
  background:var(--pale);color:var(--gray);cursor:not-allowed;border-color:var(--line-2)}
/* :user-invalid y no :invalid: :invalid pinta el campo en rojo apenas carga la pagina,
   antes de que nadie haya escrito nada. Solo despues de que el visitante lo toco. */
.field input:user-invalid,.field textarea:user-invalid,.field select:user-invalid{
  border-color:var(--err);background:var(--paper)}
.field input:focus,.field textarea:focus,.field select:focus{background:var(--paper);
  border-color:var(--navy);outline:2px solid rgba(39,76,119,.18);outline-offset:1px}
.field textarea{resize:vertical;min-height:104px}
.formcard .btn{margin-top:22px}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.formmsg{margin-top:14px;font-size:.92rem;min-height:1.2em}
.formmsg[data-s="ok"]{color:var(--ok-t)}
.formmsg[data-s="err"]{color:var(--err-t)}

/* ── subhero de paginas internas ─────────────────────────────────────── */
.shero{position:relative;background:var(--navy);color:var(--paper);overflow:hidden;
  padding:clamp(56px,7vw,96px) 0 clamp(48px,6vw,80px)}
.shero__bg{position:absolute;inset:0;z-index:0}
.shero__bg img{width:100%;height:100%;object-fit:cover;opacity:.92;
  filter:saturate(1.24) contrast(1.08) brightness(1.02)}
.shero__bg::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(102deg,rgba(20,57,88,.96) 0%,rgba(39,76,119,.86) 38%,rgba(39,76,119,.34) 72%,rgba(20,39,63,.12))}
/* Hairline de corrugado: el material del negocio del cliente es carton, no una textura
   decorativa suelta. Encima del degrade (z-index mas alto), muy tenue, solo lineas. */
.shero__bg::before{content:"";position:absolute;inset:0;z-index:2;
  background-image:repeating-linear-gradient(124deg,rgba(255,255,255,.07) 0 1px,transparent 1px 13px)}
/* En pantalla angosta el texto ocupa todo el ancho y llega a la zona clara del scrim
   diagonal: ahi el degradé pasa a ser vertical y mantiene el contraste. */
@media(max-width:860px){
  .shero__bg::after{background:linear-gradient(168deg,var(--navy) 48%,rgba(39,76,119,.74))}
}
.shero .wrap{position:relative;z-index:1}
.shero h1{margin-top:18px;max-width:19ch}
.shero .lede{color:var(--on-navy);margin-top:18px;max-width:58ch}
.shero__cta{margin-top:28px;display:flex;flex-wrap:wrap;gap:12px}
/* Sobre foto, el celeste de marca se queda en 4,2:1. La versión clara del mismo
   tono llega a AA sin cambiar el registro cromático. */
.shero .eyebrow{color:var(--on-navy)}
.shero .eyebrow::before{background:var(--on-navy)}
/* Al sacar la etiqueta del subhero, la miga de pan pasó a ser el texto más chico
   sobre la foto: sube a un celeste casi blanco para llegar a AA sobre el scrim. */
.crumb{font-family:var(--f-n);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--on-navy);display:flex;flex-wrap:wrap;gap:9px;align-items:center;margin-bottom:14px}
.crumb a{border-bottom:1px solid rgba(255,255,255,.3)}
.crumb a:hover{border-bottom-color:var(--paper);color:var(--paper)}

/* ── banda de cierre ─────────────────────────────────────────────────── */
.band{position:relative;background:var(--navy);color:var(--paper);overflow:hidden;
  padding:clamp(56px,7vw,96px) 0}
.band__bg{position:absolute;inset:0;z-index:0}
/* Misma receta que el subhero, y por la misma razon: con opacidad .3 y un degrade que
   nunca baja del 60% de navy, la foto se entierra y la mitad derecha de la banda queda
   vacia (739 px medidos, el 60% del contenedor). El sitio ya tenia resuelto esto dos
   secciones mas arriba; la banda no tenia por que inventar otra formula. */
.band__bg img{width:100%;height:100%;object-fit:cover;opacity:.9;
  filter:saturate(1.24) contrast(1.09) brightness(1.02)}
.band__bg::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(102deg,rgba(20,57,88,.96) 0%,rgba(39,76,119,.86) 38%,rgba(39,76,119,.34) 72%,rgba(20,39,63,.12))}
.band__bg::before{content:"";position:absolute;inset:0;z-index:2;
  background-image:repeating-linear-gradient(124deg,rgba(255,255,255,.07) 0 1px,transparent 1px 13px)}
@media(max-width:860px){
  .band__bg::after{background:linear-gradient(168deg,var(--navy) 48%,rgba(39,76,119,.74))}
}
.band .wrap{position:relative;z-index:1}
.band .d2{margin-top:16px;max-width:20ch}
.band p{margin-top:16px;color:var(--on-navy);max-width:56ch}
.band__cta{margin-top:28px;display:flex;flex-wrap:wrap;gap:12px}

/* ── footer 01 · columnas anchas ─────────────────────────────────────── */
/* Filete de separacion: la banda (var(--navy)) y el pie (var(--ink)) son dos oscuros vecinos y
   sin nada entre medio se leen como un solo bloque, que en movil es el 40% final de la
   pagina. Un pelo del celeste de marca los vuelve a separar sin agregar una seccion. */
.sec--ink + .band{border-top:1px solid rgba(163,206,241,.22)}
.ft{background:var(--ink);color:var(--on-ink-2);border-top:1px solid rgba(163,206,241,.22);
  padding-bottom:env(safe-area-inset-bottom)}
.ft__in{max-width:var(--maxw);margin-inline:auto;padding:clamp(52px,6.5vw,88px) var(--gut) 0}
/* CINCO pistas para cinco columnas. Con cuatro, la de contacto caia a una segunda fila y
   dejaba tres celdas vacias al lado: el mismo hueco que ya se habia corregido en la tira de
   navegacion cruzada. Si se agrega o quita una columna, se ajusta aca. */
.ft__grid{display:grid;grid-template-columns:1.45fr 1.15fr 1.05fr .9fr 1.05fr;
  gap:clamp(24px,3vw,40px);
  padding-bottom:clamp(34px,4vw,52px)}
@media(max-width:1120px){.ft__grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:900px){.ft__grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.ft__grid{grid-template-columns:1fr}}
.ft__logo{display:inline-flex;align-items:center;gap:12px}
.ft__logo img{width:auto;height:38px}
.ft__logo .hdr__wm b{color:var(--paper)}
.ft__logo .hdr__wm span{color:var(--on-ink)}
.ft__tag{margin-top:16px;color:var(--on-ink);font-size:.93rem;max-width:36ch;line-height:1.7}
.ft__addr{margin-top:16px;font-family:var(--f-n);font-size:.74rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--on-ink)}
.ft__col h3{font-family:var(--f-n);font-size:.7rem;font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--on-ink)}
.ft__col ul{margin-top:16px;display:flex;flex-direction:column;gap:11px}
/* Los enlaces del pie median 16px de alto. Pasan AA por la excepcion de espaciado de
   WCAG 2.5.8 (paso de 40px entre centros), pero 16px es un tercio del minimo de
   plataforma. El aire que ya existia se convierte en area tocable sin mover el ritmo. */
.ft__col a{font-size:.94rem;color:var(--on-navy);position:relative;width:max-content;
  display:inline-block;padding-block:11px;
  transition:color var(--t) var(--ease)}
/* El padding tocable corre el borde inferior de la caja: el filete se ancla al texto. */
.ft__col a::after{content:"";position:absolute;left:0;right:0;bottom:8px;height:1px;background:var(--sky);
  transform:scaleX(0);transform-origin:right;transition:transform .42s var(--ease)}
.ft__col a:hover{color:var(--paper)}
.ft__col a:hover::after{transform:scaleX(1);transform-origin:left}
.ft__cta{display:inline-flex;align-items:center;gap:9px;margin-top:20px;font-family:var(--f-n);
  font-size:.72rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--paper);
  border:1px solid rgba(255,255,255,.4);border-radius:var(--r);padding:11px 17px;
  transition:background-color var(--t) var(--ease),color var(--t) var(--ease),border-color var(--t) var(--ease)}
.ft__cta svg{width:13px;height:13px;transition:transform var(--t) var(--ease)}
.ft__cta:hover{background:var(--paper);color:var(--ink);border-color:var(--paper)}
.ft__cta:hover svg{transform:translateX(3px)}
.ft__bottom{border-top:1px solid rgba(255,255,255,.13);padding:20px 0 30px;display:flex;
  flex-wrap:wrap;gap:12px 26px;justify-content:space-between;align-items:center;
  font-size:.8rem;color:var(--on-ink)}
.ft__bottom a{border-bottom:1px solid transparent;transition:border-color var(--t) var(--ease)}
.ft__bottom a:hover{border-bottom-color:var(--on-ink)}
.ft__up{display:inline-flex;align-items:center;gap:8px;font-family:var(--f-n);font-size:.7rem;
  letter-spacing:.16em;text-transform:uppercase}
.ft__up svg{width:13px;height:13px}

/* ── aviso de cookies: barra inferior fija, nunca encima del contenido ─── */
/* Con la barra visible, el pie quedaba tapado: en las legales eso deja el cierre del
   texto inalcanzable hasta aceptar. El body reserva el alto de la barra mientras esta. */
html.ck body{padding-bottom:var(--ck-h,132px)}
.cookie{position:fixed;left:0;right:0;bottom:0;z-index:80;background:var(--ink);color:var(--on-ink-2);
  padding:14px var(--gut);display:flex;flex-wrap:wrap;gap:14px;align-items:center;
  justify-content:center;font-size:.88rem;
  transform:translateY(0);transition:transform .42s var(--ease)}
.cookie.hide{transform:translateY(110%)}
.cookie .btn{padding:9px 16px}

/* ── UN solo momento de motion, y es el de la marca ────────────────────────
   Antes cada seccion entraba con el mismo desplazamiento de 14 px: repetido
   catorce veces deja de ser un gesto y pasa a ser un tic. Ahora el sitio tiene
   un unico momento autoral, y es literalmente su firma: al cargar el home, las
   dos escuadras de registro de la hoja del hero se dibujan (la misma marca del
   logotipo trazandose sobre la pagina), la linea de plegado corre de izquierda
   a derecha y el "08" fantasma de la placa cae como un sello. Tres cuadros de
   la MISMA secuencia de carga, en el MISMO lugar — no tres momentos sueltos. */
/* Se dibujan con clip-path y no creciendo de tamano: animar width/height obliga al
   navegador a recalcular layout en cada cuadro. La escuadra ya esta a su medida y lo
   que corre es la mascara, cada una desde SU esquina, que ademas es como se traza. */
.js .phero__sheet::before{animation:mark-draw-tl .9s var(--ease) both}
.js .phero__sheet::after{animation:mark-draw-br .9s var(--ease) .12s both}
@keyframes mark-draw-tl{
  from{opacity:0;clip-path:inset(0 100% 100% 0)}
  to{opacity:1;clip-path:inset(0 0 0 0)}
}
@keyframes mark-draw-br{
  from{opacity:0;clip-path:inset(100% 0 0 100%)}
  to{opacity:1;clip-path:inset(0 0 0 0)}
}
.js .phero .fold{transform-origin:left center;animation:fold-run 1.1s var(--ease) .18s both}
@keyframes fold-run{from{transform:scaleX(0)}to{transform:scaleX(1)}}
/* Cierra la secuencia: el 08 fantasma "cae" y asienta, como un sello de goma que pega y
   rebota una vez. Arranca despues de que el pliegue termino (1.1s + .18s de delay). */
.js .plate::after{animation:stamp-hit .5s var(--ease-2) 1.05s both}
@keyframes stamp-hit{0%{transform:scale(1.5)}60%{transform:scale(.95)}100%{transform:scale(1)}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
  /* el momento de la firma no se reproduce: las marcas, el pliegue y el sello arrancan quietos */
  .js .phero__sheet::before,.js .phero__sheet::after{animation:none;opacity:1;clip-path:none}
  .js .phero .fold{animation:none;transform:none}
  .js .plate::after{animation:none;transform:none}
  /* la elevacion y la escala son movimiento: quien las apaga no las quiere */
  .cat:hover img,.cat:focus-visible img{transform:none}
  .card:hover{transform:none}
}

/* ── impresion ───────────────────────────────────────────────────────── */
@media print{
  .hdr,.cookie,.band,.ft__cta{display:none}
  body{background:var(--paper)}
}


/* ============================================================================
   CAPA DE EFECTOS — firma `troquel-trazado`
   ----------------------------------------------------------------------------
   Todo cuelga de .fx: sin esa clase (JS apagado, o la capa retirada) el sitio
   queda exactamente como estaba. Nada de aca toca una regla de la base.

   El oficio del cliente son tres verbos y hay un efecto por verbo:
     marcar  -> las escuadras de registro se trazan desde su propia esquina
     plegar  -> la linea de hendido recorre el ancho, atada al scroll
     cerrar  -> el pliego plano se levanta y queda de frente: la caja terminada

   Los valores salen de los tokens. Nada hardcodeado (criterio (g).6 de la partitura).
   ============================================================================ */
.fx{
  /* La escala de motion de la capa NO es una copia de la del sitio: ES la del sitio.
     Estos tres estaban escritos a mano (120ms/240ms/420ms) — los mismos numeros que
     --t-tap/--t/--t-panel, pero desconectados: una copia se desincroniza en cuanto
     alguien retempla la base, y ademas los tres estaban DECLARADOS Y SIN USAR, con la
     unica duracion real de la capa (--fx-marca) puesta a mano fuera de la escala.
     Derivados, no pueden mentir; y abajo cada uno tiene su consumidor. */
  --fx-dur-1:var(--t-tap);   /* amortiguar algo chico: la linea de hendido, 1.5px */
  --fx-dur-2:var(--t);       /* amortiguar una superficie: el pliego del set-piece */
  --fx-dur-3:var(--t-panel); /* trazo declarado: la escuadra de registro */
  --fx-ease-out:var(--ease-2);
  --fx-ease-out-expo:var(--ease);
  --fx-stagger:70ms;
  /* Lo que tarda una escuadra en trazarse. Era 520ms sueltos. Una escuadra dibujandose
     es, en el vocabulario del propio sitio, "una superficie que se abre": --fx-dur-3.
     Medido: con --fx-ease-out-expo el 95% del trazo se completa en el 38% de la
     duracion (198ms a 520 / 160ms a 420), asi que el cambio no lo hace brusco: le quita
     una cola invisible de 100ms y lo devuelve a la escala declarada. */
  --fx-marca:var(--fx-dur-3);
  /* amplitud del set-piece. 26deg y no 38: con la perspectiva YA APLICADA (ver abajo) el
     escorzo real comprime mas la caja del <img> que el aplastado plano que habia antes,
     y el gate de la BASE mide esa caja. Medido en navegador a 1024/1440/1920 con
     perspective 1600: 22deg->2.79 · 26deg->2.92 · 30deg->3.08 · 34deg->3.27 · 38deg->3.48.
     El tope que manda NO es el 3.2 de IMG-proporcion sino el mas duro de los dos:
     IMG-ratio-declarado admite 35% sobre el aspect-ratio de la hoja (21/9 = 2.333), o sea
     3.15. 26deg -> 2.922 deja 0.23 de margen; 30deg -> 3.08 dejaria 0.07 y no vale la pena.
     El angulo no era el problema: el problema era DONDE se gastaba (ver el anclaje). */
  --fx-giro:26deg;
  --fx-escala:.06;
}

/* ── marcar ───────────────────────────────────────────────────────────────
   Dos escuadras por panel, cada una trazandose DESDE SU PROPIA ESQUINA con
   clip-path. Es la geometria del logotipo del cliente: logotipo y pagina son
   la misma gramatica. Sin DOM nuevo: son pseudo-elementos sobre markup que ya
   existe, y .cat::before/::after estaban libres. */
/* :not([data-fx-modo="propio"]) NO es cosmetica. En modo "propio" la escuadra es del
   contenedor, y el JS solo le pone .fx-marcado a el — nunca a sus hijos. Pero estas
   reglas SI alcanzaban a esos hijos: cada uno cargaba su par de pseudo-elementos
   recortados, invisibles y muertos... hasta que la regla de prefers-reduced-motion los
   abria a todos. Medido en la banda de cierre del home: 2 escuadras dibujadas con motion
   normal contra 8 con la preferencia activa (h2 + p + .band__cta sumaban 6 marcas que no
   existen en ningun otro estado). Es el defecto exacto que la partitura (e) promete
   evitar: quien apaga el movimiento tiene que ver el estado FINAL, no uno inventado.
   Afectaba a las 14 paginas con banda. */
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *{position:relative}
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::before,
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::after{
  content:"";position:absolute;width:15px;height:15px;z-index:2;
  pointer-events:none;border-style:solid;border-color:var(--blue);border-width:0;
  transition:clip-path var(--fx-marca) var(--fx-ease-out-expo);
  transition-delay:calc(var(--fx-i,0) * var(--fx-stagger));
}
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::before{
  top:9px;left:9px;border-top-width:1.5px;border-left-width:1.5px;
  clip-path:inset(0 100% 100% 0);
}
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::after{
  bottom:9px;right:9px;border-bottom-width:1.5px;border-right-width:1.5px;
  clip-path:inset(100% 0 0 100%);
}
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > .fx-marcado::before,
.fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > .fx-marcado::after{clip-path:inset(0 0 0 0)}
/* Variante "propio": la escuadra marca el PROPIO elemento en vez de sus hijos.
   Es la que cierra la banda final — la hoja queda troquelada. */
.fx [data-fx="troquel-marca"][data-fx-modo="propio"]::before,
.fx [data-fx="troquel-marca"][data-fx-modo="propio"]::after{
  content:"";position:absolute;width:15px;height:15px;z-index:2;
  pointer-events:none;border-style:solid;border-color:var(--sky);border-width:0;
  transition:clip-path var(--fx-marca) var(--fx-ease-out-expo);
}
.fx [data-fx="troquel-marca"][data-fx-modo="propio"]::before{
  top:9px;left:9px;border-top-width:1.5px;border-left-width:1.5px;
  clip-path:inset(0 100% 100% 0);
}
.fx [data-fx="troquel-marca"][data-fx-modo="propio"]::after{
  bottom:9px;right:9px;border-bottom-width:1.5px;border-right-width:1.5px;
  clip-path:inset(100% 0 0 100%);
}
.fx [data-fx="troquel-marca"][data-fx-modo="propio"].fx-marcado::before,
.fx [data-fx="troquel-marca"][data-fx-modo="propio"].fx-marcado::after{clip-path:inset(0 0 0 0)}
@media (prefers-reduced-motion:reduce){
  .fx [data-fx="troquel-marca"][data-fx-modo="propio"]::before,
  .fx [data-fx="troquel-marca"][data-fx-modo="propio"]::after{clip-path:inset(0 0 0 0);transition:none}
}
/* Una marca de registro se imprime para VERSE: el impresor elige la tinta que
   contrasta con lo que tiene debajo. En azul de 1.5px sobre una fotografia
   desaparece — detectado en el golden reference antes de replicarla a las ocho
   fichas. Con data-fx-sobre="foto" la escuadra pasa a tinta clara con un halo
   minimo, que es lo que la hace legible sobre cualquier imagen. */
.fx [data-fx="troquel-marca"][data-fx-sobre="foto"]:not([data-fx-modo="propio"]) > *::before,
.fx [data-fx="troquel-marca"][data-fx-sobre="foto"]:not([data-fx-modo="propio"]) > *::after{
  border-color:var(--paper);
  filter:drop-shadow(0 0 1.5px rgba(20,39,63,.65));
}
/* Sobre navy la escuadra usa el acento claro, o no se ve. */
.fx .sec--ink [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::before,
.fx .sec--ink [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::after{border-color:var(--sky)}
/* la banda es siempre modo "propio": su escuadra la pinta la regla [data-fx-modo] de
   arriba, ya en var(--sky). La variante para hijos que habia aca no alcanzaba a nadie. */

/* ── plegar ───────────────────────────────────────────────────────────────
   La hendidura recorre el ancho con scaleX desde su propio origen. El progreso
   lo escribe la firma en --fx-pliegue; el CSS solo lo consume. */
.fx [data-fx="troquel-pliegue"]{position:relative}
.fx [data-fx="troquel-pliegue"]::before{
  content:"";position:absolute;left:0;right:0;top:-1px;height:1.5px;z-index:2;
  pointer-events:none;
  background:repeating-linear-gradient(90deg,
    var(--blue) 0 7px, transparent 7px 14px);
  transform:scaleX(var(--fx-pliegue,0));transform-origin:left center;
}
.fx .sec--ink [data-fx="troquel-pliegue"]::before{
  background:repeating-linear-gradient(90deg,
    var(--sky) 0 7px, transparent 7px 14px);
}

/* ── cerrar ───────────────────────────────────────────────────────────────
   El set-piece. NO se dobla la foto: doblar una foto se lee como una foto
   doblada, no como una caja. Lo que rota es el PLANO, con perspectiva, desde
   la posicion en que una hoja yace sobre la mesa hasta quedar de frente: el
   pliego plano convertido en la caja terminada. Solo transform y opacidad,
   asi que el layout no se entera (CLS 0). */
.fx [data-fx="troquel-cierre"] .fzig__media{perspective:1600px;perspective-origin:50% 100%}
.fx [data-fx="troquel-cierre"] img{
  transform-origin:50% 100%;
  /* El giro y la escala salen de los tokens: la amplitud del set-piece es una decision
     de la firma, no un numero perdido en una declaracion. La perspectiva vive en
     .fzig__media (el padre DIRECTO) porque perspective no atraviesa un elemento
     transform-style:flat, y ahi estaba el defecto: el pliego se aplastaba en vertical
     sin escorzo — una foto estirandose, no un plano girando. */
  transform:rotateX(calc((1 - var(--fx-cierre,1)) * var(--fx-giro)))
            scale(calc(1 - var(--fx-escala) + var(--fx-cierre,1) * var(--fx-escala)));
  will-change:transform;
}
/* Amortiguacion del scrub. Una rueda de raton avanza a saltos de ~100px: con el giro
   repartido en 405px de recorrido eso son 4 escalones de ~6.5 grados, y un pliego que
   se dobla en cuatro tirones no se lee como un pliego. La transicion no cambia el
   valor, solo persigue el que escribe la firma. Cada duracion va con el tamano de lo
   que se mueve: la superficie del pliego con --fx-dur-2, la linea de 1.5px del hendido
   con --fx-dur-1 (una linea que se arrastra 240ms se siente pegajosa).
   .fx-suave lo habilita recien en el frame siguiente al primer valor escrito: sin eso,
   el fallback var(--fx-cierre,1) del estado sin JS haria que la caja se DESDOBLARA
   sola al cargar, que es el gesto al reves. */
.fx [data-fx="troquel-cierre"].fx-suave img{
  transition:transform var(--fx-dur-2) var(--fx-ease-out);
}
.fx [data-fx="troquel-cierre"].fx-suave .fzig__media::before,
.fx [data-fx="troquel-cierre"].fx-suave .fzig__media::after,
.fx [data-fx="troquel-pliegue"].fx-suave::before{
  transition:transform var(--fx-dur-1) var(--fx-ease-out);
}
/* Las dos hendiduras del pliego, que se marcan mientras se levanta. */
.fx [data-fx="troquel-cierre"] .fzig__media{position:relative}
.fx [data-fx="troquel-cierre"] .fzig__media::before,
.fx [data-fx="troquel-cierre"] .fzig__media::after{
  content:"";position:absolute;left:0;right:0;height:1.5px;z-index:2;
  pointer-events:none;
  background:repeating-linear-gradient(90deg,
    var(--blue) 0 7px, transparent 7px 14px);
  transform:scaleX(var(--fx-cierre,1));transform-origin:left center;
}
.fx [data-fx="troquel-cierre"] .fzig__media::before{top:33.3%}
.fx [data-fx="troquel-cierre"] .fzig__media::after{top:66.6%}

/* ── movil ────────────────────────────────────────────────────────────────
   Bajo 820px el set-piece NO se scrubbea: doblar un plano en 3D con el dedo
   compite con el propio scroll y en gama baja tira frames. Estado final fijo. */
@media(max-width:820px){
  /* La partitura promete el parallax APAGADO bajo 820px y no estaba implementado: el
     driver lo desplaza en todos los anchos, y a 360 corria la foto de QC hasta que el
     texto de los pasos quedaba encima de ella (1.03:1 medido por el gate de la base).
     El driver es compartido y no se toca, asi que se neutraliza su transform inline
     desde la hoja del sitio. Es el unico !important de la capa y esta es su razon. */
  .fx [data-fx="parallax"]{transform:none !important}
  .fx [data-fx="troquel-cierre"] .fzig__media{perspective:none}
  /* sin scrub no hay nada que componer: soltar la capa promovida en vez de dejarla viva */
  .fx [data-fx="troquel-cierre"] img{transform:none;will-change:auto}
  .fx [data-fx="troquel-cierre"] .fzig__media::before,
  .fx [data-fx="troquel-cierre"] .fzig__media::after{transform:scaleX(1)}
  /* La partitura (e) promete que el hendido bajo 820px se corre "una vez al entrar".
     Lo que habia era un scaleX(1) fijo: la linea estaba dibujada desde la carga y no
     entraba nunca — intencion declarada y no implementada, que es hallazgo bloqueante
     para el 12. Ahora entra de verdad: el fallback es 1 (sin JS la linea esta, como
     manda la regla de degradacion) y la firma la baja a 0 al arrancar para soltarla
     cuando el rail cruza el pliegue. */
  .fx [data-fx="troquel-pliegue"]::before{
    transform:scaleX(var(--fx-pliegue,1));
    transition:transform var(--fx-dur-3) var(--fx-ease-out-expo);
  }
}

/* ── quien apaga el movimiento no quiere una pagina a medio construir ─────
   Los tres quedan en su estado FINAL dibujado, nunca en el inicial. */
@media (prefers-reduced-motion:reduce){
  .fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::before,
  .fx [data-fx="troquel-marca"]:not([data-fx-modo="propio"]) > *::after{clip-path:inset(0 0 0 0);transition:none}
  .fx [data-fx="troquel-pliegue"]::before{transform:scaleX(1)}
  .fx [data-fx="troquel-cierre"] .fzig__media{perspective:none}
  .fx [data-fx="troquel-cierre"] img{transform:none;will-change:auto}
  .fx [data-fx="troquel-cierre"] .fzig__media::before,
  .fx [data-fx="troquel-cierre"] .fzig__media::after{transform:scaleX(1)}
  /* nada que amortiguar cuando nada se mueve */
  .fx [data-fx="troquel-cierre"].fx-suave img,
  .fx [data-fx="troquel-cierre"].fx-suave .fzig__media::before,
  .fx [data-fx="troquel-cierre"].fx-suave .fzig__media::after,
  .fx [data-fx="troquel-pliegue"].fx-suave::before{transition:none}
}
