/* ============================================================
   VULKRON — prototipo estático. Sistema de diseño SANS, formal.
   Archivo (titulares) · IBM Plex Sans (cuerpo) · IBM Plex Mono (datos).
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap');

:root {
  --canvas:#0a0a0a; --surface:#111111; --raised:#161616;
  --line:#232323; --line-strong:#333333; --field:#6b6b6b;
  --ink:#ededed; --ink-2:#a8a8a8; --ink-3:#8a8a8a;
  --steel-300:#8fb3d4; --steel-400:#7ea3c4; --steel-500:#5a7d9e;
  --steel-600:#4a6a88; --steel-700:#3d5a78;
  /* ---- Rojo de MARCA (decisión del cliente, 31-jul) ----
     Regla de uso —hoy sin aplicación en el render: el rollback dejó el
     chevron en blanco y el acento del claim en steel—: SOLO cuando el
     sujeto es VULKRON la marca o una de sus caras. Los DOMINIOS
     (Fire/Electrical, bento, matrices) van siempre en steel.
     El hex de origen viene del prototipo v1 desplegado
     (deploy-6a28cbbb32cbdd6282ff8222/index.html). El logo v1
     (vulkron.svg) es un raster monocromo enmascarado en blanco: no
     aporta hex propio.
     La regla y la tabla de abajo se conservan para cuando el rojo vuelva
     a hacer falta.
     Contrastes calculados (WCAG AA 4.5:1, texto normal):
       #e53935 sobre canvas 4.68 ✓ · surface 4.47 ✗ · raised 4.28 ✗ ·
               banda steel #111b27 4.11 ✗  → NO sirve como color de texto.
       #e84e4a sobre canvas 5.30 · surface 5.05 · raised 4.84 ·
               banda steel 4.64 · glow 4.64 → ✓ en todas. Es el de texto.
       #c8201c con #fff encima 5.71 ✓ (steel-600 da 5.66: mismo escalón).
       #a81a17 con #fff encima 7.43 ✓ (hover; steel-700 da 7.16).
     #e84e4a (el hex de texto) queda deliberadamente más saturado y oscuro
     que --crit (#f87171) para que el rojo de marca no se lea como estado
     crítico. */
  --ok:#4ade80; --warn:#fbbf24; --crit:#f87171;
  --empau:#f97316;
  --display:'Archivo',system-ui,sans-serif;
  --sans:'IBM Plex Sans',system-ui,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --ease:cubic-bezier(.25,1,.5,1);
  --maxw:75rem;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  background:var(--canvas); color:var(--ink);
  font-family:var(--sans); font-size:16px; line-height:1.6;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  overflow-x:clip;
}
img{max-width:100%; display:block}
a{color:inherit; text-decoration:none}
::selection{background:var(--steel-600); color:#fff}
:focus-visible{outline:2px solid var(--steel-400); outline-offset:2px}

.container{width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:clamp(1.25rem,4vw,2.5rem)}
.rule-v{display:inline-block; inline-size:1px; block-size:.9em; margin-inline:.65rem; background:var(--line-strong); vertical-align:-.05em}
.mono{font-family:var(--mono); font-variant-numeric:tabular-nums}
.steel{color:var(--steel-400)}
.muted{color:var(--ink-2)}
.faint{color:var(--ink-3)}

/* ---- Tipografía ---- */
h1,h2,h3{font-family:var(--display); font-weight:700; letter-spacing:-.02em; line-height:1.04}
.h-hero{font-size:clamp(3rem,9vw,7rem); font-weight:700; letter-spacing:-.03em; line-height:.98}
.h-sec{font-size:clamp(1.9rem,4vw,3rem)}
.h-sub{font-size:clamp(1.35rem,2.4vw,1.9rem); letter-spacing:-.015em}
/* Sub-encabezado de tarjeta/tier: fluido pero menor que un h2 de sección.
   Reemplaza los font-size inline que rompían el escalado responsive. */
.h-sub--sm{font-size:clamp(1.2rem,1.8vw,1.5rem)}
.lede{font-size:clamp(1.0625rem,1.4vw,1.1875rem); color:var(--ink-2); line-height:1.6; max-width:40rem}

/* ---- Barra de estado ---- */
.statusbar{position:relative; z-index:200; background:color-mix(in srgb,var(--surface) 80%,transparent); backdrop-filter:blur(6px); border-bottom:1px solid transparent}
.statusbar .container{display:flex; align-items:center; gap:1.25rem; height:2.25rem; font-size:12px; color:var(--ink-3)}
.statusbar .led{inline-size:6px; block-size:6px; border-radius:50%; background:var(--ok); flex:none}
.statusbar .sb-std{display:none}
.statusbar .sb-phone{margin-left:auto; display:flex; align-items:center; white-space:nowrap}
.statusbar .sb-phone:hover{color:var(--steel-300)}
@media(min-width:640px){.statusbar .sb-std{display:block}}
/* En móvil el número basta: ocultar el rótulo evita que la barra desborde */
@media(max-width:600px){.sb-phone span:first-child,.sb-phone .rule-v{display:none}}
/* El selector de idioma ya NO vive aquí: se monta en el nav (ver
   «Selector de idioma» en la sección Nav, más abajo). */
@media(max-width:600px){.statusbar .container{gap:.75rem} .statusbar .faint{display:none}}

/* ---- Nav ---- */
.nav{position:sticky; top:0; z-index:100; background:color-mix(in srgb,var(--canvas) 88%,transparent); backdrop-filter:blur(14px); border-bottom:1px solid var(--line)}
.nav .container{display:flex; align-items:center; justify-content:space-between; gap:1rem; height:4rem}
.brand{display:flex; align-items:center; gap:.65rem; font-weight:800; letter-spacing:.16em; font-size:.9rem; color:#fff}
/* El chevron se dibuja con stroke="currentColor" y hereda el blanco de
   .brand: chevron y wordmark van los dos en blanco. La regla del rojo de
   marca —hoy sin aplicación en el render— vive en :root, al inicio.
   📼 Registro del rojo v1: como gráfico el umbral era 3:1 y #e53935 sobre
   canvas daba 4.68:1. */
.brand svg{inline-size:1.05rem; block-size:auto}
.nav-links{display:none; gap:.25rem; align-items:center}
.nav-links a{padding:.7rem .85rem; font-size:.85rem; font-weight:500; color:var(--ink-2); border-radius:3px}
.nav-links a:hover{color:#fff}
.nav-links a.active{color:#fff}
@media(min-width:1000px){.nav-links{display:flex}}

/* ---- Nav móvil: botón hamburguesa + panel desplegable ----
   Ambos viven bajo el breakpoint del nav (<1000px). En ≥1000px el
   botón y el panel se ocultan por completo → el nav de escritorio
   queda intacto (cero cambio visual). El texto del panel es idéntico
   al del nav, así que i18n lo traduce con las mismas claves. */
.nav-toggle{display:inline-flex; align-items:center; justify-content:center; flex:none;
  inline-size:2.75rem; block-size:2.75rem; margin-inline-end:-.5rem; padding:0;
  color:var(--ink); background:transparent; border:1px solid transparent; border-radius:4px;
  cursor:pointer; transition:color .15s,border-color .15s,background .15s}
.nav-toggle:hover{color:#fff; border-color:var(--line-strong); background:rgba(255,255,255,.04)}
.nav-toggle svg{inline-size:1.4rem; block-size:1.4rem}
.nav-toggle .ico-close{display:none}
.nav-toggle[aria-expanded="true"] .ico-open{display:none}
.nav-toggle[aria-expanded="true"] .ico-close{display:block}
@media(min-width:1000px){.nav-toggle{display:none}}
/* En móvil el CTA del bar se pliega dentro del panel: el bar queda
   limpio (marca + hamburguesa) y se evita duplicar el CTA.
   .nav .nav-cta: especificidad mayor que .btn (definido más abajo). */
.nav .nav-cta{display:none}
@media(min-width:1000px){.nav .nav-cta{display:inline-flex}}

/* ---- Selector de idioma: caja desplegable (la inyecta i18n.js) ----
   Vive DENTRO de `.nav .container`, insertado justo antes de `.nav-cta`.
   Un solo elemento cubre los dos breakpoints:
   · ≥1000px → globo + nombre del idioma actual + caret, a la izquierda
     del CTA.
   · <1000px → CTA y conmutador se pliegan al panel, así que el vecino
     visible es la hamburguesa: aquí el selector se reduce a SOLO EL GLOBO
     —mismo registro fantasma y mismo tap target (2.75rem) que
     `.nav-toggle`, para que se lean como par— y `margin-inline-start:auto`
     lo empuja junto a ella. Nunca se pliega dentro del panel.
   Base = compacta (mobile-first); ≥1000px añade la caja con el nombre.
   RTL: el menú se ancla con `inset-inline-end` → se espeja solo, sin
   override físico (antes hacía falta `[dir="rtl"] .lang-menu`). */
.lang-switch{position:relative; flex:none; font-family:var(--sans); margin-inline-start:auto}
/* `font-family` explícita: <button> NO hereda la tipografía del documento;
   sin esto el disparador caía en Arial (lo hacía ya en la statusbar). */
.lang-toggle{display:inline-flex; align-items:center; justify-content:center; flex:none;
  inline-size:2.75rem; block-size:2.75rem; padding:0; gap:0;
  font-family:var(--sans); font-size:12px; font-weight:600; letter-spacing:.02em;
  color:var(--ink); background:transparent; border:1px solid transparent; border-radius:4px;
  cursor:pointer; line-height:1.4;
  transition:color .15s,border-color .15s,background .15s}
.lang-toggle:hover{color:#fff; border-color:var(--line-strong); background:rgba(255,255,255,.04)}
.lang-switch.is-open .lang-toggle{color:#fff; border-color:var(--steel-500); background:rgba(255,255,255,.06)}
.lang-current,.lang-caret{display:none}
.lang-globe{inline-size:1.25rem; block-size:1.25rem; flex:none}
.lang-caret{inline-size:9px; block-size:6px; flex:none; transition:transform .18s var(--ease)}
.lang-switch.is-open .lang-caret{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){.lang-caret{transition:none}}
.lang-menu{position:absolute; inset-block-start:calc(100% + 6px); inset-inline-end:0;
  margin:0; padding:4px; list-style:none; min-inline-size:150px;
  background:var(--raised); border:1px solid var(--line-strong); border-radius:7px;
  box-shadow:0 12px 32px rgba(0,0,0,.5); z-index:210}
.lang-opt{padding:7px 10px; font-size:13px; color:var(--ink-2); border-radius:4px; cursor:pointer; white-space:nowrap; transition:color .12s,background .12s}
.lang-opt:hover{color:#fff; background:rgba(255,255,255,.06)}
.lang-opt.is-active{color:#fff; background:var(--steel-700)}
.lang-opt[lang="ar"]{text-align:right; font-size:14px}

/* Escritorio (≥1000px): caja con globo + nombre del idioma + caret,
   a la izquierda del CTA. */
@media(min-width:1000px){
  .lang-switch{margin-inline-start:0}
  .lang-current,.lang-caret{display:block}
  .lang-toggle{inline-size:auto; block-size:auto; padding:3px 8px; gap:.4rem;
    color:var(--ink-3); background:rgba(255,255,255,.04);
    border-color:var(--line); border-radius:5px}
  .lang-toggle:hover{color:var(--ink); background:rgba(255,255,255,.04)}
  .lang-globe{inline-size:13px; block-size:13px; opacity:.85}
}

/* Panel: cae a ancho completo bajo la barra (absoluto contra .nav sticky).
   left/right:0 es simétrico → correcto en LTR y RTL sin overrides. */
.nav-panel{position:absolute; top:100%; left:0; right:0; z-index:50;
  display:flex; flex-direction:column; gap:0;
  padding:.5rem clamp(1.25rem,4vw,2.5rem) 1.35rem;
  background:color-mix(in srgb,var(--canvas) 96%,transparent); backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line); box-shadow:0 24px 44px rgba(0,0,0,.5)}
.nav-panel[hidden]{display:none}
.nav-panel a:not(.btn){padding:.9rem .25rem; font-size:1rem; font-weight:500;
  color:var(--ink-2); border-top:1px solid var(--line)}
.nav-panel a:not(.btn):first-child{border-top:none}
.nav-panel a:not(.btn):hover,.nav-panel a:not(.btn).active{color:#fff}
.nav-panel .btn{margin-top:1rem; width:100%}
/* Aparición: SÓLO desliza (opacity siempre 1) → nunca oculta texto. */
@keyframes nav-panel-in{from{transform:translateY(-.5rem)} to{transform:translateY(0)}}
.nav-panel:not([hidden]){animation:nav-panel-in .18s var(--ease)}
@media(prefers-reduced-motion:reduce){.nav-panel:not([hidden]){animation:none}}
@media(min-width:1000px){.nav-panel{display:none!important}}

/* ---- Botones ---- */
.btn{position:relative; display:inline-flex; align-items:center; justify-content:center; gap:.5rem; font-family:var(--sans); font-weight:600; font-size:.9rem; padding:.8rem 1.4rem; border-radius:3px; border:1px solid transparent; cursor:pointer; white-space:nowrap; transition:color .2s,border-color .2s,background .2s}
.btn-sm{padding:.7rem 1.15rem; font-size:.82rem}
.btn-primary{background:var(--steel-600); color:#fff; overflow:hidden; isolation:isolate}
.btn-primary::before{content:""; position:absolute; inset:0; z-index:-1; background:var(--steel-700); transform:scaleX(0); transform-origin:left; transition:transform .2s var(--ease)}
.btn-primary:hover::before,.btn-primary:focus-visible::before{transform:scaleX(1)}
.btn-outline{border-color:var(--line-strong); color:var(--ink)}
.btn-outline:hover{border-color:var(--ink-3); background:rgba(255,255,255,.05)}
.btn-link{position:relative; color:var(--ink); font-weight:600; font-size:.9rem; padding:.8rem .25rem}
.btn-link::after{content:""; position:absolute; left:.25rem; right:.25rem; bottom:.55rem; height:1px; background:currentColor; opacity:.5; transform:scaleX(0); transform-origin:left; transition:transform .28s var(--ease)}
.btn-link:hover::after{transform:scaleX(1)}
.btn-link:hover{color:#fff}

/* ---- Hero ---- */
.hero{position:relative; min-height:88svh; display:flex; flex-direction:column; overflow:hidden}
.hero-img{position:absolute; inset:0; z-index:-2; width:100%; height:100%; object-fit:cover; object-position:left}
.hero-scrim{position:absolute; inset:0; z-index:-1; background:linear-gradient(180deg,rgba(10,10,10,.5) 0%,rgba(10,10,10,0) 26%,rgba(10,10,10,0) 42%,rgba(10,10,10,.9) 72%,rgba(10,10,10,.98) 100%)}
.hero .container{margin-top:auto; padding-block:2rem 5rem}
/* Legibilidad garantizada del texto sobre la foto. */
.hero-desc,.hero h1,.hero .lede{text-shadow:0 1px 14px rgba(10,10,10,.55)}
.hero-desc{display:flex; flex-wrap:wrap; align-items:center; font-size:.9rem; font-weight:500; color:var(--ink)}
.hero h1{margin-top:1.25rem; max-width:16ch; text-wrap:balance}
.hero h1 .accent{display:block; color:var(--steel-400)}
.hero .lede{margin-top:1.5rem; color:var(--ink)}
.hero-cta{margin-top:2.25rem; display:flex; flex-wrap:wrap; gap:.75rem; align-items:center}

/* ---- Secciones ---- */
.section{padding-block:clamp(4rem,9vw,7rem)}
/* Ritmo vertical reducido reutilizable (mismo coeficiente 9vw que .section) */
.section--compact{padding-block:clamp(3.5rem,9vw,6rem)}
.section--surface{background:var(--surface)}
.section--line{border-top:1px solid var(--line)}
.section-head{max-width:44rem}
.section-head .lede{margin-top:1.25rem}
.grid{display:grid; gap:1.5rem}
@media(min-width:768px){
  .cols-2{grid-template-columns:repeat(2,1fr)}
  .cols-3{grid-template-columns:repeat(3,1fr)}
  .split{grid-template-columns:1fr 1fr; gap:clamp(2rem,5vw,4rem); align-items:center}
  .split-40{grid-template-columns:2fr 3fr; gap:clamp(2rem,5vw,4rem); align-items:start}
}

/* ---- Columnas editoriales (outcomes) ---- */
.edcols{display:grid; gap:0}
@media(min-width:768px){.edcols{grid-template-columns:repeat(3,1fr)}}
.edcol{padding:1.75rem 0}
@media(min-width:768px){
  .edcol{padding:.25rem 2rem}
  .edcol + .edcol{border-left:1px solid var(--line)}
  .edcol:first-child{padding-left:0}
}
.edcol h3{font-size:1.35rem; margin-bottom:.6rem}
.edcol + .edcol{border-top:1px solid var(--line)}
@media(min-width:768px){.edcol + .edcol{border-top:none}}

/* ---- Spec rows (ledger de dos columnas) ---- */
.specs{margin-top:2rem}
.spec-row{display:grid; grid-template-columns:1fr; gap:.35rem 1.5rem; border-top:1px solid var(--line); padding-block:1rem}
.spec-row:last-child{border-bottom:1px solid var(--line)}
@media(min-width:640px){.spec-row{grid-template-columns:14rem 1fr; align-items:baseline}}
.spec-row .k{font-weight:600; color:var(--ink)}
.spec-row .v{color:var(--ink-2)}
.spec-list .spec-row{grid-template-columns:1fr}

/* ---- Bitácora de fallas (problema) ---- */
.ledger{border:1px solid var(--line); background:var(--surface)}
.ledger-head{display:flex; align-items:center; gap:.6rem; border-bottom:1px solid var(--line); padding:.75rem 1.25rem; font-size:.8rem; color:var(--ink-3)}
.ledger-head .led{inline-size:7px; block-size:7px; border-radius:50%; background:var(--crit)}
.ledger-row{border-top:1px solid var(--line); border-left:2px solid var(--line); padding:1.1rem 1.25rem}
.ledger-row:first-child{border-top:none}
.ledger-row.crit{border-left-color:var(--crit)}
.ledger-row.warn{border-left-color:var(--warn)}
.ledger-row .top{display:flex; align-items:center; gap:.9rem}
.ledger-row .code{font-family:var(--mono); font-size:.75rem; color:var(--ink-3); flex:none}
.ledger-row .title{flex:1; font-weight:600; color:var(--ink); font-size:.98rem}
.ledger-row .state{font-size:.78rem; font-weight:600; flex:none}
.ledger-row.crit .state{color:var(--crit)}
.ledger-row.warn .state{color:var(--warn)}
.ledger-row .body{margin-top:.4rem; color:var(--ink-2); font-size:.9rem; padding-left:calc(.75rem + 2.5rem)}

/* ---- Cifras / gauges ---- */
.gauges{display:grid; grid-template-columns:1fr 1fr; border-top:1px solid var(--line-strong); border-bottom:1px solid var(--line-strong)}
@media(min-width:768px){.gauges{grid-template-columns:repeat(3,1fr)}}
.gauge{padding:1.75rem; position:relative}
.gauge + .gauge{border-top:1px solid var(--line)}
@media(min-width:768px){
  .gauge{border-left:1px solid var(--line)}
  .gauge:first-child{border-left:none}
  .gauge + .gauge{border-top:none}
}
.gauge .num{font-family:var(--mono); font-weight:600; font-size:clamp(2.5rem,4.5vw,3.75rem); line-height:.9; letter-spacing:-.02em; font-variant-numeric:tabular-nums}
.gauge .lbl{margin-top:1rem; font-weight:600; font-size:.85rem}
.gauge .note{margin-top:.35rem; font-size:.8rem; color:var(--ink-3)}
/* variante de cuatro cifras: 2×2 hasta escritorio ancho, 4 en línea después */
.gauges--4 .gauge .num{font-size:clamp(1.9rem,3.2vw,2.6rem)}
@media(max-width:767.98px){
  .gauges--4 .gauge:nth-child(2){border-top:none}
  .gauges--4 .gauge:nth-child(2n){border-left:1px solid var(--line)}
}
@media(min-width:768px){.gauges--4{grid-template-columns:repeat(2,1fr)}}
@media(min-width:768px) and (max-width:1079.98px){
  .gauges--4 .gauge:nth-child(3),
  .gauges--4 .gauge:nth-child(4){border-top:1px solid var(--line)}
  .gauges--4 .gauge:nth-child(3){border-left:none}
}
@media(min-width:1080px){.gauges--4{grid-template-columns:repeat(4,1fr)}}

/* ---- Matriz de rutinas ---- */
.matrix-wrap{overflow-x:auto; margin-top:2rem; border:1px solid var(--line)}
table.matrix{width:100%; border-collapse:collapse; min-width:46rem}
table.matrix th,table.matrix td{text-align:left; padding:.9rem 1rem; border-bottom:1px solid var(--line); border-right:1px solid var(--line); font-size:.85rem; vertical-align:top}
table.matrix thead th{background:var(--raised); font-weight:600; color:var(--ink-2); font-size:.78rem}
table.matrix tbody tr:hover{background:var(--raised)}
table.matrix .fam{font-weight:600; color:var(--ink); white-space:nowrap}
table.matrix .fam small{display:block; font-family:var(--mono); font-size:.7rem; color:var(--ink-3); font-weight:400; margin-top:.15rem}
table.matrix td.on{color:var(--ink); font-weight:500}
table.matrix td.off{color:var(--ink-3); text-align:center}

/* ---- Expediente (banda de papel) ---- */
.paper{background:var(--ink); color:#1c1c1c}
.paper .faint{color:#55555a}
.paper .doc{background:#fff; border:1px solid #c4c4c4; margin-top:2rem}
.paper .doc-head{display:flex; flex-wrap:wrap; gap:.75rem 1.5rem; justify-content:space-between; padding:1.1rem 1.25rem; border-bottom:1px solid #c4c4c4}
.paper .doc-head .t{font-weight:700; color:#0a0a0a}
.paper .doc-head .m{font-family:var(--mono); font-size:.8rem; color:#55555a}
/* La tabla no cabe en pantallas angostas: scroll horizontal DENTRO del
   documento (mismo patrón que `.matrix-wrap`), nunca en la página. */
.paper .exp-wrap{overflow-x:auto}
.paper table.exp{width:100%; border-collapse:collapse; min-width:30rem}
.paper table.exp th,.paper table.exp td{text-align:left; padding:.8rem 1.25rem; border-bottom:1px solid #dcdcdc; font-size:.85rem}
.paper table.exp th{font-size:.75rem; color:#55555a; font-weight:600}
.paper table.exp .mono{color:#0a0a0a}
.paper .st{display:inline-block; padding:.15rem .5rem; border-radius:2px; font-size:.75rem; font-weight:600}
.paper .st.ok{background:#bbf7d0; color:#14532d}
.paper .st.warn{background:#fde68a; color:#713f12}

/* ---- Tarjetas / teasers ---- */
.card{display:block; border:1px solid var(--line); background:var(--surface); padding:1.75rem; transition:border-color .2s,background .2s}
.card:hover{border-color:var(--steel-600); background:var(--raised)}
.card h3{font-size:1.25rem; margin-bottom:.5rem}
.card p{color:var(--ink-2); font-size:.92rem}
.card .go{margin-top:1.1rem; font-size:.85rem; font-weight:600; color:var(--steel-400)}

/* ---- Folios (secuencias) ---- */
.steps{display:grid; gap:0; margin-top:1rem}
.step{display:grid; grid-template-columns:auto 1fr; gap:1.25rem; border-top:1px solid var(--line); padding-block:1.5rem}
.step .folio{font-family:var(--display); font-weight:300; font-size:2.5rem; line-height:1; color:var(--steel-400); font-variant-numeric:lining-nums}
.step h3{font-size:1.1rem; margin-bottom:.35rem}
.step p{color:var(--ink-2); font-size:.92rem}
.step .mark{display:flex; align-items:center; flex-wrap:wrap; font-size:.8rem; color:var(--ink-3); margin-bottom:.4rem}
.step .pts{list-style:none; margin-top:.85rem; padding:0}
.step .pts li{border-top:1px solid var(--line); padding:.45rem 0; font-size:.85rem; color:var(--ink-2)}

/* ---- Cadena (contratista) ---- */
.chain{display:grid; gap:1rem; margin-top:2rem}
@media(min-width:768px){.chain{grid-template-columns:repeat(3,1fr); gap:0}}
.chain-node{border:1px solid var(--line); background:var(--surface); padding:1.25rem; position:relative}
@media(min-width:768px){.chain-node + .chain-node{border-left:none}}
.chain-node .n{font-family:var(--display); font-weight:300; font-size:1.7rem; line-height:1; color:var(--steel-400)}
.chain-node .l{font-weight:600; margin-top:.35rem}
.chain-node .d{color:var(--ink-3); font-size:.85rem; margin-top:.15rem}

/* ---- Formulario ---- */
.form{border:1px solid var(--line); background:var(--surface); padding:clamp(1.5rem,3vw,2.25rem)}
.field{margin-bottom:1.1rem}
.field label{display:block; font-size:.8rem; color:var(--ink-2); margin-bottom:.4rem}
.field input,.field select,.field textarea{width:100%; background:var(--raised); border:1px solid var(--field); color:var(--ink); padding:.7rem .85rem; font-family:var(--sans); font-size:.92rem; border-radius:2px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none; border-color:var(--steel-400)}

/* ---- Banda CTA ---- */
.cta-band{border-top:1px solid var(--line)}
.cta-band .container{padding-block:clamp(3.5rem,7vw,5.5rem); text-align:center}
.cta-band .h-sec{max-width:24ch; margin-inline:auto}
.cta-band .btns{margin-top:2rem; display:flex; gap:.75rem; justify-content:center; flex-wrap:wrap}

/* ---- Footer ---- */
.footer{border-top:1px solid var(--line); padding-block:3.5rem}
.footer-grid{display:grid; gap:2.5rem; grid-template-columns:1fr}
@media(min-width:768px){.footer-grid{grid-template-columns:1.4fr 2.6fr}}
.footer-cols{display:grid; grid-template-columns:repeat(2,1fr); gap:2rem}
@media(min-width:640px){.footer-cols{grid-template-columns:repeat(4,1fr)}}
.footer h4{font-size:.82rem; font-weight:600; color:var(--ink); margin-bottom:1rem}
.footer ul{list-style:none}
.footer li{margin-bottom:.6rem}
.footer li a{color:var(--ink-2); font-size:.88rem}
.footer li a:hover{color:var(--steel-400)}
.footer .blurb{color:var(--ink-3); font-size:.9rem; margin-top:1rem; max-width:22rem}
.footer .empau{display:flex; align-items:center; gap:.6rem; margin-top:1.75rem; font-size:.82rem; color:var(--ink-3)}
.footer .empau img{width:1.4rem; height:1.4rem}
/* Crédito del desarrollador: discreto (el naranja Empau no es pilar de marca). */
.footer .empau strong{color:var(--ink-2); font-weight:600}
/* El crédito enlaza a grupoempau.com (29-jul). Hereda el gris: el enlace NO puede
   reintroducir color de marca ajeno — hover al steel del sitio, como el resto del footer. */
.footer .empau a{color:inherit; text-decoration:none}
.footer .empau a:hover strong{color:var(--steel-400)}
.footer-legal{display:flex; flex-wrap:wrap; gap:1.25rem; align-items:center; justify-content:space-between; margin-top:2.5rem; padding-top:1.75rem; border-top:1px solid var(--line); font-size:.8rem; color:var(--ink-3)}
.footer-legal a:hover{color:var(--steel-400)}

/* ---- Reveal controlado: SÓLO desliza (opacity siempre 1) ----
   Si el JS falla o se congela, el texto queda visible (a lo sumo 20px
   desplazado). Nunca hay "palabras que no se ven". */
.reveal{transform:none; transition:transform .6s var(--ease)}
.js .reveal.pending{transform:translateY(20px)}
@media(prefers-reduced-motion:reduce){.reveal{transition:none; transform:none}}

.eyrow{display:flex; align-items:center; gap:.5rem; font-size:.85rem; color:var(--ink-2)}

/* ============================================================
   v3 — INFRAESTRUCTURA CRÍTICA: dominios, costo, capacidades, madurez
   ============================================================ */
/* Declaración de misión */
.mission{font-family:var(--display); font-weight:600; font-size:clamp(1.6rem,3.4vw,2.9rem); line-height:1.18; letter-spacing:-.02em; text-wrap:balance}
.mission .accent{color:var(--steel-400)}
.mission-src{margin-top:1.5rem; font-size:.85rem; color:var(--ink-3)}

/* Dos dominios (Inicio) */
.domains{display:grid; gap:1.5rem; margin-top:2.5rem}
@media(min-width:820px){.domains{grid-template-columns:1fr 1fr}}
.domain{position:relative; overflow:hidden; border:1px solid var(--line); background:var(--surface); padding:clamp(1.75rem,3vw,2.5rem); min-height:22rem; display:flex; flex-direction:column; transition:border-color .2s,background .2s}
.domain:hover{border-color:var(--steel-600); background:var(--raised)}
.domain .idx{font-family:var(--mono); font-size:.75rem; color:var(--steel-400); letter-spacing:.04em}
.domain h3{font-family:var(--display); font-size:clamp(1.6rem,2.6vw,2.2rem); font-weight:700; letter-spacing:-.02em; margin-top:.75rem}
.domain .sub{color:var(--ink-3); font-size:.85rem; margin-top:.35rem}
.domain p{color:var(--ink-2); margin-top:1rem; font-size:.95rem; max-width:38ch}
.domain .tags{margin-top:auto; padding-top:1.5rem; display:flex; flex-wrap:wrap; gap:.45rem .9rem; font-size:.8rem; color:var(--ink-3)}
.domain .tags span{position:relative}
.domain .tags span:not(:last-child)::after{content:""; position:absolute; right:-.5rem; top:.35em; bottom:.2em; width:1px; background:var(--line-strong)}
.domain .go{margin-top:1.35rem; font-weight:600; color:var(--steel-400); font-size:.9rem}

/* Costo de la incertidumbre */
.cost-list{margin-top:2rem}
.cost-row{display:grid; grid-template-columns:1fr; gap:.3rem 2rem; border-top:1px solid var(--line); padding:1.1rem 0}
.cost-row:last-child{border-bottom:1px solid var(--line)}
@media(min-width:680px){.cost-row{grid-template-columns:1fr auto; align-items:baseline}}
.cost-row .scn{font-weight:600; color:var(--ink); font-size:.98rem}
.cost-row .csq{color:var(--ink-3); font-size:.88rem}
.cost-row .csq b{color:var(--crit); font-weight:600}

/* ---- Fragmentación: cinco formatos heterogéneos → un mismo criterio ----
   Diagrama sobrio en SVG. Entrada gris (ink-3 / line-strong) = las cinco
   entregas que NO suman; salida steel = el criterio único que impone VULKRON.
   La dirección es GEOMETRÍA (líneas que convergen a un nodo y salen a filas
   uniformes), nunca glifos de flecha.
   Layout por grid: dos leyendas (.ff-cap) más el SVG. En desktop/tablet la
   variante ANCHA (.ff-svg--wide, 960×300) fluye izq→der con las leyendas en
   los extremos de la fila superior. En móvil (≤600px) se muestra la variante
   ALTA (.ff-svg--tall, 360×600), que reflowa el mismo relato arriba→abajo, con
   "Cinco formatos" sobre los glifos y "Un criterio" bajo la pila uniforme.
   RTL: [dir="rtl"] .ff-svg espeja el diagrama; las leyendas (grid + justify-self
   lógico) se reubican solas. Sin JS. */
.frag-figure{margin:clamp(2.5rem,5vw,3.5rem) 0 0; padding:0;
  display:grid; grid-template-columns:1fr 1fr; gap:.9rem 1rem}
.ff-cap{font-size:.8rem; font-weight:600; color:var(--ink-3); letter-spacing:.01em}
.ff-cap--in{grid-column:1; grid-row:1; justify-self:start}
.ff-cap--out{grid-column:2; grid-row:1; justify-self:end; color:var(--steel-400)}
.ff-svg{display:block; width:100%; height:auto; margin-inline:auto}
.ff-svg--wide{grid-column:1/-1; grid-row:2; max-width:60rem}
.ff-svg--tall{display:none}
.ff-glyph{fill:none; stroke:var(--ink-3); stroke-width:1.5; stroke-linejoin:round; stroke-linecap:round}
.ff-line{fill:none; stroke:var(--line-strong); stroke-width:1}
.ff-node{fill:var(--canvas); stroke:var(--steel-400); stroke-width:1.5}
.ff-out{fill:none; stroke:var(--steel-400); stroke-width:1.4}
.ff-row{fill:none; stroke:var(--steel-400); stroke-width:1.3}
.ff-row-line{stroke:var(--ink-3); stroke-width:1}
.ff-cell{fill:var(--steel-600)}
@media(max-width:600px){
  .frag-figure{grid-template-columns:1fr}
  .ff-svg--wide{display:none}
  .ff-svg--tall{display:block; grid-column:1; grid-row:2; max-width:22rem}
  .ff-cap--in{grid-column:1; grid-row:1; justify-self:start}
  .ff-cap--out{grid-column:1; grid-row:3; justify-self:end}
}
[dir="rtl"] .ff-svg{transform:scaleX(-1)}

/* Capacidades de dominio */
.caps{display:grid; grid-template-columns:repeat(2,1fr); gap:0; border-top:1px solid var(--line); border-left:1px solid var(--line); margin-top:2rem}
@media(min-width:760px){.caps{grid-template-columns:repeat(3,1fr)}}
.cap{padding:1.1rem 1.25rem; border-bottom:1px solid var(--line); border-right:1px solid var(--line)}
.cap .t{font-weight:600; font-size:.95rem}
.cap .d{color:var(--ink-3); font-size:.82rem; margin-top:.3rem; line-height:1.5}
.cap.key{background:var(--raised)}
.cap.key .t{color:var(--steel-300)}

/* Madurez / tiers */
.tiers{display:grid; gap:1.5rem; margin-top:2.5rem}
@media(min-width:768px){.tiers{grid-template-columns:1fr 1fr}}
.tier{border:1px solid var(--line-strong); background:var(--surface); padding:clamp(1.75rem,3vw,2.25rem); display:flex; flex-direction:column}
.tier.feat{border-color:var(--steel-600); background:linear-gradient(180deg,#111b27,#0c1118)}
.tier .lvl{font-size:.8rem; color:var(--steel-400); font-weight:600}
.tier h3{font-family:var(--display); font-size:1.6rem; font-weight:700; margin-top:.4rem; letter-spacing:-.01em}
.tier .inc{color:var(--ink-2); margin-top:.75rem; font-size:.92rem}
.tier ul{list-style:none; margin-top:1.35rem}
.tier li{border-top:1px solid var(--line); padding:.6rem 0; font-size:.88rem; color:var(--ink-2)}
.tier .foot{margin-top:auto; padding-top:1.5rem; font-size:.82rem; color:var(--ink-3)}

/* Eje de SITIOS — Enterprise / Enterprise PRO (enterprise.html#modelo).
   El modelo tiene DOS ejes que no se mezclan: Foundation/Professional
   gradúan DOMINIOS; Enterprise/Enterprise PRO gradúan SITIOS. Los dos
   usan .tiers/.tier — el paralelismo es deliberado, cada eje vive en su
   propia sección con su propio encabezado. Este modificador NO inventa
   superficie: sólo desequilibra la rejilla a favor de Enterprise PRO
   —la categoría que el cliente pidió publicar con énfasis principal
   (1-ago-2026)— y le presta la sombra elevada de .side--primary. */
@media(min-width:768px){.tiers--sitios{grid-template-columns:.88fr 1.12fr}}
.tiers--sitios .tier.feat{box-shadow:0 0 0 1px rgba(90,125,158,.12), 0 18px 50px rgba(0,0,0,.35)}

/* ============================================================
   HERO con mockup de producto (claridad + apoyo visual)
   ============================================================ */
.hero2{position:relative; overflow:hidden; border-bottom:1px solid var(--line)}
.hero2-bg{position:absolute; inset:0; z-index:-2; width:100%; height:100%; object-fit:cover; opacity:.55}
.hero2-scrim{position:absolute; inset:0; z-index:-1; background:
  radial-gradient(95% 105% at 12% 18%, rgba(10,10,10,.18), rgba(10,10,10,.39) 70%),
  linear-gradient(180deg, rgba(10,10,10,.21), rgba(10,10,10,0) 34%, rgba(10,10,10,.36))}
/* La legibilidad la sostiene la SOMBRA DEL TEXTO, no el scrim (decisión 31-jul):
   el fondo se ve, y el texto sigue leyéndose sobre las partes claras del video. */
.hero2-msg h1,.hero2-msg .lede{text-shadow:0 2px 10px rgba(10,10,10,.85), 0 1px 28px rgba(10,10,10,.7)}
.hero2-msg .hero2-for{text-shadow:0 1px 8px rgba(10,10,10,.85)}
.hero2-grid{display:grid; gap:2.5rem; padding-block:clamp(2.5rem,6vw,5rem); align-items:center}
@media(min-width:1000px){.hero2-grid{grid-template-columns:1.02fr 1fr; gap:clamp(2rem,4vw,3.5rem)}}
.hero2-kicker{font-size:.85rem; font-weight:600; color:var(--steel-400)}
.hero2-msg h1{margin-top:1rem; max-width:15ch; text-wrap:balance}
.hero2-msg .lede{margin-top:1.5rem; color:var(--ink)}
.hero2-msg .hero-cta{margin-top:2rem; display:flex; flex-wrap:wrap; gap:.75rem; align-items:center}
.hero2-for{margin-top:2rem; font-size:.88rem; color:var(--ink-3); max-width:40ch; line-height:1.5}

/* Hero statement (sin mockup): contenido CENTRADO sobre el video (decisión del
   cliente 31-jul; antes iba anclado al inicio). Al ser simétrico ya no depende
   de la dirección de lectura: en RTL se espeja solo y el scrim no necesita
   override de degradado. */
.hero2--solo .hero2-grid{grid-template-columns:1fr; justify-items:center; text-align:center; padding-block:clamp(4rem,11vw,8rem)}
/* inline-size:fit-content — la columna del mensaje se ciñe a su hijo más ancho,
   que es el H1. Así el bloque de abajo hereda el ancho REAL del titular en
   cualquier idioma (ver .hero2-split), sin números atados al copy español. */
.hero2--solo .hero2-msg{display:flex; flex-direction:column; align-items:center;
  inline-size:fit-content; max-inline-size:100%}
.hero2--solo .hero2-msg h1{max-width:18ch; margin-inline:auto}
.hero2--solo .hero2-msg .lede{max-width:46rem; margin-inline:auto}
.hero2--solo .hero-cta{justify-content:center}
/* Con el fondo más luminoso, ink-3 se pierde sobre las zonas claras del video:
   sube un escalón (ink-2). Legibilidad por color+sombra, nunca por más scrim. */
.hero2--solo .hero2-for{max-width:52ch; margin-inline:auto; color:var(--ink-2)}
/* Bloque bajo el H1 (decisión 31-jul): el titular sigue centrado a lo ancho y
   DEBAJO la zona se parte a la mitad — el lede al inicio de lectura, los dos
   CTAs en columna vertical del otro lado. Todo en propiedades lógicas: en RTL
   el grid se espeja solo (texto a la derecha, botones a la izquierda). */
/* contain:inline-size — el split NO participa en el cálculo del ancho de
   .hero2-msg (si participara, sus 34rem+botones ensancharían la columna por
   encima del titular); su ancho lo dicta el padre, o sea el H1. */
.hero2-split{inline-size:100%; margin-block-start:1.75rem; margin-inline:auto;
  display:grid; gap:2rem; contain:inline-size}
/* Columna de lectura del split: el lede y, pegada debajo, la línea de audiencia
   (decisión del cliente 31-jul: deja de ir centrada bajo el bloque). min-inline-size:0
   para que la columna del grid pueda encogerse en vez de desbordar. */
.hero2-split .hero2-lede{min-inline-size:0}
.hero2--solo .hero2-msg .hero2-split .lede{margin-top:0; margin-inline:0; text-align:start; max-inline-size:34rem}
/* text-align:start = mismo borde de inicio que el lede; en RTL se espeja solo. */
.hero2--solo .hero2-msg .hero2-lede .hero2-for{margin-block-start:.65rem; margin-inline:0;
  text-align:start; max-inline-size:34rem}
.hero2--solo .hero2-msg .hero2-split .hero-cta{margin-top:0; display:flex; flex-direction:column;
  align-items:stretch; justify-content:flex-start; gap:.75rem; flex-wrap:nowrap}
.hero2-split .hero-cta .btn{width:100%}
/* El borde base (--line-strong, gris opaco) desaparece sobre el video: en el
   hero el contorno se dibuja en blanco translúcido. Misma lógica que el texto:
   la legibilidad la sostiene el propio elemento, no más scrim. */
.hero2-split .hero-cta .btn-outline{border-color:rgba(255,255,255,.5); color:#fff; text-shadow:0 1px 8px rgba(10,10,10,.8)}
.hero2-split .hero-cta .btn-outline:hover{border-color:#fff; background:rgba(255,255,255,.1)}
/* El bloque partido NO puede sobresalir del titular (feedback del cliente
   31-jul: el lede arrancaba más a la izquierda que la G y el bloque era más
   ancho que el H1). Queda acotado al ANCHO VISUAL del H1 por el fit-content de
   .hero2-msg + el contain de arriba: a 1280px el titular «Gobierne el riesgo.»
   mide 943.76px y el bloque mide 943.76px (mismos bordes: 168.12 → 1111.88).
   El max-inline-size es solo la RED DE SEGURIDAD por si un navegador ignora el
   containment: 943.76px con font-size 112px = 8.426 × el tamaño de fuente, y
   como .h-hero es clamp(3rem,9vw,7rem) eso da min(8.426×9vw, 8.426×7rem) =
   min(75.8vw, 59rem), que sigue al titular en toda la curva del clamp. Solo
   desde 900px: por debajo el bloque se apila y usa el ancho disponible. */
@media(min-width:900px){
  .hero2-split{max-inline-size:min(75.8vw,59rem); align-items:start;
    grid-template-columns:minmax(0,1fr) clamp(11rem,20vw,16rem);
    gap:clamp(1.75rem,4vw,4rem)}
}
/* Scrim simétrico: viñeta centrada que sostiene el bloque de texto y deja
   respirar los bordes del video. Alfas a la mitad de la versión anterior. */
.hero2--solo .hero2-scrim{background:
  radial-gradient(115% 95% at 50% 45%, rgba(10,10,10,.42), rgba(10,10,10,.26) 55%, rgba(10,10,10,.08) 85%),
  linear-gradient(180deg, rgba(10,10,10,.22), rgba(10,10,10,.04) 40%, rgba(10,10,10,.37))}

/* Mockup del centro de control */
.mock{background:var(--surface); border:1px solid var(--line-strong); border-radius:8px; overflow:hidden; box-shadow:0 26px 70px rgba(0,0,0,.55)}
.mock-bar{display:flex; align-items:center; justify-content:space-between; padding:.7rem 1rem; border-bottom:1px solid var(--line); background:var(--raised)}
.mock-bar .t{display:flex; align-items:center; gap:.5rem; font-size:.8rem; font-weight:600}
.mock-bar .t svg{width:.85rem; color:var(--ink)}
.mock-bar .live{display:flex; align-items:center; gap:.4rem; font-size:.72rem; color:var(--ok)}
.mock-bar .live i{width:6px; height:6px; border-radius:50%; background:var(--ok); display:inline-block}
.mock-body{padding:1rem}
.mock-kpis{display:grid; grid-template-columns:repeat(2,1fr); gap:1px; background:var(--line); border:1px solid var(--line); margin-bottom:1rem}
@media(min-width:520px){.mock-kpis{grid-template-columns:repeat(4,1fr)}}
.kpi{background:var(--surface); padding:.8rem}
.kpi .l{font-size:.65rem; color:var(--ink-3)}
.kpi .n{font-family:var(--mono); font-weight:600; font-size:1.45rem; line-height:1.1; margin-top:.2rem; font-variant-numeric:tabular-nums}
.kpi .d{font-size:.66rem; color:var(--ink-3); margin-top:.15rem}
.kpi .d.up{color:var(--ok)}
.mock-sech{font-size:.7rem; color:var(--ink-3); margin:.25rem 0 .5rem}
.mock-list .row{display:grid; grid-template-columns:1fr auto; align-items:center; gap:.75rem; padding:.5rem 0; border-top:1px solid var(--line)}
.mock-list .row:first-child{border-top:none}
.mock-list .nm{display:flex; align-items:center; gap:.55rem; font-size:.82rem}
.mock-list .dot{width:7px; height:7px; border-radius:50%; flex:none}
.mock-list .val{display:flex; align-items:center; gap:.55rem}
.mock-list .bar{width:64px; height:4px; background:var(--line); border-radius:2px; overflow:hidden}
.mock-list .bar i{display:block; height:100%}
.mock-list .pct{font-family:var(--mono); font-size:.78rem; width:2.7rem; text-align:right; font-variant-numeric:tabular-nums}

/* Franja de audiencia — marquee de industrias en movimiento */
.audience{border-top:1px solid var(--line); border-bottom:1px solid var(--line); padding-block:clamp(2rem,3.5vw,3rem)}
.audience .lbl{font-size:.8rem; color:var(--ink-3); margin-bottom:1.35rem}
.marquee{position:relative; display:flex; overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.marquee-track{display:flex; flex:none; align-items:center; width:max-content;
  animation:marquee-scroll 34s linear infinite; will-change:transform}
.marquee:hover .marquee-track{animation-play-state:paused}
.marquee-item{display:inline-flex; align-items:center; flex:none;
  font-family:var(--display); font-weight:600; font-size:clamp(1.05rem,1.7vw,1.45rem);
  letter-spacing:-.01em; color:var(--ink-2); white-space:nowrap;
  padding-inline:clamp(1.1rem,2.6vw,2.1rem)}
.marquee-item::before{content:""; inline-size:1px; block-size:1.05em;
  margin-inline-end:clamp(1.1rem,2.6vw,2.1rem); background:var(--line-strong)}
@keyframes marquee-scroll{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){
  .marquee{-webkit-mask-image:none; mask-image:none}
  .marquee-track{animation:none; width:auto; flex-wrap:wrap; justify-content:center; row-gap:.5rem}
  .marquee-track [aria-hidden="true"]{display:none}
}

/* ============================================================
   BANDA CINEMATOGRÁFICA a sangre completa (chapters)
   Imagen full-bleed + texto-cartel al lado oscuro + dato ancla.
   ============================================================ */
.chp{position:relative; min-height:66svh; display:flex; align-items:center; overflow:hidden}
.chp-img{position:absolute; inset:0; z-index:-2; width:100%; height:100%; object-fit:cover; transform:scale(1.12); will-change:transform}
.chp-img.obj-left{object-position:left}
.chp-img.obj-right{object-position:right}
.chp-scrim{position:absolute; inset:0; z-index:-1}
.chp-scrim.obj-left{background:
  linear-gradient(180deg,rgba(10,10,10,.85),rgba(10,10,10,.15) 24%,rgba(10,10,10,.15) 76%,rgba(10,10,10,.9)),
  linear-gradient(80deg,rgba(10,10,10,.78),rgba(10,10,10,.15) 48%,rgba(10,10,10,0) 100%)}
.chp-scrim.obj-right{background:
  linear-gradient(180deg,rgba(10,10,10,.85),rgba(10,10,10,.15) 24%,rgba(10,10,10,.15) 76%,rgba(10,10,10,.9)),
  linear-gradient(280deg,rgba(10,10,10,.78),rgba(10,10,10,.15) 48%,rgba(10,10,10,0) 100%)}
.chp .container{position:relative; z-index:1; padding-block:clamp(3rem,7vw,5rem)}
.chp-text{max-width:38rem}
.chp-text.to-right{margin-left:auto; text-align:right}
.chp-kicker{font-size:.9rem; font-weight:600; color:var(--steel-400); text-shadow:0 1px 12px rgba(10,10,10,.7)}
.chp-statement{margin-top:1rem; font-family:var(--display); font-weight:700; font-size:clamp(1.9rem,4.6vw,3.6rem); line-height:1.05; letter-spacing:-.02em; text-wrap:balance; text-shadow:0 2px 22px rgba(10,10,10,.7)}
.chp-statement .accent{color:var(--steel-400)}
.chp-cap{margin-top:1.75rem; display:flex; flex-wrap:wrap; align-items:center; font-size:.82rem; color:var(--ink-2); text-shadow:0 1px 12px rgba(10,10,10,.8)}
.chp-text.to-right .chp-cap{justify-content:flex-end}
.chp-cap .serial{font-family:var(--mono)}
@media(prefers-reduced-motion:reduce){.chp-img{transform:scale(1.12)!important}}

/* ---- FAQ: acordeón <details> a hairlines, indicador +/− ---- */
.faq details{border-top:1px solid var(--line)}
.faq details:last-child{border-bottom:1px solid var(--line)}
.faq summary{cursor:pointer; list-style:none; display:flex; align-items:center; justify-content:space-between; gap:1.5rem; padding:1.05rem 0; font-weight:600; font-size:.95rem}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+"; font-family:var(--display); font-weight:300; font-size:1.5rem; line-height:1; color:var(--steel-400); flex:none}
.faq details[open] summary::after{content:"−"}
.faq .a{padding:0 0 1.15rem; color:var(--ink-2); font-size:.92rem; line-height:1.6; max-width:62ch}

/* ---- Estado de éxito del formulario ---- */
.form-ok{text-align:center; padding:2.5rem 1rem}
.form-ok h3{font-size:1.3rem; margin-bottom:.6rem}
.form-ok p{color:var(--ink-2); font-size:.92rem}

/* ============================================================
   DINAMISMO DE FONDOS — ritmo de superficies, no negro plano
   ============================================================ */
/* Resplandor steel sutil en la esquina de la sección */
.section--glow{position:relative; overflow:hidden}
.section--glow::before{content:""; position:absolute; inset:-1px; z-index:-1; pointer-events:none;
  background:radial-gradient(56% 62% at 16% 0%, rgba(90,125,158,.15), transparent 70%)}

/* Fondo atmosférico de hero (referente al sistema). La imagen va MUY tenue y el
   scrim oscurece con fuerza el lado del texto → la lectura nunca se compromete. */
.section--hero{position:relative; overflow:hidden}
.sec-bg{position:absolute; inset:0; z-index:-2; width:100%; height:100%; object-fit:cover; object-position:center right; opacity:.2}
.sec-bg-scrim{position:absolute; inset:0; z-index:-1; pointer-events:none; background:
  linear-gradient(90deg, rgba(10,10,10,.95) 0%, rgba(10,10,10,.82) 38%, rgba(10,10,10,.45) 100%),
  linear-gradient(180deg, rgba(10,10,10,.55), rgba(10,10,10,0) 30%, rgba(10,10,10,.65) 100%),
  radial-gradient(60% 80% at 12% 0%, rgba(90,125,158,.14), transparent 68%)}
.section--hero .container{position:relative; z-index:1}

/* Banda teñida de steel (azul industrial profundo) */
.section--steel{background:linear-gradient(180deg,#111b27 0%, #0a0e14 100%)}
.audience{background:linear-gradient(180deg,#111b27,#0b0f15)}

/* Banda INVERTIDA (clara). Remapea los tokens: todo componente interior
   se adapta solo. Máximo una banda clara por página. */
.section--invert{
  background:#e9eaec; color:#101013;
  --canvas:#e9eaec; --surface:#ffffff; --raised:#f4f4f5;
  --line:#d6d7d9; --line-strong:#bfc0c4;
  --ink:#101013; --ink-2:#3c3c42; --ink-3:#5b5b60;
  --steel-400:#3d5a78; --steel-300:#2e4a63;
  /* 📼 Registro: aquí no se remapea ningún rojo —no hay token de marca que
     remapear—. Si el rojo vuelve, en banda clara el hex de texto #e84e4a se
     queda corto (3.10:1 sobre #e9eaec) y toca #c8201c (4.74:1 ✓).
     Contrastes recalculados el 6-ago. */
}
.section--invert .h-sec,.section--invert .h-sub,.section--invert h2,.section--invert h3{color:#0a0a0a}

/* ---- Hero de Seguridad: trama técnica tenue sobre banda clara ----
   ÚNICA banda clara del sitio (.section--invert) que carece de fondo
   fotográfico. En vez de imagen: una trama de plano/blueprint invertido
   (retícula fina + esquema abstracto de infraestructura) en steel sobre
   claro. MUY tenue y enmascarada: se desvanece bajo el texto (la lectura
   manda). Selector propio .section--schema → NO afecta a las otras cuatro
   bandas .section--invert (electrical-safety, ecosistema, contacto, index).
   Sin movimiento → compatible con prefers-reduced-motion por definición. */
.section--schema{position:relative; overflow:hidden}
.section--schema > .container{position:relative; z-index:1}
/* Retícula (menor 32px + mayor 160px), hairlines steel a muy baja opacidad.
   La máscara radial vacía el centro (donde vive el texto) y deja respirar
   la trama sólo en bordes/esquinas, como el margen de un plano técnico. */
.section--schema::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:
    linear-gradient(to right,  rgba(61,90,120,.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(61,90,120,.05) 1px, transparent 1px),
    linear-gradient(to right,  rgba(61,90,120,.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(61,90,120,.07) 1px, transparent 1px);
  background-size:32px 32px, 32px 32px, 160px 160px, 160px 160px;
  -webkit-mask-image:radial-gradient(ellipse 85% 72% at 50% 44%, transparent 0%, transparent 34%, #000 88%);
          mask-image:radial-gradient(ellipse 85% 72% at 50% 44%, transparent 0%, transparent 34%, #000 88%);
}
/* Esquema abstracto (nodos + conectores ortogonales + una línea de cota).
   Vive en la esquina inferior de arranque (lógica → se espeja en RTL),
   zona que en escritorio queda libre bajo el titular (la columna de specs
   es más alta). Se desvanece hacia el titular vía máscara. Sin texto → i18n
   intacto. Oculto < 768px para no cruzar el texto apilado en móvil. */
.section--schema .schema-fig{
  position:absolute; z-index:0; pointer-events:none; display:none;
  inset-block-end:clamp(1.5rem,5vw,3.5rem);
  inset-inline-start:clamp(1rem,4vw,2.5rem);
  inline-size:clamp(180px,22vw,300px); height:auto; opacity:.34;
  -webkit-mask-image:linear-gradient(to top, #000 42%, transparent 100%);
          mask-image:linear-gradient(to top, #000 42%, transparent 100%);
}
@media(min-width:768px){.section--schema .schema-fig{display:block}}
[dir="rtl"] .section--schema .schema-fig{transform:scaleX(-1)}
/* Impresión: la trama es decorativa. La retícula (::before) y la banda clara
   (fondos) ya no se imprimen por defecto; el esquema SÍ es DOM, así que se
   oculta para que la banda impresa quede limpia y legible, sin trazos sueltos. */
@media print{.section--schema::before,.section--schema .schema-fig{display:none}}

/* CTA de cierre con gradiente steel — las páginas terminan con color */
.cta-band{background:linear-gradient(140deg,#15202d 0%, #0a0a0a 62%)}

/* ============================================================
   RTL — árabe (dir="rtl"). Sólo lo que usa izquierda/derecha físicas;
   flexbox y grid se reflejan solos. El texto se alinea al inicio (derecha).
   ============================================================ */
[dir="rtl"] .statusbar .sb-phone{margin-left:0; margin-right:auto}
[dir="rtl"] table.matrix th,[dir="rtl"] table.matrix td{text-align:right; border-right:0; border-left:1px solid var(--line)}
[dir="rtl"] .paper table.exp th,[dir="rtl"] .paper table.exp td{text-align:right}
/* Bandas cinematográficas: el bloque de texto se ancla al lado de lectura (derecha) */
[dir="rtl"] .chp-text.to-right{margin-left:0; margin-right:auto; text-align:right}
[dir="rtl"] .chp-text:not(.to-right){text-align:right}
/* El número mono de los pasos y specs mantiene su lugar lógico */
[dir="rtl"] .hero2-for,[dir="rtl"] .lede,[dir="rtl"] .muted{text-align:right}
/* Excepción: en el hero de la home sólo el titular va centrado en cualquier
   dirección de lectura. El lede y la línea de audiencia YA NO: desde el split
   del 31-jul ambos se alinean al inicio (izquierda en LTR, derecha en RTL) y
   de eso se encarga `text-align:start` en `.hero2-split .lede` y en
   `.hero2-lede .hero2-for`, sin necesidad de override por dirección. */

/* ---- RTL de los componentes v5 (definidos al final del archivo) ----
   Todo lo demás de v5 usa grid + propiedades lógicas y se espeja solo.
   Aquí sólo lo que no se puede expresar en lógicas: la alineación de
   texto de los bloques de prosa. (Los degradados direccionales sí
   necesitarían override —`90deg` no se voltea con `dir`—, pero desde el
   3-ago no queda ninguno: el último era el de la banda a sangre de
   audiencia, que murió al unificarse las dos caras; el velo de `.caras`
   es simétrico a propósito.)
   Especificidad (0,2,0) > la definición base (0,1,0), así que estas
   reglas ganan aunque vivan antes en el archivo. */
[dir="rtl"] .paquetes-nota,[dir="rtl"] .paquete,
[dir="rtl"] .wizard,[dir="rtl"] .wizard-ok,
[dir="rtl"] .piramide-et,[dir="rtl"] .piramide-fuente,
[dir="rtl"] .post-card-body,
[dir="rtl"] .post,[dir="rtl"] .post-head,[dir="rtl"] .post-meta,[dir="rtl"] .post-fuentes{text-align:right}
/* La cifra vive centrada sobre la banda: la dirección no la mueve. */
[dir="rtl"] .piramide-cifra{text-align:center}

/* ============================================================
   Jerarquía Enterprise/Contractor: protagonista + subordinado.
   .side--primary domina (borde steel, superficie elevada, más ancho);
   .side--sub queda plano y discreto.
   ============================================================ */
.sides{display:grid; gap:1.25rem; grid-template-columns:1fr}
@media(min-width:900px){.sides{grid-template-columns:1.25fr .85fr; align-items:start}}
.side{padding:clamp(1.75rem,3vw,2.25rem); border-radius:2px}
.side--primary{border:1px solid var(--steel-600); background:var(--raised); box-shadow:0 0 0 1px rgba(90,125,158,.12), 0 18px 50px rgba(0,0,0,.35)}
.side--sub{border:1px solid var(--line); background:transparent}
.side--sub .hero2-kicker{color:var(--ink-3)}
.side-note{font-size:.9rem; line-height:1.55; color:var(--ink-2)}

/* Tarjeta-enlace (Contractor como puntero desde Modelo/otras) */
a.side--link{display:block; text-decoration:none; transition:border-color .15s, background .15s}
a.side--link:hover{border-color:var(--steel-500); background:rgba(255,255,255,.02)}

/* Sección Contractor de la home: banda discreta que redirige al lead contratista */
.contractor-strip{border:1px solid var(--line); border-radius:2px; background:var(--surface); padding:clamp(1.5rem,3vw,2rem); display:flex; flex-wrap:wrap; gap:1.25rem; align-items:center; justify-content:space-between}
.contractor-strip .cs-tx{max-width:44rem}
.contractor-strip .cs-lbl{font-size:.8rem; font-weight:600; letter-spacing:.02em; color:var(--steel-400)}
.contractor-strip h3{margin-top:.35rem; font-size:clamp(1.15rem,1.8vw,1.4rem)}
.contractor-strip p{margin-top:.5rem; color:var(--ink-2); font-size:.92rem}

/* ============================================================
   Páginas legales (privacidad.html · terminos.html)
   Documento sobrio: carátula + hairline + cuerpo con medida de
   lectura cómoda (~44rem ≈ 68-70ch). Tipografía del sistema SANS
   (el serif quedó descartado): titulares en --display, cuerpo en
   --sans. Propiedades LÓGICAS para que en RTL (árabe) no desborde
   ni se rompa la alineación aunque el cuerpo quede en español.
   ============================================================ */
.legal-page{padding-block:clamp(3.5rem,7vw,6rem)}
.legal-head{max-inline-size:48rem}
.legal-head h1{text-wrap:balance}
.legal-meta{display:flex; flex-wrap:wrap; align-items:center; margin-block-start:1.25rem;
  font-size:.8rem; color:var(--ink-3)}
/* Cuerpo: hairline de registro estática (sin JS) separa carátula de prosa. */
.legal{max-inline-size:44rem; margin-block-start:2.75rem; padding-block-start:2.75rem;
  border-block-start:1px solid var(--line)}
.legal h2{font-family:var(--display); font-weight:600; font-size:clamp(1.15rem,2vw,1.4rem);
  line-height:1.2; letter-spacing:-.015em; color:var(--ink); margin-block-start:2.75rem; text-wrap:balance}
.legal h2:first-child{margin-block-start:0}
.legal h3{font-family:var(--display); font-weight:600; font-size:1.05rem; line-height:1.3;
  letter-spacing:-.01em; color:var(--ink); margin-block-start:1.875rem}
.legal p,.legal li{font-size:.95rem; line-height:1.75; color:var(--ink-2);
  margin-block-start:.9rem; text-wrap:pretty}
/* Listas legales: guion largo steel como marca, no viñeta ni palomita. */
.legal ul{margin-block-start:.5rem; padding-inline-start:1.125rem; list-style:none}
.legal li{position:relative}
.legal li::before{content:"—"; position:absolute; inset-inline-start:-1.125rem; color:var(--steel-500)}
.legal a{color:var(--steel-400); text-decoration:underline; text-underline-offset:2px; text-decoration-color:var(--steel-700)}
.legal a:hover{color:var(--steel-300)}
.legal strong{color:var(--ink); font-weight:600}
[dir="rtl"] .legal-head,[dir="rtl"] .legal,[dir="rtl"] .legal-meta{text-align:right}

/* ============================================================
   ===== v5 =====
   Componentes nuevos de la reorganización en dos caras
   (ENTERPRISE ↔ VULKRON CONTRATISTA). Nada de lo anterior se
   renombra ni se borra: esto sólo AÑADE, con UNA excepción explícita
   —la única redefinición que cruza la frontera pre-v5 / v5—: el bloque
   «7 · Nav con 5 enlaces + conmutador + CTA» (más abajo) pisa `padding`
   y `font-size` de `.nav-links a` (declarado arriba) dentro de
   @media(min-width:1000px) and (max-width:1180px). Fuera de esa franja
   la regla base manda intacta.
   Reglas heredadas que aquí se respetan:
   · motion solo-desliza, nunca opacidad sobre texto; el scroll va en
     JS (app.js), jamás animation-timeline;
   · mono SÓLO para datos/cifras/seriales;
   · sin palomitas, sin viñetas de punto, sin flechas en botones,
     sin etiquetas de sección con la categoría;
   · propiedades LÓGICAS → el árabe se espeja solo (los overrides que
     no se pueden expresar en lógicas viven en el bloque [dir="rtl"]).
   Sus overrides RTL están arriba, junto al bloque [dir="rtl"].
   ============================================================ */

/* ------------------------------------------------------------
   1 · .nav-switch — registro visual de las caras del sitio
   Botón FANTASMA (borde steel, versalitas, tamaño contenido). Convive
   con .nav-cta sin competir: el CTA es sólido y steel-600; esto es sólo
   contorno y micro-tipografía, un registro distinto tanto de los enlaces
   (sin borde) como del CTA (sólido). No es un componente por sí solo:
   es el aspecto que comparten el disparador del selector de perfil
   (.nav-faces-btn, bloque 1-bis) y las dos caras planas del panel móvil
   (.nav-faces-panel), para que se lean como el mismo control en los dos
   breakpoints.
   ------------------------------------------------------------ */
.nav-switch{display:inline-flex; align-items:center; gap:.4rem; flex:none;
  padding:.45rem .7rem; font-family:var(--sans); font-size:.66rem; font-weight:600;
  line-height:1.2; letter-spacing:.09em; text-transform:uppercase; white-space:nowrap;
  color:var(--ink-2); background:transparent;
  border:1px solid var(--steel-700); border-radius:3px;
  transition:color .18s,border-color .18s,background .18s}
.nav-switch:hover{color:#fff; border-color:var(--steel-500); background:rgba(90,125,158,.10)}
/* Prefijo opcional, atenuado ("Ir a", "Ver"…). Puede omitirse. */
.nav-switch-pre{color:var(--ink-3); font-weight:500; letter-spacing:.06em}
.nav-switch:hover .nav-switch-pre{color:var(--ink-2)}

/* .nav-switch no se pliega por sí solo: es sólo piel. En la barra, lo que
   aparece y desaparece bajo 1000px es su contenedor `.nav-faces` (bloque
   1-bis); en el panel, las dos caras que llevan esta clase. Por eso aquí
   no hay ninguna regla de visibilidad. */

/* En el panel móvil: no es un enlace más de la lista (nada de hairline
   superior a ancho completo), sino el mismo botón fantasma, al inicio.
   .nav-panel a.nav-switch (0,2,1) empata con .nav-panel a:not(.btn) y
   gana por orden — por eso se re-declara el borde completo. */
.nav-panel a.nav-switch{display:inline-flex; align-self:flex-start;
  margin-block-start:1.15rem; padding:.6rem .95rem; font-size:.7rem;
  color:var(--ink-2); border:1px solid var(--steel-700); border-radius:3px}
.nav-panel a.nav-switch:hover{color:#fff; border-color:var(--steel-500); background:rgba(90,125,158,.10)}

/* ------------------------------------------------------------
   1-bis · .nav-faces — selector de perfil (Enterprise / Contratista)
   Sustituye al conmutador estático: ahora las DOS caras están siempre a
   un clic, se venga de donde se venga. Es NAVEGACIÓN, no un estado —
   cada opción es un enlace y no se guarda preferencia.
   · El disparador conserva el registro de `.nav-switch` (fantasma,
     versalitas, borde steel): lleva las dos clases, así que aquí sólo se
     añade lo que un <button> necesita y el caret.
   · El caret es el MISMO SVG del switcher de idiomas (`.lang-caret`), no
     el chevrón de `.nav-sub`: los dos desplegables por CLIC de la barra
     se anuncian igual. Nada de flechas «→» (prohibidas).
   · El panel calca a `.lang-menu` —fondo --raised, esquina 7px, filas con
     realce— con el borde steel de `.nav-switch`, como ya hace `.nav-sub`.
     Se oculta con el atributo `hidden` (nunca con opacidad): cerrado no
     es tabulable. Por eso aquí NO se declara `display`, que anularía la
     regla de agente de usuario.
   · Propiedades lógicas (`inset-inline-end`): en árabe se espeja solo,
     sin entrada en el bloque [dir="rtl"].
   ------------------------------------------------------------ */
.nav-faces{position:relative; flex:none}
/* En el bar: mismo plegado que `.nav-switch` y `.nav-cta` — bajo 1000px
   desaparece de la barra y sus dos caras viven en el panel. */
.nav > .container > .nav-faces{display:none}
@media(min-width:1000px){.nav > .container > .nav-faces{display:block}}
/* <button> no hereda cursor ni pierde el borde por sí solo; el resto del
   aspecto (borde steel, versalitas, hover) llega de `.nav-switch`. */
.nav-faces-btn{cursor:pointer}
.nav-faces-caret{inline-size:9px; block-size:6px; flex:none; transition:transform .18s var(--ease)}
.nav-faces.is-open .nav-faces-caret{transform:rotate(180deg)}
@media(prefers-reduced-motion:reduce){.nav-faces-caret{transition:none}}
.nav-faces.is-open .nav-faces-btn{color:#fff; border-color:var(--steel-500); background:rgba(90,125,158,.10)}
.nav-faces-menu{position:absolute; inset-block-start:calc(100% + 6px); inset-inline-end:0;
  margin:0; padding:4px; list-style:none; min-inline-size:11rem;
  background:var(--raised); border:1px solid var(--steel-700); border-radius:7px;
  box-shadow:0 10px 24px rgba(0,0,0,.6); z-index:210}
.nav-faces-opt{display:block; padding:.5rem .65rem; border-radius:4px;
  font-size:.85rem; font-weight:500; line-height:1.4; color:var(--ink-2);
  white-space:nowrap; transition:color .12s,background .12s}
.nav-faces-opt:hover{color:#fff; background:rgba(255,255,255,.06)}
/* La cara de la página en la que se está. Sólo realce visual: no lleva
   aria-current, porque «la cara actual» no siempre es la página actual. */
.nav-faces-opt.is-active{color:#fff; background:rgba(90,125,158,.16)}

/* Panel móvil: NO hay desplegable —abrir una caja dentro de una caja ya
   abierta— sino las dos caras planas, en una fila, con el mismo botón
   fantasma de siempre. Un toque en lugar de dos, y ni Escape ni el clic
   fuera del panel compiten con nada. La sangría superior pasa del botón
   a la fila para que las dos caras queden a la misma altura.
   Aquí las dos caras van SIN `.is-active`, a diferencia del desplegable
   de escritorio: es deliberado, no un olvido. En la barra el realce marca
   cuál de las dos opciones corresponde al botón que se acaba de abrir;
   en el panel no hay botón que explicar y la fila es una bifurcación de
   dos, así que el bloque es idéntico en las 18 páginas y no hay variante
   por página que mantener.
   El borde superior se re-declara porque la primera cara pasa a ser primer
   hijo del div y `.nav-panel a:not(.btn):first-child` se lo quita (empata
   en 0,3,1 y gana por ir después). */
.nav-panel .nav-faces-panel{display:flex; flex-wrap:wrap; gap:.5rem; margin-block-start:1.15rem}
.nav-panel .nav-faces-panel a.nav-switch{margin-block-start:0; border-block-start:1px solid var(--steel-700)}

/* ------------------------------------------------------------
   7 · Nav con 5 enlaces + conmutador + CTA
   El breakpoint sigue siendo 1000px (no se toca). Entre 1000 y 1180px
   la barra se COMPRIME (menos padding, tipo un punto menor) para que
   quepan marca + 5 enlaces + conmutador + CTA sin envolver ni recortar,
   con margen para las traducciones largas (de/fr/ar). A partir de
   1180px vuelve a los valores originales.
   ------------------------------------------------------------ */
.nav-links a{white-space:nowrap}
@media(min-width:1000px) and (max-width:1180px){
  .nav .container{gap:.6rem}
  .nav-links{gap:0}
  .nav-links a{padding:.7rem .5rem; font-size:.8rem}
  .nav-switch{font-size:.62rem; padding:.4rem .55rem; letter-spacing:.06em}
  .nav .nav-cta{padding:.65rem .9rem; font-size:.78rem}
  /* El selector de idioma entra en la misma compresión: en esta franja
     la barra lleva marca + 5 enlaces + conmutador + idioma + CTA. */
  .nav .lang-toggle{padding:3px 6px; gap:.3rem; font-size:11px}
  .nav .lang-globe{inline-size:12px; block-size:12px}
}

/* ------------------------------------------------------------
   2 · .caras — las dos caras del sitio en UNA sección (home, 3-ago)
   Sustituye a las dos bandas a sangre de audiencia (Enterprise y
   Contratista), que desaparecen del sitio con este bloque —su regla, su
   media query y su override RTL incluidos—. Tres columnas a sangre:
   PANEL de la cara activa (pregunta + párrafo + botón) · IMAGEN ·
   TEASER de la otra cara. El estado lo lleva `data-cara` en la sección
   y el par se espeja al cambiar, con el panel siempre del lado ancho.
   Los DOS estados viven en el HTML y aquí se enseña uno: el cambio es
   un atributo, no una animación, así que ningún texto queda esperando
   un fotograma para poder leerse.
   El tinte steel viene de la banda que sustituye —la misma familia azul
   industrial de `.chp`, sin parallax: la imagen acompaña, no compite—
   pero SIMÉTRICO: se cierra por los dos costados, no hacia uno solo.
   Por eso el componente no necesita override en el bloque [dir="rtl"]:
   el degradado no tiene lado y las columnas se espejan solas con grid.
   El VELO de la imagen gira con el apilado: vertical en móvil, donde la
   imagen es una fila y los costados no empalman con nada. Ninguna de
   las dos variantes tiene lado, así que tampoco piden override RTL.
   Motion: sólo el fundido de la imagen (≤250 ms) y la palpitación del
   teaser al posar el cursor. Las dos se anulan con
   prefers-reduced-motion y ninguna toca la opacidad de un texto.
   ------------------------------------------------------------ */
.caras{position:relative; display:grid; grid-template-columns:1fr;
  border-block:1px solid var(--line);
  background:linear-gradient(180deg,#111b27 0%, #0a0e14 100%);
  overflow:hidden}

/* La cara que no está activa sale del árbol (display:none): ni se pinta,
   ni se tabula, ni la lee el lector de pantalla. Nunca se «esconde» con
   opacidad, que dejaría dos preguntas superpuestas en el documento.
   Con el teaser inactivo se va SU frase de la acción (`.caras-teaser-vh`
   con el modificador de esa cara): vive fuera del botón, como hermana
   suya, así que no hereda su ocultación y sin esto se quedaría en el
   documento sin botón al que acompañar. Retirada con `display:none`, la
   frase deja de quedar suelta; y el botón al que describía tampoco está,
   así que nada se queda sin explicación. */
.caras[data-cara="enterprise"] .caras-panel--con,
.caras[data-cara="enterprise"] .caras-teaser--ent,
.caras[data-cara="enterprise"] .caras-teaser-vh--ent,
.caras[data-cara="contratista"] .caras-panel--ent,
.caras[data-cara="contratista"] .caras-teaser--con,
.caras[data-cara="contratista"] .caras-teaser-vh--con{display:none}

/* ---- Panel de la cara activa ----
   El titular baja un escalón respecto de `.h-sec`: su columna es más
   estrecha que la media banda de antes y a 3rem la pregunta se partía
   en cuatro renglones. Contrastes sobre el fondo (#111b27→#0a0e14) son
   los ya calculados para la banda: acento steel-300 y cuerpo --ink-2. */
.caras-panel{display:flex; align-items:center;
  padding-block:clamp(2.5rem,5vw,4rem);
  padding-inline:clamp(1.25rem,3.5vw,3rem)}
.caras-panel-inner{max-inline-size:34rem}
.caras-panel h2{font-size:clamp(1.7rem,2.9vw,2.4rem);
  text-wrap:balance; max-inline-size:18ch}
.caras-panel h2 .accent{color:var(--steel-300)}
.caras-panel p{margin-block-start:1.15rem; color:var(--ink-2);
  font-size:1.0625rem; line-height:1.6; max-inline-size:46ch}
/* El botón va DEBAJO del texto, rectangular y en su tamaño natural. */
.caras-panel .btn{margin-block-start:2rem}

/* ---- Imagen: las dos cargadas, se turnan con un fundido corto ----
   Las hairlines van con la ORIENTACIÓN del apilado, no con el estado:
   a los costados cuando la imagen es columna (escritorio) y arriba y
   abajo cuando es una fila (móvil). Cada una en su media query, porque
   a sangre y en una sola columna las laterales quedarían pegadas al
   borde de la pantalla sin nada que separar. */
.caras-media{position:relative; overflow:hidden;
  min-block-size:clamp(14rem,32vw,22rem); background:var(--raised)}
.caras-img{position:absolute; inset:0; inline-size:100%; block-size:100%;
  object-fit:cover; object-position:center;
  opacity:0; transition:opacity .25s var(--ease)}
.caras[data-cara="enterprise"] .caras-img--ent,
.caras[data-cara="contratista"] .caras-img--con{opacity:1}
.caras-tint{position:absolute; inset:0; pointer-events:none; background:
  linear-gradient(180deg,rgba(10,10,10,.5),rgba(10,10,10,.1) 45%,rgba(10,10,10,.5)),
  linear-gradient(90deg,rgba(17,27,39,.72) 0%,rgba(10,10,10,0) 30%,
    rgba(10,10,10,0) 70%,rgba(17,27,39,.72) 100%)}

/* ---- Teaser de la otra cara ----
   Es el MANDO del cambio, no un enlace: no lleva botón ni destino, y su
   texto se lee entero en reposo (el hover sólo lo realza). Sin
   superficie propia para no competir con el botón outline del panel. */
.caras-teaser{display:flex; flex-direction:column; justify-content:center;
  gap:.55rem; text-align:start; cursor:pointer;
  border:0; background:transparent; color:var(--ink);
  font-family:var(--sans);
  padding-block:clamp(2rem,4vw,3rem);
  padding-inline:clamp(1.25rem,3vw,2.25rem);
  transition:background .2s}
.caras-teaser:hover{background:rgba(255,255,255,.045)}
.caras-teaser-t{font-family:var(--display); font-weight:700;
  letter-spacing:-.015em; line-height:1.1; text-wrap:balance;
  font-size:clamp(1.2rem,1.8vw,1.5rem);
  color:var(--ink-2); transition:color .2s}
.caras-teaser:hover .caras-teaser-t{color:var(--ink)}
.caras-teaser-tri{font-size:.9rem; line-height:1.5; color:var(--ink-3)}
/* El teaser es una pieza a sangre dentro de una sección con
   `overflow:hidden`: el anillo de foco por fuera se recortaría contra
   el borde. Va por dentro, como en `.pagenav-link`. */
.caras-teaser:focus-visible{outline-offset:-2px}
/* La frase de la acción («Cambiar a la cara…») acompaña al botón como
   DESCRIPCIÓN (aria-describedby), no como aria-label: el nombre del
   botón sigue siendo su texto visible. Se oculta a la vista sin salir
   del árbol —recortada, no `display:none`—, que es lo único que la deja
   legible para el lector de pantalla. Por eso vive FUERA del botón, en
   el HTML: recortada por dentro seguiría contando para el nombre y la
   frase se oiría dos veces. Su bloque contenedor es `.caras` (hermana
   del teaser, y la sección ya es `position:relative`): a propósito, no
   lleva `inset` ni desplazamiento — se queda en su posición estática,
   mide 1px y la sección la recorta. Esto vale para la frase de la cara
   que se muestra; la de la otra sí sale del árbol, con su botón, en la
   regla de estado de arriba. */
.caras-teaser-vh{position:absolute; inline-size:1px; block-size:1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap}

/* Palpitación: DOS latidos sobrios al posar el cursor, escala mínima
   sobre el botón entero. Mueve, no oculta: la opacidad del texto no
   entra en la animación. Los dos latidos llenan la gracia del hover
   (500 ms) —uno solo dejaría el resto de la espera en silencio—, así
   que el segundo se cierra justo cuando la cara cambia: es el aviso del
   cambio, no un adorno que se corta a medias. Va bajo las MISMAS
   condiciones que el cambio por cursor en `app.js` (puntero fino, hover
   real y layout de escritorio): donde el cursor no cambia de cara,
   tampoco se anuncia. */
@keyframes caras-latido{0%,50%,100%{transform:scale(1)} 25%,75%{transform:scale(1.015)}}
@media(hover:hover) and (pointer:fine) and (min-width:900px){
  .caras-teaser:hover{animation:caras-latido 500ms var(--ease)}
}
@media(prefers-reduced-motion:reduce){
  .caras-img{transition:none}
  .caras-teaser:hover{animation:none}
}

/* La altura no salta al cambiar de cara (SÓLO en escritorio): el panel
   Enterprise es más largo que el del Contratista, así que en tres
   columnas la sección encogería al cambiar. En vez de fijar una altura
   a ojo, el panel de la cara inactiva SE QUEDA en la misma celda
   de la rejilla que el activo, reservado con `visibility` en lugar de
   retirado con `display`: no se pinta, no se tabula, no lo lee el lector
   de pantalla y no recibe el cursor, pero la celda mide siempre lo que
   mide la cara más larga. La altura sale de las dos caras, no de un
   número. La reserva vive dentro del media de escritorio, más abajo.
   Por debajo de 900px NO se reserva: rige el `display:none` de la cara
   inactiva y la sección apilada refluye a su alto real. Reservar ahí
   dejaría un hueco muerto del largo de la otra cara entre el panel y la
   imagen, y en una pantalla estrecha ese vacío molesta más que el
   reflujo. El reflujo, además, está acotado y cae del lado bueno:
   apilada, la sección empieza por el panel, así que su borde superior no
   se mueve y la pregunta que se está leyendo no salta; lo que se
   desplaza —la diferencia de alto entre las dos caras, un par de
   renglones— es todo lo que va DEBAJO, que son justo las dos superficies
   desde las que se cambia en móvil: la barra del teaser y la propia
   imagen (segunda superficie de toque, ver el módulo de las caras en
   `app.js`). Se toca abajo y crece hacia abajo.
   (El teaser que se retira con `display:none`, en todos los anchos, es
   el de la cara ya activa: es la pieza corta y no gobierna la altura de
   nada. El de la otra cara sigue visible, porque es el mando.) */

/* ---- Escritorio: tres columnas y el espejo del estado ----
   El `min-block-size` de la sección es el suelo de la banda (que no
   quede baja cuando el texto es corto); el que las dos caras midan lo
   mismo lo resuelve la reserva del panel inactivo, aquí abajo. */
@media(min-width:900px){
  .caras{align-items:stretch; min-block-size:clamp(24rem,34vw,29rem)}
  .caras > *{grid-row:1}
  .caras[data-cara="enterprise"]{grid-template-columns:1fr .8fr .55fr}
  .caras[data-cara="contratista"]{grid-template-columns:.55fr .8fr 1fr}
  .caras[data-cara="enterprise"] .caras-panel--ent{grid-column:1}
  .caras[data-cara="contratista"] .caras-teaser--ent{grid-column:1}
  .caras-media{grid-column:2; border-inline:1px solid var(--line)}
  .caras[data-cara="enterprise"] .caras-teaser--con{grid-column:3}
  .caras[data-cara="contratista"] .caras-panel--con{grid-column:3}
  /* El panel de la cara inactiva vuelve al árbol, reservado con
     `visibility` (ver «La altura no salta al cambiar de cara», arriba), y
     ocupa la MISMA columna que el activo (la ancha), así mide lo que
     mediría al activarse: por simetría, la columna 1 de `1fr .8fr .55fr`
     y la 3 de `.55fr .8fr 1fr` tienen el mismo ancho. */
  .caras[data-cara="enterprise"] .caras-panel--con,
  .caras[data-cara="contratista"] .caras-panel--ent{display:flex; visibility:hidden}
  .caras[data-cara="enterprise"] .caras-panel--con{grid-column:1}
  .caras[data-cara="contratista"] .caras-panel--ent{grid-column:3}
}

/* ---- Móvil (<900px): apilado y el teaser como barra táctil ----
   El orden lo da el propio DOM en una sola columna: panel de la cara
   activa → imagen → teaser. El teaser deja de ser una columna alta y
   se convierte en una barra: superficie apenas levantada, hairline que
   la separa de la imagen y altura de toque cómoda. En tacto no hay
   hover ni palpitación — el cambio es por toque.
   Cada pieza se coloca con FILA Y COLUMNA, nunca sólo con fila: sin
   `grid-column` la colocación automática podría mandar alguna a una
   columna implícita en vez de dejarlas una debajo de otra, estrechando
   la sección entera. El corte va en 899.98px para que no quede ninguna
   franja de anchos fraccionarios sin media query. */
@media(max-width:899.98px){
  .caras-panel{grid-row:1; grid-column:1}
  /* Aquí la imagen también cambia de cara (`app.js`, módulo de las
     caras): es una superficie de toque redundante del teaser, para el
     dedo que va a lo grande en vez de a la barra. El `cursor` sólo lo
     ve quien mira este layout con ratón —una ventana de escritorio
     estrecha—; en tacto no hay cursor que enseñar, pero la señal tiene
     que ser honesta también ahí. En escritorio no se pone: allí la
     imagen no cambia nada. */
  .caras-media{grid-row:2; grid-column:1; border-block:1px solid var(--line);
    cursor:pointer}
  /* El velo cambia de eje con la imagen: aquí es una fila entre el panel
     y la barra del teaser, así que se cierra de arriba abajo —arriba
     apenas, para no ensuciar el objeto; abajo en steel, que es donde
     entrega el color a la barra—. Los viñeteados laterales del velo de
     escritorio no tendrían con qué empalmar en una sola columna. */
  .caras-tint{background:linear-gradient(180deg,rgba(10,10,10,.45),
    rgba(10,10,10,.12) 40%,rgba(17,27,39,.78) 100%)}
  .caras-teaser{grid-row:3; grid-column:1;
    flex-direction:row; flex-wrap:wrap;
    align-items:baseline; justify-content:flex-start;
    gap:.3rem .7rem; min-block-size:3.5rem;
    padding-block:.95rem; padding-inline:clamp(1.25rem,4vw,2rem);
    background:rgba(255,255,255,.03)}
  .caras-teaser-t{font-size:1.05rem}
  .caras-teaser-tri{font-size:.85rem}
}

/* ------------------------------------------------------------
   3 · .paquetes — los tres paquetes del Contratista
   SIN PRECIOS (regla 5): los tres CTAs llevan a registro.html con el
   paquete preseleccionado. La lista de lo que incluye cada paquete usa
   la convención tipográfica del sitio — filas separadas por hairline,
   como .tier li — NUNCA palomitas ni viñetas.
   ------------------------------------------------------------ */
/* Línea superior compartida: «Todos los paquetes incluyen 1 Main user». */
.paquetes-nota{margin-block-start:2rem; padding-block-end:1.25rem;
  border-block-end:1px solid var(--line);
  font-size:.88rem; color:var(--ink-2)}
.paquetes-nota strong{color:var(--ink); font-weight:600}

.paquetes{display:grid; gap:1.25rem; grid-template-columns:1fr; margin-block-start:1.5rem}
@media(min-width:760px){.paquetes{grid-template-columns:repeat(3,1fr)}}

.paquete{display:flex; flex-direction:column; border-radius:2px;
  border:1px solid var(--line-strong); background:var(--surface);
  padding:clamp(1.5rem,2.6vw,2rem);
  transition:border-color .2s,background .2s}
.paquete:hover{border-color:var(--steel-600)}
.paquete-nom{font-family:var(--display); font-weight:700;
  font-size:clamp(1.35rem,2vw,1.6rem); letter-spacing:-.01em; line-height:1.1}
.paquete-sub{margin-block-start:.45rem; color:var(--ink-3); font-size:.85rem; line-height:1.5}
.paquete-inc{list-style:none; margin-block-start:1.35rem; padding:0}
.paquete-inc li{border-block-start:1px solid var(--line); padding-block:.65rem;
  font-size:.88rem; line-height:1.55; color:var(--ink-2)}
.paquete-inc li strong{color:var(--ink); font-weight:600}
/* Nota al pie de tarjeta (p. ej. «para 5+ accesos, a la medida»). */
.paquete-pie{margin-block-start:1rem; font-size:.8rem; line-height:1.55; color:var(--ink-3)}
.paquete-cta{margin-block-start:auto; padding-block-start:1.5rem}
.paquete-cta .btn{inline-size:100%}

/* Destacado: acento steel sutil — el mismo lenguaje de .side--primary
   y .tier.feat, sin subir el brillo. */
.paquete--destacado{border-color:var(--steel-600);
  background:linear-gradient(180deg,#111b27,#0c1118);
  box-shadow:0 0 0 1px rgba(90,125,158,.12), 0 18px 50px rgba(0,0,0,.35)}
.paquete--destacado:hover{border-color:var(--steel-500)}

/* ------------------------------------------------------------
   4 · .wizard — registro de interés en dos pasos (registro.html)
   Paso 1 pide poco; paso 2, ya comprometido, pide lo específico.
   Vive DENTRO de un .form (misma caja, mismos inputs que contacto.html):
   aquí no se redefine ningún input, sólo se añade rejilla, progreso,
   obligatorios y estados de error.
   Contrato con el JS: el contenedor lleva [data-paso-actual="1|2"] y
   cada paso [data-paso="1|2"]; se muestran/ocultan con el atributo
   hidden (nunca con opacidad: el texto jamás se oculta a medias).
   ------------------------------------------------------------ */
.wizard-progress{margin-block-end:1.75rem}
.wizard-progress-lbl{display:block; font-size:.78rem; font-weight:600;
  color:var(--ink-3); letter-spacing:.01em; margin-block-end:.6rem}
.wizard-bar{block-size:2px; background:var(--line); overflow:hidden}
.wizard-bar i{display:block; block-size:100%; inline-size:50%;
  background:var(--steel-400); transition:inline-size .32s var(--ease)}
.wizard[data-paso-actual="2"] .wizard-bar i{inline-size:100%}
@media(prefers-reduced-motion:reduce){.wizard-bar i{transition:none}}

/* Pasos. [hidden] explícito por si algún reset lo pisa. */
.wizard-paso[hidden]{display:none}
.wizard-paso h2{font-size:1.1rem; margin-block-end:.4rem}
.wizard-paso > .lede{margin-block-end:1.5rem; font-size:.92rem}

/* Rejilla de campos: 2 columnas en ≥640px, 1 en móvil.
   El espaciado vertical lo sigue dando el .field existente. */
.wizard-campos{display:grid; grid-template-columns:1fr; gap:0 1.25rem}
@media(min-width:640px){.wizard-campos{grid-template-columns:1fr 1fr}}
.wizard-campos .field--full{grid-column:1/-1}

/* Obligatorio: asterisco en el acento del sistema (steel), no en rojo —
   el rojo queda reservado al error. */
.field .req{color:var(--steel-400); font-weight:600; margin-inline-start:.15rem}

/* Error accesible: borde + mensaje. El estado real lo marca
   aria-invalid="true" en el control (lo que anuncia el lector de
   pantalla); el CSS sólo lo hace visible. */
.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"]{border-color:var(--crit)}
.field input[aria-invalid="true"]:focus,
.field select[aria-invalid="true"]:focus,
.field textarea[aria-invalid="true"]:focus{border-color:var(--crit)}
.field-error{display:block; margin-block-start:.4rem; font-size:.78rem;
  line-height:1.45; color:var(--crit)}
.field-error[hidden]{display:none}

.wizard-acciones{display:flex; flex-wrap:wrap; gap:.75rem; align-items:center;
  margin-block-start:1.5rem; padding-block-start:1.5rem;
  border-block-start:1px solid var(--line)}
.wizard-acciones .btn-primary{min-inline-size:10rem}
.wizard-nota{margin-block-start:1rem; font-size:.78rem; color:var(--ink-3);
  display:flex; flex-wrap:wrap; align-items:center}

/* Confirmación. Mismo tono que .form-ok, pieza propia para no tocar
   el estado de éxito del formulario de contacto. */
.wizard-ok{padding:2.5rem 1rem; text-align:center}
.wizard-ok[hidden]{display:none}
.wizard-ok h2{font-size:1.3rem; margin-block-end:.6rem}
.wizard-ok p{color:var(--ink-2); font-size:.92rem; max-inline-size:44ch; margin-inline:auto}
.wizard-ok .btn{margin-block-start:1.75rem}

/* ------------------------------------------------------------
   5 · .piramide — pirámide de Bird en cinco niveles (prevencion.html)
   Cinco bandas apiladas, cada una recortada en trapecio con clip-path;
   los anchos decrecen hacia arriba y los cortes de niveles contiguos
   coinciden, así que la pila se lee como una sola pirámide.
   La cifra va en mono (ES un dato) y centrada SOBRE la banda; la
   etiqueta va en Plex Sans, fuera del recorte (clip-path recorta
   también el contenido, por eso banda y texto son capas distintas).
   Paleta: una sola familia steel que se apaga hacia la base. Sin
   arcoíris y SIN animación — es un diagrama, no un efecto.
   ------------------------------------------------------------ */
.piramide{--forma:clamp(11rem,38vw,22rem);
  list-style:none; margin-block-start:2.5rem; padding:0;
  display:grid; gap:.3rem}
.piramide-nivel{position:relative; display:grid;
  grid-template-columns:var(--forma) minmax(0,1fr);
  align-items:center; gap:1.25rem; min-block-size:3.9rem}
/* Columna 1: la forma. Es contenedor posicionado; la banda recortada
   va absoluta detrás y la cifra encima, sin sufrir el recorte. */
.piramide-forma{position:relative; align-self:stretch; display:flex;
  align-items:center; justify-content:center; min-block-size:3.9rem}
.piramide-banda{position:absolute; inset:0; z-index:0}
.piramide-cifra{position:relative; z-index:1; text-align:center;
  font-family:var(--mono); font-weight:600; font-variant-numeric:tabular-nums;
  font-size:clamp(1.05rem,1.9vw,1.45rem); line-height:1; color:#fff;
  text-shadow:0 1px 10px rgba(10,10,10,.45)}
/* El nivel base no lleva cifra sino palabra: sale del mono (que es sólo
   para datos) y pasa a la sans en versalitas. */
.piramide-cifra--base{font-family:var(--sans); font-size:.78rem;
  font-weight:600; letter-spacing:.08em; text-transform:uppercase}
/* Columna 2: la etiqueta. */
.piramide-et{min-inline-size:0}
.piramide-et .t{font-weight:600; font-size:.95rem; line-height:1.3; color:var(--ink)}
.piramide-et .d{margin-block-start:.2rem; font-size:.82rem; line-height:1.5; color:var(--ink-3)}

/* Cortes: los seis límites (42 · 34 · 26 · 17 · 9 · 0 % de sangrado por
   lado) encadenan las cinco bandas en una pirámide continua. */
.piramide-nivel--1 .piramide-banda{clip-path:polygon(42% 0,58% 0,66% 100%,34% 100%);
  background:var(--steel-600)}
.piramide-nivel--2 .piramide-banda{clip-path:polygon(34% 0,66% 0,74% 100%,26% 100%);
  background:color-mix(in srgb,var(--steel-600) 88%,var(--canvas))}
.piramide-nivel--3 .piramide-banda{clip-path:polygon(26% 0,74% 0,83% 100%,17% 100%);
  background:color-mix(in srgb,var(--steel-600) 74%,var(--canvas))}
.piramide-nivel--4 .piramide-banda{clip-path:polygon(17% 0,83% 0,91% 100%,9% 100%);
  background:color-mix(in srgb,var(--steel-600) 60%,var(--canvas))}
.piramide-nivel--5 .piramide-banda{clip-path:polygon(9% 0,91% 0,100% 100%,0 100%);
  background:color-mix(in srgb,var(--steel-600) 46%,var(--canvas))}

.piramide-fuente{margin-block-start:1.5rem; font-size:.82rem; color:var(--ink-3)}

/* Móvil: la banda pasa a ancho completo y la etiqueta cae debajo.
   Todo está en %, así que no hay desbordamiento posible. */
@media(max-width:720px){
  .piramide{--forma:100%; gap:.5rem}
  .piramide-nivel{grid-template-columns:1fr; gap:.5rem; min-block-size:0}
  .piramide-forma{min-block-size:3rem}
  .piramide-et{padding-inline:.1rem}
}

/* ------------------------------------------------------------
   6 · .blog-grid / .post — sección de artículos
   Tarjeta: imagen 16:9, fecha en mono discreto (dato), título, extracto.
   Artículo: medida de lectura ~68ch, jerarquía h2/h3, cita sobria y
   referencias al pie. Mismo lenguaje sobrio que las páginas legales.
   ------------------------------------------------------------ */
.blog-grid{display:grid; grid-template-columns:1fr; gap:1.5rem; margin-block-start:2.5rem}
@media(min-width:680px){.blog-grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.blog-grid{grid-template-columns:repeat(3,1fr)}}

.post-card{display:flex; flex-direction:column; border:1px solid var(--line);
  background:var(--surface); transition:border-color .2s,background .2s}
.post-card:hover{border-color:var(--steel-600); background:var(--raised)}
.post-card-media{aspect-ratio:16/9; overflow:hidden;
  background:var(--raised); border-block-end:1px solid var(--line)}
.post-card-media img{inline-size:100%; block-size:100%; object-fit:cover}
.post-card-body{padding:1.35rem; display:flex; flex-direction:column; flex:1}
.post-card-fecha{font-family:var(--mono); font-size:.72rem; letter-spacing:.02em;
  color:var(--ink-3); font-variant-numeric:tabular-nums}
.post-card h3{margin-block-start:.55rem; font-size:1.15rem; line-height:1.22;
  text-wrap:balance; transition:color .2s}
.post-card:hover h3{color:#fff}
.post-card-extracto{margin-block-start:.6rem; color:var(--ink-2);
  font-size:.9rem; line-height:1.6}

/* Carátula del artículo */
.post-head{max-inline-size:68ch}
.post-head h1{text-wrap:balance}
.post-meta{display:flex; flex-wrap:wrap; align-items:center;
  margin-block-start:1.25rem; font-size:.8rem; color:var(--ink-3)}
.post-meta .fecha{font-family:var(--mono); font-variant-numeric:tabular-nums}

/* Cuerpo: medida de lectura y hairline de registro, como .legal */
.post{max-inline-size:68ch; margin-block-start:2.75rem;
  padding-block-start:2.75rem; border-block-start:1px solid var(--line)}
.post h2{font-family:var(--display); font-weight:700;
  font-size:clamp(1.3rem,2.2vw,1.65rem); line-height:1.2; letter-spacing:-.015em;
  color:var(--ink); margin-block-start:2.75rem; text-wrap:balance}
.post h2:first-child{margin-block-start:0}
.post h3{font-family:var(--display); font-weight:600; font-size:1.08rem;
  line-height:1.3; letter-spacing:-.01em; color:var(--ink); margin-block-start:1.875rem}
.post p,.post li{font-size:1rem; line-height:1.75; color:var(--ink-2);
  margin-block-start:1rem; text-wrap:pretty}
.post ul{margin-block-start:.5rem; padding-inline-start:1.125rem; list-style:none}
.post ul li{position:relative}
.post ul li::before{content:"—"; position:absolute; inset-inline-start:-1.125rem; color:var(--steel-500)}
.post a{color:var(--steel-400); text-decoration:underline; text-underline-offset:2px;
  text-decoration-color:var(--steel-700)}
.post a:hover{color:var(--steel-300)}
.post strong{color:var(--ink); font-weight:600}
.post figure{margin-block-start:2rem}
.post figure img{inline-size:100%; block-size:auto}
.post figcaption{margin-block-start:.6rem; font-size:.8rem; color:var(--ink-3)}
/* Cita sobria: filete steel al inicio, sin comillas decorativas. */
.post blockquote{margin-block-start:1.75rem; padding-inline-start:1.35rem;
  border-inline-start:2px solid var(--steel-600)}
.post blockquote p{color:var(--ink); font-size:1.05rem; line-height:1.6}
.post blockquote cite{display:block; margin-block-start:.7rem; font-style:normal;
  font-size:.82rem; color:var(--ink-3)}

/* Referencias al pie: numeradas (es una referencia, no adorno) */
.post-fuentes{max-inline-size:68ch; margin-block-start:3rem;
  padding-block-start:1.5rem; border-block-start:1px solid var(--line)}
.post-fuentes .t{font-size:.82rem; font-weight:600; color:var(--ink)}
.post-fuentes ol{list-style:none; counter-reset:fuente; margin-block-start:.9rem; padding:0}
.post-fuentes li{counter-increment:fuente; position:relative;
  padding-inline-start:1.9rem; margin-block-start:.55rem;
  font-size:.82rem; line-height:1.6; color:var(--ink-3)}
.post-fuentes li::before{content:counter(fuente); position:absolute;
  inset-inline-start:0; font-family:var(--mono); font-size:.75rem; color:var(--steel-400)}
.post-fuentes a{color:var(--ink-2); text-decoration:underline;
  text-underline-offset:2px; text-decoration-color:var(--line-strong)}
.post-fuentes a:hover{color:var(--steel-400)}

/* ------------------------------------------------------------
   8 · .nav-item--sub / .nav-sub — submenú del nav (SIN JS)
   ⚠️ 14-ago: EL DESPLEGABLE SE DISOLVIÓ en las 17 páginas VULKRON —
   «Ecosistema» volvió a ser enlace plano y STUDY subió a la barra `.partes`.
   Este bloque SOBREVIVE porque `expo123.html` está congelada y sigue
   usándolo: no borrarlo y no propagarlo. Lo que se describe abajo es el
   chrome de esa página congelada, no el que hoy se sirve.
   El enlace «Ecosistema» de la barra pasa a ser también la entrada a un
   desplegable de dos destinos (Ecosistema · VULKRON STUDY). Sigue siendo
   un ENLACE REAL a ecosistema.html: quien no despliega, igual llega.
   Apertura: :hover (ratón) y :focus-within (teclado). El disparador es
   un hijo enfocable del propio contenedor, así que tabular hasta él
   abre el panel y salir de él lo cierra — sin aria-expanded, que sin JS
   no cambiaría nunca y mentiría al lector de pantalla.
   Cierre solo: al perder hover/foco. El panel se oculta con `display`
   (no con opacidad): cerrado no es tabulable ni lo anuncia el lector, y
   se respeta «el motion nunca oculta texto».
   El panel NO se solapa con la barra: cae 14px bajo el disparador, que
   es lo que mide el aire entre el enlace y el hairline inferior del nav
   (barra de 4rem, enlaces centrados) más la separación de 2px. Así
   cuelga del hairline en vez de cortarlo. Ese hueco lo cubre un puente
   transparente (.nav-item--sub::after) que SÓLO existe con el menú
   abierto: sin él el ratón «se cae» al cruzar y el menú se cerraría
   antes de llegar a las filas; condicionado, no deja zona muerta
   capturando clics cuando está cerrado.
   Lenguaje visual: el de .lang-menu (fondo --raised, esquina 7px,
   filas con realce), con el borde steel de .nav-switch. La sombra es
   corta y opaca —caída, no halo— para no caer en «sombra difusa».
   RTL: anclado con inset-inline-start → se espeja solo; NO necesita
   entrada en el bloque [dir="rtl"]. La única excepción son los bordes
   del chevrón, que son FÍSICOS a propósito: la figura se construye
   girando un cuadrado y `rotate()` es físico, así que con lógicas el
   chevrón apuntaría de lado en árabe.
   ------------------------------------------------------------ */
.nav-item--sub{position:relative; align-self:stretch; display:flex; align-items:center}
/* Puente de hover sobre el hueco de 14px. Invisible, sin fondo y sólo
   presente mientras el menú está abierto: el ratón ya está dentro del
   elemento cuando aparece, así que el :hover no se interrumpe al
   cruzar. */
.nav-item--sub::after{content:""; position:absolute; inset-inline:0;
  inset-block-start:100%; block-size:15px; display:none}
.nav-item--sub:hover::after,
.nav-item--sub:focus-within::after{display:block}

/* Disparador + caret. El caret es un chevrón dibujado (dos bordes de un
   cuadrado girado): ni «→» —prohibido— ni glifo tipográfico. Ocupa
   ~13px con su separación, contemplado en la franja comprimida. */
.nav-links .nav-sub-link{display:inline-flex; align-items:center; gap:.35rem}
.nav-sub-link::after{content:""; flex:none; inline-size:.3125rem; block-size:.3125rem;
  border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
  transform:translateY(-1px) rotate(45deg); opacity:.55;
  transition:transform .18s var(--ease),opacity .18s}

/* Abierto: el disparador se mantiene encendido aunque el ratón esté ya
   sobre una fila del panel, y el chevrón apunta hacia arriba. */
.nav-item--sub:hover > .nav-sub-link,
.nav-item--sub:focus-within > .nav-sub-link{color:#fff}
.nav-item--sub:hover > .nav-sub-link::after,
.nav-item--sub:focus-within > .nav-sub-link::after{transform:translateY(1px) rotate(-135deg); opacity:1}
@media(prefers-reduced-motion:reduce){.nav-sub-link::after{transition:none}}

/* El panel. z-index dentro del contexto de apilamiento de .nav (z:100),
   por encima del contenido de la barra y del .nav-panel (z:50). */
.nav-sub{position:absolute; inset-block-start:calc(100% + 14px); inset-inline-start:0;
  z-index:120; display:none; min-inline-size:13rem; padding:4px;
  background:var(--raised); border:1px solid var(--steel-700); border-radius:7px;
  box-shadow:0 10px 24px rgba(0,0,0,.6)}
.nav-item--sub:hover > .nav-sub,
.nav-item--sub:focus-within > .nav-sub{display:block}

/* Filas. Se re-declaran padding y tamaño porque `.nav-links a` (0,1,1)
   los impone —y los COMPRIME entre 1000 y 1180px—: con `.nav-links
   .nav-sub a` (0,3,1) el interior del panel queda estable a cualquier
   ancho, independientemente del orden en el archivo. */
.nav-links .nav-sub a{display:block; padding:.5rem .65rem; border-radius:4px;
  font-size:.85rem; font-weight:500; line-height:1.4; color:var(--ink-2);
  white-space:nowrap; transition:color .12s,background .12s}
.nav-links .nav-sub a:hover{color:#fff; background:rgba(255,255,255,.06)}
.nav-links .nav-sub a.active{color:#fff; background:rgba(90,125,158,.16)}

/* Franja comprimida (1000–1180px): el caret cede su separación como el
   resto de la barra. El bloque 7 no se toca. */
@media(min-width:1000px) and (max-width:1180px){
  .nav-links .nav-sub-link{gap:.28rem}
}

/* Panel móvil: NO hay desplegable — los dos destinos van planos, como
   dos enlaces más de la lista. Esta red de seguridad garantiza que, si
   el markup del panel reutilizara las clases, no aparezca una caja
   flotante dentro del panel: `display:contents` disuelve los envoltorios
   y los enlaces vuelven a ser filas del panel. */
.nav-panel .nav-item--sub,
.nav-panel .nav-sub{display:contents}
.nav-panel .nav-item--sub::after,
.nav-panel .nav-sub-link::after{content:none}

/* v5 · fixes del submenú STUDY (residuo de `expo123.html`: ver el aviso del
   14-ago en el encabezado del bloque 8 — el desplegable ya no se sirve) */
.nav-item--sub:has(.nav-sub a.active) > a{color:#fff}
[id]{scroll-margin-block-start:5.5rem}

/* v5 · hero en video (secuencia de planta en producción) */
video.hero2-bg{pointer-events:none}
.hero2-bg--fallback{display:none}
@media (prefers-reduced-motion: reduce){
  video.hero2-bg{display:none}
  .hero2-bg--fallback{display:block}
}

/* ------------------------------------------------------------
   9 · Cuerpo de la landing v5 — menos párrafo, más estructura
   Rediseño del tramo entre el hero y el pie de `index.html`
   (decisión del cliente, 31-jul): las secciones altas de prosa se
   sustituyen por rejilla y tarjetas-destino. Siete piezas,
   todas con propiedades LÓGICAS (el árabe se espeja solo; sólo el
   degradado direccional de `.cta-strip` lleva override RTL):

     .claim               → la misión comprimida a UNA línea
     .claim-video         → el porqué de VULKRON, en video bajo el claim
     .claim-sub           → la frase que cierra el bloque, bajo el video
     .sum-top             → resumen: titular + diagrama a dos columnas
     .sum-notes           → la nota al pie del resumen, en franja
     .briefs / .brief     → tarjetas-destino (Prevención · C-TPAT ·
                            Criterios · STUDY): H2 corto, 2-3 líneas y
                            un enlace. Sustituyen cuatro secciones altas
     .cta-strip           → CTA de cierre en UNA tira horizontal
                            (sustituye a la `.cta-band` alta de index)

   Reglas heredadas respetadas: sin flechas en enlaces, sin palomitas,
   sin kickers de categoría, sin mono decorativo, sin sombra difusa.
   Motion: aquí NADA anima — el deslizamiento de `.reveal` lo sigue
   haciendo `app.js`.
   ------------------------------------------------------------ */

/* --- .claim — la frase grande. Protagonista tipográfica y, en
   escritorio, UNA SOLA LÍNEA: el tamaño está calibrado (4.6vw, tope
   3.7rem) para que la frase entre completa en el ancho del contenedor
   sin partirse a media oración. Por debajo de 760px ya no cabe: ahí el
   corte se fuerza en el PUNTO —el acento pasa a bloque— para que la
   segunda oración empiece su propia línea en vez de quedar colgando. --- */
.claim{font-family:var(--display); font-weight:600;
  font-size:clamp(1.75rem,4.6vw,3.7rem); line-height:1.08;
  letter-spacing:-.03em; text-wrap:balance}
/* El acento pasa a bloque para que la segunda oración empiece su propia línea. */
@media(max-width:760px){.claim .accent{display:block}}
/* --- .claim-sub — la frase que remata el bloque. Desde el 2-ago va
   DEBAJO del video (antes iba entre el claim y él), así que su margen
   ya no se mide contra la frase grande sino contra una pieza con borde
   y sombra: 1.75rem, moderado a propósito. Queda por debajo del clamp
   que separa el video del claim (2.25-3.25rem) para que la jerarquía se
   lea sola —el video abre hueco, la frase se queda pegada a él como
   cierre— en vez de flotar a medio camino entre las dos piezas.

   Comparte además la caja del video (54rem, `margin-inline:auto`): al ir
   debajo de un bloque centrado y más estrecho que el contenedor, la
   frase a ancho completo arrancaba descolgada a la izquierda del borde
   del video. Con la misma medida los dos bordes coinciden y el pie lee
   como parte de la pieza. Logical, así el árabe se espeja solo. --- */
.claim-sub{margin-block-start:1.75rem; max-inline-size:54rem;
  margin-inline:auto; color:var(--ink-2);
  font-size:clamp(1rem,1.3vw,1.125rem); line-height:1.5}

/* --- .claim-video — el porqué de VULKRON, en video, justo debajo del
   claim. No estrena superficie: toma el radio en clamp de `.bento-card`
   y la elevación sobria de `.side--primary` / `.tier.feat`, la misma que
   ya usan las piezas destacadas del sistema. Ancho contenido (54rem,
   frente a las 75rem del contenedor) y `margin-inline:auto` — logical,
   así el árabe se espeja solo: el bloque queda centrado y no le disputa
   el peso a la frase grande.

   El `aspect-ratio` reserva el hueco 16:9 antes de que el póster cargue,
   de modo que la sección no salta. En reposo lo único que se ve es esa
   imagen fija: no hay movimiento que reducir y `prefers-reduced-motion`
   no tiene nada que hacer aquí.

   El archivo se sustituye sin tocar código mientras conserve la
   proporción 16:9 (`img/porque.mp4` + `img/porque-poster.webp`). Si el
   video definitivo no fuese 16:9, hay que ajustar aquí el
   `aspect-ratio` y los atributos width/height del <video>.

   El foco del teclado invierte su offset: el `overflow:hidden` del
   contenedor recorta todo lo que se pinte fuera del video, y el anillo
   global se dibuja 2px POR FUERA, justo en la zona recortada. Con
   offset negativo el mismo anillo —igual color, igual grosor— se
   dibuja por dentro y sigue viéndose. --- */
.claim-video{margin-block-start:clamp(2.25rem,4vw,3.25rem);
  max-inline-size:54rem; margin-inline:auto;
  border:1px solid var(--line); border-radius:clamp(14px,1.6vw,22px);
  background:var(--raised); overflow:hidden;
  box-shadow:0 0 0 1px rgba(90,125,158,.12), 0 18px 50px rgba(0,0,0,.35)}
.claim-video video{display:block; inline-size:100%; block-size:auto;
  aspect-ratio:16/9; background:#000}
.claim-video video:focus-visible{outline-offset:-3px}

/* --- .sum-top — el resumen abre con titular a la izquierda y el
   diagrama de convergencia a la derecha: el diagrama deja de ser un
   bloque apilado (alto) y pasa a ocupar el aire del titular. --- */
.sum-top{display:grid; gap:clamp(1.75rem,4vw,3.5rem); align-items:center}
@media(min-width:960px){.sum-top{grid-template-columns:1fr 1.1fr}}
/* La figura ya no necesita su respiro superior: la columna se lo da. */
.sum-top .frag-figure{margin-block-start:0}

/* --- .sum-notes — el resumen cierra con UNA sola nota al pie (el
   deslinde de organismos y estándares), en el registro tipográfico más
   bajo. La franja ocupa el ancho completo: el hairline que la abre es lo
   que la separa del resumen. La nota no: desde 860px lleva medida de
   lectura, en `ch` sobre su propia letra, para que la línea no se estire
   a lo ancho del contenedor. Por debajo de 860px la nota sigue ocupando
   todo el ancho, igual que antes. --- */
.sum-notes{margin-block-start:clamp(2rem,4vw,2.75rem);
  padding-block-start:1.5rem; border-block-start:1px solid var(--line);
  display:grid; gap:1rem}
.sum-notes p{margin:0; color:var(--ink-3);
  font-size:.85rem; line-height:1.6}
@media(min-width:860px){.sum-notes p{max-inline-size:80ch}}

/* --- .briefs / .brief — las cuatro entradas de profundidad
   (Prevención · C-TPAT · Criterios · STUDY) en una rejilla de
   tarjetas-enlace. Las separaciones son el propio `gap:1px` sobre el
   color de línea: retícula de hairlines, sin bordes dobles. --- */
.briefs{display:grid; gap:1px; margin-block-start:0;
  background:var(--line); border:1px solid var(--line)}
@media(min-width:820px){.briefs{grid-template-columns:1fr 1fr}}
.brief{display:flex; flex-direction:column; background:var(--canvas);
  padding:clamp(1.75rem,3.2vw,2.75rem); transition:background .2s}
a.brief:hover{background:var(--raised)}
.brief h2{font-family:var(--display); font-weight:700;
  font-size:clamp(1.35rem,2.2vw,1.75rem); line-height:1.14;
  letter-spacing:-.02em; text-wrap:balance; max-inline-size:24ch}
.brief h2 .steel{color:var(--steel-400)}
.brief p{margin-block-start:1rem; color:var(--ink-2);
  font-size:.94rem; line-height:1.6; max-inline-size:48ch}
/* El enlace se ancla abajo: las cuatro tarjetas alinean su salida. */
.brief .go{display:block; margin-block-start:auto; padding-block-start:1.75rem;
  font-size:.88rem; font-weight:600; color:var(--steel-400); transition:color .2s}
a.brief:hover .go{color:var(--steel-300)}

/* --- .cta-strip — el cierre en UNA tira: frase y botón en la misma
   línea; en móvil se apila y el botón toma el ancho. --- */
.cta-strip{border-block-start:1px solid var(--line);
  background:linear-gradient(100deg,#15202d 0%, #0a0a0a 68%)}
.cta-strip > .container{display:flex; flex-wrap:wrap; align-items:center;
  justify-content:space-between; gap:1.25rem clamp(1.5rem,4vw,3rem);
  padding-block:clamp(2rem,4vw,2.75rem)}
.cta-strip-tx{font-family:var(--display); font-weight:600;
  font-size:clamp(1.3rem,2.6vw,2rem); line-height:1.14;
  letter-spacing:-.02em; text-wrap:balance; max-inline-size:28ch}
.cta-strip-tx .steel{color:var(--steel-400)}
.cta-strip .btn{flex:none}
@media(max-width:719px){
  .cta-strip > .container{flex-direction:column; align-items:stretch}
  .cta-strip .btn{inline-size:100%}
}
/* RTL: el degradado es direccional (los grados no se voltean con dir). */
[dir="rtl"] .cta-strip{background:linear-gradient(260deg,#15202d 0%, #0a0a0a 68%)}

/* ------------------------------------------------------------
   10 · .bento — la rejilla de dominios (`index.html#dominios`)
   Decisión del cliente (31-jul, con captura de referencia): la sección
   pasa del par de tarjetas con BORDE a una rejilla bento de SUPERFICIE
   —relleno oscuro elevado y esquina generosa, sin contorno de línea—,
   con tamaños mixtos y una fotografía dentro de las dos tarjetas
   grandes. Adaptado a la marca: paleta steel/negro y las dos familias
   de siempre (Archivo en el titular, Plex Sans en el cuerpo).

   Reparto (≥900px, rejilla de 6 columnas):
     fila 1 → Fire Protection (4) + cifra de incendios (2)
     fila 2 → cifra de riesgo eléctrico (2) + Electrical Safety (4)
   Las dos tarjetas grandes son ENLACE COMPLETO (patrón `.brief`).

   Las dos celdas menores CAMBIARON el 1-ago por decisión del cliente:
   donde antes había texto reutilizado del sitio, ahora va un DATO DEL
   SECTOR con su fuente —del mismo género que la banda «El costo de no
   prevenir ya está medido.»—, para que el costo de no prevenir empuje a
   entrar al dominio que lo gobierna. Consecuencias de esa decisión:
     · Sólo existen en ESCRITORIO (≥900px). Por debajo se ocultan por
       completo: en una columna, dos cifras intercaladas entre las dos
       tarjetas de dominio rompen la lectura del par, y el móvil ya
       recibe las cifras del sector en la banda que viene enseguida.
       Al ocultarse con `display:none` salen de la rejilla —no dejan
       hueco— y el `order` que las mandaba al final sobra: se retiró.
     · Cada celda cierra con un enlace de texto a SU dominio. Es la
       única navegación nueva: la celda entera NO es enlace, para que
       una cifra de tercero con atribución visible no se comporte como
       tarjeta promocional de VULKRON. El enlace no repite el CTA
       principal del sitio («Verlo en acción» → registro.html).
     · La atribución (organismo + año) vive DENTRO de la celda, en
       `.bento-src`: el dato jamás debe leerse como métrica de VULKRON.
       Ambas cifras y sus sub-claims quedaron verificados contra fuente
       primaria el 1-ago: NFPA, «Fire Loss in the United States During
       2024» (nov-2025), y la página de estadística de ESFI con datos
       de la BLS (dato 2023–2024, publicado en 2026).
   El número usa mono porque es una cifra —el único uso permitido—, y
   se queda en la superficie steel de la celda: no se clona la banda
   clara `.section--invert`.

   Reglas heredadas respetadas: sin kickers de categoría, sin palomitas,
   sin flechas en el enlace, sin mono decorativo, sin sombra difusa —la
   elevación la da la SUPERFICIE (#161616 sobre #0a0a0a), no un halo—.
   Motion: sólo transiciones de hover; el deslizamiento de entrada lo
   sigue haciendo `.reveal` desde app.js.
   RTL: rejilla con `span` y propiedades lógicas → se espeja sola; el
   degradado del velo es vertical (180deg) y las cifras van en dígitos
   occidentales con `tabular-nums`, igual que la banda → sin overrides.
   (Queda abajo un `[dir="rtl"] .bento-ico--conv` de una variante de
   ícono que ya no está en el HTML: inerte, anotado como residuo.)
   ------------------------------------------------------------ */
.bento{display:grid; grid-template-columns:1fr;
  gap:clamp(.85rem,1.5vw,1.15rem);
  margin-block-start:clamp(2.25rem,4vw,3rem)}
/* Móvil y tablet (una columna): sólo los dos dominios. Las celdas de
   cifra se ocultan —no se reordenan— y la rejilla queda de dos filas.
   Va por el hijo directo (`.bento >`) a propósito: `.bento-card` fija
   `display:flex` MÁS ABAJO en el archivo y, a igual especificidad,
   ganaría la última. */
.bento > .bento-card--nota{display:none}
@media(min-width:900px){
  .bento{grid-template-columns:repeat(6,1fr)}
  .bento-card--dom{grid-column:span 4}
  .bento > .bento-card--nota{display:flex; grid-column:span 2}
}

/* La tarjeta. `isolation:isolate` la vuelve contexto de apilamiento
   propio: así la franja fotográfica (z-index:-1) queda POR ENCIMA del
   relleno de la tarjeta y por debajo del texto, sin tocar el z-index
   de la sección. */
.bento-card{position:relative; isolation:isolate; overflow:hidden;
  display:flex; flex-direction:column;
  border-radius:clamp(14px,1.6vw,22px);
  background:var(--raised);
  padding:clamp(1.6rem,2.8vw,2.75rem);
  overflow-wrap:break-word}
.bento-card--dom{min-block-size:clamp(22rem,30vw,27rem)}
/* Las celdas menores llevan el tinte steel del sistema (mismo azul
   industrial de `.section--steel`), que las distingue de las dos
   tarjetas de dominio sin subir el brillo. */
.bento-card--nota{background:linear-gradient(180deg,#141a22 0%, #101318 100%)}

/* Hover del enlace: un velo uniforme sobre TODA la tarjeta —foto
   incluida—. Aclarar el fondo en vez del velo abriría una costura
   visible justo donde el relleno se funde con la fotografía. */
a.bento-card::after{content:""; position:absolute; inset:0; z-index:-1;
  pointer-events:none; background:rgba(255,255,255,0); transition:background .22s}
a.bento-card:hover::after{background:rgba(255,255,255,.04)}

/* --- Franja fotográfica: se ancla al fondo de la tarjeta y se funde
   hacia arriba con el propio relleno. Altura en clamp (nunca en %):
   la tarjeta crece con su contenido y un porcentaje dependería de una
   altura que no siempre es definida. --- */
.bento-media{position:absolute; inset-inline:0; inset-block-end:0; z-index:-1;
  block-size:clamp(10rem,24vw,15rem); overflow:hidden; pointer-events:none}
/* Las fotos de planta son casi negras: un realce corto de brillo las
   hace legibles dentro de la tarjeta sin lavar los negros. El encuadre
   baja al 72% porque el equipo (bombas, transformadores) vive en el
   tercio inferior de ambas tomas. */
.bento-media img{inline-size:100%; block-size:100%; object-fit:cover;
  object-position:50% 72%; filter:brightness(1.35) contrast(1.02);
  transform:scale(1.01); transition:transform .5s var(--ease)}
a.bento-card:hover .bento-media img{transform:scale(1.05)}
@media(prefers-reduced-motion:reduce){
  .bento-media img{transition:none}
  a.bento-card:hover .bento-media img{transform:scale(1.01)}
}
/* Velo: arranca en el color EXACTO del relleno (empalme invisible),
   deja ver la foto en la franja media y vuelve a cerrarse abajo, que es
   donde se apoyan las etiquetas y el enlace. */
.bento-veil{position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(180deg,
    var(--raised) 0%,
    rgba(22,22,22,.88) 18%,
    rgba(14,14,14,.62) 40%,
    rgba(10,10,10,.46) 62%,
    rgba(10,10,10,.80) 100%)}

/* --- Contenido. `position:relative` es sólo un seguro: el contenido en
   flujo ya pinta por encima de un hijo con z-index negativo. --- */
.bento-tope{position:relative}
.bento-ico{display:block; inline-size:1.75rem; block-size:1.75rem;
  color:var(--steel-400)}
[dir="rtl"] .bento-ico--conv{transform:scaleX(-1)}

.bento-card h3{margin-block-start:1.1rem; font-family:var(--display);
  font-weight:700; letter-spacing:-.025em; line-height:1.06; text-wrap:balance}
.bento-card--dom h3{font-size:clamp(1.85rem,3vw,2.6rem)}
.bento-sub{margin-block-start:.5rem; color:var(--ink-3); font-size:.85rem}
.bento-tx{margin-block-start:1.15rem; color:var(--ink-2);
  font-size:.95rem; line-height:1.6; max-inline-size:42ch}

/* --- El dato del sector dentro de la celda menor. Mismo orden de
   lectura que la banda de cifras (número → etiqueta → fuente), pero
   sobre la superficie steel: el número queda en tinta plena y la
   atribución baja a `--ink-3`, sin línea divisoria (aquí el contorno
   lo da la propia celda). El número NO es encabezado: es un dato, y
   los únicos h3 de la sección siguen siendo los de los dominios. --- */
.bento-num{font-family:var(--mono); font-weight:600;
  font-size:clamp(2.2rem,3.6vw,3rem); line-height:.9;
  letter-spacing:-.02em; font-variant-numeric:tabular-nums}
.bento-lbl{margin-block-start:1.1rem; font-weight:600;
  font-size:.9rem; line-height:1.4; max-inline-size:26ch;
  text-wrap:balance}
.bento-src{margin-block-start:.55rem; color:var(--ink-3);
  font-size:.78rem; line-height:1.55; max-inline-size:32ch}
/* Cierre de la celda: enlace de TEXTO al dominio (no la celda entera).
   Lleva subrayado —convención de enlace en texto del sitio, como
   `.post a`— porque fuera de una tarjeta-enlace el color solo no
   basta para leerlo como destino. Sin flecha. */
.bento-nota-go{display:inline-block; font-size:.9rem; font-weight:600;
  color:var(--steel-400); text-decoration:underline;
  text-underline-offset:3px; text-decoration-color:var(--steel-700);
  transition:color .2s, text-decoration-color .2s}
.bento-nota-go:hover{color:var(--steel-300);
  text-decoration-color:var(--steel-500)}

/* Pie: etiquetas y enlace anclados abajo, sobre la parte cerrada del
   velo. Las etiquetas son superficie translúcida (el mismo registro de
   la tarjeta), nunca viñeta ni palomita. */
.bento-pie{position:relative; margin-block-start:auto; padding-block-start:2rem}
.bento-chips{display:flex; flex-wrap:wrap; gap:.4rem}
.bento-chips span{padding:.32rem .62rem; border-radius:7px;
  background:rgba(255,255,255,.07); color:var(--ink-2);
  font-size:.78rem; line-height:1.35; white-space:nowrap}
.bento-go{margin-block-start:1.15rem; font-size:.9rem; font-weight:600;
  color:var(--steel-400); transition:color .2s}
a.bento-card:hover .bento-go{color:var(--steel-300)}

/* restauración post-rollback del rojo: acento steel del claim. El de las
   preguntas de audiencia vive en el bloque de `.caras`, con ellas. */
.claim .accent{color:var(--steel-400)}

/* ============================================================
   ===== ENTERPRISE (rediseño 3-ago-2026) =====
   Componentes de `enterprise.html` y las clases que sustituyen a
   los estilos INLINE que tenía la página. Nada se renombra ni se
   borra: esto sólo AÑADE.
   · Los bloques PRESERVADOS (#modelo, capacidades, blindaje,
     superuser) conservan su render EXACTO: cada clase de abajo
     reproduce, valor por valor, el inline que sustituye.
   · Propiedades LÓGICAS → el árabe se espeja solo; ningún
     componente de aquí necesita override en el bloque [dir="rtl"].
   · Motion: aquí viven dos cosas, y sólo dos — la transición del
     enlace del subnav (color y borde, .2s) y los retardos que
     escalonan la cascada de las tres rejillas narrativas. El
     deslizamiento en sí sigue siendo `.reveal` (app.js), y el
     parallax de la banda `.chp` también. Nada de esto oculta texto.
   ============================================================ */

/* --- Alturas del chrome pegajoso. Son VALORES DE RESPALDO que
   coinciden con la altura real de cada barra; el módulo de app.js las
   remide con getBoundingClientRect y las reescribe en :root, para que
   el ancla nunca quede por debajo de la barra (tipografías o zoom
   distintos). El `+1px` de `--nav-h` es el `border-bottom` del `.nav`:
   sin él, el primer píxel del subnav quedaría por debajo de una barra
   translúcida y se vería el hairline cruzarlo al hacer scroll. --- */
:root{--nav-h:calc(4rem + 1px); --pagenav-h:3.25rem}

/* --- 2 · .pagenav — subnav interno de la página, pegajoso BAJO el
   nav del sitio. Son ENLACES DE ANCLA, no un menú: sin aria-haspopup,
   sin desplegable. Va en el flujo (no absoluto), así que al fijarse no
   provoca salto de layout. En móvil la fila hace su propio scroll
   horizontal: el desbordamiento vive en la lista, nunca en el body.
   El estado activo lo pone app.js (`is-active` + `aria-current`); sin
   JS la barra sigue siendo un índice navegable, sólo sin resaltado. --- */
.pagenav{position:sticky; inset-block-start:var(--nav-h); z-index:90;
  background:color-mix(in srgb,var(--canvas) 92%,transparent);
  backdrop-filter:blur(14px);
  border-block-end:1px solid var(--line)}
.pagenav-list{display:flex; align-items:stretch; list-style:none;
  overflow-x:auto; overscroll-behavior-inline:contain;
  scrollbar-width:none; -ms-overflow-style:none}
.pagenav-list::-webkit-scrollbar{display:none}
.pagenav-link{display:inline-flex; align-items:center; white-space:nowrap;
  padding:.9rem .85rem; font-size:.85rem; font-weight:500; color:var(--ink-2);
  border-block-end:2px solid transparent;
  transition:color .2s, border-color .2s}
.pagenav-link:hover{color:#fff}
.pagenav-link.is-active{color:#fff; border-block-end-color:var(--steel-400)}
.pagenav-link:focus-visible{outline-offset:-2px}
/* Por debajo de ~760px la fila de seis ya no cabe en el ancho útil del
   `.container` en todos los idiomas (el francés y el árabe son los más
   largos), así que ahí scrollea de BORDE A BORDE: el sangrado del
   `.container` pasa a la lista (padding + scroll-padding), y así el
   primer y el último enlace se alcanzan enteros y no quedan cortados
   contra el filo de la pantalla. Sin scroll el aspecto es idéntico —el
   sangrado es el mismo—, sólo cambia hasta dónde puede desplazarse.
   Como es padding lógico, en árabe el scroll arranca por la derecha sin
   ningún override. */
@media(max-width:760px){
  .pagenav .container{padding-inline:0}
  .pagenav-list{padding-inline:clamp(1.25rem,4vw,2.5rem);
    scroll-padding-inline:clamp(1.25rem,4vw,2.5rem);
    -webkit-mask-image:linear-gradient(to right,transparent,#000 1.25rem,#000 calc(100% - 1.25rem),transparent);
    mask-image:linear-gradient(to right,transparent,#000 1.25rem,#000 calc(100% - 1.25rem),transparent)}
}
/* Teléfono: la fila se aprieta un punto para que quepan más enlaces. */
@media(max-width:600px){
  .pagenav-link{padding-inline:.7rem; font-size:.82rem}
}

/* Destinos de las anclas: se apartan de la barra fija (nav + subnav). */
.pn-target{scroll-margin-block-start:calc(var(--nav-h) + var(--pagenav-h))}

/* --- 3 · .stmts / .stmt — los tres enunciados del bloque del riesgo.
   Fila de tres en escritorio, columna en móvil; hairline de registro
   arriba de cada uno y, en el tercero —el que cierra el argumento—,
   la línea en steel. Sin numeración y sin viñeta. --- */
.stmts{display:grid; gap:0; margin-block-start:3rem}
.stmt{border-block-start:1px solid var(--line-strong); padding-block:1.5rem;
  font-family:var(--display); font-weight:600;
  font-size:clamp(1.15rem,1.9vw,1.45rem); line-height:1.25;
  letter-spacing:-.015em; color:var(--ink); text-wrap:balance}
.stmts .stmt:last-child{border-block-start-color:var(--steel-600)}
@media(min-width:820px){
  .stmts{grid-template-columns:repeat(3,1fr)}
  .stmt{padding-inline-end:2rem}
  .stmt + .stmt{padding-inline-start:2rem; border-inline-start:1px solid var(--line)}
  .stmts .stmt:last-child{padding-inline-end:0}
}

/* --- 6 · .momentos / .momento — el recorrido del mecanismo en tres
   momentos. Misma rejilla de tres que `.stmts`, pero con título y
   cuerpo: la marca steel de arriba es una regla corta (no viñeta) que
   señala el arranque de cada momento. --- */
.momentos{display:grid; gap:0; margin-block-start:3rem}
.momento{border-block-start:1px solid var(--line); padding-block:1.75rem}
.momento::before{content:""; display:block; inline-size:2.25rem; block-size:2px;
  background:var(--steel-500); margin-block-end:1.25rem}
.momento h3{font-size:1.15rem; letter-spacing:-.015em; text-wrap:balance}
.momento p{margin-block-start:.75rem; color:var(--ink-2);
  font-size:.95rem; line-height:1.65}
@media(min-width:900px){
  .momentos{grid-template-columns:repeat(3,1fr)}
  .momento{padding-inline-end:2.25rem}
  .momento + .momento{padding-inline-start:2.25rem; border-inline-start:1px solid var(--line)}
  .momentos .momento:last-child{padding-inline-end:0}
}

/* --- 9 · .pasos / .paso — los tres pasos del arranque. Ledger
   editorial de dos columnas (título | cuerpo), deliberadamente
   distinto de la rejilla de tres del recorrido: aquí el orden es una
   secuencia, no tres vistas del mismo mecanismo. Sin folios «0N». --- */
.pasos{margin-block-start:2.5rem; max-inline-size:60rem}
.paso{display:grid; gap:.5rem 2.5rem; border-block-start:1px solid var(--line);
  padding-block:1.75rem}
.pasos > .paso:last-child{border-block-end:1px solid var(--line)}
.paso h3{font-size:1.15rem; letter-spacing:-.015em}
.paso p{color:var(--ink-2); font-size:.95rem; line-height:1.65; max-inline-size:56ch}
@media(min-width:760px){
  .paso{grid-template-columns:16rem 1fr; align-items:baseline}
}

/* --- 9 bis · Ledger de definiciones de `#control` en enterprise
   (Activos · Rutinas · Criterio · Evidencia). El otro ledger editorial
   del rediseño, junto a `.pasos`: aquí la anatomía es la de `.specs`
   (término | definición), y sólo se ajusta la caja. Misma medida que
   la `.side--wide` que le sigue, para que el bloque y la tarjeta
   compartan borde óptico. Propiedades lógicas: se espeja solo en RTL,
   sin override. --- */
.specs--control{margin-block-start:2.5rem; max-inline-size:60rem}

/* --- Cascada de las tres rejillas narrativas. El `.reveal` vive ahora
   en cada pieza (no en el contenedor): las tres intersectan en el mismo
   fotograma y el retardo las escalona 90 ms. La transición sigue siendo
   sólo `transform`, y con `prefers-reduced-motion` la regla global de
   `.reveal` (transition:none) anula la transición entera, de modo que
   estos retardos quedan inertes. --- */
.stmt.reveal:nth-child(2),.momento.reveal:nth-child(2),.paso.reveal:nth-child(2){transition-delay:.09s}
.stmt.reveal:nth-child(3),.momento.reveal:nth-child(3),.paso.reveal:nth-child(3){transition-delay:.18s}
.stmt.reveal:nth-child(4),.momento.reveal:nth-child(4),.paso.reveal:nth-child(4){transition-delay:.27s}

/* --- Prosa secundaria de sección: el párrafo que sigue al `lede`
   (bloque del riesgo) o el que hace de puente al CTA (arranque). Un
   escalón por debajo del `lede` y por encima de `.side-note`. --- */
.sec-p{margin-block-start:1.25rem; max-inline-size:44rem;
  color:var(--ink-2); font-size:1rem; line-height:1.7}
.sec-p--gap{margin-block-start:2.5rem}

/* --- Clases que sustituyen a los estilos INLINE de la página. Los
   valores son los mismos que traía el HTML: el render de los bloques
   preservados no cambia. --- */
.section-head--wide{max-inline-size:56rem}
.side--wide{max-inline-size:60rem; margin-block-start:2.5rem}
.side--wide .muted{margin-block-start:.9rem}
.side-note--lead{max-inline-size:56rem; margin-block-start:1.5rem}
.side-note--rule{margin-block-start:1.25rem; padding-block-start:1rem;
  border-block-start:1px solid var(--steel-700)}
.tiers--modelo{margin-block-start:3rem}
.specs--modelo{margin-block-start:3rem; max-inline-size:60rem}
.tier .inc--lead{color:var(--ink); font-weight:600; font-size:1.0625rem; line-height:1.5}
/* Lista de capacidades a hairlines (la misma anatomía que `.tier li`,
   fuera de una tarjeta). NUNCA palomitas ni viñetas de punto. */
.pts--flat{list-style:none; margin-block-start:1.25rem; padding:0}
.pts--flat li{border-block-start:1px solid var(--line); padding-block:.55rem;
  font-size:.88rem; color:var(--ink-2)}

/* ============================================================
   LANDING DEL FOLLETO DE EXPO (`expo123.html`, destino del QR impreso).
   Piezas propias `exp-*`: la franja de idioma que abre la página, el
   lockup de portada y tres ajustes de espaciado que en la home viajaban
   como estilo inline. Todo lo demás reusa el sistema (section--*, specs,
   gauges, pasos, side, cta-strip). Sin reglas direccionales: el bloque
   [dir="rtl"] no necesita override aquí.
   OJO con el prefijo: `.paper .exp-wrap` y `table.exp` (más arriba, y su
   override RTL) son del EXPEDIENTE de fire-protection.html, no de esta
   landing. Van namespaced con `.paper`, así que no colisionan.
   ============================================================ */

/* Franja de idioma: lo primero de la página, porque quien llega escaneó
   el QR multilingüe del folleto. Los botones NO traducen (van con
   data-no-i18n): el nombre nativo es lo que el visitante reconoce.
   El borde va en `--steel-700`, igual que `.nav-switch`: sobre `--raised`
   un borde `--line` da 1.15:1 y los cinco idiomas se leerían como una
   lista de texto, no como botones —y en táctil no hay hover que lo
   rescate—. `.is-active` marca el idioma aplicado (lo sincroniza el
   módulo [data-langstrip] de app.js), con el mismo par color/fondo que
   `.lang-opt.is-active` del menú del nav. */
.exp-lang{border-block-end:1px solid var(--line); background:var(--raised)}
.exp-lang > .container{display:flex; flex-wrap:wrap; align-items:center;
  gap:.5rem .9rem; padding-block:.7rem}
.exp-lang-tx{font-size:.85rem; color:var(--ink-2)}
.exp-lang-list{display:flex; flex-wrap:wrap; gap:.4rem; list-style:none;
  margin:0; padding:0}
.exp-lang-btn{font-family:var(--sans); font-size:.85rem; line-height:1.2;
  color:var(--ink-2); background:transparent; border:1px solid var(--steel-700);
  border-radius:3px; padding:.4rem .7rem; cursor:pointer;
  transition:color .12s var(--ease), border-color .12s var(--ease), background .12s var(--ease)}
.exp-lang-btn:hover{color:#fff; border-color:var(--steel-500); background:rgba(255,255,255,.05)}
.exp-lang-btn.is-active{color:#fff; border-color:var(--steel-500); background:var(--steel-700)}

/* Portada: gancho + lockup de marca (wordmark, descriptor de categoría y
   los dos dominios separados por la regla vertical del sistema). */
.exp-hero .sec-bg{opacity:.26; object-position:50% 26%}
.exp-lockup{margin-block-start:2.25rem; padding-block-start:1.75rem;
  border-block-start:1px solid var(--steel-700)}
.exp-wordmark{font-family:var(--display); font-weight:700;
  font-size:clamp(1.5rem,3vw,2.1rem); letter-spacing:.06em; line-height:1}
.exp-descriptor{margin-block-start:.6rem}
.exp-dominios{margin-block-start:.9rem; font-size:.8rem; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase; color:var(--steel-400)}

/* Cifras y cierre. Esta página se lee sobre todo en teléfono (se llega
   escaneando un QR) y son TRES cifras: en móvil van en una columna, que
   es donde el borde de `.gauge + .gauge` cae bien. Desde 768px hereda las
   tres columnas de `.gauges`, que es la lectura que pide el folleto. */
.exp-gauges{margin-block-start:2rem}
@media (max-width:767.98px){ .exp-gauges{grid-template-columns:1fr} }
.exp-claim{margin-block-start:1.5rem; font-family:var(--display);
  font-weight:600; font-size:clamp(1.05rem,1.8vw,1.35rem); line-height:1.35}
.exp-fuentes{margin-block-start:1.25rem; font-size:.82rem; max-inline-size:48rem}
.exp-contacto{margin-block-start:1.5rem; display:flex; flex-wrap:wrap;
  align-items:center; font-size:.9rem; color:var(--ink-2)}

/* ---- Barra de partes (14-ago): VULKRON | VULKRON STUDY.
   Delgada, sobre el nav, NO pegajosa (el nav conserva sticky top:0
   intacto, estilo.css:89). Propiedades lógicas → RTL solo. ---- */
.partes{background:var(--surface); border-bottom:1px solid var(--line)}
.partes .container{display:flex; align-items:stretch; gap:.25rem; height:2.25rem}
.partes-item{display:inline-flex; align-items:center; padding-inline:.85rem;
  font-family:var(--sans); font-size:12px; font-weight:600; letter-spacing:.08em;
  color:var(--ink-3); transition:color .15s}
.partes-item:hover{color:var(--ink)}
.partes-item:focus-visible{outline-offset:-2px}
.partes-item.is-active{color:#fff; box-shadow:inset 0 -2px 0 var(--steel-400)}
@media(max-width:999.98px){.partes .container{height:2rem; gap:0}
  .partes-item{font-size:11px; padding-inline:.6rem}}
