/* PacificKali — sistema de diseño (v3, 2026-10-18: corregido con capturas
   REALES de las referencias — la v2 asumía "ciberseguridad = todo oscuro",
   un cliché propio, no sacado de ninguna referencia real. Capturas reales
   de Kilowatty (fondo claro gris-celeste, acento dorado solido) y Gamma
   Ingenieros — el competidor mas directo — (fondo BLANCO en todo el
   cuerpo, hero oscuro con foto real + overlay, rojo solido como acento,
   cifras grandes y bold, nav CLARO con boton solido) muestran que el
   patron real y probado es: hero oscuro como momento dramatico + resto
   del sitio en claro, colores solidos y vivos (no gradientes sutiles
   sobre fondo oscuro). Se corrige a ese patron.
   Tipografia: Sora (titulos) + IBM Plex Sans (cuerpo) + IBM Plex Mono
   (cifras/datos) — sin cambios, eso no era el problema. */

:root{
  /* Tema CLARO — default para todo el sitio fuera del hero */
  --page-bg:    #f5f6fc;
  --ink:        #11152b;
  --surface:    #ffffff;
  --surface-2:  #eef0fa;
  --line:       rgba(17,21,43,.10);
  --text:       #171c35;
  --text-dim:   #5b6180;
  --violet:     #7c3aed;
  --violet-soft:#6d28d9;
  --cyan:       #0891b2;
  --cyan-soft:  #0e7490;
  --amber:      #7c3aed;       /* alias retrocompat */
  --amber-soft: #6d28d9;
  --ocean:      #0891b2;       /* alias retrocompat */
  --ocean-soft: #0e7490;
  --ok:         #059669;
  --warn:       #d97706;
  --crit:       #e11d48;
  --grad: linear-gradient(120deg, var(--violet), var(--cyan));
  --radius:     14px;
  --radius-sm:  9px;
  --max:        1180px;
  --font-display: "Sora", ui-sans-serif, system-ui, sans-serif;
  --font-body:    "IBM Plex Sans", ui-sans-serif, system-ui, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "Courier New", monospace;
  --shadow: 0 20px 50px rgba(17,21,43,.10);
}

/* Hero: unico tramo oscuro del sitio (mismo patron que Gamma Ingenieros) —
   redefine los MISMOS tokens solo dentro de este scope, asi cada
   componente que ya usa var(--surface)/var(--text)/etc (cards, botones,
   el diagrama de capas) hereda automaticamente la version oscura sin
   duplicar ni una sola regla. */
.hero, .darkBand{
  --page-bg:   #0a0e1c;
  --ink:       #0a0e1c;
  --surface:   #141a33;
  --surface-2: #1d2650;
  --line:      rgba(205,214,255,.14);
  --text:      #eef1ff;
  --text-dim:  #a6addc;
  --violet-soft:#b79bff;
  --amber-soft: #b79bff;
  --cyan-soft: #7fe8f7;
  --ocean-soft: #7fe8f7;
  --ok:        #22e5a8;
  --crit:      #ff4d6d;
  --shadow: 0 20px 50px rgba(3,10,16,.45);
  /* BUG real encontrado con captura: redefinir las variables no alcanza —
     sin esto el fondo oscuro nunca se pinta, se transparenta el --page-bg
     claro del body de atras. */
  background:var(--ink); color:var(--text);
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto;} }
body{
  margin:0; background:var(--page-bg); color:var(--text);
  font-family:var(--font-body); line-height:1.55; -webkit-font-smoothing:antialiased;
}
img{max-width:100%; display:block;}
a{color:inherit; text-decoration:none;}
.container{max-width:var(--max); margin:0 auto; padding:0 20px;}
.pad{padding:84px 0;}
.pad-sm{padding:48px 0;}
h1,h2,h3{font-family:var(--font-display); line-height:1.15; margin:0; text-wrap:balance;}
h1{font-size:clamp(34px,5.4vw,58px); font-weight:700;}
h2{font-size:clamp(26px,3.6vw,38px); font-weight:700;}
h3{font-size:19px; font-weight:600;}
p{margin:0;}
.eyebrow{
  font-family:var(--font-mono); font-size:12px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--amber-soft);
}
.lead{font-size:18px; color:var(--text-dim); max-width:640px;}
.mono{font-family:var(--font-mono);}
.srOnly{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;}

