:root{
  --blue-900:#07234F;
  --blue-700:#0044BE;
  --blue-600:#005AEF;
  --blue-500:#2E7CF6;
  --blue-100:#E7F0FE;
  --blue-50:#F4F8FF;
  --ink-900:#0A0A0C;
  --ink-700:#3B3E46;
  --ink-500:#6B707B;
  --gray-50:#F7F8FA;
  --gray-100:#F0F2F5;
  --border:#E3E7ED;
  --white:#FFFFFF;
  --radius-xl:28px;
  --radius-lg:20px;
  --radius-md:14px;
  --radius-sm:10px;
  --shadow-sm:0 1px 2px rgba(10,10,20,0.04);
  --shadow-md:0 8px 24px rgba(10,20,50,0.07);
  --shadow-lg:0 24px 60px -14px rgba(7,35,79,0.22);
}
*{box-sizing:border-box;}
body{margin:0;font-family:'IBM Plex Sans',system-ui,sans-serif;color:var(--ink-700);background:var(--white);-webkit-font-smoothing:antialiased;}
h1,h2,h3,h4{font-family:'Space Grotesk',system-ui,sans-serif;color:var(--ink-900);margin:0;letter-spacing:-0.015em;}
p{margin:0;}
a{color:var(--blue-600);text-decoration:none;}
a:hover{color:var(--blue-700);}
ul{margin:0;padding:0;list-style:none;}
button{font-family:inherit;}
img{display:block;max-width:100%;}
svg{display:block;}

