/* ============================================================
   CAUS — HERO / IMMERSIVE 3D WORLD (hero, twin, xray, final sections)
   Extracted verbatim from the original single-file build.
============================================================ */


/* ============================================================
   IMMERSIVE 3D WORLD (hero / twin / xray / final)
============================================================ */
#gl-fixed{
  position:fixed;inset:0;
  z-index:1;
  background:
    radial-gradient(ellipse 120% 90% at 50% 18%, #14202f 0%, #0a121c 46%, #060a10 100%);
}
#gl-fixed canvas{position:absolute;inset:0;width:100%;height:100%;display:block;}
#gl-fixed .grain{
  position:absolute;inset:0;pointer-events:none;mix-blend-mode:overlay;opacity:.05;
  background-image:url("../assets/textures/grain.svg");
}
#gl-fixed .vignette{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 80% 70% at 50% 45%, transparent 40%, rgba(4,6,9,.55) 100%);
}
#gl-status{
  position:fixed;left:0;right:0;bottom:0;text-align:center;color:rgba(255,255,255,.3);
  font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.1em;padding:10px;z-index:2;
}

.immersive-section{position:relative;z-index:5;color:#fff;}
.immersive-section .wrap{position:relative;z-index:2;height:100%;}

/* ---------- HERO — single continuous Three.js facility ----------
   First-viewport only: no scroll-jacking, no image, no second canvas.
   The shared #gl-fixed WebGL canvas (z-index:1, behind everything)
   renders the actual plant; this section only lays copy over the
   LEFT ~35% and leaves the RIGHT ~65% empty so the 3D shows through.
   Markers + the tech panel are position:fixed DOM overlays, positioned
   every frame from the live Three.js world→screen projection of the
   real equipment (see part_script2.html). No card, no border, no
   screenshot ever sits over the render. */
#hero{min-height:100vh;padding-bottom:34px;}
.hero-sticky{position:relative;padding-top:calc(var(--nav-h) + 22px);}
#hero .hero-topline{position:relative;z-index:4;margin-bottom:22px;}

/* hero-only eyebrow refinement -- sharper tracking/weight and a soft glow
   on the leading rule; scoped to .hero-topline so every other .eyebrow
   on the site (delivery, footer, section intros) is untouched. */
.hero-topline .eyebrow{font-weight:600;letter-spacing:.19em;}
.hero-topline .eyebrow::before{opacity:.9;box-shadow:0 0 10px rgba(57,195,242,.55);}

.hero-grid{
  position:relative;z-index:3;
  display:grid;grid-template-columns:minmax(280px,33%) 1fr;align-items:center;gap:38px;
}
.hero-copy{max-width:420px;}
.hero-headline-v2{font-size:clamp(28px,3.6vw,47px);line-height:1.08;font-weight:700;letter-spacing:-0.02em;}
.hero-headline-v2 span{display:block;text-wrap:balance;}
.hero-headline-v2 span+span{margin-top:2px;}
.hero-headline-v2 .hl-strong{color:#fff;font-weight:700;}
.hero-headline-v2 .hl-soft{color:rgba(255,255,255,.46);font-weight:400;}
.hero-headline-v2 .hl-accent{color:var(--green);font-weight:700;text-shadow:0 0 26px rgba(107,191,58,.4);}
.hero-sub{
  margin-top:20px;
  font-size:clamp(14px,1vw,15.5px);
  line-height:1.6;
  color:rgba(255,255,255,.68);
  max-width:40ch;
  font-weight:400;
}
.hero-ctas{display:flex;align-items:center;gap:22px;margin-top:32px;flex-wrap:wrap;}
.hero-stat-row{
  margin-top:40px;display:grid;grid-template-columns:repeat(3,1fr);gap:18px 20px;
  padding-top:22px;border-top:1px solid rgba(255,255,255,.16);max-width:380px;
}
/* vertical dividers between the 3 columns (matches the .hpn-btn divider
   language used in the process navigator below), so the 3+2 layout reads
   as a deliberate spec table rather than an uneven wrap. */
.hero-stat-row>div:nth-child(3n+2),
.hero-stat-row>div:nth-child(3n){padding-left:18px;border-left:1px solid rgba(255,255,255,.12);}
.hero-stat-row .hs-k{font-family:'JetBrains Mono',monospace;font-size:9.5px;letter-spacing:.12em;color:rgba(255,255,255,.42);text-transform:uppercase;}
.hero-stat-row .hs-v{margin-top:7px;font-size:14.5px;font-weight:600;color:#fff;font-family:'JetBrains Mono',monospace;font-variant-numeric:tabular-nums;}

/* ---- right column: no box, no border — the live 3D canvas shows
   through unobstructed. This div exists only to hold the fixed-
   position marker/tech-panel overlays and reserve the grid column. ---- */
.hero-visual{position:relative;}

/* numbered markers: position:fixed, placed every frame at the
   projected screen coordinates of the real equipment in the 3D scene */
.hero-markers{position:fixed;inset:0;z-index:50;pointer-events:none;}
.hero-marker{
  position:absolute;pointer-events:none;cursor:pointer;transform:translate(-50%,-50%);
  width:25px;height:25px;
  display:flex;align-items:center;justify-content:center;
  border-radius:50%;border:1px solid rgba(57,195,242,.6);background:rgba(6,10,16,.6);backdrop-filter:blur(3px);
  font-family:'JetBrains Mono',monospace;font-size:9.5px;color:var(--cyan);font-weight:600;
  transition:transform .25s var(--ease-out), background .25s, border-color .25s, opacity .35s var(--ease-out);
  opacity:0;
}
.hero-marker.show{opacity:1;pointer-events:auto;}
.hero-marker::before{
  content:"";position:absolute;inset:-6px;border-radius:50%;border:1px solid rgba(57,195,242,.25);
}
.hero-marker.sludge{border-color:rgba(201,146,79,.6);color:#e0aa6c;}
.hero-marker.sludge::before{border-color:rgba(201,146,79,.28);}
.hero-marker:hover,.hero-marker.active{background:var(--cyan);color:var(--navy-950);border-color:var(--cyan);transform:translate(-50%,-50%) scale(1.18);}
.hero-marker.sludge:hover,.hero-marker.sludge.active{background:#c9924f;color:var(--navy-950);border-color:#c9924f;}
.hero-marker .hm-tip{
  position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%);
  display:flex;flex-direction:column;gap:4px;width:max-content;max-width:220px;
  background:rgba(6,10,16,.97);border:1px solid rgba(255,255,255,.16);
  padding:9px 12px;font-family:'JetBrains Mono',monospace;color:#fff;
  opacity:0;visibility:hidden;transition:opacity .2s;pointer-events:none;z-index:5;
}
.hero-marker .hm-tip b{font-size:11px;font-weight:600;color:#fff;text-wrap:balance;}
.hero-marker .hm-tip i{font-size:9.5px;font-style:normal;color:rgba(255,255,255,.5);letter-spacing:.01em;}
.hero-marker:hover .hm-tip{opacity:1;visibility:visible;}

/* floating technical panel: compact "now viewing" readout, fixed to the
   upper-right of the viewport — never a card around the 3D itself */
.hero-tech-panel{
  position:fixed;top:calc(var(--nav-h) + 20px);right:var(--gutter);z-index:50;
  width:188px;border:1px solid rgba(255,255,255,.16);background:rgba(6,10,16,.66);backdrop-filter:blur(8px);
  padding:12px 14px;
  opacity:0;transition:opacity .4s var(--ease-out);pointer-events:none;
}
.hero-tech-panel.show{opacity:1;}
.hero-tech-panel .htp-title{font-family:'JetBrains Mono',monospace;font-size:9px;letter-spacing:.12em;color:rgba(255,255,255,.4);text-transform:uppercase;margin-bottom:8px;}
.hero-tech-panel .htp-row{display:flex;flex-direction:column;gap:3px;font-family:'JetBrains Mono',monospace;padding-top:8px;border-top:1px solid rgba(57,195,242,.22);}
.hero-tech-panel .htp-row span:first-child{font-size:9px;color:rgba(255,255,255,.4);letter-spacing:.08em;}
.hero-tech-panel .htp-row span:last-child{font-size:13px;color:var(--cyan);font-weight:600;line-height:1.25;}
.hero-tech-panel .htp-meta{margin-top:10px;padding-top:10px;border-top:1px solid rgba(255,255,255,.09);font-size:9px;letter-spacing:.06em;color:rgba(255,255,255,.3);}

/* bottom process navigator: main water line + branching sludge line */
.hero-proc-nav-wrap{position:relative;z-index:3;margin-top:22px;}
.hero-proc-nav{
  display:flex;align-items:stretch;gap:0;
  border:1px solid rgba(255,255,255,.14);background:rgba(6,10,16,.6);backdrop-filter:blur(10px);
  overflow-x:auto;
}
.hpn-btn{
  flex:1 1 0;min-width:104px;background:none;border:none;border-right:1px solid rgba(255,255,255,.1);
  padding:13px 13px;display:flex;flex-direction:column;gap:6px;text-align:left;
  color:rgba(255,255,255,.55);transition:background .25s,color .25s;
}
.hpn-btn:last-child{border-right:none;}
.hpn-n{font-family:'JetBrains Mono',monospace;font-size:10px;color:rgba(255,255,255,.35);}
.hpn-t{font-size:11px;font-weight:500;letter-spacing:.01em;line-height:1.25;color:inherit;}
.hpn-btn.active{background:rgba(57,195,242,.1);color:#fff;}
.hpn-btn.active .hpn-n{color:var(--cyan);}
.hpn-btn:hover{color:#fff;}

.hero-proc-nav-sludge{margin-top:10px;margin-left:44px;border-color:rgba(201,146,79,.22);position:relative;}
.hero-proc-nav-sludge::before{
  content:"";position:absolute;left:-44px;top:-10px;width:30px;height:calc(50% + 10px);
  border-left:1px solid rgba(201,146,79,.4);border-bottom:1px solid rgba(201,146,79,.4);
}
.hero-proc-nav-sludge .hpn-btn.active{background:rgba(201,146,79,.14);}
.hero-proc-nav-sludge .hpn-btn.active .hpn-n{color:#c9924f;}

@media (max-width:1080px){
  .hero-tech-panel{width:160px;padding:10px 12px;}
}
@media (max-width:900px){
  .hero-topline .eyebrow{font-size:10px;letter-spacing:.1em;gap:8px;}
  .hero-topline .eyebrow::before{width:16px;}
  .hero-grid{grid-template-columns:1fr;gap:26px;}
  .hero-copy{max-width:none;}
  .hero-headline-v2{font-size:clamp(26px,7vw,36px);}
  .hero-tech-panel{display:none;}
  .hero-stat-row{grid-template-columns:repeat(2,1fr);max-width:none;}
  .hero-marker{width:22px;height:22px;font-size:9px;}
  .hero-proc-nav{overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .hpn-btn{min-width:126px;}
  .hero-proc-nav-sludge{margin-left:0;}
  .hero-proc-nav-sludge::before{display:none;}
}
@media (prefers-reduced-motion: reduce){
  .hero-marker{transition:background .2s,border-color .2s;}
}

/* ---------- TWIN scroll section ---------- */
#twin{height:420vh;}  /* was 220vh: lengthened so the 13-stop full-facility tour (01-12) isn't rushed */
.twin-sticky{position:sticky;top:0;height:100vh;display:flex;align-items:center;overflow:hidden;}
.twin-panel{
  position:absolute;
  border:1px solid rgba(255,255,255,.16);
  background:rgba(6,10,16,.42);
  backdrop-filter:blur(6px);
  padding:18px 20px;
  min-width:220px;
  opacity:0;transform:translateY(10px);
  transition:opacity .6s var(--ease-out), transform .6s var(--ease-out);
}
.twin-panel.show{opacity:1;transform:translateY(0);}
.twin-panel .tp-title{font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.12em;color:var(--cyan);margin-bottom:12px;text-transform:uppercase;}
.twin-panel .tp-row{display:flex;justify-content:space-between;gap:18px;font-family:'JetBrains Mono',monospace;font-size:12px;padding:6px 0;border-top:1px solid rgba(255,255,255,.09);}
.twin-panel .tp-row:first-of-type{border-top:none;}
.twin-panel .tp-row span:first-child{color:rgba(255,255,255,.45);letter-spacing:.03em;}
.twin-panel .tp-row span:last-child{color:#fff;font-weight:500;}
#twin-panel-a{top:18%;left:var(--gutter);}
#twin-panel-b{bottom:16%;right:var(--gutter);}
.twin-caption{
  position:absolute;left:50%;bottom:9%;transform:translateX(-50%);
  text-align:center;opacity:0;transition:opacity .7s var(--ease-out);
  max-width:520px;padding:0 20px;
}
.twin-caption.show{opacity:1;}
.twin-caption h3{font-size:clamp(20px,2.4vw,30px);font-weight:500;color:#fff;letter-spacing:-0.01em;}
.twin-caption p{margin-top:10px;font-size:14px;color:rgba(255,255,255,.6);}
.twin-progress{position:absolute;left:var(--gutter);bottom:6%;display:flex;align-items:center;gap:10px;font-family:'JetBrains Mono',monospace;font-size:10px;color:rgba(255,255,255,.4);letter-spacing:.1em;}
.twin-progress .bar{width:140px;height:1px;background:rgba(255,255,255,.18);position:relative;}
.twin-progress .bar i{position:absolute;left:0;top:0;height:100%;background:var(--cyan);width:0%;}
@media (max-width:900px){
  /* Mobile #twin overlay layout: at desktop widths panel-a (top-left),
     panel-b (bottom-right) and the centered caption sit far enough apart
     to never touch. Below ~900px there isn't enough width for that
     diagonal layout — panel-b (bottom-right) and the centered caption
     land in the same vertical band and their text collides illegibly.
     Fix: stack panel-a then panel-b as a single left column (panel-b
     anchored a fixed px offset below panel-a via calc(), so the gap
     stays constant regardless of viewport height), and run the caption
     full-width/left-aligned near the bottom, clear of both panels and
     of the progress bar below it. */
  .twin-panel{min-width:170px;padding:12px 14px;}
  .twin-panel .tp-title{margin-bottom:8px;}
  .twin-panel .tp-row{padding:4px 0;}
  #twin-panel-a{top:14%;}
  #twin-panel-b{top:calc(14% + 134px);left:var(--gutter);right:auto;bottom:auto;}
  .twin-caption{
    left:var(--gutter);right:var(--gutter);transform:none;
    bottom:12%;max-width:none;text-align:left;padding:0;
  }
  .twin-caption p{margin-top:8px;}
}

/* ---------- XRAY ---------- */
#xray{height:130vh;}
#xray .xray-sticky.wrap{position:sticky;top:0;height:100vh;display:flex;align-items:center;}
.xray-label{
  position:absolute;left:var(--gutter);top:50%;transform:translateY(-50%);
  max-width:360px;opacity:0;transition:opacity .8s var(--ease-out);
}
.xray-label.show{opacity:1;}
@media (max-width:900px){
  /* At narrow widths max-width:360px no longer constrains anything (the
     viewport itself is narrower than that), so the label's shrink-to-fit
     box runs flush to the right edge with a left gutter but no matching
     right one. Give it the same right gutter so text isn't flush against
     the screen edge. */
  .xray-label{right:var(--gutter);max-width:none;}
}
.xray-label .eyebrow{margin-bottom:16px;}
.xray-label h3{font-size:clamp(24px,2.8vw,34px);color:#fff;font-weight:500;letter-spacing:-0.01em;line-height:1.1;}
.xray-label p{margin-top:14px;font-size:14.5px;color:rgba(255,255,255,.62);line-height:1.6;}
.xray-list{margin-top:20px;display:flex;flex-direction:column;gap:0;font-family:'JetBrains Mono',monospace;font-size:11.5px;color:rgba(255,255,255,.5);}
.xray-list div{padding:9px 0;border-top:1px solid rgba(255,255,255,.1);display:flex;justify-content:space-between;}
.xray-list div:first-child{border-top:none;}
.xray-list b{color:var(--cyan);font-weight:500;}

/* ---------- FINAL ---------- */
#final{height:100vh;min-height:640px;}
/* Vertical centering lives on .wrap itself (same pattern as #xray
   .xray-sticky.wrap), not on the #final section. Putting display:flex
   on the SECTION instead would turn .wrap into a flex item that
   shrinks to its content width and gets auto-centered horizontally,
   pulling the whole CTA block toward the middle of the screen instead
   of sitting at the standard left gutter the nav/logo use. Keeping
   .wrap a normal block (sized by its own max-width + margin:0 auto,
   exactly like every other section) and making IT the flex container
   for .final-inner centers the content vertically without disturbing
   its horizontal position. */
#final .wrap{display:flex;align-items:center;}
.final-inner{max-width:640px;}
.final-inner h2{font-size:clamp(32px,4.4vw,54px);color:#fff;font-weight:500;letter-spacing:-0.02em;line-height:1.08;}
.final-inner p{margin-top:18px;font-size:16px;color:rgba(255,255,255,.65);max-width:44ch;line-height:1.6;}
.final-ctas{display:flex;align-items:center;gap:28px;margin-top:34px;flex-wrap:wrap;}
.final-contact{margin-top:56px;display:flex;gap:48px;flex-wrap:wrap;border-top:1px solid rgba(255,255,255,.14);padding-top:26px;}
.final-contact div{font-size:13px;}
.final-contact .fc-label{font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.12em;color:rgba(255,255,255,.4);text-transform:uppercase;margin-bottom:8px;}
.final-contact .fc-value{color:#fff;font-weight:500;}