.btn{
  display:inline-flex; align-items:center; gap:8px; padding:13px 22px; border-radius:999px;
  font-weight:600; font-size:15px; border:1px solid transparent; cursor:pointer;
  transition:transform .15s ease, box-shadow .15s ease;
}
/* BUG real visto en captura: el atributo [hidden] y .btn{display:inline-flex}
   tienen la misma especificidad — como estilo.css carga despues, .btn gana
   y el boton "oculto" queda visible igual. */
.btn[hidden]{display:none;}
.btnArrow{display:inline-block; transition:transform .25s cubic-bezier(.3,1.5,.5,1);}
.btn-primary{background:var(--violet); color:#ffffff; box-shadow:0 10px 30px rgba(124,58,237,.3);}
.btn-outline{background:transparent; border-color:var(--line); color:var(--text);}
/* 2026-10-18 (hallazgo real): los :hover de movimiento solo deberian aplicar
   en dispositivos que de verdad tienen hover (mouse/trackpad) — en celular,
   un tap dispara :hover y queda "pegado" hasta tocar otra cosa, un glitch
   visual real que no existe en ninguna de las referencias que vimos bien
   hechas. Los hover de solo color (links de nav, footer) se dejan afuera de
   este guard — ahi quedarse "pegado" un momento no es un problema visible. */
@media (hover: hover) and (pointer: fine){
  .btn:hover{transform:translateY(-2px);}
  .btn-primary:hover{box-shadow:0 14px 34px rgba(124,58,237,.42); background:#6d28d9;}
  .btn-outline:hover{box-shadow:0 8px 20px rgba(17,21,43,.08); border-color:var(--amber-soft);}
  .btn:hover .btnArrow{transform:translateX(4px);}
}
.btn-sm{padding:9px 16px; font-size:13px;}

.navbar{
  position:sticky; top:0; z-index:50; backdrop-filter:blur(10px);
  background:rgba(255,255,255,.88); border-bottom:1px solid var(--line);
}
.navbar .container{display:flex; align-items:center; justify-content:space-between; height:68px;}
.navbrand{font-family:var(--font-display); font-weight:700; font-size:19px; display:flex; align-items:center; gap:9px; color:var(--text);}
.brandMark{width:21px; height:21px; flex-shrink:0;}
.navlinks{display:flex; gap:26px; font-size:14px; font-weight:600;}
.navlinks a{color:var(--text-dim);}
.navlinks a:hover{color:var(--text);}
.navcta{display:flex; align-items:center; gap:14px;}
.navToggle{display:none; background:none; border:0; color:var(--text); font-size:22px;}

.hero{padding:70px 0 50px; position:relative; overflow:hidden;}
.heroGrid{display:grid; grid-template-columns:1.05fr .95fr; gap:54px; align-items:start; position:relative; z-index:1;}
/* 2026-10-20 (auditoria, medido a 13 anchos distintos): antes esto era
   min-height:4.4em para evitar el salto de layout entre frases. Evitaba el
   salto, si, pero reservando SIEMPRE el peor caso imaginable: a 1280px
   reservaba 255px cuando la frase mas alta mide 133px, y a 900px reservaba
   214px cuando la mas alta mide 56px — entre 120 y 160px de hueco vacio
   entre el titular y el parrafo, visible en captura.
   Ahora las 4 frases se apilan en la MISMA celda de grid: la altura la fija
   la frase mas alta de verdad, sin salto y sin hueco. El JS alterna
   visibility (no display) justamente para que las ocultas sigan midiendo. */
.heroHeadline{display:grid;}
.heroHeadline .step{display:block; grid-area:1 / 1;}

/* Fondo: grilla tecnica sutil en movimiento + linea de "escaneo" — CSS puro,
   sin canvas ni libreria. Alusion a monitoreo/SOC sin ser literal. */
/* Foto real (servidor/data center, no una ilustracion) con degrade oscuro
   hacia el texto — mismo recurso que las 3 referencias reales que vimos
   con captura (Gamma, Absolute, WEBLife: foto real + overlay en el hero). */
.heroBg{
  position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:
    linear-gradient(100deg, rgba(10,14,28,.97) 0%, rgba(10,14,28,.93) 38%, rgba(10,14,28,.62) 72%, rgba(10,14,28,.35) 100%),
    url('/assets/img/hero-servers.jpg');
  background-size:cover, cover;
  background-position:center, center 30%;
  background-repeat:no-repeat;
}
.heroBg::before{
  content:""; position:absolute; inset:0;
  background-image:
    linear-gradient(rgba(139,92,246,.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(139,92,246,.07) 1px, transparent 1px);
  background-size:42px 42px;
  mask-image:linear-gradient(100deg, rgba(0,0,0,.9), transparent 70%);
}
.heroBg::after{
  content:""; position:absolute; left:0; right:0; height:120px; top:-120px;
  background:linear-gradient(180deg, transparent, rgba(139,92,246,.14), transparent);
  animation:scanDown 9s linear infinite;
}
@keyframes scanDown{ from{transform:translateY(0);} to{transform:translateY(760px);} }
@media (prefers-reduced-motion: reduce){ .heroBg::after{animation:none; display:none;} }

/* Badges bajo el H1, revelados en cascada (patron real de Tesla: cifras en
   grupo, cada una con su propio delay via --d, no todas a la vez). */
/* 2026-10-20: align-items:center centraba cada .stat segun su propia
   altura — como el texto debajo de cada numero envuelve distinto (1 a 3
   lineas), los 3 numeros grandes terminaban en alturas distintas entre si
   (hallazgo real de la auditoria, medido en pixeles). flex-start los
   alinea todos arriba, sin importar cuanto envuelva el texto de abajo. */
.heroStats{display:flex; gap:22px; margin-top:34px; flex-wrap:wrap; align-items:flex-start;}
.heroStats .stat{font-family:var(--font-mono); opacity:0; transform:translateY(10px); transition:opacity .5s ease, transform .5s ease; transition-delay:calc(var(--d,0) * 130ms);}
.heroStats.show .stat{opacity:1; transform:none;}
.heroStats .stat b{display:block; font-size:28px; font-family:var(--font-display); color:var(--violet-soft);}
.heroStats .stat span{font-size:12px; color:var(--text-dim); max-width:140px; display:block;}
.heroStats a.stat{transition-delay:calc(var(--d,0) * 130ms), none;}

/* Diagrama operable: pila de 6 capas en cascada (efecto de profundidad por
   desplazamiento, no cards de ancho igual) — esto ES la demo, no una foto. */
.heroStack{position:relative; padding-left:8px;}
.stackScore{font-family:var(--font-mono); font-size:13px; margin-bottom:16px; color:var(--text);}
.stackLayer{
  position:relative; margin-left:calc(var(--i) * 16px); margin-bottom:9px;
  background:var(--surface); border:1px solid var(--line); border-left:4px solid var(--crit);
  border-radius:10px; padding:13px 16px; cursor:pointer; display:flex; align-items:center; gap:10px;
  transition:border-color .25s ease, background .25s ease, transform .18s ease, box-shadow .25s ease;
}
@media (hover: hover) and (pointer: fine){ .stackLayer:hover{transform:translateX(5px);} }
.stackLayer.on{border-left-color:var(--cyan); background:var(--surface-2); box-shadow:0 8px 24px rgba(34,211,238,.15);}
.stackLayer:focus-visible{outline:2px solid var(--violet-soft); outline-offset:2px;}
.stackIcon{width:20px; height:20px; flex-shrink:0; color:var(--text-dim); transition:color .25s ease;}
.stackLayer.on .stackIcon{color:var(--cyan-soft);}
.cardIcon{
  width:23px; height:23px; color:var(--violet); margin-bottom:12px;
  padding:7px; box-sizing:content-box; background:#f0e9fe; border-radius:10px;
}
.cardIcon--cyan{color:var(--cyan); background:#e3f4f8;}
.stackLayer b{font-family:var(--font-display); font-size:15px; font-weight:600;}
.stackSub{font-size:12px; color:var(--text-dim); margin-left:auto;}
.stackLayer .dot{width:9px; height:9px; border-radius:50%; background:var(--crit); flex-shrink:0; animation:dotPulse 1.7s ease-in-out infinite;}
.stackLayer.on .dot{background:var(--ok); animation:none; box-shadow:0 0 0 4px rgba(76,175,125,.18);}
@keyframes dotPulse{0%,100%{box-shadow:0 0 0 0 rgba(217,83,79,.4);} 50%{box-shadow:0 0 0 6px rgba(217,83,79,0);}}
@media (prefers-reduced-motion: reduce){ .stackLayer .dot{animation:none;} }

.card{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:24px;
  transition:border-color .25s ease, transform .2s ease, box-shadow .25s ease;
}
@media (hover: hover) and (pointer: fine){
  .card:has(.cardIcon):hover{
    border-color:var(--violet); transform:translateY(-3px); box-shadow:0 14px 30px rgba(17,21,43,.1);
  }
  .card:has(.cardIcon):hover .cardIcon{transform:scale(1.08);}
}

/* 2026-10-18: se habia perdido esta regla en una edicion anterior — el JS
   del autodiagnostico seguia generando <div class="diagBar"><i></i></div>
   pero sin esto es un div vacio de 0px de alto, invisible. Encontrado
   mirando la captura real, no se habria notado solo leyendo el HTML. */
.diagBar{height:9px; border-radius:6px; background:var(--surface-2); overflow:hidden; border:1px solid var(--line);}
.diagBar i{display:block; height:100%; background:var(--violet); border-radius:6px; transition:width .4s ease;}
.cardIcon{transition:transform .25s ease;}
.grid{display:grid; gap:20px;}
.grid-2{grid-template-columns:repeat(2,1fr);}
.grid-3{grid-template-columns:repeat(3,1fr);}
.grid-4{grid-template-columns:repeat(4,1fr);}

.sectionHead{max-width:640px; margin-bottom:38px;}

/* Reveal al hacer scroll — IntersectionObserver, sin librerias */
.reveal{opacity:0; transform:translateY(16px); transition:opacity .6s ease, transform .6s ease;}
.reveal.show{opacity:1; transform:none;}
@media (prefers-reduced-motion: reduce){
  .reveal{opacity:1; transform:none; transition:none;}
}

/* 2026-10-18: antes dependia de un ancestro ".capa" que ya no existe (se
   reemplazo por ".stackLayer" al rehacer el hero) — las 9 tarjetas de
   servicio nunca recibian este estilo. De paso, mas peso visual: la
   investigacion encontro que los nombres de fabricantes van como texto gris
   chico cuando en las referencias reales (Gamma, Absolute) son la señal de
   legitimidad mas rapida para un MSSP nuevo — se suben de tamaño y color. */
.powered{font-family:var(--font-mono); font-size:13px; font-weight:600; color:var(--violet); margin-top:10px; letter-spacing:.01em;}
.card:has(.cardIcon--cyan) .powered{color:var(--cyan);}

/* 2026-10-20 (auditoria con captura real): en el footer (.darkBand) estas
   dos reglas usaban var(--violet) = #7c3aed, que es el violeta del tema
   CLARO. El scope oscuro redefine --violet-soft pero no --violet, asi que
   sobre #0a0e1c quedaban en 3.37:1 de contraste, debajo del minimo legible
   de 4.5:1 — justo los nombres de fabricante, que segun la nota de arriba
   son la señal de legitimidad mas rapida. Se pasan al token que el scope
   oscuro ya define (--violet-soft = #b79bff, 8.37:1). El tema claro no se
   toca, y --violet sigue intacto porque .btn-primary lo usa de fondo. */
.hero .powered, .darkBand .powered{color:var(--violet-soft);}
.hero .statusPill, .darkBand .statusPill{color:var(--violet-soft);}
/* 2026-10-20 (auditoria con captura real): BUG grave. El panel de detalle
   vive en un segundo .container del hero, sin position ni z-index. Como
   .heroBg es position:absolute con z-index:0, se pinta DESPUES de los
   bloques sin posicionar — o sea encima del panel. Resultado: tocabas una
   capa, el contador subia y el borde cambiaba, pero el texto que explica
   la capa quedaba tapado por el degrade del hero (hasta 97% de opacidad) y
   no se veia NADA. Se le da la misma salida que a .heroGrid: posicionarlo
   y subirlo sobre el fondo. */
.capaDetalle{
  background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius);
  padding:24px; margin-top:20px; display:none;
  position:relative; z-index:1;
}
.capaDetalle.show{display:block;}

/* Catalogo doble eje */
.ejeTabs{display:flex; gap:10px; margin-bottom:22px; flex-wrap:wrap;}
.ejeTab{
  padding:9px 16px; border-radius:999px; border:1px solid var(--line); font-size:13px; font-weight:600;
  cursor:pointer; background:transparent; color:var(--text-dim);
}
.ejeTab.activo{background:var(--violet); color:#ffffff; border-color:var(--violet);}

/* Linea de tiempo */
.timeline{position:relative; padding-left:28px; border-left:2px solid var(--line);}
.tItem{position:relative; padding-bottom:30px;}
.tItem::before{content:""; position:absolute; left:-35px; top:4px; width:12px; height:12px; border-radius:50%; background:var(--amber);}
.tItem .hora{font-family:var(--font-mono); font-size:12px; color:var(--ocean-soft);}

.simulBadge{
  display:inline-block; font-family:var(--font-mono); font-size:11px; letter-spacing:.08em;
  background:rgba(139,92,246,.18); color:var(--amber-soft); border:1px solid rgba(139,92,246,.4);
  padding:4px 10px; border-radius:6px; margin-bottom:14px;
}

.statusPill{display:inline-flex; align-items:center; gap:8px; font-family:var(--font-mono); font-size:13px; color:var(--violet); font-weight:600;}
@media (hover: hover) and (pointer: fine){ .statusPill:hover{text-decoration:underline;} }
.statusDot{width:9px; height:9px; border-radius:50%; background:var(--ok); box-shadow:0 0 0 4px rgba(76,175,125,.2);}
@media (prefers-reduced-motion: no-preference){
  .statusDot{animation:statusPulse 2s ease-in-out infinite;}
}
@keyframes statusPulse{0%,100%{box-shadow:0 0 0 0 rgba(34,229,168,.45);} 50%{box-shadow:0 0 0 6px rgba(34,229,168,0);}}

.verifStep{display:flex; gap:14px; align-items:flex-start; padding:16px 0; border-bottom:1px solid var(--line);}
.verifStep .n{font-family:var(--font-mono); color:var(--amber-soft); font-weight:700; width:28px; flex-shrink:0;}

.rolTabs{display:flex; gap:10px; margin-bottom:24px;}
.rolTab{flex:1; padding:14px; text-align:center; border-radius:var(--radius-sm); border:1px solid var(--line); cursor:pointer; background:transparent; color:var(--text-dim); font-weight:600;}
.rolTab.activo{background:var(--surface-2); color:var(--text); border-color:var(--amber);}
.rolPanel{display:none;}
.rolPanel.show{display:block;}

.placeholder-note{
  font-family:var(--font-mono); font-size:11px; color:var(--text-dim); background:var(--surface-2);
  border:1px dashed var(--line); padding:3px 8px; border-radius:6px; margin-left:8px;
}

/* Demo interactiva de ransomware (100% simulada, sin backend) — la ventana
   interna (.rwWin) queda siempre oscura a propósito, como una captura de
   pantalla incrustada, independiente del tema claro/oscuro de la sección
   que la rodea. */
.rwDemo{background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:22px; box-shadow:var(--shadow); margin-bottom:28px;}
.rwTop{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:14px; margin-bottom:18px;}
.rwControls{display:flex; flex-wrap:wrap; gap:10px;}
.rwBody{display:grid; grid-template-columns:1fr 280px; gap:18px;}

.rwWin{background:#0a0e1c; border-radius:10px; overflow:hidden; border:1px solid rgba(205,214,255,.14); position:relative; min-height:300px;}
.rwWinTop{display:flex; align-items:center; gap:10px; padding:10px 14px; background:rgba(255,255,255,.04); border-bottom:1px solid rgba(205,214,255,.12);}
.rwDots{display:flex; gap:6px; flex-shrink:0;}
.rwDots i{width:9px; height:9px; border-radius:50%; display:block; background:#4a5178;}
.rwDots i:nth-child(1){background:#ff5f57;}
.rwDots i:nth-child(2){background:#febc2e;}
.rwDots i:nth-child(3){background:#28c840;}
.rwRuta{font-family:var(--font-mono); font-size:12px; color:#a6addc; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.rwEstado{font-family:var(--font-mono); font-size:11px; font-weight:600; letter-spacing:.03em; text-transform:uppercase; color:#a6addc; background:rgba(255,255,255,.06); padding:4px 10px; border-radius:20px; flex-shrink:0;}
.rwEstado.cifrando{color:#ff8a9b; background:rgba(255,77,109,.15);}
.rwEstado.cifrado{color:#ff4d6d; background:rgba(255,77,109,.2);}
.rwEstado.contenido{color:#22e5a8; background:rgba(34,229,168,.15);}

.rwGrid{display:grid; grid-template-columns:repeat(5,1fr); gap:12px; padding:18px;}
/* min-width:0 — 2026-10-20 (auditoria, medido a 390px): sin esto las
   celdas del grid conservan min-width:auto, los nombres de archivo largos
   ("Presupuesto_Q4.xlsx") ensanchan su columna y el grid de 3 columnas
   terminaba midiendo 380px dentro de una ventana de 302px. Como .rwWin
   tiene overflow:hidden, la tercera columna salia cortada a la mitad de
   una letra y el text-overflow:ellipsis del span nunca se activaba. */
.rwFile{display:flex; flex-direction:column; align-items:center; gap:6px; padding:10px 4px; border-radius:8px; transition:background .2s ease; min-width:0;}
.rwFile svg{width:26px; height:26px; color:#8890c2; transition:color .2s ease;}
.rwFile span{font-family:var(--font-mono); font-size:10px; color:#7781ad; text-align:center; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
.rwFile.cifrado{background:rgba(255,77,109,.1);}
.rwFile.cifrado svg{color:#ff4d6d;}
.rwFile.cifrado span{color:#ff8a9b;}
.rwFile.protegido svg{color:#22e5a8;}
.rwFile.protegido span{color:#7fe8f7;}

.rwOverlay{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; background:rgba(5,7,18,0); opacity:0; pointer-events:none; transition:opacity .4s ease, background .4s ease; padding:20px;}
.rwOverlay.show{background:rgba(5,7,18,.82); opacity:1; pointer-events:auto;}
.rwNote{background:#141a33; border:1px solid rgba(255,77,109,.4); border-radius:10px; padding:20px 22px; max-width:320px; text-align:left; transform:scale(.96); transition:transform .4s ease;}
.rwOverlay.show .rwNote{transform:scale(1);}
.rwNote b{color:#ff4d6d; font-family:var(--font-mono); font-size:13px; letter-spacing:.03em;}
.rwNote p{color:#c7cdf2; font-size:13px; margin-top:8px; line-height:1.5;}

.rwSide{display:flex; flex-direction:column; gap:14px;}
.rwStat{display:flex; flex-direction:column; gap:4px; font-size:12px; color:var(--text-dim);}
.rwStat b{font-size:15px; color:var(--text); font-weight:600;}
.rwProg{height:8px; border-radius:6px; background:var(--surface-2); overflow:hidden; border:1px solid var(--line);}
.rwProg i{display:block; height:100%; width:0%; background:var(--crit); border-radius:6px; transition:width .3s ease;}
.rwProg.protegido i{background:var(--ok);}
.rwLog{flex:1; min-height:120px; max-height:170px; overflow-y:auto; font-family:var(--font-mono); font-size:11px; line-height:1.6; color:var(--text-dim); background:var(--surface-2); border:1px solid var(--line); border-radius:8px; padding:10px 12px;}
.rwLog div{opacity:0; animation:rwLogIn .3s ease forwards;}
@keyframes rwLogIn{from{opacity:0; transform:translateY(-3px);} to{opacity:1; transform:none;}}

.rwDato{margin-bottom:22px;}
.rwDato:last-child{margin-bottom:0;}
.rwDato b{display:block; font-size:16px; margin-bottom:6px;}
.rwDato .lead{font-size:14px;}

@media (prefers-reduced-motion: reduce){
  .rwLog div{animation:none; opacity:1;}
  .rwOverlay, .rwNote, .rwFile, .rwProg i{transition:none;}
}

/* "Sitio en construccion": 2026-10-20, rediseñado a pedido del dueño con
   ilustracion plana de colores reales (casco amarillo/naranja, overol,
   piel) en vez del muñeco geometrico abstracto en violeta/cian de antes —
   y ahora SI estan martillando (antes uno cavaba y el otro cargaba un
   balde). Probado con capturas reales en /tmp antes de subir: a este
   tamaño se reconoce de inmediato como obrero, no como mancha.
   2026-10-20 (segunda vuelta): el dueño señalo que "martillan al aire" —
   el giro original no llevaba el martillo hasta ningun lado. Se agrego un
   caballete/tabla de madera debajo de cada uno y se corrigio el angulo de
   giro para que el martillo SI toque la madera, con chispas de impacto
   sincronizadas al golpe. Verificado capturando la animacion fotograma a
   fotograma (no solo mirandola correr) para confirmar el contacto real. */
.constrRow{display:flex; align-items:flex-end; gap:10px;}
.wkr{height:84px; width:auto; flex-shrink:0; overflow:visible;}
.wkrArm{transform-origin:14px 29px;}
/* 2026-10-20 (tercera vuelta): el dueño señalo que el Obrero 1 se veia
   "raro" aun golpeando algo real — tenia razon. Un giro grande (-100deg)
   de TODO el brazo alrededor del hombro hace que a mitad de camino el
   brazo quede estirado derecho hacia el costado, como señalando, en vez
   de verse como un golpe de martillo. El Obrero 2 ya usaba un giro chico
   (24deg) con el martillo descansando CERCA de la tabla, y ese SI se veia
   natural (confirmado capturando el ciclo completo fotograma a fotograma).
   Se le dio al Obrero 1 la misma geometria del brazo (mano ya cerca de su
   caballete) y el mismo giro chico, solo con el delay cambiado para que
   no golpeen los dos exactamente a la vez. */
.wkrArm1{animation:wkrSwing .9s ease-in-out infinite;}
.wkrArm2{animation:wkrSwing .9s ease-in-out infinite; animation-delay:.45s;}
@keyframes wkrSwing{0%,15%{transform:rotate(0deg);} 70%,100%{transform:rotate(24deg);}}
.wkrImpact{opacity:0; transform-origin:center;}
.wkrImpact1{animation:wkrHit .9s ease-in-out infinite;}
.wkrImpact2{animation:wkrHit .9s ease-in-out infinite; animation-delay:.45s;}
@keyframes wkrHit{0%,52%,100%{opacity:0;} 58%{opacity:1;} 68%{opacity:0;}}
.wkrBlocks{height:34px; width:auto; flex-shrink:0; margin-left:2px;}
.cBlock{fill:var(--cyan); opacity:0; animation:cBlockIn 2.6s ease-in-out infinite;}
.cBlock.cB2{fill:var(--violet-soft); animation-delay:.5s;}
.cBlock.cB3{animation-delay:1s;}
@keyframes cBlockIn{0%{opacity:0;} 8%,70%{opacity:1;} 85%,100%{opacity:0;}}
@media (prefers-reduced-motion: reduce){
  .cBlock{animation:none; opacity:1;}
  .wkrArm1, .wkrArm2{animation:none;}
  .wkrImpact1, .wkrImpact2{animation:none; opacity:0;}
}
@media (max-width:900px){
  .wkr{height:64px;} .wkrBlocks{height:26px;}
}

/* Autodiagnostico: stepper de una pregunta a la vez (2026-10-19, antes eran
   8 tarjetas apiladas — consumia demasiado espacio vertical). */
.diagDots{display:flex; gap:10px; margin-bottom:14px;}
.diagDot{position:relative; width:9px; height:9px; border-radius:50%; border:1px solid var(--line); background:var(--surface-2); padding:0; cursor:pointer; transition:background .2s ease, transform .2s ease;}
/* 2026-10-20: el punto visible de 9px era tambien toda el area de toque —
   hallazgo real de la auditoria. Se agranda el area clickeable con un
   pseudo-elemento invisible sin agrandar el punto que se ve. */
.diagDot::before{content:""; position:absolute; top:50%; left:50%; width:18px; height:18px; transform:translate(-50%,-50%);}
.diagDot.hecho{background:var(--violet); border-color:var(--violet);}
.diagDot.activo{background:var(--violet); border-color:var(--violet); transform:scale(1.35);}
.diagOpt.activo{background:var(--violet); border-color:var(--violet); color:#fff;}

footer{padding:56px 0 34px; color:var(--text-dim); font-size:14px;}
footer a{color:var(--text-dim);}
footer a:hover{color:var(--amber-soft);}

@media (max-width: 900px){
  .heroGrid{grid-template-columns:1fr; gap:36px;}
  /* Composicion deliberadamente distinta en mobile (mismo criterio que el
     art-direction de Tesla: no es solo "se acomoda", es otra composicion) —
     se pierde el efecto de profundidad en cascada porque ahi se come
     ancho real en pantalla chica; queda una lista recta, igual operable. */
  .stackLayer{margin-left:0;}
  .grid-2,.grid-3,.grid-4{grid-template-columns:1fr;}
  .navlinks{display:none;}
  .navlinks.show{display:flex; flex-direction:column; position:absolute; top:68px; left:0; right:0; background:var(--surface); padding:16px 20px; border-bottom:1px solid var(--line);}
  .navToggle{display:block;}
  .rolTabs{flex-direction:column;}
  .rwBody{grid-template-columns:1fr;}
  .rwGrid{grid-template-columns:repeat(3,1fr); padding:14px;}
  .rwNote{max-width:260px;}
}