.container{max-width:1240px;margin:0 auto;padding:0 32px;}
.section{padding:112px 0;}
.section--tight{padding:88px 0;}
.section--alt{background:var(--gray-50);}
.eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;letter-spacing:0.07em;text-transform:uppercase;color:var(--blue-700);margin-bottom:20px;padding:7px 14px 7px 11px;background:var(--blue-50);border:1px solid var(--blue-100);border-radius:999px;}
.eyebrow::before{content:'';width:6px;height:6px;background:#005AEF;display:inline-block;border-radius:50%;box-shadow:0 0 0 3px var(--blue-100);flex-shrink:0;}
.section-title{font-size:clamp(28px,3.6vw,42px);font-weight:600;line-height:1.15;max-width:760px;}
.section-lead{font-size:17px;line-height:1.65;color:var(--ink-500);max-width:620px;margin-top:20px;}
.section-head{margin-bottom:64px;}
.section-head--center{text-align:center;margin-left:auto;margin-right:auto;}
.section-head--center .section-title,.section-head--center .section-lead{margin-left:auto;margin-right:auto;}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;padding:15px 26px;border-radius:999px;font-size:15px;font-weight:600;border:1.5px solid transparent;cursor:pointer;transition:background .2s ease,border-color .2s ease,color .2s ease,transform .18s ease,box-shadow .2s ease;white-space:nowrap;}
.btn:active{transform:translateY(1px) scale(0.99);}
.btn-primary{background:#005AEF;color:#fff;box-shadow:0 10px 24px -10px #005AEF;}
.btn-primary:hover{background:var(--blue-700);color:#fff;transform:translateY(-2px);box-shadow:0 16px 30px -10px var(--blue-700);}
.btn-secondary{background:#fff;color:var(--ink-900);border-color:var(--border);}
.btn-secondary:hover{border-color:#005AEF;color:#005AEF;transform:translateY(-2px);box-shadow:var(--shadow-md);}
.btn-ghost-inverse{background:transparent;color:#fff;border-color:rgba(255,255,255,0.5);}
.btn-ghost-inverse:hover{background:rgba(255,255,255,0.12);border-color:#fff;transform:translateY(-2px);}
.btn-light{background:#fff;color:var(--blue-700);}
.btn-light:hover{background:var(--blue-50);transform:translateY(-2px);box-shadow:0 16px 30px -12px rgba(7,35,79,0.4);}
.btn-sm{padding:10px 18px;font-size:13.5px;}
.btn svg{width:17px;height:17px;transition:transform .18s ease;flex-shrink:0;}
.btn:hover svg{transform:translateX(2px);}

/* header */
.header{position:sticky;top:0;z-index:80;background:rgba(255,255,255,0.8);backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4);border-bottom:1px solid var(--border);box-shadow:0 16px 32px -24px rgba(10,20,50,0.35);}
.header-inner{max-width:1240px;margin:0 auto;padding:0 32px;height:76px;display:flex;align-items:center;justify-content:space-between;gap:24px;}
.brand{display:flex;align-items:center;height:36px;transition:transform .2s ease;}
.brand:hover{transform:scale(1.03);}
.brand img{height:100%;width:auto;}
.nav-desktop{display:flex;align-items:center;gap:6px;}
.nav-desktop a{font-size:14.5px;font-weight:500;color:var(--ink-700);padding:9px 14px;border-radius:999px;transition:color .18s ease,background .18s ease;}
.nav-desktop a:hover{color:var(--blue-700);background:var(--blue-50);}
.header-actions{display:flex;align-items:center;gap:20px;}
.menu-toggle{display:none;background:none;border:none;padding:8px;cursor:pointer;color:var(--ink-900);}
.mobile-nav{display:none;}
@media (max-width:900px){
  .nav-desktop{display:none;}
  .header-actions .btn-primary{display:none;}
  .menu-toggle{display:flex;}
  .mobile-nav{display:flex;flex-direction:column;gap:2px;padding:12px 20px 24px;border-top:1px solid var(--border);background:#fff;}
  .mobile-nav a{padding:13px 4px;font-size:15.5px;font-weight:500;color:var(--ink-900);border-bottom:1px solid var(--gray-100);}
  .mobile-nav .btn{margin-top:14px;width:100%;}
  .header-inner{padding:0 20px;}
}

/* hero */
.hero{padding:100px 0 132px;overflow:hidden;position:relative;background:radial-gradient(560px 420px at 88% -8%,var(--blue-50) 0%,transparent 68%),radial-gradient(480px 380px at -8% 105%,#EEF4FF 0%,transparent 62%),#fff;}
.hero::before{content:'';position:absolute;inset:0;background-image:radial-gradient(rgba(10,20,50,0.05) 1px,transparent 1px);background-size:26px 26px;-webkit-mask-image:radial-gradient(ellipse 70% 60% at 80% 18%,#000 0%,transparent 72%);mask-image:radial-gradient(ellipse 70% 60% at 80% 18%,#000 0%,transparent 72%);pointer-events:none;}
.hero-grid{position:relative;display:grid;grid-template-columns:1.05fr 0.95fr;gap:64px;align-items:center;}
.hero-kicker{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;font-weight:600;letter-spacing:0.05em;text-transform:uppercase;color:var(--blue-700);background:#fff;border:1px solid var(--blue-100);padding:7px 14px;border-radius:999px;margin-bottom:24px;box-shadow:var(--shadow-sm);}
.hero-kicker .dot{width:7px;height:7px;border-radius:50%;background:#22C55E;box-shadow:0 0 0 3px rgba(34,197,94,0.18);flex-shrink:0;}
.hero-title{font-size:clamp(36px,4.8vw,60px);font-weight:700;line-height:1.06;color:var(--ink-900);letter-spacing:-0.02em;}
.hero-title em{font-style:normal;background:linear-gradient(100deg,#005AEF 10%,var(--blue-500) 55%,#6FA3FF 92%);-webkit-background-clip:text;background-clip:text;color:transparent;}
.hero-lead{margin-top:26px;font-size:18px;line-height:1.65;color:var(--ink-500);max-width:520px;}
.hero-actions{display:flex;gap:16px;margin-top:38px;flex-wrap:wrap;}
.hero-visual{position:relative;width:100%;max-width:600px;aspect-ratio:1/1;margin:0 auto;}
.hero-glow{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:340px;height:340px;border-radius:50%;background:radial-gradient(circle,rgba(0,90,239,0.28) 0%,transparent 68%);z-index:0;}
.hero-node{position:absolute;transform:translate(-50%,-50%);background:rgba(255,255,255,0.72);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(227,231,237,0.9);border-radius:14px;box-shadow:0 10px 26px -12px rgba(10,20,50,0.2);padding:12px 16px;display:flex;align-items:center;gap:9px;font-size:13px;font-weight:600;color:var(--ink-900);white-space:nowrap;transition:transform .2s ease,box-shadow .2s ease;z-index:1;}
.hero-node:hover{transform:translate(-50%,-50%) translateY(-3px);box-shadow:0 16px 32px -12px rgba(10,20,50,0.26);}
.hero-node svg{width:17px;height:17px;color:#005AEF;flex-shrink:0;}
.hero-badge{position:absolute;left:4%;bottom:3%;display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--border);border-radius:999px;padding:9px 16px 9px 9px;box-shadow:var(--shadow-lg);z-index:3;}
.hero-badge .ring{width:28px;height:28px;border-radius:50%;background:var(--blue-50);display:flex;align-items:center;justify-content:center;color:#005AEF;flex-shrink:0;}
.hero-badge .ring svg{width:15px;height:15px;}
.hero-badge span{font-size:12.5px;font-weight:600;color:var(--ink-900);}
.hero-core{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:160px;height:160px;border-radius:50%;background:linear-gradient(155deg,var(--blue-700),#005AEF 60%,var(--blue-500));display:flex;flex-direction:column;align-items:center;justify-content:center;color:#fff;box-shadow:0 0 0 8px rgba(255,255,255,0.9),0 20px 44px -10px rgba(0,68,190,0.4);z-index:2;}
.hero-core .cube-mark{width:30px;height:30px;margin-bottom:6px;}
.hero-core strong{font-family:'Space Grotesk',sans-serif;font-size:15px;font-weight:700;letter-spacing:0.03em;}
.hero-core span{font-size:10px;letter-spacing:0.1em;text-transform:uppercase;opacity:0.85;margin-top:2px;}
.hero-lines{position:absolute;inset:0;width:100%;height:100%;z-index:0;}
.flow-line{stroke:#005AEF;stroke-opacity:0.32;stroke-width:2;stroke-dasharray:5 7;animation:dashmove 26s linear infinite;}
@keyframes dashmove{to{stroke-dashoffset:-480;}}
@media (prefers-reduced-motion:reduce){.flow-line{animation:none;}}
@media (max-width:1024px){.hero-grid{grid-template-columns:1fr;}.hero-visual{margin-top:24px;}.hero-badge{display:none;}}

/* platform diagram */
.platform-wrap{display:grid;grid-template-columns:0.95fr 1.05fr;gap:72px;align-items:center;}
.platform-chain{display:flex;flex-direction:column;align-items:center;gap:0;max-width:300px;margin:0 auto;}
.chain-node{width:100%;background:#fff;border:1px solid var(--border);border-radius:var(--radius-md);padding:16px 20px;text-align:center;font-weight:600;font-size:14.5px;color:var(--ink-900);box-shadow:var(--shadow-sm);position:relative;z-index:1;}
.chain-arrow{height:34px;display:flex;align-items:center;justify-content:center;color:var(--ink-500);}
.side-row{display:flex;align-items:center;gap:14px;width:100%;max-width:460px;margin:10px 0;}
.side-node{background:var(--blue-50);border:1px solid var(--blue-100);color:var(--blue-700);border-radius:var(--radius-sm);padding:11px 16px;font-size:13px;font-weight:600;white-space:nowrap;}
.side-connector{flex:1;height:1.5px;background:repeating-linear-gradient(90deg,var(--border) 0 6px,transparent 6px 12px);}
.platform-callout{margin-top:44px;background:var(--blue-50);border:1px solid var(--blue-100);border-radius:var(--radius-md);padding:26px 30px;font-size:16.5px;line-height:1.6;color:var(--blue-900);font-weight:500;}
.platform-callout strong{color:#005AEF;}
@media (max-width:1024px){.platform-wrap{grid-template-columns:1fr;}}

/* modules */
.module-group-label{font-size:12.5px;font-weight:700;letter-spacing:0.1em;text-transform:uppercase;color:var(--ink-500);margin:0 0 20px 4px;}
.module-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;}
.module-grid + .module-group-label{margin-top:52px;}
.module-card{position:relative;background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);padding:30px;display:flex;flex-direction:column;overflow:hidden;transition:border-color .22s ease,box-shadow .22s ease,transform .22s ease;}
.module-card::before{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,#005AEF,var(--blue-500));transform:scaleX(0);transform-origin:left;transition:transform .28s ease;}
.module-card:hover{border-color:var(--blue-100);box-shadow:var(--shadow-lg);transform:translateY(-4px);}
.module-card:hover::before{transform:scaleX(1);}
.module-icon{width:46px;height:46px;border-radius:12px;background:linear-gradient(150deg,var(--blue-50),var(--blue-100));display:flex;align-items:center;justify-content:center;color:#005AEF;margin-bottom:20px;}
.module-icon svg{width:23px;height:23px;}
.module-card h3{font-size:18.5px;font-weight:600;margin-bottom:8px;}
.module-desc{font-size:14.5px;color:var(--ink-500);line-height:1.55;}
.tag-list{display:flex;flex-wrap:wrap;gap:7px;margin-top:20px;}
.tag{font-size:12px;font-weight:500;padding:6px 11px;background:var(--gray-50);border:1px solid var(--border);color:var(--ink-700);border-radius:999px;}
@media (max-width:1024px){.module-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:640px){.module-grid{grid-template-columns:1fr;}}

/* integration */
.integration-section{background:var(--ink-900);color:#fff;}
.integration-section .eyebrow{color:#8FB7FF;}
.integration-section .eyebrow::before{background:#8FB7FF;}
.integration-section .section-title{color:#fff;}
.integration-section .section-lead{color:#B7BCC8;}
.integration-visual{position:relative;width:100%;max-width:640px;aspect-ratio:1/1;margin:56px auto 0;}
.int-node{position:absolute;transform:translate(-50%,-50%);background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.14);border-radius:14px;padding:13px 18px;font-size:13px;font-weight:600;color:#fff;white-space:nowrap;backdrop-filter:blur(4px);}
.int-core{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:172px;height:172px;border-radius:50%;background:radial-gradient(circle at 35% 30%,var(--blue-500),var(--blue-700) 70%);display:flex;flex-direction:column;align-items:center;justify-content:center;box-shadow:0 0 0 14px rgba(46,124,246,0.08),0 0 60px rgba(46,124,246,0.35);z-index:2;}
.int-core .cube-mark{width:32px;height:32px;color:#fff;margin-bottom:6px;}
.int-core strong{font-family:'Space Grotesk',sans-serif;font-size:16px;color:#fff;}
.int-core span{font-size:10.5px;letter-spacing:0.1em;text-transform:uppercase;color:rgba(255,255,255,0.8);margin-top:2px;}
.flow-examples{margin-top:76px;display:flex;flex-direction:column;gap:14px;max-width:820px;margin-left:auto;margin-right:auto;}
.flow-row{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:16px 20px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);border-radius:var(--radius-sm);}
.flow-chip{font-size:13.5px;font-weight:600;color:#fff;padding:5px 2px;}
.flow-sep{color:#5C7BB8;font-size:14px;}
@media (max-width:640px){.integration-visual{max-width:100%;}.int-node{padding:9px 12px;font-size:11.5px;}.int-core{width:126px;height:126px;}}

/* benefits */
.benefit-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;}
.benefit-card{border:1px solid var(--border);border-radius:var(--radius-md);padding:26px 24px;background:#fff;transition:transform .22s ease,box-shadow .22s ease,border-color .22s ease;}
.benefit-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:var(--blue-100);}
.benefit-icon{width:40px;height:40px;border-radius:10px;background:linear-gradient(150deg,var(--blue-50),var(--blue-100));display:flex;align-items:center;justify-content:center;color:#005AEF;margin-bottom:16px;}
.benefit-icon svg{width:20px;height:20px;}
.benefit-card h3{font-size:15.5px;font-weight:700;letter-spacing:0.02em;margin-bottom:6px;}
.benefit-card p{font-size:13.5px;line-height:1.55;color:var(--ink-500);}
@media (max-width:1024px){.benefit-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:520px){.benefit-grid{grid-template-columns:1fr;}}

/* executives */
.pipeline{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap;margin-top:8px;}
.pipeline-step{flex:1;min-width:130px;background:#fff;border:1px solid var(--border);border-radius:var(--radius-md);padding:22px 14px;text-align:center;transition:transform .2s ease,box-shadow .2s ease;}
.pipeline-step:hover{transform:translateY(-3px);box-shadow:var(--shadow-md);}
.pipeline-step span{display:block;font-size:11px;font-weight:700;color:var(--ink-500);letter-spacing:0.04em;margin-bottom:6px;}
.pipeline-step strong{font-size:14.5px;font-weight:600;color:var(--ink-900);}
.pipeline-step.is-final{background:linear-gradient(155deg,var(--blue-700),#005AEF);border-color:#005AEF;box-shadow:0 16px 32px -14px rgba(0,68,190,0.45);}
.pipeline-step.is-final strong,.pipeline-step.is-final span{color:#fff;}
.pipeline-arrow{color:#B6BBC6;flex-shrink:0;}
@media (max-width:900px){.pipeline{flex-direction:column;}.pipeline-arrow{transform:rotate(90deg);}.pipeline-step{width:100%;}}
.exec-message{text-align:center;margin-top:48px;font-size:19px;font-weight:500;color:var(--ink-900);max-width:640px;margin-left:auto;margin-right:auto;line-height:1.5;}

/* differential */
.diff-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
.diff-item{display:flex;align-items:flex-start;gap:12px;padding:18px 20px;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;}
.diff-item:hover{transform:translateY(-3px);box-shadow:var(--shadow-sm);border-color:var(--blue-100);}
.diff-item svg{width:19px;height:19px;color:#005AEF;flex-shrink:0;margin-top:1px;}
.diff-item span{font-size:14.5px;font-weight:500;color:var(--ink-800,var(--ink-900));}
@media (max-width:900px){.diff-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:560px){.diff-grid{grid-template-columns:1fr;}}

/* evolution */
.timeline{display:flex;align-items:flex-start;gap:0;overflow-x:auto;padding:24px 4px 12px;margin:0 -4px;}
.tl-step{flex:1;min-width:118px;display:flex;flex-direction:column;align-items:center;text-align:center;position:relative;padding:0 6px;}
.tl-dot{width:15px;height:15px;border-radius:50%;background:#005AEF;border:3px solid #fff;box-shadow:0 0 0 4px var(--blue-100);z-index:1;transition:transform .2s ease;}
.tl-step:hover .tl-dot{transform:scale(1.15);}
.tl-line{position:absolute;top:6.5px;left:-50%;width:100%;height:2px;background:linear-gradient(90deg,var(--blue-100),#005AEF);z-index:0;}
.tl-step:first-child .tl-line{display:none;}
.tl-label{margin-top:16px;font-size:13px;font-weight:600;color:var(--ink-900);line-height:1.3;}
.tl-badge{margin-top:9px;font-size:10px;font-weight:700;letter-spacing:0.05em;text-transform:uppercase;color:var(--blue-600);border:1px dashed var(--blue-500);border-radius:999px;padding:3px 9px;background:var(--blue-50);}
.evolution-note{text-align:center;font-size:13.5px;color:var(--ink-500);margin-top:36px;}

/* cta */
.cta-section{position:relative;overflow:hidden;background:linear-gradient(135deg,var(--blue-700),var(--blue-600) 60%,var(--blue-500));color:#fff;text-align:center;}
.cta-section::before{content:'';position:absolute;width:520px;height:520px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,0.16),transparent 70%);top:-220px;left:-120px;pointer-events:none;}
.cta-section::after{content:'';position:absolute;width:420px;height:420px;border-radius:50%;background:radial-gradient(circle,rgba(255,255,255,0.12),transparent 70%);bottom:-200px;right:-100px;pointer-events:none;}
.cta-section .container{position:relative;}
.cta-section h2{color:#fff;font-size:clamp(28px,3.8vw,40px);font-weight:600;max-width:680px;margin:0 auto;}
.cta-section p{color:#DCE7FF;font-size:17px;max-width:560px;margin:20px auto 0;line-height:1.6;}
.cta-actions{display:flex;gap:16px;justify-content:center;margin-top:36px;flex-wrap:wrap;}

/* contact */
.contact-wrap{display:grid;grid-template-columns:0.85fr 1.15fr;gap:64px;}
.contact-side h2{font-size:clamp(26px,3.2vw,34px);}
.contact-side p{margin-top:18px;font-size:15.5px;color:var(--ink-500);line-height:1.65;max-width:380px;}
.contact-points{margin-top:32px;display:flex;flex-direction:column;gap:16px;}
.contact-point{display:flex;align-items:flex-start;gap:12px;font-size:14.5px;color:var(--ink-700);}
.contact-point svg{width:18px;height:18px;color:#005AEF;margin-top:2px;flex-shrink:0;}
.form-card{background:#fff;border:1px solid var(--border);border-radius:var(--radius-lg);padding:36px;box-shadow:var(--shadow-md);}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:18px;}
.field{display:flex;flex-direction:column;gap:7px;margin-bottom:18px;}
.field label{font-size:13px;font-weight:600;color:var(--ink-900);}
.field label .req{color:var(--blue-600);}
.field input,.field select,.field textarea{font-family:inherit;font-size:14.5px;padding:12px 14px;border:1.5px solid var(--border);border-radius:var(--radius-sm);color:var(--ink-900);background:#fff;width:100%;}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:#005AEF;}
.field textarea{resize:vertical;min-height:110px;}
.checkbox-fieldset{border:none;padding:0;margin:0 0 22px;}
.checkbox-fieldset legend{font-size:13px;font-weight:600;color:var(--ink-900);margin-bottom:10px;padding:0;}
.checkbox-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px 12px;}
.checkbox-item{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink-700);}
.checkbox-item input{width:16px;height:16px;accent-color:#005AEF;}
.form-submit{width:100%;margin-top:4px;}
@media (max-width:1024px){.contact-wrap{grid-template-columns:1fr;}.form-row{grid-template-columns:1fr;}.checkbox-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:640px){.form-card{padding:24px;}}

/* footer */
.footer{background:var(--gray-50);border-top:1px solid var(--border);padding:64px 0 28px;position:relative;}
.footer::before{content:'';position:absolute;top:-1px;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,#005AEF,transparent);}
.section-wave{display:block;width:100%;height:60px;line-height:0;}
.section-wave svg{display:block;width:100%;height:100%;}
.footer-top{display:flex;justify-content:space-between;align-items:flex-start;gap:40px;flex-wrap:wrap;padding-bottom:36px;border-bottom:1px solid var(--border);}
.footer-brand img{height:30px;width:auto;margin-bottom:14px;}
.footer-brand p{font-size:14px;color:var(--ink-500);max-width:280px;line-height:1.55;}
.footer-links{display:flex;gap:56px;flex-wrap:wrap;}
.footer-col h3{font-size:12.5px;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:var(--ink-500);margin-bottom:14px;}
.footer-col a{display:block;font-size:14px;color:var(--ink-700);padding:6px 0;}
.footer-col a:hover{color:#005AEF;}
.footer-bottom{padding-top:22px;font-size:13px;color:var(--ink-500);display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;}
@media (max-width:640px){.footer-top{flex-direction:column;}.section{padding:76px 0;}}

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

/* ============================================================================
   AJUSTES DE PRODUCCIÓN
   Añadidos sobre el diseño original. Cada bloque dice qué arregla.
   ========================================================================== */

/* --- 1. El header sticky (76px) tapaba el título al saltar por anclas ------ */
html{
  scroll-behavior:smooth;
  scroll-padding-top:92px;      /* 76px del header + 16px de aire */
}
@media (max-width:900px){ html{scroll-padding-top:84px;} }
@media (prefers-reduced-motion:reduce){ html{scroll-behavior:auto;} }

/* --- 2. Menú móvil por clase, no por estilo inline -------------------------
   Antes el JS escribía style="display:flex" y el menú quedaba abierto al
   pasar a escritorio. Ahora manda el CSS y el JS sólo alterna una clase.     */
.mobile-nav{display:none;}
.mobile-nav.is-open{display:flex;}
@media (min-width:901px){
  .mobile-nav,.mobile-nav.is-open{display:none;}   /* nunca en escritorio */
}
/* Teléfono en horizontal: el menú no debe desbordar la pantalla. */
@media (max-width:900px){
  .mobile-nav.is-open{
    max-height:calc(100svh - 76px);
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
}

/* --- 3. Foco visible para teclado ------------------------------------------
   El diseño original hacía outline:none en los campos, dejando a quien navega
   con Tab sin saber dónde está. Se restituye con un anillo de marca.         */
:focus-visible{
  outline:2px solid var(--blue-600);
  outline-offset:2px;
  border-radius:4px;
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible{
  outline:none;
  border-color:var(--blue-600);
  box-shadow:0 0 0 3px rgba(0,90,239,0.18);
}
.checkbox-item input:focus-visible{outline:2px solid var(--blue-600);outline-offset:2px;}

/* Enlace de salto: invisible hasta que se le da foco con Tab.
   Se esconde hacia arriba, no con left:-9999px — esa técnica creaba
   desbordamiento horizontal que había que tapar con overflow-x:hidden. */
.skip-link{
  position:fixed;top:0;left:0;z-index:200;
  transform:translateY(-130%);
  transition:transform .18s ease;
  background:var(--blue-600);color:#fff;
  padding:12px 20px;border-radius:0 0 var(--radius-sm) 0;
  font-size:14.5px;font-weight:600;
}
.skip-link:focus{transform:translateY(0);color:#fff;}
@media (prefers-reduced-motion:reduce){ .skip-link{transition:none;} }

/* --- 4. Navegadores sin backdrop-filter (Firefox antiguo, algunos Android) --
   Sin el desenfoque, un fondo al 80% deja ver el texto de atrás.             */
@supports not ((backdrop-filter:blur(2px)) or (-webkit-backdrop-filter:blur(2px))){
  .header{background:rgba(255,255,255,0.97);}
}

/* --- 5. Salvaguardas de layout --------------------------------------------- */
img{max-width:100%;height:auto;}          /* ninguna imagen desborda */
/* Los dos logos llevan alto fijo propio (.brand img / .footer-brand img);
   la regla de arriba no debe reescribirlo. */
.brand img{height:100%;width:auto;}
.footer-brand img{height:30px;width:auto;}

/* Columna de contacto del pie: los <span> se ven igual que los enlaces. */
.footer-col span{display:block;font-size:14px;color:var(--ink-700);padding:6px 0;}
.footer-pendiente{color:var(--ink-500)!important;font-style:italic;}

/* Diagrama del hero en pantallas chicas.
   ---------------------------------------------------------------------------
   Hay dos fuerzas en tensión. Los nodos se posicionan al 9,375% y 90,625% y se
   centran con translate(-50%), así que media etiqueta sobresale del círculo:
   si el diagrama es muy ancho, "Facturación" y "RR.HH." se salen de la
   pantalla. Pero si es muy angosto, las etiquetas se montan sobre el núcleo.

   El error anterior fue achicar sólo el diagrama: el núcleo estaba fijo en
   160px y nunca encogía, así que en un teléfono de 360px ocupaba el 63% del
   círculo y tapaba seis de las ocho etiquetas.

   Ahora el núcleo se mide en porcentaje del diagrama, así acompaña cualquier
   tamaño, y su texto se escala con unidades de contenedor (cqw = 1% del ancho
   del diagrama). Las etiquetas mantienen un tamaño legible fijo: reducirlas en
   proporción las dejaría en 7px. */
@media (max-width:1024px){
  .hero-visual{
    max-width:min(440px,84vw);
    container-type:inline-size;   /* habilita las unidades cqw de abajo */
  }

  .hero-core{width:30%;height:30%;}
  /* Valores de respaldo para navegadores sin unidades de contenedor. */
  .hero-core .cube-mark{width:19px;height:19px;margin-bottom:3px;}
  .hero-core strong{font-size:11px;}
  .hero-core span{font-size:8px;letter-spacing:0.06em;margin-top:1px;}

  /* El max() pone un piso: escalar en proporción pura dejaría el texto en
     9px y el cubo en 5px en un teléfono angosto. */
  @supports (width:1cqw){
    .hero-core .cube-mark{width:max(17px,6.2cqw);height:max(17px,6.2cqw);}
    .hero-core strong{font-size:max(11px,3.4cqw);}
    .hero-core span{font-size:max(7.5px,2.5cqw);}
  }

  .hero-glow{width:62%;height:62%;}
  .hero-node{padding:7px 9px;font-size:11.5px;gap:5px;border-radius:10px;}
  .hero-node svg{width:13px;height:13px;}
}

/* En teléfonos "Facturación" quedaba pegada al borde: a 1px en 320px.
   Achicar un poco el diagrama y la etiqueta da margen de sobra.

   El corte va en 440px, no en 380, a propósito: dos mediciones del mismo
   ancho (el navegador de pruebas y un render sin interfaz) daban resultados
   distintos por milímetros de tipografía. En vez de apostar a cuál era la
   correcta, se deja margen suficiente para que las dos estén holgadas. Cubre
   además los anchos de teléfono más comunes: 360, 390, 412 y 430. */
@media (max-width:440px){
  .hero-visual{max-width:min(440px,80vw);}
  .hero-node{font-size:11px;padding:6px 8px;gap:4px;}
  .hero-node svg{width:12px;height:12px;}
}

/* La línea de tiempo se desplaza en horizontal: hay que poder hacerlo
   también con el teclado, no sólo arrastrando. */
.timeline{scroll-snap-type:x proximity;}
.timeline:focus-visible{outline:2px solid var(--blue-600);outline-offset:4px;}
.tl-step{scroll-snap-align:center;}

/* Pantallas muy angostas (iPhone SE, 320px): el padding fijo apretaba todo. */
@media (max-width:380px){
  .container{padding-left:18px;padding-right:18px;}
  .header-inner{padding:0 18px;}
  .hero-title{font-size:clamp(30px,8.5vw,40px);}
  .tag{font-size:11px;}
  .flow-row{font-size:12px;}
}
/* Red de seguridad contra desbordes horizontales futuros.
   IMPORTANTE: tiene que ser `clip`, no `hidden`. `overflow-x:hidden` convierte
   al elemento en contenedor de scroll y eso rompe el position:sticky del
   header (deja de quedarse arriba al bajar). `clip` recorta sin crear ese
   contenedor. Safari < 16 lo ignora, pero hoy no hay nada que desborde. */
body{overflow-x:clip;}
/* Palabras largas sin espacios (correos, URLs) no rompen la caja. */
h1,h2,h3,h4,p,li,.tag,.flow-chip{overflow-wrap:break-word;}

/* --- 6. Formulario: estados que antes no existían -------------------------- */
/* Trampa antispam: invisible para personas, pero sigue en el DOM y se envía,
   así que los bots que rellenan todos los campos caen igual.
   Se oculta recortándola, no con left:-9999px: esa técnica ensancha la página
   y obliga a taparlo con overflow-x:hidden. */
.hp-field{
  position:absolute!important;
  width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  clip-path:inset(50%);
  white-space:nowrap;
  pointer-events:none;
}
.form-status{
  display:none;margin-top:16px;padding:14px 16px;
  border-radius:var(--radius-sm);font-size:14.5px;line-height:1.5;
}
.form-status.is-visible{display:block;}
.form-status.is-ok{background:#E8F6EE;color:#1B5E36;border:1px solid #BFE3CD;}
.form-status.is-error{background:#FDECEC;color:#8A1C1C;border:1px solid #F5C6C6;}
.field .error-msg{display:none;margin-top:6px;font-size:13px;color:#C0392B;}
.field.is-invalid .error-msg{display:block;}
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea{border-color:#C0392B;}
.form-submit[aria-busy="true"]{opacity:.65;cursor:progress;}
.form-consent{
  display:flex;gap:10px;align-items:flex-start;
  margin-top:18px;font-size:13.5px;line-height:1.55;color:var(--ink-500);
}
.form-consent input{margin-top:3px;flex:none;}

/* --- 7. Impresión ----------------------------------------------------------- */
@media print{
  .header,.mobile-nav,.cta-section,.form-card,.skip-link,.section-wave{display:none!important;}
  body{color:#000;}
  .section{padding:24px 0;break-inside:avoid;}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:11px;color:#555;}
}

/* --- 8. Contacto directo (WhatsApp / correo) -------------------------------
   Junto al formulario, para quien prefiere escribir sin llenar campos. */
.contact-directo{margin-top:34px;padding-top:28px;border-top:1px solid var(--border);}
.contact-directo-titulo{
  font-size:12.5px;font-weight:600;letter-spacing:0.07em;text-transform:uppercase;
  color:var(--ink-500);margin-bottom:14px;
}
.contact-via{
  display:flex;align-items:center;gap:13px;
  padding:12px 14px;margin-bottom:10px;
  border:1px solid var(--border);border-radius:var(--radius-md);
  background:#fff;color:var(--ink-700);
  font-size:14.5px;line-height:1.35;
  transition:border-color .18s ease,transform .18s ease,box-shadow .18s ease;
}
.contact-via:hover{
  border-color:var(--blue-500);color:var(--ink-700);
  transform:translateY(-2px);box-shadow:var(--shadow-md);
}
.contact-via strong{display:block;font-size:12.5px;color:var(--ink-500);font-weight:600;}
.contact-via-icono{
  width:38px;height:38px;flex:none;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--blue-50);color:var(--blue-600);
}
.contact-via-icono svg{width:19px;height:19px;}
.contact-via-icono--wa{background:#E7F7EE;color:#1FA855;}
.contact-via-icono--wa svg{width:21px;height:21px;}

/* --- 9. Marquesina de clientes --------------------------------------------
   Avanza sola en bucle continuo. La pista contiene el listado DOS veces, así
   que desplazarla exactamente un 50% deja la copia justo donde estaba el
   original: el salto es invisible y el bucle no corta.
   Se detiene al pasar el mouse y al entrar con el teclado.
   -------------------------------------------------------------------------- */
.marquesina{
  position:relative;
  overflow:hidden;
  padding:6px 0 24px;
  /* Difuminado en los bordes: las tarjetas entran y salen en lugar de
     aparecer cortadas de golpe. */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.marquesina-pista{
  display:flex;
  width:max-content;
  animation:desfile-clientes 48s linear infinite;
}
.marquesina:hover .marquesina-pista,
.marquesina:focus-within .marquesina-pista,
.marquesina.esta-pausada .marquesina-pista{animation-play-state:paused;}

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

.marquesina-grupo{display:flex;gap:20px;padding-right:20px;}

.cliente-card{
  flex:0 0 260px;
  display:flex;flex-direction:column;
  background:#fff;
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  padding:24px 22px 22px;
  box-shadow:var(--shadow-sm);
  transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease;
}
.cliente-card:hover{
  transform:translateY(-4px);
  border-color:var(--blue-100);
  box-shadow:var(--shadow-md);
}

/* Zona del logo: alto fijo para que todas las tarjetas queden alineadas
   aunque los logos tengan proporciones distintas. */
.cliente-logo{
  height:56px;margin-bottom:18px;
  display:flex;align-items:center;justify-content:flex-start;
}
.cliente-logo img{max-height:56px;max-width:180px;width:auto;height:auto;object-fit:contain;}

/* Monograma: lo que se ve mientras no haya archivo de logo. */
.cliente-monograma{
  width:52px;height:52px;border-radius:var(--radius-md);
  display:flex;align-items:center;justify-content:center;
  background:var(--blue-50);border:1px solid var(--blue-100);
  color:var(--blue-700);
  font-family:'Space Grotesk',system-ui,sans-serif;
  font-size:18px;font-weight:700;letter-spacing:0.02em;
}

.cliente-nombre{font-size:15.5px;font-weight:600;line-height:1.3;margin-bottom:8px;}
.cliente-sector{
  display:inline-block;align-self:flex-start;
  font-size:11px;font-weight:600;letter-spacing:0.05em;text-transform:uppercase;
  color:var(--blue-700);background:var(--blue-50);
  border:1px solid var(--blue-100);border-radius:999px;
  padding:4px 10px;margin-bottom:11px;
}
.cliente-desc{
  font-size:13.5px;line-height:1.5;color:var(--ink-500);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden;
}

/* Quien pidió menos animación no debería ver nada moviéndose solo: la
   marquesina se detiene y pasa a desplazarse a mano. El grupo duplicado
   se oculta para no mostrar la lista dos veces. */
@media (prefers-reduced-motion:reduce){
  .marquesina{
    overflow-x:auto;
    -webkit-mask-image:none;mask-image:none;
    padding-left:32px;padding-right:32px;
  }
  .marquesina-pista{animation:none;}
  .marquesina-grupo[aria-hidden="true"]{display:none;}
}

@media (max-width:640px){
  .cliente-card{flex-basis:244px;padding:20px 18px 18px;}
  .marquesina-pista{animation-duration:38s;}
}

/* --- 10. Insignia del hero: no debe tapar el nodo "Proyectos" --------------
   En el diseño original la insignia quedaba dentro del cuadrado del diagrama
   (bottom:3%) y se montaba encima del nodo central inferior en cualquier
   pantalla mayor a 1024px. Se baja para que quede apoyada justo debajo del
   círculo, despejada. Es en %, así acompaña al diagrama cuando se reescala. */
.hero-badge{bottom:-6%;left:0;}

/* Entre 1025 y 1100px el diagrama ya se achicó pero la insignia mantiene su
   tamaño en píxeles, así que vuelve a montarse sobre "Proyectos". En esa
   franja se oculta, igual que ya hacía por debajo de 1025. */
@media (max-width:1100px){ .hero-badge{display:none;} }

/* --- 11. Flecha del cierre --------------------------------------------------
   Reemplaza a los dos botones que había. Es puramente decorativa: señala
   que la página sigue, pero no se puede clicar. El sitio se recorre de
   corrido, así que un enlace que baje un tramo no aportaría nada, y un
   elemento que parece botón sin serlo confunde. */
.cta-flecha{
  --medida:60px;
  position:relative;
  display:flex;align-items:center;justify-content:center;
  width:var(--medida);height:var(--medida);
  margin:40px auto 0;
  border-radius:50%;
  border:1.5px solid rgba(255,255,255,0.45);
  background:rgba(255,255,255,0.08);
  color:#fff;
  -webkit-backdrop-filter:blur(6px);
  backdrop-filter:blur(6px);
  animation:cta-latido 2.4s ease-in-out infinite;
}
.cta-flecha svg{width:24px;height:24px;}


/* Halo que late junto con la flecha. */
.cta-flecha::before{
  content:'';position:absolute;inset:-1.5px;border-radius:50%;
  border:1.5px solid rgba(255,255,255,0.5);
  animation:cta-halo 2.4s ease-out infinite;
  pointer-events:none;
}

@keyframes cta-latido{
  0%,100%{transform:translateY(0);}
  50%    {transform:translateY(6px);}
}
@keyframes cta-halo{
  0%  {transform:scale(1);opacity:.55;}
  70% {transform:scale(1.45);opacity:0;}
  100%{transform:scale(1.45);opacity:0;}
}

/* Quien pidió menos movimiento ve la flecha quieta, sin halo. */
@media (prefers-reduced-motion:reduce){
  .cta-flecha{animation:none;}
  .cta-flecha::before{animation:none;opacity:0;}
}

@media (max-width:640px){
  .cta-flecha{--medida:54px;margin-top:32px;}
  .cta-flecha svg{width:22px;height:22px;}
}

/* ============================================================================
   12. FONDO DE PUNTOS Y SEPARACIÓN DE SECCIONES
   ----------------------------------------------------------------------------
   La grilla de puntos ya existía, pero sólo dentro del hero y con una máscara.
   Acá se extiende a toda la página como textura de base, y las secciones
   claras pasan a ser translúcidas para que se vea a través sin competir con
   el texto.

   El punto es muy tenue a propósito (6% de negro): tiene que leerse como
   papel con textura, no como una cuadrícula. La medida de 26px es la misma
   que ya usaba el hero, así el patrón es continuo de arriba a abajo.

   La capa va fija (no acompaña el scroll) para que el contenido se sienta
   deslizándose por encima de una superficie quieta.
   ========================================================================== */
:root{
  --punto:rgba(10,20,50,0.06);
  --punto-paso:26px;
  --fondo-base:#FBFCFD;
  /* Relleno de las dos ondas de transicion. Tienen token propio porque antes
     reutilizaban --gray-50 y --blue-600, y el tema oscuro le cambio el
     significado a los dos. Cada onda debe valer lo mismo que la seccion a la
     que desemboca. */
  --onda-1:#F5F7F9;   /* cae sobre .section--alt */
  --onda-2:#005AEF;   /* cae sobre el degradado del cierre */
  /* Color del reflejo del cursor, en componentes RGB sueltos: el JS los lee
     de acá y les pone la opacidad. Así el efecto acompaña al tema sin tener
     el color repetido en el JavaScript. */
  --brillo-cursor:0,90,239;
}

body{
  background-color:var(--fondo-base);
  background-image:radial-gradient(var(--punto) 1.2px, transparent 1.2px);
  background-size:var(--punto-paso) var(--punto-paso);
  background-position:0 0;
  background-attachment:fixed;
}

/* Secciones claras: translúcidas, para que la grilla se insinúe detrás. */
.section{
  position:relative;
  background:rgba(255,255,255,0.55);
  border-top:1px solid var(--border);
}
.section--alt{background:rgba(243,245,248,0.78);}

/* Las secciones de color se quedan opacas: ahí la grilla estorbaría.
   OJO con el orden: la regla .section de arriba está al final del archivo y
   tiene la misma especificidad que .integration-section y .cta-section, que
   se declaran mucho antes. Por eso hay que volver a fijarles el fondo acá:
   si no, el blanco translúcido las pisa y el texto blanco queda invisible. */
.integration-section,
.cta-section{border-top:0;}

.integration-section{background:var(--ink-900);}
.cta-section{
  background:linear-gradient(135deg,var(--blue-700),var(--blue-600) 60%,var(--blue-500));
}

/* Una línea azul muy fina marca el cambio de sección sin pesar.
   Se excluyen las secciones de color: la del cierre ya usa su ::before para
   un círculo decorativo, y esta regla se lo estaba reemplazando. */
.section + .section:not(.cta-section):not(.integration-section)::before{
  content:'';
  position:absolute;top:-1px;left:50%;transform:translateX(-50%);
  width:min(220px,40%);height:1px;
  background:linear-gradient(90deg,transparent,var(--blue-500),transparent);
  opacity:.5;
}

.footer{background:rgba(243,245,248,0.9);}

/* ----------------------------------------------------------------------------
   Reflejo del cursor sobre la grilla.
   Los puntos cercanos al puntero se tiñen de azul. El lienzo sólo se dibuja
   en una ventana chica alrededor del cursor, no en toda la pantalla: así el
   efecto cuesta casi nada aunque la página sea larga.
   Se activa únicamente donde hay un puntero real — en un teléfono no haría
   nada y sólo gastaría batería.
   -------------------------------------------------------------------------- */
#grillaViva{
  position:fixed;
  inset:0;
  z-index:-1;              /* encima del fondo del body, debajo del contenido */
  pointer-events:none;
  display:none;
}
@media (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference){
  #grillaViva{display:block;}
}

/* ============================================================================
   13. TEMA OSCURO
   ----------------------------------------------------------------------------
   Bloque autocontenido: borrándolo entero, el sitio vuelve al tema claro.

   No alcanza con voltear los tokens. El archivo tiene 134 colores escritos a
   mano, y varios tokens cumplen dos papeles a la vez: --blue-700 se usa 8
   veces como texto y 6 como fondo. Por eso acá se hacen dos cosas: se
   redefinen los tokens neutros, y después se corrigen a mano las superficies
   que estaban fijas en blanco.

   Los blancos que son TEXTO sobre color (botón azul, sección oscura, cierre)
   se dejan como están: ahí el blanco es correcto.
   ========================================================================== */
:root{
  /* Neutros, invertidos */
  --ink-900:#EDF1F7;          /* títulos */
  --ink-700:#B7C3D1;          /* cuerpo */
  --ink-500:#8795A5;          /* apagado */
  --white:#161A21;            /* superficie de tarjetas */
  --gray-50:#1B212A;          /* secciones alternas */
  --gray-100:#232B35;
  --border:#2C3542;

  /* Azules: los tintes claros pasan a tintes oscuros */
  --blue-50:#152334;
  --blue-100:#1F3552;
  /* Y los que se usan como texto se aclaran para que se lean */
  --blue-600:#5C9BFF;
  --blue-700:#8CB8FF;

  /* Superficie de la página */
  --fondo-hondo:#0D1117;
  /* La grilla se ve a traves de las secciones, que son translucidas: sólo
     pasa el 42% de lo que hay detras. Por eso el punto se define fuerte
     (24%) — en pantalla, dentro de una seccion, termina leyendose suave. */
  --punto:rgba(255,255,255,0.24);
  --brillo-cursor:150,192,255;
  --onda-1:#171C24;   /* .section--alt ya mezclada con el fondo de la pagina */
  --onda-2:#0A2E7A;   /* el arranque del degradado del cierre */
  --sombra-sm:0 1px 2px rgba(0,0,0,0.35);
  --shadow-sm:0 1px 2px rgba(0,0,0,0.3);
  --shadow-md:0 8px 24px rgba(0,0,0,0.35);
  --shadow-lg:0 24px 60px -14px rgba(0,0,0,0.6);
}

/* --- Superficie de la página, con la grilla ya visible ------------------- */
body{
  background-color:var(--fondo-hondo);
  background-image:radial-gradient(var(--punto) 1.6px, transparent 1.6px);
  background-size:var(--punto-paso) var(--punto-paso);
  background-attachment:fixed;
  color:var(--ink-700);
  padding-inline:0;
}

/* --- Secciones ----------------------------------------------------------
   Con :not() para no volver a pisar las dos que tienen color propio. */
.section:not(.integration-section):not(.cta-section){
  background:rgba(22,26,33,0.58);
}
.section--alt:not(.integration-section):not(.cta-section){
  background:rgba(27,33,42,0.68);
}
.integration-section{background:#05070A;}
.cta-section{
  background:linear-gradient(135deg,#0A2E7A,#0B44B8 60%,#1D62D8);
}

/* --- Encabezado y menú --------------------------------------------------- */
.header{background:rgba(13,17,23,0.82);}
@supports not ((backdrop-filter:blur(2px)) or (-webkit-backdrop-filter:blur(2px))){
  .header{background:rgba(13,17,23,0.97);}
}
.mobile-nav{background:#11161D;}
.mobile-nav a{border-bottom-color:var(--border);}

/* --- Hero ----------------------------------------------------------------
   El hero es lo primero que se ve, asi que tambien va translucido: si queda
   opaco, la grilla y el reflejo del cursor no aparecen hasta bajar, y el
   efecto no se entiende. Los dos destellos azules se suben un poco para
   compensar la opacidad que pierde la capa de color. */
.hero{
  background:
    radial-gradient(560px 420px at 88% -8%,rgba(0,90,239,0.20) 0%,transparent 68%),
    radial-gradient(480px 380px at -8% 105%,rgba(46,124,246,0.13) 0%,transparent 62%),
    rgba(15,20,27,0.60);
}
/* La grilla propia del hero (recortada con mascara al angulo superior) ya no
   hace falta: la de toda la pagina la cubre, y superpuestas no coinciden en
   origen y producen muare. */
.hero::before{display:none;}
.hero-kicker{background:#141A22;border-color:var(--blue-100);}
.hero-node{background:rgba(24,29,37,0.82);border-color:rgba(70,84,102,0.7);}
.hero-badge{background:#141A22;border-color:var(--border);}
.hero-core{box-shadow:0 0 0 8px rgba(255,255,255,0.06),0 20px 44px -10px rgba(0,0,0,0.7);}

/* --- Tarjetas y piezas sobre superficie ---------------------------------- */
.btn-secondary{background:#1A212A;color:var(--ink-900);border-color:var(--border);}
.chain-node,
.module-card,
.benefit-card,
.pipeline-step,
.diff-item,
.form-card,
.contact-via,
.cliente-card{background:#161C24;border-color:var(--border);}

.field input,
.field select,
.field textarea{background:#11161D;border-color:var(--border);color:var(--ink-900);}
.field input::placeholder,
.field textarea::placeholder{color:#6B7787;}

.tl-dot{border-color:#0D1117;}
.tag{background:#1A212A;border-color:var(--border);color:var(--ink-700);}

/* --- Pie ----------------------------------------------------------------- */
.footer{background:rgba(17,22,29,0.78);border-top-color:var(--border);}

/* El botón claro vive sobre el azul del cierre: ahí el texto SÍ va oscuro. */
.btn-light{background:#fff;color:#0B44B8;}
.btn-light:hover{background:#E8F0FF;color:#08307F;}

/* --- Correcciones detectadas por la auditoría de contraste ---------------
   Tres piezas quedaban ilegibles al invertir los colores:
   · .platform-callout usaba --blue-900 (azul casi negro) como texto, que
     sobre el tinte azul oscuro daba un contraste de 1,03 — invisible.
   · Su <strong> tenía #005AEF escrito a mano, que tampoco se leía.
   · El enlace de salto pinta texto blanco sobre --blue-600, y al aclarar
     ese token el blanco sobre blanco-azulado bajó a 2,77.                  */
/* · .flow-sep (las flechas entre etapas) tenia #5C7BB8 fijo, que sobre el
     negro de la seccion oscura daba 4,40 — a un pelo del minimo de 4,5.    */
.flow-sep{color:#7E9BD6;}
.platform-callout{color:var(--ink-700);}
.platform-callout strong{color:#7FB0FF;}
.skip-link{background:#0B44B8;}

/* ============================================================================
   14. PARTNER DE FRACTTAL  ·  Y ARREGLO DE LAS ONDAS
   ----------------------------------------------------------------------------
   Dos cosas relacionadas.

   (a) La alianza con Fracttal. Se muestra con el patron "marca | rol" que usan
       Oracle y SAP en las cabeceras de sus partners. El logotipo es de
       Fracttal; la palabra "Partner" va como texto nuestro, no incrustada en
       la imagen, para que escale nitida y la lean los lectores de pantalla.

       En el encabezado solo cabe de 1120px para arriba. La cuenta, medida:
       marca 117 + navegacion 552 + partner 167 + boton 117 + separaciones 68
       = 1021px de contenido, que con los 64px de margen interno necesitan una
       ventana de 1100. Se deja 1120 para no quedar al filo. Por debajo la
       alianza pasa a una franja bajo el hero, que ademas se ve mejor en
       telefono que un logotipo apretado en la barra.

   (b) Las dos ondas de transicion tenian el relleno escrito con tokens que el
       tema oscuro cambio de significado, y quedaron desalineadas con la
       seccion a la que desembocan:
         · la del hero rellenaba con --gray-50 (27,33,42) pero cae sobre una
           seccion translucida que se ve (23,28,36): un escalon de 4 niveles;
         · la de Tecnologia rellenaba con --blue-600, que en oscuro se aclaro a
           #5C9BFF para poder usarlo como texto, y desembocaba en el azul
           profundo del cierre. Quedaba una banda celeste sobre el degradado.
       Ahora cada onda tiene su propio token y no depende de colores que se
       usan para otra cosa.
   ========================================================================== */

/* --- (a) Encabezado ------------------------------------------------------- */
.partner{
  display:none;                      /* se enciende a partir de 1080px */
  align-items:center;
  gap:11px;
}
.partner img{
  height:19px;
  width:auto;
  /* El logo de Fracttal es blanco puro; sobre la barra oscura compite con el
     de Cubo si va a plena intensidad. Bajarlo un punto lo deja presente sin
     pelear por la atencion. */
  opacity:.88;
}
.partner-rol{
  font-size:12.5px;
  font-weight:500;
  letter-spacing:0.01em;
  line-height:1;
  color:var(--ink-500);
  padding-left:11px;
  border-left:1px solid var(--border);
}
@media (min-width:1120px){ .partner{display:flex;} }

/* --- (a) Franja bajo el hero ---------------------------------------------- */
.partner-franja{display:none;background:var(--onda-1);}
.partner-franja .container{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:14px;
  padding-top:17px;
  padding-bottom:17px;
}
.partner-franja-texto{
  font-size:11.5px;
  font-weight:600;
  letter-spacing:0.1em;
  text-transform:uppercase;
  color:var(--ink-500);
}
.partner-franja img{height:21px;width:auto;opacity:.9;}

@media (max-width:1119px){ .partner-franja{display:block;} }
/* En pantallas muy angostas el conjunto entra en dos lineas antes que
   achicarse hasta volverse ilegible. */
@media (max-width:360px){
  .partner-franja .container{flex-direction:column;gap:9px;}
}

/* La franja no se imprime: en papel la alianza no aporta. */
@media print{ .partner,.partner-franja{display:none!important;} }

/* ============================================================================
   15. LAS ONDAS, PEGADAS AL BORDE DE SU SECCION
   ----------------------------------------------------------------------------
   Las dos ondas estaban en el flujo normal, como ultimo hijo de su seccion.
   El problema es que el relleno inferior de la seccion viene DESPUES de ellas:

       [ contenido del hero        ]
       [ onda  (60px)              ]  <- anuncia el color de la seccion siguiente
       [ relleno inferior (132px)  ]  <- pero todavia es el hero
       [ seccion siguiente         ]  <- recien aca llega

   O sea que la onda prometia el cambio de color y despues seguian 132px del
   color viejo. En el hero eran 132px y en la seccion de Tecnologia 112px.
   Se notaba poco mientras el sitio era claro y todo tendia al blanco; con el
   tema oscuro, y con la franja de partner justo debajo, quedo a la vista.

   La solucion es sacarlas del flujo y clavarlas al borde inferior. La onda
   pasa a dibujarse encima del relleno, que es espacio vacio, asi que no tapa
   nada: el relleno mas chico que tiene una seccion es 76px y la onda mide 60.
   ========================================================================== */
.hero,
.section{position:relative;}

.section-wave{
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  height:60px;
}

/* ============================================================================
   16. LA INSIGNIA "DATOS SINCRONIZADOS" VUELVE EN MOVIL
   ----------------------------------------------------------------------------
   Estaba oculta por debajo de 1100px, y lo estaba por una razon real: vivia
   dentro del cuadrado del diagrama en posicion absoluta, y cuando el cuadrado
   se achica la insignia mantiene su tamano en pixeles, asi que terminaba
   montada sobre el nodo "Proyectos". Esconderla fue un parche.

   El arreglo de verdad es sacarla del cuadrado (hecho en el HTML) y dejar que
   en pantallas chicas caiga en el flujo normal, centrada debajo del diagrama.
   Asi ocupa su propio espacio y no puede pisar nada.

   De 1101px para arriba se mantiene el diseno original: apoyada sobre el
   borde inferior izquierdo del diagrama.
   ========================================================================== */
.hero-columna{position:relative;}

/* Escritorio: como antes. La columna mide lo mismo que el cuadrado (el
   diagrama nunca llega a su max-width de 600px porque la columna da 528),
   asi que los porcentajes siguen valiendo lo mismo que cuando la insignia
   colgaba del cuadrado. */
@media (min-width:1101px){
  .hero-badge{position:absolute;bottom:-6%;left:0;display:flex;}
}

/* Pantallas chicas: en el flujo, centrada y con su propio espacio. */
@media (max-width:1100px){
  .hero-badge{
    display:flex;
    position:static;
    margin:26px auto 0;
    width:max-content;
    max-width:100%;
  }
}

/* En telefonos angostos el texto es largo para una pastilla de una sola
   linea, asi que se afina un poco antes de dejar que rompa el ancho. */
@media (max-width:420px){
  .hero-badge{padding:7px 13px 7px 7px;gap:8px;}
  .hero-badge .ring{width:24px;height:24px;}
  .hero-badge .ring svg{width:13px;height:13px;}
  .hero-badge span{font-size:11.5px;}
}

/* ============================================================================
   17. CREDITO DE DESARROLLO
   ----------------------------------------------------------------------------
   Firma al pie. Va en su propia linea, separada por un filete, y no compitiendo
   con el copyright: es una firma, no un dato de la empresa.

   El logotipo de Nandutek esta pensado para negro y usa un gris azulado muy
   tenue en el nandu y en "tek" — a proposito. Al recortarlo se respeto esa
   intencion en vez de "arreglarla": ver tools/build-nandutek.py.

   32px de alto es lo minimo con lo que la palabra "Nandutek" se lee sin
   esfuerzo; a 22px, que seria lo habitual para una firma, queda empastada.
   ========================================================================== */
.credito{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:12px;
  margin-top:20px;
  padding-top:20px;
  border-top:1px solid var(--border);
}
.credito span{
  font-size:12px;
  font-weight:500;
  letter-spacing:0.03em;
  color:var(--ink-500);
}
.credito img{height:32px;width:auto;}

@media (max-width:420px){
  .credito{gap:10px;}
  .credito img{height:28px;}
}
